Merge "Making transition out of recents look better" into jb-dev

This commit is contained in:
Michael Jurka
2012-05-10 10:35:19 -07:00
committed by Android (Google) Code Review
10 changed files with 161 additions and 35 deletions

View File

@ -98,6 +98,8 @@ public class ActivityOptions {
public static final int ANIM_SCALE_UP = 2; public static final int ANIM_SCALE_UP = 2;
/** @hide */ /** @hide */
public static final int ANIM_THUMBNAIL = 3; public static final int ANIM_THUMBNAIL = 3;
/** @hide */
public static final int ANIM_THUMBNAIL_DELAYED = 4;
private String mPackageName; private String mPackageName;
private int mAnimationType = ANIM_NONE; private int mAnimationType = ANIM_NONE;
@ -219,9 +221,38 @@ public class ActivityOptions {
*/ */
public static ActivityOptions makeThumbnailScaleUpAnimation(View source, public static ActivityOptions makeThumbnailScaleUpAnimation(View source,
Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) { Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, listener, false);
}
/**
* Create an ActivityOptions specifying an animation where a thumbnail
* is scaled from a given position to the new activity window that is
* being started. Before the animation, there is a short delay.
*
* @param source The View that this thumbnail is animating from. This
* defines the coordinate space for <var>startX</var> and <var>startY</var>.
* @param thumbnail The bitmap that will be shown as the initial thumbnail
* of the animation.
* @param startX The x starting location of the bitmap, relative to <var>source</var>.
* @param startY The y starting location of the bitmap, relative to <var>source</var>.
* @param listener Optional OnAnimationStartedListener to find out when the
* requested animation has started running. If for some reason the animation
* is not executed, the callback will happen immediately.
* @return Returns a new ActivityOptions object that you can use to
* supply these options as the options Bundle when starting an activity.
* @hide
*/
public static ActivityOptions makeDelayedThumbnailScaleUpAnimation(View source,
Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener) {
return makeThumbnailScaleUpAnimation(source, thumbnail, startX, startY, listener, true);
}
private static ActivityOptions makeThumbnailScaleUpAnimation(View source,
Bitmap thumbnail, int startX, int startY, OnAnimationStartedListener listener,
boolean delayed) {
ActivityOptions opts = new ActivityOptions(); ActivityOptions opts = new ActivityOptions();
opts.mPackageName = source.getContext().getPackageName(); opts.mPackageName = source.getContext().getPackageName();
opts.mAnimationType = ANIM_THUMBNAIL; opts.mAnimationType = delayed ? ANIM_THUMBNAIL_DELAYED : ANIM_THUMBNAIL;
opts.mThumbnail = thumbnail; opts.mThumbnail = thumbnail;
int[] pts = new int[2]; int[] pts = new int[2];
source.getLocationOnScreen(pts); source.getLocationOnScreen(pts);
@ -258,7 +289,8 @@ public class ActivityOptions {
mStartY = opts.getInt(KEY_ANIM_START_Y, 0); mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
mStartWidth = opts.getInt(KEY_ANIM_START_WIDTH, 0); mStartWidth = opts.getInt(KEY_ANIM_START_WIDTH, 0);
mStartHeight = opts.getInt(KEY_ANIM_START_HEIGHT, 0); mStartHeight = opts.getInt(KEY_ANIM_START_HEIGHT, 0);
} else if (mAnimationType == ANIM_THUMBNAIL) { } else if (mAnimationType == ANIM_THUMBNAIL ||
mAnimationType == ANIM_THUMBNAIL_DELAYED) {
mThumbnail = (Bitmap)opts.getParcelable(KEY_ANIM_THUMBNAIL); mThumbnail = (Bitmap)opts.getParcelable(KEY_ANIM_THUMBNAIL);
mStartX = opts.getInt(KEY_ANIM_START_X, 0); mStartX = opts.getInt(KEY_ANIM_START_X, 0);
mStartY = opts.getInt(KEY_ANIM_START_Y, 0); mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
@ -359,6 +391,7 @@ public class ActivityOptions {
mStartHeight = otherOptions.mStartHeight; mStartHeight = otherOptions.mStartHeight;
break; break;
case ANIM_THUMBNAIL: case ANIM_THUMBNAIL:
case ANIM_THUMBNAIL_DELAYED:
mAnimationType = otherOptions.mAnimationType; mAnimationType = otherOptions.mAnimationType;
mThumbnail = otherOptions.mThumbnail; mThumbnail = otherOptions.mThumbnail;
mStartX = otherOptions.mStartX; mStartX = otherOptions.mStartX;
@ -401,6 +434,7 @@ public class ActivityOptions {
b.putInt(KEY_ANIM_START_HEIGHT, mStartHeight); b.putInt(KEY_ANIM_START_HEIGHT, mStartHeight);
break; break;
case ANIM_THUMBNAIL: case ANIM_THUMBNAIL:
case ANIM_THUMBNAIL_DELAYED:
b.putInt(KEY_ANIM_TYPE, mAnimationType); b.putInt(KEY_ANIM_TYPE, mAnimationType);
b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail); b.putParcelable(KEY_ANIM_THUMBNAIL, mThumbnail);
b.putInt(KEY_ANIM_START_X, mStartX); b.putInt(KEY_ANIM_START_X, mStartX);

View File

@ -84,7 +84,7 @@ interface IWindowManager
void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth, void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
int startHeight); int startHeight);
void overridePendingAppTransitionThumb(in Bitmap srcThumb, int startX, int startY, void overridePendingAppTransitionThumb(in Bitmap srcThumb, int startX, int startY,
IRemoteCallback startedCallback); IRemoteCallback startedCallback, boolean delayed);
void executeAppTransition(); void executeAppTransition();
void setAppStartingWindow(IBinder token, String pkg, int theme, void setAppStartingWindow(IBinder token, String pkg, int theme,
in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes, in CompatibilityInfo compatInfo, CharSequence nonLocalizedLabel, int labelRes,

View File

@ -27,6 +27,12 @@
systemui:recentItemLayout="@layout/status_bar_recent_item" systemui:recentItemLayout="@layout/status_bar_recent_item"
> >
<ImageView
android:id="@+id/recents_transition_placeholder_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible" />
<FrameLayout <FrameLayout
android:id="@+id/recents_bg_protect" android:id="@+id/recents_bg_protect"
android:background="@drawable/status_bar_recents_background" android:background="@drawable/status_bar_recents_background"

View File

@ -27,6 +27,12 @@
systemui:recentItemLayout="@layout/status_bar_recent_item" systemui:recentItemLayout="@layout/status_bar_recent_item"
> >
<ImageView
android:id="@+id/recents_transition_placeholder_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible" />
<FrameLayout <FrameLayout
android:id="@+id/recents_bg_protect" android:id="@+id/recents_bg_protect"
android:background="@drawable/status_bar_recents_background" android:background="@drawable/status_bar_recents_background"

View File

@ -39,6 +39,12 @@
android:clipToPadding="false" android:clipToPadding="false"
android:clipChildren="false"> android:clipChildren="false">
<ImageView
android:id="@+id/recents_transition_placeholder_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible" />
<com.android.systemui.recent.RecentsVerticalScrollView android:id="@+id/recents_container" <com.android.systemui.recent.RecentsVerticalScrollView android:id="@+id/recents_container"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -21,21 +21,21 @@ import android.animation.AnimatorSet;
import android.animation.AnimatorSet.Builder; import android.animation.AnimatorSet.Builder;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.util.Log;
import android.util.Slog; import android.util.Slog;
import android.view.View; import android.view.View;
import android.view.ViewRootImpl;
/* package */ class Choreographer implements Animator.AnimatorListener { /* package */ class Choreographer implements Animator.AnimatorListener {
// should group this into a multi-property animation // should group this into a multi-property animation
private static final int OPEN_DURATION = 136; private static final int OPEN_DURATION = 136;
private static final int CLOSE_DURATION = 250; private static final int CLOSE_DURATION = 130;
private static final int SCRIM_DURATION = 400; private static final int SCRIM_DURATION = 400;
private static final String TAG = RecentsPanelView.TAG; private static final String TAG = RecentsPanelView.TAG;
private static final boolean DEBUG = RecentsPanelView.DEBUG; private static final boolean DEBUG = RecentsPanelView.DEBUG;
boolean mVisible; boolean mVisible;
int mPanelHeight; int mPanelHeight;
View mRootView; RecentsPanelView mRootView;
View mScrimView; View mScrimView;
View mContentView; View mContentView;
View mNoRecentAppsView; View mNoRecentAppsView;
@ -45,7 +45,7 @@ import android.view.View;
// the panel will start to appear this many px from the end // the panel will start to appear this many px from the end
final int HYPERSPACE_OFFRAMP = 200; final int HYPERSPACE_OFFRAMP = 200;
public Choreographer(View root, View scrim, View content, public Choreographer(RecentsPanelView root, View scrim, View content,
View noRecentApps, Animator.AnimatorListener listener) { View noRecentApps, Animator.AnimatorListener listener) {
mRootView = root; mRootView = root;
mScrimView = scrim; mScrimView = scrim;
@ -67,7 +67,7 @@ import android.view.View;
end = 0; end = 0;
} else { } else {
start = y; start = y;
end = y + HYPERSPACE_OFFRAMP; end = y;
} }
Animator posAnim = ObjectAnimator.ofFloat(mContentView, "translationY", Animator posAnim = ObjectAnimator.ofFloat(mContentView, "translationY",
@ -77,12 +77,12 @@ import android.view.View;
: new android.view.animation.AccelerateInterpolator(2.5f)); : new android.view.animation.AccelerateInterpolator(2.5f));
posAnim.setDuration(appearing ? OPEN_DURATION : CLOSE_DURATION); posAnim.setDuration(appearing ? OPEN_DURATION : CLOSE_DURATION);
Animator glowAnim = ObjectAnimator.ofFloat(mContentView, "alpha", Animator fadeAnim = ObjectAnimator.ofFloat(mContentView, "alpha",
mContentView.getAlpha(), appearing ? 1.0f : 0.0f); mContentView.getAlpha(), appearing ? 1.0f : 0.0f);
glowAnim.setInterpolator(appearing fadeAnim.setInterpolator(appearing
? new android.view.animation.AccelerateInterpolator(1.0f) ? new android.view.animation.AccelerateInterpolator(1.0f)
: new android.view.animation.DecelerateInterpolator(1.0f)); : new android.view.animation.DecelerateInterpolator(1.0f));
glowAnim.setDuration(appearing ? OPEN_DURATION : CLOSE_DURATION); fadeAnim.setDuration(appearing ? OPEN_DURATION : CLOSE_DURATION);
Animator noRecentAppsFadeAnim = null; Animator noRecentAppsFadeAnim = null;
if (mNoRecentAppsView != null && // doesn't exist on large devices if (mNoRecentAppsView != null && // doesn't exist on large devices
@ -96,7 +96,7 @@ import android.view.View;
} }
mContentAnim = new AnimatorSet(); mContentAnim = new AnimatorSet();
final Builder builder = mContentAnim.play(glowAnim).with(posAnim); final Builder builder = mContentAnim.play(fadeAnim).with(posAnim);
if (noRecentAppsFadeAnim != null) { if (noRecentAppsFadeAnim != null) {
builder.with(noRecentAppsFadeAnim); builder.with(noRecentAppsFadeAnim);
@ -153,9 +153,10 @@ import android.view.View;
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
if (DEBUG) Slog.d(TAG, "onAnimationEnd"); if (DEBUG) Slog.d(TAG, "onAnimationEnd");
if (!mVisible) { if (!mVisible) {
mRootView.setVisibility(View.GONE); mRootView.hideWindow();
} }
mContentView.setLayerType(View.LAYER_TYPE_NONE, null); mContentView.setLayerType(View.LAYER_TYPE_NONE, null);
mContentView.setAlpha(1f);
mContentAnim = null; mContentAnim = null;
} }

View File

@ -26,7 +26,9 @@ import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix; import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.Shader.TileMode; import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
@ -48,11 +50,9 @@ import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ImageView.ScaleType; import android.widget.ImageView.ScaleType;
import android.widget.PopupMenu; import android.widget.PopupMenu;
import android.widget.ScrollView;
import android.widget.TextView; import android.widget.TextView;
import com.android.systemui.R; import com.android.systemui.R;
@ -83,6 +83,9 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
private Choreographer mChoreo; private Choreographer mChoreo;
OnRecentsPanelVisibilityChangedListener mVisibilityChangedListener; OnRecentsPanelVisibilityChangedListener mVisibilityChangedListener;
ImageView mPlaceholderThumbnail;
boolean mHideWindowAfterPlaceholderThumbnailIsHidden;
private RecentTasksLoader mRecentTasksLoader; private RecentTasksLoader mRecentTasksLoader;
private ArrayList<TaskDescription> mRecentTaskDescriptions; private ArrayList<TaskDescription> mRecentTaskDescriptions;
private Runnable mPreloadTasksRunnable; private Runnable mPreloadTasksRunnable;
@ -283,7 +286,9 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
public void show(boolean show, boolean animate, public void show(boolean show, boolean animate,
ArrayList<TaskDescription> recentTaskDescriptions, boolean firstScreenful) { ArrayList<TaskDescription> recentTaskDescriptions, boolean firstScreenful) {
// For now, disable animations. We may want to re-enable in the future // For now, disable animations. We may want to re-enable in the future
if (show) {
animate = false; animate = false;
}
if (show) { if (show) {
// Need to update list of recent apps before we set visibility so this view's // Need to update list of recent apps before we set visibility so this view's
// content description is updated before it gets focus for TalkBack mode // content description is updated before it gets focus for TalkBack mode
@ -687,11 +692,31 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
context.getSystemService(Context.ACTIVITY_SERVICE); context.getSystemService(Context.ACTIVITY_SERVICE);
holder.thumbnailViewImage.setDrawingCacheEnabled(true); holder.thumbnailViewImage.setDrawingCacheEnabled(true);
Bitmap bm = holder.thumbnailViewImage.getDrawingCache(); Bitmap bm = holder.thumbnailViewImage.getDrawingCache();
ActivityOptions opts = ActivityOptions.makeThumbnailScaleUpAnimation( mPlaceholderThumbnail = (ImageView) findViewById(R.id.recents_transition_placeholder_icon);
final ImageView placeholderThumbnail = mPlaceholderThumbnail;
mHideWindowAfterPlaceholderThumbnailIsHidden = false;
placeholderThumbnail.setVisibility(VISIBLE);
Bitmap b2 = bm.copy(bm.getConfig(), true);
placeholderThumbnail.setImageBitmap(b2);
Rect r = new Rect();
holder.thumbnailViewImage.getGlobalVisibleRect(r);
placeholderThumbnail.setTranslationX(r.left);
placeholderThumbnail.setTranslationY(r.top);
show(false, true);
ActivityOptions opts = ActivityOptions.makeDelayedThumbnailScaleUpAnimation(
holder.thumbnailViewImage, bm, 0, 0, holder.thumbnailViewImage, bm, 0, 0,
new ActivityOptions.OnAnimationStartedListener() { new ActivityOptions.OnAnimationStartedListener() {
@Override public void onAnimationStarted() { @Override public void onAnimationStarted() {
hide(true); mPlaceholderThumbnail = null;
placeholderThumbnail.setVisibility(INVISIBLE);
if (mHideWindowAfterPlaceholderThumbnailIsHidden) {
hideWindow();
}
} }
}); });
if (ad.taskId >= 0) { if (ad.taskId >= 0) {
@ -709,6 +734,15 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
holder.thumbnailViewImage.setDrawingCacheEnabled(false); holder.thumbnailViewImage.setDrawingCacheEnabled(false);
} }
public void hideWindow() {
if (mPlaceholderThumbnail != null) {
mHideWindowAfterPlaceholderThumbnailIsHidden = true;
} else {
setVisibility(GONE);
mHideWindowAfterPlaceholderThumbnailIsHidden = false;
}
}
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
handleOnClick(view); handleOnClick(view);
} }

View File

@ -552,7 +552,8 @@ final class ActivityRecord {
void applyOptionsLocked() { void applyOptionsLocked() {
if (pendingOptions != null) { if (pendingOptions != null) {
switch (pendingOptions.getAnimationType()) { final int animationType = pendingOptions.getAnimationType();
switch (animationType) {
case ActivityOptions.ANIM_CUSTOM: case ActivityOptions.ANIM_CUSTOM:
service.mWindowManager.overridePendingAppTransition( service.mWindowManager.overridePendingAppTransition(
pendingOptions.getPackageName(), pendingOptions.getPackageName(),
@ -571,10 +572,13 @@ final class ActivityRecord {
} }
break; break;
case ActivityOptions.ANIM_THUMBNAIL: case ActivityOptions.ANIM_THUMBNAIL:
case ActivityOptions.ANIM_THUMBNAIL_DELAYED:
boolean delayed = (animationType == ActivityOptions.ANIM_THUMBNAIL_DELAYED);
service.mWindowManager.overridePendingAppTransitionThumb( service.mWindowManager.overridePendingAppTransitionThumb(
pendingOptions.getThumbnail(), pendingOptions.getThumbnail(),
pendingOptions.getStartX(), pendingOptions.getStartY(), pendingOptions.getStartX(), pendingOptions.getStartY(),
pendingOptions.getOnAnimationStartListener()); pendingOptions.getOnAnimationStartListener(),
delayed);
if (intent.getSourceBounds() == null) { if (intent.getSourceBounds() == null) {
intent.setSourceBounds(new Rect(pendingOptions.getStartX(), intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
pendingOptions.getStartY(), pendingOptions.getStartY(),

View File

@ -512,6 +512,7 @@ public class WindowManagerService extends IWindowManager.Stub
int mNextAppTransitionType = ActivityOptions.ANIM_NONE; int mNextAppTransitionType = ActivityOptions.ANIM_NONE;
String mNextAppTransitionPackage; String mNextAppTransitionPackage;
Bitmap mNextAppTransitionThumbnail; Bitmap mNextAppTransitionThumbnail;
boolean mNextAppTransitionDelayed;
IRemoteCallback mNextAppTransitionCallback; IRemoteCallback mNextAppTransitionCallback;
int mNextAppTransitionEnter; int mNextAppTransitionEnter;
int mNextAppTransitionExit; int mNextAppTransitionExit;
@ -3176,7 +3177,7 @@ public class WindowManagerService extends IWindowManager.Stub
} }
private Animation createThumbnailAnimationLocked(int transit, private Animation createThumbnailAnimationLocked(int transit,
boolean enter, boolean thumb) { boolean enter, boolean thumb, boolean delayed) {
Animation a; Animation a;
final int thumbWidthI = mNextAppTransitionThumbnail.getWidth(); final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1; final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
@ -3186,6 +3187,7 @@ public class WindowManagerService extends IWindowManager.Stub
// it is the standard duration for that. Otherwise we use the longer // it is the standard duration for that. Otherwise we use the longer
// task transition duration. // task transition duration.
int duration; int duration;
int delayDuration = delayed ? 200 : 0;
switch (transit) { switch (transit) {
case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN: case WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN:
case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE: case WindowManagerPolicy.TRANSIT_ACTIVITY_CLOSE:
@ -3193,7 +3195,7 @@ public class WindowManagerService extends IWindowManager.Stub
com.android.internal.R.integer.config_shortAnimTime); com.android.internal.R.integer.config_shortAnimTime);
break; break;
default: default:
duration = 300; duration = delayed ? 200 : 300;
break; break;
} }
if (thumb) { if (thumb) {
@ -3201,6 +3203,7 @@ public class WindowManagerService extends IWindowManager.Stub
// filling the screen. // filling the screen.
float scaleW = mAppDisplayWidth/thumbWidth; float scaleW = mAppDisplayWidth/thumbWidth;
float scaleH = mAppDisplayHeight/thumbHeight; float scaleH = mAppDisplayHeight/thumbHeight;
Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH, Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
computePivot(mNextAppTransitionStartX, 1/scaleW), computePivot(mNextAppTransitionStartX, 1/scaleW),
computePivot(mNextAppTransitionStartY, 1/scaleH)); computePivot(mNextAppTransitionStartY, 1/scaleH));
@ -3210,17 +3213,38 @@ public class WindowManagerService extends IWindowManager.Stub
set.addAnimation(scale); set.addAnimation(scale);
alpha.setDuration(duration); alpha.setDuration(duration);
set.addAnimation(alpha); set.addAnimation(alpha);
set.setFillBefore(true);
if (delayDuration > 0) {
set.setStartOffset(delayDuration);
}
a = set; a = set;
} else if (enter) { } else if (enter) {
// Entering app zooms out from the center of the thumbnail. // Entering app zooms out from the center of the thumbnail.
float scaleW = thumbWidth / mAppDisplayWidth; float scaleW = thumbWidth / mAppDisplayWidth;
float scaleH = thumbHeight / mAppDisplayHeight; float scaleH = thumbHeight / mAppDisplayHeight;
a = new ScaleAnimation(scaleW, 1, scaleH, 1, AnimationSet set = new AnimationSet(true);
Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
computePivot(mNextAppTransitionStartX, scaleW), computePivot(mNextAppTransitionStartX, scaleW),
computePivot(mNextAppTransitionStartY, scaleH)); computePivot(mNextAppTransitionStartY, scaleH));
a.setDuration(duration); scale.setDuration(duration);
scale.setFillBefore(true);
set.addAnimation(scale);
// Need to set an alpha animation on the entering app window
// in case it appears one frame before the thumbnail window
// (this solves flicker)
Animation alpha = new AlphaAnimation(0, 1);
alpha.setDuration(1);
alpha.setFillAfter(true);
set.addAnimation(alpha);
a = set;
if (delayDuration > 0) {
a.setStartOffset(delayDuration);
}
} else { } else {
a = createExitAnimationLocked(transit, duration); a = createExitAnimationLocked(transit, duration);
if (delayDuration > 0) {
a.setStartOffset(delayDuration);
}
} }
a.setFillAfter(true); a.setFillAfter(true);
final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext, final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
@ -3252,12 +3276,18 @@ public class WindowManagerService extends IWindowManager.Stub
if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
+ " anim=" + a + " nextAppTransition=ANIM_SCALE_UP" + " anim=" + a + " nextAppTransition=ANIM_SCALE_UP"
+ " transit=" + transit + " Callers " + Debug.getCallers(3)); + " transit=" + transit + " Callers " + Debug.getCallers(3));
} else if (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL) { } else if (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL ||
a = createThumbnailAnimationLocked(transit, enter, false); mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_DELAYED) {
boolean delayed = (mNextAppTransitionType == ActivityOptions.ANIM_THUMBNAIL_DELAYED);
a = createThumbnailAnimationLocked(transit, enter, false, delayed);
initialized = true; initialized = true;
if (DEBUG_ANIM) Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
+ " anim=" + a + " nextAppTransition=ANIM_THUMBNAIL" if (DEBUG_ANIM) {
String animName = delayed ? "ANIM_THUMBNAIL_DELAYED" : "ANIM_THUMBNAIL";
Slog.v(TAG, "applyAnimation: wtoken=" + wtoken
+ " anim=" + a + " nextAppTransition=" + animName
+ " transit=" + transit + " Callers " + Debug.getCallers(3)); + " transit=" + transit + " Callers " + Debug.getCallers(3));
}
} else { } else {
int animAttr = 0; int animAttr = 0;
switch (transit) { switch (transit) {
@ -3879,11 +3909,13 @@ public class WindowManagerService extends IWindowManager.Stub
} }
public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX,
int startY, IRemoteCallback startedCallback) { int startY, IRemoteCallback startedCallback, boolean delayed) {
if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) { if (mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
mNextAppTransitionType = ActivityOptions.ANIM_THUMBNAIL; mNextAppTransitionType =
delayed ? ActivityOptions.ANIM_THUMBNAIL_DELAYED : ActivityOptions.ANIM_THUMBNAIL;
mNextAppTransitionPackage = null; mNextAppTransitionPackage = null;
mNextAppTransitionThumbnail = srcThumb; mNextAppTransitionThumbnail = srcThumb;
mNextAppTransitionDelayed = delayed;
mNextAppTransitionStartX = startX; mNextAppTransitionStartX = startX;
mNextAppTransitionStartY = startY; mNextAppTransitionStartY = startY;
mNextAppTransitionCallback = startedCallback; mNextAppTransitionCallback = startedCallback;
@ -8024,7 +8056,8 @@ public class WindowManagerService extends IWindowManager.Stub
drawSurface.unlockCanvasAndPost(c); drawSurface.unlockCanvasAndPost(c);
drawSurface.release(); drawSurface.release();
topOpeningApp.mAppAnimator.thumbnailLayer = topOpeningLayer; topOpeningApp.mAppAnimator.thumbnailLayer = topOpeningLayer;
Animation anim = createThumbnailAnimationLocked(transit, true, true); Animation anim = createThumbnailAnimationLocked(
transit, true, true, mNextAppTransitionDelayed);
topOpeningApp.mAppAnimator.thumbnailAnimation = anim; topOpeningApp.mAppAnimator.thumbnailAnimation = anim;
anim.restrictDuration(MAX_ANIMATION_DURATION); anim.restrictDuration(MAX_ANIMATION_DURATION);
anim.scaleCurrentDuration(mTransitionAnimationScale); anim.scaleCurrentDuration(mTransitionAnimationScale);
@ -9602,10 +9635,12 @@ public class WindowManagerService extends IWindowManager.Stub
pw.println(mNextAppTransitionStartHeight); pw.println(mNextAppTransitionStartHeight);
break; break;
case ActivityOptions.ANIM_THUMBNAIL: case ActivityOptions.ANIM_THUMBNAIL:
case ActivityOptions.ANIM_THUMBNAIL_DELAYED:
pw.print(" mNextAppTransitionThumbnail="); pw.print(" mNextAppTransitionThumbnail=");
pw.print(mNextAppTransitionThumbnail); pw.print(mNextAppTransitionThumbnail);
pw.print(" mNextAppTransitionStartX="); pw.print(mNextAppTransitionStartX); pw.print(" mNextAppTransitionStartX="); pw.print(mNextAppTransitionStartX);
pw.print(" mNextAppTransitionStartY="); pw.println(mNextAppTransitionStartY); pw.print(" mNextAppTransitionStartY="); pw.println(mNextAppTransitionStartY);
pw.print(" mNextAppTransitionDelayed="); pw.println(mNextAppTransitionDelayed);
break; break;
} }
pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition); pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);

View File

@ -240,7 +240,7 @@ public class BridgeWindowManager implements IWindowManager {
@Override @Override
public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY, public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY,
IRemoteCallback startedCallback) throws RemoteException { IRemoteCallback startedCallback, boolean delayed) throws RemoteException {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }