From 6002a6b7b203afb476c7fa15fa72dccb66ca6d96 Mon Sep 17 00:00:00 2001 From: Dave Mankoff Date: Thu, 5 Jan 2023 22:31:03 +0000 Subject: [PATCH] Skip falsing on unfolded devices. Exposes the already-known folded state on FoldStateListener such that it can be queried when needed. Bug: 236197248 Test: manually on a foldable && atest SystemUITests Change-Id: I1bca6254b7e8528e0a999d8f171e0ee1f966aeb4 --- .../devicestate/DeviceStateManager.java | 9 +++++++++ .../classifier/BrightLineFalsingManager.java | 7 +++++-- .../classifier/FalsingDataProvider.java | 8 ++++++++ .../src/com/android/systemui/flags/Flags.kt | 3 +++ .../systemui/unfold/UnfoldTransitionModule.kt | 18 ++++++++++++++++++ .../classifier/BrightLineClassifierTest.java | 2 ++ .../BrightLineFalsingManagerTest.java | 17 +++++++++++++---- .../systemui/classifier/ClassifierTest.java | 5 ++++- .../classifier/FalsingDataProviderTest.java | 18 +++++++++++++++++- 9 files changed, 79 insertions(+), 8 deletions(-) diff --git a/core/java/android/hardware/devicestate/DeviceStateManager.java b/core/java/android/hardware/devicestate/DeviceStateManager.java index dba1a5e8dfc61..6a667fe39974d 100644 --- a/core/java/android/hardware/devicestate/DeviceStateManager.java +++ b/core/java/android/hardware/devicestate/DeviceStateManager.java @@ -251,6 +251,10 @@ public final class DeviceStateManager { @Nullable private Boolean lastResult; + public FoldStateListener(Context context) { + this(context, folded -> {}); + } + public FoldStateListener(Context context, Consumer listener) { mFoldedDeviceStates = context.getResources().getIntArray( com.android.internal.R.array.config_foldedDeviceStates); @@ -266,5 +270,10 @@ public final class DeviceStateManager { mDelegate.accept(folded); } } + + @Nullable + public Boolean getFolded() { + return lastResult; + } } } diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java index e8e1f2e95f5db..e9ac840cf4f4e 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java @@ -176,7 +176,8 @@ public class BrightLineFalsingManager implements FalsingManager { private @Classifier.InteractionType int mPriorInteractionType = Classifier.GENERIC; @Inject - public BrightLineFalsingManager(FalsingDataProvider falsingDataProvider, + public BrightLineFalsingManager( + FalsingDataProvider falsingDataProvider, MetricsLogger metricsLogger, @Named(BRIGHT_LINE_GESTURE_CLASSIFERS) Set classifiers, SingleTapClassifier singleTapClassifier, LongTapClassifier longTapClassifier, @@ -399,7 +400,9 @@ public class BrightLineFalsingManager implements FalsingManager { || mDataProvider.isJustUnlockedWithFace() || mDataProvider.isDocked() || mAccessibilityManager.isTouchExplorationEnabled() - || mDataProvider.isA11yAction(); + || mDataProvider.isA11yAction() + || (mFeatureFlags.isEnabled(Flags.FALSING_OFF_FOR_UNFOLDED) + && !mDataProvider.isFolded()); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java index 09ebeeac163f4..5f347c1588182 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingDataProvider.java @@ -16,6 +16,7 @@ package com.android.systemui.classifier; +import android.hardware.devicestate.DeviceStateManager.FoldStateListener; import android.util.DisplayMetrics; import android.view.MotionEvent; import android.view.MotionEvent.PointerCoords; @@ -42,6 +43,7 @@ public class FalsingDataProvider { private final int mWidthPixels; private final int mHeightPixels; private BatteryController mBatteryController; + private final FoldStateListener mFoldStateListener; private final DockManager mDockManager; private final float mXdpi; private final float mYdpi; @@ -65,12 +67,14 @@ public class FalsingDataProvider { public FalsingDataProvider( DisplayMetrics displayMetrics, BatteryController batteryController, + FoldStateListener foldStateListener, DockManager dockManager) { mXdpi = displayMetrics.xdpi; mYdpi = displayMetrics.ydpi; mWidthPixels = displayMetrics.widthPixels; mHeightPixels = displayMetrics.heightPixels; mBatteryController = batteryController; + mFoldStateListener = foldStateListener; mDockManager = dockManager; FalsingClassifier.logInfo("xdpi, ydpi: " + getXdpi() + ", " + getYdpi()); @@ -376,6 +380,10 @@ public class FalsingDataProvider { return mBatteryController.isWirelessCharging() || mDockManager.isDocked(); } + public boolean isFolded() { + return Boolean.TRUE.equals(mFoldStateListener.getFolded()); + } + /** Implement to be alerted abotu the beginning and ending of falsing tracking. */ public interface SessionListener { /** Called when the lock screen is shown and falsing-tracking begins. */ diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index 80a8b45066e1e..c9a2a0b9b7e9e 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -207,6 +207,9 @@ object Flags { val AUTO_PIN_CONFIRMATION = unreleasedFlag(224, "auto_pin_confirmation", "auto_pin_confirmation") + // TODO(b/262859270): Tracking Bug + @JvmField val FALSING_OFF_FOR_UNFOLDED = releasedFlag(225, "falsing_off_for_unfolded") + // 300 - power menu // TODO(b/254512600): Tracking Bug @JvmField val POWER_MENU_LITE = releasedFlag(300, "power_menu_lite") diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt index 59ad24a3e7bb2..2709da38a7d83 100644 --- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt +++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldTransitionModule.kt @@ -17,6 +17,9 @@ package com.android.systemui.unfold import android.content.Context +import android.hardware.devicestate.DeviceStateManager +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.keyguard.LifecycleScreenStatusProvider import com.android.systemui.unfold.config.UnfoldTransitionConfig import com.android.systemui.unfold.system.SystemUnfoldSharedModule @@ -32,6 +35,7 @@ import dagger.Lazy import dagger.Module import dagger.Provides import java.util.Optional +import java.util.concurrent.Executor import javax.inject.Named import javax.inject.Singleton @@ -40,6 +44,20 @@ class UnfoldTransitionModule { @Provides @UnfoldTransitionATracePrefix fun tracingTagPrefix() = "systemui" + /** A globally available FoldStateListener that allows one to query the fold state. */ + @Provides + @Singleton + fun providesFoldStateListener( + deviceStateManager: DeviceStateManager, + @Application context: Context, + @Main executor: Executor + ): DeviceStateManager.FoldStateListener { + val listener = DeviceStateManager.FoldStateListener(context) + deviceStateManager.registerCallback(executor, listener) + + return listener + } + @Provides @Singleton fun providesFoldStateLoggingProvider( diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java index 0fadc138637ae..e4df754ec96a0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java @@ -106,6 +106,7 @@ public class BrightLineClassifierTest extends SysuiTestCase { mClassifiers.add(mClassifierB); when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList); when(mKeyguardStateController.isShowing()).thenReturn(true); + when(mFalsingDataProvider.isFolded()).thenReturn(true); mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider, mMetricsLogger, mClassifiers, mSingleTapClassfier, mLongTapClassifier, mDoubleTapClassifier, mHistoryTracker, mKeyguardStateController, @@ -121,6 +122,7 @@ public class BrightLineClassifierTest extends SysuiTestCase { mGestureFinalizedListener = gestureCompleteListenerCaptor.getValue(); mFakeFeatureFlags.set(Flags.FALSING_FOR_LONG_TAPS, true); mFakeFeatureFlags.set(Flags.MEDIA_FALSING_PENALTY, true); + mFakeFeatureFlags.set(Flags.FALSING_OFF_FOR_UNFOLDED, true); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java index 4281ee0f139f3..ae38eb67c4313 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineFalsingManagerTest.java @@ -89,25 +89,27 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase { mClassifiers.add(mClassifierA); when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList); when(mKeyguardStateController.isShowing()).thenReturn(true); + when(mFalsingDataProvider.isFolded()).thenReturn(true); mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider, mMetricsLogger, mClassifiers, mSingleTapClassifier, mLongTapClassifier, mDoubleTapClassifier, mHistoryTracker, mKeyguardStateController, mAccessibilityManager, false, mFakeFeatureFlags); mFakeFeatureFlags.set(Flags.FALSING_FOR_LONG_TAPS, true); + mFakeFeatureFlags.set(Flags.FALSING_OFF_FOR_UNFOLDED, true); } @Test public void testA11yDisablesGesture() { - assertThat(mBrightLineFalsingManager.isFalseTap(1)).isTrue(); + assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue(); when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true); - assertThat(mBrightLineFalsingManager.isFalseTap(1)).isFalse(); + assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse(); } @Test public void testA11yDisablesTap() { - assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue(); + assertThat(mBrightLineFalsingManager.isFalseTap(1)).isTrue(); when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(true); - assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse(); + assertThat(mBrightLineFalsingManager.isFalseTap(1)).isFalse(); } @@ -179,4 +181,11 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase { when(mFalsingDataProvider.isA11yAction()).thenReturn(true); assertThat(mBrightLineFalsingManager.isFalseTap(1)).isFalse(); } + + @Test + public void testSkipUnfolded() { + assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isTrue(); + when(mFalsingDataProvider.isFolded()).thenReturn(false); + assertThat(mBrightLineFalsingManager.isFalseTouch(Classifier.GENERIC)).isFalse(); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java index 5fa7214f07ffd..94cf384267ad9 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/ClassifierTest.java @@ -16,6 +16,7 @@ package com.android.systemui.classifier; +import android.hardware.devicestate.DeviceStateManager.FoldStateListener; import android.util.DisplayMetrics; import android.view.MotionEvent; @@ -38,6 +39,7 @@ public class ClassifierTest extends SysuiTestCase { private float mOffsetY = 0; @Mock private BatteryController mBatteryController; + private FoldStateListener mFoldStateListener = new FoldStateListener(mContext); private final DockManagerFake mDockManager = new DockManagerFake(); public void setup() { @@ -47,7 +49,8 @@ public class ClassifierTest extends SysuiTestCase { displayMetrics.ydpi = 100; displayMetrics.widthPixels = 1000; displayMetrics.heightPixels = 1000; - mDataProvider = new FalsingDataProvider(displayMetrics, mBatteryController, mDockManager); + mDataProvider = new FalsingDataProvider( + displayMetrics, mBatteryController, mFoldStateListener, mDockManager); } @After diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java index d315c2da07032..c451a1e754c96 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingDataProviderTest.java @@ -24,6 +24,7 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.hardware.devicestate.DeviceStateManager.FoldStateListener; import android.testing.AndroidTestingRunner; import android.util.DisplayMetrics; import android.view.MotionEvent; @@ -50,6 +51,8 @@ public class FalsingDataProviderTest extends ClassifierTest { private FalsingDataProvider mDataProvider; @Mock private BatteryController mBatteryController; + @Mock + private FoldStateListener mFoldStateListener; private final DockManagerFake mDockManager = new DockManagerFake(); @Before @@ -61,7 +64,8 @@ public class FalsingDataProviderTest extends ClassifierTest { displayMetrics.ydpi = 100; displayMetrics.widthPixels = 1000; displayMetrics.heightPixels = 1000; - mDataProvider = new FalsingDataProvider(displayMetrics, mBatteryController, mDockManager); + mDataProvider = new FalsingDataProvider( + displayMetrics, mBatteryController, mFoldStateListener, mDockManager); } @After @@ -316,4 +320,16 @@ public class FalsingDataProviderTest extends ClassifierTest { mDataProvider.onA11yAction(); assertThat(mDataProvider.isA11yAction()).isTrue(); } + + @Test + public void test_FoldedState_Folded() { + when(mFoldStateListener.getFolded()).thenReturn(true); + assertThat(mDataProvider.isFolded()).isTrue(); + } + + @Test + public void test_FoldedState_Unfolded() { + when(mFoldStateListener.getFolded()).thenReturn(false); + assertThat(mDataProvider.isFolded()).isFalse(); + } }