Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
FlutterMutatorViewTest.java
Go to the documentation of this file.
1package io.flutter.embedding.engine.mutatorsstack;
2
3import static android.view.View.OnFocusChangeListener;
4import static junit.framework.TestCase.*;
5import static org.mockito.Mockito.*;
6
7import android.content.Context;
8import android.graphics.Matrix;
9import android.view.MotionEvent;
10import android.view.View;
11import android.view.ViewGroup;
12import android.view.ViewTreeObserver;
13import android.view.accessibility.AccessibilityEvent;
14import android.widget.FrameLayout;
15import androidx.test.core.app.ApplicationProvider;
16import androidx.test.ext.junit.runners.AndroidJUnit4;
17import io.flutter.embedding.android.AndroidTouchProcessor;
18import org.junit.Test;
19import org.junit.runner.RunWith;
20import org.mockito.ArgumentCaptor;
21import org.robolectric.annotation.Config;
22import org.robolectric.annotation.Implementation;
23import org.robolectric.annotation.Implements;
24
25@Config(manifest = Config.NONE)
26@RunWith(AndroidJUnit4.class)
28 private final Context ctx = ApplicationProvider.getApplicationContext();
29
30 @Test
31 public void canDragViews() {
32 final AndroidTouchProcessor touchProcessor = mock(AndroidTouchProcessor.class);
33 final FlutterMutatorView view = new FlutterMutatorView(ctx, 1.0f, touchProcessor);
34 final FlutterMutatorsStack mutatorStack = mock(FlutterMutatorsStack.class);
35
36 assertTrue(view.onInterceptTouchEvent(mock(MotionEvent.class)));
37
38 {
39 view.readyToDisplay(mutatorStack, /*left=*/ 1, /*top=*/ 2, /*width=*/ 0, /*height=*/ 0);
40 view.onTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0.0f, 0.0f, 0));
41 final ArgumentCaptor<Matrix> matrixCaptor = ArgumentCaptor.forClass(Matrix.class);
42 verify(touchProcessor).onTouchEvent(any(), matrixCaptor.capture());
43
44 final Matrix screenMatrix = new Matrix();
45 screenMatrix.postTranslate(1, 2);
46 assertTrue(matrixCaptor.getValue().equals(screenMatrix));
47 }
48
49 reset(touchProcessor);
50
51 {
52 view.readyToDisplay(mutatorStack, /*left=*/ 3, /*top=*/ 4, /*width=*/ 0, /*height=*/ 0);
53 view.onTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0.0f, 0.0f, 0));
54 final ArgumentCaptor<Matrix> matrixCaptor = ArgumentCaptor.forClass(Matrix.class);
55 verify(touchProcessor).onTouchEvent(any(), matrixCaptor.capture());
56
57 final Matrix screenMatrix = new Matrix();
58 screenMatrix.postTranslate(1, 2);
59 assertTrue(matrixCaptor.getValue().equals(screenMatrix));
60 }
61
62 reset(touchProcessor);
63
64 {
65 view.readyToDisplay(mutatorStack, /*left=*/ 5, /*top=*/ 6, /*width=*/ 0, /*height=*/ 0);
66 view.onTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0.0f, 0.0f, 0));
67 final ArgumentCaptor<Matrix> matrixCaptor = ArgumentCaptor.forClass(Matrix.class);
68 verify(touchProcessor).onTouchEvent(any(), matrixCaptor.capture());
69
70 final Matrix screenMatrix = new Matrix();
71 screenMatrix.postTranslate(3, 4);
72 assertTrue(matrixCaptor.getValue().equals(screenMatrix));
73 }
74
75 reset(touchProcessor);
76
77 {
78 view.readyToDisplay(mutatorStack, /*left=*/ 7, /*top=*/ 8, /*width=*/ 0, /*height=*/ 0);
79 view.onTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0.0f, 0.0f, 0));
80 final ArgumentCaptor<Matrix> matrixCaptor = ArgumentCaptor.forClass(Matrix.class);
81 verify(touchProcessor).onTouchEvent(any(), matrixCaptor.capture());
82
83 final Matrix screenMatrix = new Matrix();
84 screenMatrix.postTranslate(7, 8);
85 assertTrue(matrixCaptor.getValue().equals(screenMatrix));
86 }
87 }
88
89 @Test
91 final ViewTreeObserver viewTreeObserver = mock(ViewTreeObserver.class);
92 when(viewTreeObserver.isAlive()).thenReturn(true);
93
94 final FlutterMutatorView view =
95 new FlutterMutatorView(ctx) {
96 @Override
97 public ViewTreeObserver getViewTreeObserver() {
98 return viewTreeObserver;
99 }
100
101 @Override
102 public boolean hasFocus() {
103 return true;
104 }
105 };
106
107 final OnFocusChangeListener focusListener = mock(OnFocusChangeListener.class);
108 view.setOnDescendantFocusChangeListener(focusListener);
109
110 final ArgumentCaptor<ViewTreeObserver.OnGlobalFocusChangeListener> focusListenerCaptor =
111 ArgumentCaptor.forClass(ViewTreeObserver.OnGlobalFocusChangeListener.class);
112 verify(viewTreeObserver).addOnGlobalFocusChangeListener(focusListenerCaptor.capture());
113
114 focusListenerCaptor.getValue().onGlobalFocusChanged(null, null);
115 verify(focusListener).onFocusChange(view, true);
116 }
117
118 @Test
120 final ViewTreeObserver viewTreeObserver = mock(ViewTreeObserver.class);
121 when(viewTreeObserver.isAlive()).thenReturn(true);
122
123 final FlutterMutatorView view =
124 new FlutterMutatorView(ctx) {
125 @Override
126 public ViewTreeObserver getViewTreeObserver() {
127 return viewTreeObserver;
128 }
129
130 @Override
131 public boolean hasFocus() {
132 return false;
133 }
134 };
135
136 final OnFocusChangeListener focusListener = mock(OnFocusChangeListener.class);
137 view.setOnDescendantFocusChangeListener(focusListener);
138
139 final ArgumentCaptor<ViewTreeObserver.OnGlobalFocusChangeListener> focusListenerCaptor =
140 ArgumentCaptor.forClass(ViewTreeObserver.OnGlobalFocusChangeListener.class);
141 verify(viewTreeObserver).addOnGlobalFocusChangeListener(focusListenerCaptor.capture());
142
143 focusListenerCaptor.getValue().onGlobalFocusChanged(null, null);
144 verify(focusListener).onFocusChange(view, false);
145 }
146
147 @Test
149 final FlutterMutatorView view =
150 new FlutterMutatorView(ctx) {
151 @Override
152 public ViewTreeObserver getViewTreeObserver() {
153 final ViewTreeObserver viewTreeObserver = mock(ViewTreeObserver.class);
154 when(viewTreeObserver.isAlive()).thenReturn(false);
155 return viewTreeObserver;
156 }
157 };
158 view.setOnDescendantFocusChangeListener(mock(OnFocusChangeListener.class));
159 }
160
161 @Test
163 final ViewTreeObserver viewTreeObserver = mock(ViewTreeObserver.class);
164 when(viewTreeObserver.isAlive()).thenReturn(true);
165
166 final FlutterMutatorView view =
167 new FlutterMutatorView(ctx) {
168 @Override
169 public ViewTreeObserver getViewTreeObserver() {
170 return viewTreeObserver;
171 }
172 };
173
174 assertNull(view.activeFocusListener);
175
176 view.setOnDescendantFocusChangeListener(mock(OnFocusChangeListener.class));
177 assertNotNull(view.activeFocusListener);
178
179 final ViewTreeObserver.OnGlobalFocusChangeListener activeFocusListener =
181
182 view.setOnDescendantFocusChangeListener(mock(OnFocusChangeListener.class));
183 assertNotNull(view.activeFocusListener);
184
185 verify(viewTreeObserver, times(1)).removeOnGlobalFocusChangeListener(activeFocusListener);
186 }
187
188 @Test
190 final ViewTreeObserver viewTreeObserver = mock(ViewTreeObserver.class);
191 when(viewTreeObserver.isAlive()).thenReturn(true);
192
193 final FlutterMutatorView view =
194 new FlutterMutatorView(ctx) {
195 @Override
196 public ViewTreeObserver getViewTreeObserver() {
197 return viewTreeObserver;
198 }
199 };
200
201 assertNull(view.activeFocusListener);
202
203 view.setOnDescendantFocusChangeListener(mock(OnFocusChangeListener.class));
204 assertNotNull(view.activeFocusListener);
205
206 final ViewTreeObserver.OnGlobalFocusChangeListener activeFocusListener =
208
210 assertNull(view.activeFocusListener);
211
213 verify(viewTreeObserver, times(1)).removeOnGlobalFocusChangeListener(activeFocusListener);
214 }
215
216 @Test
217 @Config(
218 shadows = {
219 ShadowViewGroup.class,
220 })
222 final FlutterMutatorView wrapperView = new FlutterMutatorView(ctx);
223
224 final View embeddedView = mock(View.class);
225 wrapperView.addView(embeddedView);
226
227 when(embeddedView.getImportantForAccessibility())
228 .thenReturn(View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
229 final boolean eventSent =
230 wrapperView.requestSendAccessibilityEvent(embeddedView, mock(AccessibilityEvent.class));
231 assertFalse(eventSent);
232 }
233
234 @Implements(ViewGroup.class)
235 public static class ShadowViewGroup extends org.robolectric.shadows.ShadowViewGroup {
236 @Implementation
237 protected boolean requestSendAccessibilityEvent(View child, AccessibilityEvent event) {
238 return true;
239 }
240 }
241
242 @Implements(FrameLayout.class)
243 public static class ShadowFrameLayout
244 extends io.flutter.plugin.platform.PlatformViewWrapperTest.ShadowViewGroup {}
245}
static SkISize times(const SkISize &size, float factor)
m reset()
boolean requestSendAccessibilityEvent(View child, AccessibilityEvent event)
void readyToDisplay( @NonNull FlutterMutatorsStack mutatorsStack, int left, int top, int width, int height)
ViewTreeObserver.OnGlobalFocusChangeListener activeFocusListener
void setOnDescendantFocusChangeListener(@NonNull OnFocusChangeListener userFocusListener)
FlKeyEvent * event