Fix bouncer to launcher/app animation
This CL ensures that we don't show the keyguard early when unlocking the phone from the bouncer after swiping up on the lockscreen. Bug: 191031464 Test: Manual, swipe up on lockscreen with PIN Change-Id: Id7269189c857e1108a8e33074bb5abfd40437deb
This commit is contained in:
@@ -92,5 +92,12 @@ public interface ActivityStarter {
|
||||
* *after* returning to start hiding the keyguard.
|
||||
*/
|
||||
boolean onDismiss();
|
||||
|
||||
/**
|
||||
* Whether running this action when we are locked will start an animation on the keyguard.
|
||||
*/
|
||||
default boolean willRunAnimationOnKeyguard() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2841,9 +2841,11 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mActivityIntentHelper.wouldLaunchResolverActivity(intent,
|
||||
mLockscreenUserManager.getCurrentUserId());
|
||||
|
||||
boolean animate =
|
||||
animationController != null && !willLaunchResolverActivity && shouldAnimateLaunch(
|
||||
true /* isActivityIntent */);
|
||||
ActivityLaunchAnimator.Controller animController =
|
||||
!willLaunchResolverActivity && shouldAnimateLaunch(true /* isActivityIntent */)
|
||||
? wrapAnimationController(animationController, dismissShade) : null;
|
||||
animate ? wrapAnimationController(animationController, dismissShade) : null;
|
||||
|
||||
// If we animate, we will dismiss the shade only once the animation is done. This is taken
|
||||
// care of by the StatusBarLaunchAnimationController.
|
||||
@@ -2857,7 +2859,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
int[] result = new int[]{ActivityManager.START_CANCELED};
|
||||
|
||||
mActivityLaunchAnimator.startIntentWithAnimation(animController,
|
||||
true /* animate */, intent.getPackage(), (adapter) -> {
|
||||
animate, intent.getPackage(), (adapter) -> {
|
||||
ActivityOptions options = new ActivityOptions(
|
||||
getActivityOptions(mDisplayId, adapter));
|
||||
options.setDisallowEnterPictureInPictureWhileLaunching(
|
||||
@@ -2907,16 +2909,12 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
}
|
||||
};
|
||||
executeRunnableDismissingKeyguard(runnable, cancelRunnable, dismissShadeDirectly,
|
||||
willLaunchResolverActivity, true /* deferred */);
|
||||
willLaunchResolverActivity, true /* deferred */, animate);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ActivityLaunchAnimator.Controller wrapAnimationController(
|
||||
@Nullable ActivityLaunchAnimator.Controller animationController, boolean dismissShade) {
|
||||
if (animationController == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ActivityLaunchAnimator.Controller animationController, boolean dismissShade) {
|
||||
View rootView = animationController.getLaunchContainer().getRootView();
|
||||
if (rootView == mSuperStatusBarViewFactory.getStatusBarWindowView()) {
|
||||
// We are animating a view in the status bar. We have to make sure that the status bar
|
||||
@@ -2959,34 +2957,56 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
final boolean dismissShade,
|
||||
final boolean afterKeyguardGone,
|
||||
final boolean deferred) {
|
||||
dismissKeyguardThenExecute(() -> {
|
||||
if (runnable != null) {
|
||||
if (mStatusBarKeyguardViewManager.isShowing()
|
||||
&& mStatusBarKeyguardViewManager.isOccluded()) {
|
||||
mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(runnable);
|
||||
} else {
|
||||
AsyncTask.execute(runnable);
|
||||
}
|
||||
}
|
||||
if (dismissShade) {
|
||||
if (mExpandedVisible && !mBouncerShowing) {
|
||||
mShadeController.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
|
||||
true /* force */, true /* delayed*/);
|
||||
} else {
|
||||
executeRunnableDismissingKeyguard(runnable, cancelAction, dismissShade, afterKeyguardGone,
|
||||
deferred, false /* willAnimateOnKeyguard */);
|
||||
}
|
||||
|
||||
// Do it after DismissAction has been processed to conserve the needed ordering.
|
||||
mHandler.post(mShadeController::runPostCollapseRunnables);
|
||||
public void executeRunnableDismissingKeyguard(final Runnable runnable,
|
||||
final Runnable cancelAction,
|
||||
final boolean dismissShade,
|
||||
final boolean afterKeyguardGone,
|
||||
final boolean deferred,
|
||||
final boolean willAnimateOnKeyguard) {
|
||||
OnDismissAction onDismissAction = new OnDismissAction() {
|
||||
@Override
|
||||
public boolean onDismiss() {
|
||||
if (runnable != null) {
|
||||
if (mStatusBarKeyguardViewManager.isShowing()
|
||||
&& mStatusBarKeyguardViewManager.isOccluded()) {
|
||||
mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(runnable);
|
||||
} else {
|
||||
AsyncTask.execute(runnable);
|
||||
}
|
||||
}
|
||||
} else if (isInLaunchTransition()
|
||||
&& mNotificationPanelViewController.isLaunchTransitionFinished()) {
|
||||
if (dismissShade) {
|
||||
if (mExpandedVisible && !mBouncerShowing) {
|
||||
mShadeController.animateCollapsePanels(
|
||||
CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
|
||||
true /* force */, true /* delayed*/);
|
||||
} else {
|
||||
|
||||
// We are not dismissing the shade, but the launch transition is already finished,
|
||||
// so nobody will call readyForKeyguardDone anymore. Post it such that
|
||||
// keyguardDonePending gets called first.
|
||||
mHandler.post(mStatusBarKeyguardViewManager::readyForKeyguardDone);
|
||||
// Do it after DismissAction has been processed to conserve the needed
|
||||
// ordering.
|
||||
mHandler.post(mShadeController::runPostCollapseRunnables);
|
||||
}
|
||||
} else if (StatusBar.this.isInLaunchTransition()
|
||||
&& mNotificationPanelViewController.isLaunchTransitionFinished()) {
|
||||
|
||||
// We are not dismissing the shade, but the launch transition is already
|
||||
// finished,
|
||||
// so nobody will call readyForKeyguardDone anymore. Post it such that
|
||||
// keyguardDonePending gets called first.
|
||||
mHandler.post(mStatusBarKeyguardViewManager::readyForKeyguardDone);
|
||||
}
|
||||
return deferred;
|
||||
}
|
||||
return deferred;
|
||||
}, cancelAction, afterKeyguardGone);
|
||||
|
||||
@Override
|
||||
public boolean willRunAnimationOnKeyguard() {
|
||||
return willAnimateOnKeyguard;
|
||||
}
|
||||
};
|
||||
dismissKeyguardThenExecute(onDismissAction, cancelAction, afterKeyguardGone);
|
||||
}
|
||||
|
||||
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
|
||||
@@ -4609,28 +4629,37 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
*
|
||||
* @param action The action to execute after dismissing the keyguard.
|
||||
* @param collapsePanel Whether we should collapse the panel after dismissing the keyguard.
|
||||
* @param deferKeyguardDismiss Whether we should defer the keyguard actual dismissal, for
|
||||
* instance to run animations on the keyguard before hiding it.
|
||||
* @param willAnimateOnKeyguard Whether {@param action} will run an animation on the keyguard if
|
||||
* we are locked.
|
||||
*/
|
||||
private void executeActionDismissingKeyguard(Runnable action, boolean afterKeyguardGone,
|
||||
boolean collapsePanel, boolean deferKeyguardDismiss) {
|
||||
boolean collapsePanel, boolean willAnimateOnKeyguard) {
|
||||
if (!mDeviceProvisionedController.isDeviceProvisioned()) return;
|
||||
|
||||
dismissKeyguardThenExecute(() -> {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
// The intent we are sending is for the application, which
|
||||
// won't have permission to immediately start an activity after
|
||||
// the user switches to home. We know it is safe to do at this
|
||||
// point, so make sure new activity switches are now allowed.
|
||||
ActivityManager.getService().resumeAppSwitches();
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
action.run();
|
||||
}).start();
|
||||
OnDismissAction onDismissAction = new OnDismissAction() {
|
||||
@Override
|
||||
public boolean onDismiss() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
// The intent we are sending is for the application, which
|
||||
// won't have permission to immediately start an activity after
|
||||
// the user switches to home. We know it is safe to do at this
|
||||
// point, so make sure new activity switches are now allowed.
|
||||
ActivityManager.getService().resumeAppSwitches();
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
action.run();
|
||||
}).start();
|
||||
|
||||
return collapsePanel ? mShadeController.collapsePanel() : deferKeyguardDismiss;
|
||||
}, afterKeyguardGone);
|
||||
return collapsePanel ? mShadeController.collapsePanel() : willAnimateOnKeyguard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willRunAnimationOnKeyguard() {
|
||||
return willAnimateOnKeyguard;
|
||||
}
|
||||
};
|
||||
dismissKeyguardThenExecute(onDismissAction, afterKeyguardGone);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -4674,7 +4703,6 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
// the animation on the keyguard). The animation will take care of (instantly) collapsing
|
||||
// the shade and hiding the keyguard once it is done.
|
||||
boolean collapse = !animate;
|
||||
boolean deferKeyguardDismiss = animate;
|
||||
executeActionDismissingKeyguard(() -> {
|
||||
try {
|
||||
// We wrap animationCallback with a StatusBarLaunchAnimatorController so that the
|
||||
@@ -4703,7 +4731,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
if (intentSentUiThreadCallback != null) {
|
||||
postOnUiThread(intentSentUiThreadCallback);
|
||||
}
|
||||
}, willLaunchResolverActivity, collapse, deferKeyguardDismiss);
|
||||
}, willLaunchResolverActivity, collapse, animate);
|
||||
}
|
||||
|
||||
private void postOnUiThread(Runnable runnable) {
|
||||
|
||||
@@ -192,6 +192,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
|
||||
private OnDismissAction mAfterKeyguardGoneAction;
|
||||
private Runnable mKeyguardGoneCancelAction;
|
||||
private boolean mDismissActionWillAnimateOnKeyguard;
|
||||
private final ArrayList<Runnable> mAfterKeyguardGoneRunnables = new ArrayList<>();
|
||||
|
||||
// Dismiss action to be launched when we stop dozing or the keyguard is gone.
|
||||
@@ -447,6 +448,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
|
||||
mAfterKeyguardGoneAction = r;
|
||||
mKeyguardGoneCancelAction = cancelAction;
|
||||
mDismissActionWillAnimateOnKeyguard = r != null && r.willRunAnimationOnKeyguard();
|
||||
|
||||
// If there is an an alternate auth interceptor (like the UDFPS), show that one instead
|
||||
// of the bouncer.
|
||||
@@ -625,9 +627,12 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
mBouncer.startPreHideAnimation(finishRunnable);
|
||||
mStatusBar.onBouncerPreHideAnimation();
|
||||
|
||||
// startPreHideAnimation() will change the visibility of the bouncer, so we have to
|
||||
// make sure to update its state.
|
||||
updateStates();
|
||||
// We update the state (which will show the keyguard) only if an animation will run on
|
||||
// the keyguard. If there is no animation, we wait before updating the state so that we
|
||||
// go directly from bouncer to launcher/app.
|
||||
if (mDismissActionWillAnimateOnKeyguard) {
|
||||
updateStates();
|
||||
}
|
||||
} else if (finishRunnable != null) {
|
||||
finishRunnable.run();
|
||||
}
|
||||
@@ -798,6 +803,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
mAfterKeyguardGoneAction = null;
|
||||
}
|
||||
mKeyguardGoneCancelAction = null;
|
||||
mDismissActionWillAnimateOnKeyguard = false;
|
||||
for (int i = 0; i < mAfterKeyguardGoneRunnables.size(); i++) {
|
||||
mAfterKeyguardGoneRunnables.get(i).run();
|
||||
}
|
||||
@@ -866,6 +872,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
return; // allow bouncer to trigger saved actions
|
||||
}
|
||||
mAfterKeyguardGoneAction = null;
|
||||
mDismissActionWillAnimateOnKeyguard = false;
|
||||
if (mKeyguardGoneCancelAction != null) {
|
||||
mKeyguardGoneCancelAction.run();
|
||||
mKeyguardGoneCancelAction = null;
|
||||
|
||||
@@ -260,10 +260,19 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
|
||||
boolean showOverLockscreen = mKeyguardStateController.isShowing() && intent != null
|
||||
&& mActivityIntentHelper.wouldShowOverLockscreen(intent.getIntent(),
|
||||
mLockscreenUserManager.getCurrentUserId());
|
||||
ActivityStarter.OnDismissAction postKeyguardAction =
|
||||
() -> handleNotificationClickAfterKeyguardDismissed(
|
||||
ActivityStarter.OnDismissAction postKeyguardAction = new ActivityStarter.OnDismissAction() {
|
||||
@Override
|
||||
public boolean onDismiss() {
|
||||
return handleNotificationClickAfterKeyguardDismissed(
|
||||
entry, row, controller, intent,
|
||||
isActivityIntent, animate, showOverLockscreen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willRunAnimationOnKeyguard() {
|
||||
return animate;
|
||||
}
|
||||
};
|
||||
if (showOverLockscreen) {
|
||||
mIsCollapsingToShowActivityOverLockscreen = true;
|
||||
postKeyguardAction.onDismiss();
|
||||
@@ -453,53 +462,73 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
|
||||
public void startNotificationGutsIntent(final Intent intent, final int appUid,
|
||||
ExpandableNotificationRow row) {
|
||||
boolean animate = mStatusBar.shouldAnimateLaunch(true /* isActivityIntent */);
|
||||
mActivityStarter.dismissKeyguardThenExecute(() -> {
|
||||
AsyncTask.execute(() -> {
|
||||
ActivityLaunchAnimator.Controller animationController =
|
||||
new StatusBarLaunchAnimatorController(
|
||||
mNotificationAnimationProvider.getAnimatorController(row),
|
||||
mStatusBar, true /* isActivityIntent */);
|
||||
ActivityStarter.OnDismissAction onDismissAction = new ActivityStarter.OnDismissAction() {
|
||||
@Override
|
||||
public boolean onDismiss() {
|
||||
AsyncTask.execute(() -> {
|
||||
ActivityLaunchAnimator.Controller animationController =
|
||||
new StatusBarLaunchAnimatorController(
|
||||
mNotificationAnimationProvider.getAnimatorController(row),
|
||||
mStatusBar, true /* isActivityIntent */);
|
||||
|
||||
mActivityLaunchAnimator.startIntentWithAnimation(
|
||||
animationController, animate, intent.getPackage(),
|
||||
(adapter) -> TaskStackBuilder.create(mContext)
|
||||
.addNextIntentWithParentStack(intent)
|
||||
.startActivities(getActivityOptions(
|
||||
mStatusBar.getDisplayId(),
|
||||
adapter),
|
||||
new UserHandle(UserHandle.getUserId(appUid))));
|
||||
});
|
||||
return true;
|
||||
}, null, false /* afterKeyguardGone */);
|
||||
mActivityLaunchAnimator.startIntentWithAnimation(
|
||||
animationController, animate, intent.getPackage(),
|
||||
(adapter) -> TaskStackBuilder.create(mContext)
|
||||
.addNextIntentWithParentStack(intent)
|
||||
.startActivities(getActivityOptions(
|
||||
mStatusBar.getDisplayId(),
|
||||
adapter),
|
||||
new UserHandle(UserHandle.getUserId(appUid))));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willRunAnimationOnKeyguard() {
|
||||
return animate;
|
||||
}
|
||||
};
|
||||
mActivityStarter.dismissKeyguardThenExecute(onDismissAction, null,
|
||||
false /* afterKeyguardGone */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startHistoryIntent(View view, boolean showHistory) {
|
||||
boolean animate = mStatusBar.shouldAnimateLaunch(true /* isActivityIntent */);
|
||||
mActivityStarter.dismissKeyguardThenExecute(() -> {
|
||||
AsyncTask.execute(() -> {
|
||||
Intent intent = showHistory ? new Intent(
|
||||
Settings.ACTION_NOTIFICATION_HISTORY) : new Intent(
|
||||
Settings.ACTION_NOTIFICATION_SETTINGS);
|
||||
TaskStackBuilder tsb = TaskStackBuilder.create(mContext)
|
||||
.addNextIntent(new Intent(Settings.ACTION_NOTIFICATION_SETTINGS));
|
||||
if (showHistory) {
|
||||
tsb.addNextIntent(intent);
|
||||
}
|
||||
ActivityStarter.OnDismissAction onDismissAction = new ActivityStarter.OnDismissAction() {
|
||||
@Override
|
||||
public boolean onDismiss() {
|
||||
AsyncTask.execute(() -> {
|
||||
Intent intent = showHistory ? new Intent(
|
||||
Settings.ACTION_NOTIFICATION_HISTORY) : new Intent(
|
||||
Settings.ACTION_NOTIFICATION_SETTINGS);
|
||||
TaskStackBuilder tsb = TaskStackBuilder.create(mContext)
|
||||
.addNextIntent(new Intent(Settings.ACTION_NOTIFICATION_SETTINGS));
|
||||
if (showHistory) {
|
||||
tsb.addNextIntent(intent);
|
||||
}
|
||||
|
||||
ActivityLaunchAnimator.Controller animationController =
|
||||
new StatusBarLaunchAnimatorController(
|
||||
ActivityLaunchAnimator.Controller.fromView(view), mStatusBar,
|
||||
true /* isActivityIntent */);
|
||||
ActivityLaunchAnimator.Controller animationController =
|
||||
new StatusBarLaunchAnimatorController(
|
||||
ActivityLaunchAnimator.Controller.fromView(view), mStatusBar,
|
||||
true /* isActivityIntent */);
|
||||
|
||||
mActivityLaunchAnimator.startIntentWithAnimation(animationController, animate,
|
||||
intent.getPackage(),
|
||||
(adapter) -> tsb.startActivities(
|
||||
getActivityOptions(mStatusBar.getDisplayId(), adapter),
|
||||
UserHandle.CURRENT));
|
||||
});
|
||||
return true;
|
||||
}, null, false /* afterKeyguardGone */);
|
||||
mActivityLaunchAnimator.startIntentWithAnimation(animationController, animate,
|
||||
intent.getPackage(),
|
||||
(adapter) -> tsb.startActivities(
|
||||
getActivityOptions(mStatusBar.getDisplayId(), adapter),
|
||||
UserHandle.CURRENT));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willRunAnimationOnKeyguard() {
|
||||
return animate;
|
||||
}
|
||||
};
|
||||
mActivityStarter.dismissKeyguardThenExecute(onDismissAction, null,
|
||||
false /* afterKeyguardGone */);
|
||||
}
|
||||
|
||||
private void removeHunAfterClick(ExpandableNotificationRow row) {
|
||||
|
||||
Reference in New Issue
Block a user