Merge "Uses ActivityLaunchAnimator for occlusion animations."

This commit is contained in:
TreeHugger Robot
2022-02-03 02:15:17 +00:00
committed by Android (Google) Code Review
7 changed files with 196 additions and 45 deletions

View File

@@ -301,6 +301,7 @@ class ActivityLaunchAnimator(
* The intent was started. If [willAnimate] is false, nothing else will happen and the
* animation will not be started.
*/
@JvmDefault
fun onIntentStarted(willAnimate: Boolean) {}
/**
@@ -308,6 +309,7 @@ class ActivityLaunchAnimator(
* this if the animation was already started, i.e. if [onLaunchAnimationStart] was called
* before the cancellation.
*/
@JvmDefault
fun onLaunchAnimationCancelled() {}
}

View File

@@ -100,9 +100,11 @@ class LaunchAnimator(
* needed for the animation. [isExpandingFullyAbove] will be true if the window is expanding
* fully above the [launchContainer].
*/
@JvmDefault
fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {}
/** The animation made progress and the expandable view [state] should be updated. */
@JvmDefault
fun onLaunchAnimationProgress(state: State, progress: Float, linearProgress: Float) {}
/**
@@ -110,6 +112,7 @@ class LaunchAnimator(
* called previously. This is typically used to clean up the resources initialized when the
* animation was started.
*/
@JvmDefault
fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {}
}

View File

@@ -679,6 +679,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE);
}
/**
* Whether the secure camera is currently showing over the keyguard.
*/
public boolean isSecureCameraLaunchedOverKeyguard() {
return mSecureCameraLaunched;
}
/**
* @return a cached version of DreamManager.isDreaming()
*/

View File

