blob: 82c862f6a6a8251ace5b52febc1aa809421547c3 [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 Jaggi275561a2016-02-23 10:11:02 -05005import static android.app.ActivityManagerInternal.APP_TRANSITION_SAVED_SURFACE;
Jorim Jaggi3878ca32017-02-02 17:13:05 -08006import static android.app.ActivityManagerInternal.APP_TRANSITION_SNAPSHOT;
7import static android.app.ActivityManagerInternal.APP_TRANSITION_SPLASH_SCREEN;
Jorim Jaggi275561a2016-02-23 10:11:02 -05008import static android.app.ActivityManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07009import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
10import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -070011import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_CLOSE;
12import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
Jorim Jaggife762342016-10-13 14:33:27 +020013import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
14import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
15import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
16import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_GOING_AWAY;
17import static com.android.server.wm.AppTransition.TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
Matthew Ng26a1cec2017-05-18 14:42:51 -070018import static com.android.server.wm.AppTransition.TRANSIT_NONE;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -070019import static com.android.server.wm.AppTransition.TRANSIT_TASK_CLOSE;
20import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
21import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
22import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_BACK;
23import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
24import static com.android.server.wm.AppTransition.TRANSIT_WALLPAPER_CLOSE;
25import static com.android.server.wm.AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
26import static com.android.server.wm.AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
27import static com.android.server.wm.AppTransition.TRANSIT_WALLPAPER_OPEN;
Jorim Jaggia69243a2017-06-15 15:10:38 -040028import static com.android.server.wm.AppTransition.isKeyguardGoingAwayTransit;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080029import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080030import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080031import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
32import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
Jorim Jaggi192086e2016-03-11 17:17:03 +010033import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080034import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Jorim Jaggi192086e2016-03-11 17:17:03 +010035import static com.android.server.wm.WindowManagerService.H.NOTIFY_APP_TRANSITION_STARTING;
Jorim Jaggi192086e2016-03-11 17:17:03 +010036import static com.android.server.wm.WindowManagerService.H.REPORT_WINDOWS_CHANGE;
Jorim Jaggi192086e2016-03-11 17:17:03 +010037import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
38import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070039import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070040
Andrii Kulian441e4492016-09-29 15:25:00 -070041import android.content.res.Configuration;
Winson Chungaa7fa012017-05-24 15:50:06 -070042import android.graphics.GraphicBuffer;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070043import android.graphics.PixelFormat;
44import android.graphics.Rect;
Bryce Leee6c25d42017-05-31 10:27:42 -070045import android.os.Binder;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070046import android.os.Debug;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070047import android.os.Trace;
Filip Gruszczynski49b80af2015-09-24 09:04:26 -070048import android.util.ArraySet;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070049import android.util.Slog;
Jorim Jaggi3878ca32017-02-02 17:13:05 -080050import android.util.SparseIntArray;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070051import android.view.Display;
52import android.view.DisplayInfo;
53import android.view.Surface;
54import android.view.SurfaceControl;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -080055import android.view.WindowManager.LayoutParams;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070056import android.view.animation.Animation;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070057
Jorim Jaggid75962e2016-05-03 15:10:03 -070058import com.android.server.wm.WindowManagerService.H;
59
Filip Gruszczynski24966d42015-09-05 15:00:00 -070060import java.io.PrintWriter;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070061import java.util.ArrayList;
62
63/**
64 * Positions windows and their surfaces.
65 *
66 * It sets positions of windows by calculating their frames and then applies this by positioning
67 * surfaces according to these frames. Z layer is still assigned withing WindowManagerService.
68 */
69class WindowSurfacePlacer {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -080070 private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowSurfacePlacer" : TAG_WM;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070071 private final WindowManagerService mService;
72 private final WallpaperController mWallpaperControllerLocked;
73
74 private boolean mInLayout = false;
75
76 /** Only do a maximum of 6 repeated layouts. After that quit */
77 private int mLayoutRepeatCount;
78
79 static final int SET_UPDATE_ROTATION = 1 << 0;
80 static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1;
81 static final int SET_FORCE_HIDING_CHANGED = 1 << 2;
82 static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3;
83 static final int SET_TURN_ON_SCREEN = 1 << 4;
84 static final int SET_WALLPAPER_ACTION_PENDING = 1 << 5;
85
Filip Gruszczynski4501d232015-09-02 13:00:02 -070086 private final Rect mTmpStartRect = new Rect();
Wale Ogunwaleb4ec0a32015-12-14 10:31:43 -080087 private final Rect mTmpContentRect = new Rect();
Filip Gruszczynski4501d232015-09-02 13:00:02 -070088
Filip Gruszczynski24966d42015-09-05 15:00:00 -070089 private boolean mTraversalScheduled;
Jorim Jaggic4025202015-10-22 16:43:34 +020090 private int mDeferDepth = 0;
Filip Gruszczynski24966d42015-09-05 15:00:00 -070091
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -080092 private static final class LayerAndToken {
93 public int layer;
94 public AppWindowToken token;
95 }
96 private final LayerAndToken mTmpLayerAndToken = new LayerAndToken();
97
Jorim Jaggi3dac63a2016-03-01 12:37:07 +010098 private final ArrayList<SurfaceControl> mPendingDestroyingSurfaces = new ArrayList<>();
Jorim Jaggi3878ca32017-02-02 17:13:05 -080099 private final SparseIntArray mTempTransitionReasons = new SparseIntArray();
Jorim Jaggi3dac63a2016-03-01 12:37:07 +0100100
Jorim Jaggied7993b2017-03-28 18:50:01 +0100101 private final Runnable mPerformSurfacePlacement;
102
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700103 public WindowSurfacePlacer(WindowManagerService service) {
104 mService = service;
Wale Ogunwale0303c572016-10-20 10:16:29 -0700105 mWallpaperControllerLocked = mService.mRoot.mWallpaperController;
Jorim Jaggied7993b2017-03-28 18:50:01 +0100106 mPerformSurfacePlacement = () -> {
107 synchronized (mService.mWindowMap) {
108 performSurfacePlacement();
109 }
110 };
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700111 }
112
Jorim Jaggic4025202015-10-22 16:43:34 +0200113 /**
114 * See {@link WindowManagerService#deferSurfaceLayout()}
115 */
116 void deferLayout() {
117 mDeferDepth++;
118 }
119
120 /**
121 * See {@link WindowManagerService#continueSurfaceLayout()}
122 */
123 void continueLayout() {
124 mDeferDepth--;
125 if (mDeferDepth <= 0) {
126 performSurfacePlacement();
127 }
128 }
129
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700130 final void performSurfacePlacement() {
Jorim Jaggi02886a82016-12-06 09:10:06 -0800131 performSurfacePlacement(false /* force */);
132 }
133
134 final void performSurfacePlacement(boolean force) {
135 if (mDeferDepth > 0 && !force) {
Jorim Jaggic4025202015-10-22 16:43:34 +0200136 return;
137 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700138 int loopCount = 6;
139 do {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700140 mTraversalScheduled = false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700141 performSurfacePlacementLoop();
Jorim Jaggied7993b2017-03-28 18:50:01 +0100142 mService.mAnimationHandler.removeCallbacks(mPerformSurfacePlacement);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700143 loopCount--;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700144 } while (mTraversalScheduled && loopCount > 0);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700145 mService.mRoot.mWallpaperActionPending = false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700146 }
147
148 private void performSurfacePlacementLoop() {
149 if (mInLayout) {
150 if (DEBUG) {
151 throw new RuntimeException("Recursive call!");
152 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800153 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700154 + Debug.getCallers(3));
155 return;
156 }
157
158 if (mService.mWaitingForConfig) {
159 // Our configuration has changed (most likely rotation), but we
160 // don't yet have the complete configuration to report to
161 // applications. Don't do any window layout until we have it.
162 return;
163 }
164
165 if (!mService.mDisplayReady) {
166 // Not yet initialized, nothing to do.
167 return;
168 }
169
170 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
171 mInLayout = true;
172
173 boolean recoveringMemory = false;
174 if (!mService.mForceRemoves.isEmpty()) {
175 recoveringMemory = true;
176 // Wait a little bit for things to settle down, and off we go.
177 while (!mService.mForceRemoves.isEmpty()) {
Wale Ogunwaleadde52e2016-07-16 13:11:55 -0700178 final WindowState ws = mService.mForceRemoves.remove(0);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800179 Slog.i(TAG, "Force removing: " + ws);
Wale Ogunwale571771c2016-08-26 13:18:50 -0700180 ws.removeImmediately();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700181 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800182 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700183 Object tmp = new Object();
184 synchronized (tmp) {
185 try {
186 tmp.wait(250);
187 } catch (InterruptedException e) {
188 }
189 }
190 }
191
192 try {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700193 mService.mRoot.performSurfacePlacement(recoveringMemory);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700194
195 mInLayout = false;
196
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700197 if (mService.mRoot.isLayoutNeeded()) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700198 if (++mLayoutRepeatCount < 6) {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700199 requestTraversal();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700200 } else {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800201 Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700202 mLayoutRepeatCount = 0;
203 }
204 } else {
205 mLayoutRepeatCount = 0;
206 }
207
208 if (mService.mWindowsChanged && !mService.mWindowChangeListeners.isEmpty()) {
209 mService.mH.removeMessages(REPORT_WINDOWS_CHANGE);
210 mService.mH.sendEmptyMessage(REPORT_WINDOWS_CHANGE);
211 }
212 } catch (RuntimeException e) {
213 mInLayout = false;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800214 Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700215 }
216
217 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
218 }
219
220 void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
221 if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800222 Slog.v(TAG, "Layouts looping: " + msg +
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700223 ", mPendingLayoutChanges = 0x" + Integer.toHexString(pendingLayoutChanges));
224 }
225 }
226
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700227 boolean isInLayout() {
228 return mInLayout;
229 }
230
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700231 /**
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700232 * @return bitmap indicating if another pass through layout must be made.
233 */
Wale Ogunwale0303c572016-10-20 10:16:29 -0700234 int handleAppTransitionReadyLocked() {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700235 int appsCount = mService.mOpeningApps.size();
236 if (!transitionGoodToGo(appsCount)) {
237 return 0;
238 }
Chong Zhang8784be62016-06-28 15:25:07 -0700239 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "AppTransitionReady");
240
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800241 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700242 int transit = mService.mAppTransition.getAppTransition();
Jorim Jaggia69243a2017-06-15 15:10:38 -0400243 if (mService.mSkipAppTransitionAnimation && !isKeyguardGoingAwayTransit(transit)) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700244 transit = AppTransition.TRANSIT_UNSET;
245 }
246 mService.mSkipAppTransitionAnimation = false;
247 mService.mNoAnimationNotifyOnTransitionFinished.clear();
248
Jorim Jaggid75962e2016-05-03 15:10:03 -0700249 mService.mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700250
Wale Ogunwale9adfe572016-09-08 20:43:58 -0700251 final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000252 // TODO: Don't believe this is really needed...
253 //mService.mWindowsChanged = true;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700254
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700255 mService.mRoot.mWallpaperMayChange = false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700256
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700257 // The top-most window will supply the layout params, and we will determine it below.
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800258 LayoutParams animLp = null;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700259 int bestAnimLayer = -1;
260 boolean fullscreenAnim = false;
261 boolean voiceInteraction = false;
262
Chong Zhangec8299c2016-07-29 13:09:40 -0700263 int i;
264 for (i = 0; i < appsCount; i++) {
265 final AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700266 // Clearing the mAnimatingExit flag before entering animation. It's set to true if app
267 // window is removed, or window relayout to invisible. This also affects window
268 // visibility. We need to clear it *before* maybeUpdateTransitToWallpaper() as the
269 // transition selection depends on wallpaper target visibility.
Chong Zhangec8299c2016-07-29 13:09:40 -0700270 wtoken.clearAnimatingFlags();
271
272 }
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700273
Chong Zhangec8299c2016-07-29 13:09:40 -0700274 // Adjust wallpaper before we pull the lower/upper target, since pending changes
275 // (like the clearAnimatingFlags() above) might affect wallpaper target result.
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700276 // Or, the opening app window should be a wallpaper target.
277 mWallpaperControllerLocked.adjustWallpaperWindowsForAppTransitionIfNeeded(displayContent,
Wale Ogunwale0303c572016-10-20 10:16:29 -0700278 mService.mOpeningApps);
Chong Zhangec8299c2016-07-29 13:09:40 -0700279
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800280 final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700281 boolean openingAppHasWallpaper = false;
282 boolean closingAppHasWallpaper = false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700283
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700284 // Do a first pass through the tokens for two things:
285 // (1) Determine if both the closing and opening app token sets are wallpaper targets, in
286 // which case special animations are needed (since the wallpaper needs to stay static behind
287 // them).
288 // (2) Find the layout params of the top-most application window in the tokens, which is
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700289 // what will control the animation theme.
290 final int closingAppsCount = mService.mClosingApps.size();
291 appsCount = closingAppsCount + mService.mOpeningApps.size();
292 for (i = 0; i < appsCount; i++) {
293 final AppWindowToken wtoken;
294 if (i < closingAppsCount) {
295 wtoken = mService.mClosingApps.valueAt(i);
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800296 if (wallpaperTarget != null && wtoken.windowsCanBeWallpaperTarget()) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700297 closingAppHasWallpaper = true;
298 }
299 } else {
300 wtoken = mService.mOpeningApps.valueAt(i - closingAppsCount);
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800301 if (wallpaperTarget != null && wtoken.windowsCanBeWallpaperTarget()) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700302 openingAppHasWallpaper = true;
303 }
304 }
305
Wale Ogunwale72919d22016-12-08 18:58:50 -0800306 voiceInteraction |= wtoken.mVoiceInteraction;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700307
Wale Ogunwale51362492016-09-08 17:49:17 -0700308 if (wtoken.fillsParent()) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800309 final WindowState ws = wtoken.findMainWindow();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700310 if (ws != null) {
311 animLp = ws.mAttrs;
312 bestAnimLayer = ws.mLayer;
313 fullscreenAnim = true;
314 }
315 } else if (!fullscreenAnim) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800316 final WindowState ws = wtoken.findMainWindow();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700317 if (ws != null) {
318 if (ws.mLayer > bestAnimLayer) {
319 animLp = ws.mAttrs;
320 bestAnimLayer = ws.mLayer;
321 }
322 }
323 }
324 }
325
326 transit = maybeUpdateTransitToWallpaper(transit, openingAppHasWallpaper,
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800327 closingAppHasWallpaper);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700328
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700329 // If all closing windows are obscured, then there is no need to do an animation. This is
330 // the case, for example, when this transition is being done behind the lock screen.
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700331 if (!mService.mPolicy.allowAppAnimationsLw()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800332 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700333 "Animations disallowed by keyguard or dream.");
334 animLp = null;
335 }
336
337 processApplicationsAnimatingInPlace(transit);
338
Jorim Jaggi42625d1b2016-02-11 20:11:07 -0800339 mTmpLayerAndToken.token = null;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800340 handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
341 final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
342 final int topClosingLayer = mTmpLayerAndToken.layer;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700343
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800344 final AppWindowToken topOpeningApp = handleOpeningApps(transit,
345 animLp, voiceInteraction, topClosingLayer);
346
Chong Zhang1c93f6d2016-07-27 17:52:45 -0700347 mService.mAppTransition.setLastAppTransition(transit, topOpeningApp, topClosingApp);
348
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800349 final AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ? null :
350 topOpeningApp.mAppAnimator;
351 final AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
352 topClosingApp.mAppAnimator;
353
Jorim Jaggife762342016-10-13 14:33:27 +0200354 final int flags = mService.mAppTransition.getTransitFlags();
355 int layoutRedo = mService.mAppTransition.goodToGo(transit, openingAppAnimator,
356 closingAppAnimator, mService.mOpeningApps, mService.mClosingApps);
357 handleNonAppWindowsInTransition(transit, flags);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800358 mService.mAppTransition.postAnimationCallback();
359 mService.mAppTransition.clear();
360
Jorim Jaggi02886a82016-12-06 09:10:06 -0800361 mService.mTaskSnapshotController.onTransitionStarting();
362
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800363 mService.mOpeningApps.clear();
364 mService.mClosingApps.clear();
Jorim Jaggi5a108c22016-10-13 14:33:27 +0200365 mService.mUnknownAppVisibilityController.clear();
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800366
367 // This has changed the visibility of windows, so perform
368 // a new layout to get them all up-to-date.
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700369 displayContent.setLayoutNeeded();
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800370
371 // TODO(multidisplay): IMEs are only supported on the default display.
Wale Ogunwaleae9adbf2016-10-18 15:17:06 -0700372 final DisplayContent dc = mService.getDefaultDisplayContentLocked();
Wale Ogunwale6213caa2016-12-02 16:47:15 +0000373 dc.computeImeTarget(true /* updateImeTarget */);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800374 mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
375 true /*updateInputWindows*/);
376 mService.mFocusMayChange = false;
Chong Zhang8784be62016-06-28 15:25:07 -0700377
378 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
379
Jorim Jaggife762342016-10-13 14:33:27 +0200380 return layoutRedo | FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800381 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700382
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800383 private AppWindowToken handleOpeningApps(int transit, LayoutParams animLp,
384 boolean voiceInteraction, int topClosingLayer) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700385 AppWindowToken topOpeningApp = null;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800386 final int appsCount = mService.mOpeningApps.size();
387 for (int i = 0; i < appsCount; i++) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700388 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
389 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800390 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700391
392 if (!appAnimator.usingTransferredAnimation) {
393 appAnimator.clearThumbnail();
Chong Zhang65d15d02016-03-14 13:59:32 -0700394 appAnimator.setNullAnimation();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700395 }
Chong Zhangeb22e8e2016-01-20 19:52:22 -0800396
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700397 if (!wtoken.setVisibility(animLp, true, transit, false, voiceInteraction)){
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700398 // This token isn't going to be animating. Add it to the list of tokens to
399 // be notified of app transition complete since the notification will not be
400 // sent be the app window animator.
401 mService.mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
402 }
403 wtoken.updateReportedVisibilityLocked();
404 wtoken.waitingToShow = false;
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700405 wtoken.setAllAppWinAnimators();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700406
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800407 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -0700408 ">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
Robert Carr68e5c9e2016-09-14 10:50:09 -0700409 mService.openSurfaceTransaction();
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -0700410 try {
Wale Ogunwale69cf50f2015-11-13 11:08:36 -0800411 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -0700412 } finally {
Robert Carr68e5c9e2016-09-14 10:50:09 -0700413 mService.closeSurfaceTransaction();
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800414 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -0700415 "<<< CLOSE TRANSACTION handleAppTransitionReadyLocked()");
416 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700417 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
418
419 int topOpeningLayer = 0;
420 if (animLp != null) {
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700421 final int layer = wtoken.getHighestAnimLayer();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700422 if (topOpeningApp == null || layer > topOpeningLayer) {
423 topOpeningApp = wtoken;
424 topOpeningLayer = layer;
425 }
426 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800427 if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) {
428 createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
429 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700430 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800431 return topOpeningApp;
432 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700433
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800434 private void handleClosingApps(int transit, LayoutParams animLp, boolean voiceInteraction,
435 LayerAndToken layerAndToken) {
436 final int appsCount;
437 appsCount = mService.mClosingApps.size();
438 for (int i = 0; i < appsCount; i++) {
439 AppWindowToken wtoken = mService.mClosingApps.valueAt(i);
Chong Zhangf58631a2016-05-24 16:02:10 -0700440
441 // If we still have some windows animating with saved surfaces that's
442 // either invisible or already removed, mark them exiting so that they
443 // are disposed of after the exit animation. These are not supposed to
444 // be shown, or are delayed removal until app is actually drawn (in which
445 // case the window will be removed after the animation).
446 wtoken.markSavedSurfaceExiting();
447
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800448 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800449 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800450 appAnimator.clearThumbnail();
Chong Zhang65d15d02016-03-14 13:59:32 -0700451 appAnimator.setNullAnimation();
Winson Chung87e5d552017-04-05 11:49:38 -0700452 // TODO: Do we need to add to mNoAnimationNotifyOnTransitionFinished like above if not
453 // animating?
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700454 wtoken.setVisibility(animLp, false, transit, false, voiceInteraction);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800455 wtoken.updateReportedVisibilityLocked();
456 // Force the allDrawn flag, because we want to start
457 // this guy's animations regardless of whether it's
458 // gotten drawn.
459 wtoken.allDrawn = true;
460 wtoken.deferClearAllDrawn = false;
461 // Ensure that apps that are mid-starting are also scheduled to have their
462 // starting windows removed after the animation is complete
Jorim Jaggiba41f4b2016-12-14 17:43:07 -0800463 if (wtoken.startingWindow != null && !wtoken.startingWindow.mAnimatingExit
464 && wtoken.getController() != null) {
465 wtoken.getController().removeStartingWindow();
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800466 }
467 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700468
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800469 if (animLp != null) {
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700470 int layer = wtoken.getHighestAnimLayer();
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800471 if (layerAndToken.token == null || layer > layerAndToken.layer) {
472 layerAndToken.token = wtoken;
473 layerAndToken.layer = layer;
474 }
475 }
476 if (mService.mAppTransition.isNextAppTransitionThumbnailDown()) {
477 createThumbnailAppAnimator(transit, wtoken, 0, layerAndToken.layer);
478 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700479 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700480 }
481
Jorim Jaggife762342016-10-13 14:33:27 +0200482 private void handleNonAppWindowsInTransition(int transit, int flags) {
483 if (transit == TRANSIT_KEYGUARD_GOING_AWAY) {
484 if ((flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0
485 && (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION) == 0) {
486 Animation anim = mService.mPolicy.createKeyguardWallpaperExit(
487 (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0);
488 if (anim != null) {
489 mService.getDefaultDisplayContentLocked().mWallpaperController
490 .startWallpaperAnimation(anim);
491 }
492 }
493 }
494 if (transit == TRANSIT_KEYGUARD_GOING_AWAY
495 || transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER) {
496 mService.getDefaultDisplayContentLocked().startKeyguardExitOnNonAppWindows(
497 transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER,
498 (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0);
499 }
500 }
501
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700502 private boolean transitionGoodToGo(int appsCount) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800503 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700504 "Checking " + appsCount + " opening apps (frozen="
505 + mService.mDisplayFrozen + " timeout="
506 + mService.mAppTransition.isTimeout() + ")...");
Robert Carr42769ff2016-09-20 13:36:42 -0700507 final ScreenRotationAnimation screenRotationAnimation =
508 mService.mAnimator.getScreenRotationAnimationLocked(
509 Display.DEFAULT_DISPLAY);
510
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800511 final SparseIntArray reasons = mTempTransitionReasons;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700512 if (!mService.mAppTransition.isTimeout()) {
Robert Carr42769ff2016-09-20 13:36:42 -0700513 // Imagine the case where we are changing orientation due to an app transition, but a previous
514 // orientation change is still in progress. We won't process the orientation change
515 // for our transition because we need to wait for the rotation animation to finish.
516 // If we start the app transition at this point, we will interrupt it halfway with a new rotation
517 // animation after the old one finally finishes. It's better to defer the
518 // app transition.
519 if (screenRotationAnimation != null && screenRotationAnimation.isAnimating() &&
520 mService.rotationNeedsUpdateLocked()) {
521 if (DEBUG_APP_TRANSITIONS) {
522 Slog.v(TAG, "Delaying app transition for screen rotation animation to finish");
523 }
524 return false;
525 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700526 for (int i = 0; i < appsCount; i++) {
527 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800528 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700529 "Check opening app=" + wtoken + ": allDrawn="
530 + wtoken.allDrawn + " startingDisplayed="
531 + wtoken.startingDisplayed + " startingMoved="
Chong Zhangd78ddb42016-03-02 17:01:14 -0800532 + wtoken.startingMoved + " isRelaunching()="
533 + wtoken.isRelaunching());
534
Jorim Jaggi275561a2016-02-23 10:11:02 -0500535 final boolean drawnBeforeRestoring = wtoken.allDrawn;
Wale Ogunwale9bc47732016-08-10 14:44:22 -0700536 wtoken.restoreSavedSurfaceForInterestingWindows();
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800537
Jorim Jaggi02886a82016-12-06 09:10:06 -0800538 final boolean allDrawn = wtoken.allDrawn && !wtoken.isRelaunching();
539 if (!allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700540 return false;
541 }
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800542 final TaskStack stack = wtoken.getStack();
543 final int stackId = stack != null ? stack.mStackId : INVALID_STACK_ID;
Jorim Jaggi02886a82016-12-06 09:10:06 -0800544 if (allDrawn) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800545 reasons.put(stackId, drawnBeforeRestoring ? APP_TRANSITION_WINDOWS_DRAWN
546 : APP_TRANSITION_SAVED_SURFACE);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500547 } else {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800548 reasons.put(stackId, wtoken.startingData instanceof SplashScreenStartingData
549 ? APP_TRANSITION_SPLASH_SCREEN
550 : APP_TRANSITION_SNAPSHOT);
Jorim Jaggi275561a2016-02-23 10:11:02 -0500551 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700552 }
553
Jorim Jaggi2f7d2922015-10-29 13:08:29 +0100554 // We also need to wait for the specs to be fetched, if needed.
555 if (mService.mAppTransition.isFetchingAppTransitionsSpecs()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800556 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "isFetchingAppTransitionSpecs=true");
Jorim Jaggi2f7d2922015-10-29 13:08:29 +0100557 return false;
558 }
559
Jorim Jaggi5a108c22016-10-13 14:33:27 +0200560 if (!mService.mUnknownAppVisibilityController.allResolved()) {
561 if (DEBUG_APP_TRANSITIONS) {
562 Slog.v(TAG, "unknownApps is not empty: "
563 + mService.mUnknownAppVisibilityController.getDebugMessage());
564 }
565 return false;
566 }
567
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700568 // If the wallpaper is visible, we need to check it's ready too.
Jorim Jaggi275561a2016-02-23 10:11:02 -0500569 boolean wallpaperReady = !mWallpaperControllerLocked.isWallpaperVisible() ||
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700570 mWallpaperControllerLocked.wallpaperTransitionReady();
Jorim Jaggi275561a2016-02-23 10:11:02 -0500571 if (wallpaperReady) {
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800572 mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reasons.clone())
573 .sendToTarget();
Jorim Jaggi275561a2016-02-23 10:11:02 -0500574 return true;
575 }
576 return false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700577 }
Jorim Jaggi3878ca32017-02-02 17:13:05 -0800578 mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reasons.clone()).sendToTarget();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700579 return true;
580 }
581
582 private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800583 boolean closingAppHasWallpaper) {
Matthew Ng26a1cec2017-05-18 14:42:51 -0700584 // Given no app transition pass it through instead of a wallpaper transition
585 if (transit == TRANSIT_NONE) {
586 return TRANSIT_NONE;
587 }
588
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700589 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
590 final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700591 final WindowState oldWallpaper = mWallpaperControllerLocked.isWallpaperTargetAnimating()
592 ? null : wallpaperTarget;
Filip Gruszczynski49b80af2015-09-24 09:04:26 -0700593 final ArraySet<AppWindowToken> openingApps = mService.mOpeningApps;
594 final ArraySet<AppWindowToken> closingApps = mService.mClosingApps;
Jorim Jaggife762342016-10-13 14:33:27 +0200595 boolean openingCanBeWallpaperTarget = canBeWallpaperTarget(openingApps);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800596 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700597 "New wallpaper target=" + wallpaperTarget
598 + ", oldWallpaper=" + oldWallpaper
Filip Gruszczynski49b80af2015-09-24 09:04:26 -0700599 + ", openingApps=" + openingApps
600 + ", closingApps=" + closingApps);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700601 mService.mAnimateWallpaperWithTarget = false;
Jorim Jaggia69243a2017-06-15 15:10:38 -0400602 if (openingCanBeWallpaperTarget && transit == TRANSIT_KEYGUARD_GOING_AWAY) {
Jorim Jaggife762342016-10-13 14:33:27 +0200603 transit = TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
604 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
605 "New transit: " + AppTransition.appTransitionToString(transit));
Jorim Jaggia69243a2017-06-15 15:10:38 -0400606 }
607 // We never want to change from a Keyguard transit to a non-Keyguard transit, as our logic
608 // relies on the fact that we always execute a Keyguard transition after preparing one.
609 else if (!isKeyguardGoingAwayTransit(transit)) {
610 if (closingAppHasWallpaper && openingAppHasWallpaper) {
611 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Wallpaper animation!");
612 switch (transit) {
613 case TRANSIT_ACTIVITY_OPEN:
614 case TRANSIT_TASK_OPEN:
615 case TRANSIT_TASK_TO_FRONT:
616 transit = TRANSIT_WALLPAPER_INTRA_OPEN;
617 break;
618 case TRANSIT_ACTIVITY_CLOSE:
619 case TRANSIT_TASK_CLOSE:
620 case TRANSIT_TASK_TO_BACK:
621 transit = TRANSIT_WALLPAPER_INTRA_CLOSE;
622 break;
623 }
624 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
625 "New transit: " + AppTransition.appTransitionToString(transit));
626 } else if (oldWallpaper != null && !mService.mOpeningApps.isEmpty()
627 && !openingApps.contains(oldWallpaper.mAppToken)
628 && closingApps.contains(oldWallpaper.mAppToken)) {
629 // We are transitioning from an activity with a wallpaper to one without.
630 transit = TRANSIT_WALLPAPER_CLOSE;
631 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New transit away from wallpaper: "
632 + AppTransition.appTransitionToString(transit));
633 } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw() &&
634 openingApps.contains(wallpaperTarget.mAppToken)) {
635 // We are transitioning from an activity without
636 // a wallpaper to now showing the wallpaper
637 transit = TRANSIT_WALLPAPER_OPEN;
638 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New transit into wallpaper: "
639 + AppTransition.appTransitionToString(transit));
640 } else {
641 mService.mAnimateWallpaperWithTarget = true;
642 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700643 }
644 return transit;
645 }
646
Jorim Jaggife762342016-10-13 14:33:27 +0200647 private boolean canBeWallpaperTarget(ArraySet<AppWindowToken> apps) {
648 for (int i = apps.size() - 1; i >= 0; i--) {
649 if (apps.valueAt(i).windowsCanBeWallpaperTarget()) {
650 return true;
651 }
652 }
653 return false;
654 }
655
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700656 private void processApplicationsAnimatingInPlace(int transit) {
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700657 if (transit == TRANSIT_TASK_IN_PLACE) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700658 // Find the focused window
Wale Ogunwale63d4ecc2016-09-08 18:48:26 -0700659 final WindowState win = mService.getDefaultDisplayContentLocked().findFocusedWindow();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700660 if (win != null) {
661 final AppWindowToken wtoken = win.mAppToken;
662 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
663 if (DEBUG_APP_TRANSITIONS)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800664 Slog.v(TAG, "Now animating app in place " + wtoken);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700665 appAnimator.clearThumbnail();
Chong Zhang65d15d02016-03-14 13:59:32 -0700666 appAnimator.setNullAnimation();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700667 mService.updateTokenInPlaceLocked(wtoken, transit);
668 wtoken.updateReportedVisibilityLocked();
Wale Ogunwale9f25bee2016-08-02 07:23:47 -0700669 wtoken.setAllAppWinAnimators();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700670 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
Wale Ogunwale69cf50f2015-11-13 11:08:36 -0800671 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700672 }
673 }
674 }
675
676 private void createThumbnailAppAnimator(int transit, AppWindowToken appToken,
677 int openingLayer, int closingLayer) {
678 AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
679 if (openingAppAnimator == null || openingAppAnimator.animation == null) {
680 return;
681 }
Bryce Lee6d410262017-02-28 15:30:17 -0800682 final int taskId = appToken.getTask().mTaskId;
Winson Chungaa7fa012017-05-24 15:50:06 -0700683 final GraphicBuffer thumbnailHeader =
684 mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
685 if (thumbnailHeader == null) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800686 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700687 return;
688 }
689 // This thumbnail animation is very special, we need to have
690 // an extra surface with the thumbnail included with the animation.
691 Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
692 try {
693 // TODO(multi-display): support other displays
694 final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
695 final Display display = displayContent.getDisplay();
696 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
697
698 // Create a new surface for the thumbnail
Albert Chaulke4338f82017-04-19 15:54:08 -0400699 WindowState window = appToken.findMainWindow();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700700 SurfaceControl surfaceControl = new SurfaceControl(mService.mFxSession,
701 "thumbnail anim", dirty.width(), dirty.height(),
Albert Chaulke4338f82017-04-19 15:54:08 -0400702 PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN,
Bryce Leee6c25d42017-05-31 10:27:42 -0700703 appToken.windowType,
704 window != null ? window.mOwnerUid : Binder.getCallingUid());
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700705 surfaceControl.setLayerStack(display.getLayerStack());
706 if (SHOW_TRANSACTIONS) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800707 Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700708 }
709
Winson Chungaa7fa012017-05-24 15:50:06 -0700710 // Transfer the thumbnail to the surface
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700711 Surface drawSurface = new Surface();
712 drawSurface.copyFrom(surfaceControl);
Winson Chungaa7fa012017-05-24 15:50:06 -0700713 drawSurface.attachAndQueueBuffer(thumbnailHeader);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700714 drawSurface.release();
715
716 // Get the thumbnail animation
717 Animation anim;
718 if (mService.mAppTransition.isNextThumbnailTransitionAspectScaled()) {
719 // If this is a multi-window scenario, we use the windows frame as
720 // destination of the thumbnail header animation. If this is a full screen
721 // window scenario, we use the whole display as the target.
722 WindowState win = appToken.findMainWindow();
723 Rect appRect = win != null ? win.getContentFrameLw() :
724 new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
Jorim Jaggide63d442016-03-14 14:56:56 +0100725 Rect insets = win != null ? win.mContentInsets : null;
Andrii Kulian441e4492016-09-29 15:25:00 -0700726 final Configuration displayConfig = displayContent.getConfiguration();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700727 // For the new aspect-scaled transition, we want it to always show
728 // above the animating opening/closing window, and we want to
729 // synchronize its thumbnail surface with the surface for the
730 // open/close animation (only on the way down)
731 anim = mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
Andrii Kulian441e4492016-09-29 15:25:00 -0700732 insets, thumbnailHeader, taskId, displayConfig.uiMode,
733 displayConfig.orientation);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700734 openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
735 openingAppAnimator.deferThumbnailDestruction =
736 !mService.mAppTransition.isNextThumbnailTransitionScaleUp();
737 } else {
738 anim = mService.mAppTransition.createThumbnailScaleAnimationLocked(
739 displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
740 }
741 anim.restrictDuration(MAX_ANIMATION_DURATION);
742 anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
743
744 openingAppAnimator.thumbnail = surfaceControl;
745 openingAppAnimator.thumbnailLayer = openingLayer;
746 openingAppAnimator.thumbnailAnimation = anim;
747 mService.mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700748 } catch (Surface.OutOfResourcesException e) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800749 Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700750 + dirty.width() + " h=" + dirty.height(), e);
751 openingAppAnimator.clearThumbnail();
752 }
753 }
754
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700755 void requestTraversal() {
756 if (!mTraversalScheduled) {
757 mTraversalScheduled = true;
Jorim Jaggied7993b2017-03-28 18:50:01 +0100758 mService.mAnimationHandler.post(mPerformSurfacePlacement);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700759 }
760 }
761
Jorim Jaggi3dac63a2016-03-01 12:37:07 +0100762 /**
763 * Puts the {@param surface} into a pending list to be destroyed after the current transaction
764 * has been committed.
765 */
766 void destroyAfterTransaction(SurfaceControl surface) {
767 mPendingDestroyingSurfaces.add(surface);
768 }
769
770 /**
771 * Destroys any surfaces that have been put into the pending list with
772 * {@link #destroyAfterTransaction}.
773 */
774 void destroyPendingSurfaces() {
775 for (int i = mPendingDestroyingSurfaces.size() - 1; i >= 0; i--) {
776 mPendingDestroyingSurfaces.get(i).destroy();
777 }
778 mPendingDestroyingSurfaces.clear();
779 }
780
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700781 public void dump(PrintWriter pw, String prefix) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700782 pw.println(prefix + "mTraversalScheduled=" + mTraversalScheduled);
783 pw.println(prefix + "mHoldScreenWindow=" + mService.mRoot.mHoldScreenWindow);
Wale Ogunwaled4a00a02016-10-10 11:29:17 -0700784 pw.println(prefix + "mObscuringWindow=" + mService.mRoot.mObscuringWindow);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700785 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700786}