summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/AppTransition.java109
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java38
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 =