Disable dialog exit animation when locking (1/2) am: 2d5edc3344
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16140773 Change-Id: I6ca06d82a00b2182bdf8485f3a7a0f38d9f7dd69
This commit is contained in:
committed by
Automerger Merge Worker
commit
a59ede4400
@@ -38,9 +38,6 @@ private const val TAG = "DialogLaunchAnimator"
|
||||
/**
|
||||
* A class that allows dialogs to be started in a seamless way from a view that is transforming
|
||||
* nicely into the starting dialog.
|
||||
*
|
||||
* Important: Don't forget to call [DialogLaunchAnimator.onDozeAmountChanged] when the doze amount
|
||||
* changes to gracefully handle dialogs fading out when the device is dozing.
|
||||
*/
|
||||
class DialogLaunchAnimator(
|
||||
private val context: Context,
|
||||
@@ -89,8 +86,17 @@ class DialogLaunchAnimator(
|
||||
// host dialog.
|
||||
if (dialog is ListenableDialog) {
|
||||
dialog.addListener(object : DialogListener {
|
||||
override fun onDismiss() {
|
||||
override fun onDismiss(reason: DialogListener.DismissReason) {
|
||||
dialog.removeListener(this)
|
||||
|
||||
// We disable the exit animation if we are dismissing the dialog because the
|
||||
// device is being locked, otherwise the animation looks bad if AOD is enabled.
|
||||
// If AOD is disabled the screen will directly becomes black and we won't see
|
||||
// the animation anyways.
|
||||
if (reason == DialogListener.DismissReason.DEVICE_LOCKED) {
|
||||
launchAnimation.exitAnimationDisabled = true
|
||||
}
|
||||
|
||||
hostDialog.dismiss()
|
||||
}
|
||||
|
||||
@@ -117,13 +123,6 @@ class DialogLaunchAnimator(
|
||||
return hostDialog
|
||||
}
|
||||
|
||||
/** Notify the current doze amount, to ensure that dialogs fade out when dozing. */
|
||||
// TODO(b/193634619): Replace this by some mandatory constructor parameter to make sure that we
|
||||
// don't forget to call this when the doze amount changes.
|
||||
fun onDozeAmountChanged(amount: Float) {
|
||||
currentAnimations.forEach { it.onDozeAmountChanged(amount) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that all dialogs currently shown won't animate into their touch surface when
|
||||
* dismissed.
|
||||
@@ -168,8 +167,16 @@ interface ListenableDialog {
|
||||
}
|
||||
|
||||
interface DialogListener {
|
||||
/** The reason why a dialog was dismissed. */
|
||||
enum class DismissReason {
|
||||
UNKNOWN,
|
||||
|
||||
/** The device was locked, which dismissed this dialog. */
|
||||
DEVICE_LOCKED,
|
||||
}
|
||||
|
||||
/** Called when this dialog dismiss() is called. */
|
||||
fun onDismiss()
|
||||
fun onDismiss(reason: DismissReason)
|
||||
|
||||
/** Called when this dialog hide() is called. */
|
||||
fun onHide()
|
||||
@@ -638,14 +645,4 @@ private class DialogLaunchAnimation(
|
||||
|
||||
return (touchSurface.parent as? View)?.isShown ?: true
|
||||
}
|
||||
|
||||
internal fun onDozeAmountChanged(amount: Float) {
|
||||
val alpha = Interpolators.ALPHA_OUT.getInterpolation(1 - amount)
|
||||
val decorView = this.hostDialog.window?.decorView ?: return
|
||||
if (decorView.hasOverlappingRendering() && alpha > 0.0f &&
|
||||
alpha < 1.0f && decorView.layerType != View.LAYER_TYPE_HARDWARE) {
|
||||
decorView.setLayerType(View.LAYER_TYPE_HARDWARE, null)
|
||||
}
|
||||
decorView.alpha = alpha
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,6 @@ import com.android.systemui.R;
|
||||
import com.android.systemui.SystemUI;
|
||||
import com.android.systemui.animation.ActivityLaunchAnimator;
|
||||
import com.android.systemui.animation.DelegateLaunchAnimatorController;
|
||||
import com.android.systemui.animation.DialogLaunchAnimator;
|
||||
import com.android.systemui.assist.AssistManager;
|
||||
import com.android.systemui.battery.BatteryMeterViewController;
|
||||
import com.android.systemui.biometrics.AuthRippleController;
|
||||
@@ -680,7 +679,6 @@ public class StatusBar extends SystemUI implements
|
||||
|
||||
private HeadsUpAppearanceController mHeadsUpAppearanceController;
|
||||
private final ActivityLaunchAnimator mActivityLaunchAnimator;
|
||||
private final DialogLaunchAnimator mDialogLaunchAnimator;
|
||||
private NotificationLaunchAnimatorControllerProvider mNotificationAnimationProvider;
|
||||
protected StatusBarNotificationPresenter mPresenter;
|
||||
private NotificationActivityStarter mNotificationActivityStarter;
|
||||
@@ -806,8 +804,7 @@ public class StatusBar extends SystemUI implements
|
||||
Optional<StartingSurface> startingSurfaceOptional,
|
||||
TunerService tunerService,
|
||||
DumpManager dumpManager,
|
||||
ActivityLaunchAnimator activityLaunchAnimator,
|
||||
DialogLaunchAnimator dialogLaunchAnimator) {
|
||||
ActivityLaunchAnimator activityLaunchAnimator) {
|
||||
super(context);
|
||||
mNotificationsController = notificationsController;
|
||||
mLightBarController = lightBarController;
|
||||
@@ -919,7 +916,6 @@ public class StatusBar extends SystemUI implements
|
||||
|
||||
mActivityIntentHelper = new ActivityIntentHelper(mContext);
|
||||
mActivityLaunchAnimator = activityLaunchAnimator;
|
||||
mDialogLaunchAnimator = dialogLaunchAnimator;
|
||||
|
||||
// The status bar background may need updating when the ongoing call status changes.
|
||||
mOngoingCallController.addCallback((animate) -> maybeUpdateBarMode());
|
||||
@@ -4481,8 +4477,6 @@ public class StatusBar extends SystemUI implements
|
||||
&& !mBiometricUnlockController.isWakeAndUnlock()) {
|
||||
mLightRevealScrim.setRevealAmount(1f - linear);
|
||||
}
|
||||
|
||||
mDialogLaunchAnimator.onDozeAmountChanged(linear);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -35,6 +35,7 @@ import android.view.WindowManager.LayoutParams;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.animation.DialogListener;
|
||||
import com.android.systemui.animation.DialogListener.DismissReason;
|
||||
import com.android.systemui.animation.ListenableDialog;
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
@@ -62,6 +63,10 @@ public class SystemUIDialog extends AlertDialog implements ListenableDialog {
|
||||
}
|
||||
|
||||
public SystemUIDialog(Context context, int theme) {
|
||||
this(context, theme, true /* dismissOnDeviceLock */);
|
||||
}
|
||||
|
||||
public SystemUIDialog(Context context, int theme, boolean dismissOnDeviceLock) {
|
||||
super(context, theme);
|
||||
mContext = context;
|
||||
|
||||
@@ -70,7 +75,7 @@ public class SystemUIDialog extends AlertDialog implements ListenableDialog {
|
||||
attrs.setTitle(getClass().getSimpleName());
|
||||
getWindow().setAttributes(attrs);
|
||||
|
||||
mDismissReceiver = new DismissReceiver(this);
|
||||
mDismissReceiver = dismissOnDeviceLock ? new DismissReceiver(this) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,13 +116,19 @@ public class SystemUIDialog extends AlertDialog implements ListenableDialog {
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mDismissReceiver.register();
|
||||
|
||||
if (mDismissReceiver != null) {
|
||||
mDismissReceiver.register();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mDismissReceiver.unregister();
|
||||
|
||||
if (mDismissReceiver != null) {
|
||||
mDismissReceiver.unregister();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -132,10 +143,14 @@ public class SystemUIDialog extends AlertDialog implements ListenableDialog {
|
||||
|
||||
@Override
|
||||
public void dismiss() {
|
||||
dismiss(DismissReason.UNKNOWN);
|
||||
}
|
||||
|
||||
private void dismiss(DismissReason reason) {
|
||||
super.dismiss();
|
||||
|
||||
for (DialogListener listener : new LinkedHashSet<>(mDialogListeners)) {
|
||||
listener.onDismiss();
|
||||
listener.onDismiss(reason);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,7 +266,11 @@ public class SystemUIDialog extends AlertDialog implements ListenableDialog {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
mDialog.dismiss();
|
||||
if (mDialog instanceof SystemUIDialog) {
|
||||
((SystemUIDialog) mDialog).dismiss(DismissReason.DEVICE_LOCKED);
|
||||
} else {
|
||||
mDialog.dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,18 @@ class SystemUIHostDialogProvider : HostDialogProvider {
|
||||
return SystemUIHostDialog(context, theme, onCreateCallback, dismissOverride)
|
||||
}
|
||||
|
||||
/**
|
||||
* This host dialog is a SystemUIDialog so that it's displayed above all SystemUI windows. Note
|
||||
* that it is not automatically dismissed when the device is locked, but only when the hosted
|
||||
* (original) dialog is dismissed. That way, the behavior of the dialog (dismissed when locking
|
||||
* or not) is consistent with when the dialog is shown with or without the dialog animator.
|
||||
*/
|
||||
private class SystemUIHostDialog(
|
||||
context: Context,
|
||||
theme: Int,
|
||||
private val onCreateCallback: () -> Unit,
|
||||
private val dismissOverride: (() -> Unit) -> Unit
|
||||
) : SystemUIDialog(context, theme) {
|
||||
) : SystemUIDialog(context, theme, false /* dismissOnDeviceLock */) {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
onCreateCallback()
|
||||
|
||||
@@ -29,7 +29,6 @@ import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.ViewMediatorCallback;
|
||||
import com.android.systemui.InitController;
|
||||
import com.android.systemui.animation.ActivityLaunchAnimator;
|
||||
import com.android.systemui.animation.DialogLaunchAnimator;
|
||||
import com.android.systemui.assist.AssistManager;
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||
import com.android.systemui.classifier.FalsingCollector;
|
||||
@@ -244,8 +243,7 @@ public interface StatusBarPhoneModule {
|
||||
Optional<StartingSurface> startingSurfaceOptional,
|
||||
TunerService tunerService,
|
||||
DumpManager dumpManager,
|
||||
ActivityLaunchAnimator activityLaunchAnimator,
|
||||
DialogLaunchAnimator dialogLaunchAnimator) {
|
||||
ActivityLaunchAnimator activityLaunchAnimator) {
|
||||
return new StatusBar(
|
||||
context,
|
||||
notificationsController,
|
||||
@@ -346,7 +344,7 @@ public interface StatusBarPhoneModule {
|
||||
startingSurfaceOptional,
|
||||
tunerService,
|
||||
dumpManager,
|
||||
activityLaunchAnimator,
|
||||
dialogLaunchAnimator);
|
||||
activityLaunchAnimator
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import android.view.WindowManager
|
||||
import android.widget.LinearLayout
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.animation.DialogListener.DismissReason
|
||||
import junit.framework.Assert.assertEquals
|
||||
import junit.framework.Assert.assertFalse
|
||||
import junit.framework.Assert.assertTrue
|
||||
@@ -63,10 +64,6 @@ class DialogLaunchAnimatorTest : SysuiTestCase() {
|
||||
assertEquals(1, hostDialogRoot.childCount)
|
||||
assertEquals(dialog.contentView, hostDialogRoot.getChildAt(0))
|
||||
|
||||
// If we are dozing, the host dialog window also fades out.
|
||||
runOnMainThreadAndWaitForIdleSync { dialogLaunchAnimator.onDozeAmountChanged(0.5f) }
|
||||
assertTrue(hostDialog.window!!.decorView.alpha < 1f)
|
||||
|
||||
// Hiding/showing/dismissing the dialog should hide/show/dismiss the host dialog given that
|
||||
// it's a ListenableDialog.
|
||||
runOnMainThreadAndWaitForIdleSync { dialog.hide() }
|
||||
@@ -164,7 +161,7 @@ class DialogLaunchAnimatorTest : SysuiTestCase() {
|
||||
|
||||
override fun dismiss() {
|
||||
super.dismiss()
|
||||
notifyListeners { onDismiss() }
|
||||
notifyListeners { onDismiss(DismissReason.UNKNOWN) }
|
||||
}
|
||||
|
||||
override fun hide() {
|
||||
|
||||
@@ -78,7 +78,6 @@ import com.android.systemui.InitController;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.animation.ActivityLaunchAnimator;
|
||||
import com.android.systemui.animation.DialogLaunchAnimator;
|
||||
import com.android.systemui.assist.AssistManager;
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||
import com.android.systemui.classifier.FalsingCollectorFake;
|
||||
@@ -281,7 +280,6 @@ public class StatusBarTest extends SysuiTestCase {
|
||||
@Mock private OperatorNameViewController.Factory mOperatorNameViewControllerFactory;
|
||||
@Mock private PhoneStatusBarViewController.Factory mPhoneStatusBarViewControllerFactory;
|
||||
@Mock private ActivityLaunchAnimator mActivityLaunchAnimator;
|
||||
@Mock private DialogLaunchAnimator mDialogLaunchAnimator;
|
||||
private ShadeController mShadeController;
|
||||
private final FakeSystemClock mFakeSystemClock = new FakeSystemClock();
|
||||
private FakeExecutor mMainExecutor = new FakeExecutor(mFakeSystemClock);
|
||||
@@ -462,8 +460,7 @@ public class StatusBarTest extends SysuiTestCase {
|
||||
Optional.of(mStartingSurface),
|
||||
mTunerService,
|
||||
mock(DumpManager.class),
|
||||
mActivityLaunchAnimator,
|
||||
mDialogLaunchAnimator);
|
||||
mActivityLaunchAnimator);
|
||||
when(mKeyguardViewMediator.registerStatusBar(
|
||||
any(StatusBar.class),
|
||||
any(NotificationPanelViewController.class),
|
||||
|
||||
Reference in New Issue
Block a user