Tell NotificationWakeupCoordinator if we're waking from power button w/ SFPS press-to-unlock.

Bug: 269085199
Test: wake up with/without power button, with/without touch to unlock anytime enabled
Change-Id: If0c7c5ef4e489ec3ff595e7f852c50b41644fa90
This commit is contained in:
Josh Tsuji
2023-02-23 14:36:53 -05:00
committed by Jeff DeCew
parent ec7c9ce171
commit 15cddc9d3e
8 changed files with 111 additions and 13 deletions

View File

@@ -253,6 +253,7 @@ public final class NotificationPanelViewController implements Dumpable {
public static final float FLING_SPEED_UP_FACTOR = 0.6f;
public static final float FLING_CLOSING_MAX_LENGTH_SECONDS = 0.6f;
public static final float FLING_CLOSING_SPEED_UP_FACTOR = 0.6f;
public static final int WAKEUP_ANIMATION_DELAY_MS = 250;
private static final boolean DEBUG_LOGCAT = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG);
private static final boolean SPEW_LOGCAT = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.VERBOSE);
private static final boolean DEBUG_DRAWABLE = false;
@@ -275,6 +276,7 @@ public final class NotificationPanelViewController implements Dumpable {
private static final int NO_FIXED_DURATION = -1;
private static final long SHADE_OPEN_SPRING_OUT_DURATION = 350L;
private static final long SHADE_OPEN_SPRING_BACK_DURATION = 400L;
/**
* The factor of the usual high velocity that is needed in order to reach the maximum overshoot
* when flinging. A low value will make it that most flings will reach the maximum overshoot.

View File

@@ -84,7 +84,7 @@ class NotificationWakeUpCoordinator @Inject constructor(
var fullyAwake: Boolean = false
var wakingUp = false
set(value) {
private set(value) {
field = value
willWakeUp = false
if (value) {
@@ -294,6 +294,21 @@ class NotificationWakeUpCoordinator @Inject constructor(
}
}
/**
* Notifies the wakeup coordinator that we're waking up.
*
* [requestDelayedAnimation] is used to request that we delay the start of the wakeup animation
* in order to wait for a potential fingerprint authentication to arrive, since unlocking during
* the wakeup animation looks chaotic.
*/
fun setWakingUp(
wakingUp: Boolean,
requestDelayedAnimation: Boolean,
) {
this.wakingUp = wakingUp
// TODO(jeffdq): Delay the wakeup animation if we're pressing to unlock.
}
override fun onStateChanged(newState: Int) {
logger.logOnStateChanged(newState = newState, storedState = state)
if (state == StatusBarState.SHADE && newState == StatusBarState.SHADE) {
@@ -500,6 +515,10 @@ class NotificationWakeUpCoordinator @Inject constructor(
pw.println("canShowPulsingHuns: $canShowPulsingHuns")
}
fun logClockTransitionAnimationStarting(delayWakeUpAnimation: Boolean) {
logger.logClockTransitionAnimationStarting(delayWakeUpAnimation)
}
interface WakeUpListener {
/**
* Called whenever the notifications are fully hidden or shown

View File

@@ -114,6 +114,15 @@ constructor(@NotificationLockscreenLog private val buffer: LogBuffer) {
}
)
}
fun logClockTransitionAnimationStarting(delayWakeUpAnimation: Boolean) {
buffer.log(
TAG,
DEBUG,
{ bool1 = delayWakeUpAnimation },
{ "clockTransitionAnimationStarting() withDelay=$bool1" }
)
}
}
private const val TAG = "NotificationWakeUpCoordinator"

View File

@@ -53,6 +53,7 @@ import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.shade.NotificationShadeWindowViewController;
import com.android.systemui.statusbar.LightRevealScrim;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.util.Compile;
import java.io.PrintWriter;
@@ -71,6 +72,7 @@ public interface CentralSurfaces extends Dumpable, ActivityStarter, LifecycleOwn
boolean DEBUG_MEDIA_FAKE_ARTWORK = false;
boolean DEBUG_CAMERA_LIFT = false;
boolean DEBUG_WINDOW_STATE = false;
boolean DEBUG_WAKEUP_DELAY = Compile.IS_DEBUG;
// additional instrumentation for testing purposes; intended to be left on during development
boolean CHATTY = DEBUG;
boolean SHOW_LOCKSCREEN_MEDIA_ARTWORK = true;
@@ -536,6 +538,8 @@ public interface CentralSurfaces extends Dumpable, ActivityStarter, LifecycleOwn
void extendDozePulse();
boolean shouldDelayWakeUpAnimation();
public static class KeyboardShortcutsMessage {
final int mDeviceId;

View File

@@ -69,6 +69,7 @@ import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.graphics.Point;
import android.hardware.devicestate.DeviceStateManager;
import android.hardware.fingerprint.FingerprintManager;
import android.metrics.LogMaker;
import android.net.Uri;
import android.os.Binder;
@@ -257,6 +258,7 @@ import java.util.concurrent.Executor;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import dagger.Lazy;
@@ -446,10 +448,20 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@VisibleForTesting
DozeServiceHost mDozeServiceHost;
private boolean mWakeUpComingFromTouch;
private LightRevealScrim mLightRevealScrim;
private PowerButtonReveal mPowerButtonReveal;
private boolean mWakeUpComingFromTouch;
/**
* Whether we should delay the wakeup animation (which shows the notifications and moves the
* clock view). This is typically done when waking up from a 'press to unlock' gesture on a
* device with a side fingerprint sensor, so that if the fingerprint scan is successful, we
* can play the unlock animation directly rather than interrupting the wakeup animation part
* way through.
*/
private boolean mShouldDelayWakeUpAnimation = false;
private final Object mQueueLock = new Object();
private final PulseExpansionHandler mPulseExpansionHandler;
@@ -510,6 +522,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
private final MessageRouter mMessageRouter;
private final WallpaperManager mWallpaperManager;
private final UserTracker mUserTracker;
private final Provider<FingerprintManager> mFingerprintManager;
private CentralSurfacesComponent mCentralSurfacesComponent;
@@ -753,7 +766,8 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
Lazy<CameraLauncher> cameraLauncherLazy,
Lazy<LightRevealScrimViewModel> lightRevealScrimViewModelLazy,
AlternateBouncerInteractor alternateBouncerInteractor,
UserTracker userTracker
UserTracker userTracker,
Provider<FingerprintManager> fingerprintManager
) {
mContext = context;
mNotificationsController = notificationsController;
@@ -834,6 +848,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
mCameraLauncherLazy = cameraLauncherLazy;
mAlternateBouncerInteractor = alternateBouncerInteractor;
mUserTracker = userTracker;
mFingerprintManager = fingerprintManager;
mLockscreenShadeTransitionController = lockscreenShadeTransitionController;
mStartingSurfaceOptional = startingSurfaceOptional;
@@ -3149,6 +3164,10 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
}
}
public boolean shouldDelayWakeUpAnimation() {
return mShouldDelayWakeUpAnimation;
}
private void updateDozingState() {
Trace.traceCounter(Trace.TRACE_TAG_APP, "dozing", mDozing ? 1 : 0);
Trace.beginSection("CentralSurfaces#updateDozingState");
@@ -3159,11 +3178,8 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
boolean keyguardVisibleOrWillBe =
keyguardVisible || (mDozing && mDozeParameters.shouldDelayKeyguardShow());
boolean wakeAndUnlock = mBiometricUnlockController.getMode()
== BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
boolean animate = (!mDozing && mDozeServiceHost.shouldAnimateWakeup() && !wakeAndUnlock)
|| (mDozing && mDozeParameters.shouldControlScreenOff()
&& keyguardVisibleOrWillBe);
boolean animate = (!mDozing && shouldAnimateDozeWakeup())
|| (mDozing && mDozeParameters.shouldControlScreenOff() && keyguardVisibleOrWillBe);
mNotificationPanelViewController.setDozing(mDozing, animate);
updateQsExpansionEnabled();
@@ -3516,7 +3532,42 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
DejankUtils.startDetectingBlockingIpcs(tag);
mNotificationShadeWindowController.batchApplyWindowLayoutParams(()-> {
mDeviceInteractive = true;
mWakeUpCoordinator.setWakingUp(true);
if (shouldAnimateDozeWakeup()) {
// If this is false, the power button must be physically pressed in order to
// trigger fingerprint authentication.
final boolean touchToUnlockAnytime = Settings.Secure.getIntForUser(
mContext.getContentResolver(),
Settings.Secure.SFPS_PERFORMANT_AUTH_ENABLED,
-1,
mUserTracker.getUserId()) > 0;
// Delay if we're waking up, not mid-doze animation (which means we are
// cancelling a sleep), from the power button, on a device with a power button
// FPS, and 'press to unlock' is required.
mShouldDelayWakeUpAnimation =
!isPulsing()
&& mStatusBarStateController.getDozeAmount() == 1f
&& mWakefulnessLifecycle.getLastWakeReason()
== PowerManager.WAKE_REASON_POWER_BUTTON
&& mFingerprintManager.get().isPowerbuttonFps()
&& mFingerprintManager.get().hasEnrolledFingerprints()
&& !touchToUnlockAnytime;
if (DEBUG_WAKEUP_DELAY) {
Log.d(TAG, "mShouldDelayWakeUpAnimation=" + mShouldDelayWakeUpAnimation);
}
} else {
// If we're not animating anyway, we do not need to delay it.
mShouldDelayWakeUpAnimation = false;
if (DEBUG_WAKEUP_DELAY) {
Log.d(TAG, "mShouldDelayWakeUpAnimation CLEARED");
}
}
mWakeUpCoordinator.setWakingUp(
/* wakingUp= */ true,
mShouldDelayWakeUpAnimation);
if (!mKeyguardBypassController.getBypassEnabled()) {
mHeadsUpManager.releaseAllImmediately();
}
@@ -3543,7 +3594,7 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
@Override
public void onFinishedWakingUp() {
mWakeUpCoordinator.setFullyAwake(true);
mWakeUpCoordinator.setWakingUp(false);
mWakeUpCoordinator.setWakingUp(false, false);
if (mKeyguardStateController.isOccluded()
&& !mDozeParameters.canControlUnlockedScreenOff()) {
// When the keyguard is occluded we don't use the KEYGUARD state which would
@@ -4407,4 +4458,15 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
}
return mUserTracker.getUserHandle();
}
/**
* Whether we want to animate the wake animation AOD to lockscreen. This is done only if the
* doze service host says we can, and also we're not wake and unlocking (in which case the
* AOD instantly hides).
*/
private boolean shouldAnimateDozeWakeup() {
return mDozeServiceHost.shouldAnimateWakeup()
&& mBiometricUnlockController.getMode()
!= BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
}
}

View File

@@ -18,7 +18,7 @@ package com.android.systemui.statusbar.notification
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase;
import com.android.systemui.SysuiTestCase
import com.android.systemui.plugins.log.LogBuffer
import com.android.systemui.plugins.log.LogLevel
import com.android.systemui.plugins.log.LogcatEchoTracker

View File

@@ -18,7 +18,7 @@ package com.android.systemui.statusbar.notification
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase;
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.StatusBarState

View File

@@ -311,6 +311,7 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
@Mock private ViewRootImpl mViewRootImpl;
@Mock private WindowOnBackInvokedDispatcher mOnBackInvokedDispatcher;
@Mock private UserTracker mUserTracker;
@Mock private FingerprintManager mFingerprintManager;
@Captor private ArgumentCaptor<OnBackInvokedCallback> mOnBackInvokedCallback;
@Mock IPowerManager mPowerManagerService;
@@ -521,7 +522,8 @@ public class CentralSurfacesImplTest extends SysuiTestCase {
mCameraLauncherLazy,
() -> mLightRevealScrimViewModel,
mAlternateBouncerInteractor,
mUserTracker
mUserTracker,
() -> mFingerprintManager
) {
@Override
protected ViewRootImpl getViewRootImpl() {