blob: a4bd24416f614573413028a63718cb037eb6f216 [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;
Beverly8fdb5332019-02-04 14:29:49 -050042import com.android.systemui.plugins.statusbar.StatusBarStateController;
43import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070044import com.android.systemui.statusbar.StatusBarState;
Adrian Roos7a8ae8a2017-08-02 16:26:50 +020045import com.android.systemui.util.AsyncSensorManager;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070046
Adrian Roos401caae2016-03-04 13:35:21 -080047import java.io.PrintWriter;
48
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070049/**
50 * When the phone is locked, listens to touch, sensor and phone events and sends them to
51 * DataCollector and HumanInteractionClassifier.
52 *
53 * It does not collect touch events when the bouncer shows up.
54 */
Dave Mankoffdde5ee62019-05-02 17:36:11 -040055public class FalsingManagerImpl implements FalsingManagerFactory.FalsingManager {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070056 private static final String ENFORCE_BOUNCER = "falsing_manager_enforce_bouncer";
57
Blazej Magnowski6dc59b42015-09-22 15:14:20 -070058 private static final int[] CLASSIFIER_SENSORS = new int[] {
59 Sensor.TYPE_PROXIMITY,
60 };
61
62 private static final int[] COLLECTOR_SENSORS = new int[] {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070063 Sensor.TYPE_ACCELEROMETER,
64 Sensor.TYPE_GYROSCOPE,
65 Sensor.TYPE_PROXIMITY,
66 Sensor.TYPE_LIGHT,
67 Sensor.TYPE_ROTATION_VECTOR,
68 };
Dave Mankoff63c576e2019-05-01 18:00:01 -040069 private static final String FALSING_REMAIN_LOCKED = "falsing_failure_after_attempts";
70 private static final String FALSING_SUCCESS = "falsing_success_after_attempts";
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070071
Selim Cinekf8c4add2017-06-08 09:54:58 -070072 private final Handler mHandler = new Handler(Looper.getMainLooper());
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070073 private final Context mContext;
74
75 private final SensorManager mSensorManager;
76 private final DataCollector mDataCollector;
77 private final HumanInteractionClassifier mHumanInteractionClassifier;
Adrian Roosca664b92016-04-18 14:40:27 -070078 private final AccessibilityManager mAccessibilityManager;
Jorim Jaggie549a8d2017-05-15 02:40:05 +020079 private final UiOffloadThread mUiOffloadThread;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070080
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070081 private boolean mEnforceBouncer = false;
82 private boolean mBouncerOn = false;
Siarhei Vishniakou81e1ffd2018-05-04 16:08:22 -070083 private boolean mBouncerOffOnDown = false;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070084 private boolean mSessionActive = false;
Adrian Roos004437e2017-08-16 11:58:02 +020085 private boolean mIsTouchScreen = true;
Lucas Dupin7e35d142019-05-08 15:13:36 -070086 private boolean mJustUnlockedWithFace = false;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070087 private int mState = StatusBarState.SHADE;
Adrian Roosc5584ce2016-02-24 14:17:19 -080088 private boolean mScreenOn;
Adrian Roose395b5d2017-06-28 16:52:37 +020089 private boolean mShowingAod;
Adrian Roos8e291a52016-12-09 16:10:19 -080090 private Runnable mPendingWtf;
Dave Mankoff63c576e2019-05-01 18:00:01 -040091 private int mIsFalseTouchCalls;
92 private MetricsLogger mMetricsLogger;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -070093
Dave Mankoffdde5ee62019-05-02 17:36:11 -040094 private SensorEventListener mSensorEventListener = new SensorEventListener() {
95 @Override
96 public synchronized void onSensorChanged(SensorEvent event) {
97 mDataCollector.onSensorChanged(event);
98 mHumanInteractionClassifier.onSensorChanged(event);
99 }
100
101 @Override
102 public void onAccuracyChanged(Sensor sensor, int accuracy) {
103 mDataCollector.onAccuracyChanged(sensor, accuracy);
104 }
105 };
106
107 public StateListener mStatusBarStateListener = new StateListener() {
108 @Override
109 public void onStateChanged(int newState) {
110 if (FalsingLog.ENABLED) {
111 FalsingLog.i("setStatusBarState", new StringBuilder()
112 .append("from=").append(StatusBarState.toShortString(mState))
113 .append(" to=").append(StatusBarState.toShortString(newState))
114 .toString());
115 }
116 mState = newState;
117 updateSessionActive();
118 }
119 };
120
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700121 protected final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
122 @Override
123 public void onChange(boolean selfChange) {
124 updateConfiguration();
125 }
126 };
Lucas Dupin7e35d142019-05-08 15:13:36 -0700127 private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
128 new KeyguardUpdateMonitorCallback() {
129 @Override
130 public void onBiometricAuthenticated(int userId,
131 BiometricSourceType biometricSourceType) {
132 if (userId == KeyguardUpdateMonitor.getCurrentUser()
133 && biometricSourceType == BiometricSourceType.FACE) {
134 mJustUnlockedWithFace = true;
135 }
136 }
137 };
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700138
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400139 FalsingManagerImpl(Context context) {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700140 mContext = context;
Adrian Roos7a8ae8a2017-08-02 16:26:50 +0200141 mSensorManager = Dependency.get(AsyncSensorManager.class);
Adrian Roosca664b92016-04-18 14:40:27 -0700142 mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700143 mDataCollector = DataCollector.getInstance(mContext);
144 mHumanInteractionClassifier = HumanInteractionClassifier.getInstance(mContext);
Jorim Jaggie549a8d2017-05-15 02:40:05 +0200145 mUiOffloadThread = Dependency.get(UiOffloadThread.class);
Adrian Roosc5584ce2016-02-24 14:17:19 -0800146 mScreenOn = context.getSystemService(PowerManager.class).isInteractive();
Dave Mankoff63c576e2019-05-01 18:00:01 -0400147 mMetricsLogger = new MetricsLogger();
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700148
149 mContext.getContentResolver().registerContentObserver(
150 Settings.Secure.getUriFor(ENFORCE_BOUNCER), false,
151 mSettingsObserver,
152 UserHandle.USER_ALL);
153
154 updateConfiguration();
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400155 Dependency.get(StatusBarStateController.class).addCallback(mStatusBarStateListener);
Lucas Dupin7e35d142019-05-08 15:13:36 -0700156 KeyguardUpdateMonitor.getInstance(context).registerCallback(mKeyguardUpdateCallback);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700157 }
158
159 private void updateConfiguration() {
160 mEnforceBouncer = 0 != Settings.Secure.getInt(mContext.getContentResolver(),
161 ENFORCE_BOUNCER, 0);
162 }
163
Adrian Roosc5584ce2016-02-24 14:17:19 -0800164 private boolean shouldSessionBeActive() {
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400165 if (FalsingLog.ENABLED && FalsingLog.VERBOSE) {
Adrian Roos401caae2016-03-04 13:35:21 -0800166 FalsingLog.v("shouldBeActive", new StringBuilder()
167 .append("enabled=").append(isEnabled() ? 1 : 0)
168 .append(" mScreenOn=").append(mScreenOn ? 1 : 0)
169 .append(" mState=").append(StatusBarState.toShortString(mState))
170 .toString()
171 );
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400172 }
Adrian Roose395b5d2017-06-28 16:52:37 +0200173 return isEnabled() && mScreenOn && (mState == StatusBarState.KEYGUARD) && !mShowingAod;
Adrian Roosc5584ce2016-02-24 14:17:19 -0800174 }
175
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700176 private boolean sessionEntrypoint() {
Adrian Roosc5584ce2016-02-24 14:17:19 -0800177 if (!mSessionActive && shouldSessionBeActive()) {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700178 onSessionStart();
179 return true;
180 }
181 return false;
182 }
183
Adrian Roosc5584ce2016-02-24 14:17:19 -0800184 private void sessionExitpoint(boolean force) {
185 if (mSessionActive && (force || !shouldSessionBeActive())) {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700186 mSessionActive = false;
Dave Mankoff63c576e2019-05-01 18:00:01 -0400187 if (mIsFalseTouchCalls != 0) {
188 if (FalsingLog.ENABLED) {
189 FalsingLog.i(
190 "isFalseTouchCalls", "Calls before failure: " + mIsFalseTouchCalls);
191 }
192 mMetricsLogger.histogram(FALSING_REMAIN_LOCKED, mIsFalseTouchCalls);
193 mIsFalseTouchCalls = 0;
194 }
Jorim Jaggie549a8d2017-05-15 02:40:05 +0200195
196 // This can be expensive, and doesn't need to happen on the main thread.
197 mUiOffloadThread.submit(() -> {
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400198 mSensorManager.unregisterListener(mSensorEventListener);
Jorim Jaggie549a8d2017-05-15 02:40:05 +0200199 });
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700200 }
201 }
202
Adrian Roose395b5d2017-06-28 16:52:37 +0200203 public void updateSessionActive() {
204 if (shouldSessionBeActive()) {
205 sessionEntrypoint();
206 } else {
207 sessionExitpoint(false /* force */);
208 }
209 }
210
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700211 private void onSessionStart() {
Adrian Roos401caae2016-03-04 13:35:21 -0800212 if (FalsingLog.ENABLED) {
213 FalsingLog.i("onSessionStart", "classifierEnabled=" + isClassiferEnabled());
Adrian Roos8e291a52016-12-09 16:10:19 -0800214 clearPendingWtf();
Adrian Roos401caae2016-03-04 13:35:21 -0800215 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700216 mBouncerOn = false;
217 mSessionActive = true;
Lucas Dupin7e35d142019-05-08 15:13:36 -0700218 mJustUnlockedWithFace = false;
Dave Mankoff63c576e2019-05-01 18:00:01 -0400219 mIsFalseTouchCalls = 0;
Blazej Magnowski6dc59b42015-09-22 15:14:20 -0700220
221 if (mHumanInteractionClassifier.isEnabled()) {
222 registerSensors(CLASSIFIER_SENSORS);
223 }
Adrian Roos7bb38a92016-07-21 11:44:01 -0700224 if (mDataCollector.isEnabledFull()) {
Blazej Magnowski6dc59b42015-09-22 15:14:20 -0700225 registerSensors(COLLECTOR_SENSORS);
226 }
Selim Cinek1ed50042018-01-18 17:12:32 -0800227 if (mDataCollector.isEnabled()) {
228 mDataCollector.onFalsingSessionStarted();
229 }
Blazej Magnowski6dc59b42015-09-22 15:14:20 -0700230 }
231
232 private void registerSensors(int [] sensors) {
233 for (int sensorType : sensors) {
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700234 Sensor s = mSensorManager.getDefaultSensor(sensorType);
235 if (s != null) {
Jorim Jaggie549a8d2017-05-15 02:40:05 +0200236
237 // This can be expensive, and doesn't need to happen on the main thread.
238 mUiOffloadThread.submit(() -> {
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400239 mSensorManager.registerListener(
240 mSensorEventListener, s, SensorManager.SENSOR_DELAY_GAME);
Jorim Jaggie549a8d2017-05-15 02:40:05 +0200241 });
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700242 }
243 }
244 }
245
Blazej Magnowski6dc59b42015-09-22 15:14:20 -0700246 public boolean isClassiferEnabled() {
247 return mHumanInteractionClassifier.isEnabled();
248 }
249
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700250 private boolean isEnabled() {
251 return mHumanInteractionClassifier.isEnabled() || mDataCollector.isEnabled();
252 }
253
Dave Mankoffc88d6222018-10-25 15:31:20 -0400254 public boolean isUnlockingDisabled() {
255 return mDataCollector.isUnlockingDisabled();
256 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700257 /**
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700258 * @return true if the classifier determined that this is not a human interacting with the phone
259 */
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700260 public boolean isFalseTouch() {
Adrian Roos401caae2016-03-04 13:35:21 -0800261 if (FalsingLog.ENABLED) {
Adrian Roos6a04cb12016-03-14 20:21:02 -0700262 // We're getting some false wtfs from touches that happen after the device went
263 // to sleep. Only report missing sessions that happen when the device is interactive.
Adrian Roos8e291a52016-12-09 16:10:19 -0800264 if (!mSessionActive && mContext.getSystemService(PowerManager.class).isInteractive()
265 && mPendingWtf == null) {
266 int enabled = isEnabled() ? 1 : 0;
267 int screenOn = mScreenOn ? 1 : 0;
268 String state = StatusBarState.toShortString(mState);
269 Throwable here = new Throwable("here");
270 FalsingLog.wLogcat("isFalseTouch", new StringBuilder()
Adrian Roos401caae2016-03-04 13:35:21 -0800271 .append("Session is not active, yet there's a query for a false touch.")
Adrian Roos8e291a52016-12-09 16:10:19 -0800272 .append(" enabled=").append(enabled)
273 .append(" mScreenOn=").append(screenOn)
274 .append(" mState=").append(state)
275 .append(". Escalating to WTF if screen does not turn on soon.")
Adrian Roos401caae2016-03-04 13:35:21 -0800276 .toString());
Adrian Roos8e291a52016-12-09 16:10:19 -0800277
278 // Unfortunately we're also getting false positives for touches that happen right
279 // after the screen turns on, but before that notification has made it to us.
280 // Unfortunately there's no good way to catch that, except to wait and see if we get
281 // the screen on notification soon.
282 mPendingWtf = () -> FalsingLog.wtf("isFalseTouch", new StringBuilder()
283 .append("Session did not become active after query for a false touch.")
284 .append(" enabled=").append(enabled)
285 .append('/').append(isEnabled() ? 1 : 0)
286 .append(" mScreenOn=").append(screenOn)
287 .append('/').append(mScreenOn ? 1 : 0)
288 .append(" mState=").append(state)
289 .append('/').append(StatusBarState.toShortString(mState))
290 .append(". Look for warnings ~1000ms earlier to see root cause.")
291 .toString(), here);
292 mHandler.postDelayed(mPendingWtf, 1000);
Adrian Roos401caae2016-03-04 13:35:21 -0800293 }
294 }
Adrian Roosca664b92016-04-18 14:40:27 -0700295 if (mAccessibilityManager.isTouchExplorationEnabled()) {
296 // Touch exploration triggers false positives in the classifier and
297 // already sufficiently prevents false unlocks.
298 return false;
299 }
Adrian Roos004437e2017-08-16 11:58:02 +0200300 if (!mIsTouchScreen) {
301 // Unlocking with input devices besides the touchscreen should already be sufficiently
302 // anti-falsed.
303 return false;
304 }
Lucas Dupin7e35d142019-05-08 15:13:36 -0700305 if (mJustUnlockedWithFace) {
306 // Unlocking with face is a strong user presence signal, we can assume the user
307 // is present until the next session starts.
308 return false;
309 }
Dave Mankoff63c576e2019-05-01 18:00:01 -0400310 mIsFalseTouchCalls++;
311 boolean isFalse = mHumanInteractionClassifier.isFalseTouch();
312 if (!isFalse) {
313 if (FalsingLog.ENABLED) {
314 FalsingLog.i("isFalseTouchCalls", "Calls before success: " + mIsFalseTouchCalls);
315 }
316 mMetricsLogger.histogram(FALSING_SUCCESS, mIsFalseTouchCalls);
317 mIsFalseTouchCalls = 0;
318 }
319 return isFalse;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700320 }
321
Adrian Roos8e291a52016-12-09 16:10:19 -0800322 private void clearPendingWtf() {
323 if (mPendingWtf != null) {
324 mHandler.removeCallbacks(mPendingWtf);
325 mPendingWtf = null;
326 }
327 }
328
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700329
330 public boolean shouldEnforceBouncer() {
331 return mEnforceBouncer;
332 }
333
Adrian Roose395b5d2017-06-28 16:52:37 +0200334 public void setShowingAod(boolean showingAod) {
335 mShowingAod = showingAod;
336 updateSessionActive();
337 }
338
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700339 public void onScreenTurningOn() {
Adrian Roos401caae2016-03-04 13:35:21 -0800340 if (FalsingLog.ENABLED) {
341 FalsingLog.i("onScreenTurningOn", new StringBuilder()
342 .append("from=").append(mScreenOn ? 1 : 0)
343 .toString());
Adrian Roos8e291a52016-12-09 16:10:19 -0800344 clearPendingWtf();
Adrian Roos401caae2016-03-04 13:35:21 -0800345 }
Adrian Roosc5584ce2016-02-24 14:17:19 -0800346 mScreenOn = true;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700347 if (sessionEntrypoint()) {
348 mDataCollector.onScreenTurningOn();
349 }
350 }
351
352 public void onScreenOnFromTouch() {
Adrian Roos401caae2016-03-04 13:35:21 -0800353 if (FalsingLog.ENABLED) {
354 FalsingLog.i("onScreenOnFromTouch", new StringBuilder()
355 .append("from=").append(mScreenOn ? 1 : 0)
356 .toString());
357 }
Adrian Roosc5584ce2016-02-24 14:17:19 -0800358 mScreenOn = true;
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700359 if (sessionEntrypoint()) {
360 mDataCollector.onScreenOnFromTouch();
361 }
362 }
363
364 public void onScreenOff() {
Adrian Roos401caae2016-03-04 13:35:21 -0800365 if (FalsingLog.ENABLED) {
366 FalsingLog.i("onScreenOff", new StringBuilder()
367 .append("from=").append(mScreenOn ? 1 : 0)
368 .toString());
369 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700370 mDataCollector.onScreenOff();
Adrian Roosc5584ce2016-02-24 14:17:19 -0800371 mScreenOn = false;
372 sessionExitpoint(false /* force */);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700373 }
374
375 public void onSucccessfulUnlock() {
Adrian Roos401caae2016-03-04 13:35:21 -0800376 if (FalsingLog.ENABLED) {
377 FalsingLog.i("onSucccessfulUnlock", "");
378 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700379 mDataCollector.onSucccessfulUnlock();
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700380 }
381
382 public void onBouncerShown() {
Adrian Roos401caae2016-03-04 13:35:21 -0800383 if (FalsingLog.ENABLED) {
384 FalsingLog.i("onBouncerShown", new StringBuilder()
385 .append("from=").append(mBouncerOn ? 1 : 0)
386 .toString());
387 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700388 if (!mBouncerOn) {
389 mBouncerOn = true;
390 mDataCollector.onBouncerShown();
391 }
392 }
393
394 public void onBouncerHidden() {
Adrian Roos401caae2016-03-04 13:35:21 -0800395 if (FalsingLog.ENABLED) {
396 FalsingLog.i("onBouncerHidden", new StringBuilder()
397 .append("from=").append(mBouncerOn ? 1 : 0)
398 .toString());
399 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700400 if (mBouncerOn) {
401 mBouncerOn = false;
402 mDataCollector.onBouncerHidden();
403 }
404 }
405
406 public void onQsDown() {
Adrian Roos401caae2016-03-04 13:35:21 -0800407 if (FalsingLog.ENABLED) {
408 FalsingLog.i("onQsDown", "");
409 }
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700410 mHumanInteractionClassifier.setType(Classifier.QUICK_SETTINGS);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700411 mDataCollector.onQsDown();
412 }
413
414 public void setQsExpanded(boolean expanded) {
415 mDataCollector.setQsExpanded(expanded);
416 }
417
Lucas Dupinbc9aac12018-03-04 20:18:15 -0800418 public void onTrackingStarted(boolean secure) {
Adrian Roos401caae2016-03-04 13:35:21 -0800419 if (FalsingLog.ENABLED) {
420 FalsingLog.i("onTrackingStarted", "");
421 }
Dave Mankoffdde5ee62019-05-02 17:36:11 -0400422 mHumanInteractionClassifier.setType(secure
423 ? Classifier.BOUNCER_UNLOCK : Classifier.UNLOCK);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700424 mDataCollector.onTrackingStarted();
425 }
426
427 public void onTrackingStopped() {
428 mDataCollector.onTrackingStopped();
429 }
430
431 public void onNotificationActive() {
432 mDataCollector.onNotificationActive();
433 }
434
Adrian Roos9f0b0022016-11-09 15:56:50 -0800435 public void onNotificationDoubleTap(boolean accepted, float dx, float dy) {
436 if (FalsingLog.ENABLED) {
437 FalsingLog.i("onNotificationDoubleTap", "accepted=" + accepted
438 + " dx=" + dx + " dy=" + dy + " (px)");
439 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700440 mDataCollector.onNotificationDoubleTap();
441 }
442
443 public void setNotificationExpanded() {
444 mDataCollector.setNotificationExpanded();
445 }
446
447 public void onNotificatonStartDraggingDown() {
Adrian Roos401caae2016-03-04 13:35:21 -0800448 if (FalsingLog.ENABLED) {
449 FalsingLog.i("onNotificatonStartDraggingDown", "");
450 }
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700451 mHumanInteractionClassifier.setType(Classifier.NOTIFICATION_DRAG_DOWN);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700452 mDataCollector.onNotificatonStartDraggingDown();
453 }
454
Selim Cinek3d6ae232019-01-04 14:14:33 -0800455 public void onStartExpandingFromPulse() {
456 if (FalsingLog.ENABLED) {
457 FalsingLog.i("onStartExpandingFromPulse", "");
458 }
459 mHumanInteractionClassifier.setType(Classifier.PULSE_EXPAND);
460 mDataCollector.onStartExpandingFromPulse();
461 }
462
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700463 public void onNotificatonStopDraggingDown() {
464 mDataCollector.onNotificatonStopDraggingDown();
465 }
466
Selim Cinek3d6ae232019-01-04 14:14:33 -0800467 public void onExpansionFromPulseStopped() {
468 mDataCollector.onExpansionFromPulseStopped();
469 }
470
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700471 public void onNotificationDismissed() {
472 mDataCollector.onNotificationDismissed();
473 }
474
475 public void onNotificatonStartDismissing() {
Adrian Roos401caae2016-03-04 13:35:21 -0800476 if (FalsingLog.ENABLED) {
477 FalsingLog.i("onNotificatonStartDismissing", "");
478 }
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700479 mHumanInteractionClassifier.setType(Classifier.NOTIFICATION_DISMISS);
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700480 mDataCollector.onNotificatonStartDismissing();
481 }
482
483 public void onNotificatonStopDismissing() {
484 mDataCollector.onNotificatonStopDismissing();
485 }
486
487 public void onCameraOn() {
488 mDataCollector.onCameraOn();
489 }
490
491 public void onLeftAffordanceOn() {
492 mDataCollector.onLeftAffordanceOn();
493 }
494
495 public void onAffordanceSwipingStarted(boolean rightCorner) {
Adrian Roos401caae2016-03-04 13:35:21 -0800496 if (FalsingLog.ENABLED) {
497 FalsingLog.i("onAffordanceSwipingStarted", "");
498 }
Blazej Magnowski9f01c5b2015-09-17 15:14:29 -0700499 if (rightCorner) {
500 mHumanInteractionClassifier.setType(Classifier.RIGHT_AFFORDANCE);
501 } else {
502 mHumanInteractionClassifier.setType(Classifier.LEFT_AFFORDANCE);
503 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700504 mDataCollector.onAffordanceSwipingStarted(rightCorner);
505 }
506
507 public void onAffordanceSwipingAborted() {
508 mDataCollector.onAffordanceSwipingAborted();
509 }
510
511 public void onUnlockHintStarted() {
512 mDataCollector.onUnlockHintStarted();
513 }
514
515 public void onCameraHintStarted() {
516 mDataCollector.onCameraHintStarted();
517 }
518
519 public void onLeftAffordanceHintStarted() {
520 mDataCollector.onLeftAffordanceHintStarted();
521 }
522
523 public void onTouchEvent(MotionEvent event, int width, int height) {
Adrian Roos004437e2017-08-16 11:58:02 +0200524 if (event.getAction() == MotionEvent.ACTION_DOWN) {
525 mIsTouchScreen = event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN);
Siarhei Vishniakou81e1ffd2018-05-04 16:08:22 -0700526 // If the bouncer was not shown during the down event,
527 // we want the entire gesture going to HumanInteractionClassifier
528 mBouncerOffOnDown = !mBouncerOn;
Adrian Roos004437e2017-08-16 11:58:02 +0200529 }
Siarhei Vishniakou81e1ffd2018-05-04 16:08:22 -0700530 if (mSessionActive) {
531 if (!mBouncerOn) {
532 // In case bouncer is "visible", but onFullyShown has not yet been called,
533 // avoid adding the event to DataCollector
534 mDataCollector.onTouchEvent(event, width, height);
535 }
536 if (mBouncerOffOnDown) {
537 mHumanInteractionClassifier.onTouchEvent(event);
538 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700539 }
540 }
Adrian Roos401caae2016-03-04 13:35:21 -0800541
542 public void dump(PrintWriter pw) {
543 pw.println("FALSING MANAGER");
544 pw.print("classifierEnabled="); pw.println(isClassiferEnabled() ? 1 : 0);
545 pw.print("mSessionActive="); pw.println(mSessionActive ? 1 : 0);
546 pw.print("mBouncerOn="); pw.println(mSessionActive ? 1 : 0);
547 pw.print("mState="); pw.println(StatusBarState.toShortString(mState));
548 pw.print("mScreenOn="); pw.println(mScreenOn ? 1 : 0);
549 pw.println();
550 }
Adrian Roos7bb38a92016-07-21 11:44:01 -0700551
552 public Uri reportRejectedTouch() {
553 if (mDataCollector.isEnabled()) {
554 return mDataCollector.reportRejectedTouch();
555 }
556 return null;
557 }
558
559 public boolean isReportingEnabled() {
560 return mDataCollector.isReportingEnabled();
561 }
Blazej Magnowski0e2ffbd2015-09-10 14:37:17 -0700562}