blob: 88625d35f9b483e6d4b814bd9bee85de147489bc [file] [log] [blame]
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001
Filip Gruszczynski4501d232015-09-02 13:00:02 -07002package com.android.server.wm;
3
Jorim Jaggi3878ca32017-02-02 17:13:05 -08004import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
Jorim Jaggi3878ca32017-02-02 17:13:05 -08005import static android.app.ActivityManagerInternal.APP_TRANSITION_SNAPSHOT;
6import static android.app.ActivityManagerInternal.APP_TRANSITION_SPLASH_SCREEN;
Jorim Jaggi275561a2016-02-23 10:11:02 -05007import static android.app.ActivityManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07008import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
9import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -070010import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_CLOSE;
11import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
Jorim Jaggife762342016-10-13 14:33:27 +020012import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
13import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
14import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
15import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_GOING_AWAY;
16import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
Matthew Ng26a1cec2017-05-18 14:42:51 -070017import static com.android.server.wm.AppTransition.TRANSIT_NONE;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -070018import static com.android.server.wm.AppTransition.TRANSIT_TASK_CLOSE;
19import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
20import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
21import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_BACK;
22import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
23import static com.android.server.wm.AppTransition.TRANSIT_WALLPAPER_CLOSE;
24import static com.android.server.wm.AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
25import static com.android.server.wm.AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
26import static com.android.server.wm.AppTransition.TRANSIT_WALLPAPER_OPEN;
Jorim Jaggia69243a2017-06-15 15:10:38 -040027import static com.android.server.wm.AppTransition.isKeyguardGoingAwayTransit;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080028import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080029import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080030import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
31import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
Jorim Jaggi192086e2016-03-11 17:17:03 +010032import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080033import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Jorim Jaggi192086e2016-03-11 17:17:03 +010034import static com.android.server.wm.WindowManagerService.H.NOTIFY_APP_TRANSITION_STARTING;
Jorim Jaggi192086e2016-03-11 17:17:03 +010035import static com.android.server.wm.WindowManagerService.H.REPORT_WINDOWS_CHANGE;
Jorim Jaggi192086e2016-03-11 17:17:03 +010036import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
37import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070038import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070039
Andrii Kulian441e4492016-09-29 15:25:00 -070040import android.content.res.Configuration;
Winson Chungaa7fa012017-05-24 15:50:06 -070041import android.graphics.GraphicBuffer;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070042import android.graphics.PixelFormat;
43import android.graphics.Rect;
Bryce Leee6c25d42017-05-31 10:27:42 -070044import android.os.Binder;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070045import android.os.Debug;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070046import android.os.Trace;
Filip Gruszczynski49b80af2015-09-24 09:04:26 -070047import android.util.ArraySet;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070048import android.util.Slog;
Jorim Jaggi3878ca32017-02-02 17:13:05 -080049import android.util.SparseIntArray;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070050import android.view.Display;
51import android.view.DisplayInfo;
52import android.view.Surface;
53import android.view.SurfaceControl;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -080054import android.view.WindowManager.LayoutParams;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070055import android.view.animation.Animation;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070056
Jorim Jaggid75962e2016-05-03 15:10:03 -070057import com.android.server.wm.WindowManagerService.H;
58
Filip Gruszczynski24966d42015-09-05 15:00:00 -070059import java.io.PrintWriter;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070060import java.util.ArrayList;
61
62/**
63 * Positions windows and their surfaces.
64 *
65 * It sets positions of windows by calculating their frames and then applies this by positioning
66 * surfaces according to these frames. Z layer is still assigned withing WindowManagerService.
67 */
68class WindowSurfacePlacer {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -080069 private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowSurfacePlacer" : TAG_WM;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070070 private final WindowManagerService mService;
71 private final WallpaperController mWallpaperControllerLocked;
72
73 private boolean mInLayout = false;
74
75 /** Only do a maximum of 6 repeated layouts. After that quit */
76 private int mLayoutRepeatCount;
77
78 static final int SET_UPDATE_ROTATION = 1 << 0;
79 static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1;
80 static final int SET_FORCE_HIDING_CHANGED = 1 << 2;
81 static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3;
82 static final int SET_TURN_ON_SCREEN = 1 << 4;
83 static final int SET_WALLPAPER_ACTION_PENDING = 1 << 5;
84
Filip Gruszczynski4501d232015-09-02 13:00:02 -070085 private final Rect mTmpStartRect = new Rect();
Wale Ogunwaleb4ec0a32015-12-14 10:31:43 -080086 private final Rect mTmpContentRect = new Rect();
Filip Gruszczynski4501d232015-09-02 13:00:02 -070087
Filip Gruszczynski24966d42015-09-05 15:00:00 -070088 private boolean mTraversalScheduled;
Jorim Jaggic4025202015-10-22 16:43:34 +020089 private int mDeferDepth = 0;
Filip Gruszczynski24966d42015-09-05 15:00:00 -070090
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -080091 private static final class LayerAndToken {
92 public int layer;
93 public AppWindowToken token;
94 }
95 private final LayerAndToken mTmpLayerAndToken = new LayerAndToken();
96
Jorim Jaggi3dac63a2016-03-01 12:37:07 +010097 private final ArrayList<SurfaceControl> mPendingDestroyingSurfaces = new ArrayList<>();
Jorim Jaggi3878ca32017-02-02 17:13:05 -080098 private final SparseIntArray mTempTransitionReasons = new SparseIntArray();
Jorim Jaggi3dac63a2016-03-01 12:37:07 +010099
Jorim Jaggied7993b2017-03-28 18:50:01 +0100100 private final Runnable mPerformSurfacePlacement;
101
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700102 public WindowSurfacePlacer(WindowManagerService service) {
103 mService = service;
Wale Ogunwale0303c572016-10-20 10:16:29 -0700104 mWallpaperControllerLocked = mService.mRoot.mWallpaperController;
Jorim Jaggied7993b2017-03-28 18:50:01 +0100105 mPerformSurfacePlacement = () -> {
106 synchronized (mService.mWindowMap) {
107 performSurfacePlacement();
108 }
109 };
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700110 }
111
Jorim Jaggic4025202015-10-22 16:43:34 +0200112 /**
113 * See {@link WindowManagerService#deferSurfaceLayout()}
114 */
115 void deferLayout() {
116 mDeferDepth++;
117 }
118
119 /**
120 * See {@link WindowManagerService#continueSurfaceLayout()}
121 */
122 void continueLayout() {
123 mDeferDepth--;
124 if (mDeferDepth <= 0) {
125 performSurfacePlacement();
126 }
127 }
128
Jorim Jaggi1f833082017-08-04 18:06:56 +0200129 boolean isLayoutDeferred() {
130 return mDeferDepth > 0;
131 }
132
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700133 final void performSurfacePlacement() {
Jorim Jaggi02886a82016-12-06 09:10:06 -0800134 performSurfacePlacement(false /* force */);
135 }
136
137 final void performSurfacePlacement(boolean force) {
138 if (mDeferDepth > 0 && !force) {
Jorim Jaggic4025202015-10-22 16:43:34 +0200139 return;
140 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700141 int loopCount = 6;
142 do {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700143 mTraversalScheduled = false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700144 performSurfacePlacementLoop();
Jorim Jaggied7993b2017-03-28 18:50:01 +0100145 mService.mAnimationHandler.removeCallbacks(mPerformSurfacePlacement);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700146 loopCount--;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700147 } while (mTraversalScheduled && loopCount > 0);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700148 mService.mRoot.mWallpaperActionPending = false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700149 }
150
151 private void performSurfacePlacementLoop() {
152 if (mInLayout) {
153 if (DEBUG) {
154 throw new RuntimeException("Recursive call!");
155 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800156 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700157 + Debug.getCallers(3));
158 return;
159 }
160
161 if (mService.mWaitingForConfig) {
162 // Our configuration has changed (most likely rotation), but we
163 // don't yet have the complete configuration to report to
164 // applications. Don't do any window layout until we have it.
165 return;
166 }
167
168 if (!mService.mDisplayReady) {
169 // Not yet initialized, nothing to do.
170 return;
171 }
172
173 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
174 mInLayout = true;
175
176 boolean recoveringMemory = false;
177 if (!mService.mForceRemoves.isEmpty()) {
178 recoveringMemory = true;
179 // Wait a little bit for things to settle down, and off we go.
180 while (!mService.mForceRemoves.isEmpty()) {
Wale Ogunwaleadde52e2016-07-16 13:11:55 -0700181 final WindowState ws = mService.mForceRemoves.remove(0);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800182 Slog.i(TAG, "Force removing: " + ws);
Wale Ogunwale571771c2016-08-26 13:18:50 -0700183 ws.removeImmediately();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700184 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800185 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700186 Object tmp = new Object();
187 synchronized (tmp) {
188 try {
189 tmp.wait(250);
190 } catch (InterruptedException e) {
191 }
192 }
193 }
194
195 try {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700196 mService.mRoot.performSurfacePlacement(recoveringMemory);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700197
198 mInLayout = false;
199
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700200 if (mService.mRoot.isLayoutNeeded()) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700201 if (++mLayoutRepeatCount < 6) {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700202 requestTraversal();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700203 } else {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800204 Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700205 mLayoutRepeatCount = 0;
206 }
207 } else {
208 mLayoutRepeatCount = 0;
209 }
210
211 if (mService.mWindowsChanged && !mService.mWindowChangeListeners.isEmpty()) {
212 mService.mH.removeMessages(REPORT_WINDOWS_CHANGE);
213 mService.mH.sendEmptyMessage(REPORT_WINDOWS_CHANGE);
214 }
215 } catch (RuntimeException e) {
216 mInLayout = false;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800217 Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700218 }
219
220 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
221 }
222
223 void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
224 if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800225 Slog.v(TAG, "Layouts looping: " + msg +
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700226 ", mPendingLayoutChanges = 0x" + Integer.toHexString(pendingLayoutChanges));
227 }
228 }
229
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700230 boolean isInLayout() {
231 return mInLayout;
232 }
233
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700234 /**
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700235 * @return bitmap indicating if another pass through layout must be made.
236 */
Wale Ogunwale0303c572016-10-20 10:16:29 -0700237 int handleAppTransitionReadyLocked() {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700238 int appsCount = mService.mOpeningApps.size();
Jorim Jaggidbaad382017-07-18 13:22:52 +0200239 if (!transitionGoodToGo(appsCount, mTempTransitionReasons)) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700240 return 0;
241 }
Chong Zhang8784be62016-06-28 15:25:07 -0700242 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "AppTransitionReady");
243
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800244 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700245 int transit = mService.mAppTransition.getAppTransition();
Jorim Jaggia69243a2017-06-15 15:10:38 -0400246 if (mService.mSkipAppTransitionAnimation && !isKeyguardGoingAwayTransit(transit)) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700247 transit = AppTransition.TRANSIT_UNSET;
248 }
249 mService.mSkipAppTransitionAnimation = false;
250 mService.mNoAnimationNotifyOnTransitionFinished.clear();
251
Jorim Jaggid75962e2016-05-03 15:10:03 -0700252 mService.mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700253
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700254 final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000255 // TODO: Don't believe this is really needed...
256 //mService.mWindowsChanged = true;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700257
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700258 mService.mRoot.mWallpaperMayChange = false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700259
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700260 // The top-most window will supply the layout params, and we will determine it below.
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800261 LayoutParams animLp = null;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700262 int bestAnimLayer = -1;
263 boolean fullscreenAnim = false;
264 boolean voiceInteraction = false;
265
Chong Zhangec8299c2016-07-29 13:09:40 -0700266 int i;
267 for (i = 0; i < appsCount; i++) {
268 final AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700269 // Clearing the mAnimatingExit flag before entering animation. It's set to true if app
270 // window is removed, or window relayout to invisible. This also affects window
271 // visibility. We need to clear it *before* maybeUpdateTransitToWallpaper() as the
272 // transition selection depends on wallpaper target visibility.
Chong Zhangec8299c2016-07-29 13:09:40 -0700273 wtoken.clearAnimatingFlags();
274
275 }
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700276
Chong Zhangec8299c2016-07-29 13:09:40 -0700277 // Adjust wallpaper before we pull the lower/upper target, since pending changes
278 // (like the clearAnimatingFlags() above) might affect wallpaper target result.
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700279 // Or, the opening app window should be a wallpaper target.
280 mWallpaperControllerLocked.adjustWallpaperWindowsForAppTransitionIfNeeded(displayContent,
Wale Ogunwale0303c572016-10-20 10:16:29 -0700281 mService.mOpeningApps);
Chong Zhangec8299c2016-07-29 13:09:40 -0700282
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800283 final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700284 boolean openingAppHasWallpaper = false;
285 boolean closingAppHasWallpaper = false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700286
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700287 // Do a first pass through the tokens for two things:
288 // (1) Determine if both the closing and opening app token sets are wallpaper targets, in
289 // which case special animations are needed (since the wallpaper needs to stay static behind
290 // them).
291 // (2) Find the layout params of the top-most application window in the tokens, which is
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700292 // what will control the animation theme.
293 final int closingAppsCount = mService.mClosingApps.size();
294 appsCount = closingAppsCount + mService.mOpeningApps.size();
295 for (i = 0; i < appsCount; i++) {
296 final AppWindowToken wtoken;
297 if (i < closingAppsCount) {
298 wtoken = mService.mClosingApps.valueAt(i);
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800299 if (wallpaperTarget != null && wtoken.windowsCanBeWallpaperTarget()) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700300 closingAppHasWallpaper = true;
301 }
302 } else {
303 wtoken = mService.mOpeningApps.valueAt(i - closingAppsCount);
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800304 if (wallpaperTarget != null && wtoken.windowsCanBeWallpaperTarget()) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700305 openingAppHasWallpaper = true;
306 }
307 }
308
Wale Ogunwale72919d22016-12-08 18:58:50 -0800309 voiceInteraction |= wtoken.mVoiceInteraction;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700310
Wale Ogunwale51362492016-09-08 17:49:17 -0700311 if (wtoken.fillsParent()) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800312 final WindowState ws = wtoken.findMainWindow();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700313 if (ws != null) {
314 animLp = ws.mAttrs;
315 bestAnimLayer = ws.mLayer;
316 fullscreenAnim = true;
317 }
318 } else if (!fullscreenAnim) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800319 final WindowState ws = wtoken.findMainWindow();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700320 if (ws != null) {
321 if (ws.mLayer > bestAnimLayer) {
322 animLp = ws.mAttrs;
323 bestAnimLayer = ws.mLayer;
324 }
325 }
326 }
327 }
328
329 transit = maybeUpdateTransitToWallpaper(transit, openingAppHasWallpaper,
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800330 closingAppHasWallpaper);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700331
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700332 // If all closing windows are obscured, then there is no need to do an animation. This is
333 // the case, for example, when this transition is being done behind the lock screen.
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700334 if (!mService.mPolicy.allowAppAnimationsLw()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800335 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700336 "Animations disallowed by keyguard or dream.");
337 animLp = null;
338 }
339
340 processApplicationsAnimatingInPlace(transit);
341
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800342 mTmpLayerAndToken.token = null;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800343 handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
344 final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
345 final int topClosingLayer = mTmpLayerAndToken.layer;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700346
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800347 final AppWindowToken topOpeningApp = handleOpeningApps(transit,
348 animLp, voiceInteraction, topClosingLayer);
349
Chong Zhang1c93f6d2016-07-27 17:52:45 -0700350 mService.mAppTransition.setLastAppTransition(transit, topOpeningApp, topClosingApp);
351
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800352 final AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ? null :
353 topOpeningApp.mAppAnimator;
354 final AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
355 topClosingApp.mAppAnimator;
356
Jorim Jaggife762342016-10-13 14:33:27 +0200357 final int flags = mService.mAppTransition.getTransitFlags();
358 int layoutRedo = mService.mAppTransition.goodToGo(transit, openingAppAnimator,
359 closingAppAnimator, mService.mOpeningApps, mService.mClosingApps);
360 handleNonAppWindowsInTransition(transit, flags);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800361 mService.mAppTransition.postAnimationCallback();
362 mService.mAppTransition.clear();
363
Jorim Jaggi02886a82016-12-06 09:10:06 -0800364 mService.mTaskSnapshotController.onTransitionStarting();
365
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800366 mService.mOpeningApps.clear();
367 mService.mClosingApps.clear();
Jorim Jaggi5a108c22016-10-13 14:33:27 +0200368 mService.mUnknownAppVisibilityController.clear();
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800369
370 // This has changed the visibility of windows, so perform
371 // a new layout to get them all up-to-date.
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700372 displayContent.setLayoutNeeded();
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800373
374 // TODO(multidisplay): IMEs are only supported on the default display.
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -0700375 final DisplayContent dc = mService.getDefaultDisplayContentLocked();
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000376 dc.computeImeTarget(true /* updateImeTarget */);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800377 mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
378 true /*updateInputWindows*/);
379 mService.mFocusMayChange = false;
Chong Zhang8784be62016-06-28 15:25:07 -0700380
Jorim Jaggidbaad382017-07-18 13:22:52 +0200381 mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING,
382 mTempTransitionReasons.clone()).sendToTarget();
383
Chong Zhang8784be62016-06-28 15:25:07 -0700384 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
385
Jorim Jaggife762342016-10-13 14:33:27 +0200386 return layoutRedo | FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800387 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700388
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800389 private AppWindowToken handleOpeningApps(int transit, LayoutParams animLp,
390 boolean voiceInteraction, int topClosingLayer) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700391 AppWindowToken topOpeningApp = null;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800392 final int appsCount = mService.mOpeningApps.size();
393 for (int i = 0; i < appsCount; i++) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700394 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
395 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800396 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700397
398 if (!appAnimator.usingTransferredAnimation) {
399 appAnimator.clearThumbnail();
Chong Zhang65d15d02016-03-14 13:59:32 -0700400 appAnimator.setNullAnimation();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700401 }
Chong Zhangeb22e8e2016-01-20 19:52:22 -0800402
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700403 if (!wtoken.setVisibility(animLp, true, transit, false, voiceInteraction)){
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700404 // This token isn't going to be animating. Add it to the list of tokens to
405 // be notified of app transition complete since the notification will not be
406 // sent be the app window animator.
407 mService.mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
408 }
409 wtoken.updateReportedVisibilityLocked();
410 wtoken.waitingToShow = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700411 wtoken.setAllAppWinAnimators();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700412
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800413 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -0700414 ">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
Robert Carr68e5c9e2016-09-14 10:50:09 -0700415 mService.openSurfaceTransaction();
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -0700416 try {
Wale Ogunwale69cf50f2015-11-13 11:08:36 -0800417 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -0700418 } finally {
Robert Carr68e5c9e2016-09-14 10:50:09 -0700419 mService.closeSurfaceTransaction();
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800420 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -0700421 "<<< CLOSE TRANSACTION handleAppTransitionReadyLocked()");
422 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700423 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
424
425 int topOpeningLayer = 0;
426 if (animLp != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700427 final int layer = wtoken.getHighestAnimLayer();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700428 if (topOpeningApp == null || layer > topOpeningLayer) {
429 topOpeningApp = wtoken;
430 topOpeningLayer = layer;
431 }
432 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800433 if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) {
434 createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
435 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700436 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800437 return topOpeningApp;
438 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700439
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800440 private void handleClosingApps(int transit, LayoutParams animLp, boolean voiceInteraction,
441 LayerAndToken layerAndToken) {
442 final int appsCount;
443 appsCount = mService.mClosingApps.size();
444 for (int i = 0; i < appsCount; i++) {
445 AppWindowToken wtoken = mService.mClosingApps.valueAt(i);
Chong Zhangf58631a2016-05-24 16:02:10 -0700446
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800447 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800448 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800449 appAnimator.clearThumbnail();
Chong Zhang65d15d02016-03-14 13:59:32 -0700450 appAnimator.setNullAnimation();
Winson Chung87e5d552017-04-05 11:49:38 -0700451 // TODO: Do we need to add to mNoAnimationNotifyOnTransitionFinished like above if not
452 // animating?
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700453 wtoken.setVisibility(animLp, false, transit, false, voiceInteraction);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800454 wtoken.updateReportedVisibilityLocked();
455 // Force the allDrawn flag, because we want to start
456 // this guy's animations regardless of whether it's
457 // gotten drawn.
458 wtoken.allDrawn = true;
459 wtoken.deferClearAllDrawn = false;
460 // Ensure that apps that are mid-starting are also scheduled to have their
461 // starting windows removed after the animation is complete
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800462 if (wtoken.startingWindow != null && !wtoken.startingWindow.mAnimatingExit
463 && wtoken.getController() != null) {
464 wtoken.getController().removeStartingWindow();
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800465 }
466 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700467
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800468 if (animLp != null) {
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700469 int layer = wtoken.getHighestAnimLayer();
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800470 if (layerAndToken.token == null || layer > layerAndToken.layer) {
471 layerAndToken.token = wtoken;
472 layerAndToken.layer = layer;
473 }
474 }
475 if (mService.mAppTransition.isNextAppTransitionThumbnailDown()) {
476 createThumbnailAppAnimator(transit, wtoken, 0, layerAndToken.layer);
477 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700478 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700479 }
480
Jorim Jaggife762342016-10-13 14:33:27 +0200481 private void handleNonAppWindowsInTransition(int transit, int flags) {
482 if (transit == TRANSIT_KEYGUARD_GOING_AWAY) {
483 if ((flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0
484 && (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION) == 0) {
485 Animation anim = mService.mPolicy.createKeyguardWallpaperExit(
486 (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0);
487 if (anim != null) {
488 mService.getDefaultDisplayContentLocked().mWallpaperController
489 .startWallpaperAnimation(anim);
490 }
491 }
492 }
493 if (transit == TRANSIT_KEYGUARD_GOING_AWAY
494 || transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER) {
495 mService.getDefaultDisplayContentLocked().startKeyguardExitOnNonAppWindows(
496 transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER,
497 (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0);
498 }
499 }
500
Jorim Jaggidbaad382017-07-18 13:22:52 +0200501 private boolean transitionGoodToGo(int appsCount, SparseIntArray outReasons) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800502 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700503 "Checking " + appsCount + " opening apps (frozen="
504 + mService.mDisplayFrozen + " timeout="
505 + mService.mAppTransition.isTimeout() + ")...");
Robert Carr42769ff2016-09-20 13:36:42 -0700506 final ScreenRotationAnimation screenRotationAnimation =
507 mService.mAnimator.getScreenRotationAnimationLocked(
508 Display.DEFAULT_DISPLAY);
509
Jorim Jaggidbaad382017-07-18 13:22:52 +0200510 outReasons.clear();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700511 if (!mService.mAppTransition.isTimeout()) {
Robert Carr42769ff2016-09-20 13:36:42 -0700512 // Imagine the case where we are changing orientation due to an app transition, but a previous
513 // orientation change is still in progress. We won't process the orientation change
514 // for our transition because we need to wait for the rotation animation to finish.
515 // If we start the app transition at this point, we will interrupt it halfway with a new rotation
516 // animation after the old one finally finishes. It's better to defer the
517 // app transition.
518 if (screenRotationAnimation != null && screenRotationAnimation.isAnimating() &&
519 mService.rotationNeedsUpdateLocked()) {
520 if (DEBUG_APP_TRANSITIONS) {
521 Slog.v(TAG, "Delaying app transition for screen rotation animation to finish");
522 }
523 return false;
524 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700525 for (int i = 0; i < appsCount; i++) {
526 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800527 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700528 "Check opening app=" + wtoken + ": allDrawn="
529 + wtoken.allDrawn + " startingDisplayed="
530 + wtoken.startingDisplayed + " startingMoved="
Chong Zhangd78ddb42016-03-02 17:01:14 -0800531 + wtoken.startingMoved + " isRelaunching()="
532 + wtoken.isRelaunching());
533
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800534
Jorim Jaggi02886a82016-12-06 09:10:06 -0800535 final boolean allDrawn = wtoken.allDrawn && !wtoken.isRelaunching();
536 if (!allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700537 return false;
538 }
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800539 final TaskStack stack = wtoken.getStack();
540 final int stackId = stack != null ? stack.mStackId : INVALID_STACK_ID;
Jorim Jaggi02886a82016-12-06 09:10:06 -0800541 if (allDrawn) {
Jorim Jaggie7d2b852017-08-28 17:55:15 +0200542 outReasons.put(stackId, APP_TRANSITION_WINDOWS_DRAWN);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500543 } else {
Jorim Jaggidbaad382017-07-18 13:22:52 +0200544 outReasons.put(stackId, wtoken.startingData instanceof SplashScreenStartingData
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800545 ? APP_TRANSITION_SPLASH_SCREEN
546 : APP_TRANSITION_SNAPSHOT);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500547 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700548 }
549
Jorim Jaggi2f7d2922015-10-29 13:08:29 +0100550 // We also need to wait for the specs to be fetched, if needed.
551 if (mService.mAppTransition.isFetchingAppTransitionsSpecs()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800552 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "isFetchingAppTransitionSpecs=true");
Jorim Jaggi2f7d2922015-10-29 13:08:29 +0100553 return false;
554 }
555
Jorim Jaggi5a108c22016-10-13 14:33:27 +0200556 if (!mService.mUnknownAppVisibilityController.allResolved()) {
557 if (DEBUG_APP_TRANSITIONS) {
558 Slog.v(TAG, "unknownApps is not empty: "
559 + mService.mUnknownAppVisibilityController.getDebugMessage());
560 }
561 return false;
562 }
563
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700564 // If the wallpaper is visible, we need to check it's ready too.
Jorim Jaggi275561a2016-02-23 10:11:02 -0500565 boolean wallpaperReady = !mWallpaperControllerLocked.isWallpaperVisible() ||
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700566 mWallpaperControllerLocked.wallpaperTransitionReady();
Jorim Jaggi275561a2016-02-23 10:11:02 -0500567 if (wallpaperReady) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500568 return true;
569 }
570 return false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700571 }
572 return true;
573 }
574
575 private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800576 boolean closingAppHasWallpaper) {
Matthew Ng26a1cec2017-05-18 14:42:51 -0700577 // Given no app transition pass it through instead of a wallpaper transition
578 if (transit == TRANSIT_NONE) {
579 return TRANSIT_NONE;
580 }
581
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700582 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
583 final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700584 final WindowState oldWallpaper = mWallpaperControllerLocked.isWallpaperTargetAnimating()
585 ? null : wallpaperTarget;
Filip Gruszczynski49b80af2015-09-24 09:04:26 -0700586 final ArraySet<AppWindowToken> openingApps = mService.mOpeningApps;
587 final ArraySet<AppWindowToken> closingApps = mService.mClosingApps;
Jorim Jaggife762342016-10-13 14:33:27 +0200588 boolean openingCanBeWallpaperTarget = canBeWallpaperTarget(openingApps);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800589 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700590 "New wallpaper target=" + wallpaperTarget
591 + ", oldWallpaper=" + oldWallpaper
Filip Gruszczynski49b80af2015-09-24 09:04:26 -0700592 + ", openingApps=" + openingApps
593 + ", closingApps=" + closingApps);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700594 mService.mAnimateWallpaperWithTarget = false;
Jorim Jaggia69243a2017-06-15 15:10:38 -0400595 if (openingCanBeWallpaperTarget && transit == TRANSIT_KEYGUARD_GOING_AWAY) {
Jorim Jaggife762342016-10-13 14:33:27 +0200596 transit = TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
597 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
598 "New transit: " + AppTransition.appTransitionToString(transit));
Jorim Jaggia69243a2017-06-15 15:10:38 -0400599 }
600 // We never want to change from a Keyguard transit to a non-Keyguard transit, as our logic
601 // relies on the fact that we always execute a Keyguard transition after preparing one.
602 else if (!isKeyguardGoingAwayTransit(transit)) {
603 if (closingAppHasWallpaper && openingAppHasWallpaper) {
604 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Wallpaper animation!");
605 switch (transit) {
606 case TRANSIT_ACTIVITY_OPEN:
607 case TRANSIT_TASK_OPEN:
608 case TRANSIT_TASK_TO_FRONT:
609 transit = TRANSIT_WALLPAPER_INTRA_OPEN;
610 break;
611 case TRANSIT_ACTIVITY_CLOSE:
612 case TRANSIT_TASK_CLOSE:
613 case TRANSIT_TASK_TO_BACK:
614 transit = TRANSIT_WALLPAPER_INTRA_CLOSE;
615 break;
616 }
617 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
618 "New transit: " + AppTransition.appTransitionToString(transit));
619 } else if (oldWallpaper != null && !mService.mOpeningApps.isEmpty()
620 && !openingApps.contains(oldWallpaper.mAppToken)
621 && closingApps.contains(oldWallpaper.mAppToken)) {
622 // We are transitioning from an activity with a wallpaper to one without.
623 transit = TRANSIT_WALLPAPER_CLOSE;
624 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New transit away from wallpaper: "
625 + AppTransition.appTransitionToString(transit));
626 } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw() &&
627 openingApps.contains(wallpaperTarget.mAppToken)) {
628 // We are transitioning from an activity without
629 // a wallpaper to now showing the wallpaper
630 transit = TRANSIT_WALLPAPER_OPEN;
631 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New transit into wallpaper: "
632 + AppTransition.appTransitionToString(transit));
633 } else {
634 mService.mAnimateWallpaperWithTarget = true;
635 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700636 }
637 return transit;
638 }
639
Jorim Jaggife762342016-10-13 14:33:27 +0200640 private boolean canBeWallpaperTarget(ArraySet<AppWindowToken> apps) {
641 for (int i = apps.size() - 1; i >= 0; i--) {
642 if (apps.valueAt(i).windowsCanBeWallpaperTarget()) {
643 return true;
644 }
645 }
646 return false;
647 }
648
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700649 private void processApplicationsAnimatingInPlace(int transit) {
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700650 if (transit == TRANSIT_TASK_IN_PLACE) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700651 // Find the focused window
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -0700652 final WindowState win = mService.getDefaultDisplayContentLocked().findFocusedWindow();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700653 if (win != null) {
654 final AppWindowToken wtoken = win.mAppToken;
655 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
656 if (DEBUG_APP_TRANSITIONS)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800657 Slog.v(TAG, "Now animating app in place " + wtoken);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700658 appAnimator.clearThumbnail();
Chong Zhang65d15d02016-03-14 13:59:32 -0700659 appAnimator.setNullAnimation();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700660 mService.updateTokenInPlaceLocked(wtoken, transit);
661 wtoken.updateReportedVisibilityLocked();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700662 wtoken.setAllAppWinAnimators();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700663 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
Wale Ogunwale69cf50f2015-11-13 11:08:36 -0800664 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700665 }
666 }
667 }
668
669 private void createThumbnailAppAnimator(int transit, AppWindowToken appToken,
670 int openingLayer, int closingLayer) {
671 AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
672 if (openingAppAnimator == null || openingAppAnimator.animation == null) {
673 return;
674 }
Bryce Lee6d410262017-02-28 15:30:17 -0800675 final int taskId = appToken.getTask().mTaskId;
Winson Chungaa7fa012017-05-24 15:50:06 -0700676 final GraphicBuffer thumbnailHeader =
677 mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
678 if (thumbnailHeader == null) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800679 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700680 return;
681 }
682 // This thumbnail animation is very special, we need to have
683 // an extra surface with the thumbnail included with the animation.
684 Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
685 try {
686 // TODO(multi-display): support other displays
687 final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
688 final Display display = displayContent.getDisplay();
689 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
690
691 // Create a new surface for the thumbnail
Albert Chaulke4338f82017-04-19 15:54:08 -0400692 WindowState window = appToken.findMainWindow();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700693 SurfaceControl surfaceControl = new SurfaceControl(mService.mFxSession,
694 "thumbnail anim", dirty.width(), dirty.height(),
Albert Chaulke4338f82017-04-19 15:54:08 -0400695 PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN,
Bryce Leee6c25d42017-05-31 10:27:42 -0700696 appToken.windowType,
697 window != null ? window.mOwnerUid : Binder.getCallingUid());
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700698 surfaceControl.setLayerStack(display.getLayerStack());
699 if (SHOW_TRANSACTIONS) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800700 Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700701 }
702
Winson Chungaa7fa012017-05-24 15:50:06 -0700703 // Transfer the thumbnail to the surface
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700704 Surface drawSurface = new Surface();
705 drawSurface.copyFrom(surfaceControl);
Winson Chungaa7fa012017-05-24 15:50:06 -0700706 drawSurface.attachAndQueueBuffer(thumbnailHeader);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700707 drawSurface.release();
708
709 // Get the thumbnail animation
710 Animation anim;
711 if (mService.mAppTransition.isNextThumbnailTransitionAspectScaled()) {
712 // If this is a multi-window scenario, we use the windows frame as
713 // destination of the thumbnail header animation. If this is a full screen
714 // window scenario, we use the whole display as the target.
715 WindowState win = appToken.findMainWindow();
716 Rect appRect = win != null ? win.getContentFrameLw() :
717 new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
Jorim Jaggide63d442016-03-14 14:56:56 +0100718 Rect insets = win != null ? win.mContentInsets : null;
Andrii Kulian441e4492016-09-29 15:25:00 -0700719 final Configuration displayConfig = displayContent.getConfiguration();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700720 // For the new aspect-scaled transition, we want it to always show
721 // above the animating opening/closing window, and we want to
722 // synchronize its thumbnail surface with the surface for the
723 // open/close animation (only on the way down)
724 anim = mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
Andrii Kulian441e4492016-09-29 15:25:00 -0700725 insets, thumbnailHeader, taskId, displayConfig.uiMode,
726 displayConfig.orientation);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700727 openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
728 openingAppAnimator.deferThumbnailDestruction =
729 !mService.mAppTransition.isNextThumbnailTransitionScaleUp();
730 } else {
731 anim = mService.mAppTransition.createThumbnailScaleAnimationLocked(
732 displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
733 }
734 anim.restrictDuration(MAX_ANIMATION_DURATION);
735 anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
736
737 openingAppAnimator.thumbnail = surfaceControl;
738 openingAppAnimator.thumbnailLayer = openingLayer;
739 openingAppAnimator.thumbnailAnimation = anim;
740 mService.mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700741 } catch (Surface.OutOfResourcesException e) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800742 Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700743 + dirty.width() + " h=" + dirty.height(), e);
744 openingAppAnimator.clearThumbnail();
745 }
746 }
747
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700748 void requestTraversal() {
749 if (!mTraversalScheduled) {
750 mTraversalScheduled = true;
Jorim Jaggied7993b2017-03-28 18:50:01 +0100751 mService.mAnimationHandler.post(mPerformSurfacePlacement);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700752 }
753 }
754
Jorim Jaggi3dac63a2016-03-01 12:37:07 +0100755 /**
756 * Puts the {@param surface} into a pending list to be destroyed after the current transaction
757 * has been committed.
758 */
759 void destroyAfterTransaction(SurfaceControl surface) {
760 mPendingDestroyingSurfaces.add(surface);
761 }
762
763 /**
764 * Destroys any surfaces that have been put into the pending list with
765 * {@link #destroyAfterTransaction}.
766 */
767 void destroyPendingSurfaces() {
768 for (int i = mPendingDestroyingSurfaces.size() - 1; i >= 0; i--) {
769 mPendingDestroyingSurfaces.get(i).destroy();
770 }
771 mPendingDestroyingSurfaces.clear();
772 }
773
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700774 public void dump(PrintWriter pw, String prefix) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700775 pw.println(prefix + "mTraversalScheduled=" + mTraversalScheduled);
776 pw.println(prefix + "mHoldScreenWindow=" + mService.mRoot.mHoldScreenWindow);
Wale Ogunwaled4a00a02016-10-10 11:29:17 -0700777 pw.println(prefix + "mObscuringWindow=" + mService.mRoot.mObscuringWindow);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700778 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700779}