Merge "Analyze vertical swipes on QS's Scroll View." into tm-qpr-dev

This commit is contained in:
Dave Mankoff
2022-09-23 16:46:29 +00:00
committed by Android (Google) Code Review
14 changed files with 137 additions and 33 deletions

View File

@@ -220,7 +220,7 @@ public class BrightLineFalsingManager implements FalsingManager {
return r;
}).collect(Collectors.toList());
logDebug("False Gesture: " + localResult[0]);
logDebug("False Gesture (type: " + interactionType + "): " + localResult[0]);
return localResult[0];
}
@@ -454,6 +454,12 @@ public class BrightLineFalsingManager implements FalsingManager {
}
}
static void logVerbose(String msg) {
if (DEBUG) {
Log.v(TAG, msg);
}
}
static void logInfo(String msg) {
Log.i(TAG, msg);
RECENT_INFO_LOG.add(msg);

View File

@@ -42,8 +42,9 @@ public abstract class Classifier {
public static final int QS_COLLAPSE = 12;
public static final int UDFPS_AUTHENTICATION = 13;
public static final int LOCK_ICON = 14;
public static final int QS_SWIPE = 15;
public static final int QS_SWIPE_SIDE = 15;
public static final int BACK_GESTURE = 16;
public static final int QS_SWIPE_NESTED = 17;
@IntDef({
QUICK_SETTINGS,
@@ -62,7 +63,8 @@ public abstract class Classifier {
BRIGHTNESS_SLIDER,
UDFPS_AUTHENTICATION,
LOCK_ICON,
QS_SWIPE,
QS_SWIPE_SIDE,
QS_SWIPE_NESTED,
BACK_GESTURE
})
@Retention(RetentionPolicy.SOURCE)

View File

@@ -24,6 +24,7 @@ import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHT
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_DISTANCE_VERTICAL_SWIPE_THRESHOLD_IN;
import static com.android.systemui.classifier.Classifier.BRIGHTNESS_SLIDER;
import static com.android.systemui.classifier.Classifier.QS_COLLAPSE;
import static com.android.systemui.classifier.Classifier.QS_SWIPE_NESTED;
import static com.android.systemui.classifier.Classifier.SHADE_DRAG;
import android.provider.DeviceConfig;
@@ -156,7 +157,8 @@ class DistanceClassifier extends FalsingClassifier {
|| interactionType == QS_COLLAPSE
|| interactionType == Classifier.UDFPS_AUTHENTICATION
|| interactionType == Classifier.LOCK_ICON
|| interactionType == Classifier.QS_SWIPE) {
|| interactionType == Classifier.QS_SWIPE_SIDE
|| interactionType == QS_SWIPE_NESTED) {
return Result.passed(0);
}

View File

@@ -147,6 +147,11 @@ public abstract class FalsingClassifier {
BrightLineFalsingManager.logDebug(msg);
}
/** */
public static void logVerbose(String msg) {
BrightLineFalsingManager.logVerbose(msg);
}
/** */
public static void logInfo(String msg) {
BrightLineFalsingManager.logInfo(msg);

View File

@@ -78,10 +78,10 @@ public class FalsingDataProvider {
void onMotionEvent(MotionEvent motionEvent) {
List<MotionEvent> motionEvents = unpackMotionEvent(motionEvent);
FalsingClassifier.logDebug("Unpacked into: " + motionEvents.size());
FalsingClassifier.logVerbose("Unpacked into: " + motionEvents.size());
if (BrightLineFalsingManager.DEBUG) {
for (MotionEvent m : motionEvents) {
FalsingClassifier.logDebug(
FalsingClassifier.logVerbose(
"x,y,t: " + m.getX() + "," + m.getY() + "," + m.getEventTime());
}
}
@@ -92,7 +92,7 @@ public class FalsingDataProvider {
}
mRecentMotionEvents.addAll(motionEvents);
FalsingClassifier.logDebug("Size: " + mRecentMotionEvents.size());
FalsingClassifier.logVerbose("Size: " + mRecentMotionEvents.size());
mMotionEventListeners.forEach(listener -> listener.onMotionEvent(motionEvent));

View File

@@ -19,7 +19,7 @@ package com.android.systemui.classifier;
import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.BRIGHTLINE_FALSING_PROXIMITY_PERCENT_COVERED_THRESHOLD;
import static com.android.systemui.classifier.Classifier.BRIGHTNESS_SLIDER;
import static com.android.systemui.classifier.Classifier.QS_COLLAPSE;
import static com.android.systemui.classifier.Classifier.QS_SWIPE;
import static com.android.systemui.classifier.Classifier.QS_SWIPE_SIDE;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
import android.provider.DeviceConfig;
@@ -119,7 +119,7 @@ class ProximityClassifier extends FalsingClassifier {
@Classifier.InteractionType int interactionType,
double historyBelief, double historyConfidence) {
if (interactionType == QUICK_SETTINGS || interactionType == BRIGHTNESS_SLIDER
|| interactionType == QS_COLLAPSE || interactionType == QS_SWIPE) {
|| interactionType == QS_COLLAPSE || interactionType == QS_SWIPE_SIDE) {
return Result.passed(0);
}

View File

@@ -24,7 +24,8 @@ import static com.android.systemui.classifier.Classifier.NOTIFICATION_DISMISS;
import static com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN;
import static com.android.systemui.classifier.Classifier.PULSE_EXPAND;
import static com.android.systemui.classifier.Classifier.QS_COLLAPSE;
import static com.android.systemui.classifier.Classifier.QS_SWIPE;
import static com.android.systemui.classifier.Classifier.QS_SWIPE_NESTED;
import static com.android.systemui.classifier.Classifier.QS_SWIPE_SIDE;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
import static com.android.systemui.classifier.Classifier.RIGHT_AFFORDANCE;
import static com.android.systemui.classifier.Classifier.SHADE_DRAG;
@@ -86,9 +87,12 @@ public class TypeClassifier extends FalsingClassifier {
case QS_COLLAPSE:
wrongDirection = !vertical || !up;
break;
case QS_SWIPE:
case QS_SWIPE_SIDE:
wrongDirection = vertical;
break;
case QS_SWIPE_NESTED:
wrongDirection = !vertical;
break;
default:
wrongDirection = true;
break;

View File

@@ -137,8 +137,8 @@ class ZigZagClassifier extends FalsingClassifier {
runningAbsDy += Math.abs(point.y - pY);
pX = point.x;
pY = point.y;
logDebug("(x, y, runningAbsDx, runningAbsDy) - (" + pX + ", " + pY + ", " + runningAbsDx
+ ", " + runningAbsDy + ")");
logVerbose("(x, y, runningAbsDx, runningAbsDy) - ("
+ pX + ", " + pY + ", " + runningAbsDx + ", " + runningAbsDy + ")");
}
float devianceX = runningAbsDx - actualDx;

View File

@@ -28,21 +28,29 @@ import android.widget.ScrollView;
public class NonInterceptingScrollView extends ScrollView {
private final int mTouchSlop;
private float mDownY;
private boolean mScrollEnabled = true;
private boolean mPreventingIntercept;
public NonInterceptingScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
public boolean isPreventingIntercept() {
return mPreventingIntercept;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
int action = ev.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
mPreventingIntercept = false;
if (canScrollVertically(1)) {
// If we can scroll down, make sure we're not intercepted by the parent
mPreventingIntercept = true;
final ViewParent parent = getParent();
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(true);
@@ -62,10 +70,13 @@ public class NonInterceptingScrollView extends ScrollView {
public boolean onInterceptTouchEvent(MotionEvent ev) {
// If there's a touch on this view and we can scroll down, we don't want to be intercepted
int action = ev.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
// If we can scroll down, make sure non of our parents intercepts us.
mPreventingIntercept = false;
// If we can scroll down, make sure none of our parents intercepts us.
if (canScrollVertically(1)) {
mPreventingIntercept = true;
final ViewParent parent = getParent();
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(true);

View File

@@ -131,6 +131,10 @@ public class QSContainerImpl extends FrameLayout implements Dumpable {
updateClippingPath();
}
public NonInterceptingScrollView getQSPanelContainer() {
return mQSPanelContainer;
}
public void disable(int state1, int state2, boolean animate) {
final boolean disabled = (state2 & DISABLE2_QUICK_SETTINGS) != 0;
if (disabled == mQsDisabled) return;

View File

@@ -16,8 +16,13 @@
package com.android.systemui.qs;
import android.content.res.Configuration;
import static com.android.systemui.classifier.Classifier.QS_SWIPE_NESTED;
import android.content.res.Configuration;
import android.view.MotionEvent;
import android.view.View;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.qs.dagger.QSScope;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.ViewController;
@@ -30,6 +35,8 @@ public class QSContainerImplController extends ViewController<QSContainerImpl> {
private final QSPanelController mQsPanelController;
private final QuickStatusBarHeaderController mQuickStatusBarHeaderController;
private final ConfigurationController mConfigurationController;
private final FalsingManager mFalsingManager;
private final NonInterceptingScrollView mQSPanelContainer;
private final ConfigurationController.ConfigurationListener mConfigurationListener =
new ConfigurationController.ConfigurationListener() {
@@ -39,14 +46,32 @@ public class QSContainerImplController extends ViewController<QSContainerImpl> {
}
};
private final View.OnTouchListener mContainerTouchHandler = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
if (mQSPanelContainer.isPreventingIntercept()) {
// There's really no action here to take, but we need to tell the FalsingManager
mFalsingManager.isFalseTouch(QS_SWIPE_NESTED);
}
}
return false;
}
};
@Inject
QSContainerImplController(QSContainerImpl view, QSPanelController qsPanelController,
QSContainerImplController(
QSContainerImpl view,
QSPanelController qsPanelController,
QuickStatusBarHeaderController quickStatusBarHeaderController,
ConfigurationController configurationController) {
ConfigurationController configurationController,
FalsingManager falsingManager) {
super(view);
mQsPanelController = qsPanelController;
mQuickStatusBarHeaderController = quickStatusBarHeaderController;
mConfigurationController = configurationController;
mFalsingManager = falsingManager;
mQSPanelContainer = mView.getQSPanelContainer();
}
@Override
@@ -62,11 +87,13 @@ public class QSContainerImplController extends ViewController<QSContainerImpl> {
protected void onViewAttached() {
mView.updateResources(mQsPanelController, mQuickStatusBarHeaderController);
mConfigurationController.addCallback(mConfigurationListener);
mQSPanelContainer.setOnTouchListener(mContainerTouchHandler);
}
@Override
protected void onViewDetached() {
mConfigurationController.removeCallback(mConfigurationListener);
mQSPanelContainer.setOnTouchListener(null);
}
public QSContainerImpl getView() {

View File

@@ -16,7 +16,7 @@
package com.android.systemui.qs;
import static com.android.systemui.classifier.Classifier.QS_SWIPE;
import static com.android.systemui.classifier.Classifier.QS_SWIPE_SIDE;
import static com.android.systemui.media.dagger.MediaModule.QS_PANEL;
import static com.android.systemui.qs.QSPanel.QS_SHOW_BRIGHTNESS;
import static com.android.systemui.qs.dagger.QSFragmentModule.QS_USING_MEDIA_PLAYER;
@@ -76,7 +76,7 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
mFalsingManager.isFalseTouch(QS_SWIPE);
mFalsingManager.isFalseTouch(QS_SWIPE_SIDE);
}
return false;
}

View File

@@ -17,7 +17,7 @@
package com.android.systemui.classifier;
import static com.android.systemui.classifier.Classifier.BRIGHTNESS_SLIDER;
import static com.android.systemui.classifier.Classifier.QS_SWIPE;
import static com.android.systemui.classifier.Classifier.QS_SWIPE_SIDE;
import static com.google.common.truth.Truth.assertThat;
@@ -106,9 +106,9 @@ public class DistanceClassifierTest extends ClassifierTest {
}
@Test
public void testPass_QsSwipeAlwaysPasses() {
public void testPass_QsSwipeSideAlwaysPasses() {
mClassifier.onTouchEvent(appendDownEvent(1, 1));
assertThat(mClassifier.classifyGesture(QS_SWIPE, 0.5, 1).isFalse())
assertThat(mClassifier.classifyGesture(QS_SWIPE_SIDE, 0.5, 1).isFalse())
.isFalse();
}
}

View File

@@ -22,7 +22,8 @@ import static com.android.systemui.classifier.Classifier.LEFT_AFFORDANCE;
import static com.android.systemui.classifier.Classifier.NOTIFICATION_DISMISS;
import static com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN;
import static com.android.systemui.classifier.Classifier.PULSE_EXPAND;
import static com.android.systemui.classifier.Classifier.QS_SWIPE;
import static com.android.systemui.classifier.Classifier.QS_SWIPE_NESTED;
import static com.android.systemui.classifier.Classifier.QS_SWIPE_SIDE;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
import static com.android.systemui.classifier.Classifier.RIGHT_AFFORDANCE;
import static com.android.systemui.classifier.Classifier.UNLOCK;
@@ -323,44 +324,86 @@ public class TypeClassifierTest extends ClassifierTest {
}
@Test
public void testPass_QsSwipe() {
public void testPass_QsSwipeSide() {
when(mDataProvider.isVertical()).thenReturn(false);
when(mDataProvider.isUp()).thenReturn(false); // up and right should cause no effect.
when(mDataProvider.isRight()).thenReturn(false);
assertThat(mClassifier.classifyGesture(QS_SWIPE, 0.5, 0).isFalse()).isFalse();
assertThat(mClassifier.classifyGesture(QS_SWIPE_SIDE, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.isUp()).thenReturn(true);
when(mDataProvider.isRight()).thenReturn(false);
assertThat(mClassifier.classifyGesture(QS_SWIPE, 0.5, 0).isFalse()).isFalse();
assertThat(mClassifier.classifyGesture(QS_SWIPE_SIDE, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.isUp()).thenReturn(false);
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture(QS_SWIPE, 0.5, 0).isFalse()).isFalse();
assertThat(mClassifier.classifyGesture(QS_SWIPE_SIDE, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.isUp()).thenReturn(true);
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture(QS_SWIPE, 0.5, 0).isFalse()).isFalse();
assertThat(mClassifier.classifyGesture(QS_SWIPE_SIDE, 0.5, 0).isFalse()).isFalse();
}
@Test
public void testFalse_QsSwipe() {
public void testFalse_QsSwipeSide() {
when(mDataProvider.isVertical()).thenReturn(true);
when(mDataProvider.isUp()).thenReturn(false); // up and right should cause no effect.
when(mDataProvider.isRight()).thenReturn(false);
assertThat(mClassifier.classifyGesture(QS_SWIPE, 0.5, 0).isFalse()).isTrue();
assertThat(mClassifier.classifyGesture(QS_SWIPE_SIDE, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isUp()).thenReturn(true);
when(mDataProvider.isRight()).thenReturn(false);
assertThat(mClassifier.classifyGesture(QS_SWIPE, 0.5, 0).isFalse()).isTrue();
assertThat(mClassifier.classifyGesture(QS_SWIPE_SIDE, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isUp()).thenReturn(false);
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture(QS_SWIPE, 0.5, 0).isFalse()).isTrue();
assertThat(mClassifier.classifyGesture(QS_SWIPE_SIDE, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isUp()).thenReturn(true);
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture(QS_SWIPE, 0.5, 0).isFalse()).isTrue();
assertThat(mClassifier.classifyGesture(QS_SWIPE_SIDE, 0.5, 0).isFalse()).isTrue();
}
@Test
public void testPass_QsNestedSwipe() {
when(mDataProvider.isVertical()).thenReturn(true);
when(mDataProvider.isUp()).thenReturn(false); // up and right should cause no effect.
when(mDataProvider.isRight()).thenReturn(false);
assertThat(mClassifier.classifyGesture(QS_SWIPE_NESTED, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.isUp()).thenReturn(true);
when(mDataProvider.isRight()).thenReturn(false);
assertThat(mClassifier.classifyGesture(QS_SWIPE_NESTED, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.isUp()).thenReturn(false);
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture(QS_SWIPE_NESTED, 0.5, 0).isFalse()).isFalse();
when(mDataProvider.isUp()).thenReturn(true);
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture(QS_SWIPE_NESTED, 0.5, 0).isFalse()).isFalse();
}
@Test
public void testFalse_QsNestedSwipe() {
when(mDataProvider.isVertical()).thenReturn(false);
when(mDataProvider.isUp()).thenReturn(false); // up and right should cause no effect.
when(mDataProvider.isRight()).thenReturn(false);
assertThat(mClassifier.classifyGesture(QS_SWIPE_NESTED, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isUp()).thenReturn(true);
when(mDataProvider.isRight()).thenReturn(false);
assertThat(mClassifier.classifyGesture(QS_SWIPE_NESTED, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isUp()).thenReturn(false);
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture(QS_SWIPE_NESTED, 0.5, 0).isFalse()).isTrue();
when(mDataProvider.isUp()).thenReturn(true);
when(mDataProvider.isRight()).thenReturn(true);
assertThat(mClassifier.classifyGesture(QS_SWIPE_NESTED, 0.5, 0).isFalse()).isTrue();
}
}