Merge "Wakeup display on taps before entering true AoD" into tm-qpr-dev
This commit is contained in:
@@ -147,10 +147,10 @@ public interface FalsingManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener that is alerted when a double tap is required to confirm a single tap.
|
||||
* Listener that is alerted when an additional tap is required to confirm a single tap.
|
||||
**/
|
||||
interface FalsingTapListener {
|
||||
void onDoubleTapRequired();
|
||||
void onAdditionalTapRequired();
|
||||
}
|
||||
|
||||
/** Passed to {@link FalsingManager#onProximityEvent}. */
|
||||
|
||||
@@ -291,7 +291,7 @@ public class BrightLineFalsingManager implements FalsingManager {
|
||||
FalsingClassifier.Result.falsed(
|
||||
0, getClass().getSimpleName(), "bad history"));
|
||||
logDebug("False Single Tap: true (bad history)");
|
||||
mFalsingTapListeners.forEach(FalsingTapListener::onDoubleTapRequired);
|
||||
mFalsingTapListeners.forEach(FalsingTapListener::onAdditionalTapRequired);
|
||||
return true;
|
||||
} else {
|
||||
mPriorResults = getPassedResult(0.1);
|
||||
@@ -321,7 +321,7 @@ public class BrightLineFalsingManager implements FalsingManager {
|
||||
mHistoryTracker.falseBelief(),
|
||||
mHistoryTracker.falseConfidence());
|
||||
mPriorResults = Collections.singleton(result);
|
||||
logDebug("False Double Tap: " + result.isFalse());
|
||||
logDebug("False Double Tap: " + result.isFalse() + " reason=" + result.getReason());
|
||||
return result.isFalse();
|
||||
}
|
||||
|
||||
|
||||
@@ -303,9 +303,7 @@ class FalsingCollectorImpl implements FalsingCollector {
|
||||
|
||||
@Override
|
||||
public void onTouchEvent(MotionEvent ev) {
|
||||
if (!mKeyguardStateController.isShowing()
|
||||
|| (mStatusBarStateController.isDozing()
|
||||
&& !mStatusBarStateController.isPulsing())) {
|
||||
if (!mKeyguardStateController.isShowing()) {
|
||||
avoidGesture();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_Q
|
||||
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
|
||||
import static com.android.systemui.statusbar.StatusBarState.SHADE;
|
||||
import static com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED;
|
||||
import static com.android.systemui.statusbar.VibratorHelper.TOUCH_VIBRATION_ATTRIBUTES;
|
||||
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL;
|
||||
import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_FOLD_TO_AOD;
|
||||
import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_CLOSED;
|
||||
@@ -62,6 +63,7 @@ import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.PowerManager;
|
||||
import android.os.Process;
|
||||
import android.os.Trace;
|
||||
import android.os.UserManager;
|
||||
import android.os.VibrationEffect;
|
||||
@@ -236,6 +238,9 @@ public final class NotificationPanelViewController extends PanelViewController {
|
||||
private static final boolean SPEW_LOGCAT = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.VERBOSE);
|
||||
private static final boolean DEBUG_DRAWABLE = false;
|
||||
|
||||
private static final VibrationEffect ADDITIONAL_TAP_REQUIRED_VIBRATION_EFFECT =
|
||||
VibrationEffect.get(VibrationEffect.EFFECT_STRENGTH_MEDIUM, false);
|
||||
|
||||
/**
|
||||
* The parallax amount of the quick settings translation when dragging down the panel
|
||||
*/
|
||||
@@ -682,14 +687,22 @@ public final class NotificationPanelViewController extends PanelViewController {
|
||||
|
||||
private final FalsingTapListener mFalsingTapListener = new FalsingTapListener() {
|
||||
@Override
|
||||
public void onDoubleTapRequired() {
|
||||
public void onAdditionalTapRequired() {
|
||||
if (mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED) {
|
||||
mTapAgainViewController.show();
|
||||
} else {
|
||||
mKeyguardIndicationController.showTransientIndication(
|
||||
R.string.notification_tap_again);
|
||||
}
|
||||
mVibratorHelper.vibrate(VibrationEffect.EFFECT_STRENGTH_MEDIUM);
|
||||
|
||||
if (!mStatusBarStateController.isDozing()) {
|
||||
mVibratorHelper.vibrate(
|
||||
Process.myUid(),
|
||||
mView.getContext().getPackageName(),
|
||||
ADDITIONAL_TAP_REQUIRED_VIBRATION_EFFECT,
|
||||
"falsing-additional-tap-required",
|
||||
TOUCH_VIBRATION_ATTRIBUTES);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ public class NotificationShadeWindowViewController {
|
||||
private final AmbientState mAmbientState;
|
||||
private final PulsingGestureListener mPulsingGestureListener;
|
||||
|
||||
private GestureDetector mGestureDetector;
|
||||
private GestureDetector mPulsingWakeupGestureHandler;
|
||||
private View mBrightnessMirror;
|
||||
private boolean mTouchActive;
|
||||
private boolean mTouchCancelled;
|
||||
@@ -149,7 +149,8 @@ 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);
|
||||
mGestureDetector = new GestureDetector(mView.getContext(), mPulsingGestureListener);
|
||||
mPulsingWakeupGestureHandler = new GestureDetector(mView.getContext(),
|
||||
mPulsingGestureListener);
|
||||
|
||||
mView.setInteractionEventHandler(new NotificationShadeWindowView.InteractionEventHandler() {
|
||||
@Override
|
||||
@@ -196,7 +197,7 @@ public class NotificationShadeWindowViewController {
|
||||
}
|
||||
|
||||
mFalsingCollector.onTouchEvent(ev);
|
||||
mGestureDetector.onTouchEvent(ev);
|
||||
mPulsingWakeupGestureHandler.onTouchEvent(ev);
|
||||
mStatusBarKeyguardViewManager.onTouch(ev);
|
||||
if (mBrightnessMirror != null
|
||||
&& mBrightnessMirror.getVisibility() == View.VISIBLE) {
|
||||
|
||||
@@ -26,6 +26,7 @@ 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.plugins.FalsingManager.LOW_PENALTY
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||
import com.android.systemui.statusbar.phone.CentralSurfaces
|
||||
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
|
||||
@@ -36,12 +37,12 @@ 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.
|
||||
* tap/double tap when the device is pulsing (AoD2) or transitioning to AoD. 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].
|
||||
* Touches go through the [NotificationShadeWindowViewController] when the device is dozing but the
|
||||
* screen is still ON and not in the true AoD display state. When the device is in the true AoD
|
||||
* display state, wake-ups are handled by [com.android.systemui.doze.DozeSensors].
|
||||
*/
|
||||
@CentralSurfacesComponent.CentralSurfacesScope
|
||||
class PulsingGestureListener @Inject constructor(
|
||||
@@ -75,12 +76,12 @@ class PulsingGestureListener @Inject constructor(
|
||||
dumpManager.registerDumpable(this)
|
||||
}
|
||||
|
||||
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
|
||||
if (statusBarStateController.isPulsing &&
|
||||
override fun onSingleTapUp(e: MotionEvent): Boolean {
|
||||
if (statusBarStateController.isDozing &&
|
||||
singleTapEnabled &&
|
||||
!dockManager.isDocked &&
|
||||
!falsingManager.isProximityNear &&
|
||||
!falsingManager.isFalseTap(FalsingManager.MODERATE_PENALTY)
|
||||
!falsingManager.isFalseTap(LOW_PENALTY)
|
||||
) {
|
||||
centralSurfaces.wakeUpIfDozing(
|
||||
SystemClock.uptimeMillis(),
|
||||
@@ -91,8 +92,15 @@ class PulsingGestureListener @Inject constructor(
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onDoubleTap(e: MotionEvent): Boolean {
|
||||
if (statusBarStateController.isPulsing &&
|
||||
/**
|
||||
* Receives [MotionEvent.ACTION_DOWN], [MotionEvent.ACTION_MOVE], and [MotionEvent.ACTION_UP]
|
||||
* motion events for a double tap.
|
||||
*/
|
||||
override fun onDoubleTapEvent(e: MotionEvent): Boolean {
|
||||
// React to the [MotionEvent.ACTION_UP] event after double tap is detected. Falsing
|
||||
// checks MUST be on the ACTION_UP event.
|
||||
if (e.actionMasked == MotionEvent.ACTION_UP &&
|
||||
statusBarStateController.isDozing &&
|
||||
(doubleTapEnabled || singleTapEnabled) &&
|
||||
!falsingManager.isProximityNear &&
|
||||
!falsingManager.isFalseDoubleTap
|
||||
|
||||
@@ -38,7 +38,7 @@ import javax.inject.Inject;
|
||||
public class VibratorHelper {
|
||||
|
||||
private final Vibrator mVibrator;
|
||||
private static final VibrationAttributes TOUCH_VIBRATION_ATTRIBUTES =
|
||||
public static final VibrationAttributes TOUCH_VIBRATION_ATTRIBUTES =
|
||||
VibrationAttributes.createForUsage(VibrationAttributes.USAGE_TOUCH);
|
||||
private final Executor mExecutor;
|
||||
|
||||
|
||||
@@ -229,7 +229,10 @@ public class FalsingCollectorImplTest extends SysuiTestCase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvoidDozingNotPulsing() {
|
||||
public void testGestureWhenDozing() {
|
||||
// We check the FalsingManager for taps during the transition to AoD (dozing=true,
|
||||
// pulsing=false), so the FalsingCollector needs to continue to analyze events that occur
|
||||
// while the device is dozing.
|
||||
MotionEvent down = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
|
||||
MotionEvent up = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0);
|
||||
|
||||
@@ -239,13 +242,13 @@ public class FalsingCollectorImplTest extends SysuiTestCase {
|
||||
mFalsingCollector.onTouchEvent(down);
|
||||
verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class));
|
||||
|
||||
// Up event would normally flush the up event, but doesn't.
|
||||
// Up event flushes
|
||||
mFalsingCollector.onTouchEvent(up);
|
||||
verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class));
|
||||
verify(mFalsingDataProvider, times(2)).onMotionEvent(any(MotionEvent.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAvoidDozingButPulsing() {
|
||||
public void testGestureWhenPulsing() {
|
||||
MotionEvent down = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
|
||||
MotionEvent up = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0);
|
||||
|
||||
|
||||
@@ -1022,7 +1022,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
||||
FalsingManager.FalsingTapListener listener = getFalsingTapListener();
|
||||
mStatusBarStateController.setState(KEYGUARD);
|
||||
|
||||
listener.onDoubleTapRequired();
|
||||
listener.onAdditionalTapRequired();
|
||||
|
||||
verify(mKeyguardIndicationController).showTransientIndication(anyInt());
|
||||
}
|
||||
@@ -1032,7 +1032,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
||||
FalsingManager.FalsingTapListener listener = getFalsingTapListener();
|
||||
mStatusBarStateController.setState(SHADE_LOCKED);
|
||||
|
||||
listener.onDoubleTapRequired();
|
||||
listener.onAdditionalTapRequired();
|
||||
|
||||
verify(mTapAgainViewController).show();
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ class PulsingGestureListenerTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun testGestureDetector_singleTapEnabled() {
|
||||
whenever(statusBarStateController.isPulsing).thenReturn(true)
|
||||
whenever(statusBarStateController.isDozing).thenReturn(true)
|
||||
|
||||
// GIVEN tap is enabled, prox not covered
|
||||
whenever(ambientDisplayConfiguration.tapGestureEnabled(anyInt())).thenReturn(true)
|
||||
@@ -100,7 +100,7 @@ class PulsingGestureListenerTest : SysuiTestCase() {
|
||||
whenever(falsingManager.isFalseTap(anyInt())).thenReturn(false)
|
||||
|
||||
// WHEN there's a tap
|
||||
underTest.onSingleTapConfirmed(downEv)
|
||||
underTest.onSingleTapUp(upEv)
|
||||
|
||||
// THEN wake up device if dozing
|
||||
verify(centralSurfaces).wakeUpIfDozing(anyLong(), anyObject(), anyString())
|
||||
@@ -108,7 +108,7 @@ class PulsingGestureListenerTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun testGestureDetector_doubleTapEnabled() {
|
||||
whenever(statusBarStateController.isPulsing).thenReturn(true)
|
||||
whenever(statusBarStateController.isDozing).thenReturn(true)
|
||||
|
||||
// GIVEN double tap is enabled, prox not covered
|
||||
whenever(ambientDisplayConfiguration.doubleTapGestureEnabled(anyInt())).thenReturn(true)
|
||||
@@ -119,15 +119,27 @@ class PulsingGestureListenerTest : SysuiTestCase() {
|
||||
whenever(falsingManager.isFalseDoubleTap).thenReturn(false)
|
||||
|
||||
// WHEN there's a double tap
|
||||
underTest.onDoubleTap(downEv)
|
||||
underTest.onDoubleTapEvent(upEv)
|
||||
|
||||
// THEN wake up device if dozing
|
||||
verify(centralSurfaces).wakeUpIfDozing(anyLong(), anyObject(), anyString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGestureDetector_doubleTapEnabled_onDownEvent_noFalsingCheck() {
|
||||
// GIVEN tap is enabled
|
||||
whenever(ambientDisplayConfiguration.tapGestureEnabled(anyInt())).thenReturn(true)
|
||||
|
||||
// WHEN there's a double tap on DOWN event
|
||||
underTest.onDoubleTapEvent(downEv)
|
||||
|
||||
// THEN don't check the falsing manager, should only be checked on the UP event
|
||||
verify(falsingManager, never()).isFalseDoubleTap()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGestureDetector_singleTapEnabled_falsing() {
|
||||
whenever(statusBarStateController.isPulsing).thenReturn(true)
|
||||
whenever(statusBarStateController.isDozing).thenReturn(true)
|
||||
|
||||
// GIVEN tap is enabled, prox not covered
|
||||
whenever(ambientDisplayConfiguration.tapGestureEnabled(anyInt())).thenReturn(true)
|
||||
@@ -138,29 +150,43 @@ class PulsingGestureListenerTest : SysuiTestCase() {
|
||||
whenever(falsingManager.isFalseTap(anyInt())).thenReturn(true)
|
||||
|
||||
// WHEN there's a tap
|
||||
underTest.onSingleTapConfirmed(downEv)
|
||||
underTest.onSingleTapUp(upEv)
|
||||
|
||||
// THEN the device doesn't wake up
|
||||
verify(centralSurfaces, never()).wakeUpIfDozing(anyLong(), anyObject(), anyString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGestureDetector_notPulsing_noFalsingCheck() {
|
||||
whenever(statusBarStateController.isPulsing).thenReturn(false)
|
||||
fun testSingleTap_notDozing_noFalsingCheck() {
|
||||
whenever(statusBarStateController.isDozing).thenReturn(false)
|
||||
|
||||
// GIVEN tap is enabled, prox not covered
|
||||
// GIVEN tap is enabled
|
||||
whenever(ambientDisplayConfiguration.tapGestureEnabled(anyInt())).thenReturn(true)
|
||||
// WHEN there's a tap
|
||||
underTest.onSingleTapConfirmed(downEv)
|
||||
underTest.onSingleTapUp(upEv)
|
||||
|
||||
// THEN the falsing manager never gets a call (because the device wasn't pulsing
|
||||
// THEN the falsing manager never gets a call (because the device wasn't dozing
|
||||
// during the tap)
|
||||
verify(falsingManager, never()).isFalseTap(anyInt())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDoubleTap_notDozing_noFalsingCheck() {
|
||||
whenever(statusBarStateController.isDozing).thenReturn(false)
|
||||
|
||||
// GIVEN tap is enabled
|
||||
whenever(ambientDisplayConfiguration.tapGestureEnabled(anyInt())).thenReturn(true)
|
||||
// WHEN there's a tap
|
||||
underTest.onDoubleTapEvent(upEv)
|
||||
|
||||
// THEN the falsing manager never gets a call (because the device wasn't dozing
|
||||
// during the tap)
|
||||
verify(falsingManager, never()).isFalseTap(anyInt())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGestureDetector_doubleTapEnabled_falsing() {
|
||||
whenever(statusBarStateController.isPulsing).thenReturn(true)
|
||||
whenever(statusBarStateController.isDozing).thenReturn(true)
|
||||
|
||||
// GIVEN double tap is enabled, prox not covered
|
||||
whenever(ambientDisplayConfiguration.doubleTapGestureEnabled(anyInt())).thenReturn(true)
|
||||
@@ -170,8 +196,8 @@ class PulsingGestureListenerTest : SysuiTestCase() {
|
||||
// GIVEN the falsing manager thinks the tap is a false tap
|
||||
whenever(falsingManager.isFalseDoubleTap).thenReturn(true)
|
||||
|
||||
// WHEN there's a tap
|
||||
underTest.onDoubleTap(downEv)
|
||||
// WHEN there's a double tap ACTION_UP event
|
||||
underTest.onDoubleTapEvent(upEv)
|
||||
|
||||
// THEN the device doesn't wake up
|
||||
verify(centralSurfaces, never()).wakeUpIfDozing(anyLong(), anyObject(), anyString())
|
||||
@@ -179,7 +205,7 @@ class PulsingGestureListenerTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun testGestureDetector_singleTapEnabled_proxCovered() {
|
||||
whenever(statusBarStateController.isPulsing).thenReturn(true)
|
||||
whenever(statusBarStateController.isDozing).thenReturn(true)
|
||||
|
||||
// GIVEN tap is enabled, not a false tap based on classifiers
|
||||
whenever(ambientDisplayConfiguration.tapGestureEnabled(anyInt())).thenReturn(true)
|
||||
@@ -190,7 +216,7 @@ class PulsingGestureListenerTest : SysuiTestCase() {
|
||||
whenever(falsingManager.isProximityNear()).thenReturn(true)
|
||||
|
||||
// WHEN there's a tap
|
||||
underTest.onSingleTapConfirmed(downEv)
|
||||
underTest.onSingleTapUp(upEv)
|
||||
|
||||
// THEN the device doesn't wake up
|
||||
verify(centralSurfaces, never()).wakeUpIfDozing(anyLong(), anyObject(), anyString())
|
||||
@@ -198,7 +224,7 @@ class PulsingGestureListenerTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun testGestureDetector_doubleTapEnabled_proxCovered() {
|
||||
whenever(statusBarStateController.isPulsing).thenReturn(true)
|
||||
whenever(statusBarStateController.isDozing).thenReturn(true)
|
||||
|
||||
// GIVEN double tap is enabled, not a false tap based on classifiers
|
||||
whenever(ambientDisplayConfiguration.doubleTapGestureEnabled(anyInt())).thenReturn(true)
|
||||
@@ -209,7 +235,7 @@ class PulsingGestureListenerTest : SysuiTestCase() {
|
||||
whenever(falsingManager.isProximityNear()).thenReturn(true)
|
||||
|
||||
// WHEN there's a tap
|
||||
underTest.onDoubleTap(downEv)
|
||||
underTest.onDoubleTapEvent(upEv)
|
||||
|
||||
// THEN the device doesn't wake up
|
||||
verify(centralSurfaces, never()).wakeUpIfDozing(anyLong(), anyObject(), anyString())
|
||||
@@ -227,3 +253,4 @@ class PulsingGestureListenerTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
private val downEv = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
|
||||
private val upEv = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_UP, 0f, 0f, 0)
|
||||
|
||||
Reference in New Issue
Block a user