diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index d73606f3003f4..51b7279c97e8a 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -161,6 +161,7 @@ public class AppTransition implements Dump { private static final int MAX_CLIP_REVEAL_TRANSITION_DURATION = 420; private static final int THUMBNAIL_APP_TRANSITION_DURATION = 336; private static final long APP_TRANSITION_TIMEOUT_MS = 5000; + static final int MAX_APP_TRANSITION_DURATION = 3 * 1000; // 3 secs. private final Context mContext; private final WindowManagerService mService; diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index bd5d35eae77d8..23af7d6755cdf 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -1843,7 +1843,16 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree displayConfig.uiMode, displayConfig.orientation, frame, displayFrame, insets, surfaceInsets, stableInsets, isVoiceInteraction, freeform, getTask().mTaskId); if (a != null) { - if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + this); + if (a != null) { + // Setup the maximum app transition duration to prevent malicious app may set a long + // animation duration or infinite repeat counts for the app transition through + // ActivityOption#makeCustomAnimation or WindowManager#overridePendingTransition. + a.restrictDuration(MAX_APP_TRANSITION_DURATION); + } + if (DEBUG_ANIM) { + logWithStack(TAG, "Loaded animation " + a + " for " + this + + ", duration: " + ((a != null) ? a.getDuration() : 0)); + } final int containingWidth = frame.width(); final int containingHeight = frame.height(); a.initialize(containingWidth, containingHeight, width, height);