Merge "Introduce new API overrideActivityTransition(1/N)"
This commit is contained in:
committed by
Android (Google) Code Review
commit
5b839395dd
@@ -4319,6 +4319,7 @@ package android.app {
|
||||
@UiContext public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
|
||||
ctor public Activity();
|
||||
method public void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
|
||||
method public void clearOverrideActivityTransition(int);
|
||||
method public void closeContextMenu();
|
||||
method public void closeOptionsMenu();
|
||||
method public android.app.PendingIntent createPendingResult(int, @NonNull android.content.Intent, int);
|
||||
@@ -4487,6 +4488,8 @@ package android.app {
|
||||
method @Nullable public android.view.ActionMode onWindowStartingActionMode(android.view.ActionMode.Callback, int);
|
||||
method public void openContextMenu(android.view.View);
|
||||
method public void openOptionsMenu();
|
||||
method public void overrideActivityTransition(int, @AnimRes int, @AnimRes int);
|
||||
method public void overrideActivityTransition(int, @AnimRes int, @AnimRes int, @ColorInt int);
|
||||
method public void overridePendingTransition(int, int);
|
||||
method public void overridePendingTransition(int, int, int);
|
||||
method public void postponeEnterTransition();
|
||||
@@ -4588,6 +4591,8 @@ package android.app {
|
||||
field protected static final int[] FOCUSED_STATE_SET;
|
||||
field public static final int FULLSCREEN_MODE_REQUEST_ENTER = 1; // 0x1
|
||||
field public static final int FULLSCREEN_MODE_REQUEST_EXIT = 0; // 0x0
|
||||
field public static final int OVERRIDE_TRANSITION_CLOSE = 1; // 0x1
|
||||
field public static final int OVERRIDE_TRANSITION_OPEN = 0; // 0x0
|
||||
field public static final int RESULT_CANCELED = 0; // 0x0
|
||||
field public static final int RESULT_FIRST_USER = 1; // 0x1
|
||||
field public static final int RESULT_OK = -1; // 0xffffffff
|
||||
|
||||
@@ -26,8 +26,10 @@ import static android.os.Process.myUid;
|
||||
|
||||
import static java.lang.Character.MIN_VALUE;
|
||||
|
||||
import android.annotation.AnimRes;
|
||||
import android.annotation.CallSuper;
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.annotation.ColorInt;
|
||||
import android.annotation.DrawableRes;
|
||||
import android.annotation.IdRes;
|
||||
import android.annotation.IntDef;
|
||||
@@ -108,6 +110,7 @@ import android.util.AttributeSet;
|
||||
import android.util.Dumpable;
|
||||
import android.util.EventLog;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.util.PrintWriterPrinter;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
@@ -1006,6 +1009,25 @@ public class Activity extends ContextThemeWrapper
|
||||
*/
|
||||
public static final int FULLSCREEN_MODE_REQUEST_ENTER = 1;
|
||||
|
||||
/** @hide */
|
||||
@IntDef(prefix = { "OVERRIDE_TRANSITION_" }, value = {
|
||||
OVERRIDE_TRANSITION_OPEN,
|
||||
OVERRIDE_TRANSITION_CLOSE
|
||||
})
|
||||
public @interface OverrideTransition {}
|
||||
|
||||
/**
|
||||
* Request type of {@link #overrideActivityTransition(int, int, int)} or
|
||||
* {@link #overrideActivityTransition(int, int, int, int)}, to override the
|
||||
* opening transition.
|
||||
*/
|
||||
public static final int OVERRIDE_TRANSITION_OPEN = 0;
|
||||
/**
|
||||
* Request type of {@link #overrideActivityTransition(int, int, int)} or
|
||||
* {@link #overrideActivityTransition(int, int, int, int)}, to override the
|
||||
* closing transition.
|
||||
*/
|
||||
public static final int OVERRIDE_TRANSITION_CLOSE = 1;
|
||||
private boolean mShouldDockBigOverlays;
|
||||
|
||||
private UiTranslationController mUiTranslationController;
|
||||
@@ -6461,6 +6483,124 @@ public class Activity extends ContextThemeWrapper
|
||||
flagsMask, flagsValues, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Customizes the animation for the activity transition with this activity. This can be called
|
||||
* at any time while the activity still alive.
|
||||
*
|
||||
* <p> This is a more robust method of overriding the transition animation at runtime without
|
||||
* relying on {@link #overridePendingTransition(int, int)} which doesn't work for predictive
|
||||
* back. However, the animation set from {@link #overridePendingTransition(int, int)} still
|
||||
* has higher priority when the system is looking for the next transition animation.</p>
|
||||
* <p> The animations resources set by this method will be chosen if and only if the activity is
|
||||
* on top of the task while activity transitions are being played.
|
||||
* For example, if we want to customize the opening transition when launching Activity B which
|
||||
* gets started from Activity A, we should call this method inside B's onCreate with
|
||||
* {@code overrideType = OVERRIDE_TRANSITION_OPEN} because the Activity B will on top of the
|
||||
* task. And if we want to customize the closing transition when finishing Activity B and back
|
||||
* to Activity A, since B is still is above A, we should call this method in Activity B with
|
||||
* {@code overrideType = OVERRIDE_TRANSITION_CLOSE}. </p>
|
||||
*
|
||||
* <p> If an Activity has called this method, and it also set another activity animation
|
||||
* by {@link Window#setWindowAnimations(int)}, the system will choose the animation set from
|
||||
* this method.</p>
|
||||
*
|
||||
* <p> Note that {@link Window#setWindowAnimations},
|
||||
* {@link #overridePendingTransition(int, int)} and this method will be ignored if the Activity
|
||||
* is started with {@link ActivityOptions#makeSceneTransitionAnimation(Activity, Pair[])}. Also
|
||||
* note that this method can only be used to customize cross-activity transitions but not
|
||||
* cross-task transitions which are fully non-customizable as of Android 11.</p>
|
||||
*
|
||||
* @param overrideType {@code OVERRIDE_TRANSITION_OPEN} This animation will be used when
|
||||
* starting/entering an activity. {@code OVERRIDE_TRANSITION_CLOSE} This
|
||||
* animation will be used when finishing/closing an activity.
|
||||
* @param enterAnim A resource ID of the animation resource to use for the incoming activity.
|
||||
* Use 0 for no animation.
|
||||
* @param exitAnim A resource ID of the animation resource to use for the outgoing activity.
|
||||
* Use 0 for no animation.
|
||||
*
|
||||
* @see #overrideActivityTransition(int, int, int, int)
|
||||
* @see #clearOverrideActivityTransition(int)
|
||||
* @see OnBackInvokedCallback
|
||||
* @see #overridePendingTransition(int, int)
|
||||
* @see Window#setWindowAnimations(int)
|
||||
* @see ActivityOptions#makeSceneTransitionAnimation(Activity, Pair[])
|
||||
*/
|
||||
public void overrideActivityTransition(@OverrideTransition int overrideType,
|
||||
@AnimRes int enterAnim, @AnimRes int exitAnim) {
|
||||
overrideActivityTransition(overrideType, enterAnim, exitAnim, Color.TRANSPARENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Customizes the animation for the activity transition with this activity. This can be called
|
||||
* at any time while the activity still alive.
|
||||
*
|
||||
* <p> This is a more robust method of overriding the transition animation at runtime without
|
||||
* relying on {@link #overridePendingTransition(int, int)} which doesn't work for predictive
|
||||
* back. However, the animation set from {@link #overridePendingTransition(int, int)} still
|
||||
* has higher priority when the system is looking for the next transition animation.</p>
|
||||
* <p> The animations resources set by this method will be chosen if and only if the activity is
|
||||
* on top of the task while activity transitions are being played.
|
||||
* For example, if we want to customize the opening transition when launching Activity B which
|
||||
* gets started from Activity A, we should call this method inside B's onCreate with
|
||||
* {@code overrideType = OVERRIDE_TRANSITION_OPEN} because the Activity B will on top of the
|
||||
* task. And if we want to customize the closing transition when finishing Activity B and back
|
||||
* to Activity A, since B is still is above A, we should call this method in Activity B with
|
||||
* {@code overrideType = OVERRIDE_TRANSITION_CLOSE}. </p>
|
||||
*
|
||||
* <p> If an Activity has called this method, and it also set another activity animation
|
||||
* by {@link Window#setWindowAnimations(int)}, the system will choose the animation set from
|
||||
* this method.</p>
|
||||
*
|
||||
* <p> Note that {@link Window#setWindowAnimations},
|
||||
* {@link #overridePendingTransition(int, int)} and this method will be ignored if the Activity
|
||||
* is started with {@link ActivityOptions#makeSceneTransitionAnimation(Activity, Pair[])}. Also
|
||||
* note that this method can only be used to customize cross-activity transitions but not
|
||||
* cross-task transitions which are fully non-customizable as of Android 11.</p>
|
||||
*
|
||||
* @param overrideType {@code OVERRIDE_TRANSITION_OPEN} This animation will be used when
|
||||
* starting/entering an activity. {@code OVERRIDE_TRANSITION_CLOSE} This
|
||||
* animation will be used when finishing/closing an activity.
|
||||
* @param enterAnim A resource ID of the animation resource to use for the incoming activity.
|
||||
* Use 0 for no animation.
|
||||
* @param exitAnim A resource ID of the animation resource to use for the outgoing activity.
|
||||
* Use 0 for no animation.
|
||||
* @param backgroundColor The background color to use for the background during the animation
|
||||
* if the animation requires a background. Set to
|
||||
* {@link Color#TRANSPARENT} to not override the default color.
|
||||
* @see #overrideActivityTransition(int, int, int)
|
||||
* @see #clearOverrideActivityTransition(int)
|
||||
* @see OnBackInvokedCallback
|
||||
* @see #overridePendingTransition(int, int)
|
||||
* @see Window#setWindowAnimations(int)
|
||||
* @see ActivityOptions#makeSceneTransitionAnimation(Activity, Pair[])
|
||||
*/
|
||||
public void overrideActivityTransition(@OverrideTransition int overrideType,
|
||||
@AnimRes int enterAnim, @AnimRes int exitAnim, @ColorInt int backgroundColor) {
|
||||
if (overrideType != OVERRIDE_TRANSITION_OPEN && overrideType != OVERRIDE_TRANSITION_CLOSE) {
|
||||
throw new IllegalArgumentException("Override type must be either open or close");
|
||||
}
|
||||
|
||||
ActivityClient.getInstance().overrideActivityTransition(mToken,
|
||||
overrideType == OVERRIDE_TRANSITION_OPEN, enterAnim, exitAnim, backgroundColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the animations which are set from {@link #overrideActivityTransition}.
|
||||
* @param overrideType {@code OVERRIDE_TRANSITION_OPEN} clear the animation set for starting a
|
||||
* new activity. {@code OVERRIDE_TRANSITION_CLOSE} clear the animation set
|
||||
* for finishing an activity.
|
||||
*
|
||||
* @see #overrideActivityTransition(int, int, int)
|
||||
* @see #overrideActivityTransition(int, int, int, int)
|
||||
*/
|
||||
public void clearOverrideActivityTransition(@OverrideTransition int overrideType) {
|
||||
if (overrideType != OVERRIDE_TRANSITION_OPEN && overrideType != OVERRIDE_TRANSITION_CLOSE) {
|
||||
throw new IllegalArgumentException("Override type must be either open or close");
|
||||
}
|
||||
ActivityClient.getInstance().clearOverrideActivityTransition(mToken,
|
||||
overrideType == OVERRIDE_TRANSITION_OPEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call immediately after one of the flavors of {@link #startActivity(Intent)}
|
||||
* or {@link #finish} to specify an explicit transition animation to
|
||||
|
||||
@@ -486,6 +486,24 @@ public class ActivityClient {
|
||||
}
|
||||
}
|
||||
|
||||
void overrideActivityTransition(IBinder token, boolean open, int enterAnim, int exitAnim,
|
||||
int backgroundColor) {
|
||||
try {
|
||||
getActivityClientController().overrideActivityTransition(
|
||||
token, open, enterAnim, exitAnim, backgroundColor);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
void clearOverrideActivityTransition(IBinder token, boolean open) {
|
||||
try {
|
||||
getActivityClientController().clearOverrideActivityTransition(token, open);
|
||||
} catch (RemoteException e) {
|
||||
e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
void overridePendingTransition(IBinder token, String packageName, int enterAnim, int exitAnim,
|
||||
int backgroundColor) {
|
||||
try {
|
||||
|
||||
@@ -121,6 +121,9 @@ interface IActivityClientController {
|
||||
oneway void setInheritShowWhenLocked(in IBinder token, boolean setInheritShownWhenLocked);
|
||||
oneway void setTurnScreenOn(in IBinder token, boolean turnScreenOn);
|
||||
oneway void reportActivityFullyDrawn(in IBinder token, boolean restoredFromBundle);
|
||||
oneway void overrideActivityTransition(IBinder token, boolean open, int enterAnim, int exitAnim,
|
||||
int backgroundColor);
|
||||
oneway void clearOverrideActivityTransition(IBinder token, boolean open);
|
||||
/**
|
||||
* Overrides the animation of activity pending transition. This call is not one-way because
|
||||
* the method is usually used after startActivity or Activity#finish. If this is non-blocking,
|
||||
|
||||
@@ -846,6 +846,9 @@ public final class TransitionInfo implements Parcelable {
|
||||
private HardwareBuffer mThumbnail;
|
||||
private int mAnimations;
|
||||
private @ColorInt int mBackgroundColor;
|
||||
// Customize activity transition animation
|
||||
private CustomActivityTransition mCustomActivityOpenTransition;
|
||||
private CustomActivityTransition mCustomActivityCloseTransition;
|
||||
|
||||
private AnimationOptions(int type) {
|
||||
mType = type;
|
||||
@@ -861,6 +864,15 @@ public final class TransitionInfo implements Parcelable {
|
||||
mTransitionBounds.readFromParcel(in);
|
||||
mThumbnail = in.readTypedObject(HardwareBuffer.CREATOR);
|
||||
mAnimations = in.readInt();
|
||||
mCustomActivityOpenTransition = in.readTypedObject(CustomActivityTransition.CREATOR);
|
||||
mCustomActivityCloseTransition = in.readTypedObject(CustomActivityTransition.CREATOR);
|
||||
}
|
||||
|
||||
/** Make basic customized animation for a package */
|
||||
public static AnimationOptions makeCommonAnimOptions(String packageName) {
|
||||
AnimationOptions options = new AnimationOptions(ANIM_FROM_STYLE);
|
||||
options.mPackageName = packageName;
|
||||
return options;
|
||||
}
|
||||
|
||||
public static AnimationOptions makeAnimOptionsFromLayoutParameters(
|
||||
@@ -871,6 +883,27 @@ public final class TransitionInfo implements Parcelable {
|
||||
return options;
|
||||
}
|
||||
|
||||
/** Add customized window animations */
|
||||
public void addOptionsFromLayoutParameters(WindowManager.LayoutParams lp) {
|
||||
mAnimations = lp.windowAnimations;
|
||||
}
|
||||
|
||||
/** Add customized activity animation attributes */
|
||||
public void addCustomActivityTransition(boolean isOpen,
|
||||
int enterResId, int exitResId, int backgroundColor) {
|
||||
CustomActivityTransition customTransition = isOpen
|
||||
? mCustomActivityOpenTransition : mCustomActivityCloseTransition;
|
||||
if (customTransition == null) {
|
||||
customTransition = new CustomActivityTransition();
|
||||
if (isOpen) {
|
||||
mCustomActivityOpenTransition = customTransition;
|
||||
} else {
|
||||
mCustomActivityCloseTransition = customTransition;
|
||||
}
|
||||
}
|
||||
customTransition.addCustomActivityTransition(enterResId, exitResId, backgroundColor);
|
||||
}
|
||||
|
||||
public static AnimationOptions makeCustomAnimOptions(String packageName, int enterResId,
|
||||
int exitResId, @ColorInt int backgroundColor, boolean overrideTaskTransition) {
|
||||
AnimationOptions options = new AnimationOptions(ANIM_CUSTOM);
|
||||
@@ -946,6 +979,11 @@ public final class TransitionInfo implements Parcelable {
|
||||
return mAnimations;
|
||||
}
|
||||
|
||||
/** Return customized activity transition if existed. */
|
||||
public CustomActivityTransition getCustomActivityTransition(boolean open) {
|
||||
return open ? mCustomActivityOpenTransition : mCustomActivityCloseTransition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(mType);
|
||||
@@ -957,6 +995,8 @@ public final class TransitionInfo implements Parcelable {
|
||||
mTransitionBounds.writeToParcel(dest, flags);
|
||||
dest.writeTypedObject(mThumbnail, flags);
|
||||
dest.writeInt(mAnimations);
|
||||
dest.writeTypedObject(mCustomActivityOpenTransition, flags);
|
||||
dest.writeTypedObject(mCustomActivityCloseTransition, flags);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@@ -997,5 +1037,68 @@ public final class TransitionInfo implements Parcelable {
|
||||
return "{ AnimationOptions type= " + typeToString(mType) + " package=" + mPackageName
|
||||
+ " override=" + mOverrideTaskTransition + " b=" + mTransitionBounds + "}";
|
||||
}
|
||||
|
||||
/** Customized activity transition. */
|
||||
public static class CustomActivityTransition implements Parcelable {
|
||||
private int mCustomEnterResId;
|
||||
private int mCustomExitResId;
|
||||
private int mCustomBackgroundColor;
|
||||
|
||||
/** Returns customize activity animation enter resource id */
|
||||
public int getCustomEnterResId() {
|
||||
return mCustomEnterResId;
|
||||
}
|
||||
|
||||
/** Returns customize activity animation exit resource id */
|
||||
public int getCustomExitResId() {
|
||||
return mCustomExitResId;
|
||||
}
|
||||
|
||||
/** Returns customize activity animation background color */
|
||||
public int getCustomBackgroundColor() {
|
||||
return mCustomBackgroundColor;
|
||||
}
|
||||
CustomActivityTransition() {}
|
||||
|
||||
CustomActivityTransition(Parcel in) {
|
||||
mCustomEnterResId = in.readInt();
|
||||
mCustomExitResId = in.readInt();
|
||||
mCustomBackgroundColor = in.readInt();
|
||||
}
|
||||
|
||||
/** Add customized activity animation attributes */
|
||||
public void addCustomActivityTransition(
|
||||
int enterResId, int exitResId, int backgroundColor) {
|
||||
mCustomEnterResId = enterResId;
|
||||
mCustomExitResId = exitResId;
|
||||
mCustomBackgroundColor = backgroundColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(mCustomEnterResId);
|
||||
dest.writeInt(mCustomExitResId);
|
||||
dest.writeInt(mCustomBackgroundColor);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static final Creator<CustomActivityTransition> CREATOR =
|
||||
new Creator<CustomActivityTransition>() {
|
||||
@Override
|
||||
public CustomActivityTransition createFromParcel(Parcel in) {
|
||||
return new CustomActivityTransition(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomActivityTransition[] newArray(int size) {
|
||||
return new CustomActivityTransition[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,9 +142,12 @@ public class TransitionAnimationHelper {
|
||||
Animation a = null;
|
||||
if (animAttr != 0) {
|
||||
if (overrideType == ANIM_FROM_STYLE && !isTask) {
|
||||
a = transitionAnimation
|
||||
.loadAnimationAttr(options.getPackageName(), options.getAnimations(),
|
||||
animAttr, translucent);
|
||||
a = loadCustomActivityTransition(animAttr, options, enter, transitionAnimation);
|
||||
if (a == null) {
|
||||
a = transitionAnimation
|
||||
.loadAnimationAttr(options.getPackageName(), options.getAnimations(),
|
||||
animAttr, translucent);
|
||||
}
|
||||
} else {
|
||||
a = transitionAnimation.loadDefaultAnimationAttr(animAttr, translucent);
|
||||
}
|
||||
@@ -157,6 +160,37 @@ public class TransitionAnimationHelper {
|
||||
return a;
|
||||
}
|
||||
|
||||
static Animation loadCustomActivityTransition(int animAttr,
|
||||
TransitionInfo.AnimationOptions options, boolean enter,
|
||||
TransitionAnimation transitionAnimation) {
|
||||
Animation a = null;
|
||||
boolean isOpen = false;
|
||||
switch (animAttr) {
|
||||
case R.styleable.WindowAnimation_activityOpenEnterAnimation:
|
||||
case R.styleable.WindowAnimation_activityOpenExitAnimation:
|
||||
isOpen = true;
|
||||
break;
|
||||
case R.styleable.WindowAnimation_activityCloseEnterAnimation:
|
||||
case R.styleable.WindowAnimation_activityCloseExitAnimation:
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
final TransitionInfo.AnimationOptions.CustomActivityTransition transitionAnim =
|
||||
options.getCustomActivityTransition(isOpen);
|
||||
if (transitionAnim != null) {
|
||||
a = transitionAnimation.loadAppTransitionAnimation(options.getPackageName(),
|
||||
enter ? transitionAnim.getCustomEnterResId()
|
||||
: transitionAnim.getCustomExitResId());
|
||||
if (a != null && transitionAnim.getCustomBackgroundColor() != 0) {
|
||||
a.setBackdropColor(transitionAnim.getCustomBackgroundColor());
|
||||
}
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the background {@link ColorInt} for the given transition animation if it is set.
|
||||
*
|
||||
|
||||
@@ -1381,6 +1381,31 @@ class ActivityClientController extends IActivityClientController.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void overrideActivityTransition(IBinder token, boolean open, int enterAnim, int exitAnim,
|
||||
int backgroundColor) {
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
synchronized (mGlobalLock) {
|
||||
final ActivityRecord r = ActivityRecord.isInRootTaskLocked(token);
|
||||
if (r != null) {
|
||||
r.overrideCustomTransition(open, enterAnim, exitAnim, backgroundColor);
|
||||
}
|
||||
}
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearOverrideActivityTransition(IBinder token, boolean open) {
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
synchronized (mGlobalLock) {
|
||||
final ActivityRecord r = ActivityRecord.isInRootTaskLocked(token);
|
||||
if (r != null) {
|
||||
r.clearCustomTransition(open);
|
||||
}
|
||||
}
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void overridePendingTransition(IBinder token, String packageName,
|
||||
int enterAnim, int exitAnim, @ColorInt int backgroundColor) {
|
||||
|
||||
@@ -945,6 +945,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
// Whether the ActivityEmbedding is enabled on the app.
|
||||
private final boolean mAppActivityEmbeddingSplitsEnabled;
|
||||
|
||||
// Records whether client has overridden the WindowAnimation_(Open/Close)(Enter/Exit)Animation.
|
||||
private CustomAppTransition mCustomOpenTransition;
|
||||
private CustomAppTransition mCustomCloseTransition;
|
||||
|
||||
private final Runnable mPauseTimeoutRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -10352,6 +10356,41 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
&& !inPinnedWindowingMode() && !inFreeformWindowingMode();
|
||||
}
|
||||
|
||||
void overrideCustomTransition(boolean open, int enterAnim, int exitAnim, int backgroundColor) {
|
||||
CustomAppTransition transition = getCustomAnimation(open);
|
||||
if (transition == null) {
|
||||
transition = new CustomAppTransition();
|
||||
if (open) {
|
||||
mCustomOpenTransition = transition;
|
||||
} else {
|
||||
mCustomCloseTransition = transition;
|
||||
}
|
||||
}
|
||||
|
||||
transition.mEnterAnim = enterAnim;
|
||||
transition.mExitAnim = exitAnim;
|
||||
transition.mBackgroundColor = backgroundColor;
|
||||
}
|
||||
|
||||
void clearCustomTransition(boolean open) {
|
||||
if (open) {
|
||||
mCustomOpenTransition = null;
|
||||
} else {
|
||||
mCustomCloseTransition = null;
|
||||
}
|
||||
}
|
||||
|
||||
CustomAppTransition getCustomAnimation(boolean open) {
|
||||
return open ? mCustomOpenTransition : mCustomCloseTransition;
|
||||
}
|
||||
|
||||
// Override the WindowAnimation_(Open/Close)(Enter/Exit)Animation
|
||||
static class CustomAppTransition {
|
||||
int mEnterAnim;
|
||||
int mExitAnim;
|
||||
int mBackgroundColor;
|
||||
}
|
||||
|
||||
static class Builder {
|
||||
private final ActivityTaskManagerService mAtmService;
|
||||
private WindowProcessController mCallerApp;
|
||||
|
||||
@@ -142,6 +142,7 @@ import com.android.internal.protolog.common.ProtoLog;
|
||||
import com.android.internal.util.DumpUtils.Dump;
|
||||
import com.android.internal.util.function.pooled.PooledLambda;
|
||||
import com.android.internal.util.function.pooled.PooledPredicate;
|
||||
import com.android.server.wm.ActivityRecord.CustomAppTransition;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
@@ -886,9 +887,18 @@ public class AppTransition implements Dump {
|
||||
a, appTransitionOldToString(transit), enter, Debug.getCallers(3));
|
||||
} else {
|
||||
int animAttr = mapOpenCloseTransitTypes(transit, enter);
|
||||
a = animAttr == 0 ? null : (canCustomizeAppTransition
|
||||
? loadAnimationAttr(lp, animAttr, transit)
|
||||
: mTransitionAnimation.loadDefaultAnimationAttr(animAttr, transit));
|
||||
if (animAttr != 0) {
|
||||
a = loadCustomActivityAnimation(animAttr, enter, container);
|
||||
if (a == null) {
|
||||
if (canCustomizeAppTransition) {
|
||||
a = loadAnimationAttr(lp, animAttr, transit);
|
||||
} else {
|
||||
a = mTransitionAnimation.loadDefaultAnimationAttr(animAttr, transit);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
a = null;
|
||||
}
|
||||
|
||||
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
|
||||
"applyAnimation: anim=%s animAttr=0x%x transit=%s isEntrance=%b "
|
||||
@@ -901,6 +911,48 @@ public class AppTransition implements Dump {
|
||||
return a;
|
||||
}
|
||||
|
||||
Animation loadCustomActivityAnimation(int animAttr, boolean enter, WindowContainer container) {
|
||||
ActivityRecord customAnimationSource = container.asActivityRecord();
|
||||
if (customAnimationSource == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Only top activity can customize activity animation.
|
||||
// If the animation is for the one below, try to get from the above activity.
|
||||
if (animAttr == WindowAnimation_activityOpenExitAnimation
|
||||
|| animAttr == WindowAnimation_activityCloseEnterAnimation) {
|
||||
customAnimationSource = customAnimationSource.getTask()
|
||||
.getActivityAbove(customAnimationSource);
|
||||
if (customAnimationSource == null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
final CustomAppTransition custom;
|
||||
switch (animAttr) {
|
||||
case WindowAnimation_activityOpenEnterAnimation:
|
||||
case WindowAnimation_activityOpenExitAnimation:
|
||||
custom = customAnimationSource.getCustomAnimation(true /* open */);
|
||||
break;
|
||||
case WindowAnimation_activityCloseEnterAnimation:
|
||||
case WindowAnimation_activityCloseExitAnimation:
|
||||
custom = customAnimationSource.getCustomAnimation(false /* open */);
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
if (custom != null) {
|
||||
final Animation a = mTransitionAnimation.loadAppTransitionAnimation(
|
||||
customAnimationSource.packageName, enter
|
||||
? custom.mEnterAnim : custom.mExitAnim);
|
||||
if (a != null && custom.mBackgroundColor != 0) {
|
||||
a.setBackdropColor(custom.mBackgroundColor);
|
||||
a.setShowBackdrop(true);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
int getAppRootTaskClipMode() {
|
||||
return mNextAppTransitionRequests.contains(TRANSIT_RELAUNCH)
|
||||
|| mNextAppTransitionRequests.contains(TRANSIT_KEYGUARD_GOING_AWAY)
|
||||
|
||||
@@ -1881,6 +1881,12 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
|
||||
out.addChange(change);
|
||||
}
|
||||
|
||||
TransitionInfo.AnimationOptions animOptions = null;
|
||||
if (topApp.asActivityRecord() != null) {
|
||||
final ActivityRecord topActivity = topApp.asActivityRecord();
|
||||
animOptions = addCustomActivityTransition(topActivity, true/* open */, null);
|
||||
animOptions = addCustomActivityTransition(topActivity, false/* open */, animOptions);
|
||||
}
|
||||
final WindowManager.LayoutParams animLp =
|
||||
getLayoutParamsForAnimationsStyle(type, sortedTargets);
|
||||
if (animLp != null && animLp.type != TYPE_APPLICATION_STARTING
|
||||
@@ -1888,14 +1894,33 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
|
||||
// Don't send animation options if no windowAnimations have been set or if the we are
|
||||
// running an app starting animation, in which case we don't want the app to be able to
|
||||
// change its animation directly.
|
||||
TransitionInfo.AnimationOptions animOptions =
|
||||
TransitionInfo.AnimationOptions.makeAnimOptionsFromLayoutParameters(animLp);
|
||||
if (animOptions != null) {
|
||||
animOptions.addOptionsFromLayoutParameters(animLp);
|
||||
} else {
|
||||
animOptions = TransitionInfo.AnimationOptions
|
||||
.makeAnimOptionsFromLayoutParameters(animLp);
|
||||
}
|
||||
}
|
||||
if (animOptions != null) {
|
||||
out.setAnimationOptions(animOptions);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static TransitionInfo.AnimationOptions addCustomActivityTransition(ActivityRecord topActivity,
|
||||
boolean open, TransitionInfo.AnimationOptions animOptions) {
|
||||
final ActivityRecord.CustomAppTransition customAnim =
|
||||
topActivity.getCustomAnimation(open);
|
||||
if (customAnim != null) {
|
||||
if (animOptions == null) {
|
||||
animOptions = TransitionInfo.AnimationOptions
|
||||
.makeCommonAnimOptions(topActivity.packageName);
|
||||
}
|
||||
animOptions.addCustomActivityTransition(open, customAnim.mEnterAnim,
|
||||
customAnim.mExitAnim, customAnim.mBackgroundColor);
|
||||
}
|
||||
return animOptions;
|
||||
}
|
||||
/**
|
||||
* Finds the top-most common ancestor of app targets.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user