Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6855037 authored by Adrian Roos's avatar Adrian Roos Committed by Android (Google) Code Review
Browse files

Merge "RemoteAnimations: Add failsafe" into pi-dev

parents 75165141 842e788f
Loading
Loading
Loading
Loading
+0 −17
Original line number Diff line number Diff line
@@ -42,18 +42,13 @@ import com.android.server.wm.WindowManagerService;
class RecentsAnimation implements RecentsAnimationCallbacks {
    private static final String TAG = RecentsAnimation.class.getSimpleName();

    private static final int RECENTS_ANIMATION_TIMEOUT = 10 * 1000;

    private final ActivityManagerService mService;
    private final ActivityStackSupervisor mStackSupervisor;
    private final ActivityStartController mActivityStartController;
    private final WindowManagerService mWindowManager;
    private final UserController mUserController;
    private final Handler mHandler;
    private final int mCallingPid;

    private final Runnable mCancelAnimationRunnable;

    // The stack to restore the home stack behind when the animation is finished
    private ActivityStack mRestoreHomeBehindStack;

@@ -63,16 +58,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
        mService = am;
        mStackSupervisor = stackSupervisor;
        mActivityStartController = activityStartController;
        mHandler = new Handler(mStackSupervisor.mLooper);
        mWindowManager = wm;
        mUserController = userController;
        mCallingPid = callingPid;

