blob: 9052093346cb3f7d8ac29a733b620cde9d3e1e86 [file] [log] [blame]
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07001/*
Dave Mankoffdde5ee62019-05-02 17:36:11 -04002 * Copyright (C) 2019 The Android Open Source Project
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -07003 *
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
Dave Mankoffdde5ee62019-05-02 17:36:11 -040014 * limitations under the License.
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070015 */
16
17package com.android.systemui.classifier;
18
19import android.content.Context;
20import android.database.ContentObserver;
21import android.hardware.Sensor;
22import android.hardware.SensorEvent;
23import android.hardware.SensorEventListener;
24import android.hardware.SensorManager;
Adrian Roos7bb38a92016-07-21 11:44:01 -070025import android.net.Uri;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070026import android.os.Handler;
Selim Cinekf8c4add2017-06-08 09:54:58 -070027import android.os.Looper;
Adrian Roosc5584ce2016-02-24 14:17:19 -080028import android.os.PowerManager;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070029import android.os.UserHandle;
30import android.provider.Settings;
Adrian Roos004437e2017-08-16 11:58:02 +020031import android.view.InputDevice;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070032import android.view.MotionEvent;
Adrian Roosca664b92016-04-18 14:40:27 -070033import android.view.accessibility.AccessibilityManager;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070034
Dave Mankoff63c576e2019-05-01 18:00:01 -040035import com.android.internal.logging.MetricsLogger;
Jorim Jaggie549a8d2017-05-15 02:40:05 +020036import com.android.systemui.Dependency;
37import com.android.systemui.UiOffloadThread;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070038import com.android.systemui.analytics.DataCollector;
Beverly8fdb5332019-02-04 14:29:49 -050039import com.android.systemui.plugins.statusbar.StatusBarStateController;
40import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070041import com.android.systemui.statusbar.StatusBarState;
Adrian Roos7a8ae8a2017-08-02 16:26:50 +020042import com.android.systemui.util.AsyncSensorManager;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070043
Adrian Roos401caae2016-03-04 13:35:21 -080044import java.io.PrintWriter;
45
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070046/**
47 * When the phone is locked, listens to touch, sensor and phone events and sends them to
48 * DataCollector and HumanInteractionClassifier.
49 *
50 * It does not collect touch events when the bouncer shows up.
51 */
Dave Mankoffdde5ee62019-05-02 17:36:11 -040052public class FalsingManagerImpl implements FalsingManagerFactory.FalsingManager {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070053 private static final String ENFORCE_BOUNCER = "falsing_manager_enforce_bouncer";
54
Blazej Magnowski6dc59b42015-09-22 15:14:20 -070055 private static final int[] CLASSIFIER_SENSORS = new int[] {
56 Sensor.TYPE_PROXIMITY,
57 };
58
59 private static final int[] COLLECTOR_SENSORS = new int[] {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070060 Sensor.TYPE_ACCELEROMETER,
61 Sensor.TYPE_GYROSCOPE,
62 Sensor.TYPE_PROXIMITY,
63 Sensor.TYPE_LIGHT,
64 Sensor.TYPE_ROTATION_VECTOR,
65 };
Dave Mankoff63c576e2019-05-01 18:00:01 -040066 private static final String FALSING_REMAIN_LOCKED = "falsing_failure_after_attempts";
67 private static final String FALSING_SUCCESS = "falsing_success_after_attempts";
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070068
Selim Cinekf8c4add2017-06-08 09:54:58 -070069 private final Handler mHandler = new Handler(Looper.getMainLooper());
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070070 private final Context mContext;
71
72 private final SensorManager mSensorManager;
73 private final DataCollector mDataCollector;
74 private final HumanInteractionClassifier mHumanInteractionClassifier;
Adrian Roosca664b92016-04-18 14:40:27 -070075 private final AccessibilityManager mAccessibilityManager;
Jorim Jaggie549a8d2017-05-15 02:40:05 +020076 private final UiOffloadThread mUiOffloadThread;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070077
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070078 private boolean mEnforceBouncer = false;
79 private boolean mBouncerOn = false;
Siarhei Vishniakou81e1ffd2018-05-04 16:08:22 -070080 private boolean mBouncerOffOnDown = false;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070081 private boolean mSessionActive = false;
Adrian Roos004437e2017-08-16 11:58:02 +020082 private boolean mIsTouchScreen = true;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070083 private int mState = StatusBarState.SHADE;
Adrian Roosc5584ce2016-02-24 14:17:19 -080084 private boolean mScreenOn;
Adrian Roose395b5d2017-06-28 16:52:37 +020085 private boolean mShowingAod;
Adrian Roos8e291a52016-12-09 16:10:19 -080086 private Runnable mPendingWtf;
Dave Mankoff63c576e2019-05-01 18:00:01 -040087 private int mIsFalseTouchCalls;
88 private MetricsLogger mMetricsLogger;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070089
Dave Mankoffdde5ee62019-05-02 17:36:11 -040090 private SensorEventListener mSensorEventListener = new SensorEventListener() {
91 @Override
92 public synchronized void onSensorChanged(SensorEvent event) {
93 mDataCollector.onSensorChanged(event);
94 mHumanInteractionClassifier.onSensorChanged(event);
95 }
96
97 @Override
98 public void onAccuracyChanged(Sensor sensor, int accuracy) {
99 mDataCollector.onAccuracyChanged(sensor, accuracy);
100 }
101 };
102
103 public StateListener mStatusBarStateListener = new StateListener() {
104 @Override
105 public void onStateChanged(int newState) {
106 if (FalsingLog.ENABLED) {
107 FalsingLog.i("setStatusBarState", new StringBuilder()
108 .append("from=").append(StatusBarState.toShortString(mState))
109 .append(" to=").append(StatusBarState.toShortString(newState))
110 .toString());
111 }
112 mState = newState;
113 updateSessionActive();
114 }
115 };
116
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700117 protected final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
118 @Override
119 public void onChange(boolean selfChange) {
120 updateConfiguration();
121 }
122 };
123
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400124 FalsingManagerImpl(Context context) {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700125 mContext = context;
Adrian Roos7a8ae8a2017-08-02 16:26:50 +0200126 mSensorManager = Dependency.get(AsyncSensorManager.class);
Adrian Roosca664b92016-04-18 14:40:27 -0700127 mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700128 mDataCollector = DataCollector.getInstance(mContext);
129 mHumanInteractionClassifier = HumanInteractionClassifier.getInstance(mContext);
Jorim Jaggie549a8d2017-05-15 02:40:05 +0200130 mUiOffloadThread = Dependency.get(UiOffloadThread.class);
Adrian Roosc5584ce2016-02-24 14:17:19 -0800131 mScreenOn = context.getSystemService(PowerManager.class).isInteractive();
Dave Mankoff63c576e2019-05-01 18:00:01 -0400132 mMetricsLogger = new MetricsLogger();
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700133
134 mContext.getContentResolver().registerContentObserver(
135 Settings.Secure.getUriFor(ENFORCE_BOUNCER), false,
136 mSettingsObserver,
137 UserHandle.USER_ALL);
138
139 updateConfiguration();
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400140 Dependency.get(StatusBarStateController.class).addCallback(mStatusBarStateListener);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700141 }
142
143 private void updateConfiguration() {
144 mEnforceBouncer = 0 != Settings.Secure.getInt(mContext.getContentResolver(),
145 ENFORCE_BOUNCER, 0);
146 }
147
Adrian Roosc5584ce2016-02-24 14:17:19 -0800148 private boolean shouldSessionBeActive() {
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400149 if (FalsingLog.ENABLED && FalsingLog.VERBOSE) {
Adrian Roos401caae2016-03-04 13:35:21 -0800150 FalsingLog.v("shouldBeActive", new StringBuilder()
151 .append("enabled=").append(isEnabled() ? 1 : 0)
152 .append(" mScreenOn=").append(mScreenOn ? 1 : 0)
153 .append(" mState=").append(StatusBarState.toShortString(mState))
154 .toString()
155 );
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400156 }
Adrian Roose395b5d2017-06-28 16:52:37 +0200157 return isEnabled() && mScreenOn && (mState == StatusBarState.KEYGUARD) && !mShowingAod;
Adrian Roosc5584ce2016-02-24 14:17:19 -0800158 }
159
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700160 private boolean sessionEntrypoint() {
Adrian Roosc5584ce2016-02-24 14:17:19 -0800161 if (!mSessionActive && shouldSessionBeActive()) {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700162 onSessionStart();
163 return true;
164 }
165 return false;
166 }
167
Adrian Roosc5584ce2016-02-24 14:17:19 -0800168 private void sessionExitpoint(boolean force) {
169 if (mSessionActive && (force || !shouldSessionBeActive())) {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700170 mSessionActive = false;
Dave Mankoff63c576e2019-05-01 18:00:01 -0400171 if (mIsFalseTouchCalls != 0) {
172 if (FalsingLog.ENABLED) {
173 FalsingLog.i(
174 "isFalseTouchCalls", "Calls before failure: " + mIsFalseTouchCalls);
175 }
176 mMetricsLogger.histogram(FALSING_REMAIN_LOCKED, mIsFalseTouchCalls);
177 mIsFalseTouchCalls = 0;
178 }
Jorim Jaggie549a8d2017-05-15 02:40:05 +0200179
180 // This can be expensive, and doesn't need to happen on the main thread.
181 mUiOffloadThread.submit(() -> {
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400182 mSensorManager.unregisterListener(mSensorEventListener);
Jorim Jaggie549a8d2017-05-15 02:40:05 +0200183 });
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700184 }
185 }
186
Adrian Roose395b5d2017-06-28 16:52:37 +0200187 public void updateSessionActive() {
188 if (shouldSessionBeActive()) {
189 sessionEntrypoint();
190 } else {
191 sessionExitpoint(false /* force */);
192 }
193 }
194
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700195 private void onSessionStart() {
Adrian Roos401caae2016-03-04 13:35:21 -0800196 if (FalsingLog.ENABLED) {
197 FalsingLog.i("onSessionStart", "classifierEnabled=" + isClassiferEnabled());
Adrian Roos8e291a52016-12-09 16:10:19 -0800198 clearPendingWtf();
Adrian Roos401caae2016-03-04 13:35:21 -0800199 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700200 mBouncerOn = false;
201 mSessionActive = true;
Dave Mankoff63c576e2019-05-01 18:00:01 -0400202 mIsFalseTouchCalls = 0;
Blazej Magnowski6dc59b42015-09-22 15:14:20 -0700203
204 if (mHumanInteractionClassifier.isEnabled()) {
205 registerSensors(CLASSIFIER_SENSORS);
206 }
Adrian Roos7bb38a92016-07-21 11:44:01 -0700207 if (mDataCollector.isEnabledFull()) {
Blazej Magnowski6dc59b42015-09-22 15:14:20 -0700208 registerSensors(COLLECTOR_SENSORS);
209 }
Selim Cinek1ed50042018-01-18 17:12:32 -0800210 if (mDataCollector.isEnabled()) {
211 mDataCollector.onFalsingSessionStarted();
212 }
Blazej Magnowski6dc59b42015-09-22 15:14:20 -0700213 }
214
215 private void registerSensors(int [] sensors) {
216 for (int sensorType : sensors) {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700217 Sensor s = mSensorManager.getDefaultSensor(sensorType);
218 if (s != null) {
Jorim Jaggie549a8d2017-05-15 02:40:05 +0200219
220 // This can be expensive, and doesn't need to happen on the main thread.
221 mUiOffloadThread.submit(() -> {
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400222 mSensorManager.registerListener(
223 mSensorEventListener, s, SensorManager.SENSOR_DELAY_GAME);
Jorim Jaggie549a8d2017-05-15 02:40:05 +0200224 });
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700225 }
226 }
227 }
228
Blazej Magnowski6dc59b42015-09-22 15:14:20 -0700229 public boolean isClassiferEnabled() {
230 return mHumanInteractionClassifier.isEnabled();
231 }
232
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700233 private boolean isEnabled() {
234 return mHumanInteractionClassifier.isEnabled() || mDataCollector.isEnabled();
235 }
236
Dave Mankoffc88d6222018-10-25 15:31:20 -0400237 public boolean isUnlockingDisabled() {
238 return mDataCollector.isUnlockingDisabled();
239 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700240 /**
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700241 * @return true if the classifier determined that this is not a human interacting with the phone
242 */
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700243 public boolean isFalseTouch() {
Adrian Roos401caae2016-03-04 13:35:21 -0800244 if (FalsingLog.ENABLED) {
Adrian Roos6a04cb12016-03-14 20:21:02 -0700245 // We're getting some false wtfs from touches that happen after the device went
246 // to sleep. Only report missing sessions that happen when the device is interactive.
Adrian Roos8e291a52016-12-09 16:10:19 -0800247 if (!mSessionActive && mContext.getSystemService(PowerManager.class).isInteractive()
248 && mPendingWtf == null) {
249 int enabled = isEnabled() ? 1 : 0;
250 int screenOn = mScreenOn ? 1 : 0;
251 String state = StatusBarState.toShortString(mState);
252 Throwable here = new Throwable("here");
253 FalsingLog.wLogcat("isFalseTouch", new StringBuilder()
Adrian Roos401caae2016-03-04 13:35:21 -0800254 .append("Session is not active, yet there's a query for a false touch.")
Adrian Roos8e291a52016-12-09 16:10:19 -0800255 .append(" enabled=").append(enabled)
256 .append(" mScreenOn=").append(screenOn)
257 .append(" mState=").append(state)
258 .append(". Escalating to WTF if screen does not turn on soon.")
Adrian Roos401caae2016-03-04 13:35:21 -0800259 .toString());
Adrian Roos8e291a52016-12-09 16:10:19 -0800260
261 // Unfortunately we're also getting false positives for touches that happen right
262 // after the screen turns on, but before that notification has made it to us.
263 // Unfortunately there's no good way to catch that, except to wait and see if we get
264 // the screen on notification soon.
265 mPendingWtf = () -> FalsingLog.wtf("isFalseTouch", new StringBuilder()
266 .append("Session did not become active after query for a false touch.")
267 .append(" enabled=").append(enabled)
268 .append('/').append(isEnabled() ? 1 : 0)
269 .append(" mScreenOn=").append(screenOn)
270 .append('/').append(mScreenOn ? 1 : 0)
271 .append(" mState=").append(state)
272 .append('/').append(StatusBarState.toShortString(mState))
273 .append(". Look for warnings ~1000ms earlier to see root cause.")
274 .toString(), here);
275 mHandler.postDelayed(mPendingWtf, 1000);
Adrian Roos401caae2016-03-04 13:35:21 -0800276 }
277 }
Adrian Roosca664b92016-04-18 14:40:27 -0700278 if (mAccessibilityManager.isTouchExplorationEnabled()) {
279 // Touch exploration triggers false positives in the classifier and
280 // already sufficiently prevents false unlocks.
281 return false;
282 }
Adrian Roos004437e2017-08-16 11:58:02 +0200283 if (!mIsTouchScreen) {
284 // Unlocking with input devices besides the touchscreen should already be sufficiently
285 // anti-falsed.
286 return false;
287 }
Dave Mankoff63c576e2019-05-01 18:00:01 -0400288 mIsFalseTouchCalls++;
289 boolean isFalse = mHumanInteractionClassifier.isFalseTouch();
290 if (!isFalse) {
291 if (FalsingLog.ENABLED) {
292 FalsingLog.i("isFalseTouchCalls", "Calls before success: " + mIsFalseTouchCalls);
293 }
294 mMetricsLogger.histogram(FALSING_SUCCESS, mIsFalseTouchCalls);
295 mIsFalseTouchCalls = 0;
296 }
297 return isFalse;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700298 }
299
Adrian Roos8e291a52016-12-09 16:10:19 -0800300 private void clearPendingWtf() {
301 if (mPendingWtf != null) {
302 mHandler.removeCallbacks(mPendingWtf);
303 mPendingWtf = null;
304 }
305 }
306
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700307
308 public boolean shouldEnforceBouncer() {
309 return mEnforceBouncer;
310 }
311
Adrian Roose395b5d2017-06-28 16:52:37 +0200312 public void setShowingAod(boolean showingAod) {
313 mShowingAod = showingAod;
314 updateSessionActive();
315 }
316
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700317 public void onScreenTurningOn() {
Adrian Roos401caae2016-03-04 13:35:21 -0800318 if (FalsingLog.ENABLED) {
319 FalsingLog.i("onScreenTurningOn", new StringBuilder()
320 .append("from=").append(mScreenOn ? 1 : 0)
321 .toString());
Adrian Roos8e291a52016-12-09 16:10:19 -0800322 clearPendingWtf();
Adrian Roos401caae2016-03-04 13:35:21 -0800323 }
Adrian Roosc5584ce2016-02-24 14:17:19 -0800324 mScreenOn = true;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700325 if (sessionEntrypoint()) {
326 mDataCollector.onScreenTurningOn();
327 }
328 }
329
330 public void onScreenOnFromTouch() {
Adrian Roos401caae2016-03-04 13:35:21 -0800331 if (FalsingLog.ENABLED) {
332 FalsingLog.i("onScreenOnFromTouch", new StringBuilder()
333 .append("from=").append(mScreenOn ? 1 : 0)
334 .toString());
335 }
Adrian Roosc5584ce2016-02-24 14:17:19 -0800336 mScreenOn = true;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700337 if (sessionEntrypoint()) {
338 mDataCollector.onScreenOnFromTouch();
339 }
340 }
341
342 public void onScreenOff() {
Adrian Roos401caae2016-03-04 13:35:21 -0800343 if (FalsingLog.ENABLED) {
344 FalsingLog.i("onScreenOff", new StringBuilder()
345 .append("from=").append(mScreenOn ? 1 : 0)
346 .toString());
347 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700348 mDataCollector.onScreenOff();
Adrian Roosc5584ce2016-02-24 14:17:19 -0800349 mScreenOn = false;
350 sessionExitpoint(false /* force */);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700351 }
352
353 public void onSucccessfulUnlock() {
Adrian Roos401caae2016-03-04 13:35:21 -0800354 if (FalsingLog.ENABLED) {
355 FalsingLog.i("onSucccessfulUnlock", "");
356 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700357 mDataCollector.onSucccessfulUnlock();
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700358 }
359
360 public void onBouncerShown() {
Adrian Roos401caae2016-03-04 13:35:21 -0800361 if (FalsingLog.ENABLED) {
362 FalsingLog.i("onBouncerShown", new StringBuilder()
363 .append("from=").append(mBouncerOn ? 1 : 0)
364 .toString());
365 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700366 if (!mBouncerOn) {
367 mBouncerOn = true;
368 mDataCollector.onBouncerShown();
369 }
370 }
371
372 public void onBouncerHidden() {
Adrian Roos401caae2016-03-04 13:35:21 -0800373 if (FalsingLog.ENABLED) {
374 FalsingLog.i("onBouncerHidden", new StringBuilder()
375 .append("from=").append(mBouncerOn ? 1 : 0)
376 .toString());
377 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700378 if (mBouncerOn) {
379 mBouncerOn = false;
380 mDataCollector.onBouncerHidden();
381 }
382 }
383
384 public void onQsDown() {
Adrian Roos401caae2016-03-04 13:35:21 -0800385 if (FalsingLog.ENABLED) {
386 FalsingLog.i("onQsDown", "");
387 }
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700388 mHumanInteractionClassifier.setType(Classifier.QUICK_SETTINGS);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700389 mDataCollector.onQsDown();
390 }
391
392 public void setQsExpanded(boolean expanded) {
393 mDataCollector.setQsExpanded(expanded);
394 }
395
Lucas Dupinbc9aac12018-03-04 20:18:15 -0800396 public void onTrackingStarted(boolean secure) {
Adrian Roos401caae2016-03-04 13:35:21 -0800397 if (FalsingLog.ENABLED) {
398 FalsingLog.i("onTrackingStarted", "");
399 }
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400400 mHumanInteractionClassifier.setType(secure
401 ? Classifier.BOUNCER_UNLOCK : Classifier.UNLOCK);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700402 mDataCollector.onTrackingStarted();
403 }
404
405 public void onTrackingStopped() {
406 mDataCollector.onTrackingStopped();
407 }
408
409 public void onNotificationActive() {
410 mDataCollector.onNotificationActive();
411 }
412
Adrian Roos9f0b0022016-11-09 15:56:50 -0800413 public void onNotificationDoubleTap(boolean accepted, float dx, float dy) {
414 if (FalsingLog.ENABLED) {
415 FalsingLog.i("onNotificationDoubleTap", "accepted=" + accepted
416 + " dx=" + dx + " dy=" + dy + " (px)");
417 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700418 mDataCollector.onNotificationDoubleTap();
419 }
420
421 public void setNotificationExpanded() {
422 mDataCollector.setNotificationExpanded();
423 }
424
425 public void onNotificatonStartDraggingDown() {
Adrian Roos401caae2016-03-04 13:35:21 -0800426 if (FalsingLog.ENABLED) {
427 FalsingLog.i("onNotificatonStartDraggingDown", "");
428 }
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700429 mHumanInteractionClassifier.setType(Classifier.NOTIFICATION_DRAG_DOWN);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700430 mDataCollector.onNotificatonStartDraggingDown();
431 }
432
Selim Cinek3d6ae232019-01-04 14:14:33 -0800433 public void onStartExpandingFromPulse() {
434 if (FalsingLog.ENABLED) {
435 FalsingLog.i("onStartExpandingFromPulse", "");
436 }
437 mHumanInteractionClassifier.setType(Classifier.PULSE_EXPAND);
438 mDataCollector.onStartExpandingFromPulse();
439 }
440
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700441 public void onNotificatonStopDraggingDown() {
442 mDataCollector.onNotificatonStopDraggingDown();
443 }
444
Selim Cinek3d6ae232019-01-04 14:14:33 -0800445 public void onExpansionFromPulseStopped() {
446 mDataCollector.onExpansionFromPulseStopped();
447 }
448
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700449 public void onNotificationDismissed() {
450 mDataCollector.onNotificationDismissed();
451 }
452
453 public void onNotificatonStartDismissing() {
Adrian Roos401caae2016-03-04 13:35:21 -0800454 if (FalsingLog.ENABLED) {
455 FalsingLog.i("onNotificatonStartDismissing", "");
456 }
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700457 mHumanInteractionClassifier.setType(Classifier.NOTIFICATION_DISMISS);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700458 mDataCollector.onNotificatonStartDismissing();
459 }
460
461 public void onNotificatonStopDismissing() {
462 mDataCollector.onNotificatonStopDismissing();
463 }
464
465 public void onCameraOn() {
466 mDataCollector.onCameraOn();
467 }
468
469 public void onLeftAffordanceOn() {
470 mDataCollector.onLeftAffordanceOn();
471 }
472
473 public void onAffordanceSwipingStarted(boolean rightCorner) {
Adrian Roos401caae2016-03-04 13:35:21 -0800474 if (FalsingLog.ENABLED) {
475 FalsingLog.i("onAffordanceSwipingStarted", "");
476 }
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700477 if (rightCorner) {
478 mHumanInteractionClassifier.setType(Classifier.RIGHT_AFFORDANCE);
479 } else {
480 mHumanInteractionClassifier.setType(Classifier.LEFT_AFFORDANCE);
481 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700482 mDataCollector.onAffordanceSwipingStarted(rightCorner);
483 }
484
485 public void onAffordanceSwipingAborted() {
486 mDataCollector.onAffordanceSwipingAborted();
487 }
488
489 public void onUnlockHintStarted() {
490 mDataCollector.onUnlockHintStarted();
491 }
492
493 public void onCameraHintStarted() {
494 mDataCollector.onCameraHintStarted();
495 }
496
497 public void onLeftAffordanceHintStarted() {
498 mDataCollector.onLeftAffordanceHintStarted();
499 }
500
501 public void onTouchEvent(MotionEvent event, int width, int height) {
Adrian Roos004437e2017-08-16 11:58:02 +0200502 if (event.getAction() == MotionEvent.ACTION_DOWN) {
503 mIsTouchScreen = event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN);
Siarhei Vishniakou81e1ffd2018-05-04 16:08:22 -0700504 // If the bouncer was not shown during the down event,
505 // we want the entire gesture going to HumanInteractionClassifier
506 mBouncerOffOnDown = !mBouncerOn;
Adrian Roos004437e2017-08-16 11:58:02 +0200507 }
Siarhei Vishniakou81e1ffd2018-05-04 16:08:22 -0700508 if (mSessionActive) {
509 if (!mBouncerOn) {
510 // In case bouncer is "visible", but onFullyShown has not yet been called,
511 // avoid adding the event to DataCollector
512 mDataCollector.onTouchEvent(event, width, height);
513 }
514 if (mBouncerOffOnDown) {
515 mHumanInteractionClassifier.onTouchEvent(event);
516 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700517 }
518 }
Adrian Roos401caae2016-03-04 13:35:21 -0800519
520 public void dump(PrintWriter pw) {
521 pw.println("FALSING MANAGER");
522 pw.print("classifierEnabled="); pw.println(isClassiferEnabled() ? 1 : 0);
523 pw.print("mSessionActive="); pw.println(mSessionActive ? 1 : 0);
524 pw.print("mBouncerOn="); pw.println(mSessionActive ? 1 : 0);
525 pw.print("mState="); pw.println(StatusBarState.toShortString(mState));
526 pw.print("mScreenOn="); pw.println(mScreenOn ? 1 : 0);
527 pw.println();
528 }
Adrian Roos7bb38a92016-07-21 11:44:01 -0700529
530 public Uri reportRejectedTouch() {
531 if (mDataCollector.isEnabled()) {
532 return mDataCollector.reportRejectedTouch();
533 }
534 return null;
535 }
536
537 public boolean isReportingEnabled() {
538 return mDataCollector.isReportingEnabled();
539 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700540}