Capture recent motion events used for falsing.
This spits out the last 20 motion events that the FalsingManager uses into bug reports. It only records the data in eng/userdebug builds. This has been cleared with PWG over VC. A tool to visualize this data in in progress. Bug: 148084465 Test: manual Change-Id: I3edf5dc8693a202ff0e31e737e912500a3e4363d
This commit is contained in:
@@ -25,9 +25,12 @@ import android.provider.DeviceConfig;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.DumpController;
|
||||
import com.android.systemui.Dumpable;
|
||||
import com.android.systemui.classifier.brightline.BrightLineFalsingManager;
|
||||
import com.android.systemui.classifier.brightline.FalsingDataProvider;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
@@ -40,6 +43,7 @@ import com.android.systemui.shared.plugins.PluginManager;
|
||||
import com.android.systemui.util.DeviceConfigProxy;
|
||||
import com.android.systemui.util.sensors.ProximitySensor;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@@ -52,7 +56,7 @@ import javax.inject.Singleton;
|
||||
* {@link FalsingManagerImpl} is used when a Plugin is not loaded.
|
||||
*/
|
||||
@Singleton
|
||||
public class FalsingManagerProxy implements FalsingManager {
|
||||
public class FalsingManagerProxy implements FalsingManager, Dumpable {
|
||||
|
||||
private static final String PROXIMITY_SENSOR_TAG = "FalsingManager";
|
||||
|
||||
@@ -63,16 +67,20 @@ public class FalsingManagerProxy implements FalsingManager {
|
||||
private final DeviceConfigProxy mDeviceConfig;
|
||||
private boolean mBrightlineEnabled;
|
||||
private final DockManager mDockManager;
|
||||
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
private Executor mUiBgExecutor;
|
||||
|
||||
@Inject
|
||||
FalsingManagerProxy(Context context, PluginManager pluginManager, @Main Executor executor,
|
||||
DisplayMetrics displayMetrics, ProximitySensor proximitySensor,
|
||||
DeviceConfigProxy deviceConfig, DockManager dockManager,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
||||
DumpController dumpController,
|
||||
@UiBackground Executor uiBgExecutor) {
|
||||
mDisplayMetrics = displayMetrics;
|
||||
mProximitySensor = proximitySensor;
|
||||
mDockManager = dockManager;
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
mUiBgExecutor = uiBgExecutor;
|
||||
mProximitySensor.setTag(PROXIMITY_SENSOR_TAG);
|
||||
mProximitySensor.setSensorDelay(SensorManager.SENSOR_DELAY_GAME);
|
||||
@@ -101,6 +109,8 @@ public class FalsingManagerProxy implements FalsingManager {
|
||||
};
|
||||
|
||||
pluginManager.addPluginListener(mPluginListener, FalsingPlugin.class);
|
||||
|
||||
dumpController.registerDumpable("FalsingManager", this);
|
||||
}
|
||||
|
||||
private void onDeviceConfigPropertiesChanged(Context context, String namespace) {
|
||||
@@ -130,7 +140,7 @@ public class FalsingManagerProxy implements FalsingManager {
|
||||
} else {
|
||||
mInternalFalsingManager = new BrightLineFalsingManager(
|
||||
new FalsingDataProvider(mDisplayMetrics),
|
||||
Dependency.get(KeyguardUpdateMonitor.class),
|
||||
mKeyguardUpdateMonitor,
|
||||
mProximitySensor,
|
||||
mDeviceConfig,
|
||||
mDockManager
|
||||
@@ -321,6 +331,11 @@ public class FalsingManagerProxy implements FalsingManager {
|
||||
mInternalFalsingManager.onTouchEvent(ev, width, height);
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
@@ -21,6 +21,7 @@ import static com.android.systemui.classifier.FalsingManagerImpl.FALSING_SUCCESS
|
||||
|
||||
import android.hardware.biometrics.BiometricSourceType;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
@@ -40,15 +41,19 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Queue;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* FalsingManager designed to make clear why a touch was rejected.
|
||||
*/
|
||||
public class BrightLineFalsingManager implements FalsingManager {
|
||||
|
||||
static final boolean DEBUG = false;
|
||||
private static final String TAG = "FalsingManager";
|
||||
private static final int RECENT_INFO_LOG_SIZE = 20;
|
||||
static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
private static final int RECENT_INFO_LOG_SIZE = 40;
|
||||
private static final int RECENT_SWIPE_LOG_SIZE = 20;
|
||||
|
||||
private final FalsingDataProvider mDataProvider;
|
||||
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
@@ -62,6 +67,8 @@ public class BrightLineFalsingManager implements FalsingManager {
|
||||
private boolean mJustUnlockedWithFace;
|
||||
private static final Queue<String> RECENT_INFO_LOG =
|
||||
new ArrayDeque<>(RECENT_INFO_LOG_SIZE + 1);
|
||||
private static final Queue<DebugSwipeRecord> RECENT_SWIPES =
|
||||
new ArrayDeque<>(RECENT_SWIPE_LOG_SIZE + 1);
|
||||
|
||||
private final List<FalsingClassifier> mClassifiers;
|
||||
|
||||
@@ -78,6 +85,7 @@ public class BrightLineFalsingManager implements FalsingManager {
|
||||
}
|
||||
}
|
||||
};
|
||||
private boolean mPreviousResult = false;
|
||||
|
||||
public BrightLineFalsingManager(FalsingDataProvider falsingDataProvider,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor, ProximitySensor proximitySensor,
|
||||
@@ -148,7 +156,11 @@ public class BrightLineFalsingManager implements FalsingManager {
|
||||
|
||||
@Override
|
||||
public boolean isFalseTouch() {
|
||||
boolean r = !mJustUnlockedWithFace && !mDockManager.isDocked()
|
||||
if (!mDataProvider.isDirty()) {
|
||||
return mPreviousResult;
|
||||
}
|
||||
|
||||
mPreviousResult = !mJustUnlockedWithFace && !mDockManager.isDocked()
|
||||
&& mClassifiers.stream().anyMatch(falsingClassifier -> {
|
||||
boolean result = falsingClassifier.isFalseTouch();
|
||||
if (result) {
|
||||
@@ -167,9 +179,26 @@ public class BrightLineFalsingManager implements FalsingManager {
|
||||
return result;
|
||||
});
|
||||
|
||||
logDebug("Is false touch? " + r);
|
||||
logDebug("Is false touch? " + mPreviousResult);
|
||||
|
||||
return r;
|
||||
if (Build.IS_ENG || Build.IS_USERDEBUG) {
|
||||
// Copy motion events, as the passed in list gets emptied out elsewhere in the code.
|
||||
RECENT_SWIPES.add(new DebugSwipeRecord(
|
||||
mPreviousResult,
|
||||
mDataProvider.getInteractionType(),
|
||||
mDataProvider.getRecentMotionEvents().stream().map(
|
||||
motionEvent -> new XYDt(
|
||||
(int) motionEvent.getX(),
|
||||
(int) motionEvent.getY(),
|
||||
(int) (motionEvent.getEventTime() - motionEvent.getDownTime())))
|
||||
.collect(Collectors.toList())));
|
||||
while (RECENT_SWIPES.size() > RECENT_INFO_LOG_SIZE) {
|
||||
DebugSwipeRecord record = RECENT_SWIPES.remove();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return mPreviousResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -212,7 +241,6 @@ public class BrightLineFalsingManager implements FalsingManager {
|
||||
@Override
|
||||
public void onNotificatonStartDraggingDown() {
|
||||
updateInteractionType(Classifier.NOTIFICATION_DRAG_DOWN);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -348,15 +376,35 @@ public class BrightLineFalsingManager implements FalsingManager {
|
||||
public void dump(PrintWriter pw) {
|
||||
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
|
||||
ipw.println("BRIGHTLINE FALSING MANAGER");
|
||||
ipw.print("classifierEnabled="); pw.println(isClassifierEnabled() ? 1 : 0);
|
||||
ipw.print("mJustUnlockedWithFace="); pw.println(mJustUnlockedWithFace ? 1 : 0);
|
||||
ipw.print("isDocked="); pw.println(mDockManager.isDocked() ? 1 : 0);
|
||||
ipw.print("classifierEnabled=");
|
||||
ipw.println(isClassifierEnabled() ? 1 : 0);
|
||||
ipw.print("mJustUnlockedWithFace=");
|
||||
ipw.println(mJustUnlockedWithFace ? 1 : 0);
|
||||
ipw.print("isDocked=");
|
||||
ipw.println(mDockManager.isDocked() ? 1 : 0);
|
||||
ipw.print("width=");
|
||||
ipw.println(mDataProvider.getWidthPixels());
|
||||
ipw.print("height=");
|
||||
ipw.println(mDataProvider.getHeightPixels());
|
||||
ipw.println();
|
||||
if (RECENT_SWIPES.size() != 0) {
|
||||
ipw.println("Recent swipes:");
|
||||
ipw.increaseIndent();
|
||||
for (DebugSwipeRecord record : RECENT_SWIPES) {
|
||||
ipw.println(record.getString());
|
||||
ipw.println();
|
||||
}
|
||||
ipw.decreaseIndent();
|
||||
} else {
|
||||
ipw.println("No recent swipes");
|
||||
}
|
||||
ipw.println();
|
||||
ipw.println("Recent falsing info:");
|
||||
ipw.increaseIndent();
|
||||
for (String msg : RECENT_INFO_LOG) {
|
||||
ipw.println(msg);
|
||||
}
|
||||
ipw.println();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -386,4 +434,46 @@ public class BrightLineFalsingManager implements FalsingManager {
|
||||
static void logError(String msg) {
|
||||
Log.e(TAG, msg);
|
||||
}
|
||||
|
||||
private static class DebugSwipeRecord {
|
||||
private static final byte VERSION = 1; // opaque version number indicating format of data.
|
||||
private final boolean mIsFalse;
|
||||
private final int mInteractionType;
|
||||
private final List<XYDt> mRecentMotionEvents;
|
||||
|
||||
DebugSwipeRecord(boolean isFalse, int interactionType,
|
||||
List<XYDt> recentMotionEvents) {
|
||||
mIsFalse = isFalse;
|
||||
mInteractionType = interactionType;
|
||||
mRecentMotionEvents = recentMotionEvents;
|
||||
}
|
||||
|
||||
String getString() {
|
||||
StringJoiner sj = new StringJoiner(",");
|
||||
sj.add(Integer.toString(VERSION))
|
||||
.add(mIsFalse ? "1" : "0")
|
||||
.add(Integer.toString(mInteractionType));
|
||||
for (XYDt event : mRecentMotionEvents) {
|
||||
sj.add(event.toString());
|
||||
}
|
||||
return sj.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private static class XYDt {
|
||||
private final int mX;
|
||||
private final int mY;
|
||||
private final int mDT;
|
||||
|
||||
XYDt(int x, int y, int dT) {
|
||||
mX = x;
|
||||
mY = y;
|
||||
mDT = dT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return mX + "," + mY + "," + mDT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,6 +113,10 @@ public class FalsingDataProvider {
|
||||
this.mInteractionType = interactionType;
|
||||
}
|
||||
|
||||
public boolean isDirty() {
|
||||
return mDirty;
|
||||
}
|
||||
|
||||
final int getInteractionType() {
|
||||
return mInteractionType;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.os.ServiceManager;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.IWindowManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.util.NotificationMessagingUtil;
|
||||
@@ -98,10 +99,10 @@ public class DependencyProvider {
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
// Single instance of DisplayMetrics, gets updated by StatusBar, but can be used
|
||||
// anywhere it is needed.
|
||||
public DisplayMetrics provideDisplayMetrics() {
|
||||
return new DisplayMetrics();
|
||||
public DisplayMetrics provideDisplayMetrics(Context context, WindowManager windowManager) {
|
||||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||
context.getDisplay().getMetrics(displayMetrics);
|
||||
return displayMetrics;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.util.DisplayMetrics;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.systemui.DumpController;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.classifier.brightline.BrightLineFalsingManager;
|
||||
import com.android.systemui.dock.DockManager;
|
||||
@@ -53,6 +54,8 @@ public class FalsingManagerProxyTest extends SysuiTestCase {
|
||||
PluginManager mPluginManager;
|
||||
@Mock(stubOnly = true)
|
||||
ProximitySensor mProximitySensor;
|
||||
@Mock(stubOnly = true)
|
||||
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
private FalsingManagerProxy mProxy;
|
||||
private DeviceConfigProxy mDeviceConfig;
|
||||
private DisplayMetrics mDisplayMetrics = new DisplayMetrics();
|
||||
@@ -63,7 +66,6 @@ public class FalsingManagerProxyTest extends SysuiTestCase {
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mDependency.injectMockDependency(KeyguardUpdateMonitor.class);
|
||||
mDeviceConfig = new DeviceConfigProxyFake();
|
||||
mDeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
|
||||
BRIGHTLINE_FALSING_MANAGER_ENABLED, "false", false);
|
||||
@@ -79,7 +81,8 @@ public class FalsingManagerProxyTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void test_brightLineFalsingManagerDisabled() {
|
||||
mProxy = new FalsingManagerProxy(getContext(), mPluginManager, mExecutor, mDisplayMetrics,
|
||||
mProximitySensor, mDeviceConfig, mDockManager, mUiBgExecutor);
|
||||
mProximitySensor, mDeviceConfig, mDockManager, mKeyguardUpdateMonitor,
|
||||
new DumpController(), mUiBgExecutor);
|
||||
assertThat(mProxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class));
|
||||
}
|
||||
|
||||
@@ -89,14 +92,16 @@ public class FalsingManagerProxyTest extends SysuiTestCase {
|
||||
BRIGHTLINE_FALSING_MANAGER_ENABLED, "true", false);
|
||||
mExecutor.runAllReady();
|
||||
mProxy = new FalsingManagerProxy(getContext(), mPluginManager, mExecutor, mDisplayMetrics,
|
||||
mProximitySensor, mDeviceConfig, mDockManager, mUiBgExecutor);
|
||||
mProximitySensor, mDeviceConfig, mDockManager, mKeyguardUpdateMonitor,
|
||||
new DumpController(), mUiBgExecutor);
|
||||
assertThat(mProxy.getInternalFalsingManager(), instanceOf(BrightLineFalsingManager.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_brightLineFalsingManagerToggled() throws InterruptedException {
|
||||
mProxy = new FalsingManagerProxy(getContext(), mPluginManager, mExecutor, mDisplayMetrics,
|
||||
mProximitySensor, mDeviceConfig, mDockManager, mUiBgExecutor);
|
||||
mProximitySensor, mDeviceConfig, mDockManager, mKeyguardUpdateMonitor,
|
||||
new DumpController(), mUiBgExecutor);
|
||||
assertThat(mProxy.getInternalFalsingManager(), instanceOf(FalsingManagerImpl.class));
|
||||
|
||||
mDeviceConfig.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
|
||||
|
||||
Reference in New Issue
Block a user