Merge "Improve logging information available from BrightLineFalsingManager."
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 0aa66af..bd0906a 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
@@ -35,6 +35,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 
 /**
  * FalsingManager designed to make clear why a touch was rejected.
@@ -42,7 +43,7 @@
 public class BrightLineFalsingManager implements FalsingManager {
 
     static final boolean DEBUG = false;
-    private static final String TAG = "FalsingManagerPlugin";
+    private static final String TAG = "FalsingManager";
 
     private final FalsingDataProvider mDataProvider;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@@ -142,7 +143,15 @@
         boolean r = !mJustUnlockedWithFace && mClassifiers.stream().anyMatch(falsingClassifier -> {
             boolean result = falsingClassifier.isFalseTouch();
             if (result) {
-                logInfo(falsingClassifier.getClass().getName() + ": true");
+                logInfo(String.format(
+                        (Locale) null,
+                        "{classifier=%s, interactionType=%d}",
+                        falsingClassifier.getClass().getName(),
+                        mDataProvider.getInteractionType()));
+                String reason = falsingClassifier.getReason();
+                if (reason != null) {
+                    logInfo(reason);
+                }
             } else {
                 logDebug(falsingClassifier.getClass().getName() + ": false");
             }
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java
index 9c03b91..520e0a1 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DiagonalClassifier.java
@@ -25,6 +25,8 @@
 
 import com.android.systemui.util.DeviceConfigProxy;
 
+import java.util.Locale;
+
 /**
  * False on swipes that are too close to 45 degrees.
  *
@@ -84,6 +86,15 @@
                 maxAngle + ONE_HUNDRED_EIGHTY_DEG);
     }
 
+    @Override
+    String getReason() {
+        return String.format(
+                (Locale) null,
+                "{angle=%f, vertical=%s}",
+                getAngle(),
+                isVertical());
+    }
+
     private boolean angleBetween(float angle, float min, float max) {
         // No need to normalize angle as it is guaranteed to be between 0 and 2*PI.
         min = normalizeAngle(min);
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java
index 0954f9e..7f45cc8 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/DistanceClassifier.java
@@ -30,6 +30,7 @@
 import com.android.systemui.util.DeviceConfigProxy;
 
 import java.util.List;
+import java.util.Locale;
 
 /**
  * Ensure that the swipe + momentum covers a minimum distance.
@@ -144,15 +145,66 @@
 
     @Override
     public boolean isFalseTouch() {
-        return !getDistances().getPassedFlingThreshold();
+        return !getPassedFlingThreshold();
+    }
+
+    @Override
+    String getReason() {
+        DistanceVectors distanceVectors = getDistances();
+
+        return String.format(
+                (Locale) null,
+                "{distanceVectors=%s, isHorizontal=%s, velocityToDistanceMultiplier=%f, "
+                        + "horizontalFlingThreshold=%f, verticalFlingThreshold=%f, "
+                        + "horizontalSwipeThreshold=%f, verticalSwipeThreshold=%s}",
+                distanceVectors,
+                isHorizontal(),
+                mVelocityToDistanceMultiplier,
+                mHorizontalFlingThresholdPx,
+                mVerticalFlingThresholdPx,
+                mHorizontalSwipeThresholdPx,
+                mVerticalSwipeThresholdPx);
     }
 
     boolean isLongSwipe() {
-        boolean longSwipe = getDistances().getPassedDistanceThreshold();
+        boolean longSwipe = getPassedDistanceThreshold();
         logDebug("Is longSwipe? " + longSwipe);
         return longSwipe;
     }
 
+    private boolean getPassedDistanceThreshold() {
+        DistanceVectors distanceVectors = getDistances();
+        if (isHorizontal()) {
+            logDebug("Horizontal swipe distance: " + Math.abs(distanceVectors.mDx));
+            logDebug("Threshold: " + mHorizontalSwipeThresholdPx);
+
+            return Math.abs(distanceVectors.mDx) >= mHorizontalSwipeThresholdPx;
+        }
+
+        logDebug("Vertical swipe distance: " + Math.abs(distanceVectors.mDy));
+        logDebug("Threshold: " + mVerticalSwipeThresholdPx);
+        return Math.abs(distanceVectors.mDy) >= mVerticalSwipeThresholdPx;
+    }
+
+    private boolean getPassedFlingThreshold() {
+        DistanceVectors distanceVectors = getDistances();
+
+        float dX = distanceVectors.mDx + distanceVectors.mVx * mVelocityToDistanceMultiplier;
+        float dY = distanceVectors.mDy + distanceVectors.mVy * mVelocityToDistanceMultiplier;
+
+        if (isHorizontal()) {
+            logDebug("Horizontal swipe and fling distance: " + distanceVectors.mDx + ", "
+                    + distanceVectors.mVx * mVelocityToDistanceMultiplier);
+            logDebug("Threshold: " + mHorizontalFlingThresholdPx);
+            return Math.abs(dX) >= mHorizontalFlingThresholdPx;
+        }
+
+        logDebug("Vertical swipe and fling distance: " + distanceVectors.mDy + ", "
+                + distanceVectors.mVy * mVelocityToDistanceMultiplier);
+        logDebug("Threshold: " + mVerticalFlingThresholdPx);
+        return Math.abs(dY) >= mVerticalFlingThresholdPx;
+    }
+
     private class DistanceVectors {
         final float mDx;
         final float mDy;
@@ -166,34 +218,9 @@
             this.mVy = vY;
         }
 
-        boolean getPassedDistanceThreshold() {
-            if (isHorizontal()) {
-                logDebug("Horizontal swipe distance: " + Math.abs(mDx));
-                logDebug("Threshold: " + mHorizontalSwipeThresholdPx);
-
-                return Math.abs(mDx) >= mHorizontalSwipeThresholdPx;
-            }
-
-            logDebug("Vertical swipe distance: " + Math.abs(mDy));
-            logDebug("Threshold: " + mVerticalSwipeThresholdPx);
-            return Math.abs(mDy) >= mVerticalSwipeThresholdPx;
-        }
-
-        boolean getPassedFlingThreshold() {
-            float dX = this.mDx + this.mVx * mVelocityToDistanceMultiplier;
-            float dY = this.mDy + this.mVy * mVelocityToDistanceMultiplier;
-
-            if (isHorizontal()) {
-                logDebug("Horizontal swipe and fling distance: " + this.mDx + ", "
-                        + this.mVx * mVelocityToDistanceMultiplier);
-                logDebug("Threshold: " + mHorizontalFlingThresholdPx);
-                return Math.abs(dX) >= mHorizontalFlingThresholdPx;
-            }
-
-            logDebug("Vertical swipe and fling distance: " + this.mDy + ", "
-                    + this.mVy * mVelocityToDistanceMultiplier);
-            logDebug("Threshold: " + mVerticalFlingThresholdPx);
-            return Math.abs(dY) >= mVerticalFlingThresholdPx;
+        @Override
+        public String toString() {
+            return String.format((Locale) null, "{dx=%f, vx=%f, dy=%f, vy=%f}", mDx, mVx, mDy, mVy);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java
index 53ca783..7555051 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/FalsingClassifier.java
@@ -117,6 +117,14 @@
      */
     abstract boolean isFalseTouch();
 
