Merge "Animate the Wallet activity launch on lockscreen (1/2)" into sc-v2-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
38e9684d15
@@ -5,7 +5,6 @@ import android.animation.AnimatorListenerAdapter
|
|||||||
import android.animation.ValueAnimator
|
import android.animation.ValueAnimator
|
||||||
import android.app.ActivityManager
|
import android.app.ActivityManager
|
||||||
import android.app.ActivityTaskManager
|
import android.app.ActivityTaskManager
|
||||||
import android.app.AppGlobals
|
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.app.TaskInfo
|
import android.app.TaskInfo
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
@@ -44,6 +43,7 @@ class ActivityLaunchAnimator(
|
|||||||
context: Context
|
context: Context
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
|
private const val DEBUG = false
|
||||||
const val ANIMATION_DURATION = 500L
|
const val ANIMATION_DURATION = 500L
|
||||||
private const val ANIMATION_DURATION_FADE_OUT_CONTENT = 150L
|
private const val ANIMATION_DURATION_FADE_OUT_CONTENT = 150L
|
||||||
private const val ANIMATION_DURATION_FADE_IN_WINDOW = 183L
|
private const val ANIMATION_DURATION_FADE_IN_WINDOW = 183L
|
||||||
@@ -75,8 +75,6 @@ class ActivityLaunchAnimator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val packageManager = AppGlobals.getPackageManager()
|
|
||||||
|
|
||||||
/** The interpolator used for the width, height, Y position and corner radius. */
|
/** The interpolator used for the width, height, Y position and corner radius. */
|
||||||
private val animationInterpolator = AnimationUtils.loadInterpolator(context,
|
private val animationInterpolator = AnimationUtils.loadInterpolator(context,
|
||||||
R.interpolator.launch_animation_interpolator_y)
|
R.interpolator.launch_animation_interpolator_y)
|
||||||
@@ -100,6 +98,10 @@ class ActivityLaunchAnimator(
|
|||||||
* If possible, you should pass the [packageName] of the intent that will be started so that
|
* If possible, you should pass the [packageName] of the intent that will be started so that
|
||||||
* trampoline activity launches will also be animated.
|
* trampoline activity launches will also be animated.
|
||||||
*
|
*
|
||||||
|
* If the device is currently locked, the user will have to unlock it before the intent is
|
||||||
|
* started unless [showOverLockscreen] is true. In that case, the activity will be started
|
||||||
|
* directly over the lockscreen.
|
||||||
|
*
|
||||||
* This method will throw any exception thrown by [intentStarter].
|
* This method will throw any exception thrown by [intentStarter].
|
||||||
*/
|
*/
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
@@ -107,21 +109,22 @@ class ActivityLaunchAnimator(
|
|||||||
controller: Controller?,
|
controller: Controller?,
|
||||||
animate: Boolean = true,
|
animate: Boolean = true,
|
||||||
packageName: String? = null,
|
packageName: String? = null,
|
||||||
|
showOverLockscreen: Boolean = false,
|
||||||
intentStarter: (RemoteAnimationAdapter?) -> Int
|
intentStarter: (RemoteAnimationAdapter?) -> Int
|
||||||
) {
|
) {
|
||||||
if (controller == null || !animate) {
|
if (controller == null || !animate) {
|
||||||
Log.d(TAG, "Starting intent with no animation")
|
Log.i(TAG, "Starting intent with no animation")
|
||||||
intentStarter(null)
|
intentStarter(null)
|
||||||
controller?.callOnIntentStartedOnMainThread(willAnimate = false)
|
controller?.callOnIntentStartedOnMainThread(willAnimate = false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(TAG, "Starting intent with a launch animation")
|
|
||||||
val runner = Runner(controller)
|
val runner = Runner(controller)
|
||||||
val isOnKeyguard = callback.isOnKeyguard()
|
val hideKeyguardWithAnimation = callback.isOnKeyguard() && !showOverLockscreen
|
||||||
|
|
||||||
// Pass the RemoteAnimationAdapter to the intent starter only if we are not on the keyguard.
|
// Pass the RemoteAnimationAdapter to the intent starter only if we are not hiding the
|
||||||
val animationAdapter = if (!isOnKeyguard) {
|
// keyguard with the animation
|
||||||
|
val animationAdapter = if (!hideKeyguardWithAnimation) {
|
||||||
RemoteAnimationAdapter(
|
RemoteAnimationAdapter(
|
||||||
runner,
|
runner,
|
||||||
ANIMATION_DURATION,
|
ANIMATION_DURATION,
|
||||||
@@ -149,9 +152,11 @@ class ActivityLaunchAnimator(
|
|||||||
val willAnimate =
|
val willAnimate =
|
||||||
launchResult == ActivityManager.START_TASK_TO_FRONT ||
|
launchResult == ActivityManager.START_TASK_TO_FRONT ||
|
||||||
launchResult == ActivityManager.START_SUCCESS ||
|
launchResult == ActivityManager.START_SUCCESS ||
|
||||||
(launchResult == ActivityManager.START_DELIVERED_TO_TOP && isOnKeyguard)
|
(launchResult == ActivityManager.START_DELIVERED_TO_TOP &&
|
||||||
|
hideKeyguardWithAnimation)
|
||||||
|
|
||||||
Log.d(TAG, "launchResult=$launchResult willAnimate=$willAnimate isOnKeyguard=$isOnKeyguard")
|
Log.i(TAG, "launchResult=$launchResult willAnimate=$willAnimate " +
|
||||||
|
"hideKeyguardWithAnimation=$hideKeyguardWithAnimation")
|
||||||
controller.callOnIntentStartedOnMainThread(willAnimate)
|
controller.callOnIntentStartedOnMainThread(willAnimate)
|
||||||
|
|
||||||
// If we expect an animation, post a timeout to cancel it in case the remote animation is
|
// If we expect an animation, post a timeout to cancel it in case the remote animation is
|
||||||
@@ -160,7 +165,7 @@ class ActivityLaunchAnimator(
|
|||||||
runner.postTimeout()
|
runner.postTimeout()
|
||||||
|
|
||||||
// Hide the keyguard using the launch animation instead of the default unlock animation.
|
// Hide the keyguard using the launch animation instead of the default unlock animation.
|
||||||
if (isOnKeyguard) {
|
if (hideKeyguardWithAnimation) {
|
||||||
callback.hideKeyguardWithAnimation(runner)
|
callback.hideKeyguardWithAnimation(runner)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -424,13 +429,16 @@ class ActivityLaunchAnimator(
|
|||||||
nonApps: Array<out RemoteAnimationTarget>?,
|
nonApps: Array<out RemoteAnimationTarget>?,
|
||||||
iCallback: IRemoteAnimationFinishedCallback?
|
iCallback: IRemoteAnimationFinishedCallback?
|
||||||
) {
|
) {
|
||||||
Log.d(TAG, "Remote animation started")
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "Remote animation started")
|
||||||
|
}
|
||||||
|
|
||||||
val window = apps?.firstOrNull {
|
val window = apps?.firstOrNull {
|
||||||
it.mode == RemoteAnimationTarget.MODE_OPENING
|
it.mode == RemoteAnimationTarget.MODE_OPENING
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window == null) {
|
if (window == null) {
|
||||||
Log.d(TAG, "Aborting the animation as no window is opening")
|
Log.i(TAG, "Aborting the animation as no window is opening")
|
||||||
removeTimeout()
|
removeTimeout()
|
||||||
iCallback?.invoke()
|
iCallback?.invoke()
|
||||||
controller.onLaunchAnimationCancelled()
|
controller.onLaunchAnimationCancelled()
|
||||||
@@ -500,7 +508,10 @@ class ActivityLaunchAnimator(
|
|||||||
val launchContainerOverlay = launchContainer.overlay
|
val launchContainerOverlay = launchContainer.overlay
|
||||||
animator.addListener(object : AnimatorListenerAdapter() {
|
animator.addListener(object : AnimatorListenerAdapter() {
|
||||||
override fun onAnimationStart(animation: Animator?, isReverse: Boolean) {
|
override fun onAnimationStart(animation: Animator?, isReverse: Boolean) {
|
||||||
Log.d(TAG, "Animation started")
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "Animation started")
|
||||||
|
}
|
||||||
|
|
||||||
callback.setBlursDisabledForAppLaunch(true)
|
callback.setBlursDisabledForAppLaunch(true)
|
||||||
controller.onLaunchAnimationStart(isExpandingFullyAbove)
|
controller.onLaunchAnimationStart(isExpandingFullyAbove)
|
||||||
|
|
||||||
@@ -511,7 +522,10 @@ class ActivityLaunchAnimator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onAnimationEnd(animation: Animator?) {
|
override fun onAnimationEnd(animation: Animator?) {
|
||||||
Log.d(TAG, "Animation ended")
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "Animation ended")
|
||||||
|
}
|
||||||
|
|
||||||
callback.setBlursDisabledForAppLaunch(false)
|
callback.setBlursDisabledForAppLaunch(false)
|
||||||
iCallback?.invoke()
|
iCallback?.invoke()
|
||||||
controller.onLaunchAnimationEnd(isExpandingFullyAbove)
|
controller.onLaunchAnimationEnd(isExpandingFullyAbove)
|
||||||
@@ -686,7 +700,7 @@ class ActivityLaunchAnimator(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(TAG, "Remote animation timed out")
|
Log.i(TAG, "Remote animation timed out")
|
||||||
timedOut = true
|
timedOut = true
|
||||||
controller.onLaunchAnimationCancelled()
|
controller.onLaunchAnimationCancelled()
|
||||||
}
|
}
|
||||||
@@ -696,7 +710,7 @@ class ActivityLaunchAnimator(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(TAG, "Remote animation was cancelled")
|
Log.i(TAG, "Remote animation was cancelled")
|
||||||
cancelled = true
|
cancelled = true
|
||||||
removeTimeout()
|
removeTimeout()
|
||||||
context.mainExecutor.execute {
|
context.mainExecutor.execute {
|
||||||
|
|||||||
@@ -60,8 +60,16 @@ public interface ActivityStarter {
|
|||||||
*/
|
*/
|
||||||
void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade, int flags);
|
void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade, int flags);
|
||||||
void startActivity(Intent intent, boolean dismissShade);
|
void startActivity(Intent intent, boolean dismissShade);
|
||||||
|
|
||||||
|
default void startActivity(Intent intent, boolean dismissShade,
|
||||||
|
@Nullable ActivityLaunchAnimator.Controller animationController) {
|
||||||
|
startActivity(intent, dismissShade, animationController,
|
||||||
|
false /* showOverLockscreenWhenLocked */);
|
||||||
|
}
|
||||||
|
|
||||||
void startActivity(Intent intent, boolean dismissShade,
|
void startActivity(Intent intent, boolean dismissShade,
|
||||||
@Nullable ActivityLaunchAnimator.Controller animationController);
|
@Nullable ActivityLaunchAnimator.Controller animationController,
|
||||||
|
boolean showOverLockscreenWhenLocked);
|
||||||
void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade);
|
void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade);
|
||||||
void startActivity(Intent intent, boolean dismissShade, Callback callback);
|
void startActivity(Intent intent, boolean dismissShade, Callback callback);
|
||||||
void postStartActivityDismissingKeyguard(Intent intent, int delay);
|
void postStartActivityDismissingKeyguard(Intent intent, int delay);
|
||||||
|
|||||||
@@ -22,11 +22,12 @@
|
|||||||
android:color="?android:attr/textColorPrimary">
|
android:color="?android:attr/textColorPrimary">
|
||||||
<item>
|
<item>
|
||||||
<shape
|
<shape
|
||||||
android:shape="oval">
|
android:shape="rectangle">
|
||||||
<solid android:color="?androidprv:attr/colorSurface"/>
|
<solid android:color="?androidprv:attr/colorSurface"/>
|
||||||
<size
|
<size
|
||||||
android:width="@dimen/keyguard_affordance_width"
|
android:width="@dimen/keyguard_affordance_width"
|
||||||
android:height="@dimen/keyguard_affordance_height"/>
|
android:height="@dimen/keyguard_affordance_height"/>
|
||||||
|
<corners android:radius="@dimen/keyguard_affordance_fixed_radius"/>
|
||||||
</shape>
|
</shape>
|
||||||
</item>
|
</item>
|
||||||
</ripple>
|
</ripple>
|
||||||
|
|||||||
@@ -918,6 +918,7 @@
|
|||||||
|
|
||||||
<dimen name="keyguard_affordance_fixed_height">48dp</dimen>
|
<dimen name="keyguard_affordance_fixed_height">48dp</dimen>
|
||||||
<dimen name="keyguard_affordance_fixed_width">48dp</dimen>
|
<dimen name="keyguard_affordance_fixed_width">48dp</dimen>
|
||||||
|
<dimen name="keyguard_affordance_fixed_radius">24dp</dimen>
|
||||||
|
|
||||||
<dimen name="keyguard_affordance_horizontal_offset">32dp</dimen>
|
<dimen name="keyguard_affordance_horizontal_offset">32dp</dimen>
|
||||||
<dimen name="keyguard_affordance_vertical_offset">32dp</dimen>
|
<dimen name="keyguard_affordance_vertical_offset">32dp</dimen>
|
||||||
|
|||||||
@@ -92,9 +92,11 @@ public class ActivityStarterDelegate implements ActivityStarter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startActivity(Intent intent, boolean dismissShade,
|
public void startActivity(Intent intent, boolean dismissShade,
|
||||||
@Nullable ActivityLaunchAnimator.Controller animationController) {
|
@Nullable ActivityLaunchAnimator.Controller animationController,
|
||||||
|
boolean showOverLockscreenWhenLocked) {
|
||||||
mActualStarterOptionalLazy.get().ifPresent(
|
mActualStarterOptionalLazy.get().ifPresent(
|
||||||
starter -> starter.startActivity(intent, dismissShade, animationController));
|
starter -> starter.startActivity(intent, dismissShade, animationController,
|
||||||
|
showOverLockscreenWhenLocked));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -131,22 +131,16 @@ public class QuickAccessWalletTile extends QSTileImpl<QSTile.State> {
|
|||||||
Intent intent = new Intent(mContext, WalletActivity.class)
|
Intent intent = new Intent(mContext, WalletActivity.class)
|
||||||
.setAction(Intent.ACTION_VIEW)
|
.setAction(Intent.ACTION_VIEW)
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
if (mKeyguardStateController.isUnlocked()) {
|
mActivityStarter.startActivity(intent, true /* dismissShade */,
|
||||||
mActivityStarter.startActivity(intent, true /* dismissShade */,
|
animationController, true /* showOverLockscreenWhenLocked */);
|
||||||
animationController);
|
|
||||||
} else {
|
|
||||||
mHost.collapsePanels();
|
|
||||||
// Do not use ActivityStarter here because the WalletActivity is required to be
|
|
||||||
// started without prompting keyguard when the device is locked.
|
|
||||||
mContext.startActivity(intent);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (mController.getWalletClient().createWalletIntent() == null) {
|
Intent intent = mController.getWalletClient().createWalletIntent();
|
||||||
|
if (intent == null) {
|
||||||
Log.w(TAG, "Could not get intent of the wallet app.");
|
Log.w(TAG, "Could not get intent of the wallet app.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mActivityStarter.postStartActivityDismissingKeyguard(
|
mActivityStarter.postStartActivityDismissingKeyguard(
|
||||||
mController.getWalletClient().createWalletIntent(),
|
intent,
|
||||||
/* delay= */ 0,
|
/* delay= */ 0,
|
||||||
animationController);
|
animationController);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ import com.android.settingslib.Utils;
|
|||||||
import com.android.systemui.ActivityIntentHelper;
|
import com.android.systemui.ActivityIntentHelper;
|
||||||
import com.android.systemui.Dependency;
|
import com.android.systemui.Dependency;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
|
import com.android.systemui.animation.ActivityLaunchAnimator;
|
||||||
import com.android.systemui.animation.Interpolators;
|
import com.android.systemui.animation.Interpolators;
|
||||||
import com.android.systemui.assist.AssistManager;
|
import com.android.systemui.assist.AssistManager;
|
||||||
import com.android.systemui.camera.CameraIntents;
|
import com.android.systemui.camera.CameraIntents;
|
||||||
@@ -1044,11 +1045,13 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ActivityLaunchAnimator.Controller animationController = createLaunchAnimationController(v);
|
||||||
if (mHasCard) {
|
if (mHasCard) {
|
||||||
Intent intent = new Intent(mContext, WalletActivity.class)
|
Intent intent = new Intent(mContext, WalletActivity.class)
|
||||||
.setAction(Intent.ACTION_VIEW)
|
.setAction(Intent.ACTION_VIEW)
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
mContext.startActivity(intent);
|
mActivityStarter.startActivity(intent, true /* dismissShade */, animationController,
|
||||||
|
true /* showOverLockscreenWhenLocked */);
|
||||||
} else {
|
} else {
|
||||||
if (mQuickAccessWalletController.getWalletClient().createWalletIntent() == null) {
|
if (mQuickAccessWalletController.getWalletClient().createWalletIntent() == null) {
|
||||||
Log.w(TAG, "Could not get intent of the wallet app.");
|
Log.w(TAG, "Could not get intent of the wallet app.");
|
||||||
@@ -1056,10 +1059,14 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
|||||||
}
|
}
|
||||||
mActivityStarter.postStartActivityDismissingKeyguard(
|
mActivityStarter.postStartActivityDismissingKeyguard(
|
||||||
mQuickAccessWalletController.getWalletClient().createWalletIntent(),
|
mQuickAccessWalletController.getWalletClient().createWalletIntent(),
|
||||||
/* delay= */ 0);
|
/* delay= */ 0, animationController);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected ActivityLaunchAnimator.Controller createLaunchAnimationController(View view) {
|
||||||
|
return ActivityLaunchAnimator.Controller.fromView(view, null);
|
||||||
|
}
|
||||||
|
|
||||||
private void onControlsClick(View v) {
|
private void onControlsClick(View v) {
|
||||||
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -672,6 +672,13 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
|
|||||||
mNotificationsTint = mState.getNotifTint();
|
mNotificationsTint = mState.getNotifTint();
|
||||||
mBehindTint = behindTint;
|
mBehindTint = behindTint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// At the end of a launch animation over the lockscreen, the state is either KEYGUARD or
|
||||||
|
// SHADE_LOCKED and this code is called. We have to set the notification alpha to 0
|
||||||
|
// otherwise there is a flicker to its previous value.
|
||||||
|
if (mKeyguardOccluded) {
|
||||||
|
mNotificationsAlpha = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assertAlphasValid();
|
assertAlphasValid();
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ import android.app.NotificationManager;
|
|||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.StatusBarManager;
|
import android.app.StatusBarManager;
|
||||||
import android.app.TaskInfo;
|
import android.app.TaskInfo;
|
||||||
|
import android.app.TaskStackBuilder;
|
||||||
import android.app.UiModeManager;
|
import android.app.UiModeManager;
|
||||||
import android.app.WallpaperInfo;
|
import android.app.WallpaperInfo;
|
||||||
import android.app.WallpaperManager;
|
import android.app.WallpaperManager;
|
||||||
@@ -644,6 +645,7 @@ public class StatusBar extends SystemUI implements
|
|||||||
private boolean mIsOccluded;
|
private boolean mIsOccluded;
|
||||||
private boolean mWereIconsJustHidden;
|
private boolean mWereIconsJustHidden;
|
||||||
private boolean mBouncerWasShowingWhenHidden;
|
private boolean mBouncerWasShowingWhenHidden;
|
||||||
|
private boolean mIsLaunchingActivityOverLockscreen;
|
||||||
|
|
||||||
private final UserSwitcherController mUserSwitcherController;
|
private final UserSwitcherController mUserSwitcherController;
|
||||||
private final NetworkController mNetworkController;
|
private final NetworkController mNetworkController;
|
||||||
@@ -1728,10 +1730,77 @@ public class StatusBar extends SystemUI implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startActivity(Intent intent, boolean dismissShade,
|
public void startActivity(Intent intent, boolean dismissShade,
|
||||||
ActivityLaunchAnimator.Controller animationController) {
|
@Nullable ActivityLaunchAnimator.Controller animationController,
|
||||||
startActivityDismissingKeyguard(intent, false, dismissShade,
|
boolean showOverLockscreenWhenLocked) {
|
||||||
|
// Make sure that we dismiss the keyguard if it is directly dismissable or when we don't
|
||||||
|
// want to show the activity above it.
|
||||||
|
if (mKeyguardStateController.isUnlocked() || !showOverLockscreenWhenLocked) {
|
||||||
|
startActivityDismissingKeyguard(intent, false, dismissShade,
|
||||||
false /* disallowEnterPictureInPictureWhileLaunching */, null /* callback */,
|
false /* disallowEnterPictureInPictureWhileLaunching */, null /* callback */,
|
||||||
0 /* flags */, animationController);
|
0 /* flags */, animationController);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean animate =
|
||||||
|
animationController != null && shouldAnimateLaunch(true /* isActivityIntent */,
|
||||||
|
showOverLockscreenWhenLocked);
|
||||||
|
|
||||||
|
ActivityLaunchAnimator.Controller controller = null;
|
||||||
|
if (animate) {
|
||||||
|
// Wrap the animation controller to dismiss the shade and set
|
||||||
|
// mIsLaunchingActivityOverLockscreen during the animation.
|
||||||
|
ActivityLaunchAnimator.Controller delegate = wrapAnimationController(
|
||||||
|
animationController, dismissShade);
|
||||||
|
controller = new DelegateLaunchAnimatorController(delegate) {
|
||||||
|
@Override
|
||||||
|
public void onIntentStarted(boolean willAnimate) {
|
||||||
|
getDelegate().onIntentStarted(willAnimate);
|
||||||
|
|
||||||
|
if (willAnimate) {
|
||||||
|
StatusBar.this.mIsLaunchingActivityOverLockscreen = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLaunchAnimationEnd(boolean isExpandingFullyAbove) {
|
||||||
|
// Set mIsLaunchingActivityOverLockscreen to false before actually finishing the
|
||||||
|
// animation so that we can assume that mIsLaunchingActivityOverLockscreen
|
||||||
|
// being true means that we will collapse the shade (or at least run the
|
||||||
|
// post collapse runnables) later on.
|
||||||
|
StatusBar.this.mIsLaunchingActivityOverLockscreen = false;
|
||||||
|
getDelegate().onLaunchAnimationEnd(isExpandingFullyAbove);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLaunchAnimationCancelled() {
|
||||||
|
// Set mIsLaunchingActivityOverLockscreen to false before actually finishing the
|
||||||
|
// animation so that we can assume that mIsLaunchingActivityOverLockscreen
|
||||||
|
// being true means that we will collapse the shade (or at least run the
|
||||||
|
// post collapse runnables) later on.
|
||||||
|
StatusBar.this.mIsLaunchingActivityOverLockscreen = false;
|
||||||
|
getDelegate().onLaunchAnimationCancelled();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else if (dismissShade) {
|
||||||
|
// The animation will take care of dismissing the shade at the end of the animation. If
|
||||||
|
// we don't animate, collapse it directly.
|
||||||
|
collapseShade();
|
||||||
|
}
|
||||||
|
|
||||||
|
mActivityLaunchAnimator.startIntentWithAnimation(controller, animate,
|
||||||
|
intent.getPackage(), showOverLockscreenWhenLocked, (adapter) -> TaskStackBuilder
|
||||||
|
.create(mContext)
|
||||||
|
.addNextIntent(intent)
|
||||||
|
.startActivities(getActivityOptions(getDisplayId(), adapter),
|
||||||
|
UserHandle.CURRENT));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether we are currently animating an activity launch above the lockscreen (occluding
|
||||||
|
* activity).
|
||||||
|
*/
|
||||||
|
public boolean isLaunchingActivityOverLockscreen() {
|
||||||
|
return mIsLaunchingActivityOverLockscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1892,23 +1961,30 @@ public class StatusBar extends SystemUI implements
|
|||||||
*
|
*
|
||||||
* Note: This method must be called *before* dismissing the keyguard.
|
* Note: This method must be called *before* dismissing the keyguard.
|
||||||
*/
|
*/
|
||||||
public boolean shouldAnimateLaunch(boolean isActivityIntent) {
|
public boolean shouldAnimateLaunch(boolean isActivityIntent, boolean showOverLockscreen) {
|
||||||
// TODO(b/184121838): Support launch animations when occluded.
|
// TODO(b/184121838): Support launch animations when occluded.
|
||||||
if (isOccluded()) {
|
if (isOccluded()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always animate if we are unlocked.
|
// Always animate if we are not showing the keyguard or if we animate over the lockscreen
|
||||||
if (!mKeyguardStateController.isShowing()) {
|
// (without unlocking it).
|
||||||
|
if (showOverLockscreen || !mKeyguardStateController.isShowing()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are locked, only animate if remote unlock animations are enabled. We also don't
|
// If we are locked and have to dismiss the keyguard, only animate if remote unlock
|
||||||
// animate non-activity launches as they can break the animation.
|
// animations are enabled. We also don't animate non-activity launches as they can break the
|
||||||
|
// animation.
|
||||||
// TODO(b/184121838): Support non activity launches on the lockscreen.
|
// TODO(b/184121838): Support non activity launches on the lockscreen.
|
||||||
return isActivityIntent && KeyguardService.sEnableRemoteKeyguardGoingAwayAnimation;
|
return isActivityIntent && KeyguardService.sEnableRemoteKeyguardGoingAwayAnimation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Whether we should animate an activity launch. */
|
||||||
|
public boolean shouldAnimateLaunch(boolean isActivityIntent) {
|
||||||
|
return shouldAnimateLaunch(isActivityIntent, false /* showOverLockscreen */);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isDeviceInVrMode() {
|
public boolean isDeviceInVrMode() {
|
||||||
return mPresenter.isDeviceInVrMode();
|
return mPresenter.isDeviceInVrMode();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ import java.util.Optional;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.Lazy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages creating, showing, hiding and resetting the keyguard within the status bar. Calls back
|
* Manages creating, showing, hiding and resetting the keyguard within the status bar. Calls back
|
||||||
* via {@link ViewMediatorCallback} to poke the wake lock and report that the keyguard is done,
|
* via {@link ViewMediatorCallback} to poke the wake lock and report that the keyguard is done,
|
||||||
@@ -111,6 +113,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
|||||||
private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
|
private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
|
||||||
private final KeyguardMessageAreaController.Factory mKeyguardMessageAreaFactory;
|
private final KeyguardMessageAreaController.Factory mKeyguardMessageAreaFactory;
|
||||||
private KeyguardMessageAreaController mKeyguardMessageAreaController;
|
private KeyguardMessageAreaController mKeyguardMessageAreaController;
|
||||||
|
private final Lazy<ShadeController> mShadeController;
|
||||||
private final BouncerExpansionCallback mExpansionCallback = new BouncerExpansionCallback() {
|
private final BouncerExpansionCallback mExpansionCallback = new BouncerExpansionCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onFullyShown() {
|
public void onFullyShown() {
|
||||||
@@ -243,7 +246,8 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
|||||||
KeyguardBouncer.Factory keyguardBouncerFactory,
|
KeyguardBouncer.Factory keyguardBouncerFactory,
|
||||||
WakefulnessLifecycle wakefulnessLifecycle,
|
WakefulnessLifecycle wakefulnessLifecycle,
|
||||||
UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
|
UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
|
||||||
KeyguardMessageAreaController.Factory keyguardMessageAreaFactory) {
|
KeyguardMessageAreaController.Factory keyguardMessageAreaFactory,
|
||||||
|
Lazy<ShadeController> shadeController) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mViewMediatorCallback = callback;
|
mViewMediatorCallback = callback;
|
||||||
mLockPatternUtils = lockPatternUtils;
|
mLockPatternUtils = lockPatternUtils;
|
||||||
@@ -260,6 +264,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
|||||||
mWakefulnessLifecycle = wakefulnessLifecycle;
|
mWakefulnessLifecycle = wakefulnessLifecycle;
|
||||||
mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
|
mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
|
||||||
mKeyguardMessageAreaFactory = keyguardMessageAreaFactory;
|
mKeyguardMessageAreaFactory = keyguardMessageAreaFactory;
|
||||||
|
mShadeController = shadeController;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -634,6 +639,18 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mStatusBar.isLaunchingActivityOverLockscreen()) {
|
||||||
|
mOccluded = true;
|
||||||
|
|
||||||
|
// When isLaunchingActivityOverLockscreen() is true, we know for sure that the post
|
||||||
|
// collapse runnables will be run.
|
||||||
|
mShadeController.get().addPostCollapseAction(() -> {
|
||||||
|
mNotificationShadeWindowController.setKeyguardOccluded(mOccluded);
|
||||||
|
reset(true /* hideBouncerWhenShowing */);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else if (!occluded && mOccluded && mShowing) {
|
} else if (!occluded && mOccluded && mShowing) {
|
||||||
SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_STATE_CHANGED,
|
SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_STATE_CHANGED,
|
||||||
SysUiStatsLog.KEYGUARD_STATE_CHANGED__STATE__SHOWN);
|
SysUiStatsLog.KEYGUARD_STATE_CHANGED__STATE__SHOWN);
|
||||||
|
|||||||
@@ -228,7 +228,9 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
|
|||||||
mTile.handleClick(null /* view */);
|
mTile.handleClick(null /* view */);
|
||||||
mTestableLooper.processAllMessages();
|
mTestableLooper.processAllMessages();
|
||||||
|
|
||||||
verify(mSpiedContext).startActivity(mIntentCaptor.capture());
|
verify(mActivityStarter).startActivity(mIntentCaptor.capture(), eq(true) /* dismissShade */,
|
||||||
|
(ActivityLaunchAnimator.Controller) eq(null),
|
||||||
|
eq(true) /* showOverLockscreenWhenLocked */);
|
||||||
|
|
||||||
Intent nextStartedIntent = mIntentCaptor.getValue();
|
Intent nextStartedIntent = mIntentCaptor.getValue();
|
||||||
String walletClassName = "com.android.systemui.wallet.ui.WalletActivity";
|
String walletClassName = "com.android.systemui.wallet.ui.WalletActivity";
|
||||||
@@ -246,7 +248,8 @@ public class QuickAccessWalletTileTest extends SysuiTestCase {
|
|||||||
mTestableLooper.processAllMessages();
|
mTestableLooper.processAllMessages();
|
||||||
|
|
||||||
verify(mActivityStarter).startActivity(mIntentCaptor.capture(), eq(true) /* dismissShade */,
|
verify(mActivityStarter).startActivity(mIntentCaptor.capture(), eq(true) /* dismissShade */,
|
||||||
(ActivityLaunchAnimator.Controller) eq(null));
|
(ActivityLaunchAnimator.Controller) eq(null),
|
||||||
|
eq(true) /* showOverLockscreenWhenLocked */);
|
||||||
|
|
||||||
Intent nextStartedIntent = mIntentCaptor.getValue();
|
Intent nextStartedIntent = mIntentCaptor.getValue();
|
||||||
String walletClassName = "com.android.systemui.wallet.ui.WalletActivity";
|
String walletClassName = "com.android.systemui.wallet.ui.WalletActivity";
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ import org.mockito.MockitoAnnotations;
|
|||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import dagger.Lazy;
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidTestingRunner.class)
|
@RunWith(AndroidTestingRunner.class)
|
||||||
@TestableLooper.RunWithLooper
|
@TestableLooper.RunWithLooper
|
||||||
@@ -103,6 +105,8 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
|
|||||||
private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
|
private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
|
||||||
@Mock
|
@Mock
|
||||||
private KeyguardMessageArea mKeyguardMessageArea;
|
private KeyguardMessageArea mKeyguardMessageArea;
|
||||||
|
@Mock
|
||||||
|
private Lazy<ShadeController> mShadeController;
|
||||||
|
|
||||||
private WakefulnessLifecycle mWakefulnessLifecycle;
|
private WakefulnessLifecycle mWakefulnessLifecycle;
|
||||||
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
||||||
@@ -133,7 +137,8 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
|
|||||||
mKeyguardBouncerFactory,
|
mKeyguardBouncerFactory,
|
||||||
mWakefulnessLifecycle,
|
mWakefulnessLifecycle,
|
||||||
mUnlockedScreenOffAnimationController,
|
mUnlockedScreenOffAnimationController,
|
||||||
mKeyguardMessageAreaFactory);
|
mKeyguardMessageAreaFactory,
|
||||||
|
mShadeController);
|
||||||
mStatusBarKeyguardViewManager.registerStatusBar(mStatusBar, mContainer,
|
mStatusBarKeyguardViewManager.registerStatusBar(mStatusBar, mContainer,
|
||||||
mNotificationPanelView, mBiometrucUnlockController,
|
mNotificationPanelView, mBiometrucUnlockController,
|
||||||
mNotificationContainer, mBypassController);
|
mNotificationContainer, mBypassController);
|
||||||
|
|||||||
Reference in New Issue
Block a user