Merge "Fix flicker when starting an activity from Recents." into sc-dev am: c6fa4e9892

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13473993

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I4a7faceb95345b35a8ed68c189f8041227dec91e
This commit is contained in:
Issei Suzuki
2021-02-05 11:22:05 +00:00
committed by Automerger Merge Worker
9 changed files with 91 additions and 6 deletions

View File

@@ -28,6 +28,7 @@ package android {
field public static final String READ_PRIVILEGED_PHONE_STATE = "android.permission.READ_PRIVILEGED_PHONE_STATE";
field public static final String REMOVE_TASKS = "android.permission.REMOVE_TASKS";
field public static final String RESET_APP_ERRORS = "android.permission.RESET_APP_ERRORS";
field public static final String START_TASKS_FROM_RECENTS = "android.permission.START_TASKS_FROM_RECENTS";
field public static final String SUSPEND_APPS = "android.permission.SUSPEND_APPS";
field public static final String TEST_BIOMETRIC = "android.permission.TEST_BIOMETRIC";
field public static final String TEST_MANAGE_ROLLBACKS = "android.permission.TEST_MANAGE_ROLLBACKS";
@@ -119,6 +120,7 @@ package android.app {
public class ActivityOptions {
method @NonNull public static android.app.ActivityOptions makeCustomAnimation(@NonNull android.content.Context, int, int, @Nullable android.os.Handler, @Nullable android.app.ActivityOptions.OnAnimationStartedListener, @Nullable android.app.ActivityOptions.OnAnimationFinishedListener);
method @NonNull @RequiresPermission(android.Manifest.permission.START_TASKS_FROM_RECENTS) public static android.app.ActivityOptions makeCustomTaskAnimation(@NonNull android.content.Context, int, int, @Nullable android.os.Handler, @Nullable android.app.ActivityOptions.OnAnimationStartedListener, @Nullable android.app.ActivityOptions.OnAnimationFinishedListener);
method public static void setExitTransitionTimeout(long);
method public void setLaunchActivityType(int);
method public void setLaunchTaskId(int);

View File

@@ -17,6 +17,7 @@
package android.app;
import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.Display.INVALID_DISPLAY;
@@ -310,6 +311,9 @@ public class ActivityOptions {
private static final String KEY_REMOTE_TRANSITION =
"android:activity.remoteTransition";
private static final String KEY_OVERRIDE_TASK_TRANSITION =
"android:activity.overrideTaskTransition";
/**
* @see #setLaunchCookie
* @hide
@@ -393,6 +397,7 @@ public class ActivityOptions {
private RemoteAnimationAdapter mRemoteAnimationAdapter;
private IBinder mLaunchCookie;
private IRemoteTransition mRemoteTransition;
private boolean mOverrideTaskTransition;
/**
* Create an ActivityOptions specifying a custom animation to run when
@@ -475,6 +480,40 @@ public class ActivityOptions {
return opts;
}
/**
* Create an ActivityOptions specifying a custom animation to run when the activity in the
* different task is displayed.
*
* @param context Who is defining this. This is the application that the
* animation resources will be loaded from.
* @param enterResId A resource ID of the animation resource to use for
* the incoming activity. Use 0 for no animation.
* @param exitResId A resource ID of the animation resource to use for
* the outgoing activity. Use 0 for no animation.
* @param handler If <var>listener</var> is non-null this must be a valid
* Handler on which to dispatch the callback; otherwise it should be null.
* @param startedListener 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.
* @param finishedListener Optional OnAnimationFinishedListener when the animation
* has finished running.
*
* @return Returns a new ActivityOptions object that you can use to
* supply these options as the options Bundle when starting an activity.
* @hide
*/
@RequiresPermission(START_TASKS_FROM_RECENTS)
@TestApi
public static @NonNull ActivityOptions makeCustomTaskAnimation(@NonNull Context context,
int enterResId, int exitResId, @Nullable Handler handler,
@Nullable OnAnimationStartedListener startedListener,
@Nullable OnAnimationFinishedListener finishedListener) {
ActivityOptions opts = makeCustomAnimation(context, enterResId, exitResId, handler,
startedListener, finishedListener);
opts.mOverrideTaskTransition = true;
return opts;
}
/**
* Creates an ActivityOptions specifying a custom animation to run in place on an existing
* activity.
@@ -1107,6 +1146,7 @@ public class ActivityOptions {
mLaunchCookie = opts.getBinder(KEY_LAUNCH_COOKIE);
mRemoteTransition = IRemoteTransition.Stub.asInterface(opts.getBinder(
KEY_REMOTE_TRANSITION));
mOverrideTaskTransition = opts.getBoolean(KEY_OVERRIDE_TASK_TRANSITION);
}
/**
@@ -1561,6 +1601,12 @@ public class ActivityOptions {
return mLaunchCookie;
}
/** @hide */
public boolean getOverrideTaskTransition() {
return mOverrideTaskTransition;
}
/**
* Update the current values in this ActivityOptions from those supplied
* in <var>otherOptions</var>. Any values
@@ -1789,6 +1835,9 @@ public class ActivityOptions {
if (mRemoteTransition != null) {
b.putBinder(KEY_REMOTE_TRANSITION, mRemoteTransition.asBinder());
}
if (mOverrideTaskTransition) {
b.putBoolean(KEY_OVERRIDE_TASK_TRANSITION, mOverrideTaskTransition);
}
return b;
}

View File

@@ -2539,7 +2539,7 @@
<permission android:name="android.permission.REAL_GET_TASKS"
android:protectionLevel="signature|privileged" />
<!-- Allows an application to start a task from a ActivityManager#RecentTaskInfo.
<!-- @TestApi Allows an application to start a task from a ActivityManager#RecentTaskInfo.
@hide -->
<permission android:name="android.permission.START_TASKS_FROM_RECENTS"
android:protectionLevel="signature|privileged|recents" />

View File

@@ -72,9 +72,13 @@ public abstract class ActivityOptionsCompat {
return ActivityOptions.makeRemoteTransition(remoteTransition.getTransition());
}
/**
* Returns ActivityOptions for overriding task transition animation.
*/
public static ActivityOptions makeCustomAnimation(Context context, int enterResId,
int exitResId, final Runnable callback, final Handler callbackHandler) {
return ActivityOptions.makeCustomAnimation(context, enterResId, exitResId, callbackHandler,
return ActivityOptions.makeCustomTaskAnimation(context, enterResId, exitResId,
callbackHandler,
new ActivityOptions.OnAnimationStartedListener() {
@Override
public void onAnimationStarted() {

View File

@@ -975,7 +975,8 @@ class ActivityClientController extends IActivityClientController.Stub {
final ActivityRecord r = ActivityRecord.isInRootTaskLocked(token);
if (r != null && r.isState(Task.ActivityState.RESUMED, Task.ActivityState.PAUSING)) {
r.mDisplayContent.mAppTransition.overridePendingAppTransition(
packageName, enterAnim, exitAnim, null, null);
packageName, enterAnim, exitAnim, null, null,
r.mOverrideTaskTransition);
}
}
Binder.restoreCallingIdentity(origId);

View File

@@ -682,6 +682,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
boolean mRequestForceTransition;
boolean mEnteringAnimation;
boolean mOverrideTaskTransition;
boolean mAppStopped;
// A hint to override the window specified rotation animation, or -1 to use the window specified
@@ -1627,6 +1628,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (rotationAnimation >= 0) {
mRotationAnimationHint = rotationAnimation;
}
mOverrideTaskTransition = options.getOverrideTaskTransition();
}
ColorDisplayService.ColorDisplayServiceInternal cds = LocalServices.getService(
@@ -3997,7 +4000,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
pendingOptions.getCustomEnterResId(),
pendingOptions.getCustomExitResId(),
pendingOptions.getAnimationStartedListener(),
pendingOptions.getAnimationFinishedListener());
pendingOptions.getAnimationFinishedListener(),
pendingOptions.getOverrideTaskTransition());
break;
case ANIM_CLIP_REVEAL:
displayContent.mAppTransition.overridePendingAppTransitionClipReveal(

View File

@@ -266,6 +266,7 @@ public class AppTransition implements Dump {
private final boolean mLowRamRecentsEnabled;
private final int mDefaultWindowAnimationStyleResId;
private boolean mOverrideTaskTransition;
private RemoteAnimationController mRemoteAnimationController;
@@ -971,7 +972,8 @@ public class AppTransition implements Dump {
@Nullable Rect surfaceInsets, @Nullable Rect stableInsets, boolean isVoiceInteraction,
boolean freeform, WindowContainer container) {
if (mNextAppTransitionOverrideRequested && container.canCustomizeAppTransition()) {
if (mNextAppTransitionOverrideRequested
&& (container.canCustomizeAppTransition() || mOverrideTaskTransition)) {
mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM;
}
@@ -1175,7 +1177,8 @@ public class AppTransition implements Dump {
}
void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim,
IRemoteCallback startedCallback, IRemoteCallback endedCallback) {
IRemoteCallback startedCallback, IRemoteCallback endedCallback,
boolean overrideTaskTransaction) {
if (canOverridePendingAppTransition()) {
clear();
mNextAppTransitionOverrideRequested = true;
@@ -1185,6 +1188,7 @@ public class AppTransition implements Dump {
postAnimationCallback();
mNextAppTransitionCallback = startedCallback;
mAnimationFinishedCallback = endedCallback;
mOverrideTaskTransition = overrideTaskTransaction;
}
}

View File

@@ -709,6 +709,13 @@ public class AppTransitionController {
applyAnimations(closingWcs, closingApps, transit, false /* visible */, animLp,
voiceInteraction);
for (int i = 0; i < openingApps.size(); ++i) {
openingApps.valueAtUnchecked(i).mOverrideTaskTransition = false;
}
for (int i = 0; i < closingApps.size(); ++i) {
closingApps.valueAtUnchecked(i).mOverrideTaskTransition = false;
}
final AccessibilityController accessibilityController =
mDisplayContent.mWmService.mAccessibilityController;
if (accessibilityController != null) {

View File

@@ -253,6 +253,20 @@ public class SafeActivityOptions {
throw new SecurityException(msg);
}
// Check if the caller is allowed to override any app transition animation.
final boolean overrideTaskTransition = options.getOverrideTaskTransition();
if (aInfo != null && overrideTaskTransition) {
final int startTasksFromRecentsPerm = ActivityTaskManagerService.checkPermission(
START_TASKS_FROM_RECENTS, callingPid, callingUid);
if (startTasksFromRecentsPerm != PERMISSION_GRANTED) {
final String msg = "Permission Denial: starting " + getIntentString(intent)
+ " from " + callerApp + " (pid=" + callingPid
+ ", uid=" + callingUid + ") with overrideTaskTransition=true";
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
}
// Check permission for remote animations
final RemoteAnimationAdapter adapter = options.getRemoteAnimationAdapter();
if (adapter != null && supervisor.mService.checkPermission(