blob: 20742d6d235866ba50e3760141026dc9f717fa68 [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;
Lucas Dupin7e35d142019-05-08 15:13:36 -070025import android.hardware.biometrics.BiometricSourceType;
Adrian Roos7bb38a92016-07-21 11:44:01 -070026import android.net.Uri;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070027import android.os.Handler;
Selim Cinekf8c4add2017-06-08 09:54:58 -070028import android.os.Looper;
Adrian Roosc5584ce2016-02-24 14:17:19 -080029import android.os.PowerManager;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070030import android.os.UserHandle;
31import android.provider.Settings;
Adrian Roos004437e2017-08-16 11:58:02 +020032import android.view.InputDevice;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070033import android.view.MotionEvent;
Adrian Roosca664b92016-04-18 14:40:27 -070034import android.view.accessibility.AccessibilityManager;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070035
Dave Mankoff63c576e2019-05-01 18:00:01 -040036import com.android.internal.logging.MetricsLogger;
Lucas Dupin7e35d142019-05-08 15:13:36 -070037import com.android.keyguard.KeyguardUpdateMonitor;
38import com.android.keyguard.KeyguardUpdateMonitorCallback;
Jorim Jaggie549a8d2017-05-15 02:40:05 +020039import com.android.systemui.Dependency;
40import com.android.systemui.UiOffloadThread;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070041import com.android.systemui.analytics.DataCollector;
Dave Mankoff468d4f62019-05-08 14:56:29 -040042import com.android.systemui.plugins.FalsingManager;
Beverly8fdb5332019-02-04 14:29:49 -050043import com.android.systemui.plugins.statusbar.StatusBarStateController;
44import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070045import com.android.systemui.statusbar.StatusBarState;
Dave Mankoff63a12822019-09-16 14:38:06 -040046import com.android.systemui.util.sensors.AsyncSensorManager;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070047
Adrian Roos401caae2016-03-04 13:35:21 -080048import java.io.PrintWriter;
49
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070050/**
51 * When the phone is locked, listens to touch, sensor and phone events and sends them to
52 * DataCollector and HumanInteractionClassifier.
53 *
54 * It does not collect touch events when the bouncer shows up.
55 */
Dave Mankoff468d4f62019-05-08 14:56:29 -040056public class FalsingManagerImpl implements FalsingManager {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070057 private static final String ENFORCE_BOUNCER = "falsing_manager_enforce_bouncer";
58
Blazej Magnowski6dc59b42015-09-22 15:14:20 -070059 private static final int[] CLASSIFIER_SENSORS = new int[] {
60 Sensor.TYPE_PROXIMITY,
61 };
62
63 private static final int[] COLLECTOR_SENSORS = new int[] {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070064 Sensor.TYPE_ACCELEROMETER,
65 Sensor.TYPE_GYROSCOPE,
66 Sensor.TYPE_PROXIMITY,
67 Sensor.TYPE_LIGHT,
68 Sensor.TYPE_ROTATION_VECTOR,
69 };
Dave Mankoff1dee0342019-07-11 17:44:54 -040070 public static final String FALSING_REMAIN_LOCKED = "falsing_failure_after_attempts";
71 public static final String FALSING_SUCCESS = "falsing_success_after_attempts";
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070072
Selim Cinekf8c4add2017-06-08 09:54:58 -070073 private final Handler mHandler = new Handler(Looper.getMainLooper());
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070074 private final Context mContext;
75
76 private final SensorManager mSensorManager;
77 private final DataCollector mDataCollector;
78 private final HumanInteractionClassifier mHumanInteractionClassifier;
Adrian Roosca664b92016-04-18 14:40:27 -070079 private final AccessibilityManager mAccessibilityManager;
Jorim Jaggie549a8d2017-05-15 02:40:05 +020080 private final UiOffloadThread mUiOffloadThread;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070081
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070082 private boolean mEnforceBouncer = false;
83 private boolean mBouncerOn = false;
Siarhei Vishniakou81e1ffd2018-05-04 16:08:22 -070084 private boolean mBouncerOffOnDown = false;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070085 private boolean mSessionActive = false;
Adrian Roos004437e2017-08-16 11:58:02 +020086 private boolean mIsTouchScreen = true;
Lucas Dupin7e35d142019-05-08 15:13:36 -070087 private boolean mJustUnlockedWithFace = false;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070088 private int mState = StatusBarState.SHADE;
Adrian Roosc5584ce2016-02-24 14:17:19 -080089 private boolean mScreenOn;
Adrian Roose395b5d2017-06-28 16:52:37 +020090 private boolean mShowingAod;
Adrian Roos8e291a52016-12-09 16:10:19 -080091 private Runnable mPendingWtf;
Dave Mankoff63c576e2019-05-01 18:00:01 -040092 private int mIsFalseTouchCalls;
93 private MetricsLogger mMetricsLogger;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070094
Dave Mankoffdde5ee62019-05-02 17:36:11 -040095 private SensorEventListener mSensorEventListener = new SensorEventListener() {
96 @Override
97 public synchronized void onSensorChanged(SensorEvent event) {
98 mDataCollector.onSensorChanged(event);
99 mHumanInteractionClassifier.onSensorChanged(event);
100 }
101
102 @Override
103 public void onAccuracyChanged(Sensor sensor, int accuracy) {
104 mDataCollector.onAccuracyChanged(sensor, accuracy);
105 }
106 };
107
108 public StateListener mStatusBarStateListener = new StateListener() {
109 @Override
110 public void onStateChanged(int newState) {
111 if (FalsingLog.ENABLED) {
112 FalsingLog.i("setStatusBarState", new StringBuilder()
113 .append("from=").append(StatusBarState.toShortString(mState))
114 .append(" to=").append(StatusBarState.toShortString(newState))
115 .toString());
116 }
117 mState = newState;
118 updateSessionActive();
119 }
120 };
121
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700122 protected final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
123 @Override
124 public void onChange(boolean selfChange) {
125 updateConfiguration();
126 }
127 };
Lucas Dupin7e35d142019-05-08 15:13:36 -0700128 private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
129 new KeyguardUpdateMonitorCallback() {
130 @Override
131 public void onBiometricAuthenticated(int userId,
132 BiometricSourceType biometricSourceType) {
133 if (userId == KeyguardUpdateMonitor.getCurrentUser()
134 && biometricSourceType == BiometricSourceType.FACE) {
135 mJustUnlockedWithFace = true;
136 }
137 }
138 };
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700139
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400140 FalsingManagerImpl(Context context) {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700141 mContext = context;
Adrian Roos7a8ae8a2017-08-02 16:26:50 +0200142 mSensorManager = Dependency.get(AsyncSensorManager.class);
Adrian Roosca664b92016-04-18 14:40:27 -0700143 mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700144 mDataCollector = DataCollector.getInstance(mContext);
145 mHumanInteractionClassifier = HumanInteractionClassifier.getInstance(mContext);
Jorim Jaggie549a8d2017-05-15 02:40:05 +0200146 mUiOffloadThread = Dependency.get(UiOffloadThread.class);
Adrian Roosc5584ce2016-02-24 14:17:19 -0800147 mScreenOn = context.getSystemService(PowerManager.class).isInteractive();
Dave Mankoff63c576e2019-05-01 18:00:01 -0400148 mMetricsLogger = new MetricsLogger();
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700149
150 mContext.getContentResolver().registerContentObserver(
151 Settings.Secure.getUriFor(ENFORCE_BOUNCER), false,
152 mSettingsObserver,
153 UserHandle.USER_ALL);
154
155 updateConfiguration();
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400156 Dependency.get(StatusBarStateController.class).addCallback(mStatusBarStateListener);
Dave Mankoffe2294692019-08-14 11:53:13 -0400157 Dependency.get(KeyguardUpdateMonitor.class).registerCallback(mKeyguardUpdateCallback);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700158 }
159
160 private void updateConfiguration() {
161 mEnforceBouncer = 0 != Settings.Secure.getInt(mContext.getContentResolver(),
162 ENFORCE_BOUNCER, 0);
163 }
164
Adrian Roosc5584ce2016-02-24 14:17:19 -0800165 private boolean shouldSessionBeActive() {
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400166 if (FalsingLog.ENABLED && FalsingLog.VERBOSE) {
Adrian Roos401caae2016-03-04 13:35:21 -0800167 FalsingLog.v("shouldBeActive", new StringBuilder()
168 .append("enabled=").append(isEnabled() ? 1 : 0)
169 .append(" mScreenOn=").append(mScreenOn ? 1 : 0)
170 .append(" mState=").append(StatusBarState.toShortString(mState))
Dave Mankoffb32ba472019-07-16 15:07:01 -0400171 .append(" mShowingAod=").append(mShowingAod ? 1 : 0)
Adrian Roos401caae2016-03-04 13:35:21 -0800172 .toString()
173 );
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400174 }
Adrian Roose395b5d2017-06-28 16:52:37 +0200175 return isEnabled() && mScreenOn && (mState == StatusBarState.KEYGUARD) && !mShowingAod;
Adrian Roosc5584ce2016-02-24 14:17:19 -0800176 }
177
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700178 private boolean sessionEntrypoint() {
Adrian Roosc5584ce2016-02-24 14:17:19 -0800179 if (!mSessionActive && shouldSessionBeActive()) {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700180 onSessionStart();
181 return true;
182 }
183 return false;
184 }
185
Adrian Roosc5584ce2016-02-24 14:17:19 -0800186 private void sessionExitpoint(boolean force) {
187 if (mSessionActive && (force || !shouldSessionBeActive())) {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700188 mSessionActive = false;
Dave Mankoff63c576e2019-05-01 18:00:01 -0400189 if (mIsFalseTouchCalls != 0) {
190 if (FalsingLog.ENABLED) {
191 FalsingLog.i(
192 "isFalseTouchCalls", "Calls before failure: " + mIsFalseTouchCalls);
193 }
194 mMetricsLogger.histogram(FALSING_REMAIN_LOCKED, mIsFalseTouchCalls);
195 mIsFalseTouchCalls = 0;
196 }
Jorim Jaggie549a8d2017-05-15 02:40:05 +0200197
198 // This can be expensive, and doesn't need to happen on the main thread.
199 mUiOffloadThread.submit(() -> {
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400200 mSensorManager.unregisterListener(mSensorEventListener);
Jorim Jaggie549a8d2017-05-15 02:40:05 +0200201 });
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700202 }
203 }
204
Adrian Roose395b5d2017-06-28 16:52:37 +0200205 public void updateSessionActive() {
206 if (shouldSessionBeActive()) {
207 sessionEntrypoint();
208 } else {
209 sessionExitpoint(false /* force */);
210 }
211 }
212
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700213 private void onSessionStart() {
Adrian Roos401caae2016-03-04 13:35:21 -0800214 if (FalsingLog.ENABLED) {
215 FalsingLog.i("onSessionStart", "classifierEnabled=" + isClassiferEnabled());
Adrian Roos8e291a52016-12-09 16:10:19 -0800216 clearPendingWtf();
Adrian Roos401caae2016-03-04 13:35:21 -0800217 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700218 mBouncerOn = false;
219 mSessionActive = true;
Lucas Dupin7e35d142019-05-08 15:13:36 -0700220 mJustUnlockedWithFace = false;
Dave Mankoff63c576e2019-05-01 18:00:01 -0400221 mIsFalseTouchCalls = 0;
Blazej Magnowski6dc59b42015-09-22 15:14:20 -0700222
223 if (mHumanInteractionClassifier.isEnabled()) {
224 registerSensors(CLASSIFIER_SENSORS);
225 }
Adrian Roos7bb38a92016-07-21 11:44:01 -0700226 if (mDataCollector.isEnabledFull()) {
Blazej Magnowski6dc59b42015-09-22 15:14:20 -0700227 registerSensors(COLLECTOR_SENSORS);
228 }
Selim Cinek1ed50042018-01-18 17:12:32 -0800229 if (mDataCollector.isEnabled()) {
230 mDataCollector.onFalsingSessionStarted();
231 }
Blazej Magnowski6dc59b42015-09-22 15:14:20 -0700232 }
233
234 private void registerSensors(int [] sensors) {
235 for (int sensorType : sensors) {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700236 Sensor s = mSensorManager.getDefaultSensor(sensorType);
237 if (s != null) {
Jorim Jaggie549a8d2017-05-15 02:40:05 +0200238
239 // This can be expensive, and doesn't need to happen on the main thread.
240 mUiOffloadThread.submit(() -> {
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400241 mSensorManager.registerListener(
242 mSensorEventListener, s, SensorManager.SENSOR_DELAY_GAME);
Jorim Jaggie549a8d2017-05-15 02:40:05 +0200243 });
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700244 }
245 }
246 }
247
Blazej Magnowski6dc59b42015-09-22 15:14:20 -0700248 public boolean isClassiferEnabled() {
249 return mHumanInteractionClassifier.isEnabled();
250 }
251
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700252 private boolean isEnabled() {
253 return mHumanInteractionClassifier.isEnabled() || mDataCollector.isEnabled();
254 }
255
Dave Mankoffc88d6222018-10-25 15:31:20 -0400256 public boolean isUnlockingDisabled() {
257 return mDataCollector.isUnlockingDisabled();
258 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700259 /**
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700260 * @return true if the classifier determined that this is not a human interacting with the phone
261 */
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700262 public boolean isFalseTouch() {
Adrian Roos401caae2016-03-04 13:35:21 -0800263 if (FalsingLog.ENABLED) {
Adrian Roos6a04cb12016-03-14 20:21:02 -0700264 // We're getting some false wtfs from touches that happen after the device went
265 // to sleep. Only report missing sessions that happen when the device is interactive.
Adrian Roos8e291a52016-12-09 16:10:19 -0800266 if (!mSessionActive && mContext.getSystemService(PowerManager.class).isInteractive()
267 && mPendingWtf == null) {
268 int enabled = isEnabled() ? 1 : 0;
269 int screenOn = mScreenOn ? 1 : 0;
270 String state = StatusBarState.toShortString(mState);
271 Throwable here = new Throwable("here");
272 FalsingLog.wLogcat("isFalseTouch", new StringBuilder()
Adrian Roos401caae2016-03-04 13:35:21 -0800273 .append("Session is not active, yet there's a query for a false touch.")
Adrian Roos8e291a52016-12-09 16:10:19 -0800274 .append(" enabled=").append(enabled)
275 .append(" mScreenOn=").append(screenOn)
276 .append(" mState=").append(state)
277 .append(". Escalating to WTF if screen does not turn on soon.")
Adrian Roos401caae2016-03-04 13:35:21 -0800278 .toString());
Adrian Roos8e291a52016-12-09 16:10:19 -0800279
280 // Unfortunately we're also getting false positives for touches that happen right
281 // after the screen turns on, but before that notification has made it to us.
282 // Unfortunately there's no good way to catch that, except to wait and see if we get
283 // the screen on notification soon.
284 mPendingWtf = () -> FalsingLog.wtf("isFalseTouch", new StringBuilder()
285 .append("Session did not become active after query for a false touch.")
286 .append(" enabled=").append(enabled)
287 .append('/').append(isEnabled() ? 1 : 0)
288 .append(" mScreenOn=").append(screenOn)
289 .append('/').append(mScreenOn ? 1 : 0)
290 .append(" mState=").append(state)
291 .append('/').append(StatusBarState.toShortString(mState))
292 .append(". Look for warnings ~1000ms earlier to see root cause.")
293 .toString(), here);
294 mHandler.postDelayed(mPendingWtf, 1000);
Adrian Roos401caae2016-03-04 13:35:21 -0800295 }
296 }
Adrian Roosca664b92016-04-18 14:40:27 -0700297 if (mAccessibilityManager.isTouchExplorationEnabled()) {
298 // Touch exploration triggers false positives in the classifier and
299 // already sufficiently prevents false unlocks.
300 return false;
301 }
Adrian Roos004437e2017-08-16 11:58:02 +0200302 if (!mIsTouchScreen) {
303 // Unlocking with input devices besides the touchscreen should already be sufficiently
304 // anti-falsed.
305 return false;
306 }
Lucas Dupin7e35d142019-05-08 15:13:36 -0700307 if (mJustUnlockedWithFace) {
308 // Unlocking with face is a strong user presence signal, we can assume the user
309 // is present until the next session starts.
310 return false;
311 }
Dave Mankoff63c576e2019-05-01 18:00:01 -0400312 mIsFalseTouchCalls++;
313 boolean isFalse = mHumanInteractionClassifier.isFalseTouch();
314 if (!isFalse) {
315 if (FalsingLog.ENABLED) {
316 FalsingLog.i("isFalseTouchCalls", "Calls before success: " + mIsFalseTouchCalls);
317 }
318 mMetricsLogger.histogram(FALSING_SUCCESS, mIsFalseTouchCalls);
319 mIsFalseTouchCalls = 0;
320 }
321 return isFalse;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700322 }
323
Adrian Roos8e291a52016-12-09 16:10:19 -0800324 private void clearPendingWtf() {
325 if (mPendingWtf != null) {
326 mHandler.removeCallbacks(mPendingWtf);
327 mPendingWtf = null;
328 }
329 }
330
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700331
332 public boolean shouldEnforceBouncer() {
333 return mEnforceBouncer;
334 }
335
Adrian Roose395b5d2017-06-28 16:52:37 +0200336 public void setShowingAod(boolean showingAod) {
337 mShowingAod = showingAod;
338 updateSessionActive();
339 }
340
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700341 public void onScreenTurningOn() {
Adrian Roos401caae2016-03-04 13:35:21 -0800342 if (FalsingLog.ENABLED) {
343 FalsingLog.i("onScreenTurningOn", new StringBuilder()
344 .append("from=").append(mScreenOn ? 1 : 0)
345 .toString());
Adrian Roos8e291a52016-12-09 16:10:19 -0800346 clearPendingWtf();
Adrian Roos401caae2016-03-04 13:35:21 -0800347 }
Adrian Roosc5584ce2016-02-24 14:17:19 -0800348 mScreenOn = true;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700349 if (sessionEntrypoint()) {
350 mDataCollector.onScreenTurningOn();
351 }
352 }
353
354 public void onScreenOnFromTouch() {
Adrian Roos401caae2016-03-04 13:35:21 -0800355 if (FalsingLog.ENABLED) {
356 FalsingLog.i("onScreenOnFromTouch", new StringBuilder()
357 .append("from=").append(mScreenOn ? 1 : 0)
358 .toString());
359 }
Adrian Roosc5584ce2016-02-24 14:17:19 -0800360 mScreenOn = true;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700361 if (sessionEntrypoint()) {
362 mDataCollector.onScreenOnFromTouch();
363 }
364 }
365
366 public void onScreenOff() {
Adrian Roos401caae2016-03-04 13:35:21 -0800367 if (FalsingLog.ENABLED) {
368 FalsingLog.i("onScreenOff", new StringBuilder()
369 .append("from=").append(mScreenOn ? 1 : 0)
370 .toString());
371 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700372 mDataCollector.onScreenOff();
Adrian Roosc5584ce2016-02-24 14:17:19 -0800373 mScreenOn = false;
374 sessionExitpoint(false /* force */);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700375 }
376
377 public void onSucccessfulUnlock() {
Adrian Roos401caae2016-03-04 13:35:21 -0800378 if (FalsingLog.ENABLED) {
379 FalsingLog.i("onSucccessfulUnlock", "");
380 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700381 mDataCollector.onSucccessfulUnlock();
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700382 }
383
384 public void onBouncerShown() {
Adrian Roos401caae2016-03-04 13:35:21 -0800385 if (FalsingLog.ENABLED) {
386 FalsingLog.i("onBouncerShown", new StringBuilder()
387 .append("from=").append(mBouncerOn ? 1 : 0)
388 .toString());
389 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700390 if (!mBouncerOn) {
391 mBouncerOn = true;
392 mDataCollector.onBouncerShown();
393 }
394 }
395
396 public void onBouncerHidden() {
Adrian Roos401caae2016-03-04 13:35:21 -0800397 if (FalsingLog.ENABLED) {
398 FalsingLog.i("onBouncerHidden", new StringBuilder()
399 .append("from=").append(mBouncerOn ? 1 : 0)
400 .toString());
401 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700402 if (mBouncerOn) {
403 mBouncerOn = false;
404 mDataCollector.onBouncerHidden();
405 }
406 }
407
408 public void onQsDown() {
Adrian Roos401caae2016-03-04 13:35:21 -0800409 if (FalsingLog.ENABLED) {
410 FalsingLog.i("onQsDown", "");
411 }
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700412 mHumanInteractionClassifier.setType(Classifier.QUICK_SETTINGS);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700413 mDataCollector.onQsDown();
414 }
415
416 public void setQsExpanded(boolean expanded) {
417 mDataCollector.setQsExpanded(expanded);
418 }
419
Lucas Dupinbc9aac12018-03-04 20:18:15 -0800420 public void onTrackingStarted(boolean secure) {
Adrian Roos401caae2016-03-04 13:35:21 -0800421 if (FalsingLog.ENABLED) {
422 FalsingLog.i("onTrackingStarted", "");
423 }
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400424 mHumanInteractionClassifier.setType(secure
425 ? Classifier.BOUNCER_UNLOCK : Classifier.UNLOCK);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700426 mDataCollector.onTrackingStarted();
427 }
428
429 public void onTrackingStopped() {
430 mDataCollector.onTrackingStopped();
431 }
432
433 public void onNotificationActive() {
434 mDataCollector.onNotificationActive();
435 }
436
Adrian Roos9f0b0022016-11-09 15:56:50 -0800437 public void onNotificationDoubleTap(boolean accepted, float dx, float dy) {
438 if (FalsingLog.ENABLED) {
439 FalsingLog.i("onNotificationDoubleTap", "accepted=" + accepted
440 + " dx=" + dx + " dy=" + dy + " (px)");
441 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700442 mDataCollector.onNotificationDoubleTap();
443 }
444
445 public void setNotificationExpanded() {
446 mDataCollector.setNotificationExpanded();
447 }
448
449 public void onNotificatonStartDraggingDown() {
Adrian Roos401caae2016-03-04 13:35:21 -0800450 if (FalsingLog.ENABLED) {
451 FalsingLog.i("onNotificatonStartDraggingDown", "");
452 }
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700453 mHumanInteractionClassifier.setType(Classifier.NOTIFICATION_DRAG_DOWN);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700454 mDataCollector.onNotificatonStartDraggingDown();
455 }
456
Selim Cinek3d6ae232019-01-04 14:14:33 -0800457 public void onStartExpandingFromPulse() {
458 if (FalsingLog.ENABLED) {
459 FalsingLog.i("onStartExpandingFromPulse", "");
460 }
461 mHumanInteractionClassifier.setType(Classifier.PULSE_EXPAND);
462 mDataCollector.onStartExpandingFromPulse();
463 }
464
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700465 public void onNotificatonStopDraggingDown() {
466 mDataCollector.onNotificatonStopDraggingDown();
467 }
468
Selim Cinek3d6ae232019-01-04 14:14:33 -0800469 public void onExpansionFromPulseStopped() {
470 mDataCollector.onExpansionFromPulseStopped();
471 }
472
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700473 public void onNotificationDismissed() {
474 mDataCollector.onNotificationDismissed();
475 }
476
477 public void onNotificatonStartDismissing() {
Adrian Roos401caae2016-03-04 13:35:21 -0800478 if (FalsingLog.ENABLED) {
479 FalsingLog.i("onNotificatonStartDismissing", "");
480 }
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700481 mHumanInteractionClassifier.setType(Classifier.NOTIFICATION_DISMISS);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700482 mDataCollector.onNotificatonStartDismissing();
483 }
484
485 public void onNotificatonStopDismissing() {
486 mDataCollector.onNotificatonStopDismissing();
487 }
488
489 public void onCameraOn() {
490 mDataCollector.onCameraOn();
491 }
492
493 public void onLeftAffordanceOn() {
494 mDataCollector.onLeftAffordanceOn();
495 }
496
497 public void onAffordanceSwipingStarted(boolean rightCorner) {
Adrian Roos401caae2016-03-04 13:35:21 -0800498 if (FalsingLog.ENABLED) {
499 FalsingLog.i("onAffordanceSwipingStarted", "");
500 }
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700501 if (rightCorner) {
502 mHumanInteractionClassifier.setType(Classifier.RIGHT_AFFORDANCE);
503 } else {
504 mHumanInteractionClassifier.setType(Classifier.LEFT_AFFORDANCE);
505 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700506 mDataCollector.onAffordanceSwipingStarted(rightCorner);
507 }
508
509 public void onAffordanceSwipingAborted() {
510 mDataCollector.onAffordanceSwipingAborted();
511 }
512
513 public void onUnlockHintStarted() {
514 mDataCollector.onUnlockHintStarted();
515 }
516
517 public void onCameraHintStarted() {
518 mDataCollector.onCameraHintStarted();
519 }
520
521 public void onLeftAffordanceHintStarted() {
522 mDataCollector.onLeftAffordanceHintStarted();
523 }
524
525 public void onTouchEvent(MotionEvent event, int width, int height) {
Adrian Roos004437e2017-08-16 11:58:02 +0200526 if (event.getAction() == MotionEvent.ACTION_DOWN) {
527 mIsTouchScreen = event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN);
Siarhei Vishniakou81e1ffd2018-05-04 16:08:22 -0700528 // If the bouncer was not shown during the down event,
529 // we want the entire gesture going to HumanInteractionClassifier
530 mBouncerOffOnDown = !mBouncerOn;
Adrian Roos004437e2017-08-16 11:58:02 +0200531 }
Siarhei Vishniakou81e1ffd2018-05-04 16:08:22 -0700532 if (mSessionActive) {
533 if (!mBouncerOn) {
534 // In case bouncer is "visible", but onFullyShown has not yet been called,
535 // avoid adding the event to DataCollector
536 mDataCollector.onTouchEvent(event, width, height);
537 }
538 if (mBouncerOffOnDown) {
539 mHumanInteractionClassifier.onTouchEvent(event);
540 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700541 }
542 }
Adrian Roos401caae2016-03-04 13:35:21 -0800543
544 public void dump(PrintWriter pw) {
545 pw.println("FALSING MANAGER");
546 pw.print("classifierEnabled="); pw.println(isClassiferEnabled() ? 1 : 0);
547 pw.print("mSessionActive="); pw.println(mSessionActive ? 1 : 0);
548 pw.print("mBouncerOn="); pw.println(mSessionActive ? 1 : 0);
549 pw.print("mState="); pw.println(StatusBarState.toShortString(mState));
550 pw.print("mScreenOn="); pw.println(mScreenOn ? 1 : 0);
551 pw.println();
552 }
Adrian Roos7bb38a92016-07-21 11:44:01 -0700553
Dave Mankoffb32ba472019-07-16 15:07:01 -0400554 @Override
555 public void cleanup() {
556 mSensorManager.unregisterListener(mSensorEventListener);
557 mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
558 Dependency.get(StatusBarStateController.class).removeCallback(mStatusBarStateListener);
Dave Mankoffe2294692019-08-14 11:53:13 -0400559 Dependency.get(KeyguardUpdateMonitor.class).removeCallback(mKeyguardUpdateCallback);
Dave Mankoffb32ba472019-07-16 15:07:01 -0400560 }
561
Adrian Roos7bb38a92016-07-21 11:44:01 -0700562 public Uri reportRejectedTouch() {
563 if (mDataCollector.isEnabled()) {
564 return mDataCollector.reportRejectedTouch();
565 }
566 return null;
567 }
568
569 public boolean isReportingEnabled() {
570 return mDataCollector.isReportingEnabled();
571 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700572}