Merge "Boost remote-transition animator processes during animation" into sc-v2-dev am: 62924f1213

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

Change-Id: I7a8baa9e6671022ed8e997592f35ee36f529d1a7
This commit is contained in:
Evan Rosky
2021-11-03 21:11:28 +00:00
committed by Automerger Merge Worker
12 changed files with 118 additions and 23 deletions

View File

@@ -18,6 +18,7 @@ package android.window;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.IApplicationThread;
import android.os.IBinder;
import android.os.Parcelable;
@@ -34,6 +35,14 @@ public class RemoteTransition implements Parcelable {
/** The actual remote-transition interface used to run the transition animation. */
private @NonNull IRemoteTransition mRemoteTransition;
/** The application thread that will be running the remote transition. */
private @Nullable IApplicationThread mAppThread;
/** Constructs with no app thread (animation runs in shell). */
public RemoteTransition(@NonNull IRemoteTransition remoteTransition) {
this(remoteTransition, null /* appThread */);
}
/** Get the IBinder associated with the underlying IRemoteTransition. */
public @Nullable IBinder asBinder() {
return mRemoteTransition.asBinder();
@@ -59,13 +68,17 @@ public class RemoteTransition implements Parcelable {
*
* @param remoteTransition
* The actual remote-transition interface used to run the transition animation.
* @param appThread
* The application thread that will be running the remote transition.
*/
@DataClass.Generated.Member
public RemoteTransition(
@NonNull IRemoteTransition remoteTransition) {
@NonNull IRemoteTransition remoteTransition,
@Nullable IApplicationThread appThread) {
this.mRemoteTransition = remoteTransition;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mRemoteTransition);
this.mAppThread = appThread;
// onConstructed(); // You can define this method to get a callback
}
@@ -78,6 +91,14 @@ public class RemoteTransition implements Parcelable {
return mRemoteTransition;
}
/**
* The application thread that will be running the remote transition.
*/
@DataClass.Generated.Member
public @Nullable IApplicationThread getAppThread() {
return mAppThread;
}
/**
* The actual remote-transition interface used to run the transition animation.
*/
@@ -89,6 +110,15 @@ public class RemoteTransition implements Parcelable {
return this;
}
/**
* The application thread that will be running the remote transition.
*/
@DataClass.Generated.Member
public @NonNull RemoteTransition setAppThread(@NonNull IApplicationThread value) {
mAppThread = value;
return this;
}
@Override
@DataClass.Generated.Member
public String toString() {
@@ -96,7 +126,8 @@ public class RemoteTransition implements Parcelable {
// String fieldNameToString() { ... }
return "RemoteTransition { " +
"remoteTransition = " + mRemoteTransition +
"remoteTransition = " + mRemoteTransition + ", " +
"appThread = " + mAppThread +
" }";
}
@@ -106,7 +137,11 @@ public class RemoteTransition implements Parcelable {
// You can override field parcelling by defining methods like:
// void parcelFieldName(Parcel dest, int flags) { ... }
byte flg = 0;
if (mAppThread != null) flg |= 0x2;
dest.writeByte(flg);
dest.writeStrongInterface(mRemoteTransition);
if (mAppThread != null) dest.writeStrongInterface(mAppThread);
}
@Override
@@ -120,11 +155,14 @@ public class RemoteTransition implements Parcelable {
// You can override field unparcelling by defining methods like:
// static FieldType unparcelFieldName(Parcel in) { ... }
byte flg = in.readByte();
IRemoteTransition remoteTransition = IRemoteTransition.Stub.asInterface(in.readStrongBinder());
IApplicationThread appThread = (flg & 0x2) == 0 ? null : IApplicationThread.Stub.asInterface(in.readStrongBinder());
this.mRemoteTransition = remoteTransition;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mRemoteTransition);
this.mAppThread = appThread;
// onConstructed(); // You can define this method to get a callback
}
@@ -144,10 +182,10 @@ public class RemoteTransition implements Parcelable {
};
@DataClass.Generated(
time = 1630613039043L,
time = 1630690027011L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/window/RemoteTransition.java",
inputSignatures = "private @android.annotation.NonNull android.window.IRemoteTransition mRemoteTransition\npublic @android.annotation.Nullable android.os.IBinder asBinder()\nclass RemoteTransition extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genSetters=true, genAidl=true)")
inputSignatures = "private @android.annotation.NonNull android.window.IRemoteTransition mRemoteTransition\nprivate @android.annotation.Nullable android.app.IApplicationThread mAppThread\npublic @android.annotation.Nullable android.os.IBinder asBinder()\nclass RemoteTransition extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genSetters=true, genAidl=true)")
@Deprecated
private void __metadata() {}

View File

@@ -340,8 +340,13 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
augmentedNonApps[augmentedNonApps.length - 1] = getDividerBarLegacyTarget();
try {
ActivityTaskManager.getService().setRunningRemoteTransitionDelegate(
adapter.getCallingApplication());
try {
ActivityTaskManager.getService().setRunningRemoteTransitionDelegate(
adapter.getCallingApplication());
} catch (SecurityException e) {
Slog.e(TAG, "Unable to boost animation thread. This should only happen"
+ " during unit tests");
}
adapter.getRunner().onAnimationStart(transit, apps, wallpapers, nonApps,
finishedCallback);
} catch (RemoteException e) {

View File

@@ -18,9 +18,11 @@ package com.android.wm.shell.transition;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityTaskManager;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.util.Slog;
import android.view.SurfaceControl;
import android.window.IRemoteTransition;
import android.window.IRemoteTransitionFinishedCallback;
@@ -89,6 +91,13 @@ public class OneShotRemoteHandler implements Transitions.TransitionHandler {
if (mRemote.asBinder() != null) {
mRemote.asBinder().linkToDeath(remoteDied, 0 /* flags */);
}
try {
ActivityTaskManager.getService().setRunningRemoteTransitionDelegate(
mRemote.getAppThread());
} catch (SecurityException e) {
Slog.e(Transitions.TAG, "Unable to boost animation thread. This should only happen"
+ " during unit tests");
}
mRemote.getRemoteTransition().startAnimation(transition, info, startTransaction, cb);
} catch (RemoteException e) {
Log.e(Transitions.TAG, "Error running remote transition.", e);

View File

@@ -18,6 +18,7 @@ package com.android.wm.shell.transition;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityTaskManager;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.ArrayMap;
@@ -130,6 +131,13 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler {
};
try {
handleDeath(remote.asBinder(), finishCallback);
try {
ActivityTaskManager.getService().setRunningRemoteTransitionDelegate(
remote.getAppThread());
} catch (SecurityException e) {
Log.e(Transitions.TAG, "Unable to boost animation thread. This should only happen"
+ " during unit tests");
}
remote.getRemoteTransition().startAnimation(transition, info, startTransaction, cb);
} catch (RemoteException e) {
Log.e(Transitions.TAG, "Error running remote transition.", e);

View File

@@ -26,6 +26,7 @@ import static android.view.WindowManager.TransitionOldType;
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
import android.annotation.SuppressLint;
import android.app.IApplicationThread;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.ArrayMap;
@@ -51,10 +52,10 @@ public class RemoteAnimationAdapterCompat {
private final RemoteTransitionCompat mRemoteTransition;
public RemoteAnimationAdapterCompat(RemoteAnimationRunnerCompat runner, long duration,
long statusBarTransitionDelay) {
long statusBarTransitionDelay, IApplicationThread appThread) {
mWrapped = new RemoteAnimationAdapter(wrapRemoteAnimationRunner(runner), duration,
statusBarTransitionDelay);
mRemoteTransition = buildRemoteTransition(runner);
mRemoteTransition = buildRemoteTransition(runner, appThread);
}
RemoteAnimationAdapter getWrapped() {
@@ -62,9 +63,10 @@ public class RemoteAnimationAdapterCompat {
}
/** Helper to just build a remote transition. Use this if the legacy adapter isn't needed. */
public static RemoteTransitionCompat buildRemoteTransition(RemoteAnimationRunnerCompat runner) {
public static RemoteTransitionCompat buildRemoteTransition(RemoteAnimationRunnerCompat runner,
IApplicationThread appThread) {
return new RemoteTransitionCompat(
new RemoteTransition(wrapRemoteTransition(runner)));
new RemoteTransition(wrapRemoteTransition(runner), appThread));
}
public RemoteTransitionCompat getRemoteTransition() {

View File

@@ -30,6 +30,7 @@ import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.app.IApplicationThread;
import android.content.ComponentName;
import android.graphics.Rect;
import android.os.IBinder;
@@ -72,7 +73,7 @@ public class RemoteTransitionCompat implements Parcelable {
}
public RemoteTransitionCompat(@NonNull RemoteTransitionRunner runner,
@NonNull Executor executor) {
@NonNull Executor executor, @Nullable IApplicationThread appThread) {
IRemoteTransition remote = new IRemoteTransition.Stub() {
@Override
public void startAnimation(IBinder transition, TransitionInfo info,
@@ -103,12 +104,12 @@ public class RemoteTransitionCompat implements Parcelable {
finishAdapter));
}
};
mTransition = new RemoteTransition(remote);
mTransition = new RemoteTransition(remote, appThread);
}
/** Constructor specifically for recents animation */
public RemoteTransitionCompat(RecentsAnimationListener recents,
RecentsAnimationControllerCompat controller) {
RecentsAnimationControllerCompat controller, IApplicationThread appThread) {
IRemoteTransition remote = new IRemoteTransition.Stub() {
final RecentsControllerWrap mRecentsSession = new RecentsControllerWrap();
IBinder mToken = null;
@@ -168,7 +169,7 @@ public class RemoteTransitionCompat implements Parcelable {
}
}
};
mTransition = new RemoteTransition(remote);
mTransition = new RemoteTransition(remote, appThread);
}
/** Adds a filter check that restricts this remote transition to home open transitions. */

View File

@@ -238,7 +238,7 @@ public class KeyguardService extends Service {
TransitionFilter f = new TransitionFilter();
f.mFlags = TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
shellTransitions.registerRemote(f,
new RemoteTransition(wrap(mExitAnimationRunner)));
new RemoteTransition(wrap(mExitAnimationRunner), getIApplicationThread()));
}
if (sEnableRemoteKeyguardOccludeAnimation) {
Slog.d(TAG, "KeyguardService registerRemote: TRANSIT_KEYGUARD_(UN)OCCLUDE");
@@ -257,7 +257,8 @@ public class KeyguardService extends Service {
f.mRequirements[1].mMustBeIndependent = false;
f.mRequirements[1].mFlags = FLAG_OCCLUDES_KEYGUARD;
f.mRequirements[1].mModes = new int[]{TRANSIT_CLOSE, TRANSIT_TO_BACK};
shellTransitions.registerRemote(f, new RemoteTransition(mOccludeAnimation));
shellTransitions.registerRemote(f,
new RemoteTransition(mOccludeAnimation, getIApplicationThread()));
// Now register for un-occlude.
f = new TransitionFilter();
@@ -277,7 +278,8 @@ public class KeyguardService extends Service {
f.mRequirements[0].mMustBeIndependent = false;
f.mRequirements[0].mFlags = FLAG_OCCLUDES_KEYGUARD;
f.mRequirements[0].mModes = new int[]{TRANSIT_OPEN, TRANSIT_TO_FRONT};
shellTransitions.registerRemote(f, new RemoteTransition(mUnoccludeAnimation));
shellTransitions.registerRemote(f,
new RemoteTransition(mUnoccludeAnimation, getIApplicationThread()));
}
} else {
RemoteAnimationDefinition definition = new RemoteAnimationDefinition();

View File

@@ -27,6 +27,7 @@ import static android.view.WindowManager.TRANSIT_OPEN;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.IApplicationThread;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.RemoteException;
@@ -68,6 +69,7 @@ class TransitionController {
private ITransitionPlayer mTransitionPlayer;
final TransitionMetricsReporter mTransitionMetricsReporter = new TransitionMetricsReporter();
private IApplicationThread mTransitionPlayerThread;
final ActivityTaskManagerService mAtm;
final TaskSnapshotController mTaskSnapshotController;
@@ -136,7 +138,8 @@ class TransitionController {
return mCollectingTransition;
}
void registerTransitionPlayer(@Nullable ITransitionPlayer player) {
void registerTransitionPlayer(@Nullable ITransitionPlayer player,
@Nullable IApplicationThread appThread) {
try {
// Note: asBinder() can be null if player is same process (likely in a test).
if (mTransitionPlayer != null) {
@@ -149,6 +152,7 @@ class TransitionController {
player.asBinder().linkToDeath(mTransitionPlayerDeath, 0);
}
mTransitionPlayer = player;
mTransitionPlayerThread = appThread;
} catch (RemoteException e) {
throw new RuntimeException("Unable to set transition player");
}
@@ -362,6 +366,9 @@ class TransitionController {
}
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Finish Transition: %s", record);
mPlayingTransitions.remove(record);
if (mPlayingTransitions.isEmpty()) {
setAnimationRunning(false /* running */);
}
record.finishTransition();
mRunningLock.doNotifyLocked();
}
@@ -371,9 +378,22 @@ class TransitionController {
throw new IllegalStateException("Trying to move non-collecting transition to playing");
}
mCollectingTransition = null;
if (mPlayingTransitions.isEmpty()) {
setAnimationRunning(true /* running */);
}
mPlayingTransitions.add(transition);
}
private void setAnimationRunning(boolean running) {
if (mTransitionPlayerThread == null) return;
final WindowProcessController wpc = mAtm.getProcessController(mTransitionPlayerThread);
if (wpc == null) {
Slog.w(TAG, "Unable to find process for player thread=" + mTransitionPlayerThread);
return;
}
wpc.setRunningRemoteAnimation(running);
}
void abort(Transition transition) {
if (transition != mCollectingTransition) {
throw new IllegalStateException("Too late to abort.");

View File

@@ -45,6 +45,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.IApplicationThread;
import android.app.WindowConfiguration;
import android.content.ActivityNotFoundException;
import android.content.Intent;
@@ -1031,10 +1032,18 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
@Override
public void registerTransitionPlayer(ITransitionPlayer player) {
enforceTaskPermission("registerTransitionPlayer()");
final int callerPid = Binder.getCallingPid();
final int callerUid = Binder.getCallingUid();
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
mTransitionController.registerTransitionPlayer(player);
final WindowProcessController wpc =
mService.getProcessController(callerPid, callerUid);
IApplicationThread appThread = null;
if (wpc != null) {
appThread = wpc.getThread();
}
mTransitionController.registerTransitionPlayer(player, appThread);
}
} finally {
Binder.restoreCallingIdentity(ident);

View File

@@ -473,7 +473,7 @@ public class TransitionTests extends WindowTestsBase {
final TaskSnapshotController snapshotController = mock(TaskSnapshotController.class);
final TransitionController controller = new TransitionController(mAtm, snapshotController);
final ITransitionPlayer player = new ITransitionPlayer.Default();
controller.registerTransitionPlayer(player);
controller.registerTransitionPlayer(player, null /* appThread */);
ITaskOrganizer mockOrg = mock(ITaskOrganizer.class);
final Transition openTransition = controller.createTransition(TRANSIT_OPEN);
@@ -539,7 +539,7 @@ public class TransitionTests extends WindowTestsBase {
final TaskSnapshotController snapshotController = mock(TaskSnapshotController.class);
final TransitionController controller = new TransitionController(mAtm, snapshotController);
final ITransitionPlayer player = new ITransitionPlayer.Default();
controller.registerTransitionPlayer(player);
controller.registerTransitionPlayer(player, null /* appThread */);
ITaskOrganizer mockOrg = mock(ITaskOrganizer.class);
final Transition openTransition = controller.createTransition(TRANSIT_OPEN);

View File

@@ -316,7 +316,8 @@ public class WallpaperControllerTests extends WindowTestsBase {
final IBinder mockBinder = mock(IBinder.class);
final ITransitionPlayer mockPlayer = mock(ITransitionPlayer.class);
doReturn(mockBinder).when(mockPlayer).asBinder();
mWm.mAtmService.getTransitionController().registerTransitionPlayer(mockPlayer);
mWm.mAtmService.getTransitionController().registerTransitionPlayer(mockPlayer,
null /* appThread */);
Transition transit =
mWm.mAtmService.getTransitionController().createTransition(TRANSIT_OPEN);

View File

@@ -802,7 +802,7 @@ class WindowTestsBase extends SystemServiceTestsBase {
TestTransitionPlayer registerTestTransitionPlayer() {
final TestTransitionPlayer testPlayer = new TestTransitionPlayer(
mAtm.getTransitionController(), mAtm.mWindowOrganizerController);
testPlayer.mController.registerTransitionPlayer(testPlayer);
testPlayer.mController.registerTransitionPlayer(testPlayer, null /* appThread */);
return testPlayer;
}