diff options
| -rw-r--r-- | services/core/java/com/android/server/wm/AppTransition.java | 109 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowManagerService.java | 38 |
2 files changed, 95 insertions, 52 deletions
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index 7bd0635a814a..a2307f9263ce 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import android.annotation.Nullable; import android.content.Context; import android.content.res.Configuration; import android.graphics.Bitmap; @@ -651,7 +652,7 @@ public class AppTransition implements Dump { * when a thumbnail is specified with the activity options. */ Animation createThumbnailAspectScaleAnimationLocked(int appWidth, int appHeight, - int deviceWidth, int transit) { + int deviceWidth) { Animation a; final int thumbWidthI = mNextAppTransitionThumbnail.getWidth(); final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1; @@ -659,7 +660,6 @@ public class AppTransition implements Dump { final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1; float scaleW = deviceWidth / thumbWidth; - float unscaledWidth = deviceWidth; float unscaledHeight = thumbHeight * scaleW; float unscaledStartY = mNextAppTransitionStartY - (unscaledHeight - thumbHeight) / 2f; if (mNextAppTransitionScaleUp) { @@ -716,7 +716,7 @@ public class AppTransition implements Dump { */ Animation createAspectScaledThumbnailEnterExitAnimationLocked(int thumbTransitState, int appWidth, int appHeight, int orientation, int transit, Rect containingFrame, - Rect contentInsets) { + Rect contentInsets, @Nullable Rect surfaceInsets, boolean resizedWindow) { Animation a; final int thumbWidthI = mNextAppTransitionStartWidth; final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1; @@ -729,40 +729,45 @@ public class AppTransition implements Dump { switch (thumbTransitState) { case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: { - // App window scaling up to become full screen - if (orientation == Configuration.ORIENTATION_PORTRAIT) { - // In portrait, we scale the width and clip to the top/left square - scale = thumbWidth / appWidth; - scaledTopDecor = (int) (scale * contentInsets.top); - int unscaledThumbHeight = (int) (thumbHeight / scale); - mTmpFromClipRect.set(containingFrame); - mTmpFromClipRect.bottom = (mTmpFromClipRect.top + unscaledThumbHeight); - mTmpToClipRect.set(containingFrame); + if (resizedWindow) { + a = createAspectScaledThumbnailEnterNonFullscreenAnimationLocked( + containingFrame, surfaceInsets); } else { - // In landscape, we scale the height and clip to the top/left square - scale = thumbHeight / (appHeight - contentInsets.top); - scaledTopDecor = (int) (scale * contentInsets.top); - int unscaledThumbWidth = (int) (thumbWidth / scale); - mTmpFromClipRect.set(containingFrame); - mTmpFromClipRect.right = (mTmpFromClipRect.left + unscaledThumbWidth); - mTmpToClipRect.set(containingFrame); + // App window scaling up to become full screen + if (orientation == Configuration.ORIENTATION_PORTRAIT) { + // In portrait, we scale the width and clip to the top/left square + scale = thumbWidth / appWidth; + scaledTopDecor = (int) (scale * contentInsets.top); + int unscaledThumbHeight = (int) (thumbHeight / scale); + mTmpFromClipRect.set(containingFrame); + mTmpFromClipRect.bottom = (mTmpFromClipRect.top + unscaledThumbHeight); + mTmpToClipRect.set(containingFrame); + } else { + // In landscape, we scale the height and clip to the top/left square + scale = thumbHeight / (appHeight - contentInsets.top); + scaledTopDecor = (int) (scale * contentInsets.top); + int unscaledThumbWidth = (int) (thumbWidth / scale); + mTmpFromClipRect.set(containingFrame); + mTmpFromClipRect.right = (mTmpFromClipRect.left + unscaledThumbWidth); + mTmpToClipRect.set(containingFrame); + } + // exclude top screen decor (status bar) region from the source clip. + mTmpFromClipRect.top = contentInsets.top; + + mNextAppTransitionInsets.set(contentInsets); + + Animation scaleAnim = new ScaleAnimation(scale, 1, scale, 1, + computePivot(mNextAppTransitionStartX, scale), + computePivot(mNextAppTransitionStartY, scale)); + Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect); + Animation translateAnim = new TranslateAnimation(0, 0, -scaledTopDecor, 0); + + AnimationSet set = new AnimationSet(true); + set.addAnimation(clipAnim); + set.addAnimation(scaleAnim); + set.addAnimation(translateAnim); + a = set; } - // exclude top screen decor (status bar) region from the source clip. - mTmpFromClipRect.top = contentInsets.top; - - mNextAppTransitionInsets.set(contentInsets); - - Animation scaleAnim = new ScaleAnimation(scale, 1, scale, 1, - computePivot(mNextAppTransitionStartX, scale), - computePivot(mNextAppTransitionStartY, scale)); - Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect); - Animation translateAnim = new TranslateAnimation(0, 0, -scaledTopDecor, 0); - - AnimationSet set = new AnimationSet(true); - set.addAnimation(clipAnim); - set.addAnimation(scaleAnim); - set.addAnimation(translateAnim); - a = set; break; } case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: { @@ -836,6 +841,31 @@ public class AppTransition implements Dump { mTouchResponseInterpolator); } + private Animation createAspectScaledThumbnailEnterNonFullscreenAnimationLocked( + Rect containingFrame, @Nullable Rect surfaceInsets) { + float width = containingFrame.width(); + float height = containingFrame.height(); + float scaleWidth = mNextAppTransitionStartWidth / width; + float scaleHeight = mNextAppTransitionStartHeight / height; + AnimationSet set = new AnimationSet(true); + int surfaceInsetsHorizontal = surfaceInsets == null + ? 0 : surfaceInsets.left + surfaceInsets.right; + int surfaceInsetsVertical = surfaceInsets == null + ? 0 : surfaceInsets.top + surfaceInsets.bottom; + // We want the scaling to happen from the center of the surface. In order to achieve that, + // we need to account for surface insets that will be used to enlarge the surface. + ScaleAnimation scale = new ScaleAnimation(scaleWidth, 1, scaleHeight, 1, + (width + surfaceInsetsHorizontal) / 2, (height + surfaceInsetsVertical) / 2); + int fromX = mNextAppTransitionStartX + mNextAppTransitionStartWidth / 2 + - (containingFrame.left + containingFrame.width() / 2); + int fromY = mNextAppTransitionStartY + mNextAppTransitionStartHeight / 2 + - (containingFrame.top + containingFrame.height() / 2); + TranslateAnimation translation = new TranslateAnimation(fromX, 0, fromY, 0); + set.addAnimation(scale); + set.addAnimation(translation); + return set; + } + /** * This animation runs for the thumbnail that gets cross faded with the enter/exit activity * when a thumbnail is specified with the activity options. @@ -881,7 +911,7 @@ public class AppTransition implements Dump { * leaving, and the activity that is entering. */ Animation createThumbnailEnterExitAnimationLocked(int thumbTransitState, int appWidth, - int appHeight, int transit) { + int appHeight, int transit) { Animation a; final int thumbWidthI = mNextAppTransitionThumbnail.getWidth(); final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1; @@ -954,7 +984,8 @@ public class AppTransition implements Dump { Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter, int appWidth, int appHeight, int orientation, Rect containingFrame, Rect contentInsets, - Rect appFrame, boolean isVoiceInteraction) { + @Nullable Rect surfaceInsets, Rect appFrame, boolean isVoiceInteraction, + boolean resizedWindow) { Animation a; if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_OPEN || transit == TRANSIT_TASK_OPEN @@ -1023,8 +1054,8 @@ public class AppTransition implements Dump { mNextAppTransitionScaleUp = (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP); a = createAspectScaledThumbnailEnterExitAnimationLocked( - getThumbnailTransitionState(enter), appWidth, appHeight, orientation, - transit, containingFrame, contentInsets); + getThumbnailTransitionState(enter), appWidth, appHeight, orientation, transit, + containingFrame, contentInsets, surfaceInsets, resizedWindow); if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { String animName = mNextAppTransitionScaleUp ? "ANIM_THUMBNAIL_ASPECT_SCALE_UP" : "ANIM_THUMBNAIL_ASPECT_SCALE_DOWN"; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 9af5e146ef7f..5ec2137167d8 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -3448,8 +3448,8 @@ public class WindowManagerService extends IWindowManager.Stub } } - private boolean applyAnimationLocked(AppWindowToken atoken, - WindowManager.LayoutParams lp, int transit, boolean enter, boolean isVoiceInteraction) { + private boolean applyAnimationLocked(AppWindowToken atoken, WindowManager.LayoutParams lp, + int transit, boolean enter, boolean isVoiceInteraction) { // Only apply an animation if the display isn't frozen. If it is // frozen, there is no reason to animate and it can cause strange // artifacts when we unfreeze the display if some different animation @@ -3466,24 +3466,36 @@ public class WindowManagerService extends IWindowManager.Stub Rect containingFrame = new Rect(0, 0, width, height); Rect contentInsets = new Rect(); Rect appFrame = new Rect(0, 0, width, height); - if (win != null && win.isFullscreen(width, height)) { - // For fullscreen windows use the window frames and insets to set the thumbnail - // clip. For none-fullscreen windows we use the app display region so the clip - // isn't affected by the window insets. + Rect surfaceInsets = null; + final boolean fullscreen = win != null && win.isFullscreen(width, height); + // Dialog activities have windows with containing frame being very large, but not + // exactly fullscreen and much smaller mFrame. We use this distinction to identify + // dialog activities. + final boolean dialogWindow = win != null && !win.mContainingFrame.equals(win.mFrame); + if (win != null) { containingFrame.set(win.mContainingFrame); - contentInsets.set(win.mContentInsets); - appFrame.set(win.mFrame); + surfaceInsets = win.getAttrs().surfaceInsets; + if (fullscreen) { + // For fullscreen windows use the window frames and insets to set the thumbnail + // clip. For none-fullscreen windows we use the app display region so the clip + // isn't affected by the window insets. + contentInsets.set(win.mContentInsets); + appFrame.set(win.mFrame); + } } + final int containingWidth = containingFrame.width(); + final int containingHeight = containingFrame.height(); if (atoken.mLaunchTaskBehind) { // Differentiate the two animations. This one which is briefly on the screen // gets the !enter animation, and the other activity which remains on the // screen gets the enter animation. Both appear in the mOpeningApps set. enter = false; } - Animation a = mAppTransition.loadAnimation(lp, transit, enter, width, height, - mCurConfiguration.orientation, containingFrame, contentInsets, appFrame, - isVoiceInteraction); + final boolean resizedWindow = !fullscreen && !dialogWindow; + Animation a = mAppTransition.loadAnimation(lp, transit, enter, containingWidth, + containingHeight, mCurConfiguration.orientation, containingFrame, contentInsets, + surfaceInsets, appFrame, isVoiceInteraction, resizedWindow); if (a != null) { if (DEBUG_ANIM) { RuntimeException e = null; @@ -3493,7 +3505,7 @@ public class WindowManagerService extends IWindowManager.Stub } Slog.v(TAG, "Loaded animation " + a + " for " + atoken, e); } - atoken.mAppAnimator.setAnimation(a, width, height, + atoken.mAppAnimator.setAnimation(a, containingWidth, containingHeight, mAppTransition.canSkipFirstFrame()); } } else { @@ -9533,7 +9545,7 @@ public class WindowManagerService extends IWindowManager.Stub // open/close animation (only on the way down) anim = mAppTransition.createThumbnailAspectScaleAnimationLocked( displayInfo.appWidth, displayInfo.appHeight, - displayInfo.logicalWidth, transit); + displayInfo.logicalWidth); openingAppAnimator.thumbnailForceAboveLayer = Math.max(topOpeningLayer, topClosingLayer); openingAppAnimator.deferThumbnailDestruction = |