Loading services/core/java/com/android/server/am/RecentsAnimation.java +0 −17 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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, Loading Loading @@ -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(); Loading @@ -157,7 +141,6 @@ class RecentsAnimation implements RecentsAnimationCallbacks { @Override public void onAnimationFinished(boolean moveHomeToTop) { mHandler.removeCallbacks(mCancelAnimationRunnable); synchronized (mService) { if (mWindowManager.getRecentsAnimationController() == null) return; Loading services/core/java/com/android/server/policy/PhoneWindowManager.java +6 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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 Loading services/core/java/com/android/server/policy/WindowManagerPolicy.java +6 −0 Original line number Diff line number Diff line Loading @@ -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. */ Loading services/core/java/com/android/server/wm/RecentsAnimationController.java +23 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -296,6 +306,7 @@ public class RecentsAnimationController { // We've already canceled the animation return; } mService.mH.removeCallbacks(mFailsafeRunnable); mCanceled = true; try { mRunner.onAnimationCanceled(); Loading @@ -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() Loading services/core/java/com/android/server/wm/RemoteAnimationController.java +25 −9 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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) { Loading Loading @@ -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; } Loading @@ -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(); Loading @@ -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(); Loading Loading @@ -154,6 +164,7 @@ class RemoteAnimationController { private void onAnimationFinished() { mHandler.removeCallbacks(mTimeoutRunnable); mRemoteAnimationAdapter.getRunner().asBinder().unlinkToDeath(this, 0); synchronized (mService.mWindowMap) { releaseFinishedCallback(); mService.openSurfaceTransaction(); Loading Loading @@ -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 Loading
services/core/java/com/android/server/am/RecentsAnimation.java +0 −17 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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, Loading Loading @@ -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(); Loading @@ -157,7 +141,6 @@ class RecentsAnimation implements RecentsAnimationCallbacks { @Override public void onAnimationFinished(boolean moveHomeToTop) { mHandler.removeCallbacks(mCancelAnimationRunnable); synchronized (mService) { if (mWindowManager.getRecentsAnimationController() == null) return; Loading
services/core/java/com/android/server/policy/PhoneWindowManager.java +6 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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 Loading
services/core/java/com/android/server/policy/WindowManagerPolicy.java +6 −0 Original line number Diff line number Diff line Loading @@ -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. */ Loading
services/core/java/com/android/server/wm/RecentsAnimationController.java +23 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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(); Loading Loading @@ -296,6 +306,7 @@ public class RecentsAnimationController { // We've already canceled the animation return; } mService.mH.removeCallbacks(mFailsafeRunnable); mCanceled = true; try { mRunner.onAnimationCanceled(); Loading @@ -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() Loading
services/core/java/com/android/server/wm/RemoteAnimationController.java +25 −9 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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) { Loading Loading @@ -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; } Loading @@ -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(); Loading @@ -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(); Loading Loading @@ -154,6 +164,7 @@ class RemoteAnimationController { private void onAnimationFinished() { mHandler.removeCallbacks(mTimeoutRunnable); mRemoteAnimationAdapter.getRunner().asBinder().unlinkToDeath(this, 0); synchronized (mService.mWindowMap) { releaseFinishedCallback(); mService.openSurfaceTransaction(); Loading Loading @@ -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