+    /**
+     * Give the classifier a chance to log more details about why it triggered.
+     *
+     * This should only be called after a call to {@link #isFalseTouch()}, and only if
+     * {@link #isFalseTouch()} returns true;
+     */
+    abstract String getReason();
+
     static void logDebug(String msg) {
         BrightLineFalsingManager.logDebug(msg);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/PointerCountClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/PointerCountClassifier.java
index 40e141f..85a4d23 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/PointerCountClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/PointerCountClassifier.java
@@ -18,6 +18,8 @@
 
 import android.view.MotionEvent;
 
+import java.util.Locale;
+
 /**
  * False touch if more than one finger touches the screen.
  *
@@ -50,4 +52,13 @@
     public boolean isFalseTouch() {
         return mMaxPointerCount > MAX_ALLOWED_POINTERS;
     }
+
+    @Override
+    String getReason() {
+        return String.format(
+                (Locale) null,
+                "{pointersObserved=%d, threshold=%d}",
+                mMaxPointerCount,
+                MAX_ALLOWED_POINTERS);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java
index f0feb4e..749914e 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ProximityClassifier.java
@@ -25,6 +25,8 @@
 import com.android.systemui.util.DeviceConfigProxy;
 import com.android.systemui.util.sensors.ProximitySensor;
 
+import java.util.Locale;
+
 
 /**
  * False touch if proximity sensor is covered for more than a certain percentage of the gesture.
@@ -121,6 +123,16 @@
         return false;
     }
 
+    @Override
+    String getReason() {
+        return String.format(
+                (Locale) null,
+                "{percentInProximity=%f, threshold=%f, distanceClassifier=%s}",
+                mPercentNear,
+                mPercentCoveredThreshold,
+                mDistanceClassifier.getReason());
+    }
+
     /**
      * @param near        is the sensor showing the near state right now
      * @param timeStampNs time of this event in nanoseconds
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/TypeClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/TypeClassifier.java
index b6ceab5..5f1b37a 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/TypeClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/TypeClassifier.java
@@ -58,4 +58,9 @@
                 return true;
         }
     }
+
+    @Override
+    String getReason() {
+        return String.format("{vertical=%s, up=%s, right=%s}", isVertical(), isUp(), isRight());
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java
index a0da988..957ea8d 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/ZigZagClassifier.java
@@ -29,6 +29,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 
 /**
  * Penalizes gestures that change direction in either the x or y too much.
@@ -49,6 +50,10 @@
     private final float mMaxYPrimaryDeviance;
     private final float mMaxXSecondaryDeviance;
     private final float mMaxYSecondaryDeviance;
+    private float mLastDevianceX;
+    private float mLastDevianceY;
+    private float mLastMaxXDeviance;
+    private float mLastMaxYDeviance;
 
     ZigZagClassifier(FalsingDataProvider dataProvider, DeviceConfigProxy deviceConfigProxy) {
         super(dataProvider);
@@ -139,11 +144,25 @@
             maxYDeviance = mMaxYPrimaryDeviance * totalDistanceIn * getYdpi();
         }
 
+        // These values are saved for logging reasons. {@see #getReason()}
+        mLastDevianceX = devianceX;
+        mLastDevianceY = devianceY;
+        mLastMaxXDeviance = maxXDeviance;
+        mLastMaxYDeviance = maxYDeviance;
+
         logDebug("Straightness Deviance: (" + devianceX + "," + devianceY + ") vs "
                 + "(" + maxXDeviance + "," + maxYDeviance + ")");
         return devianceX > maxXDeviance || devianceY > maxYDeviance;
     }
 
+    @Override
+    String getReason() {
+        return String.format(
+                (Locale) null,
+                "{devianceX=%f, maxDevianceX=%s, devianceY=%s, maxDevianceY=%s}",
+                mLastDevianceX, mLastMaxXDeviance, mLastDevianceY, mLastMaxYDeviance);
+    }
+
     private float getAtan2LastPoint() {
         MotionEvent firstEvent = getFirstMotionEvent();
         MotionEvent lastEvent = getLastMotionEvent();