blob: 35f8d343acc1a9eeb2c64d5624b68f2e701a8e76 [file] [log] [blame]
Jorim Jaggi33a701a2017-12-01 14:58:18 +01001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.wm;
18
Jorim Jaggiab20e162018-03-27 13:06:09 +020019import static com.android.server.wm.AnimationAdapterProto.REMOTE;
Adrian Roosb125e0b2019-10-02 14:55:14 +020020import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_REMOTE_ANIMATIONS;
Jorim Jaggiab20e162018-03-27 13:06:09 +020021import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET;
Jorim Jaggi33a701a2017-12-01 14:58:18 +010022import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
23import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
24
25import android.graphics.Point;
26import android.graphics.Rect;
Jorim Jaggiab20e162018-03-27 13:06:09 +020027import android.os.Binder;
Jorim Jaggi33a701a2017-12-01 14:58:18 +010028import android.os.Handler;
Adrian Roos842e7882018-03-26 17:34:06 +020029import android.os.IBinder.DeathRecipient;
Jorim Jaggi33a701a2017-12-01 14:58:18 +010030import android.os.RemoteException;
31import android.os.SystemClock;
32import android.util.Slog;
Jorim Jaggif75d1612018-02-27 15:05:21 +010033import android.util.proto.ProtoOutputStream;
Jorim Jaggi33a701a2017-12-01 14:58:18 +010034import android.view.IRemoteAnimationFinishedCallback;
Jorim Jaggi33a701a2017-12-01 14:58:18 +010035import android.view.RemoteAnimationAdapter;
36import android.view.RemoteAnimationTarget;
37import android.view.SurfaceControl;
38import android.view.SurfaceControl.Transaction;
39
Jorim Jaggif75d1612018-02-27 15:05:21 +010040import com.android.internal.util.FastPrintWriter;
Adrian Roosb125e0b2019-10-02 14:55:14 +020041import com.android.server.protolog.ProtoLogImpl;
42import com.android.server.protolog.common.ProtoLog;
Issei Suzuki8b995df2020-01-08 12:23:04 +010043import com.android.server.wm.SurfaceAnimator.AnimationType;
Jorim Jaggi33a701a2017-12-01 14:58:18 +010044import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
45
Jorim Jaggif75d1612018-02-27 15:05:21 +010046import java.io.PrintWriter;
47import java.io.StringWriter;
Jorim Jaggi33a701a2017-12-01 14:58:18 +010048import java.util.ArrayList;
49
50/**
51 * Helper class to run app animations in a remote process.
52 */
Adrian Roos842e7882018-03-26 17:34:06 +020053class RemoteAnimationController implements DeathRecipient {
Winson Chungc6c3f852018-04-09 15:41:03 -070054 private static final String TAG = TAG_WITH_CLASS_NAME
Winson Chungc6c3f852018-04-09 15:41:03 -070055 ? "RemoteAnimationController" : TAG_WM;
Jorim Jaggi33a701a2017-12-01 14:58:18 +010056 private static final long TIMEOUT_MS = 2000;
57
58 private final WindowManagerService mService;
59 private final RemoteAnimationAdapter mRemoteAnimationAdapter;
Evan Rosky2289ba12018-11-19 18:28:18 -080060 private final ArrayList<RemoteAnimationRecord> mPendingAnimations = new ArrayList<>();
Winson Chungd5852192019-09-06 17:20:28 -070061 private final ArrayList<WallpaperAnimationAdapter> mPendingWallpaperAnimations =
62 new ArrayList<>();
Jorim Jaggi33a701a2017-12-01 14:58:18 +010063 private final Rect mTmpRect = new Rect();
64 private final Handler mHandler;
Winson Chungc6c3f852018-04-09 15:41:03 -070065 private final Runnable mTimeoutRunnable = () -> cancelAnimation("timeoutRunnable");
Jorim Jaggi33a701a2017-12-01 14:58:18 +010066
Adrian Roos842e7882018-03-26 17:34:06 +020067 private FinishedCallback mFinishedCallback;
68 private boolean mCanceled;
Adrian Roos653c6c12018-04-09 14:12:46 -070069 private boolean mLinkedToDeathOfRunner;
Jorim Jaggi33a701a2017-12-01 14:58:18 +010070
71 RemoteAnimationController(WindowManagerService service,
72 RemoteAnimationAdapter remoteAnimationAdapter, Handler handler) {
73 mService = service;
74 mRemoteAnimationAdapter = remoteAnimationAdapter;
75 mHandler = handler;
76 }
77
78 /**
lumark19a5d2e2019-10-11 16:19:30 +080079 * Creates an animation record for each individual {@link WindowContainer}.
Jorim Jaggi33a701a2017-12-01 14:58:18 +010080 *
lumark19a5d2e2019-10-11 16:19:30 +080081 * @param windowContainer The windows to animate.
Jorim Jaggi33a701a2017-12-01 14:58:18 +010082 * @param position The position app bounds, in screen coordinates.
lumark2ec19122020-01-23 00:09:04 +080083 * @param localBounds The bounds of the app relative to its parent.
Evan Rosky2289ba12018-11-19 18:28:18 -080084 * @param stackBounds The stack bounds of the app relative to position.
85 * @param startBounds The stack bounds before the transition, in screen coordinates
86 * @return The record representing animation(s) to run on the app.
Jorim Jaggi33a701a2017-12-01 14:58:18 +010087 */
lumark19a5d2e2019-10-11 16:19:30 +080088 RemoteAnimationRecord createRemoteAnimationRecord(WindowContainer windowContainer,
lumark2ec19122020-01-23 00:09:04 +080089 Point position, Rect localBounds, Rect stackBounds, Rect startBounds) {
lumark19a5d2e2019-10-11 16:19:30 +080090 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "createAnimationAdapter(): container=%s",
91 windowContainer);
lumark2ec19122020-01-23 00:09:04 +080092 final RemoteAnimationRecord adapters = new RemoteAnimationRecord(windowContainer, position,
93 localBounds, stackBounds, startBounds);
Evan Rosky2289ba12018-11-19 18:28:18 -080094 mPendingAnimations.add(adapters);
95 return adapters;
Jorim Jaggi33a701a2017-12-01 14:58:18 +010096 }
97
98 /**
99 * Called when the transition is ready to be started, and all leashes have been set up.
100 */
101 void goodToGo() {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200102 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "goodToGo()");
Adrian Roos842e7882018-03-26 17:34:06 +0200103 if (mPendingAnimations.isEmpty() || mCanceled) {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200104 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS,
105 "goodToGo(): Animation finished already, canceled=%s mPendingAnimations=%d",
106 mCanceled, mPendingAnimations.size());
Jorim Jaggi93f9fe32018-01-25 15:06:13 +0100107 onAnimationFinished();
108 return;
109 }
Jorim Jaggia19d7812018-02-01 15:03:59 +0100110
111 // Scale the timeout with the animator scale the controlling app is using.
112 mHandler.postDelayed(mTimeoutRunnable,
113 (long) (TIMEOUT_MS * mService.getCurrentAnimatorScale()));
Jorim Jaggi91f9f3482018-02-14 10:58:26 -0800114 mFinishedCallback = new FinishedCallback(this);
Chavi Weingarten16d0d072018-02-12 23:50:28 +0000115
Winson Chungd5852192019-09-06 17:20:28 -0700116 // Create the app targets
117 final RemoteAnimationTarget[] appTargets = createAppAnimations();
118 if (appTargets.length == 0) {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200119 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "goodToGo(): No apps to animate");
Jorim Jaggic4d29f22018-03-22 16:30:56 +0100120 onAnimationFinished();
121 return;
122 }
Winson Chungd5852192019-09-06 17:20:28 -0700123
124 // Create the remote wallpaper animation targets (if any)
125 final RemoteAnimationTarget[] wallpaperTargets = createWallpaperAnimations();
Chavi Weingarten16d0d072018-02-12 23:50:28 +0000126 mService.mAnimator.addAfterPrepareSurfacesRunnable(() -> {
127 try {
Adrian Roos653c6c12018-04-09 14:12:46 -0700128 linkToDeathOfRunner();
Winson Chungd5852192019-09-06 17:20:28 -0700129 mRemoteAnimationAdapter.getRunner().onAnimationStart(appTargets, wallpaperTargets,
130 mFinishedCallback);
Chavi Weingarten16d0d072018-02-12 23:50:28 +0000131 } catch (RemoteException e) {
132 Slog.e(TAG, "Failed to start remote animation", e);
133 onAnimationFinished();
134 }
Adrian Roosb125e0b2019-10-02 14:55:14 +0200135 if (ProtoLogImpl.isEnabled(WM_DEBUG_REMOTE_ANIMATIONS)) {
136 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "startAnimation(): Notify animation start:");
Winson Chungc6c3f852018-04-09 15:41:03 -0700137 writeStartDebugStatement();
138 }
Chavi Weingarten16d0d072018-02-12 23:50:28 +0000139 });
Jorim Jaggi589c5ba2019-07-30 16:50:13 +0200140 setRunningRemoteAnimation(true);
Jorim Jaggif75d1612018-02-27 15:05:21 +0100141 }
142
Arthur Hung442aff22019-05-07 19:49:31 +0800143 void cancelAnimation(String reason) {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200144 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "cancelAnimation(): reason=%s", reason);
Adrian Roos842e7882018-03-26 17:34:06 +0200145 synchronized (mService.getWindowManagerLock()) {
146 if (mCanceled) {
147 return;
148 }
149 mCanceled = true;
150 }
151 onAnimationFinished();
152 invokeAnimationCancelled();
153 }
154
Jorim Jaggif75d1612018-02-27 15:05:21 +0100155 private void writeStartDebugStatement() {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200156 ProtoLog.i(WM_DEBUG_REMOTE_ANIMATIONS, "Starting remote animation");
Jorim Jaggif75d1612018-02-27 15:05:21 +0100157 final StringWriter sw = new StringWriter();
158 final FastPrintWriter pw = new FastPrintWriter(sw);
159 for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
Evan Rosky2289ba12018-11-19 18:28:18 -0800160 mPendingAnimations.get(i).mAdapter.dump(pw, "");
Jorim Jaggif75d1612018-02-27 15:05:21 +0100161 }
162 pw.close();
Adrian Roosb125e0b2019-10-02 14:55:14 +0200163 ProtoLog.i(WM_DEBUG_REMOTE_ANIMATIONS, "%s", sw.toString());
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100164 }
165
Winson Chungd5852192019-09-06 17:20:28 -0700166 private RemoteAnimationTarget[] createAppAnimations() {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200167 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "createAppAnimations()");
Jorim Jaggi17770212018-01-22 20:01:21 +0100168 final ArrayList<RemoteAnimationTarget> targets = new ArrayList<>();
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100169 for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
Evan Rosky2289ba12018-11-19 18:28:18 -0800170 final RemoteAnimationRecord wrappers = mPendingAnimations.get(i);
171 final RemoteAnimationTarget target = wrappers.createRemoteAnimationTarget();
Jorim Jaggi17770212018-01-22 20:01:21 +0100172 if (target != null) {
lumark19a5d2e2019-10-11 16:19:30 +0800173 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tAdd container=%s",
174 wrappers.mWindowContainer);
Jorim Jaggi17770212018-01-22 20:01:21 +0100175 targets.add(target);
Jorim Jaggic4d29f22018-03-22 16:30:56 +0100176 } else {
lumark19a5d2e2019-10-11 16:19:30 +0800177 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tRemove container=%s",
178 wrappers.mWindowContainer);
Jorim Jaggib8a9cbe2018-03-27 18:02:18 +0200179
180 // We can't really start an animation but we still need to make sure to finish the
181 // pending animation that was started by SurfaceAnimator
Evan Rosky2289ba12018-11-19 18:28:18 -0800182 if (wrappers.mAdapter != null
183 && wrappers.mAdapter.mCapturedFinishCallback != null) {
184 wrappers.mAdapter.mCapturedFinishCallback
Issei Suzuki8b995df2020-01-08 12:23:04 +0100185 .onAnimationFinished(wrappers.mAdapter.mAnimationType,
186 wrappers.mAdapter);
Evan Rosky2289ba12018-11-19 18:28:18 -0800187 }
188 if (wrappers.mThumbnailAdapter != null
189 && wrappers.mThumbnailAdapter.mCapturedFinishCallback != null) {
190 wrappers.mThumbnailAdapter.mCapturedFinishCallback
Issei Suzuki8b995df2020-01-08 12:23:04 +0100191 .onAnimationFinished(wrappers.mAdapter.mAnimationType,
192 wrappers.mThumbnailAdapter);
Jorim Jaggib8a9cbe2018-03-27 18:02:18 +0200193 }
Jorim Jaggic4d29f22018-03-22 16:30:56 +0100194 mPendingAnimations.remove(i);
Jorim Jaggi17770212018-01-22 20:01:21 +0100195 }
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100196 }
Jorim Jaggi17770212018-01-22 20:01:21 +0100197 return targets.toArray(new RemoteAnimationTarget[targets.size()]);
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100198 }
199
Winson Chungd5852192019-09-06 17:20:28 -0700200 private RemoteAnimationTarget[] createWallpaperAnimations() {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200201 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "createWallpaperAnimations()");
Winson Chungd5852192019-09-06 17:20:28 -0700202 return WallpaperAnimationAdapter.startWallpaperAnimations(mService,
203 mRemoteAnimationAdapter.getDuration(),
204 mRemoteAnimationAdapter.getStatusBarTransitionDelay(),
205 adapter -> {
206 synchronized (mService.mGlobalLock) {
207 // If the wallpaper animation is canceled, continue with the app animation
208 mPendingWallpaperAnimations.remove(adapter);
209 }
210 }, mPendingWallpaperAnimations);
211 }
212
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100213 private void onAnimationFinished() {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200214 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "onAnimationFinished(): mPendingAnimations=%d",
215 mPendingAnimations.size());
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100216 mHandler.removeCallbacks(mTimeoutRunnable);
Wale Ogunwaledb485de2018-10-29 09:47:07 -0700217 synchronized (mService.mGlobalLock) {
Adrian Roos653c6c12018-04-09 14:12:46 -0700218 unlinkToDeathOfRunner();
Jorim Jaggi91f9f3482018-02-14 10:58:26 -0800219 releaseFinishedCallback();
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100220 mService.openSurfaceTransaction();
221 try {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200222 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS,
Winson Chung703719b2018-04-18 17:53:15 -0700223 "onAnimationFinished(): Notify animation finished:");
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100224 for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
Evan Rosky2289ba12018-11-19 18:28:18 -0800225 final RemoteAnimationRecord adapters = mPendingAnimations.get(i);
226 if (adapters.mAdapter != null) {
227 adapters.mAdapter.mCapturedFinishCallback
Issei Suzuki8b995df2020-01-08 12:23:04 +0100228 .onAnimationFinished(adapters.mAdapter.mAnimationType,
229 adapters.mAdapter);
Evan Rosky2289ba12018-11-19 18:28:18 -0800230 }
231 if (adapters.mThumbnailAdapter != null) {
232 adapters.mThumbnailAdapter.mCapturedFinishCallback
Issei Suzuki8b995df2020-01-08 12:23:04 +0100233 .onAnimationFinished(adapters.mAdapter.mAnimationType,
234 adapters.mThumbnailAdapter);
Evan Rosky2289ba12018-11-19 18:28:18 -0800235 }
Winson Chungd5852192019-09-06 17:20:28 -0700236 mPendingAnimations.remove(i);
lumark19a5d2e2019-10-11 16:19:30 +0800237 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tcontainer=%s",
238 adapters.mWindowContainer);
Winson Chungd5852192019-09-06 17:20:28 -0700239 }
240
241 for (int i = mPendingWallpaperAnimations.size() - 1; i >= 0; i--) {
242 final WallpaperAnimationAdapter adapter = mPendingWallpaperAnimations.get(i);
Issei Suzuki8b995df2020-01-08 12:23:04 +0100243 adapter.getLeashFinishedCallback().onAnimationFinished(
244 adapter.getLastAnimationType(), adapter);
Winson Chungd5852192019-09-06 17:20:28 -0700245 mPendingWallpaperAnimations.remove(i);
Adrian Roosb125e0b2019-10-02 14:55:14 +0200246 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\twallpaper=%s", adapter.getToken());
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100247 }
Winson Chungc6c3f852018-04-09 15:41:03 -0700248 } catch (Exception e) {
249 Slog.e(TAG, "Failed to finish remote animation", e);
250 throw e;
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100251 } finally {
252 mService.closeSurfaceTransaction("RemoteAnimationController#finished");
253 }
254 }
Jorim Jaggi589c5ba2019-07-30 16:50:13 +0200255 setRunningRemoteAnimation(false);
Adrian Roosb125e0b2019-10-02 14:55:14 +0200256 ProtoLog.i(WM_DEBUG_REMOTE_ANIMATIONS, "Finishing remote animation");
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100257 }
258
259 private void invokeAnimationCancelled() {
260 try {
261 mRemoteAnimationAdapter.getRunner().onAnimationCancelled();
262 } catch (RemoteException e) {
263 Slog.e(TAG, "Failed to notify cancel", e);
264 }
265 }
266
Jorim Jaggi91f9f3482018-02-14 10:58:26 -0800267 private void releaseFinishedCallback() {
268 if (mFinishedCallback != null) {
269 mFinishedCallback.release();
270 mFinishedCallback = null;
271 }
272 }
273
Jorim Jaggi589c5ba2019-07-30 16:50:13 +0200274 private void setRunningRemoteAnimation(boolean running) {
Jorim Jaggibc2aabe2018-03-08 17:27:43 +0100275 final int pid = mRemoteAnimationAdapter.getCallingPid();
Jorim Jaggi589c5ba2019-07-30 16:50:13 +0200276 final int uid = mRemoteAnimationAdapter.getCallingUid();
Jorim Jaggibc2aabe2018-03-08 17:27:43 +0100277 if (pid == 0) {
278 throw new RuntimeException("Calling pid of remote animation was null");
279 }
Jorim Jaggi589c5ba2019-07-30 16:50:13 +0200280 final WindowProcessController wpc = mService.mAtmService.getProcessController(pid, uid);
281 if (wpc == null) {
282 Slog.w(TAG, "Unable to find process with pid=" + pid + " uid=" + uid);
283 return;
284 }
285 wpc.setRunningRemoteAnimation(running);
Jorim Jaggibc2aabe2018-03-08 17:27:43 +0100286 }
287
Adrian Roos653c6c12018-04-09 14:12:46 -0700288 private void linkToDeathOfRunner() throws RemoteException {
289 if (!mLinkedToDeathOfRunner) {
290 mRemoteAnimationAdapter.getRunner().asBinder().linkToDeath(this, 0);
291 mLinkedToDeathOfRunner = true;
292 }
293 }
294
295 private void unlinkToDeathOfRunner() {
296 if (mLinkedToDeathOfRunner) {
297 mRemoteAnimationAdapter.getRunner().asBinder().unlinkToDeath(this, 0);
298 mLinkedToDeathOfRunner = false;
299 }
300 }
301
Adrian Roos842e7882018-03-26 17:34:06 +0200302 @Override
303 public void binderDied() {
Winson Chungc6c3f852018-04-09 15:41:03 -0700304 cancelAnimation("binderDied");
Adrian Roos842e7882018-03-26 17:34:06 +0200305 }
306
Jorim Jaggi91f9f3482018-02-14 10:58:26 -0800307 private static final class FinishedCallback extends IRemoteAnimationFinishedCallback.Stub {
308
309 RemoteAnimationController mOuter;
310
311 FinishedCallback(RemoteAnimationController outer) {
312 mOuter = outer;
313 }
314
315 @Override
316 public void onAnimationFinished() throws RemoteException {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200317 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "app-onAnimationFinished(): mOuter=%s", mOuter);
Jorim Jaggiab20e162018-03-27 13:06:09 +0200318 final long token = Binder.clearCallingIdentity();
319 try {
320 if (mOuter != null) {
321 mOuter.onAnimationFinished();
Jorim Jaggi91f9f3482018-02-14 10:58:26 -0800322
Jorim Jaggiab20e162018-03-27 13:06:09 +0200323 // In case the client holds on to the finish callback, make sure we don't leak
324 // RemoteAnimationController which in turn would leak the runner on the client.
325 mOuter = null;
326 }
327 } finally {
328 Binder.restoreCallingIdentity(token);
Jorim Jaggi91f9f3482018-02-14 10:58:26 -0800329 }
330 }
331
332 /**
333 * Marks this callback as not be used anymore by releasing the reference to the outer class
334 * to prevent memory leak.
335 */
336 void release() {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200337 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "app-release(): mOuter=%s", mOuter);
Jorim Jaggi91f9f3482018-02-14 10:58:26 -0800338 mOuter = null;
339 }
340 };
341
Evan Rosky2289ba12018-11-19 18:28:18 -0800342 /**
lumark19a5d2e2019-10-11 16:19:30 +0800343 * Contains information about a remote-animation for one WindowContainer. This keeps track of,
Evan Rosky2289ba12018-11-19 18:28:18 -0800344 * potentially, multiple animating surfaces (AdapterWrappers) associated with one
345 * Window/Transition. For example, a change transition has an adapter controller for the
346 * main window and an adapter controlling the start-state snapshot.
347 * <p>
348 * This can be thought of as a bridge between the information that the remote animator sees (via
349 * {@link RemoteAnimationTarget}) and what the server sees (the
350 * {@link RemoteAnimationAdapterWrapper}(s) interfacing with the moving surfaces).
351 */
352 public class RemoteAnimationRecord {
353 RemoteAnimationAdapterWrapper mAdapter;
354 RemoteAnimationAdapterWrapper mThumbnailAdapter = null;
355 RemoteAnimationTarget mTarget;
lumark19a5d2e2019-10-11 16:19:30 +0800356 final WindowContainer mWindowContainer;
Evan Rosky2289ba12018-11-19 18:28:18 -0800357 final Rect mStartBounds;
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100358
lumark2ec19122020-01-23 00:09:04 +0800359 RemoteAnimationRecord(WindowContainer windowContainer, Point endPos, Rect localBounds,
360 Rect endBounds, Rect startBounds) {
lumark19a5d2e2019-10-11 16:19:30 +0800361 mWindowContainer = windowContainer;
lumark2ec19122020-01-23 00:09:04 +0800362 mAdapter = new RemoteAnimationAdapterWrapper(this, endPos, localBounds, endBounds);
Evan Rosky2289ba12018-11-19 18:28:18 -0800363 if (startBounds != null) {
364 mStartBounds = new Rect(startBounds);
365 mTmpRect.set(startBounds);
366 mTmpRect.offsetTo(0, 0);
Evan Rosky966759f2019-01-15 10:33:58 -0800367 if (mRemoteAnimationAdapter.getChangeNeedsSnapshot()) {
368 mThumbnailAdapter =
lumark2ec19122020-01-23 00:09:04 +0800369 new RemoteAnimationAdapterWrapper(this, new Point(0, 0), localBounds,
370 mTmpRect);
Evan Rosky966759f2019-01-15 10:33:58 -0800371 }
Evan Rosky2289ba12018-11-19 18:28:18 -0800372 } else {
373 mStartBounds = null;
374 }
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100375 }
376
Evan Rosky2289ba12018-11-19 18:28:18 -0800377 RemoteAnimationTarget createRemoteAnimationTarget() {
lumark19a5d2e2019-10-11 16:19:30 +0800378 if (mAdapter == null
Evan Rosky2289ba12018-11-19 18:28:18 -0800379 || mAdapter.mCapturedFinishCallback == null
380 || mAdapter.mCapturedLeash == null) {
Jorim Jaggi17770212018-01-22 20:01:21 +0100381 return null;
382 }
lumark19a5d2e2019-10-11 16:19:30 +0800383 mTarget = mWindowContainer.createRemoteAnimationTarget(this);
Jorim Jaggif75d1612018-02-27 15:05:21 +0100384 return mTarget;
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100385 }
386
lumark19a5d2e2019-10-11 16:19:30 +0800387 int getMode() {
388 final DisplayContent dc = mWindowContainer.getDisplayContent();
lumark5341d1c2019-12-14 01:54:02 +0800389 final ActivityRecord topActivity = mWindowContainer.getTopMostActivity();
390 if (dc.mOpeningApps.contains(topActivity)) {
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100391 return RemoteAnimationTarget.MODE_OPENING;
Evan Rosky55bddd82020-01-29 13:07:18 -0800392 } else if (dc.mChangingContainers.contains(topActivity)) {
Evan Rosky2289ba12018-11-19 18:28:18 -0800393 return RemoteAnimationTarget.MODE_CHANGING;
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100394 } else {
395 return RemoteAnimationTarget.MODE_CLOSING;
396 }
397 }
Evan Rosky2289ba12018-11-19 18:28:18 -0800398 }
399
lumark19a5d2e2019-10-11 16:19:30 +0800400 class RemoteAnimationAdapterWrapper implements AnimationAdapter {
Evan Rosky2289ba12018-11-19 18:28:18 -0800401 private final RemoteAnimationRecord mRecord;
402 SurfaceControl mCapturedLeash;
403 private OnAnimationFinishedCallback mCapturedFinishCallback;
Issei Suzuki8b995df2020-01-08 12:23:04 +0100404 private @AnimationType int mAnimationType;
lumark19a5d2e2019-10-11 16:19:30 +0800405 final Point mPosition = new Point();
lumark2ec19122020-01-23 00:09:04 +0800406 final Rect mLocalBounds;
lumark19a5d2e2019-10-11 16:19:30 +0800407 final Rect mStackBounds = new Rect();
Evan Rosky2289ba12018-11-19 18:28:18 -0800408
409 RemoteAnimationAdapterWrapper(RemoteAnimationRecord record, Point position,
lumark2ec19122020-01-23 00:09:04 +0800410 Rect localBounds, Rect stackBounds) {
Evan Rosky2289ba12018-11-19 18:28:18 -0800411 mRecord = record;
412 mPosition.set(position.x, position.y);
lumark2ec19122020-01-23 00:09:04 +0800413 mLocalBounds = localBounds;
Evan Rosky2289ba12018-11-19 18:28:18 -0800414 mStackBounds.set(stackBounds);
415 }
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100416
417 @Override
Jorim Jaggi82c17862018-02-21 17:50:18 +0100418 public boolean getShowWallpaper() {
419 return false;
420 }
421
422 @Override
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100423 public void startAnimation(SurfaceControl animationLeash, Transaction t,
Issei Suzuki8b995df2020-01-08 12:23:04 +0100424 @AnimationType int type, OnAnimationFinishedCallback finishCallback) {
Adrian Roosb125e0b2019-10-02 14:55:14 +0200425 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "startAnimation");
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100426
427 // Restore z-layering, position and stack crop until client has a chance to modify it.
lumark19a5d2e2019-10-11 16:19:30 +0800428 t.setLayer(animationLeash, mRecord.mWindowContainer.getPrefixOrderIndex());
Evan Roskyb96326e2019-07-01 09:59:17 -0700429 if (mRecord.mStartBounds != null) {
430 t.setPosition(animationLeash, mRecord.mStartBounds.left, mRecord.mStartBounds.top);
431 t.setWindowCrop(animationLeash, mRecord.mStartBounds.width(),
432 mRecord.mStartBounds.height());
433 } else {
434 t.setPosition(animationLeash, mPosition.x, mPosition.y);
435 t.setWindowCrop(animationLeash, mStackBounds.width(), mStackBounds.height());
436 }
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100437 mCapturedLeash = animationLeash;
438 mCapturedFinishCallback = finishCallback;
Issei Suzuki8b995df2020-01-08 12:23:04 +0100439 mAnimationType = type;
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100440 }
441
442 @Override
443 public void onAnimationCancelled(SurfaceControl animationLeash) {
Evan Rosky2289ba12018-11-19 18:28:18 -0800444 if (mRecord.mAdapter == this) {
445 mRecord.mAdapter = null;
446 } else {
447 mRecord.mThumbnailAdapter = null;
448 }
449 if (mRecord.mAdapter == null && mRecord.mThumbnailAdapter == null) {
450 mPendingAnimations.remove(mRecord);
451 }
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100452 if (mPendingAnimations.isEmpty()) {
Winson Chungd5852192019-09-06 17:20:28 -0700453 cancelAnimation("allAppAnimationsCanceled");
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100454 }
455 }
456
457 @Override
458 public long getDurationHint() {
459 return mRemoteAnimationAdapter.getDuration();
460 }
461
462 @Override
463 public long getStatusBarTransitionsStartTime() {
464 return SystemClock.uptimeMillis()
465 + mRemoteAnimationAdapter.getStatusBarTransitionDelay();
466 }
Jorim Jaggif75d1612018-02-27 15:05:21 +0100467
468 @Override
469 public void dump(PrintWriter pw, String prefix) {
lumark19a5d2e2019-10-11 16:19:30 +0800470 pw.print(prefix); pw.print("container="); pw.println(mRecord.mWindowContainer);
Evan Rosky2289ba12018-11-19 18:28:18 -0800471 if (mRecord.mTarget != null) {
Jorim Jaggif75d1612018-02-27 15:05:21 +0100472 pw.print(prefix); pw.println("Target:");
Evan Rosky2289ba12018-11-19 18:28:18 -0800473 mRecord.mTarget.dump(pw, prefix + " ");
Jorim Jaggif75d1612018-02-27 15:05:21 +0100474 } else {
475 pw.print(prefix); pw.println("Target: null");
476 }
477 }
478
479 @Override
Jeffrey Huangcb782852019-12-05 11:28:11 -0800480 public void dumpDebug(ProtoOutputStream proto) {
Jorim Jaggif75d1612018-02-27 15:05:21 +0100481 final long token = proto.start(REMOTE);
Evan Rosky2289ba12018-11-19 18:28:18 -0800482 if (mRecord.mTarget != null) {
Jeffrey Huangcb782852019-12-05 11:28:11 -0800483 mRecord.mTarget.dumpDebug(proto, TARGET);
Jorim Jaggif75d1612018-02-27 15:05:21 +0100484 }
485 proto.end(token);
486 }
Jorim Jaggi33a701a2017-12-01 14:58:18 +0100487 }
488}