blob: 67dfdcac4b22c43ac240dc26168312a48937a39b [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;
Adrian Roos7a8ae8a2017-08-02 16:26:50 +020046import com.android.systemui.util.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);
Lucas Dupin7e35d142019-05-08 15:13:36 -0700157 KeyguardUpdateMonitor.getInstance(context).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))
171 .toString()
172 );
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400173 }
Adrian Roose395b5d2017-06-28 16:52:37 +0200174 return isEnabled() && mScreenOn && (mState == StatusBarState.KEYGUARD) && !mShowingAod;
Adrian Roosc5584ce2016-02-24 14:17:19 -0800175 }
176
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700177 private boolean sessionEntrypoint() {
Adrian Roosc5584ce2016-02-24 14:17:19 -0800178 if (!mSessionActive && shouldSessionBeActive()) {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700179 onSessionStart();
180 return true;
181 }
182 return false;
183 }
184
Adrian Roosc5584ce2016-02-24 14:17:19 -0800185 private void sessionExitpoint(boolean force) {
186 if (mSessionActive && (force || !shouldSessionBeActive())) {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700187 mSessionActive = false;
Dave Mankoff63c576e2019-05-01 18:00:01 -0400188 if (mIsFalseTouchCalls != 0) {
189 if (FalsingLog.ENABLED) {
190 FalsingLog.i(
191 "isFalseTouchCalls", "Calls before failure: " + mIsFalseTouchCalls);
192 }
193 mMetricsLogger.histogram(FALSING_REMAIN_LOCKED, mIsFalseTouchCalls);
194 mIsFalseTouchCalls = 0;
195 }
Jorim Jaggie549a8d2017-05-15 02:40:05 +0200196
197 // This can be expensive, and doesn't need to happen on the main thread.
198 mUiOffloadThread.submit(() -> {
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400199 mSensorManager.unregisterListener(mSensorEventListener);
Jorim Jaggie549a8d2017-05-15 02:40:05 +0200200 });
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700201 }
202 }
203
Adrian Roose395b5d2017-06-28 16:52:37 +0200204 public void updateSessionActive() {
205 if (shouldSessionBeActive()) {
206 sessionEntrypoint();
207 } else {
208 sessionExitpoint(false /* force */);
209 }
210 }
211
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700212 private void onSessionStart() {
Adrian Roos401caae2016-03-04 13:35:21 -0800213 if (FalsingLog.ENABLED) {
214 FalsingLog.i("onSessionStart", "classifierEnabled=" + isClassiferEnabled());
Adrian Roos8e291a52016-12-09 16:10:19 -0800215 clearPendingWtf();
Adrian Roos401caae2016-03-04 13:35:21 -0800216 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700217 mBouncerOn = false;
218 mSessionActive = true;
Lucas Dupin7e35d142019-05-08 15:13:36 -0700219 mJustUnlockedWithFace = false;
Dave Mankoff63c576e2019-05-01 18:00:01 -0400220 mIsFalseTouchCalls = 0;
Blazej Magnowski6dc59b42015-09-22 15:14:20 -0700221
222 if (mHumanInteractionClassifier.isEnabled()) {
223 registerSensors(CLASSIFIER_SENSORS);
224 }
Adrian Roos7bb38a92016-07-21 11:44:01 -0700225 if (mDataCollector.isEnabledFull()) {
Blazej Magnowski6dc59b42015-09-22 15:14:20 -0700226 registerSensors(COLLECTOR_SENSORS);
227 }
Selim Cinek1ed50042018-01-18 17:12:32 -0800228 if (mDataCollector.isEnabled()) {
229 mDataCollector.onFalsingSessionStarted();
230 }
Blazej Magnowski6dc59b42015-09-22 15:14:20 -0700231 }
232
233 private void registerSensors(int [] sensors) {
234 for (int sensorType : sensors) {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700235 Sensor s = mSensorManager.getDefaultSensor(sensorType);
236 if (s != null) {
Jorim Jaggie549a8d2017-05-15 02:40:05 +0200237
238 // This can be expensive, and doesn't need to happen on the main thread.
239 mUiOffloadThread.submit(() -> {
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400240 mSensorManager.registerListener(
241 mSensorEventListener, s, SensorManager.SENSOR_DELAY_GAME);
Jorim Jaggie549a8d2017-05-15 02:40:05 +0200242 });
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700243 }
244 }
245 }
246
Blazej Magnowski6dc59b42015-09-22 15:14:20 -0700247 public boolean isClassiferEnabled() {
248 return mHumanInteractionClassifier.isEnabled();
249 }
250
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700251 private boolean isEnabled() {
252 return mHumanInteractionClassifier.isEnabled() || mDataCollector.isEnabled();
253 }
254
Dave Mankoffc88d6222018-10-25 15:31:20 -0400255 public boolean isUnlockingDisabled() {
256 return mDataCollector.isUnlockingDisabled();
257 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700258 /**
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700259 * @return true if the classifier determined that this is not a human interacting with the phone
260 */
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700261 public boolean isFalseTouch() {
Adrian Roos401caae2016-03-04 13:35:21 -0800262 if (FalsingLog.ENABLED) {
Adrian Roos6a04cb12016-03-14 20:21:02 -0700263 // We're getting some false wtfs from touches that happen after the device went
264 // to sleep. Only report missing sessions that happen when the device is interactive.
Adrian Roos8e291a52016-12-09 16:10:19 -0800265 if (!mSessionActive && mContext.getSystemService(PowerManager.class).isInteractive()
266 && mPendingWtf == null) {
267 int enabled = isEnabled() ? 1 : 0;
268 int screenOn = mScreenOn ? 1 : 0;
269 String state = StatusBarState.toShortString(mState);
270 Throwable here = new Throwable("here");
271 FalsingLog.wLogcat("isFalseTouch", new StringBuilder()
Adrian Roos401caae2016-03-04 13:35:21 -0800272 .append("Session is not active, yet there's a query for a false touch.")
Adrian Roos8e291a52016-12-09 16:10:19 -0800273 .append(" enabled=").append(enabled)
274 .append(" mScreenOn=").append(screenOn)
275 .append(" mState=").append(state)
276 .append(". Escalating to WTF if screen does not turn on soon.")
Adrian Roos401caae2016-03-04 13:35:21 -0800277 .toString());
Adrian Roos8e291a52016-12-09 16:10:19 -0800278
279 // Unfortunately we're also getting false positives for touches that happen right
280 // after the screen turns on, but before that notification has made it to us.
281 // Unfortunately there's no good way to catch that, except to wait and see if we get
282 // the screen on notification soon.
283 mPendingWtf = () -> FalsingLog.wtf("isFalseTouch", new StringBuilder()
284 .append("Session did not become active after query for a false touch.")
285 .append(" enabled=").append(enabled)
286 .append('/').append(isEnabled() ? 1 : 0)
287 .append(" mScreenOn=").append(screenOn)
288 .append('/').append(mScreenOn ? 1 : 0)
289 .append(" mState=").append(state)
290 .append('/').append(StatusBarState.toShortString(mState))
291 .append(". Look for warnings ~1000ms earlier to see root cause.")
292 .toString(), here);
293 mHandler.postDelayed(mPendingWtf, 1000);
Adrian Roos401caae2016-03-04 13:35:21 -0800294 }
295 }
Adrian Roosca664b92016-04-18 14:40:27 -0700296 if (mAccessibilityManager.isTouchExplorationEnabled()) {
297 // Touch exploration triggers false positives in the classifier and
298 // already sufficiently prevents false unlocks.
299 return false;
300 }
Adrian Roos004437e2017-08-16 11:58:02 +0200301 if (!mIsTouchScreen) {
302 // Unlocking with input devices besides the touchscreen should already be sufficiently
303 // anti-falsed.
304 return false;
305 }
Lucas Dupin7e35d142019-05-08 15:13:36 -0700306 if (mJustUnlockedWithFace) {
307 // Unlocking with face is a strong user presence signal, we can assume the user
308 // is present until the next session starts.
309 return false;
310 }
Dave Mankoff63c576e2019-05-01 18:00:01 -0400311 mIsFalseTouchCalls++;
312 boolean isFalse = mHumanInteractionClassifier.isFalseTouch();
313 if (!isFalse) {
314 if (FalsingLog.ENABLED) {
315 FalsingLog.i("isFalseTouchCalls", "Calls before success: " + mIsFalseTouchCalls);
316 }
317 mMetricsLogger.histogram(FALSING_SUCCESS, mIsFalseTouchCalls);
318 mIsFalseTouchCalls = 0;
319 }
320 return isFalse;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700321 }
322
Adrian Roos8e291a52016-12-09 16:10:19 -0800323 private void clearPendingWtf() {
324 if (mPendingWtf != null) {
325 mHandler.removeCallbacks(mPendingWtf);
326 mPendingWtf = null;
327 }
328 }
329
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700330
331 public boolean shouldEnforceBouncer() {
332 return mEnforceBouncer;
333 }
334
Adrian Roose395b5d2017-06-28 16:52:37 +0200335 public void setShowingAod(boolean showingAod) {
336 mShowingAod = showingAod;
337 updateSessionActive();
338 }
339
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700340 public void onScreenTurningOn() {
Adrian Roos401caae2016-03-04 13:35:21 -0800341 if (FalsingLog.ENABLED) {
342 FalsingLog.i("onScreenTurningOn", new StringBuilder()
343 .append("from=").append(mScreenOn ? 1 : 0)
344 .toString());
Adrian Roos8e291a52016-12-09 16:10:19 -0800345 clearPendingWtf();
Adrian Roos401caae2016-03-04 13:35:21 -0800346 }
Adrian Roosc5584ce2016-02-24 14:17:19 -0800347 mScreenOn = true;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700348 if (sessionEntrypoint()) {
349 mDataCollector.onScreenTurningOn();
350 }
351 }
352
353 public void onScreenOnFromTouch() {
Adrian Roos401caae2016-03-04 13:35:21 -0800354 if (FalsingLog.ENABLED) {
355 FalsingLog.i("onScreenOnFromTouch", new StringBuilder()
356 .append("from=").append(mScreenOn ? 1 : 0)
357 .toString());
358 }
Adrian Roosc5584ce2016-02-24 14:17:19 -0800359 mScreenOn = true;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700360 if (sessionEntrypoint()) {
361 mDataCollector.onScreenOnFromTouch();
362 }
363 }
364
365 public void onScreenOff() {
Adrian Roos401caae2016-03-04 13:35:21 -0800366 if (FalsingLog.ENABLED) {
367 FalsingLog.i("onScreenOff", new StringBuilder()
368 .append("from=").append(mScreenOn ? 1 : 0)
369 .toString());
370 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700371 mDataCollector.onScreenOff();
Adrian Roosc5584ce2016-02-24 14:17:19 -0800372 mScreenOn = false;
373 sessionExitpoint(false /* force */);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700374 }
375
376 public void onSucccessfulUnlock() {
Adrian Roos401caae2016-03-04 13:35:21 -0800377 if (FalsingLog.ENABLED) {
378 FalsingLog.i("onSucccessfulUnlock", "");
379 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700380 mDataCollector.onSucccessfulUnlock();
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700381 }
382
383 public void onBouncerShown() {
Adrian Roos401caae2016-03-04 13:35:21 -0800384 if (FalsingLog.ENABLED) {
385 FalsingLog.i("onBouncerShown", new StringBuilder()
386 .append("from=").append(mBouncerOn ? 1 : 0)
387 .toString());
388 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700389 if (!mBouncerOn) {
390 mBouncerOn = true;
391 mDataCollector.onBouncerShown();
392 }
393 }
394
395 public void onBouncerHidden() {
Adrian Roos401caae2016-03-04 13:35:21 -0800396 if (FalsingLog.ENABLED) {
397 FalsingLog.i("onBouncerHidden", new StringBuilder()
398 .append("from=").append(mBouncerOn ? 1 : 0)
399 .toString());
400 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700401 if (mBouncerOn) {
402 mBouncerOn = false;
403 mDataCollector.onBouncerHidden();
404 }
405 }
406
407 public void onQsDown() {
Adrian Roos401caae2016-03-04 13:35:21 -0800408 if (FalsingLog.ENABLED) {
409 FalsingLog.i("onQsDown", "");
410 }
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700411 mHumanInteractionClassifier.setType(Classifier.QUICK_SETTINGS);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700412 mDataCollector.onQsDown();
413 }
414
415 public void setQsExpanded(boolean expanded) {
416 mDataCollector.setQsExpanded(expanded);
417 }
418
Lucas Dupinbc9aac12018-03-04 20:18:15 -0800419 public void onTrackingStarted(boolean secure) {
Adrian Roos401caae2016-03-04 13:35:21 -0800420 if (FalsingLog.ENABLED) {
421 FalsingLog.i("onTrackingStarted", "");
422 }
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400423 mHumanInteractionClassifier.setType(secure
424 ? Classifier.BOUNCER_UNLOCK : Classifier.UNLOCK);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700425 mDataCollector.onTrackingStarted();
426 }
427
428 public void onTrackingStopped() {
429 mDataCollector.onTrackingStopped();
430 }
431
432 public void onNotificationActive() {
433 mDataCollector.onNotificationActive();
434 }
435
Adrian Roos9f0b0022016-11-09 15:56:50 -0800436 public void onNotificationDoubleTap(boolean accepted, float dx, float dy) {
437 if (FalsingLog.ENABLED) {
438 FalsingLog.i("onNotificationDoubleTap", "accepted=" + accepted
439 + " dx=" + dx + " dy=" + dy + " (px)");
440 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700441 mDataCollector.onNotificationDoubleTap();
442 }
443
444 public void setNotificationExpanded() {
445 mDataCollector.setNotificationExpanded();
446 }
447
448 public void onNotificatonStartDraggingDown() {
Adrian Roos401caae2016-03-04 13:35:21 -0800449 if (FalsingLog.ENABLED) {
450 FalsingLog.i("onNotificatonStartDraggingDown", "");
451 }
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700452 mHumanInteractionClassifier.setType(Classifier.NOTIFICATION_DRAG_DOWN);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700453 mDataCollector.onNotificatonStartDraggingDown();
454 }
455
Selim Cinek3d6ae232019-01-04 14:14:33 -0800456 public void onStartExpandingFromPulse() {
457 if (FalsingLog.ENABLED) {
458 FalsingLog.i("onStartExpandingFromPulse", "");
459 }
460 mHumanInteractionClassifier.setType(Classifier.PULSE_EXPAND);
461 mDataCollector.onStartExpandingFromPulse();
462 }
463
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700464 public void onNotificatonStopDraggingDown() {
465 mDataCollector.onNotificatonStopDraggingDown();
466 }
467
Selim Cinek3d6ae232019-01-04 14:14:33 -0800468 public void onExpansionFromPulseStopped() {
469 mDataCollector.onExpansionFromPulseStopped();
470 }
471
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700472 public void onNotificationDismissed() {
473 mDataCollector.onNotificationDismissed();
474 }
475
476 public void onNotificatonStartDismissing() {
Adrian Roos401caae2016-03-04 13:35:21 -0800477 if (FalsingLog.ENABLED) {
478 FalsingLog.i("onNotificatonStartDismissing", "");
479 }
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700480 mHumanInteractionClassifier.setType(Classifier.NOTIFICATION_DISMISS);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700481 mDataCollector.onNotificatonStartDismissing();
482 }
483
484 public void onNotificatonStopDismissing() {
485 mDataCollector.onNotificatonStopDismissing();
486 }
487
488 public void onCameraOn() {
489 mDataCollector.onCameraOn();
490 }
491
492 public void onLeftAffordanceOn() {
493 mDataCollector.onLeftAffordanceOn();
494 }
495
496 public void onAffordanceSwipingStarted(boolean rightCorner) {
Adrian Roos401caae2016-03-04 13:35:21 -0800497 if (FalsingLog.ENABLED) {
498 FalsingLog.i("onAffordanceSwipingStarted", "");
499 }
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700500 if (rightCorner) {
501 mHumanInteractionClassifier.setType(Classifier.RIGHT_AFFORDANCE);
502 } else {
503 mHumanInteractionClassifier.setType(Classifier.LEFT_AFFORDANCE);
504 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700505 mDataCollector.onAffordanceSwipingStarted(rightCorner);
506 }
507
508 public void onAffordanceSwipingAborted() {
509 mDataCollector.onAffordanceSwipingAborted();
510 }
511
512 public void onUnlockHintStarted() {
513 mDataCollector.onUnlockHintStarted();
514 }
515
516 public void onCameraHintStarted() {
517 mDataCollector.onCameraHintStarted();
518 }
519
520 public void onLeftAffordanceHintStarted() {
521 mDataCollector.onLeftAffordanceHintStarted();
522 }
523
524 public void onTouchEvent(MotionEvent event, int width, int height) {
Adrian Roos004437e2017-08-16 11:58:02 +0200525 if (event.getAction() == MotionEvent.ACTION_DOWN) {
526 mIsTouchScreen = event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN);
Siarhei Vishniakou81e1ffd2018-05-04 16:08:22 -0700527 // If the bouncer was not shown during the down event,
528 // we want the entire gesture going to HumanInteractionClassifier
529 mBouncerOffOnDown = !mBouncerOn;
Adrian Roos004437e2017-08-16 11:58:02 +0200530 }
Siarhei Vishniakou81e1ffd2018-05-04 16:08:22 -0700531 if (mSessionActive) {
532 if (!mBouncerOn) {
533 // In case bouncer is "visible", but onFullyShown has not yet been called,
534 // avoid adding the event to DataCollector
535 mDataCollector.onTouchEvent(event, width, height);
536 }
537 if (mBouncerOffOnDown) {
538 mHumanInteractionClassifier.onTouchEvent(event);
539 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700540 }
541 }
Adrian Roos401caae2016-03-04 13:35:21 -0800542
543 public void dump(PrintWriter pw) {
544 pw.println("FALSING MANAGER");
545 pw.print("classifierEnabled="); pw.println(isClassiferEnabled() ? 1 : 0);
546 pw.print("mSessionActive="); pw.println(mSessionActive ? 1 : 0);
547 pw.print("mBouncerOn="); pw.println(mSessionActive ? 1 : 0);
548 pw.print("mState="); pw.println(StatusBarState.toShortString(mState));
549 pw.print("mScreenOn="); pw.println(mScreenOn ? 1 : 0);
550 pw.println();
551 }
Adrian Roos7bb38a92016-07-21 11:44:01 -0700552
553 public Uri reportRejectedTouch() {
554 if (mDataCollector.isEnabled()) {
555 return mDataCollector.reportRejectedTouch();
556 }
557 return null;
558 }
559
560 public boolean isReportingEnabled() {
561 return mDataCollector.isReportingEnabled();
562 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700563}