blob: a04bcc0b29c5a18181d2426f2f2bcdd767030600 [file] [log] [blame]
Jason Monk9262c942017-07-28 14:35:13 -04001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 * except in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11 * KIND, either express or implied. See the License for the specific language governing
12 * permissions and limitations under the License.
13 */
14
15package com.android.systemui.statusbar.phone;
16
17import static org.mockito.ArgumentMatchers.any;
18import static org.mockito.ArgumentMatchers.eq;
19import static org.mockito.Mockito.doAnswer;
Jason Monke57e9dc2017-08-04 10:59:13 -040020import static org.mockito.Mockito.never;
Jason Monk9262c942017-07-28 14:35:13 -040021import static org.mockito.Mockito.spy;
22import static org.mockito.Mockito.verify;
23import static org.mockito.Mockito.when;
24
Jason Monke57e9dc2017-08-04 10:59:13 -040025import android.content.res.Configuration;
Jason Monk9262c942017-07-28 14:35:13 -040026import android.testing.AndroidTestingRunner;
27import android.testing.TestableLooper.RunWithLooper;
28import android.view.MotionEvent;
29import android.view.View;
30
Brett Chabot84151d92019-02-27 15:37:59 -080031import androidx.test.filters.SmallTest;
32
Jason Monk9262c942017-07-28 14:35:13 -040033import com.android.systemui.SysuiTestCase;
34
35import org.junit.Before;
36import org.junit.Test;
37import org.junit.runner.RunWith;
38
39@RunWith(AndroidTestingRunner.class)
40@RunWithLooper
41@SmallTest
42public class NearestTouchFrameTest extends SysuiTestCase {
43
44 private NearestTouchFrame mNearestTouchFrame;
45
46 @Before
47 public void setup() {
Jason Monke57e9dc2017-08-04 10:59:13 -040048 Configuration c = new Configuration(mContext.getResources().getConfiguration());
49 c.smallestScreenWidthDp = 500;
50 mNearestTouchFrame = new NearestTouchFrame(mContext, null, c);
51 }
52
53 @Test
54 public void testNoActionOnLargeDevices() {
55 Configuration c = new Configuration(mContext.getResources().getConfiguration());
56 c.smallestScreenWidthDp = 700;
57 mNearestTouchFrame = new NearestTouchFrame(mContext, null, c);
58
59 View left = mockViewAt(0, 0, 10, 10);
60 View right = mockViewAt(20, 0, 10, 10);
61
62 mNearestTouchFrame.addView(left);
63 mNearestTouchFrame.addView(right);
64 mNearestTouchFrame.onMeasure(0, 0);
65
66 MotionEvent ev = MotionEvent.obtain(0, 0, 0,
67 12 /* x */, 5 /* y */, 0);
68 mNearestTouchFrame.onTouchEvent(ev);
69 verify(left, never()).onTouchEvent(eq(ev));
70 ev.recycle();
Jason Monk9262c942017-07-28 14:35:13 -040071 }
72
73 @Test
Jason Monk3dd17a72017-09-06 14:10:39 -040074 public void testInvisibleViews() {
75 View left = mockViewAt(0, 0, 10, 10);
76 View right = mockViewAt(20, 0, 10, 10);
77 when(left.getVisibility()).thenReturn(View.INVISIBLE);
78
79 mNearestTouchFrame.addView(left);
80 mNearestTouchFrame.addView(right);
81 mNearestTouchFrame.onMeasure(0, 0);
82
83 MotionEvent ev = MotionEvent.obtain(0, 0, 0,
84 12 /* x */, 5 /* y */, 0);
85 mNearestTouchFrame.onTouchEvent(ev);
86 verify(left, never()).onTouchEvent(eq(ev));
87 verify(right, never()).onTouchEvent(eq(ev));
88 ev.recycle();
89 }
90
Rohan Shah2adfe952018-03-05 10:00:10 -080091
92 @Test
93 public void testNearestView_DetachedViewsExcluded() {
94 View left = mockViewAt(0, 0, 10, 10);
95 when(left.isAttachedToWindow()).thenReturn(false);
96 View right = mockViewAt(20, 0, 10, 10);
97
98 mNearestTouchFrame.addView(left);
99 mNearestTouchFrame.addView(right);
100 mNearestTouchFrame.onMeasure(0, 0);
101
102 // Would go to left view if attached, but goes to right instead as left should be detached.
103 MotionEvent ev = MotionEvent.obtain(0, 0, 0,
104 12 /* x */, 5 /* y */, 0);
105 mNearestTouchFrame.onTouchEvent(ev);
106 verify(right).onTouchEvent(eq(ev));
107 ev.recycle();
108 }
109
Jason Monk3dd17a72017-09-06 14:10:39 -0400110 @Test
Jason Monk9262c942017-07-28 14:35:13 -0400111 public void testHorizontalSelection_Left() {
112 View left = mockViewAt(0, 0, 10, 10);
113 View right = mockViewAt(20, 0, 10, 10);
114
115 mNearestTouchFrame.addView(left);
116 mNearestTouchFrame.addView(right);
117 mNearestTouchFrame.onMeasure(0, 0);
118
119 MotionEvent ev = MotionEvent.obtain(0, 0, 0,
120 12 /* x */, 5 /* y */, 0);
121 mNearestTouchFrame.onTouchEvent(ev);
122 verify(left).onTouchEvent(eq(ev));
123 ev.recycle();
124 }
125
126 @Test
127 public void testHorizontalSelection_Right() {
128 View left = mockViewAt(0, 0, 10, 10);
129 View right = mockViewAt(20, 0, 10, 10);
130
131 mNearestTouchFrame.addView(left);
132 mNearestTouchFrame.addView(right);
133 mNearestTouchFrame.onMeasure(0, 0);
134
135 MotionEvent ev = MotionEvent.obtain(0, 0, 0,
136 18 /* x */, 5 /* y */, 0);
137 mNearestTouchFrame.onTouchEvent(ev);
138 verify(right).onTouchEvent(eq(ev));
139 ev.recycle();
140 }
141
142 @Test
143 public void testVerticalSelection_Top() {
144 View top = mockViewAt(0, 0, 10, 10);
145 View bottom = mockViewAt(0, 20, 10, 10);
146
147 mNearestTouchFrame.addView(top);
148 mNearestTouchFrame.addView(bottom);
149 mNearestTouchFrame.onMeasure(0, 0);
150
151 MotionEvent ev = MotionEvent.obtain(0, 0, 0,
152 5 /* x */, 12 /* y */, 0);
153 mNearestTouchFrame.onTouchEvent(ev);
154 verify(top).onTouchEvent(eq(ev));
155 ev.recycle();
156 }
157
158 @Test
159 public void testVerticalSelection_Bottom() {
160 View top = mockViewAt(0, 0, 10, 10);
161 View bottom = mockViewAt(0, 20, 10, 10);
162
163 mNearestTouchFrame.addView(top);
164 mNearestTouchFrame.addView(bottom);
165 mNearestTouchFrame.onMeasure(0, 0);
166
167 MotionEvent ev = MotionEvent.obtain(0, 0, 0,
168 5 /* x */, 18 /* y */, 0);
169 mNearestTouchFrame.onTouchEvent(ev);
170 verify(bottom).onTouchEvent(eq(ev));
171 ev.recycle();
172 }
173
Matthew Ng81818762019-01-18 11:35:54 -0800174 @Test
175 public void testViewNotAttachedNoCrash() {
176 View view = mockViewAt(0, 20, 10, 10);
177 when(view.isAttachedToWindow()).thenReturn(false);
178 mNearestTouchFrame.addView(view);
179 mNearestTouchFrame.onMeasure(0, 0);
180
181 MotionEvent ev = MotionEvent.obtain(0, 0, 0, 5 /* x */, 18 /* y */, 0);
182 mNearestTouchFrame.onTouchEvent(ev);
183 verify(view, never()).onTouchEvent(eq(ev));
184 ev.recycle();
185 }
186
Jason Monk9262c942017-07-28 14:35:13 -0400187 private View mockViewAt(int x, int y, int width, int height) {
188 View v = spy(new View(mContext));
189 doAnswer(invocation -> {
190 int[] pos = (int[]) invocation.getArguments()[0];
191 pos[0] = x;
192 pos[1] = y;
193 return null;
194 }).when(v).getLocationInWindow(any());
195 when(v.isClickable()).thenReturn(true);
Rohan Shah2adfe952018-03-05 10:00:10 -0800196 when(v.isAttachedToWindow()).thenReturn(true);
Jason Monk9262c942017-07-28 14:35:13 -0400197
198 // Stupid final methods.
199 v.setLeft(0);
200 v.setRight(width);
201 v.setTop(0);
202 v.setBottom(height);
Jason Monk9262c942017-07-28 14:35:13 -0400203 return v;
204 }
205}