Merge "Use Launcher smartspace instead of SysUI's for the shared element transition." into tm-dev am: 7b5e80f2f6 am: b9d48538d5
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17892808 Change-Id: I33592b0e0398a1662f43dfd1686930b28cb78f85 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -16,17 +16,20 @@
|
|||||||
|
|
||||||
package com.android.systemui.shared.system.smartspace;
|
package com.android.systemui.shared.system.smartspace;
|
||||||
|
|
||||||
|
import android.graphics.Rect;
|
||||||
import com.android.systemui.shared.system.smartspace.SmartspaceState;
|
import com.android.systemui.shared.system.smartspace.SmartspaceState;
|
||||||
|
|
||||||
// Methods for System UI to interface with Launcher to perform the unlock animation.
|
// Methods for System UI to interface with Launcher to perform the unlock animation.
|
||||||
interface ILauncherUnlockAnimationController {
|
interface ILauncherUnlockAnimationController {
|
||||||
// Prepares Launcher for the unlock animation by setting scale/alpha/etc. to their starting
|
// Prepares Launcher for the unlock animation by setting scale/alpha/etc. to their starting
|
||||||
// values.
|
// values.
|
||||||
void prepareForUnlock(boolean willAnimateSmartspace, int selectedPage);
|
void prepareForUnlock(boolean animateSmartspace, in Rect lockscreenSmartspaceBounds,
|
||||||
|
int selectedPage);
|
||||||
|
|
||||||
// Set the unlock percentage. This is used when System UI is controlling each frame of the
|
// Set the unlock percentage. This is used when System UI is controlling each frame of the
|
||||||
// unlock animation, such as during a swipe to unlock touch gesture.
|
// unlock animation, such as during a swipe to unlock touch gesture. Will not apply this change
|
||||||
oneway void setUnlockAmount(float amount);
|
// if the unlock amount is animating unless forceIfAnimating is true.
|
||||||
|
oneway void setUnlockAmount(float amount, boolean forceIfAnimating);
|
||||||
|
|
||||||
// Play a full unlock animation from 0f to 1f. This is used when System UI is unlocking from a
|
// Play a full unlock animation from 0f to 1f. This is used when System UI is unlocking from a
|
||||||
// single action, such as biometric auth, and doesn't need to control individual frames.
|
// single action, such as biometric auth, and doesn't need to control individual frames.
|
||||||
|
|||||||
@@ -58,9 +58,7 @@ import com.android.systemui.util.ViewController;
|
|||||||
import com.android.systemui.util.settings.SecureSettings;
|
import com.android.systemui.util.settings.SecureSettings;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
@@ -133,14 +131,6 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
|||||||
private final KeyguardUnlockAnimationController.KeyguardUnlockAnimationListener
|
private final KeyguardUnlockAnimationController.KeyguardUnlockAnimationListener
|
||||||
mKeyguardUnlockAnimationListener =
|
mKeyguardUnlockAnimationListener =
|
||||||
new KeyguardUnlockAnimationController.KeyguardUnlockAnimationListener() {
|
new KeyguardUnlockAnimationController.KeyguardUnlockAnimationListener() {
|
||||||
@Override
|
|
||||||
public void onSmartspaceSharedElementTransitionStarted() {
|
|
||||||
// The smartspace needs to be able to translate out of bounds in order to
|
|
||||||
// end up where the launcher's smartspace is, while its container is being
|
|
||||||
// swiped off the top of the screen.
|
|
||||||
setClipChildrenForUnlock(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUnlockAnimationFinished() {
|
public void onUnlockAnimationFinished() {
|
||||||
// For performance reasons, reset this once the unlock animation ends.
|
// For performance reasons, reset this once the unlock animation ends.
|
||||||
@@ -390,41 +380,6 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
|||||||
if (mStatusArea != null) {
|
if (mStatusArea != null) {
|
||||||
PropertyAnimator.setProperty(mStatusArea, AnimatableProperty.TRANSLATION_X,
|
PropertyAnimator.setProperty(mStatusArea, AnimatableProperty.TRANSLATION_X,
|
||||||
x, props, animate);
|
x, props, animate);
|
||||||
|
|
||||||
// If we're unlocking with the SmartSpace shared element transition, let the controller
|
|
||||||
// know that it should re-position our SmartSpace.
|
|
||||||
if (mKeyguardUnlockAnimationController.isUnlockingWithSmartSpaceTransition()) {
|
|
||||||
mKeyguardUnlockAnimationController.updateLockscreenSmartSpacePosition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets an alpha value on every child view except for the smartspace. */
|
|
||||||
public void setChildrenAlphaExcludingSmartspace(float alpha) {
|
|
||||||
final Set<View> excludedViews = new HashSet<>();
|
|
||||||
|
|
||||||
if (mSmartspaceView != null) {
|
|
||||||
excludedViews.add(mStatusArea);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't change the alpha of the invisible clock.
|
|
||||||
if (mCurrentClockSize == LARGE) {
|
|
||||||
excludedViews.add(mClockFrame);
|
|
||||||
} else {
|
|
||||||
excludedViews.add(mLargeClockFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
setChildrenAlphaExcluding(alpha, excludedViews);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets an alpha value on every child view except for the views in the provided set. */
|
|
||||||
public void setChildrenAlphaExcluding(float alpha, Set<View> excludedViews) {
|
|
||||||
for (int i = 0; i < mView.getChildCount(); i++) {
|
|
||||||
final View child = mView.getChildAt(i);
|
|
||||||
|
|
||||||
if (!excludedViews.contains(child)) {
|
|
||||||
child.setAlpha(alpha);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ public class KeyguardStatusView extends GridLayout {
|
|||||||
|
|
||||||
private float mDarkAmount = 0;
|
private float mDarkAmount = 0;
|
||||||
private int mTextColor;
|
private int mTextColor;
|
||||||
private float mChildrenAlphaExcludingSmartSpace = 1f;
|
|
||||||
|
|
||||||
public KeyguardStatusView(Context context) {
|
public KeyguardStatusView(Context context) {
|
||||||
this(context, null, 0);
|
this(context, null, 0);
|
||||||
@@ -95,23 +94,6 @@ public class KeyguardStatusView extends GridLayout {
|
|||||||
mClockView.setTextColor(blendedTextColor);
|
mClockView.setTextColor(blendedTextColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChildrenAlphaExcludingClockView(float alpha) {
|
|
||||||
setChildrenAlphaExcluding(alpha, Set.of(mClockView));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets an alpha value on every view except for the views in the provided set. */
|
|
||||||
public void setChildrenAlphaExcluding(float alpha, Set<View> excludedViews) {
|
|
||||||
mChildrenAlphaExcludingSmartSpace = alpha;
|
|
||||||
|
|
||||||
for (int i = 0; i < mStatusViewContainer.getChildCount(); i++) {
|
|
||||||
final View child = mStatusViewContainer.getChildAt(i);
|
|
||||||
|
|
||||||
if (!excludedViews.contains(child)) {
|
|
||||||
child.setAlpha(alpha);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets a translationY value on every child view except for the media view. */
|
/** Sets a translationY value on every child view except for the media view. */
|
||||||
public void setChildrenTranslationYExcludingMediaView(float translationY) {
|
public void setChildrenTranslationYExcludingMediaView(float translationY) {
|
||||||
setChildrenTranslationYExcluding(translationY, Set.of(mMediaHostContainer));
|
setChildrenTranslationYExcluding(translationY, Set.of(mMediaHostContainer));
|
||||||
@@ -128,10 +110,6 @@ public class KeyguardStatusView extends GridLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getChildrenAlphaExcludingSmartSpace() {
|
|
||||||
return mChildrenAlphaExcludingSmartSpace;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dump(PrintWriter pw, String[] args) {
|
public void dump(PrintWriter pw, String[] args) {
|
||||||
pw.println("KeyguardStatusView:");
|
pw.println("KeyguardStatusView:");
|
||||||
pw.println(" mDarkAmount: " + mDarkAmount);
|
pw.println(" mDarkAmount: " + mDarkAmount);
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import android.graphics.Rect;
|
|||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
|
|
||||||
import com.android.keyguard.KeyguardClockSwitch.ClockSize;
|
import com.android.keyguard.KeyguardClockSwitch.ClockSize;
|
||||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
|
||||||
import com.android.systemui.statusbar.notification.AnimatableProperty;
|
import com.android.systemui.statusbar.notification.AnimatableProperty;
|
||||||
import com.android.systemui.statusbar.notification.PropertyAnimator;
|
import com.android.systemui.statusbar.notification.PropertyAnimator;
|
||||||
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
|
import com.android.systemui.statusbar.notification.stack.AnimationProperties;
|
||||||
@@ -49,10 +48,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
|
|||||||
private final KeyguardClockSwitchController mKeyguardClockSwitchController;
|
private final KeyguardClockSwitchController mKeyguardClockSwitchController;
|
||||||
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||||
private final ConfigurationController mConfigurationController;
|
private final ConfigurationController mConfigurationController;
|
||||||
private final DozeParameters mDozeParameters;
|
|
||||||
private final KeyguardVisibilityHelper mKeyguardVisibilityHelper;
|
private final KeyguardVisibilityHelper mKeyguardVisibilityHelper;
|
||||||
private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
|
|
||||||
private final KeyguardStateController mKeyguardStateController;
|
|
||||||
private final Rect mClipBounds = new Rect();
|
private final Rect mClipBounds = new Rect();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@@ -64,18 +60,14 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
|
|||||||
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
||||||
ConfigurationController configurationController,
|
ConfigurationController configurationController,
|
||||||
DozeParameters dozeParameters,
|
DozeParameters dozeParameters,
|
||||||
KeyguardUnlockAnimationController keyguardUnlockAnimationController,
|
|
||||||
ScreenOffAnimationController screenOffAnimationController) {
|
ScreenOffAnimationController screenOffAnimationController) {
|
||||||
super(keyguardStatusView);
|
super(keyguardStatusView);
|
||||||
mKeyguardSliceViewController = keyguardSliceViewController;
|
mKeyguardSliceViewController = keyguardSliceViewController;
|
||||||
mKeyguardClockSwitchController = keyguardClockSwitchController;
|
mKeyguardClockSwitchController = keyguardClockSwitchController;
|
||||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||||
mConfigurationController = configurationController;
|
mConfigurationController = configurationController;
|
||||||
mDozeParameters = dozeParameters;
|
|
||||||
mKeyguardStateController = keyguardStateController;
|
|
||||||
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController,
|
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController,
|
||||||
dozeParameters, screenOffAnimationController, /* animateYPos= */ true);
|
dozeParameters, screenOffAnimationController, /* animateYPos= */ true);
|
||||||
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -87,14 +79,12 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
|
|||||||
protected void onViewAttached() {
|
protected void onViewAttached() {
|
||||||
mKeyguardUpdateMonitor.registerCallback(mInfoCallback);
|
mKeyguardUpdateMonitor.registerCallback(mInfoCallback);
|
||||||
mConfigurationController.addCallback(mConfigurationListener);
|
mConfigurationController.addCallback(mConfigurationListener);
|
||||||
mKeyguardStateController.addCallback(mKeyguardStateControllerCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onViewDetached() {
|
protected void onViewDetached() {
|
||||||
mKeyguardUpdateMonitor.removeCallback(mInfoCallback);
|
mKeyguardUpdateMonitor.removeCallback(mInfoCallback);
|
||||||
mConfigurationController.removeCallback(mConfigurationListener);
|
mConfigurationController.removeCallback(mConfigurationListener);
|
||||||
mKeyguardStateController.removeCallback(mKeyguardStateControllerCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -148,24 +138,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
|
|||||||
*/
|
*/
|
||||||
public void setAlpha(float alpha) {
|
public void setAlpha(float alpha) {
|
||||||
if (!mKeyguardVisibilityHelper.isVisibilityAnimating()) {
|
if (!mKeyguardVisibilityHelper.isVisibilityAnimating()) {
|
||||||
// If we're capable of performing the SmartSpace shared element transition, and we are
|
mView.setAlpha(alpha);
|
||||||
// going to (we're swiping to dismiss vs. bringing up the PIN screen), then fade out
|
|
||||||
// everything except for the SmartSpace.
|
|
||||||
if (mKeyguardUnlockAnimationController.isUnlockingWithSmartSpaceTransition()) {
|
|
||||||
mView.setChildrenAlphaExcludingClockView(alpha);
|
|
||||||
mKeyguardClockSwitchController.setChildrenAlphaExcludingSmartspace(alpha);
|
|
||||||
} else if (!mKeyguardVisibilityHelper.isVisibilityAnimating()) {
|
|
||||||
// Otherwise, we can just set the alpha for the entire container.
|
|
||||||
mView.setAlpha(alpha);
|
|
||||||
|
|
||||||
// If we previously unlocked with the shared element transition, some child views
|
|
||||||
// might still have alpha = 0f. Set them back to 1f since we're just using the
|
|
||||||
// parent container's alpha.
|
|
||||||
if (mView.getChildrenAlphaExcludingSmartSpace() < 1f) {
|
|
||||||
mView.setChildrenAlphaExcludingClockView(1f);
|
|
||||||
mKeyguardClockSwitchController.setChildrenAlphaExcludingSmartspace(1f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,19 +262,6 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private KeyguardStateController.Callback mKeyguardStateControllerCallback =
|
|
||||||
new KeyguardStateController.Callback() {
|
|
||||||
@Override
|
|
||||||
public void onKeyguardShowingChanged() {
|
|
||||||
// If we explicitly re-show the keyguard, make sure that all the child views are
|
|
||||||
// visible. They might have been animating out as part of the SmartSpace shared
|
|
||||||
// element transition.
|
|
||||||
if (mKeyguardStateController.isShowing()) {
|
|
||||||
mView.setChildrenAlphaExcludingClockView(1f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rect that specifies how KSV should be clipped, on its parent's coordinates.
|
* Rect that specifies how KSV should be clipped, on its parent's coordinates.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import android.content.Context
|
|||||||
import android.graphics.Matrix
|
import android.graphics.Matrix
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.provider.Settings
|
import android.os.RemoteException
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.RemoteAnimationTarget
|
import android.view.RemoteAnimationTarget
|
||||||
import android.view.SyncRtSurfaceTransactionApplier
|
import android.view.SyncRtSurfaceTransactionApplier
|
||||||
@@ -47,7 +47,6 @@ import com.android.systemui.statusbar.phone.BiometricUnlockController
|
|||||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
import dagger.Lazy
|
import dagger.Lazy
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.math.min
|
|
||||||
|
|
||||||
const val TAG = "KeyguardUnlock"
|
const val TAG = "KeyguardUnlock"
|
||||||
|
|
||||||
@@ -77,7 +76,7 @@ const val SURFACE_BEHIND_SCALE_PIVOT_Y = 0.66f
|
|||||||
* The dismiss amount is the inverse of the notification panel expansion, which decreases as the
|
* The dismiss amount is the inverse of the notification panel expansion, which decreases as the
|
||||||
* lock screen is swiped away.
|
* lock screen is swiped away.
|
||||||
*/
|
*/
|
||||||
const val DISMISS_AMOUNT_SHOW_SURFACE_THRESHOLD = 0.25f
|
const val DISMISS_AMOUNT_SHOW_SURFACE_THRESHOLD = 0.15f
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dismiss amount at which to complete the keyguard exit animation and hide the keyguard.
|
* Dismiss amount at which to complete the keyguard exit animation and hide the keyguard.
|
||||||
@@ -85,7 +84,7 @@ const val DISMISS_AMOUNT_SHOW_SURFACE_THRESHOLD = 0.25f
|
|||||||
* The dismiss amount is the inverse of the notification panel expansion, which decreases as the
|
* The dismiss amount is the inverse of the notification panel expansion, which decreases as the
|
||||||
* lock screen is swiped away.
|
* lock screen is swiped away.
|
||||||
*/
|
*/
|
||||||
const val DISMISS_AMOUNT_EXIT_KEYGUARD_THRESHOLD = 0.4f
|
const val DISMISS_AMOUNT_EXIT_KEYGUARD_THRESHOLD = 0.3f
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How long the canned unlock animation takes. This is used if we are unlocking from biometric auth,
|
* How long the canned unlock animation takes. This is used if we are unlocking from biometric auth,
|
||||||
@@ -112,7 +111,7 @@ const val CANNED_UNLOCK_START_DELAY = 100L
|
|||||||
* Duration for the alpha animation on the surface behind. This plays to fade in the surface during
|
* Duration for the alpha animation on the surface behind. This plays to fade in the surface during
|
||||||
* a swipe to unlock (and to fade it back out if the swipe is cancelled).
|
* a swipe to unlock (and to fade it back out if the swipe is cancelled).
|
||||||
*/
|
*/
|
||||||
const val SURFACE_BEHIND_SWIPE_FADE_DURATION_MS = 150L
|
const val SURFACE_BEHIND_SWIPE_FADE_DURATION_MS = 175L
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start delay for the surface behind animation, used so that the lockscreen can get out of the way
|
* Start delay for the surface behind animation, used so that the lockscreen can get out of the way
|
||||||
@@ -151,12 +150,21 @@ class KeyguardUnlockAnimationController @Inject constructor(
|
|||||||
* [playingCannedAnimation] indicates whether we are playing a canned animation to show the
|
* [playingCannedAnimation] indicates whether we are playing a canned animation to show the
|
||||||
* app/launcher behind the keyguard, vs. this being a swipe to unlock where the dismiss
|
* app/launcher behind the keyguard, vs. this being a swipe to unlock where the dismiss
|
||||||
* amount drives the animation.
|
* amount drives the animation.
|
||||||
|
*
|
||||||
* [fromWakeAndUnlock] tells us whether we are unlocking directly from AOD - in this case,
|
* [fromWakeAndUnlock] tells us whether we are unlocking directly from AOD - in this case,
|
||||||
* the lockscreen is dismissed instantly, so we shouldn't run any animations that rely on it
|
* the lockscreen is dismissed instantly, so we shouldn't run any animations that rely on it
|
||||||
* being visible.
|
* being visible.
|
||||||
|
*
|
||||||
|
* [unlockAnimationStartDelay] and [unlockAnimationDuration] provide the timing parameters
|
||||||
|
* for the canned animation (if applicable) so interested parties can sync with it. If no
|
||||||
|
* canned animation is playing, these are both 0.
|
||||||
*/
|
*/
|
||||||
@JvmDefault
|
@JvmDefault
|
||||||
fun onUnlockAnimationStarted(playingCannedAnimation: Boolean, fromWakeAndUnlock: Boolean) {}
|
fun onUnlockAnimationStarted(
|
||||||
|
playingCannedAnimation: Boolean,
|
||||||
|
fromWakeAndUnlock: Boolean,
|
||||||
|
unlockAnimationStartDelay: Long,
|
||||||
|
unlockAnimationDuration: Long) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the remote unlock animation ends, in all cases, canned or swipe-to-unlock.
|
* Called when the remote unlock animation ends, in all cases, canned or swipe-to-unlock.
|
||||||
@@ -165,19 +173,6 @@ class KeyguardUnlockAnimationController @Inject constructor(
|
|||||||
*/
|
*/
|
||||||
@JvmDefault
|
@JvmDefault
|
||||||
fun onUnlockAnimationFinished() {}
|
fun onUnlockAnimationFinished() {}
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when we begin the smartspace shared element transition, either due to an unlock
|
|
||||||
* action (biometric, etc.) or a swipe to unlock.
|
|
||||||
*
|
|
||||||
* This transition can begin BEFORE [onUnlockAnimationStarted] is called, if we are swiping
|
|
||||||
* to unlock and the surface behind the keyguard has not yet been made visible. This is
|
|
||||||
* because the lockscreen smartspace immediately begins moving towards the launcher
|
|
||||||
* smartspace location when a swipe begins, even before we start the keyguard exit remote
|
|
||||||
* animation and show the launcher itself.
|
|
||||||
*/
|
|
||||||
@JvmDefault
|
|
||||||
fun onSmartspaceSharedElementTransitionStarted() {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The SmartSpace view on the lockscreen, provided by [KeyguardClockSwitchController]. */
|
/** The SmartSpace view on the lockscreen, provided by [KeyguardClockSwitchController]. */
|
||||||
@@ -262,7 +257,6 @@ class KeyguardUnlockAnimationController @Inject constructor(
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
var surfaceBehindAlphaAnimator = ValueAnimator.ofFloat(0f, 1f)
|
var surfaceBehindAlphaAnimator = ValueAnimator.ofFloat(0f, 1f)
|
||||||
private var smartspaceAnimator = ValueAnimator.ofFloat(0f, 1f)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Matrix applied to [surfaceBehindRemoteAnimationTarget], which is the surface of the
|
* Matrix applied to [surfaceBehindRemoteAnimationTarget], which is the surface of the
|
||||||
@@ -283,59 +277,38 @@ class KeyguardUnlockAnimationController @Inject constructor(
|
|||||||
private var roundedCornerRadius = 0f
|
private var roundedCornerRadius = 0f
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether we tried to start the SmartSpace shared element transition for this unlock swipe.
|
* Whether we decided in [prepareForInWindowLauncherAnimations] that we are able to and want to
|
||||||
* It's possible we were unable to do so (if the Launcher SmartSpace is not available), and we
|
* play the in-window launcher unlock animations rather than simply animating the Launcher
|
||||||
* need to keep track of that so that we don't start doing it halfway through the swipe if
|
* window like any other app. This can be true while [willUnlockWithSmartspaceTransition] is
|
||||||
* Launcher becomes available suddenly.
|
* false, if the smartspace is not available or was not ready in time.
|
||||||
*/
|
*/
|
||||||
private var attemptedSmartSpaceTransitionForThisSwipe = false
|
private var willUnlockWithInWindowLauncherAnimations: Boolean = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The original location of the lockscreen smartspace on the screen.
|
* Whether we decided in [prepareForInWindowLauncherAnimations] that we are able to and want to
|
||||||
|
* play the smartspace shared element animation. If true,
|
||||||
|
* [willUnlockWithInWindowLauncherAnimations] will also always be true since in-window
|
||||||
|
* animations are a prerequisite for the smartspace transition.
|
||||||
*/
|
*/
|
||||||
private val smartspaceOriginBounds = Rect()
|
private var willUnlockWithSmartspaceTransition: Boolean = false
|
||||||
|
|
||||||
/**
|
|
||||||
* The bounds to which the lockscreen smartspace is moving. This is set to the bounds of the
|
|
||||||
* launcher's smartspace prior to the transition starting.
|
|
||||||
*/
|
|
||||||
private val smartspaceDestBounds = Rect()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* From 0f to 1f, the progress of the smartspace shared element animation. 0f means the
|
|
||||||
* smartspace is at its normal position within the lock screen hierarchy, and 1f means it has
|
|
||||||
* fully animated to the location of the Launcher's smartspace.
|
|
||||||
*/
|
|
||||||
private var smartspaceUnlockProgress = 0f
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether we're currently unlocking, and we're talking to Launcher to perform in-window
|
|
||||||
* animations rather than simply animating the Launcher window like any other app. This can be
|
|
||||||
* true while [unlockingWithSmartspaceTransition] is false, if the smartspace is not available
|
|
||||||
* or was not ready in time.
|
|
||||||
*/
|
|
||||||
private var unlockingToLauncherWithInWindowAnimations: Boolean = false
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether we are currently unlocking, and the smartspace shared element transition is in
|
|
||||||
* progress. If true, we're also [unlockingToLauncherWithInWindowAnimations].
|
|
||||||
*/
|
|
||||||
private var unlockingWithSmartspaceTransition: Boolean = false
|
|
||||||
|
|
||||||
private val handler = Handler()
|
private val handler = Handler()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
with(surfaceBehindAlphaAnimator) {
|
with(surfaceBehindAlphaAnimator) {
|
||||||
duration = SURFACE_BEHIND_SWIPE_FADE_DURATION_MS
|
duration = SURFACE_BEHIND_SWIPE_FADE_DURATION_MS
|
||||||
interpolator = Interpolators.TOUCH_RESPONSE
|
interpolator = Interpolators.LINEAR
|
||||||
addUpdateListener { valueAnimator: ValueAnimator ->
|
addUpdateListener { valueAnimator: ValueAnimator ->
|
||||||
surfaceBehindAlpha = valueAnimator.animatedValue as Float
|
surfaceBehindAlpha = valueAnimator.animatedValue as Float
|
||||||
updateSurfaceBehindAppearAmount()
|
updateSurfaceBehindAppearAmount()
|
||||||
}
|
}
|
||||||
addListener(object : AnimatorListenerAdapter() {
|
addListener(object : AnimatorListenerAdapter() {
|
||||||
override fun onAnimationEnd(animation: Animator) {
|
override fun onAnimationEnd(animation: Animator) {
|
||||||
// If the surface alpha is 0f, it's no longer visible so we can safely be done
|
// If we animated the surface alpha to 0f, it means we cancelled a swipe to
|
||||||
// with the animation even if other properties are still animating.
|
// dismiss. In this case, we should ask the KeyguardViewMediator to end the
|
||||||
|
// remote animation to hide the surface behind the keyguard, but should *not*
|
||||||
|
// call onKeyguardExitRemoteAnimationFinished since that will hide the keyguard
|
||||||
|
// and unlock the device as well as hiding the surface.
|
||||||
if (surfaceBehindAlpha == 0f) {
|
if (surfaceBehindAlpha == 0f) {
|
||||||
keyguardViewMediator.get().finishSurfaceBehindRemoteAnimation(
|
keyguardViewMediator.get().finishSurfaceBehindRemoteAnimation(
|
||||||
false /* cancelled */)
|
false /* cancelled */)
|
||||||
@@ -362,21 +335,6 @@ class KeyguardUnlockAnimationController @Inject constructor(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
with(smartspaceAnimator) {
|
|
||||||
duration = UNLOCK_ANIMATION_DURATION_MS
|
|
||||||
interpolator = Interpolators.TOUCH_RESPONSE
|
|
||||||
addUpdateListener {
|
|
||||||
smartspaceUnlockProgress = it.animatedValue as Float
|
|
||||||
}
|
|
||||||
addListener(object : AnimatorListenerAdapter() {
|
|
||||||
override fun onAnimationEnd(animation: Animator?) {
|
|
||||||
launcherUnlockController?.setSmartspaceVisibility(View.VISIBLE)
|
|
||||||
keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(
|
|
||||||
false /* cancelled */)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen for changes in the dismiss amount.
|
// Listen for changes in the dismiss amount.
|
||||||
keyguardStateController.addCallback(this)
|
keyguardStateController.addCallback(this)
|
||||||
|
|
||||||
@@ -395,6 +353,74 @@ class KeyguardUnlockAnimationController @Inject constructor(
|
|||||||
listeners.remove(listener)
|
listeners.remove(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether we should be able to do the in-window launcher animations given the current state of
|
||||||
|
* the device.
|
||||||
|
*/
|
||||||
|
fun canPerformInWindowLauncherAnimations(): Boolean {
|
||||||
|
return isNexusLauncherUnderneath() &&
|
||||||
|
launcherUnlockController != null &&
|
||||||
|
!keyguardStateController.isDismissingFromSwipe &&
|
||||||
|
// Temporarily disable for foldables since foldable launcher has two first pages,
|
||||||
|
// which breaks the in-window animation.
|
||||||
|
!isFoldable(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called from [KeyguardStateController] to let us know that the keyguard going away state has
|
||||||
|
* changed.
|
||||||
|
*/
|
||||||
|
override fun onKeyguardGoingAwayChanged() {
|
||||||
|
if (keyguardStateController.isKeyguardGoingAway) {
|
||||||
|
prepareForInWindowLauncherAnimations()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare for in-window Launcher unlock animations, if we're able to do so.
|
||||||
|
*
|
||||||
|
* The in-window animations consist of the staggered ring icon unlock animation, and optionally
|
||||||
|
* the shared element smartspace transition.
|
||||||
|
*/
|
||||||
|
fun prepareForInWindowLauncherAnimations() {
|
||||||
|
willUnlockWithInWindowLauncherAnimations = canPerformInWindowLauncherAnimations()
|
||||||
|
|
||||||
|
if (!willUnlockWithInWindowLauncherAnimations) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// There are additional conditions under which we should not perform the smartspace
|
||||||
|
// transition specifically, so check those.
|
||||||
|
willUnlockWithSmartspaceTransition = shouldPerformSmartspaceTransition()
|
||||||
|
|
||||||
|
var lockscreenSmartspaceBounds = Rect()
|
||||||
|
|
||||||
|
// Grab the bounds of our lockscreen smartspace and send them to launcher so they can
|
||||||
|
// position their smartspace there initially, then animate it to its resting position.
|
||||||
|
if (willUnlockWithSmartspaceTransition) {
|
||||||
|
lockscreenSmartspaceBounds = Rect().apply {
|
||||||
|
lockscreenSmartspace!!.getBoundsOnScreen(this)
|
||||||
|
offset(lockscreenSmartspace!!.paddingLeft, lockscreenSmartspace!!.paddingTop)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Currently selected lockscreen smartspace page, or -1 if it's not available.
|
||||||
|
val selectedPage =
|
||||||
|
(lockscreenSmartspace as BcSmartspaceDataPlugin.SmartspaceView?)?.selectedPage ?: -1
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
// Let the launcher know to prepare for this animation.
|
||||||
|
launcherUnlockController?.prepareForUnlock(
|
||||||
|
willUnlockWithSmartspaceTransition, /* willAnimateSmartspace */
|
||||||
|
lockscreenSmartspaceBounds, /* lockscreenSmartspaceBounds */
|
||||||
|
selectedPage, /* selectedPage */
|
||||||
|
)
|
||||||
|
} catch (e: RemoteException) {
|
||||||
|
Log.e(TAG, "Remote exception in prepareForInWindowUnlockAnimations.", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called from [KeyguardViewMediator] to tell us that the RemoteAnimation on the surface behind
|
* Called from [KeyguardViewMediator] to tell us that the RemoteAnimation on the surface behind
|
||||||
* the keyguard has started successfully. We can use these parameters to directly manipulate the
|
* the keyguard has started successfully. We can use these parameters to directly manipulate the
|
||||||
@@ -406,7 +432,8 @@ class KeyguardUnlockAnimationController @Inject constructor(
|
|||||||
*
|
*
|
||||||
* [requestedShowSurfaceBehindKeyguard] indicates whether the animation started because of a
|
* [requestedShowSurfaceBehindKeyguard] indicates whether the animation started because of a
|
||||||
* call to [KeyguardViewMediator.showSurfaceBehindKeyguard], as happens during a swipe gesture,
|
* call to [KeyguardViewMediator.showSurfaceBehindKeyguard], as happens during a swipe gesture,
|
||||||
* as opposed to being called because the device was unlocked and the keyguard is going away.
|
* as opposed to being called because the device was unlocked instantly by some other means
|
||||||
|
* (fingerprint, tap, etc.) and the keyguard is going away.
|
||||||
*/
|
*/
|
||||||
fun notifyStartSurfaceBehindRemoteAnimation(
|
fun notifyStartSurfaceBehindRemoteAnimation(
|
||||||
target: RemoteAnimationTarget,
|
target: RemoteAnimationTarget,
|
||||||
@@ -446,7 +473,9 @@ class KeyguardUnlockAnimationController @Inject constructor(
|
|||||||
listeners.forEach {
|
listeners.forEach {
|
||||||
it.onUnlockAnimationStarted(
|
it.onUnlockAnimationStarted(
|
||||||
playingCannedUnlockAnimation /* playingCannedAnimation */,
|
playingCannedUnlockAnimation /* playingCannedAnimation */,
|
||||||
biometricUnlockControllerLazy.get().isWakeAndUnlock /* isWakeAndUnlock */) }
|
biometricUnlockControllerLazy.get().isWakeAndUnlock /* isWakeAndUnlock */,
|
||||||
|
CANNED_UNLOCK_START_DELAY /* unlockStartDelay */,
|
||||||
|
LAUNCHER_ICONS_ANIMATION_DURATION_MS /* unlockAnimationDuration */) }
|
||||||
|
|
||||||
// Finish the keyguard remote animation if the dismiss amount has crossed the threshold.
|
// Finish the keyguard remote animation if the dismiss amount has crossed the threshold.
|
||||||
// Check it here in case there is no more change to the dismiss amount after the last change
|
// Check it here in case there is no more change to the dismiss amount after the last change
|
||||||
@@ -454,58 +483,33 @@ class KeyguardUnlockAnimationController @Inject constructor(
|
|||||||
finishKeyguardExitRemoteAnimationIfReachThreshold()
|
finishKeyguardExitRemoteAnimationIfReachThreshold()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Called by [KeyguardViewMediator] to let us know that the remote animation has finished, and
|
|
||||||
* we should clean up all of our state.
|
|
||||||
*/
|
|
||||||
fun notifyFinishedKeyguardExitAnimation(cancelled: Boolean) {
|
|
||||||
// Cancel any pending actions.
|
|
||||||
handler.removeCallbacksAndMessages(null)
|
|
||||||
|
|
||||||
// Make sure we made the surface behind fully visible, just in case. It should already be
|
|
||||||
// fully visible.
|
|
||||||
setSurfaceBehindAppearAmount(1f)
|
|
||||||
launcherUnlockController?.setUnlockAmount(1f)
|
|
||||||
smartspaceDestBounds.setEmpty()
|
|
||||||
|
|
||||||
// That target is no longer valid since the animation finished, null it out.
|
|
||||||
surfaceBehindRemoteAnimationTarget = null
|
|
||||||
surfaceBehindParams = null
|
|
||||||
|
|
||||||
playingCannedUnlockAnimation = false
|
|
||||||
unlockingToLauncherWithInWindowAnimations = false
|
|
||||||
unlockingWithSmartspaceTransition = false
|
|
||||||
resetSmartspaceTransition()
|
|
||||||
|
|
||||||
listeners.forEach { it.onUnlockAnimationFinished() }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Play a canned unlock animation to unlock the device. This is used when we were *not* swiping
|
* Play a canned unlock animation to unlock the device. This is used when we were *not* swiping
|
||||||
* to unlock using a touch gesture. If we were swiping to unlock, the animation will be driven
|
* to unlock using a touch gesture. If we were swiping to unlock, the animation will be driven
|
||||||
* by the dismiss amount via [onKeyguardDismissAmountChanged].
|
* by the dismiss amount via [onKeyguardDismissAmountChanged].
|
||||||
*/
|
*/
|
||||||
fun playCannedUnlockAnimation() {
|
private fun playCannedUnlockAnimation() {
|
||||||
playingCannedUnlockAnimation = true
|
playingCannedUnlockAnimation = true
|
||||||
|
|
||||||
if (canPerformInWindowLauncherAnimations()) {
|
|
||||||
// If possible, use the neat in-window animations to unlock to the launcher.
|
|
||||||
unlockToLauncherWithInWindowAnimations()
|
|
||||||
} else if (!biometricUnlockControllerLazy.get().isWakeAndUnlock) {
|
|
||||||
// If the launcher isn't behind the keyguard, or the launcher unlock controller is not
|
|
||||||
// available, animate in the entire window.
|
|
||||||
surfaceBehindEntryAnimator.start()
|
|
||||||
} else {
|
|
||||||
setSurfaceBehindAppearAmount(1f)
|
|
||||||
keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this is a wake and unlock, hide the lockscreen immediately. In the future, we should
|
when {
|
||||||
// animate it out nicely instead, but to the current state of wake and unlock, not hiding it
|
// If we're set up for in-window launcher animations, ask Launcher to play its in-window
|
||||||
// causes a lot of issues.
|
// canned animation.
|
||||||
// TODO(b/210016643): Not this, it looks not-ideal!
|
willUnlockWithInWindowLauncherAnimations -> unlockToLauncherWithInWindowAnimations()
|
||||||
if (biometricUnlockControllerLazy.get().isWakeAndUnlock) {
|
|
||||||
keyguardViewController.hide(surfaceBehindRemoteAnimationStartTime, 350)
|
// If we're waking and unlocking to a non-Launcher app surface (or Launcher in-window
|
||||||
|
// animations are not available), show it immediately and end the remote animation. The
|
||||||
|
// circular light reveal will show the app surface, and it looks weird if it's moving
|
||||||
|
// around behind that.
|
||||||
|
biometricUnlockControllerLazy.get().isWakeAndUnlock -> {
|
||||||
|
setSurfaceBehindAppearAmount(1f)
|
||||||
|
keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(
|
||||||
|
false /* cancelled */)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, we're doing a normal full-window unlock. Start this animator, which will
|
||||||
|
// scale/translate the window underneath the lockscreen.
|
||||||
|
else -> surfaceBehindEntryAnimator.start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -514,205 +518,31 @@ class KeyguardUnlockAnimationController @Inject constructor(
|
|||||||
* transition if possible.
|
* transition if possible.
|
||||||
*/
|
*/
|
||||||
private fun unlockToLauncherWithInWindowAnimations() {
|
private fun unlockToLauncherWithInWindowAnimations() {
|
||||||
// See if we can do the smartspace transition, and if so, do it!
|
setSurfaceBehindAppearAmount(1f)
|
||||||
if (prepareForSmartspaceTransition()) {
|
|
||||||
animateSmartspaceToDestination()
|
|
||||||
listeners.forEach { it.onSmartspaceSharedElementTransitionStarted() }
|
|
||||||
}
|
|
||||||
|
|
||||||
val startDelay = Settings.Secure.getLong(
|
|
||||||
context.contentResolver, "unlock_start_delay", CANNED_UNLOCK_START_DELAY)
|
|
||||||
val duration = Settings.Secure.getLong(
|
|
||||||
context.contentResolver, "unlock_duration", LAUNCHER_ICONS_ANIMATION_DURATION_MS)
|
|
||||||
|
|
||||||
unlockingToLauncherWithInWindowAnimations = true
|
|
||||||
prepareLauncherWorkspaceForUnlockAnimation()
|
|
||||||
|
|
||||||
// Begin the animation, waiting for the shade to animate out.
|
// Begin the animation, waiting for the shade to animate out.
|
||||||
launcherUnlockController?.playUnlockAnimation(
|
launcherUnlockController?.playUnlockAnimation(
|
||||||
true /* unlocked */,
|
true /* unlocked */,
|
||||||
duration /* duration */,
|
LAUNCHER_ICONS_ANIMATION_DURATION_MS /* duration */,
|
||||||
startDelay /* startDelay */)
|
CANNED_UNLOCK_START_DELAY /* startDelay */)
|
||||||
|
|
||||||
|
// Now that the Launcher surface (with its smartspace positioned identically to ours) is
|
||||||
|
// visible, hide our smartspace.
|
||||||
|
lockscreenSmartspace!!.visibility = View.INVISIBLE
|
||||||
|
|
||||||
|
// As soon as the shade has animated out of the way, finish the keyguard exit animation. The
|
||||||
|
// in-window animations in the Launcher window will end on their own.
|
||||||
handler.postDelayed({
|
handler.postDelayed({
|
||||||
applyParamsToSurface(
|
if (keyguardViewMediator.get().isShowingAndNotOccluded &&
|
||||||
SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(
|
!keyguardStateController.isKeyguardGoingAway) {
|
||||||
surfaceBehindRemoteAnimationTarget!!.leash)
|
Log.e(TAG, "Finish keyguard exit animation delayed Runnable ran, but we are " +
|
||||||
.withAlpha(1f)
|
"showing and not going away.")
|
||||||
.build())
|
return@postDelayed
|
||||||
}, startDelay)
|
|
||||||
|
|
||||||
if (!unlockingWithSmartspaceTransition) {
|
|
||||||
// If we are not unlocking with the smartspace transition, wait for the unlock animation
|
|
||||||
// to end and then finish the remote animation. If we are using the smartspace
|
|
||||||
// transition, it will finish the remote animation once it ends.
|
|
||||||
handler.postDelayed({
|
|
||||||
keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(
|
|
||||||
false /* cancelled */)
|
|
||||||
}, UNLOCK_ANIMATION_DURATION_MS)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Asks Launcher to prepare the workspace to be unlocked. This sets up the animation and makes
|
|
||||||
* the page invisible.
|
|
||||||
*/
|
|
||||||
private fun prepareLauncherWorkspaceForUnlockAnimation() {
|
|
||||||
// Tell the launcher to prepare for the animation by setting its views invisible and
|
|
||||||
// syncing the selected smartspace pages.
|
|
||||||
launcherUnlockController?.prepareForUnlock(
|
|
||||||
unlockingWithSmartspaceTransition /* willAnimateSmartspace */,
|
|
||||||
(lockscreenSmartspace as BcSmartspaceDataPlugin.SmartspaceView?)?.selectedPage ?: -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Animates the lockscreen smartspace all the way to the launcher's smartspace location, then
|
|
||||||
* makes the launcher smartspace visible and ends the remote animation.
|
|
||||||
*/
|
|
||||||
private fun animateSmartspaceToDestination() {
|
|
||||||
smartspaceAnimator.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset the lockscreen smartspace's position, and reset all state involving the smartspace
|
|
||||||
* transition.
|
|
||||||
*/
|
|
||||||
public fun resetSmartspaceTransition() {
|
|
||||||
unlockingWithSmartspaceTransition = false
|
|
||||||
smartspaceUnlockProgress = 0f
|
|
||||||
|
|
||||||
lockscreenSmartspace?.post {
|
|
||||||
lockscreenSmartspace!!.translationX = 0f
|
|
||||||
lockscreenSmartspace!!.translationY = 0f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Moves the lockscreen smartspace towards the launcher smartspace's position.
|
|
||||||
*/
|
|
||||||
private fun setSmartspaceProgressToDestinationBounds(progress: Float) {
|
|
||||||
if (smartspaceDestBounds.isEmpty) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val progressClamped = min(1f, progress)
|
|
||||||
|
|
||||||
// Calculate the distance (relative to the origin) that we need to be for the current
|
|
||||||
// progress value.
|
|
||||||
val progressX =
|
|
||||||
(smartspaceDestBounds.left - smartspaceOriginBounds.left) * progressClamped
|
|
||||||
val progressY =
|
|
||||||
(smartspaceDestBounds.top - smartspaceOriginBounds.top) * progressClamped
|
|
||||||
|
|
||||||
val lockscreenSmartspaceCurrentBounds = Rect().also {
|
|
||||||
lockscreenSmartspace!!.getBoundsOnScreen(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Figure out how far that is from our present location on the screen. This approach
|
|
||||||
// compensates for the fact that our parent container is also translating to animate out.
|
|
||||||
val dx = smartspaceOriginBounds.left + progressX -
|
|
||||||
lockscreenSmartspaceCurrentBounds.left
|
|
||||||
val dy = smartspaceOriginBounds.top + progressY -
|
|
||||||
lockscreenSmartspaceCurrentBounds.top
|
|
||||||
|
|
||||||
with(lockscreenSmartspace!!) {
|
|
||||||
translationX += dx
|
|
||||||
translationY += dy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the lockscreen SmartSpace to be positioned according to the current dismiss amount. As
|
|
||||||
* the dismiss amount increases, we will increase our SmartSpace's progress to the destination
|
|
||||||
* bounds (the location of the Launcher SmartSpace).
|
|
||||||
*
|
|
||||||
* This is used by [KeyguardClockSwitchController] to keep the smartspace position updated as
|
|
||||||
* the clock is swiped away.
|
|
||||||
*/
|
|
||||||
fun updateLockscreenSmartSpacePosition() {
|
|
||||||
setSmartspaceProgressToDestinationBounds(smartspaceUnlockProgress)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Asks the keyguard view to hide, using the start time from the beginning of the remote
|
|
||||||
* animation.
|
|
||||||
*/
|
|
||||||
fun hideKeyguardViewAfterRemoteAnimation() {
|
|
||||||
if (keyguardViewController.isShowing) {
|
|
||||||
// Hide the keyguard, with no fade out since we animated it away during the unlock.
|
|
||||||
keyguardViewController.hide(
|
|
||||||
surfaceBehindRemoteAnimationStartTime,
|
|
||||||
0 /* fadeOutDuration */
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "#hideKeyguardViewAfterRemoteAnimation called when keyguard view is not " +
|
|
||||||
"showing. Ignoring...")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun applyParamsToSurface(params: SyncRtSurfaceTransactionApplier.SurfaceParams) {
|
|
||||||
surfaceTransactionApplier!!.scheduleApply(params)
|
|
||||||
surfaceBehindParams = params
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Scales in and translates up the surface behind the keyguard. This is used during unlock
|
|
||||||
* animations and swipe gestures to animate the surface's entry (and exit, if the swipe is
|
|
||||||
* cancelled).
|
|
||||||
*/
|
|
||||||
fun setSurfaceBehindAppearAmount(amount: Float) {
|
|
||||||
if (surfaceBehindRemoteAnimationTarget == null) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlockingToLauncherWithInWindowAnimations) {
|
|
||||||
// If we aren't using the canned unlock animation (which would be setting the unlock
|
|
||||||
// amount in its update listener), do it here.
|
|
||||||
if (!isPlayingCannedUnlockAnimation()) {
|
|
||||||
launcherUnlockController?.setUnlockAmount(amount)
|
|
||||||
|
|
||||||
if (surfaceBehindParams?.alpha?.let { it < 1f } != false) {
|
|
||||||
applyParamsToSurface(
|
|
||||||
SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(
|
|
||||||
surfaceBehindRemoteAnimationTarget!!.leash)
|
|
||||||
.withAlpha(1f)
|
|
||||||
.build())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// Otherwise, animate in the surface's scale/transltion.
|
|
||||||
val surfaceHeight: Int = surfaceBehindRemoteAnimationTarget!!.screenSpaceBounds.height()
|
|
||||||
val scaleFactor = (SURFACE_BEHIND_START_SCALE_FACTOR +
|
|
||||||
(1f - SURFACE_BEHIND_START_SCALE_FACTOR) *
|
|
||||||
MathUtils.clamp(amount, 0f, 1f))
|
|
||||||
|
|
||||||
// Scale up from a point at the center-bottom of the surface.
|
keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(
|
||||||
surfaceBehindMatrix.setScale(
|
false /* cancelled */)
|
||||||
scaleFactor,
|
}, CANNED_UNLOCK_START_DELAY)
|
||||||
scaleFactor,
|
|
||||||
surfaceBehindRemoteAnimationTarget!!.screenSpaceBounds.width() / 2f,
|
|
||||||
surfaceHeight * SURFACE_BEHIND_SCALE_PIVOT_Y
|
|
||||||
)
|
|
||||||
|
|
||||||
// Translate up from the bottom.
|
|
||||||
surfaceBehindMatrix.postTranslate(
|
|
||||||
0f,
|
|
||||||
surfaceHeight * SURFACE_BEHIND_START_TRANSLATION_Y * (1f - amount)
|
|
||||||
)
|
|
||||||
|
|
||||||
// If we're snapping the keyguard back, immediately begin fading it out.
|
|
||||||
val animationAlpha =
|
|
||||||
if (keyguardStateController.isSnappingKeyguardBackAfterSwipe) amount
|
|
||||||
else surfaceBehindAlpha
|
|
||||||
|
|
||||||
applyParamsToSurface(
|
|
||||||
SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(
|
|
||||||
surfaceBehindRemoteAnimationTarget!!.leash)
|
|
||||||
.withMatrix(surfaceBehindMatrix)
|
|
||||||
.withCornerRadius(roundedCornerRadius)
|
|
||||||
.withAlpha(animationAlpha)
|
|
||||||
.build())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -750,7 +580,7 @@ class KeyguardUnlockAnimationController @Inject constructor(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyguardViewController.isShowing) {
|
if (keyguardViewController.isShowing && !playingCannedUnlockAnimation) {
|
||||||
showOrHideSurfaceIfDismissAmountThresholdsReached()
|
showOrHideSurfaceIfDismissAmountThresholdsReached()
|
||||||
|
|
||||||
// If the surface is visible or it's about to be, start updating its appearance to
|
// If the surface is visible or it's about to be, start updating its appearance to
|
||||||
@@ -762,11 +592,6 @@ class KeyguardUnlockAnimationController @Inject constructor(
|
|||||||
updateSurfaceBehindAppearAmount()
|
updateSurfaceBehindAppearAmount()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The end of the SmartSpace transition can occur after the keyguard is hidden (when we tell
|
|
||||||
// Launcher's SmartSpace to become visible again), so update it even if the keyguard view is
|
|
||||||
// no longer showing.
|
|
||||||
applyDismissAmountToSmartspaceTransition()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -787,16 +612,15 @@ class KeyguardUnlockAnimationController @Inject constructor(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!keyguardStateController.isShowing) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val dismissAmount = keyguardStateController.dismissAmount
|
val dismissAmount = keyguardStateController.dismissAmount
|
||||||
|
|
||||||
if (dismissAmount >= DISMISS_AMOUNT_SHOW_SURFACE_THRESHOLD &&
|
if (dismissAmount >= DISMISS_AMOUNT_SHOW_SURFACE_THRESHOLD &&
|
||||||
!keyguardViewMediator.get().requestedShowSurfaceBehindKeyguard()) {
|
!keyguardViewMediator.get().requestedShowSurfaceBehindKeyguard()) {
|
||||||
// We passed the threshold, and we're not yet showing the surface behind the
|
|
||||||
// keyguard. Animate it in.
|
|
||||||
if (!unlockingToLauncherWithInWindowAnimations &&
|
|
||||||
canPerformInWindowLauncherAnimations()) {
|
|
||||||
unlockingToLauncherWithInWindowAnimations = true
|
|
||||||
prepareLauncherWorkspaceForUnlockAnimation()
|
|
||||||
}
|
|
||||||
keyguardViewMediator.get().showSurfaceBehindKeyguard()
|
keyguardViewMediator.get().showSurfaceBehindKeyguard()
|
||||||
} else if (dismissAmount < DISMISS_AMOUNT_SHOW_SURFACE_THRESHOLD &&
|
} else if (dismissAmount < DISMISS_AMOUNT_SHOW_SURFACE_THRESHOLD &&
|
||||||
keyguardViewMediator.get().requestedShowSurfaceBehindKeyguard()) {
|
keyguardViewMediator.get().requestedShowSurfaceBehindKeyguard()) {
|
||||||
@@ -839,58 +663,101 @@ class KeyguardUnlockAnimationController @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates flags related to the SmartSpace transition in response to a change in keyguard
|
* Scales in and translates up the surface behind the keyguard. This is used during unlock
|
||||||
* dismiss amount, and also updates the SmartSpaceTransitionController, which will let Launcher
|
* animations and swipe gestures to animate the surface's entry (and exit, if the swipe is
|
||||||
* know if it needs to do something as a result.
|
* cancelled).
|
||||||
*/
|
*/
|
||||||
private fun applyDismissAmountToSmartspaceTransition() {
|
fun setSurfaceBehindAppearAmount(amount: Float) {
|
||||||
if (!featureFlags.isEnabled(Flags.SMARTSPACE_SHARED_ELEMENT_TRANSITION_ENABLED)) {
|
if (surfaceBehindRemoteAnimationTarget == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are playing the canned animation, the smartspace is being animated directly between
|
// Otherwise, animate in the surface's scale/transltion.
|
||||||
// its original location and the location of the launcher smartspace by smartspaceAnimator.
|
val surfaceHeight: Int = surfaceBehindRemoteAnimationTarget!!.screenSpaceBounds.height()
|
||||||
// We can ignore the dismiss amount, which is caused by panel height changes as the panel is
|
val scaleFactor = (SURFACE_BEHIND_START_SCALE_FACTOR +
|
||||||
// flung away.
|
(1f - SURFACE_BEHIND_START_SCALE_FACTOR) *
|
||||||
if (playingCannedUnlockAnimation) {
|
MathUtils.clamp(amount, 0f, 1f))
|
||||||
return
|
|
||||||
|
// Scale up from a point at the center-bottom of the surface.
|
||||||
|
surfaceBehindMatrix.setScale(
|
||||||
|
scaleFactor,
|
||||||
|
scaleFactor,
|
||||||
|
surfaceBehindRemoteAnimationTarget!!.screenSpaceBounds.width() / 2f,
|
||||||
|
surfaceHeight * SURFACE_BEHIND_SCALE_PIVOT_Y
|
||||||
|
)
|
||||||
|
|
||||||
|
// Translate up from the bottom.
|
||||||
|
surfaceBehindMatrix.postTranslate(
|
||||||
|
0f,
|
||||||
|
surfaceHeight * SURFACE_BEHIND_START_TRANSLATION_Y * (1f - amount)
|
||||||
|
)
|
||||||
|
|
||||||
|
// If we're snapping the keyguard back, immediately begin fading it out.
|
||||||
|
val animationAlpha =
|
||||||
|
if (keyguardStateController.isSnappingKeyguardBackAfterSwipe) amount
|
||||||
|
else surfaceBehindAlpha
|
||||||
|
|
||||||
|
applyParamsToSurface(
|
||||||
|
SyncRtSurfaceTransactionApplier.SurfaceParams.Builder(
|
||||||
|
surfaceBehindRemoteAnimationTarget!!.leash)
|
||||||
|
.withMatrix(surfaceBehindMatrix)
|
||||||
|
.withCornerRadius(roundedCornerRadius)
|
||||||
|
.withAlpha(animationAlpha)
|
||||||
|
.build())
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by [KeyguardViewMediator] to let us know that the remote animation has finished, and
|
||||||
|
* we should clean up all of our state.
|
||||||
|
*
|
||||||
|
* This is generally triggered by us, calling
|
||||||
|
* [KeyguardViewMediator.finishSurfaceBehindRemoteAnimation].
|
||||||
|
*/
|
||||||
|
fun notifyFinishedKeyguardExitAnimation(cancelled: Boolean) {
|
||||||
|
// Cancel any pending actions.
|
||||||
|
handler.removeCallbacksAndMessages(null)
|
||||||
|
|
||||||
|
// Make sure we made the surface behind fully visible, just in case. It should already be
|
||||||
|
// fully visible. If the launcher is doing its own animation, let it continue without
|
||||||
|
// forcing it to 1f.
|
||||||
|
setSurfaceBehindAppearAmount(1f)
|
||||||
|
launcherUnlockController?.setUnlockAmount(1f, false /* forceIfAnimating */)
|
||||||
|
|
||||||
|
// That target is no longer valid since the animation finished, null it out.
|
||||||
|
surfaceBehindRemoteAnimationTarget = null
|
||||||
|
surfaceBehindParams = null
|
||||||
|
|
||||||
|
playingCannedUnlockAnimation = false
|
||||||
|
willUnlockWithInWindowLauncherAnimations = false
|
||||||
|
willUnlockWithSmartspaceTransition = false
|
||||||
|
|
||||||
|
// The lockscreen surface is gone, so it is now safe to re-show the smartspace.
|
||||||
|
lockscreenSmartspace?.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
listeners.forEach { it.onUnlockAnimationFinished() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asks the keyguard view to hide, using the start time from the beginning of the remote
|
||||||
|
* animation.
|
||||||
|
*/
|
||||||
|
fun hideKeyguardViewAfterRemoteAnimation() {
|
||||||
|
if (keyguardViewController.isShowing) {
|
||||||
|
// Hide the keyguard, with no fade out since we animated it away during the unlock.
|
||||||
|
|
||||||
|
keyguardViewController.hide(
|
||||||
|
surfaceBehindRemoteAnimationStartTime,
|
||||||
|
0 /* fadeOutDuration */
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "#hideKeyguardViewAfterRemoteAnimation called when keyguard view is not " +
|
||||||
|
"showing. Ignoring...")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val dismissAmount = keyguardStateController.dismissAmount
|
private fun applyParamsToSurface(params: SyncRtSurfaceTransactionApplier.SurfaceParams) {
|
||||||
|
surfaceTransactionApplier!!.scheduleApply(params)
|
||||||
// If we've begun a swipe, and haven't yet tried doing the SmartSpace transition, do that
|
surfaceBehindParams = params
|
||||||
// now.
|
|
||||||
if (!attemptedSmartSpaceTransitionForThisSwipe &&
|
|
||||||
keyguardViewController.isShowing &&
|
|
||||||
dismissAmount > 0f &&
|
|
||||||
dismissAmount < 1f) {
|
|
||||||
attemptedSmartSpaceTransitionForThisSwipe = true
|
|
||||||
|
|
||||||
if (prepareForSmartspaceTransition()) {
|
|
||||||
unlockingWithSmartspaceTransition = true
|
|
||||||
|
|
||||||
// Ensure that the smartspace is invisible if we're doing the transition, and
|
|
||||||
// visible if we aren't.
|
|
||||||
launcherUnlockController?.setSmartspaceVisibility(
|
|
||||||
if (unlockingWithSmartspaceTransition) View.INVISIBLE else View.VISIBLE)
|
|
||||||
|
|
||||||
if (unlockingWithSmartspaceTransition) {
|
|
||||||
listeners.forEach { it.onSmartspaceSharedElementTransitionStarted() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (attemptedSmartSpaceTransitionForThisSwipe &&
|
|
||||||
(dismissAmount == 0f || dismissAmount == 1f)) {
|
|
||||||
attemptedSmartSpaceTransitionForThisSwipe = false
|
|
||||||
unlockingWithSmartspaceTransition = false
|
|
||||||
launcherUnlockController?.setSmartspaceVisibility(View.VISIBLE)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlockingWithSmartspaceTransition) {
|
|
||||||
val swipedFraction: Float = keyguardStateController.dismissAmount
|
|
||||||
val progress = swipedFraction / DISMISS_AMOUNT_EXIT_KEYGUARD_THRESHOLD
|
|
||||||
smartspaceUnlockProgress = progress
|
|
||||||
setSmartspaceProgressToDestinationBounds(smartspaceUnlockProgress)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fadeInSurfaceBehind() {
|
private fun fadeInSurfaceBehind() {
|
||||||
@@ -903,14 +770,8 @@ class KeyguardUnlockAnimationController @Inject constructor(
|
|||||||
surfaceBehindAlphaAnimator.reverse()
|
surfaceBehindAlphaAnimator.reverse()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare for the smartspace shared element transition, if possible, by figuring out where we
|
private fun shouldPerformSmartspaceTransition(): Boolean {
|
||||||
* are animating from/to.
|
|
||||||
*
|
|
||||||
* Return true if we'll be able to do the smartspace transition, or false if conditions are not
|
|
||||||
* right to do it right now.
|
|
||||||
*/
|
|
||||||
private fun prepareForSmartspaceTransition(): Boolean {
|
|
||||||
// Feature is disabled, so we don't want to.
|
// Feature is disabled, so we don't want to.
|
||||||
if (!featureFlags.isEnabled(Flags.SMARTSPACE_SHARED_ELEMENT_TRANSITION_ENABLED)) {
|
if (!featureFlags.isEnabled(Flags.SMARTSPACE_SHARED_ELEMENT_TRANSITION_ENABLED)) {
|
||||||
return false
|
return false
|
||||||
@@ -951,45 +812,22 @@ class KeyguardUnlockAnimationController @Inject constructor(
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
unlockingWithSmartspaceTransition = true
|
// We started to swipe to dismiss, but now we're doing a fling animation to complete the
|
||||||
smartspaceDestBounds.setEmpty()
|
// dismiss. In this case, the smartspace swiped away with the rest of the keyguard, so don't
|
||||||
|
// do the shared element transition.
|
||||||
// Assuming we were able to retrieve the launcher's state, start the lockscreen
|
if (keyguardStateController.isFlingingToDismissKeyguardDuringSwipeGesture) {
|
||||||
// smartspace at 0, 0, and save its starting bounds.
|
return false
|
||||||
with(lockscreenSmartspace!!) {
|
|
||||||
translationX = 0f
|
|
||||||
translationY = 0f
|
|
||||||
getBoundsOnScreen(smartspaceOriginBounds)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the destination bounds to the launcher smartspace's bounds, offset by any
|
|
||||||
// padding on our smartspace.
|
|
||||||
with(smartspaceDestBounds) {
|
|
||||||
set(launcherSmartspaceState!!.boundsOnScreen)
|
|
||||||
offset(-lockscreenSmartspace!!.paddingLeft, -lockscreenSmartspace!!.paddingTop)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether we should be able to do the in-window launcher animations given the current state of
|
|
||||||
* the device.
|
|
||||||
*/
|
|
||||||
fun canPerformInWindowLauncherAnimations(): Boolean {
|
|
||||||
return isNexusLauncherUnderneath() &&
|
|
||||||
launcherUnlockController != null &&
|
|
||||||
// Temporarily disable for foldables since foldable launcher has two first pages,
|
|
||||||
// which breaks the in-window animation.
|
|
||||||
!isFoldable(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether we are currently in the process of unlocking the keyguard, and we are performing the
|
* Whether we are currently in the process of unlocking the keyguard, and we are performing the
|
||||||
* shared element SmartSpace transition.
|
* shared element SmartSpace transition.
|
||||||
*/
|
*/
|
||||||
fun isUnlockingWithSmartSpaceTransition(): Boolean {
|
fun isUnlockingWithSmartSpaceTransition(): Boolean {
|
||||||
return unlockingWithSmartspaceTransition
|
return willUnlockWithSmartspaceTransition
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2678,7 +2678,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** If it's running, finishes the RemoteAnimation on the surface behind the keyguard. */
|
/** If it's running, finishes the RemoteAnimation on the surface behind the keyguard. */
|
||||||
public void finishSurfaceBehindRemoteAnimation(boolean cancelled) {
|
void finishSurfaceBehindRemoteAnimation(boolean cancelled) {
|
||||||
if (!mSurfaceBehindRemoteAnimationRunning) {
|
if (!mSurfaceBehindRemoteAnimationRunning) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2951,8 +2951,6 @@ public class CentralSurfaces extends CoreStartable implements
|
|||||||
|
|
||||||
public void showKeyguardImpl() {
|
public void showKeyguardImpl() {
|
||||||
Trace.beginSection("CentralSurfaces#showKeyguard");
|
Trace.beginSection("CentralSurfaces#showKeyguard");
|
||||||
// In case we're locking while a smartspace transition is in progress, reset it.
|
|
||||||
mKeyguardUnlockAnimationController.resetSmartspaceTransition();
|
|
||||||
if (mKeyguardStateController.isLaunchTransitionFadingAway()) {
|
if (mKeyguardStateController.isLaunchTransitionFadingAway()) {
|
||||||
mNotificationPanelViewController.cancelAnimation();
|
mNotificationPanelViewController.cancelAnimation();
|
||||||
onLaunchTransitionFadingEnded();
|
onLaunchTransitionFadingEnded();
|
||||||
|
|||||||
@@ -885,7 +885,10 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUnlockAnimationStarted(
|
public void onUnlockAnimationStarted(
|
||||||
boolean playingCannedAnimation, boolean isWakeAndUnlock) {
|
boolean playingCannedAnimation,
|
||||||
|
boolean isWakeAndUnlock,
|
||||||
|
long unlockAnimationStartDelay,
|
||||||
|
long unlockAnimationDuration) {
|
||||||
// Disable blurs while we're unlocking so that panel expansion does not
|
// Disable blurs while we're unlocking so that panel expansion does not
|
||||||
// cause blurring. This will eventually be re-enabled by the panel view on
|
// cause blurring. This will eventually be re-enabled by the panel view on
|
||||||
// ACTION_UP, since the user's finger might still be down after a swipe to
|
// ACTION_UP, since the user's finger might still be down after a swipe to
|
||||||
@@ -902,7 +905,22 @@ public class NotificationPanelViewController extends PanelViewController {
|
|||||||
onTrackingStopped(false);
|
onTrackingStopped(false);
|
||||||
instantCollapse();
|
instantCollapse();
|
||||||
} else {
|
} else {
|
||||||
fling(0f, false, 1f, false);
|
mView.animate()
|
||||||
|
.alpha(0f)
|
||||||
|
.setStartDelay(0)
|
||||||
|
// Translate up by 4%.
|
||||||
|
.translationY(mView.getHeight() * -0.04f)
|
||||||
|
// This start delay is to give us time to animate out before
|
||||||
|
// the launcher icons animation starts, so use that as our
|
||||||
|
// duration.
|
||||||
|
.setDuration(unlockAnimationStartDelay)
|
||||||
|
.setInterpolator(EMPHASIZED_DECELERATE)
|
||||||
|
.withEndAction(() -> {
|
||||||
|
instantCollapse();
|
||||||
|
mView.setAlpha(1f);
|
||||||
|
mView.setTranslationY(0f);
|
||||||
|
})
|
||||||
|
.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import android.test.suitebuilder.annotation.SmallTest;
|
|||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
|
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
|
||||||
import com.android.systemui.statusbar.phone.DozeParameters;
|
import com.android.systemui.statusbar.phone.DozeParameters;
|
||||||
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
|
import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
|
||||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||||
@@ -55,8 +54,6 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase {
|
|||||||
@Mock
|
@Mock
|
||||||
DozeParameters mDozeParameters;
|
DozeParameters mDozeParameters;
|
||||||
@Mock
|
@Mock
|
||||||
KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
|
|
||||||
@Mock
|
|
||||||
ScreenOffAnimationController mScreenOffAnimationController;
|
ScreenOffAnimationController mScreenOffAnimationController;
|
||||||
@Captor
|
@Captor
|
||||||
private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallbackCaptor;
|
private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallbackCaptor;
|
||||||
@@ -75,7 +72,6 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase {
|
|||||||
mKeyguardUpdateMonitor,
|
mKeyguardUpdateMonitor,
|
||||||
mConfigurationController,
|
mConfigurationController,
|
||||||
mDozeParameters,
|
mDozeParameters,
|
||||||
mKeyguardUnlockAnimationController,
|
|
||||||
mScreenOffAnimationController);
|
mScreenOffAnimationController);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user