@@ -233,10 +233,13 @@ public class KeyguardService extends Service {
mKeyguardViewMediator = keyguardViewMediator;
mKeyguardLifecyclesDispatcher = keyguardLifecyclesDispatcher;
mShellTransitions = shellTransitions;
}
if (shellTransitions != null && Transitions.ENABLE_SHELL_TRANSITIONS) {
// Nothing here. Initialization for this happens in onCreate.
} else {
@Override
public void onCreate() {
((SystemUIApplication) getApplication()).startServicesIfNeeded();
if (mShellTransitions == null || !Transitions.ENABLE_SHELL_TRANSITIONS) {
RemoteAnimationDefinition definition = new RemoteAnimationDefinition();
if (sEnableRemoteKeyguardGoingAwayAnimation) {
final RemoteAnimationAdapter exitAnimationAdapter =
@@ -248,22 +251,19 @@ public class KeyguardService extends Service {
}
if (sEnableRemoteKeyguardOccludeAnimation) {
final RemoteAnimationAdapter occludeAnimationAdapter =
new RemoteAnimationAdapter(mOccludeAnimationRunner, 0, 0);
new RemoteAnimationAdapter(
mKeyguardViewMediator.getOccludeAnimationRunner(), 0, 0);
definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_OCCLUDE,
occludeAnimationAdapter);
final RemoteAnimationAdapter unoccludeAnimationAdapter =
new RemoteAnimationAdapter(
mKeyguardViewMediator.getUnoccludeAnimationRunner(), 0, 0);
definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_UNOCCLUDE,
occludeAnimationAdapter);
unoccludeAnimationAdapter);
}
ActivityTaskManager.getInstance().registerRemoteAnimationsForDisplay(
DEFAULT_DISPLAY, definition);
}
}
@Override
public void onCreate() {
((SystemUIApplication) getApplication()).startServicesIfNeeded();
if (mShellTransitions == null || !Transitions.ENABLE_SHELL_TRANSITIONS) {
return;
}
if (sEnableRemoteKeyguardGoingAwayAnimation) {
@@ -354,33 +354,6 @@ public class KeyguardService extends Service {
}
};
private final IRemoteAnimationRunner.Stub mOccludeAnimationRunner =
new IRemoteAnimationRunner.Stub() {
@Override // Binder interface
public void onAnimationStart(@WindowManager.TransitionOldType int transit,
RemoteAnimationTarget[] apps,
RemoteAnimationTarget[] wallpapers,
RemoteAnimationTarget[] nonApps,
IRemoteAnimationFinishedCallback finishedCallback) {
Slog.d(TAG, "mOccludeAnimationRunner.onAnimationStart: transit=" + transit);
try {
if (transit == TRANSIT_OLD_KEYGUARD_OCCLUDE) {
mBinder.setOccluded(true /* isOccluded */, true /* animate */);
} else if (transit == TRANSIT_OLD_KEYGUARD_UNOCCLUDE) {
mBinder.setOccluded(false /* isOccluded */, false /* animate */);
}
// TODO(bc-unlock): Implement (un)occlude animation.
finishedCallback.onAnimationFinished();
} catch (RemoteException e) {
Slog.e(TAG, "RemoteException");
}
}
@Override // Binder interface
public void onAnimationCancelled() {
}
};
final IRemoteTransition mOccludeAnimation = new IRemoteTransition.Stub() {
@Override
public void startAnimation(IBinder transition, TransitionInfo info,

View File

@@ -77,11 +77,13 @@ import android.view.IRemoteAnimationRunner;
import android.view.RemoteAnimationTarget;
import android.view.SyncRtSurfaceTransactionApplier;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.WindowManagerPolicyConstants;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.jank.InteractionJankMonitor;
@@ -89,6 +91,7 @@ import com.android.internal.jank.InteractionJankMonitor.Configuration;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IKeyguardExitCallback;
import com.android.internal.policy.IKeyguardStateCallback;
import com.android.internal.policy.ScreenDecorationsUtils;
import com.android.internal.util.LatencyTracker;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardConstants;
@@ -102,7 +105,10 @@ import com.android.keyguard.mediator.ScreenOnCoordinator;
import com.android.systemui.CoreStartable;
import com.android.systemui.DejankUtils;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.animation.LaunchAnimator;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.dagger.qualifiers.UiBackground;
@@ -375,6 +381,9 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
private int mUnlockSoundId;
private int mTrustedSoundId;
private int mLockSoundStreamId;
private final float mPowerButtonY;
private final float mWindowCornerRadius;
/**
* The animation used for hiding keyguard. This is used to fetch the animation timings if
* WindowManager is not providing us with them.
@@ -815,6 +824,109 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
}
};
/**
* Animation launch controller for activities that occlude the keyguard.
*/
private final ActivityLaunchAnimator.Controller mOccludeAnimationController =
new ActivityLaunchAnimator.Controller() {
@Override
public void onLaunchAnimationStart(boolean isExpandingFullyAbove) {
setOccluded(true /* occluded */, false /* animate */);
}
@Override
public void onLaunchAnimationCancelled() {
setOccluded(true /* occluded */, false /* animate */);
}
@NonNull
@Override
public ViewGroup getLaunchContainer() {
return ((ViewGroup) mKeyguardViewControllerLazy.get()
.getViewRootImpl().getView());
}
@Override
public void setLaunchContainer(@NonNull ViewGroup launchContainer) {
// No-op, launch container is always the shade.
Log.wtf(TAG, "Someone tried to change the launch container for the "
+ "ActivityLaunchAnimator, which should never happen.");
}
@NonNull
@Override
public LaunchAnimator.State createAnimatorState() {
final int width = getLaunchContainer().getWidth();
final int height = getLaunchContainer().getHeight();
final float initialHeight = height / 3f;
final float initialWidth = width / 3f;
if (mUpdateMonitor.isSecureCameraLaunchedOverKeyguard()) {
// Start the animation near the power button, at one-third size, since the
// camera was launched from the power button.
return new LaunchAnimator.State(
(int) (mPowerButtonY - initialHeight / 2f) /* top */,
(int) (mPowerButtonY + initialHeight / 2f) /* bottom */,
(int) (width - initialWidth) /* left */,
width /* right */,
mWindowCornerRadius, mWindowCornerRadius);
} else {
// Start the animation in the center of the screen, scaled down.
return new LaunchAnimator.State(
height / 2, height / 2, width / 2, width / 2,
mWindowCornerRadius, mWindowCornerRadius);
}
}
};
/**
* Animation controller for activities that unocclude the keyguard. This will play the launch
* animation in reverse.
*/
private final ActivityLaunchAnimator.Controller mUnoccludeAnimationController =
new ActivityLaunchAnimator.Controller() {
@Override
public void onLaunchAnimationEnd(boolean isExpandingFullyAbove) {
setOccluded(false /* isOccluded */, false /* animate */);
}
@Override
public void onLaunchAnimationCancelled() {
setOccluded(false /* isOccluded */, false /* animate */);
}
@NonNull
@Override
public ViewGroup getLaunchContainer() {
return ((ViewGroup) mKeyguardViewControllerLazy.get()
.getViewRootImpl().getView());
}
@Override
public void setLaunchContainer(@NonNull ViewGroup launchContainer) {
// No-op, launch container is always the shade.
Log.wtf(TAG, "Someone tried to change the launch container for the "
+ "ActivityLaunchAnimator, which should never happen.");
}
@NonNull
@Override
public LaunchAnimator.State createAnimatorState() {
final int width = getLaunchContainer().getWidth();
final int height = getLaunchContainer().getHeight();
// TODO(b/207399883): Unocclude animation. This currently ends instantly.
return new LaunchAnimator.State(
0, height, 0, width, mWindowCornerRadius, mWindowCornerRadius);
}
};
private IRemoteAnimationRunner mOccludeAnimationRunner =
new ActivityLaunchRemoteAnimationRunner(mOccludeAnimationController);
private IRemoteAnimationRunner mUnoccludeAnimationRunner =
new ActivityLaunchRemoteAnimationRunner(mUnoccludeAnimationController);
private DeviceConfigProxy mDeviceConfig;
private DozeParameters mDozeParameters;
@@ -824,6 +936,8 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
private boolean mWallpaperSupportsAmbientMode;
private ScreenOnCoordinator mScreenOnCoordinator;
private Lazy<ActivityLaunchAnimator> mActivityLaunchAnimator;
/**
* Injected constructor. See {@link KeyguardModule}.
*/
@@ -850,7 +964,8 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
ScreenOnCoordinator screenOnCoordinator,
InteractionJankMonitor interactionJankMonitor,
DreamOverlayStateController dreamOverlayStateController,
Lazy<NotificationShadeWindowController> notificationShadeWindowControllerLazy) {
Lazy<NotificationShadeWindowController> notificationShadeWindowControllerLazy,
Lazy<ActivityLaunchAnimator> activityLaunchAnimator) {
super(context);
mFalsingCollector = falsingCollector;
mLockPatternUtils = lockPatternUtils;
@@ -890,6 +1005,12 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
mScreenOffAnimationController = screenOffAnimationController;
mInteractionJankMonitor = interactionJankMonitor;
mDreamOverlayStateController = dreamOverlayStateController;
mActivityLaunchAnimator = activityLaunchAnimator;
mPowerButtonY = context.getResources().getDimensionPixelSize(
R.dimen.physical_power_button_center_screen_location_y);
mWindowCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context);
}
public void userActivity() {
@@ -1440,6 +1561,14 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
Trace.endSection();
}
public IRemoteAnimationRunner getOccludeAnimationRunner() {
return mOccludeAnimationRunner;
}
public IRemoteAnimationRunner getUnoccludeAnimationRunner() {
return mUnoccludeAnimationRunner;
}
public boolean isHiding() {
return mHiding;
}
@@ -2868,4 +2997,36 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable,
return mMessage;
}
}
/**
* Implementation of RemoteAnimationRunner that creates a new
* {@link ActivityLaunchAnimator.Runner} whenever onAnimationStart is called, delegating the
* remote animation methods to that runner.
*/
private class ActivityLaunchRemoteAnimationRunner extends IRemoteAnimationRunner.Stub {
private final ActivityLaunchAnimator.Controller mActivityLaunchController;
@Nullable private ActivityLaunchAnimator.Runner mRunner;
ActivityLaunchRemoteAnimationRunner(ActivityLaunchAnimator.Controller controller) {
mActivityLaunchController = controller;
}
@Override
public void onAnimationCancelled() throws RemoteException {
if (mRunner != null) {
mRunner.onAnimationCancelled();
}
}
@Override
public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
RemoteAnimationTarget[] wallpapers,
RemoteAnimationTarget[] nonApps,
IRemoteAnimationFinishedCallback finishedCallback)
throws RemoteException {
mRunner = mActivityLaunchAnimator.get().createRunner(mActivityLaunchController);
mRunner.onAnimationStart(transit, apps, wallpapers, nonApps, finishedCallback);
}
}
}

