blob: 1b9eeb0f499d4a06120edff2f5a40098b6027646 [file] [log] [blame]
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001package com.android.server.wm;
2
Jorim Jaggi275561a2016-02-23 10:11:02 -05003import static android.app.ActivityManagerInternal.APP_TRANSITION_SAVED_SURFACE;
4import static android.app.ActivityManagerInternal.APP_TRANSITION_STARTING_WINDOW;
5import static android.app.ActivityManagerInternal.APP_TRANSITION_TIMEOUT;
6import static android.app.ActivityManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07007import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
8import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
9import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
10import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
Ruchi Kandoi43e38de2016-04-14 19:34:53 -070011import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070012import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
13import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070014import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
15import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
16import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
17import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
18import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
19import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
20import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080021import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
22import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
23import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
24import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
25import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
26import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
27import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
28import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
29import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
30import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
31import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
32import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
Chong Zhang4ffc3182016-05-04 15:06:02 -070033import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080034import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
35import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
Chong Zhang4ffc3182016-05-04 15:06:02 -070036import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
Jorim Jaggi192086e2016-03-11 17:17:03 +010037import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080038import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Jorim Jaggi192086e2016-03-11 17:17:03 +010039import static com.android.server.wm.WindowManagerService.H.DO_TRAVERSAL;
40import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN;
41import static com.android.server.wm.WindowManagerService.H.NOTIFY_APP_TRANSITION_STARTING;
42import static com.android.server.wm.WindowManagerService.H.NOTIFY_STARTING_WINDOW_DRAWN;
43import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
44import static com.android.server.wm.WindowManagerService.H.REPORT_WINDOWS_CHANGE;
45import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
46import static com.android.server.wm.WindowManagerService.H.UPDATE_DOCKED_STACK_DIVIDER;
47import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT;
48import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
49import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070050import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
51import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
52import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
53
54import android.graphics.Bitmap;
55import android.graphics.Canvas;
56import android.graphics.PixelFormat;
57import android.graphics.Rect;
58import android.os.Debug;
59import android.os.PowerManager;
60import android.os.RemoteException;
61import android.os.SystemClock;
62import android.os.Trace;
63import android.provider.Settings;
Filip Gruszczynski49b80af2015-09-24 09:04:26 -070064import android.util.ArraySet;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070065import android.util.Slog;
66import android.view.Display;
67import android.view.DisplayInfo;
68import android.view.Surface;
69import android.view.SurfaceControl;
70import android.view.View;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -080071import android.view.WindowManager.LayoutParams;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070072import android.view.animation.Animation;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070073
Jorim Jaggid75962e2016-05-03 15:10:03 -070074import com.android.server.wm.WindowManagerService.H;
75
Filip Gruszczynski24966d42015-09-05 15:00:00 -070076import java.io.PrintWriter;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070077import java.util.ArrayList;
78
79/**
80 * Positions windows and their surfaces.
81 *
82 * It sets positions of windows by calculating their frames and then applies this by positioning
83 * surfaces according to these frames. Z layer is still assigned withing WindowManagerService.
84 */
85class WindowSurfacePlacer {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -080086 private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowSurfacePlacer" : TAG_WM;
Filip Gruszczynski4501d232015-09-02 13:00:02 -070087 private final WindowManagerService mService;
88 private final WallpaperController mWallpaperControllerLocked;
89
90 private boolean mInLayout = false;
91
92 /** Only do a maximum of 6 repeated layouts. After that quit */
93 private int mLayoutRepeatCount;
94
95 static final int SET_UPDATE_ROTATION = 1 << 0;
96 static final int SET_WALLPAPER_MAY_CHANGE = 1 << 1;
97 static final int SET_FORCE_HIDING_CHANGED = 1 << 2;
98 static final int SET_ORIENTATION_CHANGE_COMPLETE = 1 << 3;
99 static final int SET_TURN_ON_SCREEN = 1 << 4;
100 static final int SET_WALLPAPER_ACTION_PENDING = 1 << 5;
101
102 boolean mWallpaperMayChange = false;
103 boolean mOrientationChangeComplete = true;
104 boolean mWallpaperActionPending = false;
105
106 private boolean mWallpaperForceHidingChanged = false;
107 private Object mLastWindowFreezeSource = null;
108 private Session mHoldScreen = null;
109 private boolean mObscured = false;
110 private boolean mSyswin = false;
111 private float mScreenBrightness = -1;
112 private float mButtonBrightness = -1;
113 private long mUserActivityTimeout = -1;
114 private boolean mUpdateRotation = false;
115 private final Rect mTmpStartRect = new Rect();
Wale Ogunwaleb4ec0a32015-12-14 10:31:43 -0800116 private final Rect mTmpContentRect = new Rect();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700117
118 // Set to true when the display contains content to show the user.
119 // When false, the display manager may choose to mirror or blank the display.
120 private boolean mDisplayHasContent = false;
121
122 // Only set while traversing the default display based on its content.
123 // Affects the behavior of mirroring on secondary displays.
124 private boolean mObscureApplicationContentOnSecondaryDisplays = false;
125
126 private float mPreferredRefreshRate = 0;
127
128 private int mPreferredModeId = 0;
129
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700130 private boolean mTraversalScheduled;
Jorim Jaggic4025202015-10-22 16:43:34 +0200131 private int mDeferDepth = 0;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700132
Ruchi Kandoi43e38de2016-04-14 19:34:53 -0700133 private boolean mSustainedPerformanceModeEnabled = false;
134 private boolean mSustainedPerformanceModeCurrent = false;
135
Chong Zhang4ffc3182016-05-04 15:06:02 -0700136 // Following variables are for debugging screen wakelock only.
137 // Last window that requires screen wakelock
138 WindowState mHoldScreenWindow = null;
139 // Last window that obscures all windows below
140 WindowState mObsuringWindow = null;
141
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -0800142 private static final class LayerAndToken {
143 public int layer;
144 public AppWindowToken token;
145 }
146 private final LayerAndToken mTmpLayerAndToken = new LayerAndToken();
147
Jorim Jaggi3dac63a2016-03-01 12:37:07 +0100148 private final ArrayList<SurfaceControl> mPendingDestroyingSurfaces = new ArrayList<>();
149
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700150 public WindowSurfacePlacer(WindowManagerService service) {
151 mService = service;
152 mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
153 }
154
Jorim Jaggic4025202015-10-22 16:43:34 +0200155 /**
156 * See {@link WindowManagerService#deferSurfaceLayout()}
157 */
158 void deferLayout() {
159 mDeferDepth++;
160 }
161
162 /**
163 * See {@link WindowManagerService#continueSurfaceLayout()}
164 */
165 void continueLayout() {
166 mDeferDepth--;
167 if (mDeferDepth <= 0) {
168 performSurfacePlacement();
169 }
170 }
171
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700172 final void performSurfacePlacement() {
Jorim Jaggic4025202015-10-22 16:43:34 +0200173 if (mDeferDepth > 0) {
174 return;
175 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700176 int loopCount = 6;
177 do {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700178 mTraversalScheduled = false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700179 performSurfacePlacementLoop();
180 mService.mH.removeMessages(DO_TRAVERSAL);
181 loopCount--;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700182 } while (mTraversalScheduled && loopCount > 0);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700183 mWallpaperActionPending = false;
184 }
185
186 private void performSurfacePlacementLoop() {
187 if (mInLayout) {
188 if (DEBUG) {
189 throw new RuntimeException("Recursive call!");
190 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800191 Slog.w(TAG, "performLayoutAndPlaceSurfacesLocked called while in layout. Callers="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700192 + Debug.getCallers(3));
193 return;
194 }
195
196 if (mService.mWaitingForConfig) {
197 // Our configuration has changed (most likely rotation), but we
198 // don't yet have the complete configuration to report to
199 // applications. Don't do any window layout until we have it.
200 return;
201 }
202
203 if (!mService.mDisplayReady) {
204 // Not yet initialized, nothing to do.
205 return;
206 }
207
208 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmLayout");
209 mInLayout = true;
210
211 boolean recoveringMemory = false;
212 if (!mService.mForceRemoves.isEmpty()) {
213 recoveringMemory = true;
214 // Wait a little bit for things to settle down, and off we go.
215 while (!mService.mForceRemoves.isEmpty()) {
Wale Ogunwaleadde52e2016-07-16 13:11:55 -0700216 final WindowState ws = mService.mForceRemoves.remove(0);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800217 Slog.i(TAG, "Force removing: " + ws);
Wale Ogunwaleadde52e2016-07-16 13:11:55 -0700218 ws.removeLocked();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700219 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800220 Slog.w(TAG, "Due to memory failure, waiting a bit for next layout");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700221 Object tmp = new Object();
222 synchronized (tmp) {
223 try {
224 tmp.wait(250);
225 } catch (InterruptedException e) {
226 }
227 }
228 }
229
230 try {
231 performSurfacePlacementInner(recoveringMemory);
232
233 mInLayout = false;
234
235 if (mService.needsLayout()) {
236 if (++mLayoutRepeatCount < 6) {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700237 requestTraversal();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700238 } else {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800239 Slog.e(TAG, "Performed 6 layouts in a row. Skipping");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700240 mLayoutRepeatCount = 0;
241 }
242 } else {
243 mLayoutRepeatCount = 0;
244 }
245
246 if (mService.mWindowsChanged && !mService.mWindowChangeListeners.isEmpty()) {
247 mService.mH.removeMessages(REPORT_WINDOWS_CHANGE);
248 mService.mH.sendEmptyMessage(REPORT_WINDOWS_CHANGE);
249 }
250 } catch (RuntimeException e) {
251 mInLayout = false;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800252 Slog.wtf(TAG, "Unhandled exception while laying out windows", e);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700253 }
254
255 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
256 }
257
258 void debugLayoutRepeats(final String msg, int pendingLayoutChanges) {
259 if (mLayoutRepeatCount >= LAYOUT_REPEAT_THRESHOLD) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800260 Slog.v(TAG, "Layouts looping: " + msg +
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700261 ", mPendingLayoutChanges = 0x" + Integer.toHexString(pendingLayoutChanges));
262 }
263 }
264
265 // "Something has changed! Let's make it correct now."
266 private void performSurfacePlacementInner(boolean recoveringMemory) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800267 if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
268 + Debug.getCallers(3));
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700269
270 int i;
271 boolean updateInputWindowsNeeded = false;
272
273 if (mService.mFocusMayChange) {
274 mService.mFocusMayChange = false;
275 updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
276 UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
277 }
278
279 // Initialize state of exiting tokens.
280 final int numDisplays = mService.mDisplayContents.size();
281 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
282 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
283 for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
284 displayContent.mExitingTokens.get(i).hasVisible = false;
285 }
286 }
287
288 for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
289 // Initialize state of exiting applications.
290 final AppTokenList exitingAppTokens =
291 mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
292 for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
293 exitingAppTokens.get(tokenNdx).hasVisible = false;
294 }
295 }
296
297 mHoldScreen = null;
Chong Zhang4ffc3182016-05-04 15:06:02 -0700298 mHoldScreenWindow = null;
299 mObsuringWindow = null;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700300 mScreenBrightness = -1;
301 mButtonBrightness = -1;
302 mUserActivityTimeout = -1;
303 mObscureApplicationContentOnSecondaryDisplays = false;
Ruchi Kandoi43e38de2016-04-14 19:34:53 -0700304 mSustainedPerformanceModeCurrent = false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700305 mService.mTransactionSequence++;
306
307 final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
308 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
309 final int defaultDw = defaultInfo.logicalWidth;
310 final int defaultDh = defaultInfo.logicalHeight;
311
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800312 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700313 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
314 SurfaceControl.openTransaction();
315 try {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700316 applySurfaceChangesTransaction(recoveringMemory, numDisplays, defaultDw, defaultDh);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700317 } catch (RuntimeException e) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800318 Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700319 } finally {
320 SurfaceControl.closeTransaction();
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800321 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700322 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
323 }
324
325 final WindowList defaultWindows = defaultDisplay.getWindowList();
326
327 // If we are ready to perform an app transition, check through
328 // all of the app tokens to be shown and see if they are ready
329 // to go.
330 if (mService.mAppTransition.isReady()) {
331 defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
332 if (DEBUG_LAYOUT_REPEATS)
333 debugLayoutRepeats("after handleAppTransitionReadyLocked",
334 defaultDisplay.pendingLayoutChanges);
335 }
336
337 if (!mService.mAnimator.mAppWindowAnimating && mService.mAppTransition.isRunning()) {
338 // We have finished the animation of an app transition. To do
339 // this, we have delayed a lot of operations like showing and
340 // hiding apps, moving apps in Z-order, etc. The app token list
341 // reflects the correct Z-order, but the window list may now
342 // be out of sync with it. So here we will just rebuild the
343 // entire app window list. Fun!
344 defaultDisplay.pendingLayoutChanges |=
345 mService.handleAnimatingStoppedAndTransitionLocked();
346 if (DEBUG_LAYOUT_REPEATS)
347 debugLayoutRepeats("after handleAnimStopAndXitionLock",
348 defaultDisplay.pendingLayoutChanges);
349 }
350
351 if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
352 && !mService.mAppTransition.isReady()) {
353 // At this point, there was a window with a wallpaper that
354 // was force hiding other windows behind it, but now it
355 // is going away. This may be simple -- just animate
356 // away the wallpaper and its window -- or it may be
357 // hard -- the wallpaper now needs to be shown behind
358 // something that was hidden.
359 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
360 if (DEBUG_LAYOUT_REPEATS)
361 debugLayoutRepeats("after animateAwayWallpaperLocked",
362 defaultDisplay.pendingLayoutChanges);
363 }
364 mWallpaperForceHidingChanged = false;
365
366 if (mWallpaperMayChange) {
367 if (DEBUG_WALLPAPER_LIGHT)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800368 Slog.v(TAG, "Wallpaper may change! Adjusting");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700369 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
370 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
371 defaultDisplay.pendingLayoutChanges);
372 }
373
374 if (mService.mFocusMayChange) {
375 mService.mFocusMayChange = false;
376 if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
377 false /*updateInputWindows*/)) {
378 updateInputWindowsNeeded = true;
379 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
380 }
381 }
382
383 if (mService.needsLayout()) {
384 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
385 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
386 defaultDisplay.pendingLayoutChanges);
387 }
388
389 for (i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
390 WindowState win = mService.mResizingWindows.get(i);
391 if (win.mAppFreezing) {
392 // Don't remove this window until rotation has completed.
393 continue;
394 }
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700395 // Discard the saved surface if window size is changed, it can't be reused.
Chong Zhangbef461f2015-10-27 11:38:24 -0700396 if (win.mAppToken != null) {
397 win.mAppToken.destroySavedSurfaces();
Chong Zhangdb20b5f2015-10-23 14:01:43 -0700398 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700399 win.reportResized();
400 mService.mResizingWindows.remove(i);
401 }
402
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800403 if (DEBUG_ORIENTATION && mService.mDisplayFrozen) Slog.v(TAG,
404 "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700405 if (mOrientationChangeComplete) {
406 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
407 mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
408 mService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
409 mService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
410 }
411 mService.stopFreezingDisplayLocked();
412 }
413
414 // Destroy the surface of any windows that are no longer visible.
Filip Gruszczynski19723a42015-11-25 15:01:48 -0800415 boolean wallpaperDestroyed = false;
416 i = mService.mDestroySurface.size();
417 if (i > 0) {
418 do {
419 i--;
420 WindowState win = mService.mDestroySurface.get(i);
421 win.mDestroying = false;
422 if (mService.mInputMethodWindow == win) {
423 mService.mInputMethodWindow = null;
424 }
425 if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
426 wallpaperDestroyed = true;
427 }
Robert Carr13f7be9e2015-12-02 18:39:45 -0800428 win.destroyOrSaveSurface();
Filip Gruszczynski19723a42015-11-25 15:01:48 -0800429 } while (i > 0);
430 mService.mDestroySurface.clear();
431 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700432
433 // Time to remove any exiting tokens?
434 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
435 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
436 ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
437 for (i = exitingTokens.size() - 1; i >= 0; i--) {
438 WindowToken token = exitingTokens.get(i);
439 if (!token.hasVisible) {
440 exitingTokens.remove(i);
441 if (token.windowType == TYPE_WALLPAPER) {
442 mWallpaperControllerLocked.removeWallpaperToken(token);
443 }
444 }
445 }
446 }
447
448 // Time to remove any exiting applications?
449 for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
450 // Initialize state of exiting applications.
451 final AppTokenList exitingAppTokens =
452 mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
453 for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
454 AppWindowToken token = exitingAppTokens.get(i);
455 if (!token.hasVisible && !mService.mClosingApps.contains(token) &&
456 (!token.mIsExiting || token.allAppWindows.isEmpty())) {
457 // Make sure there is no animation running on this token,
458 // so any windows associated with it will be removed as
459 // soon as their animations are complete
460 token.mAppAnimator.clearAnimation();
461 token.mAppAnimator.animating = false;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800462 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
463 "performLayout: App token exiting now removed" + token);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700464 token.removeAppFromTaskLocked();
465 }
466 }
467 }
468
469 if (wallpaperDestroyed) {
470 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
471 defaultDisplay.layoutNeeded = true;
472 }
473
474 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
475 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
476 if (displayContent.pendingLayoutChanges != 0) {
477 displayContent.layoutNeeded = true;
478 }
479 }
480
481 // Finally update all input windows now that the window changes have stabilized.
482 mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
483
484 mService.setHoldScreenLocked(mHoldScreen);
485 if (!mService.mDisplayFrozen) {
486 if (mScreenBrightness < 0 || mScreenBrightness > 1.0f) {
487 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
488 } else {
489 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
490 toBrightnessOverride(mScreenBrightness));
491 }
492 if (mButtonBrightness < 0
493 || mButtonBrightness > 1.0f) {
494 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
495 } else {
496 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
497 toBrightnessOverride(mButtonBrightness));
498 }
499 mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
500 mUserActivityTimeout);
501 }
502
Ruchi Kandoi43e38de2016-04-14 19:34:53 -0700503 if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) {
504 mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent;
505 mService.mPowerManagerInternal.powerHint(
506 mService.mPowerManagerInternal.POWER_HINT_SUSTAINED_PERFORMANCE_MODE,
507 (mSustainedPerformanceModeEnabled ? 1 : 0));
508 }
509
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700510 if (mService.mTurnOnScreen) {
511 if (mService.mAllowTheaterModeWakeFromLayout
512 || Settings.Global.getInt(mService.mContext.getContentResolver(),
513 Settings.Global.THEATER_MODE_ON, 0) == 0) {
514 if (DEBUG_VISIBILITY || DEBUG_POWER) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800515 Slog.v(TAG, "Turning screen on after layout!");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700516 }
517 mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
518 "android.server.wm:TURN_ON");
519 }
520 mService.mTurnOnScreen = false;
521 }
522
523 if (mUpdateRotation) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800524 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700525 if (mService.updateRotationUncheckedLocked(false)) {
526 mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
527 } else {
528 mUpdateRotation = false;
529 }
530 }
531
532 if (mService.mWaitingForDrawnCallback != null ||
533 (mOrientationChangeComplete && !defaultDisplay.layoutNeeded &&
534 !mUpdateRotation)) {
535 mService.checkDrawnWindowsLocked();
536 }
537
538 final int N = mService.mPendingRemove.size();
539 if (N > 0) {
540 if (mService.mPendingRemoveTmp.length < N) {
541 mService.mPendingRemoveTmp = new WindowState[N+10];
542 }
543 mService.mPendingRemove.toArray(mService.mPendingRemoveTmp);
544 mService.mPendingRemove.clear();
545 DisplayContentList displayList = new DisplayContentList();
546 for (i = 0; i < N; i++) {
Wale Ogunwaleadde52e2016-07-16 13:11:55 -0700547 final WindowState w = mService.mPendingRemoveTmp[i];
548 w.removeLocked();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700549 final DisplayContent displayContent = w.getDisplayContent();
550 if (displayContent != null && !displayList.contains(displayContent)) {
551 displayList.add(displayContent);
552 }
553 }
554
555 for (DisplayContent displayContent : displayList) {
Filip Gruszczynski92e432c2015-12-15 19:17:09 -0800556 mService.mLayersController.assignLayersLocked(displayContent.getWindowList());
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700557 displayContent.layoutNeeded = true;
558 }
559 }
560
561 // Remove all deferred displays stacks, tasks, and activities.
562 for (int displayNdx = mService.mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
563 mService.mDisplayContents.valueAt(displayNdx).checkForDeferredActions();
564 }
565
566 if (updateInputWindowsNeeded) {
567 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
568 }
Chong Zhangb15758a2015-11-17 12:12:03 -0800569 mService.setFocusTaskRegionLocked();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700570
571 // Check to see if we are now in a state where the screen should
572 // be enabled, because the window obscured flags have changed.
573 mService.enableScreenIfNeededLocked();
574
575 mService.scheduleAnimationLocked();
Jorim Jaggi3dac63a2016-03-01 12:37:07 +0100576 mService.mWindowPlacerLocked.destroyPendingSurfaces();
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700577
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800578 if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
Wale Ogunwale69cf50f2015-11-13 11:08:36 -0800579 "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700580 }
581
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700582 private void applySurfaceChangesTransaction(boolean recoveringMemory, int numDisplays,
583 int defaultDw, int defaultDh) {
584 if (mService.mWatermark != null) {
585 mService.mWatermark.positionSurface(defaultDw, defaultDh);
586 }
587 if (mService.mStrictModeFlash != null) {
588 mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
589 }
590 if (mService.mCircularDisplayMask != null) {
591 mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh,
592 mService.mRotation);
593 }
594 if (mService.mEmulatorDisplayOverlay != null) {
595 mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
596 mService.mRotation);
597 }
598
599 boolean focusDisplayed = false;
600
601 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
602 final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
603 boolean updateAllDrawn = false;
604 WindowList windows = displayContent.getWindowList();
605 DisplayInfo displayInfo = displayContent.getDisplayInfo();
606 final int displayId = displayContent.getDisplayId();
607 final int dw = displayInfo.logicalWidth;
608 final int dh = displayInfo.logicalHeight;
609 final int innerDw = displayInfo.appWidth;
610 final int innerDh = displayInfo.appHeight;
611 final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
612
613 // Reset for each display.
614 mDisplayHasContent = false;
615 mPreferredRefreshRate = 0;
616 mPreferredModeId = 0;
617
618 int repeats = 0;
619 do {
620 repeats++;
621 if (repeats > 6) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800622 Slog.w(TAG, "Animation repeat aborted after too many iterations");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700623 displayContent.layoutNeeded = false;
624 break;
625 }
626
627 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
628 "On entry to LockedInner", displayContent.pendingLayoutChanges);
629
630 if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
631 mWallpaperControllerLocked.adjustWallpaperWindows()) {
Filip Gruszczynski92e432c2015-12-15 19:17:09 -0800632 mService.mLayersController.assignLayersLocked(windows);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700633 displayContent.layoutNeeded = true;
634 }
635
636 if (isDefaultDisplay
637 && (displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800638 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700639 if (mService.updateOrientationFromAppTokensLocked(true)) {
640 displayContent.layoutNeeded = true;
641 mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
642 }
643 }
644
645 if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
646 displayContent.layoutNeeded = true;
647 }
648
649 // FIRST LOOP: Perform a layout, if needed.
650 if (repeats < LAYOUT_REPEAT_THRESHOLD) {
651 performLayoutLockedInner(displayContent, repeats == 1,
652 false /* updateInputWindows */);
653 } else {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800654 Slog.w(TAG, "Layout repeat skipped after too many iterations");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700655 }
656
657 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
658 // it is animating.
659 displayContent.pendingLayoutChanges = 0;
660
661 if (isDefaultDisplay) {
662 mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
663 for (int i = windows.size() - 1; i >= 0; i--) {
664 WindowState w = windows.get(i);
665 if (w.mHasSurface) {
666 mService.mPolicy.applyPostLayoutPolicyLw(w, w.mAttrs,
Wale Ogunwale7ed4d372016-07-09 15:28:55 -0700667 w.mParentWindow);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700668 }
669 }
670 displayContent.pendingLayoutChanges |=
671 mService.mPolicy.finishPostLayoutPolicyLw();
672 if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after finishPostLayoutPolicyLw",
673 displayContent.pendingLayoutChanges);
674 }
675 } while (displayContent.pendingLayoutChanges != 0);
676
677 mObscured = false;
678 mSyswin = false;
679 displayContent.resetDimming();
680
681 // Only used if default window
682 final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
683
684 for (int i = windows.size() - 1; i >= 0; i--) {
685 WindowState w = windows.get(i);
Robert Carr0d00c2e2016-02-29 17:45:02 -0800686 final Task task = w.getTask();
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700687 final boolean obscuredChanged = w.mObscured != mObscured;
688
689 // Update effect.
690 w.mObscured = mObscured;
691 if (!mObscured) {
Chong Zhang0abb20f2015-11-19 14:17:31 -0800692 handleNotObscuredLocked(w, displayInfo);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700693 }
694
Chong Zhang112eb8c2015-11-02 11:17:00 -0800695 w.applyDimLayerIfNeeded();
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700696
697 if (isDefaultDisplay && obscuredChanged
698 && mWallpaperControllerLocked.isWallpaperTarget(w) && w.isVisibleLw()) {
699 // This is the wallpaper target and its obscured state
700 // changed... make sure the current wallaper's visibility
701 // has been updated accordingly.
702 mWallpaperControllerLocked.updateWallpaperVisibility();
703 }
704
705 final WindowStateAnimator winAnimator = w.mWinAnimator;
706
707 // If the window has moved due to its containing content frame changing, then
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800708 // notify the listeners and optionally animate it. Simply checking a change of
709 // position is not enough, because being move due to dock divider is not a trigger
710 // for animation.
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700711 if (w.hasMoved()) {
712 // Frame has moved, containing content frame has also moved, and we're not
713 // currently animating... let's do something.
714 final int left = w.mFrame.left;
715 final int top = w.mFrame.top;
Chong Zhangbaba7832016-03-24 10:21:26 -0700716 final boolean adjustedForMinimizedDockOrIme = task != null
717 && (task.mStack.isAdjustedForMinimizedDockedStack()
718 || task.mStack.isAdjustedForIme());
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800719 if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
Chong Zhangbaba7832016-03-24 10:21:26 -0700720 && !w.isDragResizing() && !adjustedForMinimizedDockOrIme
Robert Carrc7294602016-05-13 11:32:05 -0700721 && (task == null || w.getTask().mStack.hasMovementAnimations())
Jorim Jaggi192086e2016-03-11 17:17:03 +0100722 && !w.mWinAnimator.mLastHidden) {
Filip Gruszczynskif52dd202015-11-15 20:36:38 -0800723 winAnimator.setMoveAnimation(left, top);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700724 }
725
726 //TODO (multidisplay): Accessibility supported only for the default display.
727 if (mService.mAccessibilityController != null
728 && displayId == Display.DEFAULT_DISPLAY) {
729 mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
730 }
731
732 try {
Wale Ogunwale7774bd52016-06-17 09:44:22 -0700733 w.mClient.moved(left, top);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700734 } catch (RemoteException e) {
735 }
Jorim Jaggi192086e2016-03-11 17:17:03 +0100736 w.mMovedByResize = false;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700737 }
738
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800739 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700740 w.mContentChanged = false;
741
742 // Moved from updateWindowsAndWallpaperLocked().
743 if (w.mHasSurface) {
Robert Carr679c8072016-04-07 15:51:48 -0700744 // If we have recently synchronized a previous transaction for this
745 // window ensure we don't push through an unsynchronized one now.
746 winAnimator.deferToPendingTransaction();
747
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700748 // Take care of the window being ready to display.
749 final boolean committed = winAnimator.commitFinishDrawingLocked();
750 if (isDefaultDisplay && committed) {
751 if (w.mAttrs.type == TYPE_DREAM) {
752 // HACK: When a dream is shown, it may at that
753 // point hide the lock screen. So we need to
754 // redo the layout to let the phone window manager
755 // make this happen.
756 displayContent.pendingLayoutChanges |=
757 FINISH_LAYOUT_REDO_LAYOUT;
758 if (DEBUG_LAYOUT_REPEATS) {
759 debugLayoutRepeats("dream and commitFinishDrawingLocked true",
760 displayContent.pendingLayoutChanges);
761 }
762 }
763 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
764 if (DEBUG_WALLPAPER_LIGHT)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800765 Slog.v(TAG, "First draw done in potential wallpaper target " + w);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700766 mWallpaperMayChange = true;
767 displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
768 if (DEBUG_LAYOUT_REPEATS) {
769 debugLayoutRepeats("wallpaper and commitFinishDrawingLocked true",
770 displayContent.pendingLayoutChanges);
771 }
772 }
773 }
Chong Zhange22006d2016-05-09 10:59:59 -0700774 if (!winAnimator.isAnimationStarting() && !winAnimator.isWaitingForOpening()) {
Filip Gruszczynskic46f41c2016-01-05 11:29:21 -0800775 // Updates the shown frame before we set up the surface. This is needed
776 // because the resizing could change the top-left position (in addition to
777 // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700778 // position the surface.
779 //
780 // If an animation is being started, we can't call this method because the
781 // animation hasn't processed its initial transformation yet, but in general
782 // we do want to update the position if the window is animating.
Filip Gruszczynskic46f41c2016-01-05 11:29:21 -0800783 winAnimator.computeShownFrameLocked();
784 }
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700785 winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
786 }
787
788 final AppWindowToken atoken = w.mAppToken;
789 if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800790 Slog.d(TAG, "updateWindows: starting " + w
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700791 + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
792 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
793 }
Chong Zhang8e4bda92016-05-04 15:08:18 -0700794 if (atoken != null && (!atoken.allDrawn || !atoken.allDrawnExcludingSaved
795 || atoken.mAppAnimator.freezingScreen)) {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700796 if (atoken.lastTransactionSequence != mService.mTransactionSequence) {
797 atoken.lastTransactionSequence = mService.mTransactionSequence;
798 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
Chong Zhang8e4bda92016-05-04 15:08:18 -0700799 atoken.numInterestingWindowsExcludingSaved = 0;
800 atoken.numDrawnWindowsExclusingSaved = 0;
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700801 atoken.startingDisplayed = false;
802 }
Chong Zhang8e4bda92016-05-04 15:08:18 -0700803 if (!atoken.allDrawn && w.mightAffectAllDrawn(false /* visibleOnly */)) {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700804 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800805 Slog.v(TAG, "Eval win " + w + ": isDrawn="
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700806 + w.isDrawnLw()
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700807 + ", isAnimationSet=" + winAnimator.isAnimationSet());
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700808 if (!w.isDrawnLw()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800809 Slog.v(TAG, "Not displayed: s="
Robert Carre6a83512015-11-03 16:09:21 -0800810 + winAnimator.mSurfaceController
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700811 + " pv=" + w.mPolicyVisibility
812 + " mDrawState=" + winAnimator.drawStateToString()
Wale Ogunwale9d147902016-07-16 11:58:55 -0700813 + " ph=" + w.isParentWindowHidden()
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700814 + " th=" + atoken.hiddenRequested
815 + " a=" + winAnimator.mAnimating);
816 }
817 }
Chong Zhangbfc2f8f2016-01-29 15:50:34 -0800818 if (w != atoken.startingWindow) {
Chong Zhang8e4bda92016-05-04 15:08:18 -0700819 if (w.isInteresting()) {
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700820 atoken.numInterestingWindows++;
821 if (w.isDrawnLw()) {
822 atoken.numDrawnWindows++;
823 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800824 Slog.v(TAG, "tokenMayBeDrawn: " + atoken
Chong Zhang8e4bda92016-05-04 15:08:18 -0700825 + " w=" + w + " numInteresting="
826 + atoken.numInterestingWindows
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700827 + " freezingScreen="
828 + atoken.mAppAnimator.freezingScreen
829 + " mAppFreezing=" + w.mAppFreezing);
830 updateAllDrawn = true;
831 }
832 }
833 } else if (w.isDrawnLw()) {
Jorim Jaggi275561a2016-02-23 10:11:02 -0500834 mService.mH.sendEmptyMessage(NOTIFY_STARTING_WINDOW_DRAWN);
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700835 atoken.startingDisplayed = true;
836 }
837 }
Chong Zhang8e4bda92016-05-04 15:08:18 -0700838 if (!atoken.allDrawnExcludingSaved
839 && w.mightAffectAllDrawn(true /* visibleOnly */)) {
840 if (w != atoken.startingWindow && w.isInteresting()) {
841 atoken.numInterestingWindowsExcludingSaved++;
842 if (w.isDrawnLw() && !w.isAnimatingWithSavedSurface()) {
843 atoken.numDrawnWindowsExclusingSaved++;
844 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
845 Slog.v(TAG, "tokenMayBeDrawnExcludingSaved: " + atoken
846 + " w=" + w + " numInteresting="
847 + atoken.numInterestingWindowsExcludingSaved
848 + " freezingScreen="
849 + atoken.mAppAnimator.freezingScreen
850 + " mAppFreezing=" + w.mAppFreezing);
851 updateAllDrawn = true;
852 }
853 }
854 }
Filip Gruszczynski24966d42015-09-05 15:00:00 -0700855 }
856
857 if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
858 && w.isDisplayedLw()) {
859 focusDisplayed = true;
860 }
861
862 mService.updateResizingWindows(w);
863 }
864
865 mService.mDisplayManagerInternal.setDisplayProperties(displayId,
866 mDisplayHasContent,
867 mPreferredRefreshRate,
868 mPreferredModeId,
869 true /* inTraversal, must call performTraversalInTrans... below */);
870
871 mService.getDisplayContentLocked(displayId).stopDimmingIfNeeded();
872
873 if (updateAllDrawn) {
874 updateAllDrawnLocked(displayContent);
875 }
876 }
877
878 if (focusDisplayed) {
879 mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
880 }
881
882 // Give the display manager a chance to adjust properties
883 // like display rotation if it needs to.
884 mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
885 }
886
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700887 boolean isInLayout() {
888 return mInLayout;
889 }
890
891 final void performLayoutLockedInner(final DisplayContent displayContent,
892 boolean initial, boolean updateInputWindows) {
893 if (!displayContent.layoutNeeded) {
894 return;
895 }
896 displayContent.layoutNeeded = false;
897 WindowList windows = displayContent.getWindowList();
898 boolean isDefaultDisplay = displayContent.isDefaultDisplay;
899
900 DisplayInfo displayInfo = displayContent.getDisplayInfo();
901 final int dw = displayInfo.logicalWidth;
902 final int dh = displayInfo.logicalHeight;
903
904 if (mService.mInputConsumer != null) {
905 mService.mInputConsumer.layout(dw, dh);
906 }
907
Vladislav Kaznacheev0d50d862016-03-29 15:43:28 -0700908 if (mService.mWallpaperInputConsumer != null) {
909 mService.mWallpaperInputConsumer.layout(dw, dh);
910 }
911
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700912 final int N = windows.size();
913 int i;
914
915 if (DEBUG_LAYOUT) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800916 Slog.v(TAG, "-------------------------------------");
917 Slog.v(TAG, "performLayout: needed="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700918 + displayContent.layoutNeeded + " dw=" + dw + " dh=" + dh);
919 }
920
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800921 mService.mPolicy.beginLayoutLw(isDefaultDisplay, dw, dh, mService.mRotation,
922 mService.mCurConfiguration.uiMode);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700923 if (isDefaultDisplay) {
924 // Not needed on non-default displays.
925 mService.mSystemDecorLayer = mService.mPolicy.getSystemDecorLayerLw();
926 mService.mScreenRect.set(0, 0, dw, dh);
927 }
928
Wale Ogunwaleb4ec0a32015-12-14 10:31:43 -0800929 mService.mPolicy.getContentRectLw(mTmpContentRect);
930 displayContent.resize(mTmpContentRect);
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700931
932 int seq = mService.mLayoutSeq+1;
933 if (seq < 0) seq = 0;
934 mService.mLayoutSeq = seq;
935
936 boolean behindDream = false;
937
938 // First perform layout of any root windows (not attached
939 // to another window).
940 int topAttached = -1;
941 for (i = N-1; i >= 0; i--) {
942 final WindowState win = windows.get(i);
943
944 // Don't do layout of a window if it is not visible, or
945 // soon won't be visible, to avoid wasting time and funky
946 // changes while a window is animating away.
947 final boolean gone = (behindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs))
948 || win.isGoneForLayoutLw();
949
950 if (DEBUG_LAYOUT && !win.mLayoutAttached) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800951 Slog.v(TAG, "1ST PASS " + win
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700952 + ": gone=" + gone + " mHaveFrame=" + win.mHaveFrame
953 + " mLayoutAttached=" + win.mLayoutAttached
954 + " screen changed=" + win.isConfigChanged());
955 final AppWindowToken atoken = win.mAppToken;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800956 if (gone) Slog.v(TAG, " GONE: mViewVisibility="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700957 + win.mViewVisibility + " mRelayoutCalled="
958 + win.mRelayoutCalled + " hidden="
959 + win.mRootToken.hidden + " hiddenRequested="
960 + (atoken != null && atoken.hiddenRequested)
Wale Ogunwale9d147902016-07-16 11:58:55 -0700961 + " parentHidden=" + win.isParentWindowHidden());
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800962 else Slog.v(TAG, " VIS: mViewVisibility="
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700963 + win.mViewVisibility + " mRelayoutCalled="
964 + win.mRelayoutCalled + " hidden="
965 + win.mRootToken.hidden + " hiddenRequested="
966 + (atoken != null && atoken.hiddenRequested)
Wale Ogunwale9d147902016-07-16 11:58:55 -0700967 + " parentHidden=" + win.isParentWindowHidden());
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700968 }
969
970 // If this view is GONE, then skip it -- keep the current
971 // frame, and let the caller know so they can ignore it
972 // if they want. (We do the normal layout for INVISIBLE
973 // windows, since that means "perform layout as normal,
974 // just don't display").
975 if (!gone || !win.mHaveFrame || win.mLayoutNeeded
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700976 || ((win.isConfigChanged() || win.setInsetsChanged())
977 && !win.isGoneForLayoutLw() &&
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700978 ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
979 (win.mHasSurface && win.mAppToken != null &&
980 win.mAppToken.layoutConfigChanges)))) {
981 if (!win.mLayoutAttached) {
982 if (initial) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -0800983 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Filip Gruszczynski4501d232015-09-02 13:00:02 -0700984 win.mContentChanged = false;
985 }
986 if (win.mAttrs.type == TYPE_DREAM) {
987 // Don't layout windows behind a dream, so that if it
988 // does stuff like hide the status bar we won't get a
989 // bad transition when it goes away.
990 behindDream = true;
991 }
992 win.mLayoutNeeded = false;
993 win.prelayout();
994 mService.mPolicy.layoutWindowLw(win, null);
995 win.mLayoutSeq = seq;
Chong Zhang4c9ba52a2015-11-10 18:36:33 -0800996
997 // Window frames may have changed. Update dim layer with the new bounds.
998 final Task task = win.getTask();
999 if (task != null) {
1000 displayContent.mDimLayerController.updateDimLayer(task);
1001 }
1002
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001003 if (DEBUG_LAYOUT) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001004 " LAYOUT: mFrame="
1005 + win.mFrame + " mContainingFrame="
1006 + win.mContainingFrame + " mDisplayFrame="
1007 + win.mDisplayFrame);
1008 } else {
1009 if (topAttached < 0) topAttached = i;
1010 }
1011 }
1012 }
1013
1014 boolean attachedBehindDream = false;
1015
1016 // Now perform layout of attached windows, which usually
1017 // depend on the position of the window they are attached to.
1018 // XXX does not deal with windows that are attached to windows
1019 // that are themselves attached.
1020 for (i = topAttached; i >= 0; i--) {
1021 final WindowState win = windows.get(i);
1022
1023 if (win.mLayoutAttached) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001024 if (DEBUG_LAYOUT) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001025 "2ND PASS " + win + " mHaveFrame=" + win.mHaveFrame + " mViewVisibility="
1026 + win.mViewVisibility + " mRelayoutCalled=" + win.mRelayoutCalled);
1027 // If this view is GONE, then skip it -- keep the current
1028 // frame, and let the caller know so they can ignore it
1029 // if they want. (We do the normal layout for INVISIBLE
1030 // windows, since that means "perform layout as normal,
1031 // just don't display").
1032 if (attachedBehindDream && mService.mPolicy.canBeForceHidden(win, win.mAttrs)) {
1033 continue;
1034 }
1035 if ((win.mViewVisibility != View.GONE && win.mRelayoutCalled)
1036 || !win.mHaveFrame || win.mLayoutNeeded) {
1037 if (initial) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001038 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - initial");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001039 win.mContentChanged = false;
1040 }
1041 win.mLayoutNeeded = false;
1042 win.prelayout();
Wale Ogunwale7ed4d372016-07-09 15:28:55 -07001043 mService.mPolicy.layoutWindowLw(win, win.mParentWindow);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001044 win.mLayoutSeq = seq;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001045 if (DEBUG_LAYOUT) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001046 " LAYOUT: mFrame=" + win.mFrame + " mContainingFrame="
1047 + win.mContainingFrame + " mDisplayFrame=" + win.mDisplayFrame);
1048 }
1049 } else if (win.mAttrs.type == TYPE_DREAM) {
1050 // Don't layout windows behind a dream, so that if it
1051 // does stuff like hide the status bar we won't get a
1052 // bad transition when it goes away.
1053 attachedBehindDream = behindDream;
1054 }
1055 }
1056
Chong Zhang4c9ba52a2015-11-10 18:36:33 -08001057 // Window frames may have changed. Tell the input dispatcher about it.
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001058 mService.mInputMonitor.setUpdateInputWindowsNeededLw();
1059 if (updateInputWindows) {
1060 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
1061 }
1062
1063 mService.mPolicy.finishLayoutLw();
Jorim Jaggi61f39a72015-10-29 16:54:18 +01001064 mService.mH.sendEmptyMessage(UPDATE_DOCKED_STACK_DIVIDER);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001065 }
1066
1067 /**
1068 * @param windows List of windows on default display.
1069 * @return bitmap indicating if another pass through layout must be made.
1070 */
1071 private int handleAppTransitionReadyLocked(WindowList windows) {
1072 int appsCount = mService.mOpeningApps.size();
1073 if (!transitionGoodToGo(appsCount)) {
1074 return 0;
1075 }
Chong Zhang8784be62016-06-28 15:25:07 -07001076 Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "AppTransitionReady");
1077
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001078 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "**** GOOD TO GO");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001079 int transit = mService.mAppTransition.getAppTransition();
1080 if (mService.mSkipAppTransitionAnimation) {
1081 transit = AppTransition.TRANSIT_UNSET;
1082 }
1083 mService.mSkipAppTransitionAnimation = false;
1084 mService.mNoAnimationNotifyOnTransitionFinished.clear();
1085
Jorim Jaggid75962e2016-05-03 15:10:03 -07001086 mService.mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001087
1088 mService.rebuildAppWindowListLocked();
1089
1090 mWallpaperMayChange = false;
1091
1092 // The top-most window will supply the layout params,
1093 // and we will determine it below.
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001094 LayoutParams animLp = null;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001095 int bestAnimLayer = -1;
1096 boolean fullscreenAnim = false;
1097 boolean voiceInteraction = false;
1098
1099 final WindowState lowerWallpaperTarget =
1100 mWallpaperControllerLocked.getLowerWallpaperTarget();
1101 final WindowState upperWallpaperTarget =
1102 mWallpaperControllerLocked.getUpperWallpaperTarget();
1103
1104 boolean openingAppHasWallpaper = false;
1105 boolean closingAppHasWallpaper = false;
1106 final AppWindowToken lowerWallpaperAppToken;
1107 final AppWindowToken upperWallpaperAppToken;
1108 if (lowerWallpaperTarget == null) {
1109 lowerWallpaperAppToken = upperWallpaperAppToken = null;
1110 } else {
1111 lowerWallpaperAppToken = lowerWallpaperTarget.mAppToken;
1112 upperWallpaperAppToken = upperWallpaperTarget.mAppToken;
1113 }
1114
1115 int i;
1116 // Do a first pass through the tokens for two
1117 // things:
1118 // (1) Determine if both the closing and opening
1119 // app token sets are wallpaper targets, in which
1120 // case special animations are needed
1121 // (since the wallpaper needs to stay static
1122 // behind them).
1123 // (2) Find the layout params of the top-most
1124 // application window in the tokens, which is
1125 // what will control the animation theme.
1126 final int closingAppsCount = mService.mClosingApps.size();
1127 appsCount = closingAppsCount + mService.mOpeningApps.size();
1128 for (i = 0; i < appsCount; i++) {
1129 final AppWindowToken wtoken;
1130 if (i < closingAppsCount) {
1131 wtoken = mService.mClosingApps.valueAt(i);
1132 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1133 closingAppHasWallpaper = true;
1134 }
1135 } else {
1136 wtoken = mService.mOpeningApps.valueAt(i - closingAppsCount);
1137 if (wtoken == lowerWallpaperAppToken || wtoken == upperWallpaperAppToken) {
1138 openingAppHasWallpaper = true;
1139 }
1140 }
1141
1142 voiceInteraction |= wtoken.voiceInteraction;
1143
1144 if (wtoken.appFullscreen) {
1145 WindowState ws = wtoken.findMainWindow();
1146 if (ws != null) {
1147 animLp = ws.mAttrs;
1148 bestAnimLayer = ws.mLayer;
1149 fullscreenAnim = true;
1150 }
1151 } else if (!fullscreenAnim) {
1152 WindowState ws = wtoken.findMainWindow();
1153 if (ws != null) {
1154 if (ws.mLayer > bestAnimLayer) {
1155 animLp = ws.mAttrs;
1156 bestAnimLayer = ws.mLayer;
1157 }
1158 }
1159 }
1160 }
1161
1162 transit = maybeUpdateTransitToWallpaper(transit, openingAppHasWallpaper,
1163 closingAppHasWallpaper, lowerWallpaperTarget, upperWallpaperTarget);
1164
1165 // If all closing windows are obscured, then there is
1166 // no need to do an animation. This is the case, for
1167 // example, when this transition is being done behind
1168 // the lock screen.
1169 if (!mService.mPolicy.allowAppAnimationsLw()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001170 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001171 "Animations disallowed by keyguard or dream.");
1172 animLp = null;
1173 }
1174
1175 processApplicationsAnimatingInPlace(transit);
1176
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001177 mTmpLayerAndToken.token = null;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001178 handleClosingApps(transit, animLp, voiceInteraction, mTmpLayerAndToken);
1179 final AppWindowToken topClosingApp = mTmpLayerAndToken.token;
1180 final int topClosingLayer = mTmpLayerAndToken.layer;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001181
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001182 final AppWindowToken topOpeningApp = handleOpeningApps(transit,
1183 animLp, voiceInteraction, topClosingLayer);
1184
1185 final AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ? null :
1186 topOpeningApp.mAppAnimator;
1187 final AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
1188 topClosingApp.mAppAnimator;
1189
Jorim Jaggi42625d1b2016-02-11 20:11:07 -08001190 mService.mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator,
1191 mService.mOpeningApps, mService.mClosingApps);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001192 mService.mAppTransition.postAnimationCallback();
1193 mService.mAppTransition.clear();
1194
1195 mService.mOpeningApps.clear();
1196 mService.mClosingApps.clear();
1197
1198 // This has changed the visibility of windows, so perform
1199 // a new layout to get them all up-to-date.
1200 mService.getDefaultDisplayContentLocked().layoutNeeded = true;
1201
1202 // TODO(multidisplay): IMEs are only supported on the default display.
1203 if (windows == mService.getDefaultWindowListLocked()
1204 && !mService.moveInputMethodWindowsIfNeededLocked(true)) {
Filip Gruszczynski92e432c2015-12-15 19:17:09 -08001205 mService.mLayersController.assignLayersLocked(windows);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001206 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001207 mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
1208 true /*updateInputWindows*/);
1209 mService.mFocusMayChange = false;
1210 mService.notifyActivityDrawnForKeyguard();
Chong Zhang8784be62016-06-28 15:25:07 -07001211
1212 Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
1213
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001214 return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_CONFIG;
1215 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001216
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001217 private AppWindowToken handleOpeningApps(int transit, LayoutParams animLp,
1218 boolean voiceInteraction, int topClosingLayer) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001219 AppWindowToken topOpeningApp = null;
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001220 final int appsCount = mService.mOpeningApps.size();
1221 for (int i = 0; i < appsCount; i++) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001222 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
1223 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001224 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001225
1226 if (!appAnimator.usingTransferredAnimation) {
1227 appAnimator.clearThumbnail();
Chong Zhang65d15d02016-03-14 13:59:32 -07001228 appAnimator.setNullAnimation();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001229 }
1230 wtoken.inPendingTransaction = false;
Chong Zhangeb22e8e2016-01-20 19:52:22 -08001231
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001232 if (!mService.setTokenVisibilityLocked(
1233 wtoken, animLp, true, transit, false, voiceInteraction)){
1234 // This token isn't going to be animating. Add it to the list of tokens to
1235 // be notified of app transition complete since the notification will not be
1236 // sent be the app window animator.
1237 mService.mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
1238 }
1239 wtoken.updateReportedVisibilityLocked();
1240 wtoken.waitingToShow = false;
1241
1242 appAnimator.mAllAppWinAnimators.clear();
1243 final int windowsCount = wtoken.allAppWindows.size();
1244 for (int j = 0; j < windowsCount; j++) {
1245 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1246 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001247 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001248 ">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
1249 SurfaceControl.openTransaction();
1250 try {
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001251 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001252 } finally {
1253 SurfaceControl.closeTransaction();
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001254 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
Filip Gruszczynski974eb3d2015-10-23 17:33:11 -07001255 "<<< CLOSE TRANSACTION handleAppTransitionReadyLocked()");
1256 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001257 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
1258
1259 int topOpeningLayer = 0;
1260 if (animLp != null) {
1261 int layer = -1;
Chong Zhange22006d2016-05-09 10:59:59 -07001262 for (int j = 0; j < wtoken.allAppWindows.size(); j++) {
1263 final WindowState win = wtoken.allAppWindows.get(j);
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001264 // Clearing the mAnimatingExit flag before entering animation. It will be set to true
Filip Gruszczynski78a08ee2015-11-08 18:04:32 -08001265 // if app window is removed, or window relayout to invisible. We don't want to
1266 // clear it out for windows that get replaced, because the animation depends on
1267 // the flag to remove the replaced window.
Robert Carr7fed68d2016-01-19 21:24:57 -08001268 //
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001269 // We also don't clear the mAnimatingExit flag for windows which have the
Robert Carr7fed68d2016-01-19 21:24:57 -08001270 // mRemoveOnExit flag. This indicates an explicit remove request has been issued
1271 // by the client. We should let animation proceed and not clear this flag or
Wale Ogunwaleadde52e2016-07-16 13:11:55 -07001272 // they won't eventually be removed by WindowState#onExitAnimationDone.
Robert Carr7fed68d2016-01-19 21:24:57 -08001273 if (!win.mWillReplaceWindow && !win.mRemoveOnExit) {
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001274 win.mAnimatingExit = false;
Chong Zhange22006d2016-05-09 10:59:59 -07001275 // Clear mAnimating flag together with mAnimatingExit. When animation
1276 // changes from exiting to entering, we need to clear this flag until the
1277 // new animation gets applied, so that isAnimationStarting() becomes true
1278 // until then.
1279 // Otherwise applySurfaceChangesTransaction will faill to skip surface
1280 // placement for this window during this period, one or more frame will
1281 // show up with wrong position or scale.
1282 win.mWinAnimator.mAnimating = false;
Filip Gruszczynski78a08ee2015-11-08 18:04:32 -08001283 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001284 if (win.mWinAnimator.mAnimLayer > layer) {
1285 layer = win.mWinAnimator.mAnimLayer;
1286 }
1287 }
1288 if (topOpeningApp == null || layer > topOpeningLayer) {
1289 topOpeningApp = wtoken;
1290 topOpeningLayer = layer;
1291 }
1292 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001293 if (mService.mAppTransition.isNextAppTransitionThumbnailUp()) {
1294 createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
1295 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001296 }
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001297 return topOpeningApp;
1298 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001299
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001300 private void handleClosingApps(int transit, LayoutParams animLp, boolean voiceInteraction,
1301 LayerAndToken layerAndToken) {
1302 final int appsCount;
1303 appsCount = mService.mClosingApps.size();
1304 for (int i = 0; i < appsCount; i++) {
1305 AppWindowToken wtoken = mService.mClosingApps.valueAt(i);
Chong Zhangf58631a2016-05-24 16:02:10 -07001306
1307 // If we still have some windows animating with saved surfaces that's
1308 // either invisible or already removed, mark them exiting so that they
1309 // are disposed of after the exit animation. These are not supposed to
1310 // be shown, or are delayed removal until app is actually drawn (in which
1311 // case the window will be removed after the animation).
1312 wtoken.markSavedSurfaceExiting();
1313
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001314 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001315 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001316 appAnimator.clearThumbnail();
Chong Zhang65d15d02016-03-14 13:59:32 -07001317 appAnimator.setNullAnimation();
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001318 wtoken.inPendingTransaction = false;
1319 mService.setTokenVisibilityLocked(wtoken, animLp, false, transit, false,
1320 voiceInteraction);
1321 wtoken.updateReportedVisibilityLocked();
1322 // Force the allDrawn flag, because we want to start
1323 // this guy's animations regardless of whether it's
1324 // gotten drawn.
1325 wtoken.allDrawn = true;
1326 wtoken.deferClearAllDrawn = false;
1327 // Ensure that apps that are mid-starting are also scheduled to have their
1328 // starting windows removed after the animation is complete
Wale Ogunwalec48a3542016-02-19 15:18:45 -08001329 if (wtoken.startingWindow != null && !wtoken.startingWindow.mAnimatingExit) {
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001330 mService.scheduleRemoveStartingWindowLocked(wtoken);
1331 }
1332 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001333
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001334 if (animLp != null) {
1335 int layer = -1;
1336 for (int j = 0; j < wtoken.windows.size(); j++) {
1337 WindowState win = wtoken.windows.get(j);
1338 if (win.mWinAnimator.mAnimLayer > layer) {
1339 layer = win.mWinAnimator.mAnimLayer;
1340 }
1341 }
1342 if (layerAndToken.token == null || layer > layerAndToken.layer) {
1343 layerAndToken.token = wtoken;
1344 layerAndToken.layer = layer;
1345 }
1346 }
1347 if (mService.mAppTransition.isNextAppTransitionThumbnailDown()) {
1348 createThumbnailAppAnimator(transit, wtoken, 0, layerAndToken.layer);
1349 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001350 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001351 }
1352
1353 private boolean transitionGoodToGo(int appsCount) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001354 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001355 "Checking " + appsCount + " opening apps (frozen="
1356 + mService.mDisplayFrozen + " timeout="
1357 + mService.mAppTransition.isTimeout() + ")...");
Jorim Jaggi275561a2016-02-23 10:11:02 -05001358 int reason = APP_TRANSITION_TIMEOUT;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001359 if (!mService.mAppTransition.isTimeout()) {
1360 for (int i = 0; i < appsCount; i++) {
1361 AppWindowToken wtoken = mService.mOpeningApps.valueAt(i);
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001362 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001363 "Check opening app=" + wtoken + ": allDrawn="
1364 + wtoken.allDrawn + " startingDisplayed="
1365 + wtoken.startingDisplayed + " startingMoved="
Chong Zhangd78ddb42016-03-02 17:01:14 -08001366 + wtoken.startingMoved + " isRelaunching()="
1367 + wtoken.isRelaunching());
1368
1369 if (wtoken.isRelaunching()) {
1370 return false;
1371 }
Chong Zhangdb20b5f2015-10-23 14:01:43 -07001372
Jorim Jaggi275561a2016-02-23 10:11:02 -05001373 final boolean drawnBeforeRestoring = wtoken.allDrawn;
Chong Zhangbfc2f8f2016-01-29 15:50:34 -08001374 wtoken.restoreSavedSurfaces();
1375
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001376 if (!wtoken.allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) {
1377 return false;
1378 }
Jorim Jaggi275561a2016-02-23 10:11:02 -05001379 if (wtoken.allDrawn) {
1380 reason = drawnBeforeRestoring ? APP_TRANSITION_WINDOWS_DRAWN
1381 : APP_TRANSITION_SAVED_SURFACE;
1382 } else {
1383 reason = APP_TRANSITION_STARTING_WINDOW;
1384 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001385 }
1386
Jorim Jaggi2f7d2922015-10-29 13:08:29 +01001387 // We also need to wait for the specs to be fetched, if needed.
1388 if (mService.mAppTransition.isFetchingAppTransitionsSpecs()) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001389 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "isFetchingAppTransitionSpecs=true");
Jorim Jaggi2f7d2922015-10-29 13:08:29 +01001390 return false;
1391 }
1392
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001393 // If the wallpaper is visible, we need to check it's ready too.
Jorim Jaggi275561a2016-02-23 10:11:02 -05001394 boolean wallpaperReady = !mWallpaperControllerLocked.isWallpaperVisible() ||
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001395 mWallpaperControllerLocked.wallpaperTransitionReady();
Jorim Jaggi275561a2016-02-23 10:11:02 -05001396 if (wallpaperReady) {
1397 mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget();
1398 return true;
1399 }
1400 return false;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001401 }
Jorim Jaggi275561a2016-02-23 10:11:02 -05001402 mService.mH.obtainMessage(NOTIFY_APP_TRANSITION_STARTING, reason, 0).sendToTarget();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001403 return true;
1404 }
1405
1406 private int maybeUpdateTransitToWallpaper(int transit, boolean openingAppHasWallpaper,
1407 boolean closingAppHasWallpaper, WindowState lowerWallpaperTarget,
1408 WindowState upperWallpaperTarget) {
1409 // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
1410 final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
1411 final WindowState oldWallpaper =
1412 mWallpaperControllerLocked.isWallpaperTargetAnimating()
1413 ? null : wallpaperTarget;
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001414 final ArraySet<AppWindowToken> openingApps = mService.mOpeningApps;
1415 final ArraySet<AppWindowToken> closingApps = mService.mClosingApps;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001416 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001417 "New wallpaper target=" + wallpaperTarget
1418 + ", oldWallpaper=" + oldWallpaper
1419 + ", lower target=" + lowerWallpaperTarget
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001420 + ", upper target=" + upperWallpaperTarget
1421 + ", openingApps=" + openingApps
1422 + ", closingApps=" + closingApps);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001423 mService.mAnimateWallpaperWithTarget = false;
1424 if (closingAppHasWallpaper && openingAppHasWallpaper) {
1425 if (DEBUG_APP_TRANSITIONS)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001426 Slog.v(TAG, "Wallpaper animation!");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001427 switch (transit) {
1428 case AppTransition.TRANSIT_ACTIVITY_OPEN:
1429 case AppTransition.TRANSIT_TASK_OPEN:
1430 case AppTransition.TRANSIT_TASK_TO_FRONT:
1431 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_OPEN;
1432 break;
1433 case AppTransition.TRANSIT_ACTIVITY_CLOSE:
1434 case AppTransition.TRANSIT_TASK_CLOSE:
1435 case AppTransition.TRANSIT_TASK_TO_BACK:
1436 transit = AppTransition.TRANSIT_WALLPAPER_INTRA_CLOSE;
1437 break;
1438 }
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001439 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001440 "New transit: " + AppTransition.appTransitionToString(transit));
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001441 } else if (oldWallpaper != null && !mService.mOpeningApps.isEmpty()
1442 && !openingApps.contains(oldWallpaper.mAppToken)
1443 && closingApps.contains(oldWallpaper.mAppToken)) {
1444 // We are transitioning from an activity with a wallpaper to one without.
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001445 transit = AppTransition.TRANSIT_WALLPAPER_CLOSE;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001446 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001447 "New transit away from wallpaper: "
1448 + AppTransition.appTransitionToString(transit));
Filip Gruszczynski49b80af2015-09-24 09:04:26 -07001449 } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw() &&
1450 openingApps.contains(wallpaperTarget.mAppToken)) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001451 // We are transitioning from an activity without
1452 // a wallpaper to now showing the wallpaper
1453 transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001454 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001455 "New transit into wallpaper: "
1456 + AppTransition.appTransitionToString(transit));
1457 } else {
1458 mService.mAnimateWallpaperWithTarget = true;
1459 }
1460 return transit;
1461 }
1462
1463 /**
1464 * @param w WindowState this method is applied to.
Chong Zhang0abb20f2015-11-19 14:17:31 -08001465 * @param dispInfo info of the display that the window's obscuring state is checked against.
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001466 */
Chong Zhang0abb20f2015-11-19 14:17:31 -08001467 private void handleNotObscuredLocked(final WindowState w, final DisplayInfo dispInfo) {
Filip Gruszczynski4cbc3152015-12-07 11:50:57 -08001468 final LayoutParams attrs = w.mAttrs;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001469 final int attrFlags = attrs.flags;
1470 final boolean canBeSeen = w.isDisplayedLw();
Ruchi Kandoi43e38de2016-04-14 19:34:53 -07001471 final int privateflags = attrs.privateFlags;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001472
Chong Zhang0abb20f2015-11-19 14:17:31 -08001473 if (canBeSeen && w.isObscuringFullscreen(dispInfo)) {
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001474 // This window completely covers everything behind it,
1475 // so we want to leave all of them as undimmed (for
1476 // performance reasons).
Chong Zhang4ffc3182016-05-04 15:06:02 -07001477 if (!mObscured) {
1478 mObsuringWindow = w;
1479 }
1480
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001481 mObscured = true;
1482 }
1483
1484 if (w.mHasSurface) {
1485 if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
1486 mHoldScreen = w.mSession;
Chong Zhang4ffc3182016-05-04 15:06:02 -07001487 mHoldScreenWindow = w;
1488 } else if (DEBUG_KEEP_SCREEN_ON && w == mService.mLastWakeLockHoldingWindow) {
1489 Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w + " was holding "
1490 + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by"
1491 + Debug.getCallers(10));
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001492 }
1493 if (!mSyswin && w.mAttrs.screenBrightness >= 0
1494 && mScreenBrightness < 0) {
1495 mScreenBrightness = w.mAttrs.screenBrightness;
1496 }
1497 if (!mSyswin && w.mAttrs.buttonBrightness >= 0
1498 && mButtonBrightness < 0) {
1499 mButtonBrightness = w.mAttrs.buttonBrightness;
1500 }
1501 if (!mSyswin && w.mAttrs.userActivityTimeout >= 0
1502 && mUserActivityTimeout < 0) {
1503 mUserActivityTimeout = w.mAttrs.userActivityTimeout;
1504 }
1505
1506 final int type = attrs.type;
1507 if (canBeSeen
1508 && (type == TYPE_SYSTEM_DIALOG
1509 || type == TYPE_SYSTEM_ERROR
1510 || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0)) {
1511 mSyswin = true;
1512 }
1513
1514 if (canBeSeen) {
1515 // This function assumes that the contents of the default display are
1516 // processed first before secondary displays.
1517 final DisplayContent displayContent = w.getDisplayContent();
1518 if (displayContent != null && displayContent.isDefaultDisplay) {
1519 // While a dream or keyguard is showing, obscure ordinary application
1520 // content on secondary displays (by forcibly enabling mirroring unless
1521 // there is other content we want to show) but still allow opaque
1522 // keyguard dialogs to be shown.
1523 if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
1524 mObscureApplicationContentOnSecondaryDisplays = true;
1525 }
1526 mDisplayHasContent = true;
1527 } else if (displayContent != null &&
1528 (!mObscureApplicationContentOnSecondaryDisplays
1529 || (mObscured && type == TYPE_KEYGUARD_DIALOG))) {
1530 // Allow full screen keyguard presentation dialogs to be seen.
1531 mDisplayHasContent = true;
1532 }
1533 if (mPreferredRefreshRate == 0
1534 && w.mAttrs.preferredRefreshRate != 0) {
1535 mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
1536 }
1537 if (mPreferredModeId == 0
1538 && w.mAttrs.preferredDisplayModeId != 0) {
1539 mPreferredModeId = w.mAttrs.preferredDisplayModeId;
1540 }
Ruchi Kandoi43e38de2016-04-14 19:34:53 -07001541 if ((privateflags & PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE) != 0) {
1542 mSustainedPerformanceModeCurrent = true;
1543 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001544 }
1545 }
1546 }
1547
1548 private void updateAllDrawnLocked(DisplayContent displayContent) {
1549 // See if any windows have been drawn, so they (and others
1550 // associated with them) can now be shown.
1551 ArrayList<TaskStack> stacks = displayContent.getStacks();
1552 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
1553 final ArrayList<Task> tasks = stacks.get(stackNdx).getTasks();
1554 for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
1555 final AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
1556 for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
1557 final AppWindowToken wtoken = tokens.get(tokenNdx);
1558 if (!wtoken.allDrawn) {
1559 int numInteresting = wtoken.numInterestingWindows;
1560 if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) {
1561 if (DEBUG_VISIBILITY)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001562 Slog.v(TAG, "allDrawn: " + wtoken
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001563 + " interesting=" + numInteresting
1564 + " drawn=" + wtoken.numDrawnWindows);
1565 wtoken.allDrawn = true;
1566 // Force an additional layout pass where WindowStateAnimator#
1567 // commitFinishDrawingLocked() will call performShowLocked().
1568 displayContent.layoutNeeded = true;
1569 mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN,
1570 wtoken.token).sendToTarget();
1571 }
1572 }
Chong Zhang8e4bda92016-05-04 15:08:18 -07001573 if (!wtoken.allDrawnExcludingSaved) {
1574 int numInteresting = wtoken.numInterestingWindowsExcludingSaved;
1575 if (numInteresting > 0
1576 && wtoken.numDrawnWindowsExclusingSaved >= numInteresting) {
1577 if (DEBUG_VISIBILITY)
1578 Slog.v(TAG, "allDrawnExcludingSaved: " + wtoken
1579 + " interesting=" + numInteresting
1580 + " drawn=" + wtoken.numDrawnWindowsExclusingSaved);
1581 wtoken.allDrawnExcludingSaved = true;
1582 displayContent.layoutNeeded = true;
1583 if (wtoken.isAnimatingInvisibleWithSavedSurface()
1584 && !mService.mFinishedEarlyAnim.contains(wtoken)) {
1585 mService.mFinishedEarlyAnim.add(wtoken);
1586 }
1587 }
1588 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001589 }
1590 }
1591 }
1592 }
1593
1594 private static int toBrightnessOverride(float value) {
1595 return (int)(value * PowerManager.BRIGHTNESS_ON);
1596 }
1597
1598 private void processApplicationsAnimatingInPlace(int transit) {
1599 if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
1600 // Find the focused window
1601 final WindowState win = mService.findFocusedWindowLocked(
1602 mService.getDefaultDisplayContentLocked());
1603 if (win != null) {
1604 final AppWindowToken wtoken = win.mAppToken;
1605 final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
1606 if (DEBUG_APP_TRANSITIONS)
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001607 Slog.v(TAG, "Now animating app in place " + wtoken);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001608 appAnimator.clearThumbnail();
Chong Zhang65d15d02016-03-14 13:59:32 -07001609 appAnimator.setNullAnimation();
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001610 mService.updateTokenInPlaceLocked(wtoken, transit);
1611 wtoken.updateReportedVisibilityLocked();
1612
1613 appAnimator.mAllAppWinAnimators.clear();
1614 final int N = wtoken.allAppWindows.size();
1615 for (int j = 0; j < N; j++) {
1616 appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
1617 }
1618 mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
Wale Ogunwale69cf50f2015-11-13 11:08:36 -08001619 mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001620 }
1621 }
1622 }
1623
1624 private void createThumbnailAppAnimator(int transit, AppWindowToken appToken,
1625 int openingLayer, int closingLayer) {
1626 AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
1627 if (openingAppAnimator == null || openingAppAnimator.animation == null) {
1628 return;
1629 }
1630 final int taskId = appToken.mTask.mTaskId;
1631 Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
1632 if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001633 if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001634 return;
1635 }
1636 // This thumbnail animation is very special, we need to have
1637 // an extra surface with the thumbnail included with the animation.
1638 Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
1639 try {
1640 // TODO(multi-display): support other displays
1641 final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
1642 final Display display = displayContent.getDisplay();
1643 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1644
1645 // Create a new surface for the thumbnail
1646 SurfaceControl surfaceControl = new SurfaceControl(mService.mFxSession,
1647 "thumbnail anim", dirty.width(), dirty.height(),
1648 PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
1649 surfaceControl.setLayerStack(display.getLayerStack());
1650 if (SHOW_TRANSACTIONS) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001651 Slog.i(TAG, " THUMBNAIL " + surfaceControl + ": CREATE");
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001652 }
1653
1654 // Draw the thumbnail onto the surface
1655 Surface drawSurface = new Surface();
1656 drawSurface.copyFrom(surfaceControl);
1657 Canvas c = drawSurface.lockCanvas(dirty);
1658 c.drawBitmap(thumbnailHeader, 0, 0, null);
1659 drawSurface.unlockCanvasAndPost(c);
1660 drawSurface.release();
1661
1662 // Get the thumbnail animation
1663 Animation anim;
1664 if (mService.mAppTransition.isNextThumbnailTransitionAspectScaled()) {
1665 // If this is a multi-window scenario, we use the windows frame as
1666 // destination of the thumbnail header animation. If this is a full screen
1667 // window scenario, we use the whole display as the target.
1668 WindowState win = appToken.findMainWindow();
1669 Rect appRect = win != null ? win.getContentFrameLw() :
1670 new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
Jorim Jaggide63d442016-03-14 14:56:56 +01001671 Rect insets = win != null ? win.mContentInsets : null;
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001672 // For the new aspect-scaled transition, we want it to always show
1673 // above the animating opening/closing window, and we want to
1674 // synchronize its thumbnail surface with the surface for the
1675 // open/close animation (only on the way down)
1676 anim = mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
Winsonb2024762016-04-05 17:32:30 -07001677 insets, thumbnailHeader, taskId, mService.mCurConfiguration.uiMode,
1678 mService.mCurConfiguration.orientation);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001679 openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
1680 openingAppAnimator.deferThumbnailDestruction =
1681 !mService.mAppTransition.isNextThumbnailTransitionScaleUp();
1682 } else {
1683 anim = mService.mAppTransition.createThumbnailScaleAnimationLocked(
1684 displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
1685 }
1686 anim.restrictDuration(MAX_ANIMATION_DURATION);
1687 anim.scaleCurrentDuration(mService.getTransitionAnimationScaleLocked());
1688
1689 openingAppAnimator.thumbnail = surfaceControl;
1690 openingAppAnimator.thumbnailLayer = openingLayer;
1691 openingAppAnimator.thumbnailAnimation = anim;
1692 mService.mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001693 } catch (Surface.OutOfResourcesException e) {
Filip Gruszczynskice4ec402016-01-22 11:22:47 -08001694 Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w="
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001695 + dirty.width() + " h=" + dirty.height(), e);
1696 openingAppAnimator.clearThumbnail();
1697 }
1698 }
1699
1700 boolean copyAnimToLayoutParamsLocked() {
1701 boolean doRequest = false;
1702
1703 final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
1704 if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
1705 mUpdateRotation = true;
1706 doRequest = true;
1707 }
1708 if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
1709 mWallpaperMayChange = true;
1710 doRequest = true;
1711 }
1712 if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
1713 mWallpaperForceHidingChanged = true;
1714 doRequest = true;
1715 }
1716 if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
1717 mOrientationChangeComplete = false;
1718 } else {
1719 mOrientationChangeComplete = true;
1720 mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
1721 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
1722 doRequest = true;
1723 }
1724 }
1725 if ((bulkUpdateParams & SET_TURN_ON_SCREEN) != 0) {
1726 mService.mTurnOnScreen = true;
1727 }
1728 if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
1729 mWallpaperActionPending = true;
1730 }
1731
1732 return doRequest;
1733 }
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001734
1735 void requestTraversal() {
1736 if (!mTraversalScheduled) {
1737 mTraversalScheduled = true;
1738 mService.mH.sendEmptyMessage(DO_TRAVERSAL);
1739 }
1740 }
1741
Jorim Jaggi3dac63a2016-03-01 12:37:07 +01001742 /**
1743 * Puts the {@param surface} into a pending list to be destroyed after the current transaction
1744 * has been committed.
1745 */
1746 void destroyAfterTransaction(SurfaceControl surface) {
1747 mPendingDestroyingSurfaces.add(surface);
1748 }
1749
1750 /**
1751 * Destroys any surfaces that have been put into the pending list with
1752 * {@link #destroyAfterTransaction}.
1753 */
1754 void destroyPendingSurfaces() {
1755 for (int i = mPendingDestroyingSurfaces.size() - 1; i >= 0; i--) {
1756 mPendingDestroyingSurfaces.get(i).destroy();
1757 }
1758 mPendingDestroyingSurfaces.clear();
1759 }
1760
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001761 public void dump(PrintWriter pw, String prefix) {
1762 pw.print(prefix); pw.print("mTraversalScheduled="); pw.println(mTraversalScheduled);
Chong Zhang4ffc3182016-05-04 15:06:02 -07001763 pw.print(prefix); pw.print("mHoldScreenWindow="); pw.println(mHoldScreenWindow);
1764 pw.print(prefix); pw.print("mObsuringWindow="); pw.println(mObsuringWindow);
Filip Gruszczynski24966d42015-09-05 15:00:00 -07001765 }
Filip Gruszczynski4501d232015-09-02 13:00:02 -07001766}