1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.classifier;
18 
19 import android.hardware.devicestate.DeviceStateManager.FoldStateListener;
20 import android.util.DisplayMetrics;
21 import android.view.InputDevice;
22 import android.view.MotionEvent;
23 
24 import androidx.test.uiautomator.Configurator;
25 
26 import com.android.systemui.SysuiTestCase;
27 import com.android.systemui.dock.DockManagerFake;
28 import com.android.systemui.statusbar.policy.BatteryController;
29 
30 import org.junit.After;
31 import org.mockito.Mock;
32 import org.mockito.MockitoAnnotations;
33 
34 import java.util.ArrayList;
35 import java.util.List;
36 
37 public class ClassifierTest extends SysuiTestCase {
38 
39     private FalsingDataProvider mDataProvider;
40     private final List<MotionEvent> mMotionEvents = new ArrayList<>();
41     private float mOffsetX = 0;
42     private float mOffsetY = 0;
43     @Mock
44     private BatteryController mBatteryController;
45     private FoldStateListener mFoldStateListener = new FoldStateListener(mContext);
46     private final DockManagerFake mDockManager = new DockManagerFake();
47 
setup()48     public void setup() {
49         MockitoAnnotations.initMocks(this);
50         DisplayMetrics displayMetrics = new DisplayMetrics();
51         displayMetrics.xdpi = 100;
52         displayMetrics.ydpi = 100;
53         displayMetrics.widthPixels = 1000;
54         displayMetrics.heightPixels = 1000;
55         mDataProvider = new FalsingDataProvider(
56                 displayMetrics, mBatteryController, mFoldStateListener, mDockManager, false);
57     }
58 
59     @After
tearDown()60     public void tearDown() {
61         resetDataProvider();
62     }
63 
getDataProvider()64     protected FalsingDataProvider getDataProvider() {
65         return mDataProvider;
66     }
67 
setOffsetX(float offsetX)68     protected void setOffsetX(float offsetX) {
69         mOffsetX = offsetX;
70     }
71 
setOffsetY(float offsetY)72     protected void setOffsetY(float offsetY) {
73         mOffsetY = offsetY;
74     }
75 
resetDataProvider()76     protected void resetDataProvider() {
77         for (MotionEvent motionEvent : mMotionEvents) {
78             motionEvent.recycle();
79         }
80 
81         mMotionEvents.clear();
82 
83         mDataProvider.onSessionEnd();
84     }
85 
getPointerAction(int actionType, int index)86     protected static int getPointerAction(int actionType, int index) {
87         return actionType + (index << MotionEvent.ACTION_POINTER_INDEX_SHIFT);
88     }
89 
appendDownEvent(float x, float y)90     protected MotionEvent appendDownEvent(float x, float y) {
91         return appendMotionEvent(MotionEvent.ACTION_DOWN, x, y);
92     }
93 
appendDownEvent(float x, float y, long eventTime)94     protected MotionEvent appendDownEvent(float x, float y, long eventTime) {
95         return appendMotionEvent(MotionEvent.ACTION_DOWN, x, y, eventTime);
96     }
97 
appendMoveEvent(float x, float y)98     protected MotionEvent appendMoveEvent(float x, float y) {
99         return appendMotionEvent(MotionEvent.ACTION_MOVE, x, y);
100     }
101 
appendMoveEvent(float x, float y, long eventTime)102     protected MotionEvent appendMoveEvent(float x, float y, long eventTime) {
103         return appendMotionEvent(MotionEvent.ACTION_MOVE, x, y, eventTime);
104     }
105 
106 
appendUpEvent(float x, float y)107     protected MotionEvent appendUpEvent(float x, float y) {
108         return appendMotionEvent(MotionEvent.ACTION_UP, x, y);
109     }
110 
appendUpEvent(float x, float y, long eventTime)111     protected MotionEvent appendUpEvent(float x, float y, long eventTime) {
112         return appendMotionEvent(MotionEvent.ACTION_UP, x, y, eventTime);
113     }
114 
appendMotionEvent(int actionType, float x, float y)115     private MotionEvent appendMotionEvent(int actionType, float x, float y) {
116 
117         long eventTime = mMotionEvents.isEmpty() ? 1 : mMotionEvents.get(
118                 mMotionEvents.size() - 1).getEventTime() + 1;
119         return appendMotionEvent(actionType, x, y, eventTime);
120     }
121 
appendMotionEvent(int actionType, float x, float y, long eventTime)122     private MotionEvent appendMotionEvent(int actionType, float x, float y, long eventTime) {
123         x += mOffsetX;
124         y += mOffsetY;
125 
126         MotionEvent motionEvent = MotionEvent.obtain(1, eventTime, actionType, x, y,
127                 0);
128         mMotionEvents.add(motionEvent);
129 
130         mDataProvider.onMotionEvent(motionEvent);
131 
132         return motionEvent;
133     }
134 
appendTrackpadDownEvent(float x, float y)135     protected MotionEvent appendTrackpadDownEvent(float x, float y) {
136         return appendTrackpadMotionEvent(MotionEvent.ACTION_DOWN, x, y, 1);
137     }
138 
appendTrackpadMoveEvent(float x, float y, int pointerCount)139     protected MotionEvent appendTrackpadMoveEvent(float x, float y, int pointerCount) {
140         return appendTrackpadMotionEvent(MotionEvent.ACTION_MOVE, x, y, pointerCount);
141     }
142 
appendTrackpadPointerDownEvent(int actionType, float x, float y, int pointerCount)143     protected MotionEvent appendTrackpadPointerDownEvent(int actionType, float x, float y,
144             int pointerCount) {
145         return appendTrackpadMotionEvent(actionType, x, y, pointerCount);
146     }
147 
appendTrackpadMotionEvent(int actionType, float x, float y, int pointerCount)148     private MotionEvent appendTrackpadMotionEvent(int actionType, float x, float y,
149             int pointerCount) {
150         long eventTime = mMotionEvents.isEmpty() ? 1 : mMotionEvents.get(
151                 mMotionEvents.size() - 1).getEventTime() + 1;
152         return appendTrackpadMotionEvent(actionType, x, y, pointerCount, eventTime);
153     }
154 
appendTrackpadMotionEvent(int actionType, float x, float y, int pointerCount, long eventTime)155     private MotionEvent appendTrackpadMotionEvent(int actionType, float x, float y,
156             int pointerCount, long eventTime) {
157         MotionEvent.PointerProperties[] pointerProperties =
158                 new MotionEvent.PointerProperties[pointerCount];
159         MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[pointerCount];
160         for (int i = 0; i < pointerCount; i++) {
161             pointerProperties[i] = getPointerProperties(i);
162             pointerCoords[i] = getPointerCoords(x, y);
163         }
164         return MotionEvent.obtain(1, eventTime, actionType, pointerCount, pointerProperties,
165                 pointerCoords, 0, 0, 1.0f, 1.0f, 0, 0,
166                 InputDevice.SOURCE_TOUCHPAD | InputDevice.SOURCE_MOUSE, 0, 0,
167                 MotionEvent.CLASSIFICATION_MULTI_FINGER_SWIPE);
168     }
169 
getPointerProperties(int pointerId)170     private static MotionEvent.PointerProperties getPointerProperties(int pointerId) {
171         MotionEvent.PointerProperties properties = new MotionEvent.PointerProperties();
172         properties.id = pointerId;
173         properties.toolType = Configurator.getInstance().getToolType();
174         return properties;
175     }
176 
getPointerCoords(float x, float y)177     private static MotionEvent.PointerCoords getPointerCoords(float x, float y) {
178         MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
179         coords.pressure = 1;
180         coords.size = 1;
181         coords.x = x;
182         coords.y = y;
183         return coords;
184     }
185 }
186