Loading libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java +20 −4 Original line number Diff line number Diff line Loading @@ -52,12 +52,13 @@ public class BackAnimationBackground { /** * Ensures the back animation background color layer is present. * * @param startRect The start bounds of the closing target. * @param color The background color. * @param transaction The animation transaction. */ void ensureBackground(Rect startRect, int color, @NonNull SurfaceControl.Transaction transaction) { public void ensureBackground( Rect startRect, int color, @NonNull SurfaceControl.Transaction transaction) { if (mBackgroundSurface != null) { return; } Loading @@ -81,7 +82,12 @@ public class BackAnimationBackground { mIsRequestingStatusBarAppearance = false; } void removeBackground(@NonNull SurfaceControl.Transaction transaction) { /** * Remove the back animation background. * * @param transaction The animation transaction. */ public void removeBackground(@NonNull SurfaceControl.Transaction transaction) { if (mBackgroundSurface == null) { return; } Loading @@ -93,11 +99,21 @@ public class BackAnimationBackground { mIsRequestingStatusBarAppearance = false; } /** * Attach a {@link StatusBarCustomizer} instance to allow status bar animate with back progress. * * @param customizer The {@link StatusBarCustomizer} to be used. */ void setStatusBarCustomizer(StatusBarCustomizer customizer) { mCustomizer = customizer; } void onBackProgressed(float progress) { /** * Update back animation background with for the progress. * * @param progress Progress value from {@link android.window.BackProgressAnimator} */ public void onBackProgressed(float progress) { if (mCustomizer == null || mStartBounds.isEmpty()) { return; } Loading libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +109 −130 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.app.ActivityTaskManager; import android.app.IActivityTaskManager; import android.content.ContentResolver; Loading @@ -43,7 +44,6 @@ import android.provider.Settings.Global; import android.util.DisplayMetrics; import android.util.Log; import android.util.MathUtils; import android.util.SparseArray; import android.view.IRemoteAnimationRunner; import android.view.InputDevice; import android.view.KeyCharacterMap; Loading @@ -70,6 +70,7 @@ import com.android.wm.shell.common.annotations.ShellMainThread; import com.android.wm.shell.sysui.ShellController; import com.android.wm.shell.sysui.ShellInit; import java.util.concurrent.atomic.AtomicBoolean; /** Loading Loading @@ -113,7 +114,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont private boolean mShouldStartOnNextMoveEvent = false; /** @see #setTriggerBack(boolean) */ private boolean mTriggerBack; private FlingAnimationUtils mFlingAnimationUtils; private final FlingAnimationUtils mFlingAnimationUtils; /** Registry for the back animations */ private final ShellBackAnimationRegistry mShellBackAnimationRegistry; @Nullable private BackNavigationInfo mBackNavigationInfo; Loading @@ -135,13 +140,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont private final TouchTracker mTouchTracker = new TouchTracker(); private final SparseArray<BackAnimationRunner> mAnimationDefinition = new SparseArray<>(); @Nullable private IOnBackInvokedCallback mActiveCallback; private CrossActivityAnimation mDefaultActivityAnimation; private CustomizeActivityAnimation mCustomizeActivityAnimation; @VisibleForTesting final RemoteCallback mNavigationObserver = new RemoteCallback( new RemoteCallback.OnResultListener() { Loading Loading @@ -169,10 +170,18 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont @NonNull @ShellMainThread ShellExecutor shellExecutor, @NonNull @ShellBackgroundThread Handler backgroundHandler, Context context, @NonNull BackAnimationBackground backAnimationBackground) { this(shellInit, shellController, shellExecutor, backgroundHandler, ActivityTaskManager.getService(), context, context.getContentResolver(), backAnimationBackground); @NonNull BackAnimationBackground backAnimationBackground, ShellBackAnimationRegistry shellBackAnimationRegistry) { this( shellInit, shellController, shellExecutor, backgroundHandler, ActivityTaskManager.getService(), context, context.getContentResolver(), backAnimationBackground, shellBackAnimationRegistry); } @VisibleForTesting Loading @@ -182,8 +191,10 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont @NonNull @ShellMainThread ShellExecutor shellExecutor, @NonNull @ShellBackgroundThread Handler bgHandler, @NonNull IActivityTaskManager activityTaskManager, Context context, ContentResolver contentResolver, @NonNull BackAnimationBackground backAnimationBackground) { Context context, ContentResolver contentResolver, @NonNull BackAnimationBackground backAnimationBackground, ShellBackAnimationRegistry shellBackAnimationRegistry) { mShellController = shellController; mShellExecutor = shellExecutor; mActivityTaskManager = activityTaskManager; Loading @@ -197,11 +208,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont .setMaxLengthSeconds(FLING_MAX_LENGTH_SECONDS) .setSpeedUpFactor(FLING_SPEED_UP_FACTOR) .build(); } @VisibleForTesting void setEnableUAnimation(boolean enable) { IS_U_ANIMATION_ENABLED = enable; mShellBackAnimationRegistry = shellBackAnimationRegistry; } private void onInit() { Loading @@ -209,26 +216,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont createAdapter(); mShellController.addExternalInterface(KEY_EXTRA_SHELL_BACK_ANIMATION, this::createExternalInterface, this); initBackAnimationRunners(); } private void initBackAnimationRunners() { if (!IS_U_ANIMATION_ENABLED) { return; } final CrossTaskBackAnimation crossTaskAnimation = new CrossTaskBackAnimation(mContext, mAnimationBackground); mAnimationDefinition.set(BackNavigationInfo.TYPE_CROSS_TASK, crossTaskAnimation.mBackAnimationRunner); mDefaultActivityAnimation = new CrossActivityAnimation(mContext, mAnimationBackground); mAnimationDefinition.set(BackNavigationInfo.TYPE_CROSS_ACTIVITY, mDefaultActivityAnimation.mBackAnimationRunner); mCustomizeActivityAnimation = new CustomizeActivityAnimation(mContext, mAnimationBackground); // TODO (236760237): register dialog close animation when it's completed. } private void setupAnimationDeveloperSettingsObserver( Loading Loading @@ -359,11 +346,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont void registerAnimation(@BackNavigationInfo.BackTargetType int type, @NonNull BackAnimationRunner runner) { mAnimationDefinition.set(type, runner); mShellBackAnimationRegistry.registerAnimation(type, runner); } void unregisterAnimation(@BackNavigationInfo.BackTargetType int type) { mAnimationDefinition.remove(type); mShellBackAnimationRegistry.unregisterAnimation(type); } /** Loading Loading @@ -434,9 +421,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont final int backType = backNavigationInfo.getType(); final boolean shouldDispatchToAnimator = shouldDispatchToAnimator(); if (shouldDispatchToAnimator) { if (mAnimationDefinition.contains(backType)) { mAnimationDefinition.get(backType).startGesture(); } else { if (!mShellBackAnimationRegistry.startGesture(backType)) { mActiveCallback = null; } } else { Loading @@ -459,6 +444,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont sendBackEvent(KeyEvent.ACTION_UP); } @SuppressLint("MissingPermission") private void sendBackEvent(int action) { final long when = SystemClock.uptimeMillis(); final KeyEvent ev = new KeyEvent(when, when, action, KeyEvent.KEYCODE_BACK, 0 /* repeat */, Loading Loading @@ -671,21 +657,17 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont } final int backType = mBackNavigationInfo.getType(); final BackAnimationRunner runner = mAnimationDefinition.get(backType); // Simply trigger and finish back navigation when no animator defined. if (!shouldDispatchToAnimator() || runner == null) { if (!shouldDispatchToAnimator() || mShellBackAnimationRegistry.isAnimationCancelledOrNull(backType)) { invokeOrCancelBack(); return; } if (runner.isWaitingAnimation()) { } else if (mShellBackAnimationRegistry.isWaitingAnimation(backType)) { ProtoLog.w(WM_SHELL_BACK_PREVIEW, "Gesture released, but animation didn't ready."); // Supposed it is in post commit animation state, and start the timeout to watch // if the animation is ready. mShellExecutor.executeDelayed(mAnimationTimeoutRunnable, MAX_ANIMATION_DURATION); return; } else if (runner.isAnimationCancelled()) { invokeOrCancelBack(); return; } startPostCommitAnimation(); } Loading Loading @@ -737,12 +719,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont mShouldStartOnNextMoveEvent = false; mTouchTracker.reset(); mActiveCallback = null; // reset to default if (mDefaultActivityAnimation != null && mAnimationDefinition.contains(BackNavigationInfo.TYPE_CROSS_ACTIVITY)) { mAnimationDefinition.set(BackNavigationInfo.TYPE_CROSS_ACTIVITY, mDefaultActivityAnimation.mBackAnimationRunner); } mShellBackAnimationRegistry.resetDefaultCrossActivity(); if (mBackNavigationInfo != null) { mBackNavigationInfo.onBackNavigationFinished(mTriggerBack); mBackNavigationInfo = null; Loading @@ -750,43 +727,34 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont mTriggerBack = false; } private BackAnimationRunner getAnimationRunnerAndInit() { int type = mBackNavigationInfo.getType(); // Initiate customized cross-activity animation, or fall back to cross activity animation if (type == BackNavigationInfo.TYPE_CROSS_ACTIVITY && mAnimationDefinition.contains(type)) { final BackNavigationInfo.CustomAnimationInfo animationInfo = mBackNavigationInfo.getCustomAnimationInfo(); if (animationInfo != null && mCustomizeActivityAnimation != null && mCustomizeActivityAnimation.prepareNextAnimation(animationInfo)) { mAnimationDefinition.get(type).resetWaitingAnimation(); mAnimationDefinition.set(BackNavigationInfo.TYPE_CROSS_ACTIVITY, mCustomizeActivityAnimation.mBackAnimationRunner); } } return mAnimationDefinition.get(type); } private void createAdapter() { IBackAnimationRunner runner = new IBackAnimationRunner.Stub() { IBackAnimationRunner runner = new IBackAnimationRunner.Stub() { @Override public void onAnimationStart(RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, public void onAnimationStart( RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, IBackAnimationFinishedCallback finishedCallback) { mShellExecutor.execute(() -> { mShellExecutor.execute( () -> { if (mBackNavigationInfo == null) { Log.e(TAG, "Lack of navigation info to start animation."); return; } final int type = mBackNavigationInfo.getType(); final BackAnimationRunner runner = getAnimationRunnerAndInit(); final BackAnimationRunner runner = mShellBackAnimationRegistry.getAnimationRunnerAndInit( mBackNavigationInfo); if (runner == null) { Log.e(TAG, "Animation didn't be defined for type " + BackNavigationInfo.typeToString(type)); if (finishedCallback != null) { try { finishedCallback.onAnimationFinished(false); } catch (RemoteException e) { Log.w(TAG, "Failed call IBackNaviAnimationController", e); Log.w( TAG, "Failed call IBackNaviAnimationController", e); } } return; Loading @@ -794,22 +762,34 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont mActiveCallback = runner.getCallback(); mBackAnimationFinishedCallback = finishedCallback; ProtoLog.d(WM_SHELL_BACK_PREVIEW, "BackAnimationController: startAnimation()"); runner.startAnimation(apps, wallpapers, nonApps, () -> mShellExecutor.execute( BackAnimationController.this::onBackAnimationFinished)); ProtoLog.d( WM_SHELL_BACK_PREVIEW, "BackAnimationController: startAnimation()"); runner.startAnimation( apps, wallpapers, nonApps, () -> mShellExecutor.execute( BackAnimationController.this ::onBackAnimationFinished)); if (apps.length >= 1) { dispatchOnBackStarted( mActiveCallback, mTouchTracker.createStartEvent(apps[0])); mActiveCallback, mTouchTracker.createStartEvent(apps[0])); } // Dispatch the first progress after animation start for smoothing the initial // animation, instead of waiting for next onMove. final BackMotionEvent backFinish = mTouchTracker.createProgressEvent(); // Dispatch the first progress after animation start for // smoothing the initial animation, instead of waiting for next // onMove. final BackMotionEvent backFinish = mTouchTracker.createProgressEvent(); dispatchOnBackProgressed(mActiveCallback, backFinish); if (!mBackGestureStarted) { // if the down -> up gesture happened before animation start, we have to // trigger the uninterruptible transition to finish the back animation. // if the down -> up gesture happened before animation // start, we have to trigger the uninterruptible transition // to finish the back animation. startPostCommitAnimation(); } }); Loading @@ -817,13 +797,12 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont @Override public void onAnimationCancelled() { mShellExecutor.execute(() -> { final BackAnimationRunner runner = mAnimationDefinition.get( mBackNavigationInfo.getType()); if (runner == null) { mShellExecutor.execute( () -> { if (!mShellBackAnimationRegistry.cancel( mBackNavigationInfo.getType())) { return; } runner.cancelAnimation(); if (!mBackGestureStarted) { invokeOrCancelBack(); } Loading libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java +3 −3 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ import android.window.IOnBackInvokedCallback; * before it received IBackAnimationRunner#onAnimationStart, so the controller could continue * trigger the real back behavior. */ class BackAnimationRunner { public class BackAnimationRunner { private static final String TAG = "ShellBackPreview"; private final IOnBackInvokedCallback mCallback; Loading @@ -44,8 +44,8 @@ class BackAnimationRunner { /** True when the back animation is cancelled */ private boolean mAnimationCancelled; BackAnimationRunner(@NonNull IOnBackInvokedCallback callback, @NonNull IRemoteAnimationRunner runner) { public BackAnimationRunner( @NonNull IOnBackInvokedCallback callback, @NonNull IRemoteAnimationRunner runner) { mCallback = callback; mRunner = runner; } Loading libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityAnimation.java +11 −3 Original line number Diff line number Diff line Loading @@ -51,9 +51,11 @@ import com.android.internal.policy.ScreenDecorationsUtils; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.common.annotations.ShellMainThread; import javax.inject.Inject; /** Class that defines cross-activity animation. */ @ShellMainThread class CrossActivityAnimation { public class CrossActivityAnimation extends ShellBackAnimation { /** * Minimum scale of the entering/closing window. */ Loading Loading @@ -106,6 +108,7 @@ class CrossActivityAnimation { private final SpringAnimation mLeavingProgressSpring; // Max window x-shift in pixels. private final float mWindowXShift; private final BackAnimationRunner mBackAnimationRunner; private float mEnteringProgress = 0f; private float mLeavingProgress = 0f; Loading @@ -126,11 +129,11 @@ class CrossActivityAnimation { private IRemoteAnimationFinishedCallback mFinishCallback; private final BackProgressAnimator mProgressAnimator = new BackProgressAnimator(); final BackAnimationRunner mBackAnimationRunner; private final BackAnimationBackground mBackground; CrossActivityAnimation(Context context, BackAnimationBackground background) { @Inject public CrossActivityAnimation(Context context, BackAnimationBackground background) { mCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context); mBackAnimationRunner = new BackAnimationRunner(new Callback(), new Runner()); mBackground = background; Loading Loading @@ -357,6 +360,11 @@ class CrossActivityAnimation { mTransaction.apply(); } @Override public BackAnimationRunner getRunner() { return mBackAnimationRunner; } private final class Callback extends IOnBackInvokedCallback.Default { @Override public void onBackStarted(BackMotionEvent backEvent) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java +37 −33 Original line number Diff line number Diff line Loading @@ -47,21 +47,23 @@ import com.android.internal.policy.ScreenDecorationsUtils; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.common.annotations.ShellMainThread; import javax.inject.Inject; /** * Controls the animation of swiping back and returning to another task. * * This is a two part animation. The first part is an animation that tracks gesture location to * scale and move the closing and entering app windows. * Once the gesture is committed, the second part remains the closing window in place. * The entering window plays the rest of app opening transition to enter full screen. * <p>This is a two part animation. The first part is an animation that tracks gesture location to * scale and move the closing and entering app windows. Once the gesture is committed, the second * part remains the closing window in place. The entering window plays the rest of app opening * transition to enter full screen. * * This animation is used only for apps that enable back dispatching via * {@link android.window.OnBackInvokedDispatcher}. The controller registers * an {@link IOnBackInvokedCallback} with WM Shell and receives back dispatches when a back * navigation to launcher starts. * <p>This animation is used only for apps that enable back dispatching via {@link * android.window.OnBackInvokedDispatcher}. The controller registers an {@link * IOnBackInvokedCallback} with WM Shell and receives back dispatches when a back navigation to * launcher starts. */ @ShellMainThread class CrossTaskBackAnimation { public class CrossTaskBackAnimation extends ShellBackAnimation { private static final int BACKGROUNDCOLOR = 0x43433A; /** Loading Loading @@ -104,28 +106,41 @@ class CrossTaskBackAnimation { private final float[] mTmpFloat9 = new float[9]; private final float[] mTmpTranslate = {0, 0, 0}; private final BackAnimationRunner mBackAnimationRunner; private final BackAnimationBackground mBackground; private RemoteAnimationTarget mEnteringTarget; private RemoteAnimationTarget mClosingTarget; private SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction(); private boolean mBackInProgress = false; private boolean mIsRightEdge; private float mProgress = 0; private PointF mTouchPos = new PointF(); private IRemoteAnimationFinishedCallback mFinishCallback; private BackProgressAnimator mProgressAnimator = new BackProgressAnimator(); final BackAnimationRunner mBackAnimationRunner; private final BackAnimationBackground mBackground; CrossTaskBackAnimation(Context context, BackAnimationBackground background) { @Inject public CrossTaskBackAnimation(Context context, BackAnimationBackground background) { mCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context); mBackAnimationRunner = new BackAnimationRunner(new Callback(), new Runner()); mBackground = background; } private static void computeScaleTransformMatrix(float scale, float[] matrix) { matrix[0] = scale; matrix[1] = 0; matrix[2] = 0; matrix[3] = 0; matrix[4] = scale; matrix[5] = 0; matrix[6] = 0; matrix[7] = 0; matrix[8] = scale; } private static float mapRange(float value, float min, float max) { return min + (value * (max - min)); } private float getInterpolatedProgress(float backProgress) { return 1 - (1 - backProgress) * (1 - backProgress) * (1 - backProgress); } Loading Loading @@ -233,18 +248,6 @@ class CrossTaskBackAnimation { mTransaction.setColorTransform(leash, mTmpFloat9, mTmpTranslate); } static void computeScaleTransformMatrix(float scale, float[] matrix) { matrix[0] = scale; matrix[1] = 0; matrix[2] = 0; matrix[3] = 0; matrix[4] = scale; matrix[5] = 0; matrix[6] = 0; matrix[7] = 0; matrix[8] = scale; } private void finishAnimation() { if (mEnteringTarget != null) { mEnteringTarget.leash.release(); Loading Loading @@ -314,8 +317,9 @@ class CrossTaskBackAnimation { valueAnimator.start(); } private static float mapRange(float value, float min, float max) { return min + (value * (max - min)); @Override public BackAnimationRunner getRunner() { return mBackAnimationRunner; } private final class Callback extends IOnBackInvokedCallback.Default { Loading @@ -340,7 +344,7 @@ class CrossTaskBackAnimation { mProgressAnimator.reset(); onGestureCommitted(); } }; } private final class Runner extends IRemoteAnimationRunner.Default { @Override Loading @@ -360,5 +364,5 @@ class CrossTaskBackAnimation { startBackAnimation(); mFinishCallback = finishedCallback; } }; } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationBackground.java +20 −4 Original line number Diff line number Diff line Loading @@ -52,12 +52,13 @@ public class BackAnimationBackground { /** * Ensures the back animation background color layer is present. * * @param startRect The start bounds of the closing target. * @param color The background color. * @param transaction The animation transaction. */ void ensureBackground(Rect startRect, int color, @NonNull SurfaceControl.Transaction transaction) { public void ensureBackground( Rect startRect, int color, @NonNull SurfaceControl.Transaction transaction) { if (mBackgroundSurface != null) { return; } Loading @@ -81,7 +82,12 @@ public class BackAnimationBackground { mIsRequestingStatusBarAppearance = false; } void removeBackground(@NonNull SurfaceControl.Transaction transaction) { /** * Remove the back animation background. * * @param transaction The animation transaction. */ public void removeBackground(@NonNull SurfaceControl.Transaction transaction) { if (mBackgroundSurface == null) { return; } Loading @@ -93,11 +99,21 @@ public class BackAnimationBackground { mIsRequestingStatusBarAppearance = false; } /** * Attach a {@link StatusBarCustomizer} instance to allow status bar animate with back progress. * * @param customizer The {@link StatusBarCustomizer} to be used. */ void setStatusBarCustomizer(StatusBarCustomizer customizer) { mCustomizer = customizer; } void onBackProgressed(float progress) { /** * Update back animation background with for the progress. * * @param progress Progress value from {@link android.window.BackProgressAnimator} */ public void onBackProgressed(float progress) { if (mCustomizer == null || mStartBounds.isEmpty()) { return; } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +109 −130 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.app.ActivityTaskManager; import android.app.IActivityTaskManager; import android.content.ContentResolver; Loading @@ -43,7 +44,6 @@ import android.provider.Settings.Global; import android.util.DisplayMetrics; import android.util.Log; import android.util.MathUtils; import android.util.SparseArray; import android.view.IRemoteAnimationRunner; import android.view.InputDevice; import android.view.KeyCharacterMap; Loading @@ -70,6 +70,7 @@ import com.android.wm.shell.common.annotations.ShellMainThread; import com.android.wm.shell.sysui.ShellController; import com.android.wm.shell.sysui.ShellInit; import java.util.concurrent.atomic.AtomicBoolean; /** Loading Loading @@ -113,7 +114,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont private boolean mShouldStartOnNextMoveEvent = false; /** @see #setTriggerBack(boolean) */ private boolean mTriggerBack; private FlingAnimationUtils mFlingAnimationUtils; private final FlingAnimationUtils mFlingAnimationUtils; /** Registry for the back animations */ private final ShellBackAnimationRegistry mShellBackAnimationRegistry; @Nullable private BackNavigationInfo mBackNavigationInfo; Loading @@ -135,13 +140,9 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont private final TouchTracker mTouchTracker = new TouchTracker(); private final SparseArray<BackAnimationRunner> mAnimationDefinition = new SparseArray<>(); @Nullable private IOnBackInvokedCallback mActiveCallback; private CrossActivityAnimation mDefaultActivityAnimation; private CustomizeActivityAnimation mCustomizeActivityAnimation; @VisibleForTesting final RemoteCallback mNavigationObserver = new RemoteCallback( new RemoteCallback.OnResultListener() { Loading Loading @@ -169,10 +170,18 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont @NonNull @ShellMainThread ShellExecutor shellExecutor, @NonNull @ShellBackgroundThread Handler backgroundHandler, Context context, @NonNull BackAnimationBackground backAnimationBackground) { this(shellInit, shellController, shellExecutor, backgroundHandler, ActivityTaskManager.getService(), context, context.getContentResolver(), backAnimationBackground); @NonNull BackAnimationBackground backAnimationBackground, ShellBackAnimationRegistry shellBackAnimationRegistry) { this( shellInit, shellController, shellExecutor, backgroundHandler, ActivityTaskManager.getService(), context, context.getContentResolver(), backAnimationBackground, shellBackAnimationRegistry); } @VisibleForTesting Loading @@ -182,8 +191,10 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont @NonNull @ShellMainThread ShellExecutor shellExecutor, @NonNull @ShellBackgroundThread Handler bgHandler, @NonNull IActivityTaskManager activityTaskManager, Context context, ContentResolver contentResolver, @NonNull BackAnimationBackground backAnimationBackground) { Context context, ContentResolver contentResolver, @NonNull BackAnimationBackground backAnimationBackground, ShellBackAnimationRegistry shellBackAnimationRegistry) { mShellController = shellController; mShellExecutor = shellExecutor; mActivityTaskManager = activityTaskManager; Loading @@ -197,11 +208,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont .setMaxLengthSeconds(FLING_MAX_LENGTH_SECONDS) .setSpeedUpFactor(FLING_SPEED_UP_FACTOR) .build(); } @VisibleForTesting void setEnableUAnimation(boolean enable) { IS_U_ANIMATION_ENABLED = enable; mShellBackAnimationRegistry = shellBackAnimationRegistry; } private void onInit() { Loading @@ -209,26 +216,6 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont createAdapter(); mShellController.addExternalInterface(KEY_EXTRA_SHELL_BACK_ANIMATION, this::createExternalInterface, this); initBackAnimationRunners(); } private void initBackAnimationRunners() { if (!IS_U_ANIMATION_ENABLED) { return; } final CrossTaskBackAnimation crossTaskAnimation = new CrossTaskBackAnimation(mContext, mAnimationBackground); mAnimationDefinition.set(BackNavigationInfo.TYPE_CROSS_TASK, crossTaskAnimation.mBackAnimationRunner); mDefaultActivityAnimation = new CrossActivityAnimation(mContext, mAnimationBackground); mAnimationDefinition.set(BackNavigationInfo.TYPE_CROSS_ACTIVITY, mDefaultActivityAnimation.mBackAnimationRunner); mCustomizeActivityAnimation = new CustomizeActivityAnimation(mContext, mAnimationBackground); // TODO (236760237): register dialog close animation when it's completed. } private void setupAnimationDeveloperSettingsObserver( Loading Loading @@ -359,11 +346,11 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont void registerAnimation(@BackNavigationInfo.BackTargetType int type, @NonNull BackAnimationRunner runner) { mAnimationDefinition.set(type, runner); mShellBackAnimationRegistry.registerAnimation(type, runner); } void unregisterAnimation(@BackNavigationInfo.BackTargetType int type) { mAnimationDefinition.remove(type); mShellBackAnimationRegistry.unregisterAnimation(type); } /** Loading Loading @@ -434,9 +421,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont final int backType = backNavigationInfo.getType(); final boolean shouldDispatchToAnimator = shouldDispatchToAnimator(); if (shouldDispatchToAnimator) { if (mAnimationDefinition.contains(backType)) { mAnimationDefinition.get(backType).startGesture(); } else { if (!mShellBackAnimationRegistry.startGesture(backType)) { mActiveCallback = null; } } else { Loading @@ -459,6 +444,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont sendBackEvent(KeyEvent.ACTION_UP); } @SuppressLint("MissingPermission") private void sendBackEvent(int action) { final long when = SystemClock.uptimeMillis(); final KeyEvent ev = new KeyEvent(when, when, action, KeyEvent.KEYCODE_BACK, 0 /* repeat */, Loading Loading @@ -671,21 +657,17 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont } final int backType = mBackNavigationInfo.getType(); final BackAnimationRunner runner = mAnimationDefinition.get(backType); // Simply trigger and finish back navigation when no animator defined. if (!shouldDispatchToAnimator() || runner == null) { if (!shouldDispatchToAnimator() || mShellBackAnimationRegistry.isAnimationCancelledOrNull(backType)) { invokeOrCancelBack(); return; } if (runner.isWaitingAnimation()) { } else if (mShellBackAnimationRegistry.isWaitingAnimation(backType)) { ProtoLog.w(WM_SHELL_BACK_PREVIEW, "Gesture released, but animation didn't ready."); // Supposed it is in post commit animation state, and start the timeout to watch // if the animation is ready. mShellExecutor.executeDelayed(mAnimationTimeoutRunnable, MAX_ANIMATION_DURATION); return; } else if (runner.isAnimationCancelled()) { invokeOrCancelBack(); return; } startPostCommitAnimation(); } Loading Loading @@ -737,12 +719,7 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont mShouldStartOnNextMoveEvent = false; mTouchTracker.reset(); mActiveCallback = null; // reset to default if (mDefaultActivityAnimation != null && mAnimationDefinition.contains(BackNavigationInfo.TYPE_CROSS_ACTIVITY)) { mAnimationDefinition.set(BackNavigationInfo.TYPE_CROSS_ACTIVITY, mDefaultActivityAnimation.mBackAnimationRunner); } mShellBackAnimationRegistry.resetDefaultCrossActivity(); if (mBackNavigationInfo != null) { mBackNavigationInfo.onBackNavigationFinished(mTriggerBack); mBackNavigationInfo = null; Loading @@ -750,43 +727,34 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont mTriggerBack = false; } private BackAnimationRunner getAnimationRunnerAndInit() { int type = mBackNavigationInfo.getType(); // Initiate customized cross-activity animation, or fall back to cross activity animation if (type == BackNavigationInfo.TYPE_CROSS_ACTIVITY && mAnimationDefinition.contains(type)) { final BackNavigationInfo.CustomAnimationInfo animationInfo = mBackNavigationInfo.getCustomAnimationInfo(); if (animationInfo != null && mCustomizeActivityAnimation != null && mCustomizeActivityAnimation.prepareNextAnimation(animationInfo)) { mAnimationDefinition.get(type).resetWaitingAnimation(); mAnimationDefinition.set(BackNavigationInfo.TYPE_CROSS_ACTIVITY, mCustomizeActivityAnimation.mBackAnimationRunner); } } return mAnimationDefinition.get(type); } private void createAdapter() { IBackAnimationRunner runner = new IBackAnimationRunner.Stub() { IBackAnimationRunner runner = new IBackAnimationRunner.Stub() { @Override public void onAnimationStart(RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, public void onAnimationStart( RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, IBackAnimationFinishedCallback finishedCallback) { mShellExecutor.execute(() -> { mShellExecutor.execute( () -> { if (mBackNavigationInfo == null) { Log.e(TAG, "Lack of navigation info to start animation."); return; } final int type = mBackNavigationInfo.getType(); final BackAnimationRunner runner = getAnimationRunnerAndInit(); final BackAnimationRunner runner = mShellBackAnimationRegistry.getAnimationRunnerAndInit( mBackNavigationInfo); if (runner == null) { Log.e(TAG, "Animation didn't be defined for type " + BackNavigationInfo.typeToString(type)); if (finishedCallback != null) { try { finishedCallback.onAnimationFinished(false); } catch (RemoteException e) { Log.w(TAG, "Failed call IBackNaviAnimationController", e); Log.w( TAG, "Failed call IBackNaviAnimationController", e); } } return; Loading @@ -794,22 +762,34 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont mActiveCallback = runner.getCallback(); mBackAnimationFinishedCallback = finishedCallback; ProtoLog.d(WM_SHELL_BACK_PREVIEW, "BackAnimationController: startAnimation()"); runner.startAnimation(apps, wallpapers, nonApps, () -> mShellExecutor.execute( BackAnimationController.this::onBackAnimationFinished)); ProtoLog.d( WM_SHELL_BACK_PREVIEW, "BackAnimationController: startAnimation()"); runner.startAnimation( apps, wallpapers, nonApps, () -> mShellExecutor.execute( BackAnimationController.this ::onBackAnimationFinished)); if (apps.length >= 1) { dispatchOnBackStarted( mActiveCallback, mTouchTracker.createStartEvent(apps[0])); mActiveCallback, mTouchTracker.createStartEvent(apps[0])); } // Dispatch the first progress after animation start for smoothing the initial // animation, instead of waiting for next onMove. final BackMotionEvent backFinish = mTouchTracker.createProgressEvent(); // Dispatch the first progress after animation start for // smoothing the initial animation, instead of waiting for next // onMove. final BackMotionEvent backFinish = mTouchTracker.createProgressEvent(); dispatchOnBackProgressed(mActiveCallback, backFinish); if (!mBackGestureStarted) { // if the down -> up gesture happened before animation start, we have to // trigger the uninterruptible transition to finish the back animation. // if the down -> up gesture happened before animation // start, we have to trigger the uninterruptible transition // to finish the back animation. startPostCommitAnimation(); } }); Loading @@ -817,13 +797,12 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont @Override public void onAnimationCancelled() { mShellExecutor.execute(() -> { final BackAnimationRunner runner = mAnimationDefinition.get( mBackNavigationInfo.getType()); if (runner == null) { mShellExecutor.execute( () -> { if (!mShellBackAnimationRegistry.cancel( mBackNavigationInfo.getType())) { return; } runner.cancelAnimation(); if (!mBackGestureStarted) { invokeOrCancelBack(); } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java +3 −3 Original line number Diff line number Diff line Loading @@ -32,7 +32,7 @@ import android.window.IOnBackInvokedCallback; * before it received IBackAnimationRunner#onAnimationStart, so the controller could continue * trigger the real back behavior. */ class BackAnimationRunner { public class BackAnimationRunner { private static final String TAG = "ShellBackPreview"; private final IOnBackInvokedCallback mCallback; Loading @@ -44,8 +44,8 @@ class BackAnimationRunner { /** True when the back animation is cancelled */ private boolean mAnimationCancelled; BackAnimationRunner(@NonNull IOnBackInvokedCallback callback, @NonNull IRemoteAnimationRunner runner) { public BackAnimationRunner( @NonNull IOnBackInvokedCallback callback, @NonNull IRemoteAnimationRunner runner) { mCallback = callback; mRunner = runner; } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossActivityAnimation.java +11 −3 Original line number Diff line number Diff line Loading @@ -51,9 +51,11 @@ import com.android.internal.policy.ScreenDecorationsUtils; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.common.annotations.ShellMainThread; import javax.inject.Inject; /** Class that defines cross-activity animation. */ @ShellMainThread class CrossActivityAnimation { public class CrossActivityAnimation extends ShellBackAnimation { /** * Minimum scale of the entering/closing window. */ Loading Loading @@ -106,6 +108,7 @@ class CrossActivityAnimation { private final SpringAnimation mLeavingProgressSpring; // Max window x-shift in pixels. private final float mWindowXShift; private final BackAnimationRunner mBackAnimationRunner; private float mEnteringProgress = 0f; private float mLeavingProgress = 0f; Loading @@ -126,11 +129,11 @@ class CrossActivityAnimation { private IRemoteAnimationFinishedCallback mFinishCallback; private final BackProgressAnimator mProgressAnimator = new BackProgressAnimator(); final BackAnimationRunner mBackAnimationRunner; private final BackAnimationBackground mBackground; CrossActivityAnimation(Context context, BackAnimationBackground background) { @Inject public CrossActivityAnimation(Context context, BackAnimationBackground background) { mCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context); mBackAnimationRunner = new BackAnimationRunner(new Callback(), new Runner()); mBackground = background; Loading Loading @@ -357,6 +360,11 @@ class CrossActivityAnimation { mTransaction.apply(); } @Override public BackAnimationRunner getRunner() { return mBackAnimationRunner; } private final class Callback extends IOnBackInvokedCallback.Default { @Override public void onBackStarted(BackMotionEvent backEvent) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/back/CrossTaskBackAnimation.java +37 −33 Original line number Diff line number Diff line Loading @@ -47,21 +47,23 @@ import com.android.internal.policy.ScreenDecorationsUtils; import com.android.internal.protolog.common.ProtoLog; import com.android.wm.shell.common.annotations.ShellMainThread; import javax.inject.Inject; /** * Controls the animation of swiping back and returning to another task. * * This is a two part animation. The first part is an animation that tracks gesture location to * scale and move the closing and entering app windows. * Once the gesture is committed, the second part remains the closing window in place. * The entering window plays the rest of app opening transition to enter full screen. * <p>This is a two part animation. The first part is an animation that tracks gesture location to * scale and move the closing and entering app windows. Once the gesture is committed, the second * part remains the closing window in place. The entering window plays the rest of app opening * transition to enter full screen. * * This animation is used only for apps that enable back dispatching via * {@link android.window.OnBackInvokedDispatcher}. The controller registers * an {@link IOnBackInvokedCallback} with WM Shell and receives back dispatches when a back * navigation to launcher starts. * <p>This animation is used only for apps that enable back dispatching via {@link * android.window.OnBackInvokedDispatcher}. The controller registers an {@link * IOnBackInvokedCallback} with WM Shell and receives back dispatches when a back navigation to * launcher starts. */ @ShellMainThread class CrossTaskBackAnimation { public class CrossTaskBackAnimation extends ShellBackAnimation { private static final int BACKGROUNDCOLOR = 0x43433A; /** Loading Loading @@ -104,28 +106,41 @@ class CrossTaskBackAnimation { private final float[] mTmpFloat9 = new float[9]; private final float[] mTmpTranslate = {0, 0, 0}; private final BackAnimationRunner mBackAnimationRunner; private final BackAnimationBackground mBackground; private RemoteAnimationTarget mEnteringTarget; private RemoteAnimationTarget mClosingTarget; private SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction(); private boolean mBackInProgress = false; private boolean mIsRightEdge; private float mProgress = 0; private PointF mTouchPos = new PointF(); private IRemoteAnimationFinishedCallback mFinishCallback; private BackProgressAnimator mProgressAnimator = new BackProgressAnimator(); final BackAnimationRunner mBackAnimationRunner; private final BackAnimationBackground mBackground; CrossTaskBackAnimation(Context context, BackAnimationBackground background) { @Inject public CrossTaskBackAnimation(Context context, BackAnimationBackground background) { mCornerRadius = ScreenDecorationsUtils.getWindowCornerRadius(context); mBackAnimationRunner = new BackAnimationRunner(new Callback(), new Runner()); mBackground = background; } private static void computeScaleTransformMatrix(float scale, float[] matrix) { matrix[0] = scale; matrix[1] = 0; matrix[2] = 0; matrix[3] = 0; matrix[4] = scale; matrix[5] = 0; matrix[6] = 0; matrix[7] = 0; matrix[8] = scale; } private static float mapRange(float value, float min, float max) { return min + (value * (max - min)); } private float getInterpolatedProgress(float backProgress) { return 1 - (1 - backProgress) * (1 - backProgress) * (1 - backProgress); } Loading Loading @@ -233,18 +248,6 @@ class CrossTaskBackAnimation { mTransaction.setColorTransform(leash, mTmpFloat9, mTmpTranslate); } static void computeScaleTransformMatrix(float scale, float[] matrix) { matrix[0] = scale; matrix[1] = 0; matrix[2] = 0; matrix[3] = 0; matrix[4] = scale; matrix[5] = 0; matrix[6] = 0; matrix[7] = 0; matrix[8] = scale; } private void finishAnimation() { if (mEnteringTarget != null) { mEnteringTarget.leash.release(); Loading Loading @@ -314,8 +317,9 @@ class CrossTaskBackAnimation { valueAnimator.start(); } private static float mapRange(float value, float min, float max) { return min + (value * (max - min)); @Override public BackAnimationRunner getRunner() { return mBackAnimationRunner; } private final class Callback extends IOnBackInvokedCallback.Default { Loading @@ -340,7 +344,7 @@ class CrossTaskBackAnimation { mProgressAnimator.reset(); onGestureCommitted(); } }; } private final class Runner extends IRemoteAnimationRunner.Default { @Override Loading @@ -360,5 +364,5 @@ class CrossTaskBackAnimation { startBackAnimation(); mFinishCallback = finishedCallback; } }; } }