View File

@@ -32,6 +32,7 @@ import com.android.keyguard.dagger.KeyguardStatusBarViewComponent;
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
import com.android.keyguard.mediator.ScreenOnCoordinator;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.classifier.FalsingModule;
@@ -102,7 +103,8 @@ public class KeyguardModule {
ScreenOnCoordinator screenOnCoordinator,
InteractionJankMonitor interactionJankMonitor,
DreamOverlayStateController dreamOverlayStateController,
Lazy<NotificationShadeWindowController> notificationShadeWindowController) {
Lazy<NotificationShadeWindowController> notificationShadeWindowController,
Lazy<ActivityLaunchAnimator> activityLaunchAnimator) {
return new KeyguardViewMediator(
context,
falsingCollector,
@@ -128,8 +130,8 @@ public class KeyguardModule {
screenOnCoordinator,
interactionJankMonitor,
dreamOverlayStateController,
notificationShadeWindowController
);
notificationShadeWindowController,
activityLaunchAnimator);
}
@SysUISingleton

View File

@@ -46,6 +46,7 @@ import com.android.keyguard.KeyguardDisplayManager;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.mediator.ScreenOnCoordinator;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.classifier.FalsingCollectorFake;
import com.android.systemui.dreams.DreamOverlayStateController;
@@ -100,6 +101,7 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
private @Mock ScreenOnCoordinator mScreenOnCoordinator;
private @Mock Lazy<NotificationShadeWindowController> mNotificationShadeWindowControllerLazy;
private @Mock DreamOverlayStateController mDreamOverlayStateController;
private @Mock ActivityLaunchAnimator mActivityLaunchAnimator;
private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake();
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
@@ -205,7 +207,8 @@ public class KeyguardViewMediatorTest extends SysuiTestCase {
mScreenOnCoordinator,
mInteractionJankMonitor,
mDreamOverlayStateController,
mNotificationShadeWindowControllerLazy);
mNotificationShadeWindowControllerLazy,
() -> mActivityLaunchAnimator);
mViewMediator.start();
}
}