Merge "Adding support for clipping window transition for alternate recents."
This commit is contained in:
59
core/java/android/view/animation/ClipRectAnimation.java
Normal file
59
core/java/android/view/animation/ClipRectAnimation.java
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.view.animation;
|
||||
|
||||
import android.graphics.Rect;
|
||||
|
||||
/**
|
||||
* An animation that controls the clip of an object. See the
|
||||
* {@link android.view.animation full package} description for details and
|
||||
* sample code.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class ClipRectAnimation extends Animation {
|
||||
private Rect mFromRect = new Rect();
|
||||
private Rect mToRect = new Rect();
|
||||
|
||||
/**
|
||||
* Constructor to use when building a ClipRectAnimation from code
|
||||
*
|
||||
* @param fromClip the clip rect to animate from
|
||||
* @param toClip the clip rect to animate to
|
||||
*/
|
||||
public ClipRectAnimation(Rect fromClip, Rect toClip) {
|
||||
if (fromClip == null || toClip == null) {
|
||||
throw new RuntimeException("Expected non-null animation clip rects");
|
||||
}
|
||||
mFromRect.set(fromClip);
|
||||
mToRect.set(toClip);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyTransformation(float it, Transformation tr) {
|
||||
int l = mFromRect.left + (int) ((mToRect.left - mFromRect.left) * it);
|
||||
int t = mFromRect.top + (int) ((mToRect.top - mFromRect.top) * it);
|
||||
int r = mFromRect.right + (int) ((mToRect.right - mFromRect.right) * it);
|
||||
int b = mFromRect.bottom + (int) ((mToRect.bottom - mFromRect.bottom) * it);
|
||||
tr.setClipRect(l, t, r, b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willChangeTransformationMatrix() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.view.animation;
|
||||
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Rect;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
|
||||
@@ -47,6 +48,9 @@ public class Transformation {
|
||||
protected float mAlpha;
|
||||
protected int mTransformationType;
|
||||
|
||||
private boolean mHasClipRect;
|
||||
private Rect mClipRect = new Rect();
|
||||
|
||||
/**
|
||||
* Creates a new transformation with alpha = 1 and the identity matrix.
|
||||
*/
|
||||
@@ -65,6 +69,8 @@ public class Transformation {
|
||||
} else {
|
||||
mMatrix.reset();
|
||||
}
|
||||
mClipRect.setEmpty();
|
||||
mHasClipRect = false;
|
||||
mAlpha = 1.0f;
|
||||
mTransformationType = TYPE_BOTH;
|
||||
}
|
||||
@@ -98,9 +104,15 @@ public class Transformation {
|
||||
public void set(Transformation t) {
|
||||
mAlpha = t.getAlpha();
|
||||
mMatrix.set(t.getMatrix());
|
||||
if (t.mHasClipRect) {
|
||||
setClipRect(t.getClipRect());
|
||||
} else {
|
||||
mHasClipRect = false;
|
||||
mClipRect.setEmpty();
|
||||
}
|
||||
mTransformationType = t.getTransformationType();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Apply this Transformation to an existing Transformation, e.g. apply
|
||||
* a scale effect to something that has already been rotated.
|
||||
@@ -109,6 +121,9 @@ public class Transformation {
|
||||
public void compose(Transformation t) {
|
||||
mAlpha *= t.getAlpha();
|
||||
mMatrix.preConcat(t.getMatrix());
|
||||
if (t.mHasClipRect) {
|
||||
setClipRect(t.getClipRect());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,6 +134,9 @@ public class Transformation {
|
||||
public void postCompose(Transformation t) {
|
||||
mAlpha *= t.getAlpha();
|
||||
mMatrix.postConcat(t.getMatrix());
|
||||
if (t.mHasClipRect) {
|
||||
setClipRect(t.getClipRect());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,6 +155,39 @@ public class Transformation {
|
||||
mAlpha = alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current Transform's clip rect
|
||||
* @hide
|
||||
*/
|
||||
public void setClipRect(Rect r) {
|
||||
setClipRect(r.left, r.top, r.right, r.bottom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current Transform's clip rect
|
||||
* @hide
|
||||
*/
|
||||
public void setClipRect(int l, int t, int r, int b) {
|
||||
mClipRect.set(l, t, r, b);
|
||||
mHasClipRect = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current Transform's clip rect
|
||||
* @hide
|
||||
*/
|
||||
public Rect getClipRect() {
|
||||
return mClipRect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the current Transform's clip rect is set
|
||||
* @hide
|
||||
*/
|
||||
public boolean hasClipRect() {
|
||||
return mHasClipRect;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The degree of transparency
|
||||
*/
|
||||
|
||||
@@ -19,18 +19,22 @@ package com.android.server.wm;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Debug;
|
||||
import android.os.Handler;
|
||||
import android.os.IRemoteCallback;
|
||||
import android.os.SystemProperties;
|
||||
import android.util.Slog;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.AlphaAnimation;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationSet;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.view.animation.ClipRectAnimation;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.view.animation.ScaleAnimation;
|
||||
|
||||
import android.view.animation.TranslateAnimation;
|
||||
import com.android.internal.util.DumpUtils.Dump;
|
||||
import com.android.server.AttributeCache;
|
||||
import com.android.server.wm.WindowManagerService.H;
|
||||
@@ -125,6 +129,12 @@ public class AppTransition implements Dump {
|
||||
private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN = 4;
|
||||
private int mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
|
||||
|
||||
// These are the possible states for the enter/exit activities during a thumbnail transition
|
||||
private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_UP = 0;
|
||||
private static final int THUMBNAIL_TRANSITION_EXIT_SCALE_UP = 1;
|
||||
private static final int THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN = 2;
|
||||
private static final int THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN = 3;
|
||||
|
||||
private String mNextAppTransitionPackage;
|
||||
private Bitmap mNextAppTransitionThumbnail;
|
||||
// Used for thumbnail transitions. True if we're scaling up, false if scaling down
|
||||
@@ -148,10 +158,13 @@ public class AppTransition implements Dump {
|
||||
private final Interpolator mThumbnailFadeoutInterpolator;
|
||||
|
||||
private int mCurrentUserId = 0;
|
||||
private boolean mUseAlternateThumbnailAnimation;
|
||||
|
||||
AppTransition(Context context, Handler h) {
|
||||
mContext = context;
|
||||
mH = h;
|
||||
mUseAlternateThumbnailAnimation =
|
||||
SystemProperties.getBoolean("persist.anim.use_alt_thumbnail", false);
|
||||
mConfigShortAnimTime = context.getResources().getInteger(
|
||||
com.android.internal.R.integer.config_shortAnimTime);
|
||||
mDecelerateInterpolator = AnimationUtils.loadInterpolator(context,
|
||||
@@ -384,80 +397,10 @@ public class AppTransition implements Dump {
|
||||
return a;
|
||||
}
|
||||
|
||||
Animation createThumbnailAnimationLocked(int transit, boolean enter, boolean thumb,
|
||||
int appWidth, int appHeight) {
|
||||
Animation a;
|
||||
final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
|
||||
final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
|
||||
final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
|
||||
final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
|
||||
if (thumb) {
|
||||
// Animation for zooming thumbnail from its initial size to
|
||||
// filling the screen.
|
||||
if (mNextAppTransitionScaleUp) {
|
||||
float scaleW = appWidth / thumbWidth;
|
||||
float scaleH = appHeight / thumbHeight;
|
||||
Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
|
||||
computePivot(mNextAppTransitionStartX, 1 / scaleW),
|
||||
computePivot(mNextAppTransitionStartY, 1 / scaleH));
|
||||
scale.setInterpolator(mDecelerateInterpolator);
|
||||
|
||||
Animation alpha = new AlphaAnimation(1, 0);
|
||||
alpha.setInterpolator(mThumbnailFadeoutInterpolator);
|
||||
|
||||
// This AnimationSet uses the Interpolators assigned above.
|
||||
AnimationSet set = new AnimationSet(false);
|
||||
set.addAnimation(scale);
|
||||
set.addAnimation(alpha);
|
||||
a = set;
|
||||
} else {
|
||||
float scaleW = appWidth / thumbWidth;
|
||||
float scaleH = appHeight / thumbHeight;
|
||||
a = new ScaleAnimation(scaleW, 1, scaleH, 1,
|
||||
computePivot(mNextAppTransitionStartX, 1 / scaleW),
|
||||
computePivot(mNextAppTransitionStartY, 1 / scaleH));
|
||||
}
|
||||
} else if (enter) {
|
||||
// Entering app zooms out from the center of the thumbnail.
|
||||
if (mNextAppTransitionScaleUp) {
|
||||
float scaleW = thumbWidth / appWidth;
|
||||
float scaleH = thumbHeight / appHeight;
|
||||
a = new ScaleAnimation(scaleW, 1, scaleH, 1,
|
||||
computePivot(mNextAppTransitionStartX, scaleW),
|
||||
computePivot(mNextAppTransitionStartY, scaleH));
|
||||
} else {
|
||||
// noop animation
|
||||
a = new AlphaAnimation(1, 1);
|
||||
}
|
||||
} else {
|
||||
// Exiting app
|
||||
if (mNextAppTransitionScaleUp) {
|
||||
if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
|
||||
// Fade out while bringing up selected activity. This keeps the
|
||||
// current activity from showing through a launching wallpaper
|
||||
// activity.
|
||||
a = new AlphaAnimation(1, 0);
|
||||
} else {
|
||||
// noop animation
|
||||
a = new AlphaAnimation(1, 1);
|
||||
}
|
||||
} else {
|
||||
float scaleW = thumbWidth / appWidth;
|
||||
float scaleH = thumbHeight / appHeight;
|
||||
Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
|
||||
computePivot(mNextAppTransitionStartX, scaleW),
|
||||
computePivot(mNextAppTransitionStartY, scaleH));
|
||||
|
||||
Animation alpha = new AlphaAnimation(1, 0);
|
||||
|
||||
AnimationSet set = new AnimationSet(true);
|
||||
set.addAnimation(scale);
|
||||
set.addAnimation(alpha);
|
||||
set.setZAdjustment(Animation.ZORDER_TOP);
|
||||
a = set;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the specified animation with a standard duration, interpolator, etc.
|
||||
*/
|
||||
Animation prepareThumbnailAnimation(Animation a, int appWidth, int appHeight, int transit) {
|
||||
// Pick the desired duration. If this is an inter-activity transition,
|
||||
// it is the standard duration for that. Otherwise we use the longer
|
||||
// task transition duration.
|
||||
@@ -478,9 +421,223 @@ public class AppTransition implements Dump {
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current thumbnail transition state.
|
||||
*/
|
||||
int getThumbnailTransitionState(boolean enter) {
|
||||
if (enter) {
|
||||
if (mNextAppTransitionScaleUp) {
|
||||
return THUMBNAIL_TRANSITION_ENTER_SCALE_UP;
|
||||
} else {
|
||||
return THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN;
|
||||
}
|
||||
} else {
|
||||
if (mNextAppTransitionScaleUp) {
|
||||
return THUMBNAIL_TRANSITION_EXIT_SCALE_UP;
|
||||
} else {
|
||||
return THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This animation runs for the thumbnail that gets cross faded with the enter/exit activity
|
||||
* when a thumbnail is specified with the activity options.
|
||||
*/
|
||||
Animation createThumbnailScaleAnimationLocked(int appWidth, int appHeight, int transit) {
|
||||
Animation a;
|
||||
final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
|
||||
final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
|
||||
final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
|
||||
final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
|
||||
|
||||
if (mNextAppTransitionScaleUp) {
|
||||
// Animation for the thumbnail zooming from its initial size to the full screen
|
||||
float scaleW = appWidth / thumbWidth;
|
||||
float scaleH = appHeight / thumbHeight;
|
||||
Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
|
||||
computePivot(mNextAppTransitionStartX, 1 / scaleW),
|
||||
computePivot(mNextAppTransitionStartY, 1 / scaleH));
|
||||
scale.setInterpolator(mDecelerateInterpolator);
|
||||
|
||||
Animation alpha = new AlphaAnimation(1, 0);
|
||||
alpha.setInterpolator(mThumbnailFadeoutInterpolator);
|
||||
|
||||
// This AnimationSet uses the Interpolators assigned above.
|
||||
AnimationSet set = new AnimationSet(false);
|
||||
set.addAnimation(scale);
|
||||
set.addAnimation(alpha);
|
||||
a = set;
|
||||
} else {
|
||||
// Animation for the thumbnail zooming down from the full screen to its final size
|
||||
float scaleW = appWidth / thumbWidth;
|
||||
float scaleH = appHeight / thumbHeight;
|
||||
a = new ScaleAnimation(scaleW, 1, scaleH, 1,
|
||||
computePivot(mNextAppTransitionStartX, 1 / scaleW),
|
||||
computePivot(mNextAppTransitionStartY, 1 / scaleH));
|
||||
}
|
||||
|
||||
return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
|
||||
}
|
||||
|
||||
/**
|
||||
* This alternate animation is created when we are doing a thumbnail transition, for the
|
||||
* activity that is leaving, and the activity that is entering.
|
||||
*/
|
||||
Animation createAlternateThumbnailEnterExitAnimationLocked(int thumbTransitState, int appWidth,
|
||||
int appHeight, int transit,
|
||||
Rect containingFrame, Rect contentInsets) {
|
||||
Animation a;
|
||||
final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
|
||||
final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
|
||||
final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
|
||||
final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
|
||||
|
||||
switch (thumbTransitState) {
|
||||
case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: {
|
||||
// Entering app scales up with the thumbnail
|
||||
float scale = thumbWidth / appWidth;
|
||||
int unscaledThumbHeight = (int) (thumbHeight / scale);
|
||||
int scaledTopDecor = (int) (scale * contentInsets.top);
|
||||
Rect fromClipRect = new Rect(containingFrame);
|
||||
fromClipRect.bottom = (fromClipRect.top + unscaledThumbHeight);
|
||||
Rect toClipRect = new Rect(containingFrame);
|
||||
|
||||
Animation scaleAnim = new ScaleAnimation(scale, 1, scale, 1,
|
||||
computePivot(mNextAppTransitionStartX, scale),
|
||||
computePivot(mNextAppTransitionStartY, scale));
|
||||
Animation alphaAnim = new AlphaAnimation(1, 1);
|
||||
Animation clipAnim = new ClipRectAnimation(fromClipRect, toClipRect);
|
||||
Animation translateAnim = new TranslateAnimation(0, 0, -scaledTopDecor, 0);
|
||||
|
||||
AnimationSet set = new AnimationSet(true);
|
||||
set.addAnimation(alphaAnim);
|
||||
set.addAnimation(clipAnim);
|
||||
set.addAnimation(scaleAnim);
|
||||
set.addAnimation(translateAnim);
|
||||
a = set;
|
||||
break;
|
||||
}
|
||||
case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
|
||||
// Exiting app while the thumbnail is scaling up should fade
|
||||
if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
|
||||
// Fade out while bringing up selected activity. This keeps the
|
||||
// current activity from showing through a launching wallpaper
|
||||
// activity.
|
||||
a = new AlphaAnimation(1, 0);
|
||||
} else {
|
||||
// noop animation
|
||||
a = new AlphaAnimation(1, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: {
|
||||
// Entering the other app, it should just be visible while we scale the thumbnail
|
||||
// down above it
|
||||
a = new AlphaAnimation(1, 1);
|
||||
break;
|
||||
}
|
||||
case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
|
||||
// Exiting the current app, the app should scale down with the thumbnail
|
||||
float scale = thumbWidth / appWidth;
|
||||
int unscaledThumbHeight = (int) (thumbHeight / scale);
|
||||
int scaledTopDecor = (int) (scale * contentInsets.top);
|
||||
Rect fromClipRect = new Rect(containingFrame);
|
||||
Rect toClipRect = new Rect(containingFrame);
|
||||
toClipRect.bottom = (toClipRect.top + unscaledThumbHeight);
|
||||
|
||||
Animation scaleAnim = new ScaleAnimation(1, scale, 1, scale,
|
||||
computePivot(mNextAppTransitionStartX, scale),
|
||||
computePivot(mNextAppTransitionStartY, scale));
|
||||
Animation alphaAnim = new AlphaAnimation(1, 1);
|
||||
Animation clipAnim = new ClipRectAnimation(fromClipRect, toClipRect);
|
||||
Animation translateAnim = new TranslateAnimation(0, 0, 0, -scaledTopDecor);
|
||||
|
||||
AnimationSet set = new AnimationSet(true);
|
||||
set.addAnimation(alphaAnim);
|
||||
set.addAnimation(clipAnim);
|
||||
set.addAnimation(scaleAnim);
|
||||
set.addAnimation(translateAnim);
|
||||
|
||||
a = set;
|
||||
a.setZAdjustment(Animation.ZORDER_TOP);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new RuntimeException("Invalid thumbnail transition state");
|
||||
}
|
||||
|
||||
return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
|
||||
}
|
||||
|
||||
/**
|
||||
* This animation is created when we are doing a thumbnail transition, for the activity that is
|
||||
* leaving, and the activity that is entering.
|
||||
*/
|
||||
Animation createThumbnailEnterExitAnimationLocked(int thumbTransitState, int appWidth,
|
||||
int appHeight, int transit) {
|
||||
Animation a;
|
||||
final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
|
||||
final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
|
||||
final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
|
||||
final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
|
||||
|
||||
switch (thumbTransitState) {
|
||||
case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: {
|
||||
// Entering app scales up with the thumbnail
|
||||
float scaleW = thumbWidth / appWidth;
|
||||
float scaleH = thumbHeight / appHeight;
|
||||
a = new ScaleAnimation(scaleW, 1, scaleH, 1,
|
||||
computePivot(mNextAppTransitionStartX, scaleW),
|
||||
computePivot(mNextAppTransitionStartY, scaleH));
|
||||
break;
|
||||
}
|
||||
case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
|
||||
// Exiting app while the thumbnail is scaling up should fade or stay in place
|
||||
if (transit == TRANSIT_WALLPAPER_INTRA_OPEN) {
|
||||
// Fade out while bringing up selected activity. This keeps the
|
||||
// current activity from showing through a launching wallpaper
|
||||
// activity.
|
||||
a = new AlphaAnimation(1, 0);
|
||||
} else {
|
||||
// noop animation
|
||||
a = new AlphaAnimation(1, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case THUMBNAIL_TRANSITION_ENTER_SCALE_DOWN: {
|
||||
// Entering the other app, it should just be visible while we scale the thumbnail
|
||||
// down above it
|
||||
a = new AlphaAnimation(1, 1);
|
||||
break;
|
||||
}
|
||||
case THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN: {
|
||||
// Exiting the current app, the app should scale down with the thumbnail
|
||||
float scaleW = thumbWidth / appWidth;
|
||||
float scaleH = thumbHeight / appHeight;
|
||||
Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
|
||||
computePivot(mNextAppTransitionStartX, scaleW),
|
||||
computePivot(mNextAppTransitionStartY, scaleH));
|
||||
|
||||
Animation alpha = new AlphaAnimation(1, 0);
|
||||
|
||||
AnimationSet set = new AnimationSet(true);
|
||||
set.addAnimation(scale);
|
||||
set.addAnimation(alpha);
|
||||
set.setZAdjustment(Animation.ZORDER_TOP);
|
||||
a = set;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new RuntimeException("Invalid thumbnail transition state");
|
||||
}
|
||||
|
||||
return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
|
||||
}
|
||||
|
||||
|
||||
Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
|
||||
int appWidth, int appHeight) {
|
||||
int appWidth, int appHeight, Rect containingFrame, Rect contentInsets) {
|
||||
Animation a;
|
||||
if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) {
|
||||
a = loadAnimation(mNextAppTransitionPackage, enter ?
|
||||
@@ -501,7 +658,14 @@ public class AppTransition implements Dump {
|
||||
mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN) {
|
||||
mNextAppTransitionScaleUp =
|
||||
(mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP);
|
||||
a = createThumbnailAnimationLocked(transit, enter, false, appWidth, appHeight);
|
||||
if (mUseAlternateThumbnailAnimation) {
|
||||
a = createAlternateThumbnailEnterExitAnimationLocked(
|
||||
getThumbnailTransitionState(enter), appWidth, appHeight, transit,
|
||||
containingFrame, contentInsets);
|
||||
} else {
|
||||
a = createThumbnailEnterExitAnimationLocked(getThumbnailTransitionState(enter),
|
||||
appWidth, appHeight, transit);
|
||||
}
|
||||
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
|
||||
String animName = mNextAppTransitionScaleUp ?
|
||||
"ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN";
|
||||
|
||||
@@ -3155,7 +3155,22 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
final int height = displayInfo.appHeight;
|
||||
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation: atoken="
|
||||
+ atoken);
|
||||
Animation a = mAppTransition.loadAnimation(lp, transit, enter, width, height);
|
||||
|
||||
// Determine the visible rect to calculate the thumbnail clip
|
||||
WindowState win = atoken.findMainWindow();
|
||||
Rect containingFrame = new Rect(0, 0, width, height);
|
||||
Rect contentInsets = new Rect();
|
||||
if (win != null) {
|
||||
if (win.mContainingFrame != null) {
|
||||
containingFrame.set(win.mContainingFrame);
|
||||
}
|
||||
if (win.mContentInsets != null) {
|
||||
contentInsets.set(win.mContentInsets);
|
||||
}
|
||||
}
|
||||
|
||||
Animation a = mAppTransition.loadAnimation(lp, transit, enter, width, height,
|
||||
containingFrame, contentInsets);
|
||||
if (a != null) {
|
||||
if (DEBUG_ANIM) {
|
||||
RuntimeException e = null;
|
||||
@@ -8608,11 +8623,13 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
wtoken.deferClearAllDrawn = false;
|
||||
}
|
||||
|
||||
boolean useAlternateThumbnailAnimation =
|
||||
SystemProperties.getBoolean("persist.anim.use_alt_thumbnail", false);
|
||||
AppWindowAnimator appAnimator =
|
||||
topOpeningApp == null ? null : topOpeningApp.mAppAnimator;
|
||||
Bitmap nextAppTransitionThumbnail = mAppTransition.getNextAppTransitionThumbnail();
|
||||
if (nextAppTransitionThumbnail != null && appAnimator != null
|
||||
&& appAnimator.animation != null) {
|
||||
if (!useAlternateThumbnailAnimation && nextAppTransitionThumbnail != null
|
||||
&& appAnimator != null && appAnimator.animation != null) {
|
||||
// This thumbnail animation is very special, we need to have
|
||||
// an extra surface with the thumbnail included with the animation.
|
||||
Rect dirty = new Rect(0, 0, nextAppTransitionThumbnail.getWidth(),
|
||||
@@ -8636,8 +8653,8 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
drawSurface.release();
|
||||
appAnimator.thumbnailLayer = topOpeningLayer;
|
||||
DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
|
||||
Animation anim = mAppTransition.createThumbnailAnimationLocked(
|
||||
transit, true, true, displayInfo.appWidth, displayInfo.appHeight);
|
||||
Animation anim = mAppTransition.createThumbnailScaleAnimationLocked(
|
||||
displayInfo.appWidth, displayInfo.appHeight, transit);
|
||||
appAnimator.thumbnailAnimation = anim;
|
||||
anim.restrictDuration(MAX_ANIMATION_DURATION);
|
||||
anim.scaleCurrentDuration(mTransitionAnimationScale);
|
||||
|
||||
@@ -113,6 +113,11 @@ class WindowStateAnimator {
|
||||
float mAlpha = 0;
|
||||
float mLastAlpha = 0;
|
||||
|
||||
boolean mHasClipRect;
|
||||
Rect mClipRect = new Rect();
|
||||
Rect mTmpClipRect = new Rect();
|
||||
Rect mLastClipRect = new Rect();
|
||||
|
||||
// Used to save animation distances between the time they are calculated and when they are
|
||||
// used.
|
||||
int mAnimDw;
|
||||
@@ -951,6 +956,7 @@ class WindowStateAnimator {
|
||||
if (screenAnimation) {
|
||||
tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix());
|
||||
}
|
||||
|
||||
//TODO (multidisplay): Magnification is supported only for the default display.
|
||||
if (mService.mAccessibilityController != null && displayId == Display.DEFAULT_DISPLAY) {
|
||||
MagnificationSpec spec = mService.mAccessibilityController
|
||||
@@ -985,6 +991,7 @@ class WindowStateAnimator {
|
||||
// transforming since it is more important to have that
|
||||
// animation be smooth.
|
||||
mShownAlpha = mAlpha;
|
||||
mHasClipRect = false;
|
||||
if (!mService.mLimitedAlphaCompositing
|
||||
|| (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
|
||||
|| (mWin.isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
|
||||
@@ -998,6 +1005,10 @@ class WindowStateAnimator {
|
||||
}
|
||||
if (appTransformation != null) {
|
||||
mShownAlpha *= appTransformation.getAlpha();
|
||||
if (appTransformation.hasClipRect()) {
|
||||
mClipRect.set(appTransformation.getClipRect());
|
||||
mHasClipRect = true;
|
||||
}
|
||||
}
|
||||
if (mAnimator.mUniverseBackground != null) {
|
||||
mShownAlpha *= mAnimator.mUniverseBackground.mUniverseTransform.getAlpha();
|
||||
@@ -1149,15 +1160,29 @@ class WindowStateAnimator {
|
||||
applyDecorRect(w.mDecorFrame);
|
||||
}
|
||||
|
||||
if (!w.mSystemDecorRect.equals(w.mLastSystemDecorRect)) {
|
||||
w.mLastSystemDecorRect.set(w.mSystemDecorRect);
|
||||
// By default, the clip rect is the system decor rect
|
||||
Rect clipRect = w.mSystemDecorRect;
|
||||
if (mHasClipRect) {
|
||||
|
||||
// If we have an animated clip rect, intersect it with the system decor rect
|
||||
int offsetTop = w.mSystemDecorRect.top;
|
||||
mTmpClipRect.set(w.mSystemDecorRect);
|
||||
mTmpClipRect.offset(0, -offsetTop);
|
||||
mTmpClipRect.intersect(mClipRect);
|
||||
mTmpClipRect.offset(0, offsetTop);
|
||||
clipRect = mTmpClipRect;
|
||||
|
||||
}
|
||||
|
||||
if (!clipRect.equals(mLastClipRect)) {
|
||||
mLastClipRect.set(clipRect);
|
||||
try {
|
||||
if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
|
||||
"CROP " + w.mSystemDecorRect.toShortString(), null);
|
||||
mSurfaceControl.setWindowCrop(w.mSystemDecorRect);
|
||||
"CROP " + clipRect.toShortString(), null);
|
||||
mSurfaceControl.setWindowCrop(clipRect);
|
||||
} catch (RuntimeException e) {
|
||||
Slog.w(TAG, "Error setting crop surface of " + w
|
||||
+ " crop=" + w.mSystemDecorRect.toShortString(), e);
|
||||
+ " crop=" + clipRect.toShortString(), e);
|
||||
if (!recoveringMemory) {
|
||||
mService.reclaimSomeSurfaceMemoryLocked(this, "crop", true);
|
||||
}
|
||||
@@ -1302,8 +1327,8 @@ class WindowStateAnimator {
|
||||
mSurfaceLayer = mAnimLayer;
|
||||
mSurfaceControl.setLayer(mAnimLayer);
|
||||
mSurfaceControl.setMatrix(
|
||||
mDsDx*w.mHScale, mDtDx*w.mVScale,
|
||||
mDsDy*w.mHScale, mDtDy*w.mVScale);
|
||||
mDsDx * w.mHScale, mDtDx * w.mVScale,
|
||||
mDsDy * w.mHScale, mDtDy * w.mVScale);
|
||||
|
||||
if (mLastHidden && mDrawState == HAS_DRAWN) {
|
||||
if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
|
||||
|
||||
Reference in New Issue
Block a user