blob: b68a56dcc750b36dbda40d1d97c932649b90ca79 [file] [log] [blame]
Dave Mankoff07fb7b72019-06-10 16:36:19 -04001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.systemui.classifier.brightline;
18
Dave Mankoff1dee0342019-07-11 17:44:54 -040019import static com.android.systemui.classifier.FalsingManagerImpl.FALSING_REMAIN_LOCKED;
20import static com.android.systemui.classifier.FalsingManagerImpl.FALSING_SUCCESS;
21
Dave Mankoffd61f01b2019-08-09 17:58:56 -040022import android.hardware.biometrics.BiometricSourceType;
Dave Mankoff07fb7b72019-06-10 16:36:19 -040023import android.net.Uri;
24import android.util.Log;
25import android.view.MotionEvent;
26
Dave Mankoff1dee0342019-07-11 17:44:54 -040027import com.android.internal.logging.MetricsLogger;
Dave Mankoffd61f01b2019-08-09 17:58:56 -040028import com.android.keyguard.KeyguardUpdateMonitor;
29import com.android.keyguard.KeyguardUpdateMonitorCallback;
Dave Mankoff07fb7b72019-06-10 16:36:19 -040030import com.android.systemui.classifier.Classifier;
31import com.android.systemui.plugins.FalsingManager;
Dave Mankoff46b9d682019-09-12 13:39:42 -040032import com.android.systemui.util.ProximitySensor;
Dave Mankoff07fb7b72019-06-10 16:36:19 -040033
34import java.io.PrintWriter;
35import java.util.ArrayList;
36import java.util.List;
Dave Mankoff07fb7b72019-06-10 16:36:19 -040037
38/**
39 * FalsingManager designed to make clear why a touch was rejected.
40 */
41public class BrightLineFalsingManager implements FalsingManager {
42
43 static final boolean DEBUG = false;
44 private static final String TAG = "FalsingManagerPlugin";
45
Dave Mankoff07fb7b72019-06-10 16:36:19 -040046 private final FalsingDataProvider mDataProvider;
Dave Mankoffd61f01b2019-08-09 17:58:56 -040047 private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
Dave Mankoff46b9d682019-09-12 13:39:42 -040048 private final ProximitySensor mProximitySensor;
Dave Mankoff07fb7b72019-06-10 16:36:19 -040049 private boolean mSessionStarted;
Dave Mankoff1dee0342019-07-11 17:44:54 -040050 private MetricsLogger mMetricsLogger;
51 private int mIsFalseTouchCalls;
Dave Mankoff622eeaf2019-07-26 13:50:08 -040052 private boolean mShowingAod;
53 private boolean mScreenOn;
Dave Mankoffd61f01b2019-08-09 17:58:56 -040054 private boolean mJustUnlockedWithFace;
Dave Mankoff07fb7b72019-06-10 16:36:19 -040055
Dave Mankoff07fb7b72019-06-10 16:36:19 -040056 private final List<FalsingClassifier> mClassifiers;
57
Dave Mankoff46b9d682019-09-12 13:39:42 -040058 private ProximitySensor.ProximitySensorListener mSensorEventListener = this::onProximityEvent;
Dave Mankoff07fb7b72019-06-10 16:36:19 -040059
Dave Mankoffd61f01b2019-08-09 17:58:56 -040060 private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
61 new KeyguardUpdateMonitorCallback() {
62 @Override
63 public void onBiometricAuthenticated(int userId,
64 BiometricSourceType biometricSourceType) {
65 if (userId == KeyguardUpdateMonitor.getCurrentUser()
66 && biometricSourceType == BiometricSourceType.FACE) {
67 mJustUnlockedWithFace = true;
68 }
69 }
70 };
71
72 public BrightLineFalsingManager(
73 FalsingDataProvider falsingDataProvider,
Dave Mankoff46b9d682019-09-12 13:39:42 -040074 KeyguardUpdateMonitor keyguardUpdateMonitor,
75 ProximitySensor proximitySensor) {
Dave Mankoffd61f01b2019-08-09 17:58:56 -040076 mKeyguardUpdateMonitor = keyguardUpdateMonitor;
Dave Mankoff07fb7b72019-06-10 16:36:19 -040077 mDataProvider = falsingDataProvider;
Dave Mankoff46b9d682019-09-12 13:39:42 -040078 mProximitySensor = proximitySensor;
Dave Mankoffd61f01b2019-08-09 17:58:56 -040079 mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback);
80
Dave Mankoff1dee0342019-07-11 17:44:54 -040081 mMetricsLogger = new MetricsLogger();
Dave Mankoff07fb7b72019-06-10 16:36:19 -040082 mClassifiers = new ArrayList<>();
Dave Mankoff8bfbe332019-06-12 17:58:30 -040083 DistanceClassifier distanceClassifier = new DistanceClassifier(mDataProvider);
84 ProximityClassifier proximityClassifier = new ProximityClassifier(distanceClassifier,
85 mDataProvider);
Dave Mankoff7abe1352019-06-11 11:32:52 -040086 mClassifiers.add(new PointerCountClassifier(mDataProvider));
Dave Mankofffd42bdbb2019-06-11 14:51:45 -040087 mClassifiers.add(new TypeClassifier(mDataProvider));
Dave Mankoffd8efd0d2019-06-11 16:48:34 -040088 mClassifiers.add(new DiagonalClassifier(mDataProvider));
Dave Mankoff8bfbe332019-06-12 17:58:30 -040089 mClassifiers.add(distanceClassifier);
90 mClassifiers.add(proximityClassifier);
Dave Mankoff89ad2462019-06-14 14:59:05 -040091 mClassifiers.add(new ZigZagClassifier(mDataProvider));
Dave Mankoff07fb7b72019-06-10 16:36:19 -040092 }
93
94 private void registerSensors() {
Dave Mankoff46b9d682019-09-12 13:39:42 -040095 mProximitySensor.register(mSensorEventListener);
Dave Mankoff07fb7b72019-06-10 16:36:19 -040096 }
97
98
99 private void unregisterSensors() {
Dave Mankoff46b9d682019-09-12 13:39:42 -0400100 mProximitySensor.unregister(mSensorEventListener);
Dave Mankoff07fb7b72019-06-10 16:36:19 -0400101 }
102
103 private void sessionStart() {
Dave Mankoff622eeaf2019-07-26 13:50:08 -0400104 if (!mSessionStarted && !mShowingAod && mScreenOn) {
Dave Mankoff0ae8f2e2019-07-24 18:06:44 -0400105 logDebug("Starting Session");
106 mSessionStarted = true;
Dave Mankoffd61f01b2019-08-09 17:58:56 -0400107 mJustUnlockedWithFace = false;
Dave Mankoff0ae8f2e2019-07-24 18:06:44 -0400108 registerSensors();
109 mClassifiers.forEach(FalsingClassifier::onSessionStarted);
110 }
Dave Mankoff07fb7b72019-06-10 16:36:19 -0400111 }
112
113 private void sessionEnd() {
114 if (mSessionStarted) {
115 logDebug("Ending Session");
116 mSessionStarted = false;
117 unregisterSensors();
118 mDataProvider.onSessionEnd();
119 mClassifiers.forEach(FalsingClassifier::onSessionEnded);
Dave Mankoff1dee0342019-07-11 17:44:54 -0400120 if (mIsFalseTouchCalls != 0) {
121 mMetricsLogger.histogram(FALSING_REMAIN_LOCKED, mIsFalseTouchCalls);
122 mIsFalseTouchCalls = 0;
123 }
Dave Mankoff07fb7b72019-06-10 16:36:19 -0400124 }
125 }
126
127 private void updateInteractionType(@Classifier.InteractionType int type) {
128 logDebug("InteractionType: " + type);
129 mClassifiers.forEach((classifier) -> classifier.setInteractionType(type));
130 }
131
132 @Override
133 public boolean isClassiferEnabled() {
134 return true;
135 }
136
137 @Override
138 public boolean isFalseTouch() {
Dave Mankoffd61f01b2019-08-09 17:58:56 -0400139 boolean r = !mJustUnlockedWithFace && mClassifiers.stream().anyMatch(falsingClassifier -> {
Dave Mankoff07fb7b72019-06-10 16:36:19 -0400140 boolean result = falsingClassifier.isFalseTouch();
141 if (result) {
142 logInfo(falsingClassifier.getClass().getName() + ": true");
143 } else {
144 logDebug(falsingClassifier.getClass().getName() + ": false");
145 }
146 return result;
147 });
148
149 logDebug("Is false touch? " + r);
150
151 return r;
152 }
153
154 @Override
155 public void onTouchEvent(MotionEvent motionEvent, int width, int height) {
156 // TODO: some of these classifiers might allow us to abort early, meaning we don't have to
157 // make these calls.
158 mDataProvider.onMotionEvent(motionEvent);
159 mClassifiers.forEach((classifier) -> classifier.onTouchEvent(motionEvent));
160 }
161
Dave Mankoff46b9d682019-09-12 13:39:42 -0400162 private void onProximityEvent(ProximitySensor.ProximityEvent proximityEvent) {
Dave Mankoff07fb7b72019-06-10 16:36:19 -0400163 // TODO: some of these classifiers might allow us to abort early, meaning we don't have to
164 // make these calls.
Dave Mankoff46b9d682019-09-12 13:39:42 -0400165 mClassifiers.forEach((classifier) -> classifier.onProximityEvent(proximityEvent));
Dave Mankoff07fb7b72019-06-10 16:36:19 -0400166 }
167
168 @Override
169 public void onSucccessfulUnlock() {
Dave Mankoff1dee0342019-07-11 17:44:54 -0400170 if (mIsFalseTouchCalls != 0) {
171 mMetricsLogger.histogram(FALSING_SUCCESS, mIsFalseTouchCalls);
172 mIsFalseTouchCalls = 0;
173 }
Dave Mankoff622eeaf2019-07-26 13:50:08 -0400174 sessionEnd();
Dave Mankoff07fb7b72019-06-10 16:36:19 -0400175 }
176
177 @Override
178 public void onNotificationActive() {
179 }
180
181 @Override
182 public void setShowingAod(boolean showingAod) {
Dave Mankoff622eeaf2019-07-26 13:50:08 -0400183 mShowingAod = showingAod;
Dave Mankoff07fb7b72019-06-10 16:36:19 -0400184 if (showingAod) {
185 sessionEnd();
186 } else {
187 sessionStart();
188 }
189 }
190
191 @Override
192 public void onNotificatonStartDraggingDown() {
193 updateInteractionType(Classifier.NOTIFICATION_DRAG_DOWN);
194
195 }
196
197 @Override
198 public boolean isUnlockingDisabled() {
199 return false;
200 }
201
202
203 @Override
204 public void onNotificatonStopDraggingDown() {
205 }
206
207 @Override
208 public void setNotificationExpanded() {
209 }
210
211 @Override
212 public void onQsDown() {
213 updateInteractionType(Classifier.QUICK_SETTINGS);
214 }
215
216 @Override
217 public void setQsExpanded(boolean b) {
218 }
219
220 @Override
221 public boolean shouldEnforceBouncer() {
222 return false;
223 }
224
225 @Override
226 public void onTrackingStarted(boolean secure) {
227 updateInteractionType(secure ? Classifier.BOUNCER_UNLOCK : Classifier.UNLOCK);
228 }
229
230 @Override
231 public void onTrackingStopped() {
232 }
233
234 @Override
235 public void onLeftAffordanceOn() {
236 }
237
238 @Override
239 public void onCameraOn() {
240 }
241
242 @Override
243 public void onAffordanceSwipingStarted(boolean rightCorner) {
244 updateInteractionType(
245 rightCorner ? Classifier.RIGHT_AFFORDANCE : Classifier.LEFT_AFFORDANCE);
246 }
247
248 @Override
249 public void onAffordanceSwipingAborted() {
250 }
251
252 @Override
253 public void onStartExpandingFromPulse() {
254 updateInteractionType(Classifier.PULSE_EXPAND);
255 }
256
257 @Override
258 public void onExpansionFromPulseStopped() {
259 }
260
261 @Override
262 public Uri reportRejectedTouch() {
263 return null;
264 }
265
266 @Override
267 public void onScreenOnFromTouch() {
Dave Mankoff622eeaf2019-07-26 13:50:08 -0400268 onScreenTurningOn();
Dave Mankoff07fb7b72019-06-10 16:36:19 -0400269 }
270
271 @Override
272 public boolean isReportingEnabled() {
273 return false;
274 }
275
276 @Override
277 public void onUnlockHintStarted() {
278 }
279
280 @Override
281 public void onCameraHintStarted() {
282 }
283
284 @Override
285 public void onLeftAffordanceHintStarted() {
286 }
287
288 @Override
289 public void onScreenTurningOn() {
Dave Mankoff622eeaf2019-07-26 13:50:08 -0400290 mScreenOn = true;
Dave Mankoff07fb7b72019-06-10 16:36:19 -0400291 sessionStart();
292 }
293
294 @Override
295 public void onScreenOff() {
Dave Mankoff622eeaf2019-07-26 13:50:08 -0400296 mScreenOn = false;
Dave Mankoff07fb7b72019-06-10 16:36:19 -0400297 sessionEnd();
298 }
299
300
301 @Override
302 public void onNotificatonStopDismissing() {
303 }
304
305 @Override
306 public void onNotificationDismissed() {
307 }
308
309 @Override
310 public void onNotificatonStartDismissing() {
311 updateInteractionType(Classifier.NOTIFICATION_DISMISS);
312 }
313
314 @Override
315 public void onNotificationDoubleTap(boolean b, float v, float v1) {
316 }
317
318 @Override
319 public void onBouncerShown() {
320 }
321
322 @Override
323 public void onBouncerHidden() {
324 }
325
326 @Override
327 public void dump(PrintWriter printWriter) {
328 }
329
Dave Mankoff4c5a13e2019-07-16 15:07:01 -0400330 @Override
331 public void cleanup() {
332 unregisterSensors();
Dave Mankoffd61f01b2019-08-09 17:58:56 -0400333 mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateCallback);
Dave Mankoff4c5a13e2019-07-16 15:07:01 -0400334 }
335
Dave Mankoff07fb7b72019-06-10 16:36:19 -0400336 static void logDebug(String msg) {
337 logDebug(msg, null);
338 }
339
340 static void logDebug(String msg, Throwable throwable) {
341 if (DEBUG) {
342 Log.d(TAG, msg, throwable);
343 }
344 }
345
346 static void logInfo(String msg) {
347 Log.i(TAG, msg);
348 }
349
350 static void logError(String msg) {
351 Log.e(TAG, msg);
352 }
353}