From 018189025151d7ce8173e08f6cb1a1e85b728b2a Mon Sep 17 00:00:00 2001 From: Dave Mankoff Date: Thu, 12 Nov 2020 15:28:31 -0500 Subject: [PATCH] Remove old falsing implementation. This code has not been used since Android P. Bug: 172655679 Test: manual && atest SystemUITests Change-Id: I2b96af477b063bcbb68c48951121258e56bbfff2 --- .../systemui/plugins/FalsingManager.java | 4 +- .../classifier/AccelerationClassifier.java | 99 --- .../systemui/classifier/AnglesClassifier.java | 207 ------ .../classifier/AnglesPercentageEvaluator.java | 28 - .../classifier/AnglesVarianceEvaluator.java | 28 - .../systemui/classifier/Classifier.java | 5 - .../systemui/classifier/ClassifierData.java | 101 --- .../classifier/DirectionClassifier.java | 39 -- .../classifier/DirectionEvaluator.java | 56 -- .../classifier/DurationCountClassifier.java | 36 -- .../classifier/DurationCountEvaluator.java | 30 - .../classifier/EndPointLengthClassifier.java | 35 -- .../classifier/EndPointLengthEvaluator.java | 30 - .../classifier/EndPointRatioClassifier.java | 43 -- .../classifier/EndPointRatioEvaluator.java | 30 - .../systemui/classifier/FalsingLog.java | 169 ----- .../classifier/FalsingManagerFake.java | 4 +- .../classifier/FalsingManagerImpl.java | 589 ------------------ .../classifier/FalsingManagerProxy.java | 88 ++- .../classifier/GestureClassifier.java | 32 - .../systemui/classifier/HistoryEvaluator.java | 117 ---- .../HumanInteractionClassifier.java | 241 ------- .../classifier/LengthCountClassifier.java | 40 -- .../classifier/LengthCountEvaluator.java | 34 - .../android/systemui/classifier/Point.java | 83 --- .../classifier/PointerCountClassifier.java | 53 -- .../classifier/PointerCountEvaluator.java | 23 - .../classifier/ProximityClassifier.java | 98 --- .../classifier/ProximityEvaluator.java | 29 - .../classifier/SpeedAnglesClassifier.java | 164 ----- .../SpeedAnglesPercentageEvaluator.java | 27 - .../systemui/classifier/SpeedClassifier.java | 42 -- .../systemui/classifier/SpeedEvaluator.java | 28 - .../classifier/SpeedRatioEvaluator.java | 29 - .../classifier/SpeedVarianceEvaluator.java | 28 - .../android/systemui/classifier/Stroke.java | 79 --- .../systemui/classifier/StrokeClassifier.java | 31 - .../brightline/BrightLineFalsingManager.java | 11 +- .../systemui/statusbar/phone/StatusBar.java | 8 - .../classifier/FalsingManagerProxyTest.java | 136 ---- 40 files changed, 51 insertions(+), 2903 deletions(-) delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/AccelerationClassifier.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/AnglesClassifier.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/AnglesPercentageEvaluator.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/AnglesVarianceEvaluator.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/ClassifierData.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/DirectionClassifier.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/DirectionEvaluator.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/DurationCountClassifier.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/DurationCountEvaluator.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/EndPointLengthClassifier.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/EndPointLengthEvaluator.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/EndPointRatioClassifier.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/EndPointRatioEvaluator.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/FalsingLog.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/GestureClassifier.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/HistoryEvaluator.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/LengthCountClassifier.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/LengthCountEvaluator.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/Point.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/PointerCountClassifier.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/PointerCountEvaluator.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/ProximityEvaluator.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/SpeedAnglesClassifier.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/SpeedAnglesPercentageEvaluator.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/SpeedClassifier.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/SpeedEvaluator.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/SpeedRatioEvaluator.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/SpeedVarianceEvaluator.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/Stroke.java delete mode 100644 packages/SystemUI/src/com/android/systemui/classifier/StrokeClassifier.java delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java index 16184a807bc7f..0f94bca1d8157 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java @@ -21,6 +21,7 @@ import android.view.MotionEvent; import com.android.systemui.plugins.annotations.ProvidesInterface; +import java.io.FileDescriptor; import java.io.PrintWriter; /** @@ -139,7 +140,8 @@ public interface FalsingManager { void onTouchEvent(MotionEvent ev, int width, int height); - void dump(PrintWriter pw); + /** From com.android.systemui.Dumpable. */ + void dump(FileDescriptor fd, PrintWriter pw, String[] args); void cleanup(); } diff --git a/packages/SystemUI/src/com/android/systemui/classifier/AccelerationClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/AccelerationClassifier.java deleted file mode 100644 index 4585fe9fb8687..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/AccelerationClassifier.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -import android.view.MotionEvent; - -import java.util.HashMap; - -/** - * A classifier which looks at the speed and distance between successive points of a Stroke. - * It looks at two consecutive speeds between two points and calculates the ratio between them. - * The final result is the maximum of these values. It does the same for distances. If some speed - * or distance is equal to zero then the ratio between this and the next part is not calculated. To - * the duration of each part there is added one nanosecond so that it is always possible to - * calculate the speed of a part. - */ -public class AccelerationClassifier extends StrokeClassifier { - private final HashMap mStrokeMap = new HashMap<>(); - - public AccelerationClassifier(ClassifierData classifierData) { - mClassifierData = classifierData; - } - - @Override - public String getTag() { - return "ACC"; - } - - @Override - public void onTouchEvent(MotionEvent event) { - int action = event.getActionMasked(); - - if (action == MotionEvent.ACTION_DOWN) { - mStrokeMap.clear(); - } - - for (int i = 0; i < event.getPointerCount(); i++) { - Stroke stroke = mClassifierData.getStroke(event.getPointerId(i)); - Point point = stroke.getPoints().get(stroke.getPoints().size() - 1); - if (mStrokeMap.get(stroke) == null) { - mStrokeMap.put(stroke, new Data(point)); - } else { - mStrokeMap.get(stroke).addPoint(point); - } - } - } - - @Override - public float getFalseTouchEvaluation(int type, Stroke stroke) { - Data data = mStrokeMap.get(stroke); - return 2 * SpeedRatioEvaluator.evaluate(data.maxSpeedRatio); - } - - private static class Data { - - static final float MILLIS_TO_NANOS = 1e6f; - - Point previousPoint; - float previousSpeed = 0; - float maxSpeedRatio = 0; - - public Data(Point point) { - previousPoint = point; - } - - public void addPoint(Point point) { - float distance = previousPoint.dist(point); - float duration = (float) (point.timeOffsetNano - previousPoint.timeOffsetNano + 1); - float speed = distance / duration; - - if (duration > 20 * MILLIS_TO_NANOS || duration < 5 * MILLIS_TO_NANOS) { - // reject this segment and ensure we won't use data about it in the next round. - previousSpeed = 0; - previousPoint = point; - return; - } - if (previousSpeed != 0.0f) { - maxSpeedRatio = Math.max(maxSpeedRatio, speed / previousSpeed); - } - - previousSpeed = speed; - previousPoint = point; - } - } -} \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/classifier/AnglesClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/AnglesClassifier.java deleted file mode 100644 index 6d13973d23b5a..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/AnglesClassifier.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -import android.os.Build; -import android.os.SystemProperties; -import android.view.MotionEvent; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -/** - * A classifier which calculates the variance of differences between successive angles in a stroke. - * For each stroke it keeps its last three points. If some successive points are the same, it - * ignores the repetitions. If a new point is added, the classifier calculates the angle between - * the last three points. After that, it calculates the difference between this angle and the - * previously calculated angle. Then it calculates the variance of the differences from a stroke. - * To the differences there is artificially added value 0.0 and the difference between the first - * angle and PI (angles are in radians). It helps with strokes which have few points and punishes - * more strokes which are not smooth. - * - * This classifier also tries to split the stroke into two parts in the place in which the biggest - * angle is. It calculates the angle variance of the two parts and sums them up. The reason the - * classifier is doing this, is because some human swipes at the beginning go for a moment in one - * direction and then they rapidly change direction for the rest of the stroke (like a tick). The - * final result is the minimum of angle variance of the whole stroke and the sum of angle variances - * of the two parts split up. The classifier tries the tick option only if the first part is - * shorter than the second part. - * - * Additionally, the classifier classifies the angles as left angles (those angles which value is - * in [0.0, PI - ANGLE_DEVIATION) interval), straight angles - * ([PI - ANGLE_DEVIATION, PI + ANGLE_DEVIATION] interval) and right angles - * ((PI + ANGLE_DEVIATION, 2 * PI) interval) and then calculates the percentage of angles which are - * in the same direction (straight angles can be left angels or right angles) - */ -public class AnglesClassifier extends StrokeClassifier { - private HashMap mStrokeMap = new HashMap<>(); - - public static final boolean VERBOSE = SystemProperties.getBoolean("debug.falsing_log.ang", - Build.IS_DEBUGGABLE); - - private static String TAG = "ANG"; - - public AnglesClassifier(ClassifierData classifierData) { - mClassifierData = classifierData; - } - - @Override - public String getTag() { - return TAG; - } - - @Override - public void onTouchEvent(MotionEvent event) { - int action = event.getActionMasked(); - - if (action == MotionEvent.ACTION_DOWN) { - mStrokeMap.clear(); - } - - for (int i = 0; i < event.getPointerCount(); i++) { - Stroke stroke = mClassifierData.getStroke(event.getPointerId(i)); - - if (mStrokeMap.get(stroke) == null) { - mStrokeMap.put(stroke, new Data()); - } - mStrokeMap.get(stroke).addPoint(stroke.getPoints().get(stroke.getPoints().size() - 1)); - } - } - - @Override - public float getFalseTouchEvaluation(int type, Stroke stroke) { - Data data = mStrokeMap.get(stroke); - return AnglesVarianceEvaluator.evaluate(data.getAnglesVariance(), type) - + AnglesPercentageEvaluator.evaluate(data.getAnglesPercentage(), type); - } - - private static class Data { - private final float ANGLE_DEVIATION = (float) Math.PI / 20.0f; - - private List mLastThreePoints = new ArrayList<>(); - private float mFirstAngleVariance; - private float mPreviousAngle; - private float mBiggestAngle; - private float mSumSquares; - private float mSecondSumSquares; - private float mSum; - private float mSecondSum; - private float mCount; - private float mSecondCount; - private float mFirstLength; - private float mLength; - private float mAnglesCount; - private float mLeftAngles; - private float mRightAngles; - private float mStraightAngles; - - public Data() { - mFirstAngleVariance = 0.0f; - mPreviousAngle = (float) Math.PI; - mBiggestAngle = 0.0f; - mSumSquares = mSecondSumSquares = 0.0f; - mSum = mSecondSum = 0.0f; - mCount = mSecondCount = 1.0f; - mLength = mFirstLength = 0.0f; - mAnglesCount = mLeftAngles = mRightAngles = mStraightAngles = 0.0f; - } - - public void addPoint(Point point) { - // Checking if the added point is different than the previously added point - // Repetitions are being ignored so that proper angles are calculated. - if (mLastThreePoints.isEmpty() - || !mLastThreePoints.get(mLastThreePoints.size() - 1).equals(point)) { - if (!mLastThreePoints.isEmpty()) { - mLength += mLastThreePoints.get(mLastThreePoints.size() - 1).dist(point); - } - mLastThreePoints.add(point); - if (mLastThreePoints.size() == 4) { - mLastThreePoints.remove(0); - - float angle = mLastThreePoints.get(1).getAngle(mLastThreePoints.get(0), - mLastThreePoints.get(2)); - - mAnglesCount++; - if (angle < Math.PI - ANGLE_DEVIATION) { - mLeftAngles++; - } else if (angle <= Math.PI + ANGLE_DEVIATION) { - mStraightAngles++; - } else { - mRightAngles++; - } - - float difference = angle - mPreviousAngle; - - // If this is the biggest angle of the stroke so then we save the value of - // the angle variance so far and start to count the values for the angle - // variance of the second part. - if (mBiggestAngle < angle) { - mBiggestAngle = angle; - mFirstLength = mLength; - mFirstAngleVariance = getAnglesVariance(mSumSquares, mSum, mCount); - mSecondSumSquares = 0.0f; - mSecondSum = 0.0f; - mSecondCount = 1.0f; - } else { - mSecondSum += difference; - mSecondSumSquares += difference * difference; - mSecondCount += 1.0; - } - - mSum += difference; - mSumSquares += difference * difference; - mCount += 1.0; - mPreviousAngle = angle; - } - } - } - - public float getAnglesVariance(float sumSquares, float sum, float count) { - return sumSquares / count - (sum / count) * (sum / count); - } - - public float getAnglesVariance() { - float anglesVariance = getAnglesVariance(mSumSquares, mSum, mCount); - if (VERBOSE) { - FalsingLog.i(TAG, "getAnglesVariance: (first pass) " + anglesVariance); - FalsingLog.i(TAG, " - mFirstLength=" + mFirstLength); - FalsingLog.i(TAG, " - mLength=" + mLength); - } - if (mFirstLength < mLength / 2f) { - anglesVariance = Math.min(anglesVariance, mFirstAngleVariance - + getAnglesVariance(mSecondSumSquares, mSecondSum, mSecondCount)); - if (VERBOSE) FalsingLog.i(TAG, "getAnglesVariance: (second pass) " + anglesVariance); - } - return anglesVariance; - } - - public float getAnglesPercentage() { - if (mAnglesCount == 0.0f) { - if (VERBOSE) FalsingLog.i(TAG, "getAnglesPercentage: count==0, result=1"); - return 1.0f; - } - final float result = (Math.max(mLeftAngles, mRightAngles) + mStraightAngles) / mAnglesCount; - if (VERBOSE) { - FalsingLog.i(TAG, "getAnglesPercentage: left=" + mLeftAngles + " right=" - + mRightAngles + " straight=" + mStraightAngles + " count=" + mAnglesCount - + " result=" + result); - } - return result; - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/AnglesPercentageEvaluator.java b/packages/SystemUI/src/com/android/systemui/classifier/AnglesPercentageEvaluator.java deleted file mode 100644 index e6e42f2d0eeff..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/AnglesPercentageEvaluator.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -public class AnglesPercentageEvaluator { - public static float evaluate(float value, int type) { - final boolean secureUnlock = type == Classifier.BOUNCER_UNLOCK; - float evaluation = 0.0f; - if (value < 1.00 && !secureUnlock) evaluation++; - if (value < 0.90 && !secureUnlock) evaluation++; - if (value < 0.70) evaluation++; - return evaluation; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/AnglesVarianceEvaluator.java b/packages/SystemUI/src/com/android/systemui/classifier/AnglesVarianceEvaluator.java deleted file mode 100644 index 9ffe783fbdedd..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/AnglesVarianceEvaluator.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -public class AnglesVarianceEvaluator { - public static float evaluate(float value, int type) { - float evaluation = 0.0f; - if (value > 0.20) evaluation++; - if (value > 0.40) evaluation++; - if (value > 0.80) evaluation++; - if (value > 1.50) evaluation++; - return evaluation; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java b/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java index ae7d142a9e45e..c7ad3e8f78eb6 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/Classifier.java @@ -53,11 +53,6 @@ public abstract class Classifier { @Retention(RetentionPolicy.SOURCE) public @interface InteractionType {} - /** - * Contains all the information about touch events from which the classifier can query - */ - protected ClassifierData mClassifierData; - /** * Informs the classifier that a new touch event has occurred */ diff --git a/packages/SystemUI/src/com/android/systemui/classifier/ClassifierData.java b/packages/SystemUI/src/com/android/systemui/classifier/ClassifierData.java deleted file mode 100644 index 587abba47932b..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/ClassifierData.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -import android.util.SparseArray; -import android.view.MotionEvent; - -import java.util.ArrayList; - -/** - * Contains data which is used to classify interaction sequences on the lockscreen. It does, for - * example, provide information on the current touch state. - */ -public class ClassifierData { - private static final long MINIMUM_DT_NANOS = 16666666; // 60Hz - private static final long MINIMUM_DT_SMEAR_NANOS = 2500000; // 2.5ms - - private SparseArray mCurrentStrokes = new SparseArray<>(); - private ArrayList mEndingStrokes = new ArrayList<>(); - private final float mDpi; - - public ClassifierData(float dpi) { - mDpi = dpi; - } - - /** Returns true if the event should be considered, false otherwise. */ - public boolean update(MotionEvent event) { - // We limit to 60hz sampling. Drop anything happening faster than that. - // Legacy code was created with an assumed sampling rate. As devices increase their - // sampling rate, this creates potentialy false positives. - if (event.getActionMasked() == MotionEvent.ACTION_MOVE - && mCurrentStrokes.size() != 0 - && event.getEventTimeNano() - mCurrentStrokes.valueAt(0).getLastEventTimeNano() - < MINIMUM_DT_NANOS - MINIMUM_DT_SMEAR_NANOS) { - return false; - } - - mEndingStrokes.clear(); - int action = event.getActionMasked(); - if (action == MotionEvent.ACTION_DOWN) { - mCurrentStrokes.clear(); - } - - for (int i = 0; i < event.getPointerCount(); i++) { - int id = event.getPointerId(i); - if (mCurrentStrokes.get(id) == null) { - mCurrentStrokes.put(id, new Stroke(event.getEventTimeNano(), mDpi)); - } - mCurrentStrokes.get(id).addPoint(event.getX(i), event.getY(i), - event.getEventTimeNano()); - - if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL - || (action == MotionEvent.ACTION_POINTER_UP && i == event.getActionIndex())) { - mEndingStrokes.add(getStroke(id)); - } - } - - return true; - } - - public void cleanUp(MotionEvent event) { - mEndingStrokes.clear(); - int action = event.getActionMasked(); - for (int i = 0; i < event.getPointerCount(); i++) { - int id = event.getPointerId(i); - if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL - || (action == MotionEvent.ACTION_POINTER_UP && i == event.getActionIndex())) { - mCurrentStrokes.remove(id); - } - } - } - - /** - * @return the list of Strokes which are ending in the recently added MotionEvent - */ - public ArrayList getEndingStrokes() { - return mEndingStrokes; - } - - /** - * @param id the id from MotionEvent - * @return the Stroke assigned to the id - */ - public Stroke getStroke(int id) { - return mCurrentStrokes.get(id); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/DirectionClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/DirectionClassifier.java deleted file mode 100644 index 610e21983b5d0..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/DirectionClassifier.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -/** - * A classifier which looks at the general direction of a stroke and evaluates it depending on - * the type of action that takes place. - */ -public class DirectionClassifier extends StrokeClassifier { - public DirectionClassifier(ClassifierData classifierData) { - } - - @Override - public String getTag() { - return "DIR"; - } - - @Override - public float getFalseTouchEvaluation(int type, Stroke stroke) { - Point firstPoint = stroke.getPoints().get(0); - Point lastPoint = stroke.getPoints().get(stroke.getPoints().size() - 1); - return DirectionEvaluator.evaluate(lastPoint.x - firstPoint.x, lastPoint.y - firstPoint.y, - type); - } -} \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/classifier/DirectionEvaluator.java b/packages/SystemUI/src/com/android/systemui/classifier/DirectionEvaluator.java deleted file mode 100644 index 78b41683a32b1..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/DirectionEvaluator.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -public class DirectionEvaluator { - public static float evaluate(float xDiff, float yDiff, int type) { - float falsingEvaluation = 5.5f; - boolean vertical = Math.abs(yDiff) >= Math.abs(xDiff); - switch (type) { - case Classifier.QUICK_SETTINGS: - case Classifier.PULSE_EXPAND: - case Classifier.NOTIFICATION_DRAG_DOWN: - if (!vertical || yDiff <= 0.0) { - return falsingEvaluation; - } - break; - case Classifier.NOTIFICATION_DISMISS: - if (vertical) { - return falsingEvaluation; - } - break; - case Classifier.UNLOCK: - case Classifier.BOUNCER_UNLOCK: - if (!vertical || yDiff >= 0.0) { - return falsingEvaluation; - } - break; - case Classifier.LEFT_AFFORDANCE: - if (xDiff < 0.0 && yDiff > 0.0) { - return falsingEvaluation; - } - break; - case Classifier.RIGHT_AFFORDANCE: - if (xDiff > 0.0 && yDiff > 0.0) { - return falsingEvaluation; - } - default: - break; - } - return 0.0f; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/DurationCountClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/DurationCountClassifier.java deleted file mode 100644 index 77fda2001f3c5..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/DurationCountClassifier.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -/** - * A classifier which looks at the ratio between the duration of the stroke and its number of - * points. - */ -public class DurationCountClassifier extends StrokeClassifier { - public DurationCountClassifier(ClassifierData classifierData) { - } - - @Override - public String getTag() { - return "DUR"; - } - - @Override - public float getFalseTouchEvaluation(int type, Stroke stroke) { - return DurationCountEvaluator.evaluate(stroke.getDurationSeconds() / stroke.getCount()); - } -} \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/classifier/DurationCountEvaluator.java b/packages/SystemUI/src/com/android/systemui/classifier/DurationCountEvaluator.java deleted file mode 100644 index 5395983968f76..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/DurationCountEvaluator.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - - -public class DurationCountEvaluator { - public static float evaluate(float value) { - float evaluation = 0.0f; - if (value < 0.0105) evaluation++; - if (value < 0.00909) evaluation++; - if (value < 0.00667) evaluation++; - if (value > 0.0333) evaluation++; - if (value > 0.0500) evaluation++; - return evaluation; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/EndPointLengthClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/EndPointLengthClassifier.java deleted file mode 100644 index de8a18860c382..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/EndPointLengthClassifier.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -/** - * A classifier which looks at the distance between the first and the last point from the stroke. - */ -public class EndPointLengthClassifier extends StrokeClassifier { - public EndPointLengthClassifier(ClassifierData classifierData) { - } - - @Override - public String getTag() { - return "END_LNGTH"; - } - - @Override - public float getFalseTouchEvaluation(int type, Stroke stroke) { - return EndPointLengthEvaluator.evaluate(stroke.getEndPointLength()); - } -} \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/classifier/EndPointLengthEvaluator.java b/packages/SystemUI/src/com/android/systemui/classifier/EndPointLengthEvaluator.java deleted file mode 100644 index bb2f1c4e355db..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/EndPointLengthEvaluator.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -public class EndPointLengthEvaluator { - public static float evaluate(float value) { - float evaluation = 0.0f; - if (value < 0.05) evaluation += 2.0; - if (value < 0.1) evaluation += 2.0; - if (value < 0.2) evaluation += 2.0; - if (value < 0.3) evaluation += 2.0; - if (value < 0.4) evaluation += 2.0; - if (value < 0.5) evaluation += 2.0; - return evaluation; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/EndPointRatioClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/EndPointRatioClassifier.java deleted file mode 100644 index 9b6ddc8ffb2f4..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/EndPointRatioClassifier.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -/** - * A classifier which looks at the ratio between the total length covered by the stroke and the - * distance between the first and last point from this stroke. - */ -public class EndPointRatioClassifier extends StrokeClassifier { - public EndPointRatioClassifier(ClassifierData classifierData) { - mClassifierData = classifierData; - } - - @Override - public String getTag() { - return "END_RTIO"; - } - - @Override - public float getFalseTouchEvaluation(int type, Stroke stroke) { - float ratio; - if (stroke.getTotalLength() == 0.0f) { - ratio = 1.0f; - } else { - ratio = stroke.getEndPointLength() / stroke.getTotalLength(); - } - return EndPointRatioEvaluator.evaluate(ratio); - } -} \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/classifier/EndPointRatioEvaluator.java b/packages/SystemUI/src/com/android/systemui/classifier/EndPointRatioEvaluator.java deleted file mode 100644 index 529fcec2710ee..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/EndPointRatioEvaluator.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -public class EndPointRatioEvaluator { - public static float evaluate(float value) { - float evaluation = 0.0f; - if (value < 0.85) evaluation++; - if (value < 0.75) evaluation++; - if (value < 0.65) evaluation++; - if (value < 0.55) evaluation++; - if (value < 0.45) evaluation++; - if (value < 0.35) evaluation++; - return evaluation; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingLog.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingLog.java deleted file mode 100644 index 8105c6a6e9402..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingLog.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -import android.app.ActivityThread; -import android.app.Application; -import android.os.Build; -import android.os.SystemProperties; -import android.util.Log; - -import java.io.File; -import java.io.IOException; -import java.io.PrintWriter; -import java.text.SimpleDateFormat; -import java.util.ArrayDeque; -import java.util.Date; -import java.util.Locale; - -/** - * Keeps track of interesting falsing data. - * - * By default the log only gets collected on userdebug builds. To turn it on on user: - * adb shell setprop debug.falsing_log true - * - * The log gets dumped as part of the SystemUI services. To dump on demand: - * adb shell dumpsys activity service com.android.systemui StatusBar | grep -A 999 FALSING | less - * - * To dump into logcat: - * adb shell setprop debug.falsing_logcat true - * - * To adjust the log buffer size: - * adb shell setprop debug.falsing_log_size 200 - */ -public class FalsingLog { - public static final boolean ENABLED = SystemProperties.getBoolean("debug.falsing_log", - Build.IS_DEBUGGABLE); - private static final boolean LOGCAT = SystemProperties.getBoolean("debug.falsing_logcat", - false); - - public static final boolean VERBOSE = false; - - private static final int MAX_SIZE = SystemProperties.getInt("debug.falsing_log_size", 100); - - private static final String TAG = "FalsingLog"; - - private final ArrayDeque mLog = new ArrayDeque<>(MAX_SIZE); - private final SimpleDateFormat mFormat = new SimpleDateFormat("MM-dd HH:mm:ss", Locale.US); - - private static FalsingLog sInstance; - - private FalsingLog() { - } - - public static void v(String tag, String s) { - if (!VERBOSE) { - return; - } - if (LOGCAT) { - Log.v(TAG, tag + "\t" + s); - } - log("V", tag, s); - } - - public static void i(String tag, String s) { - if (LOGCAT) { - Log.i(TAG, tag + "\t" + s); - } - log("I", tag, s); - } - - public static void wLogcat(String tag, String s) { - Log.w(TAG, tag + "\t" + s); - log("W", tag, s); - } - - public static void w(String tag, String s) { - if (LOGCAT) { - Log.w(TAG, tag + "\t" + s); - } - log("W", tag, s); - } - - public static void e(String tag, String s) { - if (LOGCAT) { - Log.e(TAG, tag + "\t" + s); - } - log("E", tag, s); - } - - public static synchronized void log(String level, String tag, String s) { - if (!ENABLED) { - return; - } - if (sInstance == null) { - sInstance = new FalsingLog(); - } - - if (sInstance.mLog.size() >= MAX_SIZE) { - sInstance.mLog.removeFirst(); - } - String entry = new StringBuilder().append(sInstance.mFormat.format(new Date())) - .append(" ").append(level).append(" ") - .append(tag).append(" ").append(s).toString(); - sInstance.mLog.add(entry); - } - - public static synchronized void dump(PrintWriter pw) { - pw.println("FALSING LOG:"); - if (!ENABLED) { - pw.println("Disabled, to enable: setprop debug.falsing_log 1"); - pw.println(); - return; - } - if (sInstance == null || sInstance.mLog.isEmpty()) { - pw.println(""); - pw.println(); - return; - } - for (String s : sInstance.mLog) { - pw.println(s); - } - pw.println(); - } - - public static synchronized void wtf(String tag, String s, Throwable here) { - if (!ENABLED) { - return; - } - e(tag, s); - - Application application = ActivityThread.currentApplication(); - String fileMessage = ""; - if (Build.IS_DEBUGGABLE && application != null) { - File f = new File(application.getDataDir(), "falsing-" - + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) + ".txt"); - PrintWriter pw = null; - try { - pw = new PrintWriter(f); - dump(pw); - pw.close(); - fileMessage = "Log written to " + f.getAbsolutePath(); - } catch (IOException e) { - Log.e(TAG, "Unable to write falsing log", e); - } finally { - if (pw != null) { - pw.close(); - } - } - } else { - Log.e(TAG, "Unable to write log, build must be debuggable."); - } - - Log.wtf(TAG, tag + " " + s + "; " + fileMessage, here); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java index 87ee4d96c0ce5..121484303b994 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java @@ -22,6 +22,7 @@ import android.view.MotionEvent; import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.plugins.FalsingManager; +import java.io.FileDescriptor; import java.io.PrintWriter; /** @@ -261,8 +262,7 @@ public class FalsingManagerFake implements FalsingManager { } @Override - public void dump(PrintWriter pw) { - + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { } @Override diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java deleted file mode 100644 index db58a45bf54e6..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerImpl.java +++ /dev/null @@ -1,589 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.classifier; - -import android.app.ActivityManager; -import android.content.Context; -import android.database.ContentObserver; -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; -import android.hardware.SensorManager; -import android.hardware.biometrics.BiometricSourceType; -import android.net.Uri; -import android.os.Handler; -import android.os.Looper; -import android.os.PowerManager; -import android.os.UserHandle; -import android.provider.Settings; -import android.view.InputDevice; -import android.view.MotionEvent; -import android.view.accessibility.AccessibilityManager; - -import com.android.internal.logging.MetricsLogger; -import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.keyguard.KeyguardUpdateMonitorCallback; -import com.android.systemui.Dependency; -import com.android.systemui.analytics.DataCollector; -import com.android.systemui.dagger.qualifiers.UiBackground; -import com.android.systemui.plugins.FalsingManager; -import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; -import com.android.systemui.statusbar.StatusBarState; -import com.android.systemui.util.sensors.AsyncSensorManager; - -import java.io.PrintWriter; -import java.util.concurrent.Executor; - -/** - * When the phone is locked, listens to touch, sensor and phone events and sends them to - * DataCollector and HumanInteractionClassifier. - * - * It does not collect touch events when the bouncer shows up. - */ -public class FalsingManagerImpl implements FalsingManager { - private static final String ENFORCE_BOUNCER = "falsing_manager_enforce_bouncer"; - - private static final int[] CLASSIFIER_SENSORS = new int[] { - Sensor.TYPE_PROXIMITY, - }; - - private static final int[] COLLECTOR_SENSORS = new int[] { - Sensor.TYPE_ACCELEROMETER, - Sensor.TYPE_GYROSCOPE, - Sensor.TYPE_PROXIMITY, - Sensor.TYPE_LIGHT, - Sensor.TYPE_ROTATION_VECTOR, - }; - public static final String FALSING_REMAIN_LOCKED = "falsing_failure_after_attempts"; - public static final String FALSING_SUCCESS = "falsing_success_after_attempts"; - - private final Handler mHandler = new Handler(Looper.getMainLooper()); - private final Context mContext; - - private final SensorManager mSensorManager; - private final DataCollector mDataCollector; - private final HumanInteractionClassifier mHumanInteractionClassifier; - private final AccessibilityManager mAccessibilityManager; - private final Executor mUiBgExecutor; - - private boolean mEnforceBouncer = false; - private boolean mBouncerOn = false; - private boolean mBouncerOffOnDown = false; - private boolean mSessionActive = false; - private boolean mIsTouchScreen = true; - private boolean mJustUnlockedWithFace = false; - private int mState = StatusBarState.SHADE; - private boolean mScreenOn; - private boolean mShowingAod; - private Runnable mPendingWtf; - private int mIsFalseTouchCalls; - private MetricsLogger mMetricsLogger; - - private SensorEventListener mSensorEventListener = new SensorEventListener() { - @Override - public synchronized void onSensorChanged(SensorEvent event) { - mDataCollector.onSensorChanged(event); - mHumanInteractionClassifier.onSensorChanged(event); - } - - @Override - public void onAccuracyChanged(Sensor sensor, int accuracy) { - mDataCollector.onAccuracyChanged(sensor, accuracy); - } - }; - - public StateListener mStatusBarStateListener = new StateListener() { - @Override - public void onStateChanged(int newState) { - if (FalsingLog.ENABLED) { - FalsingLog.i("setStatusBarState", new StringBuilder() - .append("from=").append(StatusBarState.toShortString(mState)) - .append(" to=").append(StatusBarState.toShortString(newState)) - .toString()); - } - mState = newState; - updateSessionActive(); - } - }; - - protected final ContentObserver mSettingsObserver = new ContentObserver(mHandler) { - @Override - public void onChange(boolean selfChange) { - updateConfiguration(); - } - }; - private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback = - new KeyguardUpdateMonitorCallback() { - @Override - public void onBiometricAuthenticated(int userId, - BiometricSourceType biometricSourceType, - boolean isStrongBiometric) { - if (userId == KeyguardUpdateMonitor.getCurrentUser() - && biometricSourceType == BiometricSourceType.FACE) { - mJustUnlockedWithFace = true; - } - } - }; - - FalsingManagerImpl(Context context, @UiBackground Executor uiBgExecutor) { - mContext = context; - mSensorManager = Dependency.get(AsyncSensorManager.class); - mAccessibilityManager = context.getSystemService(AccessibilityManager.class); - mDataCollector = DataCollector.getInstance(mContext); - mHumanInteractionClassifier = HumanInteractionClassifier.getInstance(mContext); - mUiBgExecutor = uiBgExecutor; - mScreenOn = context.getSystemService(PowerManager.class).isInteractive(); - mMetricsLogger = new MetricsLogger(); - - mContext.getContentResolver().registerContentObserver( - Settings.Secure.getUriFor(ENFORCE_BOUNCER), false, - mSettingsObserver, - UserHandle.USER_ALL); - - updateConfiguration(); - Dependency.get(StatusBarStateController.class).addCallback(mStatusBarStateListener); - Dependency.get(KeyguardUpdateMonitor.class).registerCallback(mKeyguardUpdateCallback); - } - - private void updateConfiguration() { - mEnforceBouncer = 0 != Settings.Secure.getInt(mContext.getContentResolver(), - ENFORCE_BOUNCER, 0); - } - - private boolean shouldSessionBeActive() { - if (FalsingLog.ENABLED && FalsingLog.VERBOSE) { - FalsingLog.v("shouldBeActive", new StringBuilder() - .append("enabled=").append(isEnabled() ? 1 : 0) - .append(" mScreenOn=").append(mScreenOn ? 1 : 0) - .append(" mState=").append(StatusBarState.toShortString(mState)) - .append(" mShowingAod=").append(mShowingAod ? 1 : 0) - .toString() - ); - } - return isEnabled() && mScreenOn && (mState == StatusBarState.KEYGUARD) && !mShowingAod; - } - - private boolean sessionEntrypoint() { - if (!mSessionActive && shouldSessionBeActive()) { - onSessionStart(); - return true; - } - return false; - } - - private void sessionExitpoint(boolean force) { - if (mSessionActive && (force || !shouldSessionBeActive())) { - mSessionActive = false; - if (mIsFalseTouchCalls != 0) { - if (FalsingLog.ENABLED) { - FalsingLog.i( - "isFalseTouchCalls", "Calls before failure: " + mIsFalseTouchCalls); - } - mMetricsLogger.histogram(FALSING_REMAIN_LOCKED, mIsFalseTouchCalls); - mIsFalseTouchCalls = 0; - } - - // This can be expensive, and doesn't need to happen on the main thread. - mUiBgExecutor.execute(() -> { - mSensorManager.unregisterListener(mSensorEventListener); - }); - } - } - - public void updateSessionActive() { - if (shouldSessionBeActive()) { - sessionEntrypoint(); - } else { - sessionExitpoint(false /* force */); - } - } - - private void onSessionStart() { - if (FalsingLog.ENABLED) { - FalsingLog.i("onSessionStart", "classifierEnabled=" + isClassifierEnabled()); - clearPendingWtf(); - } - mBouncerOn = false; - mSessionActive = true; - mJustUnlockedWithFace = false; - mIsFalseTouchCalls = 0; - - if (mHumanInteractionClassifier.isEnabled()) { - registerSensors(CLASSIFIER_SENSORS); - } - if (mDataCollector.isEnabledFull()) { - registerSensors(COLLECTOR_SENSORS); - } - if (mDataCollector.isEnabled()) { - mDataCollector.onFalsingSessionStarted(); - } - } - - private void registerSensors(int [] sensors) { - for (int sensorType : sensors) { - Sensor s = mSensorManager.getDefaultSensor(sensorType); - if (s != null) { - - // This can be expensive, and doesn't need to happen on the main thread. - mUiBgExecutor.execute(() -> { - mSensorManager.registerListener( - mSensorEventListener, s, SensorManager.SENSOR_DELAY_GAME); - }); - } - } - } - - public boolean isClassifierEnabled() { - return mHumanInteractionClassifier.isEnabled(); - } - - private boolean isEnabled() { - return mHumanInteractionClassifier.isEnabled() || mDataCollector.isEnabled(); - } - - public boolean isUnlockingDisabled() { - return mDataCollector.isUnlockingDisabled(); - } - /** - * @return true if the classifier determined that this is not a human interacting with the phone - */ - public boolean isFalseTouch(@Classifier.InteractionType int interactionType) { - if (FalsingLog.ENABLED) { - // We're getting some false wtfs from touches that happen after the device went - // to sleep. Only report missing sessions that happen when the device is interactive. - if (!mSessionActive && mContext.getSystemService(PowerManager.class).isInteractive() - && mPendingWtf == null) { - int enabled = isEnabled() ? 1 : 0; - int screenOn = mScreenOn ? 1 : 0; - String state = StatusBarState.toShortString(mState); - Throwable here = new Throwable("here"); - FalsingLog.wLogcat("isFalseTouch", new StringBuilder() - .append("Session is not active, yet there's a query for a false touch.") - .append(" enabled=").append(enabled) - .append(" mScreenOn=").append(screenOn) - .append(" mState=").append(state) - .append(". Escalating to WTF if screen does not turn on soon.") - .toString()); - - // Unfortunately we're also getting false positives for touches that happen right - // after the screen turns on, but before that notification has made it to us. - // Unfortunately there's no good way to catch that, except to wait and see if we get - // the screen on notification soon. - mPendingWtf = () -> FalsingLog.wtf("isFalseTouch", new StringBuilder() - .append("Session did not become active after query for a false touch.") - .append(" enabled=").append(enabled) - .append('/').append(isEnabled() ? 1 : 0) - .append(" mScreenOn=").append(screenOn) - .append('/').append(mScreenOn ? 1 : 0) - .append(" mState=").append(state) - .append('/').append(StatusBarState.toShortString(mState)) - .append(". Look for warnings ~1000ms earlier to see root cause.") - .toString(), here); - mHandler.postDelayed(mPendingWtf, 1000); - } - } - if (ActivityManager.isRunningInUserTestHarness()) { - // This is a test device running UiAutomator code. - return false; - } - if (mAccessibilityManager.isTouchExplorationEnabled()) { - // Touch exploration triggers false positives in the classifier and - // already sufficiently prevents false unlocks. - return false; - } - if (!mIsTouchScreen) { - // Unlocking with input devices besides the touchscreen should already be sufficiently - // anti-falsed. - return false; - } - if (mJustUnlockedWithFace) { - // Unlocking with face is a strong user presence signal, we can assume the user - // is present until the next session starts. - return false; - } - mIsFalseTouchCalls++; - boolean isFalse = mHumanInteractionClassifier.isFalseTouch(); - if (!isFalse) { - if (FalsingLog.ENABLED) { - FalsingLog.i("isFalseTouchCalls", "Calls before success: " + mIsFalseTouchCalls); - } - mMetricsLogger.histogram(FALSING_SUCCESS, mIsFalseTouchCalls); - mIsFalseTouchCalls = 0; - } - return isFalse; - } - - @Override - public boolean isFalseTap(boolean robustCheck) { - return true; - } - - @Override - public boolean isFalseDoubleTap() { - return false; - } - - private void clearPendingWtf() { - if (mPendingWtf != null) { - mHandler.removeCallbacks(mPendingWtf); - mPendingWtf = null; - } - } - - - public boolean shouldEnforceBouncer() { - return mEnforceBouncer; - } - - public void setShowingAod(boolean showingAod) { - mShowingAod = showingAod; - updateSessionActive(); - } - - public void onScreenTurningOn() { - if (FalsingLog.ENABLED) { - FalsingLog.i("onScreenTurningOn", new StringBuilder() - .append("from=").append(mScreenOn ? 1 : 0) - .toString()); - clearPendingWtf(); - } - mScreenOn = true; - if (sessionEntrypoint()) { - mDataCollector.onScreenTurningOn(); - } - } - - public void onScreenOnFromTouch() { - if (FalsingLog.ENABLED) { - FalsingLog.i("onScreenOnFromTouch", new StringBuilder() - .append("from=").append(mScreenOn ? 1 : 0) - .toString()); - } - mScreenOn = true; - if (sessionEntrypoint()) { - mDataCollector.onScreenOnFromTouch(); - } - } - - public void onScreenOff() { - if (FalsingLog.ENABLED) { - FalsingLog.i("onScreenOff", new StringBuilder() - .append("from=").append(mScreenOn ? 1 : 0) - .toString()); - } - mDataCollector.onScreenOff(); - mScreenOn = false; - sessionExitpoint(false /* force */); - } - - public void onSuccessfulUnlock() { - if (FalsingLog.ENABLED) { - FalsingLog.i("onSucccessfulUnlock", ""); - } - mDataCollector.onSucccessfulUnlock(); - } - - public void onBouncerShown() { - if (FalsingLog.ENABLED) { - FalsingLog.i("onBouncerShown", new StringBuilder() - .append("from=").append(mBouncerOn ? 1 : 0) - .toString()); - } - if (!mBouncerOn) { - mBouncerOn = true; - mDataCollector.onBouncerShown(); - } - } - - public void onBouncerHidden() { - if (FalsingLog.ENABLED) { - FalsingLog.i("onBouncerHidden", new StringBuilder() - .append("from=").append(mBouncerOn ? 1 : 0) - .toString()); - } - if (mBouncerOn) { - mBouncerOn = false; - mDataCollector.onBouncerHidden(); - } - } - - public void onQsDown() { - if (FalsingLog.ENABLED) { - FalsingLog.i("onQsDown", ""); - } - mHumanInteractionClassifier.setType(Classifier.QUICK_SETTINGS); - mDataCollector.onQsDown(); - } - - public void setQsExpanded(boolean expanded) { - mDataCollector.setQsExpanded(expanded); - } - - public void onTrackingStarted(boolean secure) { - if (FalsingLog.ENABLED) { - FalsingLog.i("onTrackingStarted", ""); - } - mHumanInteractionClassifier.setType(secure - ? Classifier.BOUNCER_UNLOCK : Classifier.UNLOCK); - mDataCollector.onTrackingStarted(); - } - - public void onTrackingStopped() { - mDataCollector.onTrackingStopped(); - } - - public void onNotificationActive() { - mDataCollector.onNotificationActive(); - } - - public void onNotificationDoubleTap(boolean accepted, float dx, float dy) { - if (FalsingLog.ENABLED) { - FalsingLog.i("onNotificationDoubleTap", "accepted=" + accepted - + " dx=" + dx + " dy=" + dy + " (px)"); - } - mDataCollector.onNotificationDoubleTap(); - } - - public void setNotificationExpanded() { - mDataCollector.setNotificationExpanded(); - } - - public void onNotificatonStartDraggingDown() { - if (FalsingLog.ENABLED) { - FalsingLog.i("onNotificatonStartDraggingDown", ""); - } - mHumanInteractionClassifier.setType(Classifier.NOTIFICATION_DRAG_DOWN); - mDataCollector.onNotificatonStartDraggingDown(); - } - - public void onStartExpandingFromPulse() { - if (FalsingLog.ENABLED) { - FalsingLog.i("onStartExpandingFromPulse", ""); - } - mHumanInteractionClassifier.setType(Classifier.PULSE_EXPAND); - mDataCollector.onStartExpandingFromPulse(); - } - - public void onNotificatonStopDraggingDown() { - mDataCollector.onNotificatonStopDraggingDown(); - } - - public void onExpansionFromPulseStopped() { - mDataCollector.onExpansionFromPulseStopped(); - } - - public void onNotificationDismissed() { - mDataCollector.onNotificationDismissed(); - } - - public void onNotificationStartDismissing() { - if (FalsingLog.ENABLED) { - FalsingLog.i("onNotificationStartDismissing", ""); - } - mHumanInteractionClassifier.setType(Classifier.NOTIFICATION_DISMISS); - mDataCollector.onNotificatonStartDismissing(); - } - - public void onNotificationStopDismissing() { - mDataCollector.onNotificatonStopDismissing(); - } - - public void onCameraOn() { - mDataCollector.onCameraOn(); - } - - public void onLeftAffordanceOn() { - mDataCollector.onLeftAffordanceOn(); - } - - public void onAffordanceSwipingStarted(boolean rightCorner) { - if (FalsingLog.ENABLED) { - FalsingLog.i("onAffordanceSwipingStarted", ""); - } - if (rightCorner) { - mHumanInteractionClassifier.setType(Classifier.RIGHT_AFFORDANCE); - } else { - mHumanInteractionClassifier.setType(Classifier.LEFT_AFFORDANCE); - } - mDataCollector.onAffordanceSwipingStarted(rightCorner); - } - - public void onAffordanceSwipingAborted() { - mDataCollector.onAffordanceSwipingAborted(); - } - - public void onUnlockHintStarted() { - mDataCollector.onUnlockHintStarted(); - } - - public void onCameraHintStarted() { - mDataCollector.onCameraHintStarted(); - } - - public void onLeftAffordanceHintStarted() { - mDataCollector.onLeftAffordanceHintStarted(); - } - - public void onTouchEvent(MotionEvent event, int width, int height) { - if (event.getAction() == MotionEvent.ACTION_DOWN) { - mIsTouchScreen = event.isFromSource(InputDevice.SOURCE_TOUCHSCREEN); - // If the bouncer was not shown during the down event, - // we want the entire gesture going to HumanInteractionClassifier - mBouncerOffOnDown = !mBouncerOn; - } - if (mSessionActive) { - if (!mBouncerOn) { - // In case bouncer is "visible", but onFullyShown has not yet been called, - // avoid adding the event to DataCollector - mDataCollector.onTouchEvent(event, width, height); - } - if (mBouncerOffOnDown) { - mHumanInteractionClassifier.onTouchEvent(event); - } - } - } - - public void dump(PrintWriter pw) { - pw.println("FALSING MANAGER"); - pw.print("classifierEnabled="); pw.println(isClassifierEnabled() ? 1 : 0); - pw.print("mSessionActive="); pw.println(mSessionActive ? 1 : 0); - pw.print("mBouncerOn="); pw.println(mSessionActive ? 1 : 0); - pw.print("mState="); pw.println(StatusBarState.toShortString(mState)); - pw.print("mScreenOn="); pw.println(mScreenOn ? 1 : 0); - pw.println(); - } - - @Override - public void cleanup() { - mSensorManager.unregisterListener(mSensorEventListener); - mContext.getContentResolver().unregisterContentObserver(mSettingsObserver); - Dependency.get(StatusBarStateController.class).removeCallback(mStatusBarStateListener); - Dependency.get(KeyguardUpdateMonitor.class).removeCallback(mKeyguardUpdateCallback); - } - - public Uri reportRejectedTouch() { - if (mDataCollector.isEnabled()) { - return mDataCollector.reportRejectedTouch(); - } - return null; - } - - public boolean isReportingEnabled() { - return mDataCollector.isReportingEnabled(); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java index f8741bf7b553e..814fff9c6d43d 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java @@ -16,8 +16,6 @@ package com.android.systemui.classifier; -import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_MANAGER_ENABLED; - import android.content.Context; import android.content.res.Resources; import android.hardware.SensorManager; @@ -35,7 +33,6 @@ import com.android.systemui.classifier.brightline.BrightLineFalsingManager; import com.android.systemui.classifier.brightline.FalsingDataProvider; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; -import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.dock.DockManager; import com.android.systemui.dump.DumpManager; import com.android.systemui.plugins.FalsingManager; @@ -55,41 +52,48 @@ import javax.inject.Inject; /** * Simple passthrough implementation of {@link FalsingManager} allowing plugins to swap in. * - * {@link FalsingManagerImpl} is used when a Plugin is not loaded. + * {@link BrightLineFalsingManager} is used when a Plugin is not loaded. */ @SysUISingleton public class FalsingManagerProxy implements FalsingManager, Dumpable { private static final String PROXIMITY_SENSOR_TAG = "FalsingManager"; + private static final String DUMPABLE_TAG = "FalsingManager"; + public static final String FALSING_REMAIN_LOCKED = "falsing_failure_after_attempts"; + public static final String FALSING_SUCCESS = "falsing_success_after_attempts"; + private final PluginManager mPluginManager; private final ProximitySensor mProximitySensor; private final Resources mResources; private final ViewConfiguration mViewConfiguration; private final FalsingDataProvider mFalsingDataProvider; - private FalsingManager mInternalFalsingManager; - private DeviceConfig.OnPropertiesChangedListener mDeviceConfigListener; private final DeviceConfigProxy mDeviceConfig; - private boolean mBrightlineEnabled; private final DockManager mDockManager; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; - private Executor mUiBgExecutor; + private final DumpManager mDumpManager; private final StatusBarStateController mStatusBarStateController; + final PluginListener mPluginListener; + + private FalsingManager mInternalFalsingManager; + + private final DeviceConfig.OnPropertiesChangedListener mDeviceConfigListener = + properties -> onDeviceConfigPropertiesChanged(properties.getNamespace()); @Inject - FalsingManagerProxy(Context context, PluginManager pluginManager, @Main Executor executor, + FalsingManagerProxy(PluginManager pluginManager, @Main Executor executor, ProximitySensor proximitySensor, DeviceConfigProxy deviceConfig, DockManager dockManager, KeyguardUpdateMonitor keyguardUpdateMonitor, DumpManager dumpManager, - @UiBackground Executor uiBgExecutor, StatusBarStateController statusBarStateController, @Main Resources resources, ViewConfiguration viewConfiguration, FalsingDataProvider falsingDataProvider) { + mPluginManager = pluginManager; mProximitySensor = proximitySensor; mDockManager = dockManager; mKeyguardUpdateMonitor = keyguardUpdateMonitor; - mUiBgExecutor = uiBgExecutor; + mDumpManager = dumpManager; mStatusBarStateController = statusBarStateController; mResources = resources; mViewConfiguration = viewConfiguration; @@ -97,16 +101,14 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable { mProximitySensor.setTag(PROXIMITY_SENSOR_TAG); mProximitySensor.setDelay(SensorManager.SENSOR_DELAY_GAME); mDeviceConfig = deviceConfig; - mDeviceConfigListener = - properties -> onDeviceConfigPropertiesChanged(context, properties.getNamespace()); - setupFalsingManager(context); + setupFalsingManager(); mDeviceConfig.addOnPropertiesChangedListener( DeviceConfig.NAMESPACE_SYSTEMUI, executor, mDeviceConfigListener ); - final PluginListener mPluginListener = new PluginListener() { + mPluginListener = new PluginListener() { public void onPluginConnected(FalsingPlugin plugin, Context context) { FalsingManager pluginFalsingManager = plugin.getFalsingManager(context); if (pluginFalsingManager != null) { @@ -116,51 +118,42 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable { } public void onPluginDisconnected(FalsingPlugin plugin) { - mInternalFalsingManager = new FalsingManagerImpl(context, mUiBgExecutor); + setupFalsingManager(); } }; - pluginManager.addPluginListener(mPluginListener, FalsingPlugin.class); + mPluginManager.addPluginListener(mPluginListener, FalsingPlugin.class); - dumpManager.registerDumpable("FalsingManager", this); + mDumpManager.registerDumpable(DUMPABLE_TAG, this); } - private void onDeviceConfigPropertiesChanged(Context context, String namespace) { + private void onDeviceConfigPropertiesChanged(String namespace) { if (!DeviceConfig.NAMESPACE_SYSTEMUI.equals(namespace)) { return; } - setupFalsingManager(context); + setupFalsingManager(); } /** - * Chooses the FalsingManager implementation. + * Setup the FalsingManager implementation. + * + * If multiple implementations are available, this is where the choice is made. */ - private void setupFalsingManager(Context context) { - boolean brightlineEnabled = mDeviceConfig.getBoolean( - DeviceConfig.NAMESPACE_SYSTEMUI, BRIGHTLINE_FALSING_MANAGER_ENABLED, true); - if (brightlineEnabled == mBrightlineEnabled && mInternalFalsingManager != null) { - return; - } - mBrightlineEnabled = brightlineEnabled; - + private void setupFalsingManager() { if (mInternalFalsingManager != null) { mInternalFalsingManager.cleanup(); } - if (!brightlineEnabled) { - mInternalFalsingManager = new FalsingManagerImpl(context, mUiBgExecutor); - } else { - mInternalFalsingManager = new BrightLineFalsingManager( - mFalsingDataProvider, - mKeyguardUpdateMonitor, - mProximitySensor, - mDeviceConfig, - mResources, - mViewConfiguration, - mDockManager, - mStatusBarStateController - ); - } + mInternalFalsingManager = new BrightLineFalsingManager( + mFalsingDataProvider, + mKeyguardUpdateMonitor, + mProximitySensor, + mDeviceConfig, + mResources, + mViewConfiguration, + mDockManager, + mStatusBarStateController + ); } /** @@ -359,17 +352,14 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable { @Override public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) { - mInternalFalsingManager.dump(pw); - } - - @Override - public void dump(PrintWriter pw) { - mInternalFalsingManager.dump(pw); + mInternalFalsingManager.dump(fd, pw, args); } @Override public void cleanup() { mDeviceConfig.removeOnPropertiesChangedListener(mDeviceConfigListener); + mPluginManager.removePluginListener(mPluginListener); + mDumpManager.unregisterDumpable(DUMPABLE_TAG); mInternalFalsingManager.cleanup(); } } diff --git a/packages/SystemUI/src/com/android/systemui/classifier/GestureClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/GestureClassifier.java deleted file mode 100644 index 11388fc49594c..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/GestureClassifier.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -/** - * An abstract class for classifiers which classify the whole gesture (all the strokes which - * occurred from DOWN event to UP/CANCEL event) - */ -public abstract class GestureClassifier extends Classifier { - - /** - * @param type the type of action for which this method is called - * @return a non-negative value which is used to determine whether the most recent gesture is a - * false interaction; the bigger the value the greater the chance that this a false - * interaction. - */ - public abstract float getFalseTouchEvaluation(int type); -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/HistoryEvaluator.java b/packages/SystemUI/src/com/android/systemui/classifier/HistoryEvaluator.java deleted file mode 100644 index 4c647118a1058..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/HistoryEvaluator.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -import android.os.SystemClock; - -import java.util.ArrayList; - -/** - * Holds the evaluations for ended strokes and gestures. These values are decreased through time. - */ -public class HistoryEvaluator { - private static final float INTERVAL = 50.0f; - private static final float HISTORY_FACTOR = 0.9f; - private static final float EPSILON = 1e-5f; - - private final ArrayList mStrokes = new ArrayList<>(); - private final ArrayList mGestureWeights = new ArrayList<>(); - private long mLastUpdate; - - public HistoryEvaluator() { - mLastUpdate = SystemClock.elapsedRealtime(); - } - - public void addStroke(float evaluation) { - decayValue(); - mStrokes.add(new Data(evaluation)); - } - - public void addGesture(float evaluation) { - decayValue(); - mGestureWeights.add(new Data(evaluation)); - } - - /** - * Calculates the weighted average of strokes and adds to it the weighted average of gestures - */ - public float getEvaluation() { - return weightedAverage(mStrokes) + weightedAverage(mGestureWeights); - } - - private float weightedAverage(ArrayList list) { - float sumValue = 0.0f; - float sumWeight = 0.0f; - int size = list.size(); - for (int i = 0; i < size; i++) { - Data data = list.get(i); - sumValue += data.evaluation * data.weight; - sumWeight += data.weight; - } - - if (sumWeight == 0.0f) { - return 0.0f; - } - - return sumValue / sumWeight; - } - - private void decayValue() { - long time = SystemClock.elapsedRealtime(); - - if (time <= mLastUpdate) { - return; - } - - // All weights are multiplied by HISTORY_FACTOR after each INTERVAL milliseconds. - float factor = (float) Math.pow(HISTORY_FACTOR, (time - mLastUpdate) / INTERVAL); - - decayValue(mStrokes, factor); - decayValue(mGestureWeights, factor); - mLastUpdate = time; - } - - private void decayValue(ArrayList list, float factor) { - int size = list.size(); - for (int i = 0; i < size; i++) { - list.get(i).weight *= factor; - } - - // Removing evaluations with such small weights that they do not matter anymore - while (!list.isEmpty() && isZero(list.get(0).weight)) { - list.remove(0); - } - } - - private boolean isZero(float x) { - return x <= EPSILON && x >= -EPSILON; - } - - /** - * For each stroke it holds its initial value and the current weight. Initially the - * weight is set to 1.0 - */ - private static class Data { - public float evaluation; - public float weight; - - public Data(float evaluation) { - this.evaluation = evaluation; - weight = 1.0f; - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java deleted file mode 100644 index 86dccb2228753..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/HumanInteractionClassifier.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -import android.content.Context; -import android.database.ContentObserver; -import android.hardware.SensorEvent; -import android.os.Handler; -import android.os.Looper; -import android.os.UserHandle; -import android.provider.Settings; -import android.util.DisplayMetrics; -import android.view.MotionEvent; - -import com.android.systemui.R; - -import java.util.ArrayDeque; - -/** - * An classifier trying to determine whether it is a human interacting with the phone or not. - */ -public class HumanInteractionClassifier extends Classifier { - private static final String HIC_ENABLE = "HIC_enable"; - private static final float FINGER_DISTANCE = 0.1f; - - private static HumanInteractionClassifier sInstance = null; - - private final Handler mHandler = new Handler(Looper.getMainLooper()); - private final Context mContext; - - private final StrokeClassifier[] mStrokeClassifiers; - private final GestureClassifier[] mGestureClassifiers; - private final ArrayDeque mBufferedEvents = new ArrayDeque<>(); - private final HistoryEvaluator mHistoryEvaluator; - private final float mDpi; - - private boolean mEnableClassifier = false; - private int mCurrentType = Classifier.GENERIC; - - protected final ContentObserver mSettingsObserver = new ContentObserver(mHandler) { - @Override - public void onChange(boolean selfChange) { - updateConfiguration(); - } - }; - - private HumanInteractionClassifier(Context context) { - mContext = context; - DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics(); - - // If the phone is rotated to landscape, the calculations would be wrong if xdpi and ydpi - // were to be used separately. Due negligible differences in xdpi and ydpi we can just - // take the average. - // Note that xdpi and ydpi are the physical pixels per inch and are not affected by scaling. - mDpi = (displayMetrics.xdpi + displayMetrics.ydpi) / 2.0f; - mClassifierData = new ClassifierData(mDpi); - mHistoryEvaluator = new HistoryEvaluator(); - - mStrokeClassifiers = new StrokeClassifier[]{ - new AnglesClassifier(mClassifierData), - new SpeedClassifier(mClassifierData), - new DurationCountClassifier(mClassifierData), - new EndPointRatioClassifier(mClassifierData), - new EndPointLengthClassifier(mClassifierData), - new AccelerationClassifier(mClassifierData), - new SpeedAnglesClassifier(mClassifierData), - new LengthCountClassifier(mClassifierData), - new DirectionClassifier(mClassifierData), - }; - - mGestureClassifiers = new GestureClassifier[] { - new PointerCountClassifier(mClassifierData), - new ProximityClassifier(mClassifierData) - }; - - mContext.getContentResolver().registerContentObserver( - Settings.Global.getUriFor(HIC_ENABLE), false, - mSettingsObserver, - UserHandle.USER_ALL); - - updateConfiguration(); - } - - public static HumanInteractionClassifier getInstance(Context context) { - if (sInstance == null) { - sInstance = new HumanInteractionClassifier(context); - } - return sInstance; - } - - private void updateConfiguration() { - boolean defaultValue = mContext.getResources().getBoolean( - R.bool.config_lockscreenAntiFalsingClassifierEnabled); - - mEnableClassifier = 0 != Settings.Global.getInt( - mContext.getContentResolver(), - HIC_ENABLE, defaultValue ? 1 : 0); - } - - public void setType(int type) { - mCurrentType = type; - } - - @Override - public void onTouchEvent(MotionEvent event) { - if (!mEnableClassifier) { - return; - } - - // If the user is dragging down the notification, they might want to drag it down - // enough to see the content, read it for a while and then lift the finger to open - // the notification. This kind of motion scores very bad in the Classifier so the - // MotionEvents which are close to the current position of the finger are not - // sent to the classifiers until the finger moves far enough. When the finger if lifted - // up, the last MotionEvent which was far enough from the finger is set as the final - // MotionEvent and sent to the Classifiers. - if (mCurrentType == Classifier.NOTIFICATION_DRAG_DOWN - || mCurrentType == Classifier.PULSE_EXPAND) { - mBufferedEvents.add(MotionEvent.obtain(event)); - Point pointEnd = new Point(event.getX() / mDpi, event.getY() / mDpi); - - while (pointEnd.dist(new Point(mBufferedEvents.getFirst().getX() / mDpi, - mBufferedEvents.getFirst().getY() / mDpi)) > FINGER_DISTANCE) { - addTouchEvent(mBufferedEvents.getFirst()); - mBufferedEvents.remove(); - } - - int action = event.getActionMasked(); - if (action == MotionEvent.ACTION_UP) { - mBufferedEvents.getFirst().setAction(MotionEvent.ACTION_UP); - addTouchEvent(mBufferedEvents.getFirst()); - mBufferedEvents.clear(); - } - } else { - addTouchEvent(event); - } - } - - private void addTouchEvent(MotionEvent event) { - if (!mClassifierData.update(event)) { - return; - } - - for (StrokeClassifier c : mStrokeClassifiers) { - c.onTouchEvent(event); - } - - for (GestureClassifier c : mGestureClassifiers) { - c.onTouchEvent(event); - } - - int size = mClassifierData.getEndingStrokes().size(); - for (int i = 0; i < size; i++) { - Stroke stroke = mClassifierData.getEndingStrokes().get(i); - float evaluation = 0.0f; - StringBuilder sb = FalsingLog.ENABLED ? new StringBuilder("stroke") : null; - for (StrokeClassifier c : mStrokeClassifiers) { - float e = c.getFalseTouchEvaluation(mCurrentType, stroke); - if (FalsingLog.ENABLED) { - String tag = c.getTag(); - sb.append(" ").append(e >= 1f ? tag : tag.toLowerCase()).append("=").append(e); - } - evaluation += e; - } - - if (FalsingLog.ENABLED) { - FalsingLog.i(" addTouchEvent", sb.toString()); - } - mHistoryEvaluator.addStroke(evaluation); - } - - int action = event.getActionMasked(); - if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { - float evaluation = 0.0f; - StringBuilder sb = FalsingLog.ENABLED ? new StringBuilder("gesture") : null; - for (GestureClassifier c : mGestureClassifiers) { - float e = c.getFalseTouchEvaluation(mCurrentType); - if (FalsingLog.ENABLED) { - String tag = c.getTag(); - sb.append(" ").append(e >= 1f ? tag : tag.toLowerCase()).append("=").append(e); - } - evaluation += e; - } - if (FalsingLog.ENABLED) { - FalsingLog.i(" addTouchEvent", sb.toString()); - } - mHistoryEvaluator.addGesture(evaluation); - setType(Classifier.GENERIC); - } - - mClassifierData.cleanUp(event); - } - - @Override - public void onSensorChanged(SensorEvent event) { - for (Classifier c : mStrokeClassifiers) { - c.onSensorChanged(event); - } - - for (Classifier c : mGestureClassifiers) { - c.onSensorChanged(event); - } - } - - public boolean isFalseTouch() { - if (mEnableClassifier) { - float evaluation = mHistoryEvaluator.getEvaluation(); - boolean result = evaluation >= 5.0f; - if (FalsingLog.ENABLED) { - FalsingLog.i("isFalseTouch", new StringBuilder() - .append("eval=").append(evaluation).append(" result=") - .append(result ? 1 : 0).toString()); - } - return result; - } - return false; - } - - public boolean isEnabled() { - return mEnableClassifier; - } - - @Override - public String getTag() { - return "HIC"; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/LengthCountClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/LengthCountClassifier.java deleted file mode 100644 index 53678a6d17300..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/LengthCountClassifier.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -/** - * A classifier which looks at the ratio between the length of the stroke and its number of - * points. The number of points is subtracted by 2 because the UP event comes in with some delay - * and it should not influence the ratio and also strokes which are long and have a small number - * of points are punished more (these kind of strokes are usually bad ones and they tend to score - * well in other classifiers). - */ -public class LengthCountClassifier extends StrokeClassifier { - public LengthCountClassifier(ClassifierData classifierData) { - } - - @Override - public String getTag() { - return "LEN_CNT"; - } - - @Override - public float getFalseTouchEvaluation(int type, Stroke stroke) { - return LengthCountEvaluator.evaluate(stroke.getTotalLength() - / Math.max(1.0f, stroke.getCount() - 2)); - } -} \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/classifier/LengthCountEvaluator.java b/packages/SystemUI/src/com/android/systemui/classifier/LengthCountEvaluator.java deleted file mode 100644 index dac7a6f720a77..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/LengthCountEvaluator.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -/** - * A classifier which looks at the ratio between the length of the stroke and its number of - * points. - */ -public class LengthCountEvaluator { - public static float evaluate(float value) { - float evaluation = 0.0f; - if (value < 0.09) evaluation++; - if (value < 0.05) evaluation++; - if (value < 0.02) evaluation++; - if (value > 0.6) evaluation++; - if (value > 0.9) evaluation++; - if (value > 1.2) evaluation++; - return evaluation; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/Point.java b/packages/SystemUI/src/com/android/systemui/classifier/Point.java deleted file mode 100644 index f3dc2be4144be..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/Point.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -public class Point { - public float x; - public float y; - public long timeOffsetNano; - - public Point(float x, float y) { - this.x = x; - this.y = y; - this.timeOffsetNano = 0; - } - - public Point(float x, float y, long timeOffsetNano) { - this.x = x; - this.y = y; - this.timeOffsetNano = timeOffsetNano; - } - - public boolean equals(Point p) { - return x == p.x && y == p.y; - } - - public float dist(Point a) { - return (float) Math.hypot(a.x - x, a.y - y); - } - - /** - * Calculates the cross product of vec(this, a) and vec(this, b) where vec(x,y) is the - * vector from point x to point y - */ - public float crossProduct(Point a, Point b) { - return (a.x - x) * (b.y - y) - (a.y - y) * (b.x - x); - } - - /** - * Calculates the dot product of vec(this, a) and vec(this, b) where vec(x,y) is the - * vector from point x to point y - */ - public float dotProduct(Point a, Point b) { - return (a.x - x) * (b.x - x) + (a.y - y) * (b.y - y); - } - - /** - * Calculates the angle in radians created by points (a, this, b). If any two of these points - * are the same, the method will return 0.0f - * - * @return the angle in radians - */ - public float getAngle(Point a, Point b) { - float dist1 = dist(a); - float dist2 = dist(b); - - if (dist1 == 0.0f || dist2 == 0.0f) { - return 0.0f; - } - - float crossProduct = crossProduct(a, b); - float dotProduct = dotProduct(a, b); - float cos = Math.min(1.0f, Math.max(-1.0f, dotProduct / dist1 / dist2)); - float angle = (float) Math.acos(cos); - if (crossProduct < 0.0) { - angle = 2.0f * (float) Math.PI - angle; - } - return angle; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/PointerCountClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/PointerCountClassifier.java deleted file mode 100644 index 136c43345c9d6..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/PointerCountClassifier.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -import android.view.MotionEvent; - -/** - * A classifier which looks at the total number of traces in the whole gesture. - */ -public class PointerCountClassifier extends GestureClassifier { - private int mCount; - - public PointerCountClassifier(ClassifierData classifierData) { - mCount = 0; - } - - @Override - public String getTag() { - return "PTR_CNT"; - } - - @Override - public void onTouchEvent(MotionEvent event) { - int action = event.getActionMasked(); - - if (action == MotionEvent.ACTION_DOWN) { - mCount = 1; - } - - if (action == MotionEvent.ACTION_POINTER_DOWN) { - ++mCount; - } - } - - @Override - public float getFalseTouchEvaluation(int type) { - return PointerCountEvaluator.evaluate(mCount); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/PointerCountEvaluator.java b/packages/SystemUI/src/com/android/systemui/classifier/PointerCountEvaluator.java deleted file mode 100644 index d7a3af0360af9..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/PointerCountEvaluator.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -public class PointerCountEvaluator { - public static float evaluate(int value) { - return (value - 1) * (value - 1); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java deleted file mode 100644 index 62adfc85621bb..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.view.MotionEvent; - -/** - * A classifier which looks at the proximity sensor during the gesture. It calculates the percentage - * the proximity sensor showing the near state during the whole gesture - */ -public class ProximityClassifier extends GestureClassifier { - private long mGestureStartTimeNano; - private long mNearStartTimeNano; - private long mNearDuration; - private boolean mNear; - private float mAverageNear; - - public ProximityClassifier(ClassifierData classifierData) { - } - - @Override - public String getTag() { - return "PROX"; - } - - @Override - public void onSensorChanged(SensorEvent event) { - if (event.sensor.getType() == Sensor.TYPE_PROXIMITY) { - update(event.values[0] < event.sensor.getMaximumRange(), event.timestamp); - } - } - - @Override - public void onTouchEvent(MotionEvent event) { - int action = event.getActionMasked(); - - if (action == MotionEvent.ACTION_DOWN) { - mGestureStartTimeNano = event.getEventTimeNano(); - mNearStartTimeNano = event.getEventTimeNano(); - mNearDuration = 0; - } - - if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { - update(mNear, event.getEventTimeNano()); - long duration = event.getEventTimeNano() - mGestureStartTimeNano; - - if (duration == 0) { - mAverageNear = mNear ? 1.0f : 0.0f; - } else { - mAverageNear = (float) mNearDuration / (float) duration; - } - } - } - - - /** - * @param near is the sensor showing the near state right now - * @param timestampNano time of this event in nanoseconds - */ - private void update(boolean near, long timestampNano) { - // This if is necessary because MotionEvents and SensorEvents do not come in - // chronological order - if (timestampNano > mNearStartTimeNano) { - // if the state before was near then add the difference of the current time and - // mNearStartTimeNano to mNearDuration. - if (mNear) { - mNearDuration += timestampNano - mNearStartTimeNano; - } - - // if the new state is near, set mNearStartTimeNano equal to this moment. - if (near) { - mNearStartTimeNano = timestampNano; - } - } - mNear = near; - } - - @Override - public float getFalseTouchEvaluation(int type) { - return ProximityEvaluator.evaluate(mAverageNear, type); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/ProximityEvaluator.java b/packages/SystemUI/src/com/android/systemui/classifier/ProximityEvaluator.java deleted file mode 100644 index 91002bf1291cd..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/ProximityEvaluator.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -public class ProximityEvaluator { - public static float evaluate(float value, int type) { - float evaluation = 0.0f; - float threshold = 0.1f; - if (type == Classifier.QUICK_SETTINGS) { - threshold = 1.0f; - } - if (value >= threshold) evaluation += 2.0; - return evaluation; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/SpeedAnglesClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/SpeedAnglesClassifier.java deleted file mode 100644 index 66f0cf68d8c16..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/SpeedAnglesClassifier.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -import android.os.Build; -import android.os.SystemProperties; -import android.view.MotionEvent; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -/** - * A classifier which for each point from a stroke, it creates a point on plane with coordinates - * (timeOffsetNano, distanceCoveredUpToThisPoint) (scaled by DURATION_SCALE and LENGTH_SCALE) - * and then it calculates the angle variance of these points like the class - * {@link AnglesClassifier} (without splitting it into two parts). The classifier ignores - * the last point of a stroke because the UP event comes in with some delay and this ruins the - * smoothness of this curve. Additionally, the classifier classifies calculates the percentage of - * angles which value is in [PI - ANGLE_DEVIATION, 2* PI) interval. The reason why the classifier - * does that is because the speed of a good stroke is most often increases, so most of these angels - * should be in this interval. - */ -public class SpeedAnglesClassifier extends StrokeClassifier { - public static final boolean VERBOSE = SystemProperties.getBoolean("debug.falsing_log.spd_ang", - Build.IS_DEBUGGABLE); - public static final String TAG = "SPD_ANG"; - - private HashMap mStrokeMap = new HashMap<>(); - - public SpeedAnglesClassifier(ClassifierData classifierData) { - mClassifierData = classifierData; - } - - @Override - public String getTag() { - return TAG; - } - - @Override - public void onTouchEvent(MotionEvent event) { - int action = event.getActionMasked(); - - if (action == MotionEvent.ACTION_DOWN) { - mStrokeMap.clear(); - } - - for (int i = 0; i < event.getPointerCount(); i++) { - Stroke stroke = mClassifierData.getStroke(event.getPointerId(i)); - - if (mStrokeMap.get(stroke) == null) { - mStrokeMap.put(stroke, new Data()); - } - - if (action != MotionEvent.ACTION_UP && action != MotionEvent.ACTION_CANCEL - && !(action == MotionEvent.ACTION_POINTER_UP && i == event.getActionIndex())) { - mStrokeMap.get(stroke).addPoint( - stroke.getPoints().get(stroke.getPoints().size() - 1)); - } - } - } - - @Override - public float getFalseTouchEvaluation(int type, Stroke stroke) { - Data data = mStrokeMap.get(stroke); - return SpeedVarianceEvaluator.evaluate(data.getAnglesVariance()) - + SpeedAnglesPercentageEvaluator.evaluate(data.getAnglesPercentage()); - } - - private static class Data { - private final float DURATION_SCALE = 1e8f; - private final float LENGTH_SCALE = 1.0f; - private final float ANGLE_DEVIATION = (float) Math.PI / 10.0f; - - private List mLastThreePoints = new ArrayList<>(); - private Point mPreviousPoint; - private float mPreviousAngle; - private float mSumSquares; - private float mSum; - private float mCount; - private float mDist; - private float mAnglesCount; - private float mAcceleratingAngles; - - public Data() { - mPreviousPoint = null; - mPreviousAngle = (float) Math.PI; - mSumSquares = 0.0f; - mSum = 0.0f; - mCount = 1.0f; - mDist = 0.0f; - mAnglesCount = mAcceleratingAngles = 0.0f; - } - - public void addPoint(Point point) { - if (mPreviousPoint != null) { - mDist += mPreviousPoint.dist(point); - } - - mPreviousPoint = point; - Point speedPoint = new Point((float) point.timeOffsetNano / DURATION_SCALE, - mDist / LENGTH_SCALE); - - // Checking if the added point is different than the previously added point - // Repetitions are being ignored so that proper angles are calculated. - if (mLastThreePoints.isEmpty() - || !mLastThreePoints.get(mLastThreePoints.size() - 1).equals(speedPoint)) { - mLastThreePoints.add(speedPoint); - if (mLastThreePoints.size() == 4) { - mLastThreePoints.remove(0); - - float angle = mLastThreePoints.get(1).getAngle(mLastThreePoints.get(0), - mLastThreePoints.get(2)); - - mAnglesCount++; - if (angle >= (float) Math.PI - ANGLE_DEVIATION) { - mAcceleratingAngles++; - } - - float difference = angle - mPreviousAngle; - mSum += difference; - mSumSquares += difference * difference; - mCount += 1.0; - mPreviousAngle = angle; - } - } - } - - public float getAnglesVariance() { - final float v = mSumSquares / mCount - (mSum / mCount) * (mSum / mCount); - if (VERBOSE) { - FalsingLog.i(TAG, "getAnglesVariance: sum^2=" + mSumSquares - + " count=" + mCount + " result=" + v); - } - return v; - } - - public float getAnglesPercentage() { - if (mAnglesCount == 0.0f) { - return 1.0f; - } - final float v = (mAcceleratingAngles) / mAnglesCount; - if (VERBOSE) { - FalsingLog.i(TAG, "getAnglesPercentage: angles=" + mAcceleratingAngles - + " count=" + mAnglesCount + " result=" + v); - } - return v; - } - } -} \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/classifier/SpeedAnglesPercentageEvaluator.java b/packages/SystemUI/src/com/android/systemui/classifier/SpeedAnglesPercentageEvaluator.java deleted file mode 100644 index d50d406f2fef1..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/SpeedAnglesPercentageEvaluator.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -public class SpeedAnglesPercentageEvaluator { - public static float evaluate(float value) { - float evaluation = 0.0f; - if (value < 1.00) evaluation++; - if (value < 0.90) evaluation++; - if (value < 0.70) evaluation++; - return evaluation; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/SpeedClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/SpeedClassifier.java deleted file mode 100644 index 01fcc377ddbda..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/SpeedClassifier.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -/** - * A classifier that looks at the speed of the stroke. It calculates the speed of a stroke in - * inches per second. - */ -public class SpeedClassifier extends StrokeClassifier { - private final float NANOS_TO_SECONDS = 1e9f; - - public SpeedClassifier(ClassifierData classifierData) { - } - - @Override - public String getTag() { - return "SPD"; - } - - @Override - public float getFalseTouchEvaluation(int type, Stroke stroke) { - float duration = (float) stroke.getDurationNanos() / NANOS_TO_SECONDS; - if (duration == 0.0f) { - return SpeedEvaluator.evaluate(0.0f); - } - return SpeedEvaluator.evaluate(stroke.getTotalLength() / duration); - } -} \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/classifier/SpeedEvaluator.java b/packages/SystemUI/src/com/android/systemui/classifier/SpeedEvaluator.java deleted file mode 100644 index afd8d01521727..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/SpeedEvaluator.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -public class SpeedEvaluator { - public static float evaluate(float value) { - float evaluation = 0.0f; - if (value < 4.0) evaluation++; - if (value < 2.2) evaluation++; - if (value > 35.0) evaluation++; - if (value > 50.0) evaluation++; - return evaluation; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/SpeedRatioEvaluator.java b/packages/SystemUI/src/com/android/systemui/classifier/SpeedRatioEvaluator.java deleted file mode 100644 index e34f222d3799e..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/SpeedRatioEvaluator.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -public class SpeedRatioEvaluator { - public static float evaluate(float value) { - float evaluation = 0.0f; - if (value == 0) return 0; - if (value <= 1.0) evaluation++; - if (value <= 0.5) evaluation++; - if (value > 9.0) evaluation++; - if (value > 18.0) evaluation++; - return evaluation; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/SpeedVarianceEvaluator.java b/packages/SystemUI/src/com/android/systemui/classifier/SpeedVarianceEvaluator.java deleted file mode 100644 index 48b1b6e0dbf11..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/SpeedVarianceEvaluator.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -public class SpeedVarianceEvaluator { - public static float evaluate(float value) { - float evaluation = 0.0f; - if (value > 0.06) evaluation++; - if (value > 0.15) evaluation++; - if (value > 0.3) evaluation++; - if (value > 0.6) evaluation++; - return evaluation; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/Stroke.java b/packages/SystemUI/src/com/android/systemui/classifier/Stroke.java deleted file mode 100644 index 977a2d0b528a6..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/Stroke.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -import java.util.ArrayList; - -/** - * Contains data about a stroke (a single trace, all the events from a given id from the - * DOWN/POINTER_DOWN event till the UP/POINTER_UP/CANCEL event.) - */ -public class Stroke { - private final float NANOS_TO_SECONDS = 1e9f; - - private ArrayList mPoints = new ArrayList<>(); - private long mStartTimeNano; - private long mEndTimeNano; - private float mLength; - private final float mDpi; - - public Stroke(long eventTimeNano, float dpi) { - mDpi = dpi; - mStartTimeNano = mEndTimeNano = eventTimeNano; - } - - public void addPoint(float x, float y, long eventTimeNano) { - mEndTimeNano = eventTimeNano; - Point point = new Point(x / mDpi, y / mDpi, eventTimeNano - mStartTimeNano); - if (!mPoints.isEmpty()) { - mLength += mPoints.get(mPoints.size() - 1).dist(point); - } - mPoints.add(point); - } - - public int getCount() { - return mPoints.size(); - } - - public float getTotalLength() { - return mLength; - } - - public float getEndPointLength() { - return mPoints.get(0).dist(mPoints.get(mPoints.size() - 1)); - } - - public long getDurationNanos() { - return mEndTimeNano - mStartTimeNano; - } - - public float getDurationSeconds() { - return (float) getDurationNanos() / NANOS_TO_SECONDS; - } - - public ArrayList getPoints() { - return mPoints; - } - - public long getLastEventTimeNano() { - if (mPoints.isEmpty()) { - return mStartTimeNano; - } - - return mPoints.get(mPoints.size() - 1).timeOffsetNano; - } -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/StrokeClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/StrokeClassifier.java deleted file mode 100644 index 5da392f31d63f..0000000000000 --- a/packages/SystemUI/src/com/android/systemui/classifier/StrokeClassifier.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.android.systemui.classifier; - -/** - * An abstract class for classifiers which classify each stroke separately. - */ -public abstract class StrokeClassifier extends Classifier { - - /** - * @param type the type of action for which this method is called - * @param stroke the stroke for which the evaluation will be calculated - * @return a non-negative value which is used to determine whether this a false touch; the - * bigger the value the greater the chance that this a false touch - */ - public abstract float getFalseTouchEvaluation(int type, Stroke stroke); -} diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java index fe295fbdb7107..334102d68507a 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java @@ -16,20 +16,22 @@ package com.android.systemui.classifier.brightline; -import static com.android.systemui.classifier.FalsingManagerImpl.FALSING_REMAIN_LOCKED; -import static com.android.systemui.classifier.FalsingManagerImpl.FALSING_SUCCESS; +import static com.android.systemui.classifier.FalsingManagerProxy.FALSING_REMAIN_LOCKED; +import static com.android.systemui.classifier.FalsingManagerProxy.FALSING_SUCCESS; import android.app.ActivityManager; import android.content.res.Resources; import android.hardware.biometrics.BiometricSourceType; import android.net.Uri; import android.os.Build; +import android.util.IndentingPrintWriter; import android.util.Log; import android.view.MotionEvent; import android.view.ViewConfiguration; +import androidx.annotation.NonNull; + import com.android.internal.logging.MetricsLogger; -import com.android.internal.util.IndentingPrintWriter; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.R; @@ -44,6 +46,7 @@ import com.android.systemui.util.DeviceConfigProxy; import com.android.systemui.util.sensors.ProximitySensor; import com.android.systemui.util.sensors.ThresholdSensor; +import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayDeque; import java.util.ArrayList; @@ -457,7 +460,7 @@ public class BrightLineFalsingManager implements FalsingManager { } @Override - public void dump(PrintWriter pw) { + public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) { IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); ipw.println("BRIGHTLINE FALSING MANAGER"); ipw.print("classifierEnabled="); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 09de57509c2a5..d66c2f2668ddf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -146,7 +146,6 @@ import com.android.systemui.SystemUI; import com.android.systemui.assist.AssistManager; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.charging.WirelessChargingAnimation; -import com.android.systemui.classifier.FalsingLog; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.qualifiers.UiBackground; import com.android.systemui.demomode.DemoMode; @@ -1238,10 +1237,6 @@ public class StatusBar extends SystemUI implements DemoMode, message.write(SystemProperties.get("ro.serialno")); message.write("\n"); - PrintWriter falsingPw = new PrintWriter(message); - FalsingLog.dump(falsingPw); - falsingPw.flush(); - startActivityDismissingKeyguard(Intent.createChooser(new Intent(Intent.ACTION_SEND) .setType("*/*") .putExtra(Intent.EXTRA_SUBJECT, "Rejected touch report") @@ -2664,9 +2659,6 @@ public class StatusBar extends SystemUI implements DemoMode, mLightBarController.dump(fd, pw, args); } - mFalsingManager.dump(pw); - FalsingLog.dump(pw); - pw.println("SharedPreferences:"); for (Map.Entry entry : Prefs.getAll(mContext).entrySet()) { pw.print(" "); pw.print(entry.getKey()); pw.print("="); pw.println(entry.getValue()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java deleted file mode 100644 index a48bd81472b81..0000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerProxyTest.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.systemui.classifier; - -import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_MANAGER_ENABLED; - -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.junit.Assert.assertThat; - -import android.content.res.Resources; -import android.provider.DeviceConfig; -import android.testing.AndroidTestingRunner; -import android.util.DisplayMetrics; -import android.view.ViewConfiguration; - -import androidx.test.filters.SmallTest; - -import com.android.internal.logging.testing.UiEventLoggerFake; -import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.systemui.classifier.brightline.BrightLineFalsingManager; -import com.android.systemui.classifier.brightline.FalsingDataProvider; -import com.android.systemui.dock.DockManager; -import com.android.systemui.dock.DockManagerFake; -import com.android.systemui.dump.DumpManager; -import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.shared.plugins.PluginManager; -import com.android.systemui.statusbar.StatusBarStateControllerImpl; -import com.android.systemui.util.DeviceConfigProxy; -import com.android.systemui.util.DeviceConfigProxyFake; -import com.android.systemui.util.concurrency.FakeExecutor; -import com.android.systemui.util.sensors.ProximitySensor; -import com.android.systemui.util.time.FakeSystemClock; -import com.android.systemui.utils.leaks.FakeBatteryController; -import com.android.systemui.utils.leaks.LeakCheckedTest; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@SmallTest -@RunWith(AndroidTestingRunner.class) -public class FalsingManagerProxyTest extends LeakCheckedTest { - @Mock(stubOnly = true) - PluginManager mPluginManager; - @Mock(stubOnly = true) - ProximitySensor mProximitySensor; - @Mock(stubOnly = true) - private KeyguardUpdateMonitor mKeyguardUpdateMonitor; - @Mock DumpManager mDumpManager; - private FalsingManagerProxy mProxy; - private DeviceConfigProxy mDeviceConfig; - private FalsingDataProvider mFalsingDataProvider; - private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock()); - private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock()); - private DockManager mDockManager = new DockManagerFake(); - private StatusBarStateController mStatusBarStateController = - new StatusBarStateControllerImpl(new UiEventLoggerFake()); - @Mock private Resources mResources; - @Mock private ViewConfiguration mViewConfiguration; - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - mDeviceConfig = new DeviceConfigProxyFake(); - mDeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, - BRIGHTLINE_FALSING_MANAGER_ENABLED, "false", false); - mFalsingDataProvider = new FalsingDataProvider( - new DisplayMetrics(), new FakeBatteryController(getLeakCheck()), - new FakeSystemClock()); - } - - @After - public void tearDown() { - if (mProxy != null) { - mProxy.cleanup(); - } - } - - @Test - public void test_brightLineFalsingManagerDisabled() { - mProxy = new FalsingManagerProxy(getContext(), mPluginManager, mExecutor, - mProximitySensor, mDeviceConfig, mDockManager, mKeyguardUpdateMonitor, - mDumpManager, mUiBgExecutor, mStatusBarStateController, mResources, - mViewConfiguration, mFalsingDataProvider); - assertThat(mProxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class)); - } - - @Test - public void test_brightLineFalsingManagerEnabled() throws InterruptedException { - mDeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, - BRIGHTLINE_FALSING_MANAGER_ENABLED, "true", false); - mExecutor.runAllReady(); - mProxy = new FalsingManagerProxy(getContext(), mPluginManager, mExecutor, - mProximitySensor, mDeviceConfig, mDockManager, mKeyguardUpdateMonitor, - mDumpManager, mUiBgExecutor, mStatusBarStateController, mResources, - mViewConfiguration, mFalsingDataProvider); - assertThat(mProxy.getInternalFalsingManager(), instanceOf(BrightLineFalsingManager.class)); - } - - @Test - public void test_brightLineFalsingManagerToggled() throws InterruptedException { - mProxy = new FalsingManagerProxy(getContext(), mPluginManager, mExecutor, - mProximitySensor, mDeviceConfig, mDockManager, mKeyguardUpdateMonitor, - mDumpManager, mUiBgExecutor, mStatusBarStateController, mResources, - mViewConfiguration, mFalsingDataProvider); - assertThat(mProxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class)); - - mDeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, - BRIGHTLINE_FALSING_MANAGER_ENABLED, "true", false); - mExecutor.runAllReady(); - assertThat(mProxy.getInternalFalsingManager(), - instanceOf(BrightLineFalsingManager.class)); - - mDeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, - BRIGHTLINE_FALSING_MANAGER_ENABLED, "false", false); - mExecutor.runAllReady(); - assertThat(mProxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class)); - } -}