Merge "Fix bug and add logging in FalsingManager" into nyc-dev
This commit is contained in:
@@ -35,6 +35,11 @@ public class AccelerationClassifier extends StrokeClassifier {
|
|||||||
mClassifierData = classifierData;
|
mClassifierData = classifierData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return "ACC";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTouchEvent(MotionEvent event) {
|
public void onTouchEvent(MotionEvent event) {
|
||||||
int action = event.getActionMasked();
|
int action = event.getActionMasked();
|
||||||
|
|||||||
@@ -53,6 +53,11 @@ public class AnglesClassifier extends StrokeClassifier {
|
|||||||
mClassifierData = classifierData;
|
mClassifierData = classifierData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return "ANG";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTouchEvent(MotionEvent event) {
|
public void onTouchEvent(MotionEvent event) {
|
||||||
int action = event.getActionMasked();
|
int action = event.getActionMasked();
|
||||||
|
|||||||
@@ -48,4 +48,6 @@ public abstract class Classifier {
|
|||||||
*/
|
*/
|
||||||
public void onSensorChanged(SensorEvent event) {
|
public void onSensorChanged(SensorEvent event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract String getTag();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,11 @@ public class DirectionClassifier extends StrokeClassifier {
|
|||||||
public DirectionClassifier(ClassifierData classifierData) {
|
public DirectionClassifier(ClassifierData classifierData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return "DIR";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getFalseTouchEvaluation(int type, Stroke stroke) {
|
public float getFalseTouchEvaluation(int type, Stroke stroke) {
|
||||||
Point firstPoint = stroke.getPoints().get(0);
|
Point firstPoint = stroke.getPoints().get(0);
|
||||||
|
|||||||
@@ -24,6 +24,11 @@ public class DurationCountClassifier extends StrokeClassifier {
|
|||||||
public DurationCountClassifier(ClassifierData classifierData) {
|
public DurationCountClassifier(ClassifierData classifierData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return "DUR";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getFalseTouchEvaluation(int type, Stroke stroke) {
|
public float getFalseTouchEvaluation(int type, Stroke stroke) {
|
||||||
return DurationCountEvaluator.evaluate(stroke.getDurationSeconds() / stroke.getCount());
|
return DurationCountEvaluator.evaluate(stroke.getDurationSeconds() / stroke.getCount());
|
||||||
|
|||||||
@@ -23,6 +23,11 @@ public class EndPointLengthClassifier extends StrokeClassifier {
|
|||||||
public EndPointLengthClassifier(ClassifierData classifierData) {
|
public EndPointLengthClassifier(ClassifierData classifierData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return "END_LNGTH";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getFalseTouchEvaluation(int type, Stroke stroke) {
|
public float getFalseTouchEvaluation(int type, Stroke stroke) {
|
||||||
return EndPointLengthEvaluator.evaluate(stroke.getEndPointLength());
|
return EndPointLengthEvaluator.evaluate(stroke.getEndPointLength());
|
||||||
|
|||||||
@@ -25,6 +25,11 @@ public class EndPointRatioClassifier extends StrokeClassifier {
|
|||||||
mClassifierData = classifierData;
|
mClassifierData = classifierData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return "END_RTIO";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getFalseTouchEvaluation(int type, Stroke stroke) {
|
public float getFalseTouchEvaluation(int type, Stroke stroke) {
|
||||||
float ratio;
|
float ratio;
|
||||||
|
|||||||
@@ -0,0 +1,166 @@
|
|||||||
|
/*
|
||||||
|
* 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.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
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 SystemBars | 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<String> 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 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("<empty>");
|
||||||
|
pw.println();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (String s : sInstance.mLog) {
|
||||||
|
pw.println(s);
|
||||||
|
}
|
||||||
|
pw.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void wtf(String tag, String s) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,6 +31,8 @@ import android.view.MotionEvent;
|
|||||||
import com.android.systemui.analytics.DataCollector;
|
import com.android.systemui.analytics.DataCollector;
|
||||||
import com.android.systemui.statusbar.StatusBarState;
|
import com.android.systemui.statusbar.StatusBarState;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When the phone is locked, listens to touch, sensor and phone events and sends them to
|
* When the phone is locked, listens to touch, sensor and phone events and sends them to
|
||||||
* DataCollector and HumanInteractionClassifier.
|
* DataCollector and HumanInteractionClassifier.
|
||||||
@@ -102,8 +104,14 @@ public class FalsingManager implements SensorEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean shouldSessionBeActive() {
|
private boolean shouldSessionBeActive() {
|
||||||
return isEnabled() && mScreenOn &&
|
if (FalsingLog.ENABLED && FalsingLog.VERBOSE)
|
||||||
(mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED);
|
FalsingLog.v("shouldBeActive", new StringBuilder()
|
||||||
|
.append("enabled=").append(isEnabled() ? 1 : 0)
|
||||||
|
.append(" mScreenOn=").append(mScreenOn ? 1 : 0)
|
||||||
|
.append(" mState=").append(StatusBarState.toShortString(mState))
|
||||||
|
.toString()
|
||||||
|
);
|
||||||
|
return isEnabled() && mScreenOn && (mState == StatusBarState.KEYGUARD);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean sessionEntrypoint() {
|
private boolean sessionEntrypoint() {
|
||||||
@@ -122,6 +130,9 @@ public class FalsingManager implements SensorEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void onSessionStart() {
|
private void onSessionStart() {
|
||||||
|
if (FalsingLog.ENABLED) {
|
||||||
|
FalsingLog.i("onSessionStart", "classifierEnabled=" + isClassiferEnabled());
|
||||||
|
}
|
||||||
mBouncerOn = false;
|
mBouncerOn = false;
|
||||||
mSessionActive = true;
|
mSessionActive = true;
|
||||||
|
|
||||||
@@ -154,6 +165,16 @@ public class FalsingManager implements SensorEventListener {
|
|||||||
* @return true if the classifier determined that this is not a human interacting with the phone
|
* @return true if the classifier determined that this is not a human interacting with the phone
|
||||||
*/
|
*/
|
||||||
public boolean isFalseTouch() {
|
public boolean isFalseTouch() {
|
||||||
|
if (FalsingLog.ENABLED) {
|
||||||
|
if (!mSessionActive) {
|
||||||
|
FalsingLog.wtf("isFalseTouch", new StringBuilder()
|
||||||
|
.append("Session is not active, yet there's a query for a false touch.")
|
||||||
|
.append(" enabled=").append(isEnabled() ? 1 : 0)
|
||||||
|
.append(" mScreenOn=").append(mScreenOn ? 1 : 0)
|
||||||
|
.append(" mState=").append(StatusBarState.toShortString(mState))
|
||||||
|
.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
return mHumanInteractionClassifier.isFalseTouch();
|
return mHumanInteractionClassifier.isFalseTouch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,6 +194,12 @@ public class FalsingManager implements SensorEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setStatusBarState(int state) {
|
public void setStatusBarState(int state) {
|
||||||
|
if (FalsingLog.ENABLED) {
|
||||||
|
FalsingLog.i("setStatusBarState", new StringBuilder()
|
||||||
|
.append("from=").append(StatusBarState.toShortString(mState))
|
||||||
|
.append(" to=").append(StatusBarState.toShortString(state))
|
||||||
|
.toString());
|
||||||
|
}
|
||||||
mState = state;
|
mState = state;
|
||||||
if (shouldSessionBeActive()) {
|
if (shouldSessionBeActive()) {
|
||||||
sessionEntrypoint();
|
sessionEntrypoint();
|
||||||
@@ -182,6 +209,11 @@ public class FalsingManager implements SensorEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onScreenTurningOn() {
|
public void onScreenTurningOn() {
|
||||||
|
if (FalsingLog.ENABLED) {
|
||||||
|
FalsingLog.i("onScreenTurningOn", new StringBuilder()
|
||||||
|
.append("from=").append(mScreenOn ? 1 : 0)
|
||||||
|
.toString());
|
||||||
|
}
|
||||||
mScreenOn = true;
|
mScreenOn = true;
|
||||||
if (sessionEntrypoint()) {
|
if (sessionEntrypoint()) {
|
||||||
mDataCollector.onScreenTurningOn();
|
mDataCollector.onScreenTurningOn();
|
||||||
@@ -189,6 +221,11 @@ public class FalsingManager implements SensorEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onScreenOnFromTouch() {
|
public void onScreenOnFromTouch() {
|
||||||
|
if (FalsingLog.ENABLED) {
|
||||||
|
FalsingLog.i("onScreenOnFromTouch", new StringBuilder()
|
||||||
|
.append("from=").append(mScreenOn ? 1 : 0)
|
||||||
|
.toString());
|
||||||
|
}
|
||||||
mScreenOn = true;
|
mScreenOn = true;
|
||||||
if (sessionEntrypoint()) {
|
if (sessionEntrypoint()) {
|
||||||
mDataCollector.onScreenOnFromTouch();
|
mDataCollector.onScreenOnFromTouch();
|
||||||
@@ -196,17 +233,30 @@ public class FalsingManager implements SensorEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onScreenOff() {
|
public void onScreenOff() {
|
||||||
|
if (FalsingLog.ENABLED) {
|
||||||
|
FalsingLog.i("onScreenOff", new StringBuilder()
|
||||||
|
.append("from=").append(mScreenOn ? 1 : 0)
|
||||||
|
.toString());
|
||||||
|
}
|
||||||
mDataCollector.onScreenOff();
|
mDataCollector.onScreenOff();
|
||||||
mScreenOn = false;
|
mScreenOn = false;
|
||||||
sessionExitpoint(false /* force */);
|
sessionExitpoint(false /* force */);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSucccessfulUnlock() {
|
public void onSucccessfulUnlock() {
|
||||||
|
if (FalsingLog.ENABLED) {
|
||||||
|
FalsingLog.i("onSucccessfulUnlock", "");
|
||||||
|
}
|
||||||
mDataCollector.onSucccessfulUnlock();
|
mDataCollector.onSucccessfulUnlock();
|
||||||
sessionExitpoint(true /* force */);
|
sessionExitpoint(true /* force */);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onBouncerShown() {
|
public void onBouncerShown() {
|
||||||
|
if (FalsingLog.ENABLED) {
|
||||||
|
FalsingLog.i("onBouncerShown", new StringBuilder()
|
||||||
|
.append("from=").append(mBouncerOn ? 1 : 0)
|
||||||
|
.toString());
|
||||||
|
}
|
||||||
if (!mBouncerOn) {
|
if (!mBouncerOn) {
|
||||||
mBouncerOn = true;
|
mBouncerOn = true;
|
||||||
mDataCollector.onBouncerShown();
|
mDataCollector.onBouncerShown();
|
||||||
@@ -214,6 +264,11 @@ public class FalsingManager implements SensorEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onBouncerHidden() {
|
public void onBouncerHidden() {
|
||||||
|
if (FalsingLog.ENABLED) {
|
||||||
|
FalsingLog.i("onBouncerHidden", new StringBuilder()
|
||||||
|
.append("from=").append(mBouncerOn ? 1 : 0)
|
||||||
|
.toString());
|
||||||
|
}
|
||||||
if (mBouncerOn) {
|
if (mBouncerOn) {
|
||||||
mBouncerOn = false;
|
mBouncerOn = false;
|
||||||
mDataCollector.onBouncerHidden();
|
mDataCollector.onBouncerHidden();
|
||||||
@@ -221,6 +276,9 @@ public class FalsingManager implements SensorEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onQsDown() {
|
public void onQsDown() {
|
||||||
|
if (FalsingLog.ENABLED) {
|
||||||
|
FalsingLog.i("onQsDown", "");
|
||||||
|
}
|
||||||
mHumanInteractionClassifier.setType(Classifier.QUICK_SETTINGS);
|
mHumanInteractionClassifier.setType(Classifier.QUICK_SETTINGS);
|
||||||
mDataCollector.onQsDown();
|
mDataCollector.onQsDown();
|
||||||
}
|
}
|
||||||
@@ -230,6 +288,9 @@ public class FalsingManager implements SensorEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onTrackingStarted() {
|
public void onTrackingStarted() {
|
||||||
|
if (FalsingLog.ENABLED) {
|
||||||
|
FalsingLog.i("onTrackingStarted", "");
|
||||||
|
}
|
||||||
mHumanInteractionClassifier.setType(Classifier.UNLOCK);
|
mHumanInteractionClassifier.setType(Classifier.UNLOCK);
|
||||||
mDataCollector.onTrackingStarted();
|
mDataCollector.onTrackingStarted();
|
||||||
}
|
}
|
||||||
@@ -251,6 +312,9 @@ public class FalsingManager implements SensorEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onNotificatonStartDraggingDown() {
|
public void onNotificatonStartDraggingDown() {
|
||||||
|
if (FalsingLog.ENABLED) {
|
||||||
|
FalsingLog.i("onNotificatonStartDraggingDown", "");
|
||||||
|
}
|
||||||
mHumanInteractionClassifier.setType(Classifier.NOTIFICATION_DRAG_DOWN);
|
mHumanInteractionClassifier.setType(Classifier.NOTIFICATION_DRAG_DOWN);
|
||||||
mDataCollector.onNotificatonStartDraggingDown();
|
mDataCollector.onNotificatonStartDraggingDown();
|
||||||
}
|
}
|
||||||
@@ -264,6 +328,9 @@ public class FalsingManager implements SensorEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onNotificatonStartDismissing() {
|
public void onNotificatonStartDismissing() {
|
||||||
|
if (FalsingLog.ENABLED) {
|
||||||
|
FalsingLog.i("onNotificatonStartDismissing", "");
|
||||||
|
}
|
||||||
mHumanInteractionClassifier.setType(Classifier.NOTIFICATION_DISMISS);
|
mHumanInteractionClassifier.setType(Classifier.NOTIFICATION_DISMISS);
|
||||||
mDataCollector.onNotificatonStartDismissing();
|
mDataCollector.onNotificatonStartDismissing();
|
||||||
}
|
}
|
||||||
@@ -281,6 +348,9 @@ public class FalsingManager implements SensorEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void onAffordanceSwipingStarted(boolean rightCorner) {
|
public void onAffordanceSwipingStarted(boolean rightCorner) {
|
||||||
|
if (FalsingLog.ENABLED) {
|
||||||
|
FalsingLog.i("onAffordanceSwipingStarted", "");
|
||||||
|
}
|
||||||
if (rightCorner) {
|
if (rightCorner) {
|
||||||
mHumanInteractionClassifier.setType(Classifier.RIGHT_AFFORDANCE);
|
mHumanInteractionClassifier.setType(Classifier.RIGHT_AFFORDANCE);
|
||||||
} else {
|
} else {
|
||||||
@@ -311,4 +381,14 @@ public class FalsingManager implements SensorEventListener {
|
|||||||
mHumanInteractionClassifier.onTouchEvent(event);
|
mHumanInteractionClassifier.onTouchEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void dump(PrintWriter pw) {
|
||||||
|
pw.println("FALSING MANAGER");
|
||||||
|
pw.print("classifierEnabled="); pw.println(isClassiferEnabled() ? 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import android.os.Handler;
|
|||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
@@ -43,14 +44,12 @@ public class HumanInteractionClassifier extends Classifier {
|
|||||||
private final Handler mHandler = new Handler();
|
private final Handler mHandler = new Handler();
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
|
||||||
private ArrayList<StrokeClassifier> mStrokeClassifiers = new ArrayList<>();
|
private final StrokeClassifier[] mStrokeClassifiers;
|
||||||
private ArrayList<GestureClassifier> mGestureClassifiers = new ArrayList<>();
|
private final GestureClassifier[] mGestureClassifiers;
|
||||||
private ArrayDeque<MotionEvent> mBufferedEvents = new ArrayDeque<>();
|
private final ArrayDeque<MotionEvent> mBufferedEvents = new ArrayDeque<>();
|
||||||
private final int mStrokeClassifiersSize;
|
private final HistoryEvaluator mHistoryEvaluator;
|
||||||
private final int mGestureClassifiersSize;
|
|
||||||
private final float mDpi;
|
private final float mDpi;
|
||||||
|
|
||||||
private HistoryEvaluator mHistoryEvaluator;
|
|
||||||
private boolean mEnableClassifier = false;
|
private boolean mEnableClassifier = false;
|
||||||
private int mCurrentType = Classifier.GENERIC;
|
private int mCurrentType = Classifier.GENERIC;
|
||||||
|
|
||||||
@@ -68,25 +67,27 @@ public class HumanInteractionClassifier extends Classifier {
|
|||||||
// If the phone is rotated to landscape, the calculations would be wrong if xdpi and ydpi
|
// 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
|
// were to be used separately. Due negligible differences in xdpi and ydpi we can just
|
||||||
// take the average.
|
// take the average.
|
||||||
|
// TODO: make this respect DPI changes.
|
||||||
mDpi = (displayMetrics.xdpi + displayMetrics.ydpi) / 2.0f;
|
mDpi = (displayMetrics.xdpi + displayMetrics.ydpi) / 2.0f;
|
||||||
mClassifierData = new ClassifierData(mDpi);
|
mClassifierData = new ClassifierData(mDpi);
|
||||||
mHistoryEvaluator = new HistoryEvaluator();
|
mHistoryEvaluator = new HistoryEvaluator();
|
||||||
|
|
||||||
mStrokeClassifiers.add(new AnglesClassifier(mClassifierData));
|
mStrokeClassifiers = new StrokeClassifier[]{
|
||||||
mStrokeClassifiers.add(new SpeedClassifier(mClassifierData));
|
new AnglesClassifier(mClassifierData),
|
||||||
mStrokeClassifiers.add(new DurationCountClassifier(mClassifierData));
|
new SpeedClassifier(mClassifierData),
|
||||||
mStrokeClassifiers.add(new EndPointRatioClassifier(mClassifierData));
|
new DurationCountClassifier(mClassifierData),
|
||||||
mStrokeClassifiers.add(new EndPointLengthClassifier(mClassifierData));
|
new EndPointRatioClassifier(mClassifierData),
|
||||||
mStrokeClassifiers.add(new AccelerationClassifier(mClassifierData));
|
new EndPointLengthClassifier(mClassifierData),
|
||||||
mStrokeClassifiers.add(new SpeedAnglesClassifier(mClassifierData));
|
new AccelerationClassifier(mClassifierData),
|
||||||
mStrokeClassifiers.add(new LengthCountClassifier(mClassifierData));
|
new SpeedAnglesClassifier(mClassifierData),
|
||||||
mStrokeClassifiers.add(new DirectionClassifier(mClassifierData));
|
new LengthCountClassifier(mClassifierData),
|
||||||
|
new DirectionClassifier(mClassifierData),
|
||||||
|
};
|
||||||
|
|
||||||
mGestureClassifiers.add(new PointerCountClassifier(mClassifierData));
|
mGestureClassifiers = new GestureClassifier[] {
|
||||||
mGestureClassifiers.add(new ProximityClassifier(mClassifierData));
|
new PointerCountClassifier(mClassifierData),
|
||||||
|
new ProximityClassifier(mClassifierData)
|
||||||
mStrokeClassifiersSize = mStrokeClassifiers.size();
|
};
|
||||||
mGestureClassifiersSize = mGestureClassifiers.size();
|
|
||||||
|
|
||||||
mContext.getContentResolver().registerContentObserver(
|
mContext.getContentResolver().registerContentObserver(
|
||||||
Settings.Global.getUriFor(HIC_ENABLE), false,
|
Settings.Global.getUriFor(HIC_ENABLE), false,
|
||||||
@@ -150,21 +151,30 @@ public class HumanInteractionClassifier extends Classifier {
|
|||||||
private void addTouchEvent(MotionEvent event) {
|
private void addTouchEvent(MotionEvent event) {
|
||||||
mClassifierData.update(event);
|
mClassifierData.update(event);
|
||||||
|
|
||||||
for (int i = 0; i < mStrokeClassifiersSize; i++) {
|
for (StrokeClassifier c : mStrokeClassifiers) {
|
||||||
mStrokeClassifiers.get(i).onTouchEvent(event);
|
c.onTouchEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < mGestureClassifiersSize; i++) {
|
for (GestureClassifier c : mGestureClassifiers) {
|
||||||
mGestureClassifiers.get(i).onTouchEvent(event);
|
c.onTouchEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
int size = mClassifierData.getEndingStrokes().size();
|
int size = mClassifierData.getEndingStrokes().size();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
Stroke stroke = mClassifierData.getEndingStrokes().get(i);
|
Stroke stroke = mClassifierData.getEndingStrokes().get(i);
|
||||||
float evaluation = 0.0f;
|
float evaluation = 0.0f;
|
||||||
for (int j = 0; j < mStrokeClassifiersSize; j++) {
|
StringBuilder sb = FalsingLog.ENABLED ? new StringBuilder("stroke") : null;
|
||||||
evaluation += mStrokeClassifiers.get(j).getFalseTouchEvaluation(
|
for (StrokeClassifier c : mStrokeClassifiers) {
|
||||||
mCurrentType, stroke);
|
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);
|
mHistoryEvaluator.addStroke(evaluation);
|
||||||
}
|
}
|
||||||
@@ -172,8 +182,17 @@ public class HumanInteractionClassifier extends Classifier {
|
|||||||
int action = event.getActionMasked();
|
int action = event.getActionMasked();
|
||||||
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
|
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
|
||||||
float evaluation = 0.0f;
|
float evaluation = 0.0f;
|
||||||
for (int i = 0; i < mGestureClassifiersSize; i++) {
|
StringBuilder sb = FalsingLog.ENABLED ? new StringBuilder("gesture") : null;
|
||||||
evaluation += mGestureClassifiers.get(i).getFalseTouchEvaluation(mCurrentType);
|
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);
|
mHistoryEvaluator.addGesture(evaluation);
|
||||||
setType(Classifier.GENERIC);
|
setType(Classifier.GENERIC);
|
||||||
@@ -184,18 +203,25 @@ public class HumanInteractionClassifier extends Classifier {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSensorChanged(SensorEvent event) {
|
public void onSensorChanged(SensorEvent event) {
|
||||||
for (int i = 0; i < mStrokeClassifiers.size(); i++) {
|
for (Classifier c : mStrokeClassifiers) {
|
||||||
mStrokeClassifiers.get(i).onSensorChanged(event);
|
c.onSensorChanged(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < mGestureClassifiers.size(); i++) {
|
for (Classifier c : mGestureClassifiers) {
|
||||||
mGestureClassifiers.get(i).onSensorChanged(event);
|
c.onSensorChanged(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isFalseTouch() {
|
public boolean isFalseTouch() {
|
||||||
if (mEnableClassifier) {
|
if (mEnableClassifier) {
|
||||||
return mHistoryEvaluator.getEvaluation() >= 5.0f;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -203,4 +229,9 @@ public class HumanInteractionClassifier extends Classifier {
|
|||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return mEnableClassifier;
|
return mEnableClassifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return "HIC";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,11 @@ public class LengthCountClassifier extends StrokeClassifier {
|
|||||||
public LengthCountClassifier(ClassifierData classifierData) {
|
public LengthCountClassifier(ClassifierData classifierData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return "LEN_CNT";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getFalseTouchEvaluation(int type, Stroke stroke) {
|
public float getFalseTouchEvaluation(int type, Stroke stroke) {
|
||||||
return LengthCountEvaluator.evaluate(stroke.getTotalLength()
|
return LengthCountEvaluator.evaluate(stroke.getTotalLength()
|
||||||
|
|||||||
@@ -28,6 +28,11 @@ public class PointerCountClassifier extends GestureClassifier {
|
|||||||
mCount = 0;
|
mCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return "PTR_CNT";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTouchEvent(MotionEvent event) {
|
public void onTouchEvent(MotionEvent event) {
|
||||||
int action = event.getActionMasked();
|
int action = event.getActionMasked();
|
||||||
|
|||||||
@@ -34,6 +34,11 @@ public class ProximityClassifier extends GestureClassifier {
|
|||||||
public ProximityClassifier(ClassifierData classifierData) {
|
public ProximityClassifier(ClassifierData classifierData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return "PROX";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSensorChanged(SensorEvent event) {
|
public void onSensorChanged(SensorEvent event) {
|
||||||
if (event.sensor.getType() == Sensor.TYPE_PROXIMITY) {
|
if (event.sensor.getType() == Sensor.TYPE_PROXIMITY) {
|
||||||
|
|||||||
@@ -40,6 +40,11 @@ public class SpeedAnglesClassifier extends StrokeClassifier {
|
|||||||
mClassifierData = classifierData;
|
mClassifierData = classifierData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return "SPD_ANG";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTouchEvent(MotionEvent event) {
|
public void onTouchEvent(MotionEvent event) {
|
||||||
int action = event.getActionMasked();
|
int action = event.getActionMasked();
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ public class SpeedClassifier extends StrokeClassifier {
|
|||||||
public SpeedClassifier(ClassifierData classifierData) {
|
public SpeedClassifier(ClassifierData classifierData) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTag() {
|
||||||
|
return "SPD";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getFalseTouchEvaluation(int type, Stroke stroke) {
|
public float getFalseTouchEvaluation(int type, Stroke stroke) {
|
||||||
float duration = (float) stroke.getDurationNanos() / NANOS_TO_SECONDS;
|
float duration = (float) stroke.getDurationNanos() / NANOS_TO_SECONDS;
|
||||||
|
|||||||
@@ -41,4 +41,20 @@ public class StatusBarState {
|
|||||||
* Status bar is locked and shows the full screen user switcher.
|
* Status bar is locked and shows the full screen user switcher.
|
||||||
*/
|
*/
|
||||||
public static final int FULLSCREEN_USER_SWITCHER = 3;
|
public static final int FULLSCREEN_USER_SWITCHER = 3;
|
||||||
|
|
||||||
|
|
||||||
|
public static String toShortString(int x) {
|
||||||
|
switch (x) {
|
||||||
|
case SHADE:
|
||||||
|
return "SHD";
|
||||||
|
case SHADE_LOCKED:
|
||||||
|
return "SHD_LCK";
|
||||||
|
case KEYGUARD:
|
||||||
|
return "KGRD";
|
||||||
|
case FULLSCREEN_USER_SWITCHER:
|
||||||
|
return "FS_USRSW";
|
||||||
|
default:
|
||||||
|
return "bad_value_" + x;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ import com.android.systemui.Prefs;
|
|||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.SystemUIFactory;
|
import com.android.systemui.SystemUIFactory;
|
||||||
import com.android.systemui.assist.AssistManager;
|
import com.android.systemui.assist.AssistManager;
|
||||||
|
import com.android.systemui.classifier.FalsingLog;
|
||||||
import com.android.systemui.classifier.FalsingManager;
|
import com.android.systemui.classifier.FalsingManager;
|
||||||
import com.android.systemui.doze.DozeHost;
|
import com.android.systemui.doze.DozeHost;
|
||||||
import com.android.systemui.doze.DozeLog;
|
import com.android.systemui.doze.DozeLog;
|
||||||
@@ -2263,6 +2264,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
|||||||
mStatusBarWindowManager.setPanelExpanded(isExpanded);
|
mStatusBarWindowManager.setPanelExpanded(isExpanded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onScreenTurnedOff() {
|
||||||
|
mFalsingManager.onScreenOff();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All changes to the status bar and notifications funnel through here and are batched.
|
* All changes to the status bar and notifications funnel through here and are batched.
|
||||||
*/
|
*/
|
||||||
@@ -2966,18 +2971,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
|||||||
KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args);
|
KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FalsingManager.getInstance(mContext).dump(pw);
|
||||||
|
FalsingLog.dump(pw);
|
||||||
|
|
||||||
pw.println("SharedPreferences:");
|
pw.println("SharedPreferences:");
|
||||||
for (Map.Entry<String, ?> entry : Prefs.getAll(mContext).entrySet()) {
|
for (Map.Entry<String, ?> entry : Prefs.getAll(mContext).entrySet()) {
|
||||||
pw.print(" "); pw.print(entry.getKey()); pw.print("="); pw.println(entry.getValue());
|
pw.print(" "); pw.print(entry.getKey()); pw.print("="); pw.println(entry.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String hunStateToString(Entry entry) {
|
|
||||||
if (entry == null) return "null";
|
|
||||||
if (entry.notification == null) return "corrupt";
|
|
||||||
return entry.notification.getPackageName();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void dumpBarTransitions(PrintWriter pw, String var, BarTransitions transitions) {
|
private static void dumpBarTransitions(PrintWriter pw, String var, BarTransitions transitions) {
|
||||||
pw.print(" "); pw.print(var); pw.print(".BarTransitions.mMode=");
|
pw.print(" "); pw.print(var); pw.print(".BarTransitions.mMode=");
|
||||||
pw.println(BarTransitions.modeToString(transitions.getMode()));
|
pw.println(BarTransitions.modeToString(transitions.getMode()));
|
||||||
@@ -4186,7 +4188,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
|
|||||||
mDeviceInteractive = false;
|
mDeviceInteractive = false;
|
||||||
mWakeUpComingFromTouch = false;
|
mWakeUpComingFromTouch = false;
|
||||||
mWakeUpTouchLocation = null;
|
mWakeUpTouchLocation = null;
|
||||||
mFalsingManager.onScreenOff();
|
|
||||||
mStackScroller.setAnimationsEnabled(false);
|
mStackScroller.setAnimationsEnabled(false);
|
||||||
updateVisibleToUser();
|
updateVisibleToUser();
|
||||||
if (mLaunchCameraOnFinishedGoingToSleep) {
|
if (mLaunchCameraOnFinishedGoingToSleep) {
|
||||||
|
|||||||
@@ -212,6 +212,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
|||||||
|
|
||||||
public void onScreenTurnedOff() {
|
public void onScreenTurnedOff() {
|
||||||
mScreenTurnedOn = false;
|
mScreenTurnedOn = false;
|
||||||
|
mPhoneStatusBar.onScreenTurnedOff();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void notifyDeviceWakeUpRequested() {
|
public void notifyDeviceWakeUpRequested() {
|
||||||
|
|||||||
Reference in New Issue
Block a user