        mCancelAnimationRunnable = () -> {
            // The caller has not finished the animation in a predefined amount of time, so
            // force-cancel the animation
            mWindowManager.cancelRecentsAnimation();
        };
    }

    void startRecentsActivity(Intent intent, IRecentsAnimationRunner recentsAnimationRunner,
@@ -133,10 +121,6 @@ class RecentsAnimation implements RecentsAnimationCallbacks {
            // duration of the gesture that is driven by the recents component
            homeActivity.mLaunchTaskBehind = true;

            // Post a timeout for the animation. This needs to happen before initializing the
            // recents animation on the WM side since we may decide to cancel the animation there
            mHandler.postDelayed(mCancelAnimationRunnable, RECENTS_ANIMATION_TIMEOUT);

            // Fetch all the surface controls and pass them to the client to get the animation
            // started
            mWindowManager.cancelRecentsAnimation();
@@ -157,7 +141,6 @@ class RecentsAnimation implements RecentsAnimationCallbacks {

    @Override
    public void onAnimationFinished(boolean moveHomeToTop) {
        mHandler.removeCallbacks(mCancelAnimationRunnable);
        synchronized (mService) {
            if (mWindowManager.getRecentsAnimationController() == null) return;

+6 −0
Original line number Diff line number Diff line
@@ -1330,6 +1330,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
            mHandler.post(mHiddenNavPanic);
        }

        // Abort possibly stuck animations.
        mHandler.post(mWindowManagerFuncs::triggerAnimationFailsafe);

        // Latch power key state to detect screenshot chord.
        if (interactive && !mScreenshotChordPowerKeyTriggered
                && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
@@ -4362,6 +4365,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
     * given the situation with the keyguard.
     */
    void launchHomeFromHotKey(final boolean awakenFromDreams, final boolean respectKeyguard) {
        // Abort possibly stuck animations.
        mHandler.post(mWindowManagerFuncs::triggerAnimationFailsafe);

        if (respectKeyguard) {
            if (isKeyguardShowingAndNotOccluded()) {
                // don't launch home if keyguard showing
+6 −0
Original line number Diff line number Diff line
@@ -649,6 +649,12 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
                    return Integer.toString(lens);
            }
        }

        /**
         * Hint to window manager that the user has started a navigation action that should
         * abort animations that have no timeout, in case they got stuck.
         */
        void triggerAnimationFailsafe();
    }

    /** Window has been added to the screen. */
+23 −1
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.app.WindowConfiguration;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder.DeathRecipient;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.ArraySet;
@@ -61,15 +62,17 @@ import java.util.ArrayList;
 * window manager when the animation is completed. In addition, window manager may also notify the
 * app if it requires the animation to be canceled at any time (ie. due to timeout, etc.)
 */
public class RecentsAnimationController {
public class RecentsAnimationController implements DeathRecipient {
    private static final String TAG = TAG_WITH_CLASS_NAME ? "RecentsAnimationController" : TAG_WM;
    private static final boolean DEBUG = false;
    private static final long FAILSAFE_DELAY = 1000;

    private final WindowManagerService mService;
    private final IRecentsAnimationRunner mRunner;
    private final RecentsAnimationCallbacks mCallbacks;
    private final ArrayList<TaskAnimationAdapter> mPendingAnimations = new ArrayList<>();
    private final int mDisplayId;
    private final Runnable mFailsafeRunnable = this::cancelAnimation;

    // The recents component app token that is shown behind the visibile tasks
    private AppWindowToken mHomeAppToken;
@@ -223,6 +226,13 @@ public class RecentsAnimationController {
            return;
        }

        try {
            mRunner.asBinder().linkToDeath(this, 0);
        } catch (RemoteException e) {
            cancelAnimation();
            return;
        }

        // Adjust the wallpaper visibility for the showing home activity
        final AppWindowToken recentsComponentAppToken =
                dc.getHomeStack().getTopChild().getTopFullscreenAppToken();
@@ -296,6 +306,7 @@ public class RecentsAnimationController {
                // We've already canceled the animation
                return;
            }
            mService.mH.removeCallbacks(mFailsafeRunnable);
            mCanceled = true;
            try {
                mRunner.onAnimationCanceled();
@@ -321,10 +332,21 @@ public class RecentsAnimationController {
        }
        mPendingAnimations.clear();

        mRunner.asBinder().unlinkToDeath(this, 0);

        mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
        mService.destroyInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION);
    }

    void scheduleFailsafe() {
        mService.mH.postDelayed(mFailsafeRunnable, FAILSAFE_DELAY);
    }

    @Override
    public void binderDied() {
        cancelAnimation();
    }

    void checkAnimationReady(WallpaperController wallpaperController) {
        if (mPendingStart) {
            final boolean wallpaperReady = !isHomeAppOverWallpaper()
+25 −9
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder.DeathRecipient;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Slog;
@@ -47,7 +48,7 @@ import java.util.ArrayList;
/**
 * Helper class to run app animations in a remote process.
 */
class RemoteAnimationController {
class RemoteAnimationController implements DeathRecipient {
    private static final String TAG = TAG_WITH_CLASS_NAME ? "RemoteAnimationController" : TAG_WM;
    private static final long TIMEOUT_MS = 2000;

@@ -56,12 +57,10 @@ class RemoteAnimationController {
    private final ArrayList<RemoteAnimationAdapterWrapper> mPendingAnimations = new ArrayList<>();
    private final Rect mTmpRect = new Rect();
    private final Handler mHandler;
    private FinishedCallback mFinishedCallback;
    private final Runnable mTimeoutRunnable = this::cancelAnimation;

    private final Runnable mTimeoutRunnable = () -> {
        onAnimationFinished();
        invokeAnimationCancelled();
    };
    private FinishedCallback mFinishedCallback;
    private boolean mCanceled;

    RemoteAnimationController(WindowManagerService service,
            RemoteAnimationAdapter remoteAnimationAdapter, Handler handler) {
@@ -90,7 +89,7 @@ class RemoteAnimationController {
     * Called when the transition is ready to be started, and all leashes have been set up.
     */
    void goodToGo() {
        if (mPendingAnimations.isEmpty()) {
        if (mPendingAnimations.isEmpty() || mCanceled) {
            onAnimationFinished();
            return;
        }
@@ -107,8 +106,8 @@ class RemoteAnimationController {
        }
        mService.mAnimator.addAfterPrepareSurfacesRunnable(() -> {
            try {
                mRemoteAnimationAdapter.getRunner().onAnimationStart(animations,
                        mFinishedCallback);
                mRemoteAnimationAdapter.getRunner().asBinder().linkToDeath(this, 0);
                mRemoteAnimationAdapter.getRunner().onAnimationStart(animations, mFinishedCallback);
            } catch (RemoteException e) {
                Slog.e(TAG, "Failed to start remote animation", e);
                onAnimationFinished();
@@ -120,6 +119,17 @@ class RemoteAnimationController {
        }
    }

    private void cancelAnimation() {
        synchronized (mService.getWindowManagerLock()) {
            if (mCanceled) {
                return;
            }
            mCanceled = true;
        }
        onAnimationFinished();
        invokeAnimationCancelled();
    }

    private void writeStartDebugStatement() {
        Slog.i(TAG, "Starting remote animation");
        final StringWriter sw = new StringWriter();
@@ -154,6 +164,7 @@ class RemoteAnimationController {

    private void onAnimationFinished() {
        mHandler.removeCallbacks(mTimeoutRunnable);
        mRemoteAnimationAdapter.getRunner().asBinder().unlinkToDeath(this, 0);
        synchronized (mService.mWindowMap) {
            releaseFinishedCallback();
            mService.openSurfaceTransaction();
@@ -193,6 +204,11 @@ class RemoteAnimationController {
        mService.sendSetRunningRemoteAnimation(pid, running);
    }

    @Override
    public void binderDied() {
        cancelAnimation();
    }

    private static final class FinishedCallback extends IRemoteAnimationFinishedCallback.Stub {

        RemoteAnimationController mOuter;
Loading