Merge "Add falsing protection to the pulsing state" into tm-qpr-dev am: c443da0fa1

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19744936

Change-Id: Ic1e36b83b7d709e2006a2d42aab26770a7182518
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Beverly Tai
2022-08-26 18:43:52 +00:00
committed by Automerger Merge Worker
11 changed files with 404 additions and 61 deletions

View File

@@ -102,6 +102,12 @@ public interface FalsingManager {
*/
boolean isFalseDoubleTap();
/**
* Whether the last proximity event reported NEAR. May be used to short circuit motion events
* that require the proximity sensor is not covered.
*/
boolean isProximityNear();
boolean isClassifierEnabled();
boolean shouldEnforceBouncer();

View File

@@ -80,12 +80,14 @@ public class BrightLineFalsingManager implements FalsingManager {
private final Collection<FalsingClassifier> mClassifiers;
private final List<FalsingBeliefListener> mFalsingBeliefListeners = new ArrayList<>();
private List<FalsingTapListener> mFalsingTapListeners = new ArrayList<>();
private ProximityEvent mLastProximityEvent;
private boolean mDestroyed;
private final SessionListener mSessionListener = new SessionListener() {
@Override
public void onSessionEnded() {
mLastProximityEvent = null;
mClassifiers.forEach(FalsingClassifier::onSessionEnded);
}
@@ -336,6 +338,7 @@ public class BrightLineFalsingManager implements FalsingManager {
public void onProximityEvent(ProximityEvent proximityEvent) {
// TODO: some of these classifiers might allow us to abort early, meaning we don't have to
// make these calls.
mLastProximityEvent = proximityEvent;
mClassifiers.forEach((classifier) -> classifier.onProximityEvent(proximityEvent));
}
@@ -347,6 +350,11 @@ public class BrightLineFalsingManager implements FalsingManager {
}
}
@Override
public boolean isProximityNear() {
return mLastProximityEvent != null && mLastProximityEvent.getCovered();
}
@Override
public boolean isUnlockingDisabled() {
return false;

View File

@@ -47,9 +47,9 @@ import javax.inject.Inject;
@SysUISingleton
class FalsingCollectorImpl implements FalsingCollector {
private static final boolean DEBUG = false;
private static final String TAG = "FalsingManager";
private static final String PROXIMITY_SENSOR_TAG = "FalsingManager";
private static final String TAG = "FalsingCollector";
private static final String PROXIMITY_SENSOR_TAG = "FalsingCollector";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final long GESTURE_PROCESSING_DELAY_MS = 100;
private final FalsingDataProvider mFalsingDataProvider;

View File

@@ -143,6 +143,11 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable {
return mInternalFalsingManager.isFalseDoubleTap();
}
@Override
public boolean isProximityNear() {
return mInternalFalsingManager.isProximityNear();
}
@Override
public boolean isClassifierEnabled() {
return mInternalFalsingManager.isClassifierEnabled();

View File

@@ -17,12 +17,9 @@
package com.android.systemui.shade;
import android.app.StatusBarManager;
import android.hardware.display.AmbientDisplayConfiguration;
import android.media.AudioManager;
import android.media.session.MediaSessionLegacyHelper;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
import android.view.GestureDetector;
import android.view.InputDevice;
@@ -52,7 +49,6 @@ import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager;
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
import com.android.systemui.tuner.TunerService;
import java.io.PrintWriter;
import java.util.Optional;
@@ -66,7 +62,6 @@ import javax.inject.Inject;
public class NotificationShadeWindowViewController {
private static final String TAG = "NotifShadeWindowVC";
private final FalsingCollector mFalsingCollector;
private final TunerService mTunerService;
private final SysuiStatusBarStateController mStatusBarStateController;
private final NotificationShadeWindowView mView;
private final NotificationShadeDepthController mDepthController;
@@ -77,6 +72,7 @@ public class NotificationShadeWindowViewController {
private final StatusBarWindowStateController mStatusBarWindowStateController;
private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
private final AmbientState mAmbientState;
private final PulsingGestureListener mPulsingGestureListener;
private GestureDetector mGestureDetector;
private View mBrightnessMirror;
@@ -88,8 +84,6 @@ public class NotificationShadeWindowViewController {
private final CentralSurfaces mService;
private final NotificationShadeWindowController mNotificationShadeWindowController;
private DragDownHelper mDragDownHelper;
private boolean mDoubleTapEnabled;
private boolean mSingleTapEnabled;
private boolean mExpandingBelowNotch;
private final DockManager mDockManager;
private final NotificationPanelViewController mNotificationPanelViewController;
@@ -102,7 +96,6 @@ public class NotificationShadeWindowViewController {
public NotificationShadeWindowViewController(
LockscreenShadeTransitionController transitionController,
FalsingCollector falsingCollector,
TunerService tunerService,
SysuiStatusBarStateController statusBarStateController,
DockManager dockManager,
NotificationShadeDepthController depthController,
@@ -117,10 +110,11 @@ public class NotificationShadeWindowViewController {
CentralSurfaces centralSurfaces,
NotificationShadeWindowController controller,
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
AmbientState ambientState) {
AmbientState ambientState,
PulsingGestureListener pulsingGestureListener
) {
mLockscreenShadeTransitionController = transitionController;
mFalsingCollector = falsingCollector;
mTunerService = tunerService;
mStatusBarStateController = statusBarStateController;
mView = notificationShadeWindowView;
mDockManager = dockManager;
@@ -136,6 +130,7 @@ public class NotificationShadeWindowViewController {
mNotificationShadeWindowController = controller;
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
mAmbientState = ambientState;
mPulsingGestureListener = pulsingGestureListener;
// This view is not part of the newly inflated expanded status bar.
mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container);
@@ -151,46 +146,7 @@ public class NotificationShadeWindowViewController {
/** Inflates the {@link R.layout#status_bar_expanded} layout and sets it up. */
public void setupExpandedStatusBar() {
mStackScrollLayout = mView.findViewById(R.id.notification_stack_scroller);
TunerService.Tunable tunable = (key, newValue) -> {
AmbientDisplayConfiguration configuration =
new AmbientDisplayConfiguration(mView.getContext());
switch (key) {
case Settings.Secure.DOZE_DOUBLE_TAP_GESTURE:
mDoubleTapEnabled = configuration.doubleTapGestureEnabled(
UserHandle.USER_CURRENT);
break;
case Settings.Secure.DOZE_TAP_SCREEN_GESTURE:
mSingleTapEnabled = configuration.tapGestureEnabled(UserHandle.USER_CURRENT);
}
};
mTunerService.addTunable(tunable,
Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
Settings.Secure.DOZE_TAP_SCREEN_GESTURE);
GestureDetector.SimpleOnGestureListener gestureListener =
new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if (mSingleTapEnabled && !mDockManager.isDocked()) {
mService.wakeUpIfDozing(
SystemClock.uptimeMillis(), mView, "SINGLE_TAP");
return true;
}
return false;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
if (mDoubleTapEnabled || mSingleTapEnabled) {
mService.wakeUpIfDozing(
SystemClock.uptimeMillis(), mView, "DOUBLE_TAP");
return true;
}
return false;
}
};
mGestureDetector = new GestureDetector(mView.getContext(), gestureListener);
mGestureDetector = new GestureDetector(mView.getContext(), mPulsingGestureListener);
mLowLightClockController.ifPresent(controller -> controller.attachLowLightClockView(mView));

View File

@@ -0,0 +1,111 @@
/*
* Copyright (C) 2022 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.shade
import android.hardware.display.AmbientDisplayConfiguration
import android.os.SystemClock
import android.os.UserHandle
import android.provider.Settings
import android.view.GestureDetector
import android.view.MotionEvent
import com.android.systemui.Dumpable
import com.android.systemui.dock.DockManager
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
import com.android.systemui.tuner.TunerService
import com.android.systemui.tuner.TunerService.Tunable
import java.io.PrintWriter
import javax.inject.Inject
/**
* If tap and/or double tap to wake is enabled, this gestureListener will wake the display on
* tap/double tap when the device is pulsing (AoD 2). Taps are gated by the proximity sensor and
* falsing manager.
*
* Touches go through the [NotificationShadeWindowViewController] when the device is pulsing.
* Otherwise, if the device is dozing and NOT pulsing, wake-ups are handled by
* [com.android.systemui.doze.DozeSensors].
*/
@CentralSurfacesComponent.CentralSurfacesScope
class PulsingGestureListener @Inject constructor(
private val notificationShadeWindowView: NotificationShadeWindowView,
private val falsingManager: FalsingManager,
private val dockManager: DockManager,
private val centralSurfaces: CentralSurfaces,
private val ambientDisplayConfiguration: AmbientDisplayConfiguration,
tunerService: TunerService,
dumpManager: DumpManager
) : GestureDetector.SimpleOnGestureListener(), Dumpable {
private var doubleTapEnabled = false
private var singleTapEnabled = false
init {
val tunable = Tunable { key: String?, _: String? ->
when (key) {
Settings.Secure.DOZE_DOUBLE_TAP_GESTURE ->
doubleTapEnabled = ambientDisplayConfiguration.doubleTapGestureEnabled(
UserHandle.USER_CURRENT)
Settings.Secure.DOZE_TAP_SCREEN_GESTURE ->
singleTapEnabled = ambientDisplayConfiguration.tapGestureEnabled(
UserHandle.USER_CURRENT)
}
}
tunerService.addTunable(tunable,
Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
Settings.Secure.DOZE_TAP_SCREEN_GESTURE)
dumpManager.registerDumpable(this)
}
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
if (singleTapEnabled &&
!dockManager.isDocked &&
!falsingManager.isProximityNear &&
!falsingManager.isFalseTap(FalsingManager.MODERATE_PENALTY)
) {
centralSurfaces.wakeUpIfDozing(
SystemClock.uptimeMillis(),
notificationShadeWindowView,
"PULSING_SINGLE_TAP")
return true
}
return false
}
override fun onDoubleTap(e: MotionEvent): Boolean {
if ((doubleTapEnabled || singleTapEnabled) &&
!falsingManager.isProximityNear &&
!falsingManager.isFalseDoubleTap
) {
centralSurfaces.wakeUpIfDozing(
SystemClock.uptimeMillis(),
notificationShadeWindowView,
"PULSING_DOUBLE_TAP")
return true
}
return false
}
override fun dump(pw: PrintWriter, args: Array<out String>) {
pw.println("singleTapEnabled=$singleTapEnabled")
pw.println("doubleTapEnabled=$doubleTapEnabled")
pw.println("isDocked=${dockManager.isDocked}")
pw.println("isProxCovered=${falsingManager.isProximityNear}")
}
}

View File

@@ -32,6 +32,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.testing.FakeMetricsLogger;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import org.junit.Before;
@@ -111,5 +112,51 @@ public class BrightLineFalsingManagerTest extends SysuiTestCase {
assertThat(mBrightLineFalsingManager.isFalseDoubleTap()).isFalse();
}
@Test
public void testIsProxNear_noProxEvents_defaultsToFalse() {
assertThat(mBrightLineFalsingManager.isProximityNear()).isFalse();
}
@Test
public void testIsProxNear_receivesNearEvent() {
mBrightLineFalsingManager.onProximityEvent(new FalsingManager.ProximityEvent() {
@Override
public boolean getCovered() {
return true;
}
@Override
public long getTimestampNs() {
return 0;
}
});
assertThat(mBrightLineFalsingManager.isProximityNear()).isTrue();
}
@Test
public void testIsProxNear_receivesNearAndThenFarEvent() {
mBrightLineFalsingManager.onProximityEvent(new FalsingManager.ProximityEvent() {
@Override
public boolean getCovered() {
return true;
}
@Override
public long getTimestampNs() {
return 0;
}
});
mBrightLineFalsingManager.onProximityEvent(new FalsingManager.ProximityEvent() {
@Override
public boolean getCovered() {
return false;
}
@Override
public long getTimestampNs() {
return 5;
}
});
assertThat(mBrightLineFalsingManager.isProximityNear()).isFalse();
}
}

View File

@@ -26,19 +26,18 @@ import com.android.systemui.classifier.FalsingCollectorFake
import com.android.systemui.dock.DockManager
import com.android.systemui.keyguard.KeyguardUnlockAnimationController
import com.android.systemui.lowlightclock.LowLightClockController
import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
import com.android.systemui.statusbar.LockscreenShadeTransitionController
import com.android.systemui.statusbar.NotificationShadeDepthController
import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.notification.stack.AmbientState
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.systemui.statusbar.phone.PhoneStatusBarViewController
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager
import com.android.systemui.statusbar.window.StatusBarWindowStateController
import com.android.systemui.tuner.TunerService
import com.google.common.truth.Truth.assertThat
import java.util.Optional
import org.junit.Before
@@ -60,8 +59,6 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
@Mock
private lateinit var view: NotificationShadeWindowView
@Mock
private lateinit var tunserService: TunerService
@Mock
private lateinit var sysuiStatusBarStateController: SysuiStatusBarStateController
@Mock
private lateinit var centralSurfaces: CentralSurfaces
@@ -91,6 +88,8 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
private lateinit var phoneStatusBarViewController: PhoneStatusBarViewController
@Mock
private lateinit var lowLightClockController: LowLightClockController
@Mock
private lateinit var pulsingGestureListener: PulsingGestureListener
private lateinit var interactionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
private lateinit var interactionEventHandler: InteractionEventHandler
@@ -105,7 +104,6 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
underTest = NotificationShadeWindowViewController(
lockscreenShadeTransitionController,
FalsingCollectorFake(),
tunserService,
sysuiStatusBarStateController,
dockManager,
notificationShadeDepthController,
@@ -120,7 +118,8 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
centralSurfaces,
notificationShadeWindowController,
keyguardUnlockAnimationController,
ambientState
ambientState,
pulsingGestureListener
)
underTest.setupExpandedStatusBar()

View File

@@ -89,6 +89,7 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
@Mock private LowLightClockController mLowLightClockController;
@Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
@Mock private AmbientState mAmbientState;
@Mock private PulsingGestureListener mPulsingGestureListener;
@Captor private ArgumentCaptor<NotificationShadeWindowView.InteractionEventHandler>
mInteractionEventHandlerCaptor;
@@ -110,7 +111,6 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
mController = new NotificationShadeWindowViewController(
mLockscreenShadeTransitionController,
new FalsingCollectorFake(),
mTunerService,
mStatusBarStateController,
mDockManager,
mNotificationShadeDepthController,
@@ -125,7 +125,9 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
mCentralSurfaces,
mNotificationShadeWindowController,
mKeyguardUnlockAnimationController,
mAmbientState);
mAmbientState,
mPulsingGestureListener
);
mController.setupExpandedStatusBar();
mController.setDragDownHelper(mDragDownHelper);
}

View File

@@ -0,0 +1,199 @@
/*
* Copyright (C) 2022 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.shade
import android.hardware.display.AmbientDisplayConfiguration
import android.provider.Settings.Secure.DOZE_DOUBLE_TAP_GESTURE
import android.provider.Settings.Secure.DOZE_TAP_SCREEN_GESTURE
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.MotionEvent
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dock.DockManager
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.systemui.tuner.TunerService
import com.android.systemui.tuner.TunerService.Tunable
import com.android.systemui.util.mockito.eq
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyLong
import org.mockito.ArgumentMatchers.anyObject
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
@RunWithLooper(setAsMainLooper = true)
@SmallTest
class PulsingGestureListenerTest : SysuiTestCase() {
@Mock
private lateinit var view: NotificationShadeWindowView
@Mock
private lateinit var centralSurfaces: CentralSurfaces
@Mock
private lateinit var dockManager: DockManager
@Mock
private lateinit var falsingManager: FalsingManager
@Mock
private lateinit var ambientDisplayConfiguration: AmbientDisplayConfiguration
@Mock
private lateinit var tunerService: TunerService
@Mock
private lateinit var dumpManager: DumpManager
private lateinit var tunableCaptor: ArgumentCaptor<Tunable>
private lateinit var underTest: PulsingGestureListener
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
underTest = PulsingGestureListener(
view,
falsingManager,
dockManager,
centralSurfaces,
ambientDisplayConfiguration,
tunerService,
dumpManager
)
whenever(dockManager.isDocked).thenReturn(false)
}
@Test
fun testGestureDetector_singleTapEnabled() {
// GIVEN tap is enabled, prox not covered
whenever(ambientDisplayConfiguration.tapGestureEnabled(anyInt())).thenReturn(true)
updateSettings()
whenever(falsingManager.isProximityNear).thenReturn(false)
// GIVEN the falsing manager does NOT think the tap is a false tap
whenever(falsingManager.isFalseTap(anyInt())).thenReturn(false)
// WHEN there's a tap
underTest.onSingleTapConfirmed(downEv)
// THEN wake up device if dozing
verify(centralSurfaces).wakeUpIfDozing(anyLong(), anyObject(), anyString())
}
@Test
fun testGestureDetector_doubleTapEnabled() {
// GIVEN double tap is enabled, prox not covered
whenever(ambientDisplayConfiguration.doubleTapGestureEnabled(anyInt())).thenReturn(true)
updateSettings()
whenever(falsingManager.isProximityNear).thenReturn(false)
// GIVEN the falsing manager does NOT think the tap is a false tap
whenever(falsingManager.isFalseDoubleTap).thenReturn(false)
// WHEN there's a double tap
underTest.onDoubleTap(downEv)
// THEN wake up device if dozing
verify(centralSurfaces).wakeUpIfDozing(anyLong(), anyObject(), anyString())
}
@Test
fun testGestureDetector_singleTapEnabled_falsing() {
// GIVEN tap is enabled, prox not covered
whenever(ambientDisplayConfiguration.tapGestureEnabled(anyInt())).thenReturn(true)
updateSettings()
whenever(falsingManager.isProximityNear).thenReturn(false)
// GIVEN the falsing manager thinks the tap is a false tap
whenever(falsingManager.isFalseTap(anyInt())).thenReturn(true)
// WHEN there's a tap
underTest.onSingleTapConfirmed(downEv)
// THEN the device doesn't wake up
verify(centralSurfaces, never()).wakeUpIfDozing(anyLong(), anyObject(), anyString())
}
@Test
fun testGestureDetector_doubleTapEnabled_falsing() {
// GIVEN double tap is enabled, prox not covered
whenever(ambientDisplayConfiguration.doubleTapGestureEnabled(anyInt())).thenReturn(true)
updateSettings()
whenever(falsingManager.isProximityNear).thenReturn(false)
// GIVEN the falsing manager thinks the tap is a false tap
whenever(falsingManager.isFalseDoubleTap).thenReturn(true)
// WHEN there's a tap
underTest.onDoubleTap(downEv)
// THEN the device doesn't wake up
verify(centralSurfaces, never()).wakeUpIfDozing(anyLong(), anyObject(), anyString())
}
@Test
fun testGestureDetector_singleTapEnabled_proxCovered() {
// GIVEN tap is enabled, not a false tap based on classifiers
whenever(ambientDisplayConfiguration.tapGestureEnabled(anyInt())).thenReturn(true)
updateSettings()
whenever(falsingManager.isFalseTap(anyInt())).thenReturn(false)
// GIVEN prox is covered
whenever(falsingManager.isProximityNear()).thenReturn(true)
// WHEN there's a tap
underTest.onSingleTapConfirmed(downEv)
// THEN the device doesn't wake up
verify(centralSurfaces, never()).wakeUpIfDozing(anyLong(), anyObject(), anyString())
}
@Test
fun testGestureDetector_doubleTapEnabled_proxCovered() {
// GIVEN double tap is enabled, not a false tap based on classifiers
whenever(ambientDisplayConfiguration.doubleTapGestureEnabled(anyInt())).thenReturn(true)
updateSettings()
whenever(falsingManager.isFalseDoubleTap).thenReturn(false)
// GIVEN prox is covered
whenever(falsingManager.isProximityNear()).thenReturn(true)
// WHEN there's a tap
underTest.onDoubleTap(downEv)
// THEN the device doesn't wake up
verify(centralSurfaces, never()).wakeUpIfDozing(anyLong(), anyObject(), anyString())
}
fun updateSettings() {
tunableCaptor = ArgumentCaptor.forClass(Tunable::class.java)
verify(tunerService).addTunable(
tunableCaptor.capture(),
eq(DOZE_DOUBLE_TAP_GESTURE),
eq(DOZE_TAP_SCREEN_GESTURE))
tunableCaptor.value.onTuningChanged(DOZE_DOUBLE_TAP_GESTURE, "")
tunableCaptor.value.onTuningChanged(DOZE_TAP_SCREEN_GESTURE, "")
}
}
private val downEv = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)

View File

@@ -40,6 +40,7 @@ public class FalsingManagerFake implements FalsingManager {
private boolean mIsReportingEnabled;
private boolean mIsFalseRobustTap;
private boolean mDestroyed;
private boolean mIsProximityNear;
private final List<FalsingBeliefListener> mFalsingBeliefListeners = new ArrayList<>();
private final List<FalsingTapListener> mTapListeners = new ArrayList<>();
@@ -82,6 +83,10 @@ public class FalsingManagerFake implements FalsingManager {
mIsFalseDoubleTap = falseDoubleTap;
}
public void setIsProximityNear(boolean proxNear) {
mIsProximityNear = proxNear;
}
@Override
public boolean isSimpleTap() {
checkDestroyed();
@@ -100,6 +105,11 @@ public class FalsingManagerFake implements FalsingManager {
return mIsFalseDoubleTap;
}
@Override
public boolean isProximityNear() {
return mIsProximityNear;
}
@VisibleForTesting
public void setIsClassifierEnabled(boolean isClassifierEnabled) {
mIsClassifierEnabled = isClassifierEnabled;