blob: d119fb7a7576f1760b61088a3c06d40f7ca15d5d [file] [log] [blame]
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.wm;
18
19import android.app.AppOpsManager;
20import android.content.res.Configuration;
21import android.graphics.Rect;
22import android.os.Binder;
23import android.os.Debug;
24import android.os.ParcelFileDescriptor;
25import android.os.PowerManager;
26import android.os.RemoteException;
27import android.os.SystemClock;
28import android.os.UserHandle;
29import android.provider.Settings;
30import android.util.EventLog;
31import android.util.Slog;
32import android.util.SparseArray;
33import android.util.SparseIntArray;
34import android.view.Display;
35import android.view.DisplayInfo;
36import android.view.InputChannel;
37import android.view.WindowManager;
38import com.android.internal.util.ArrayUtils;
39import com.android.server.EventLogTags;
40import com.android.server.input.InputWindowHandle;
41
42import java.io.FileDescriptor;
43import java.io.PrintWriter;
44import java.util.ArrayList;
45
46import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
47import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
48import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
49import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
50import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
51import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
52import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
53import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
54import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
55import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
56import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
57import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
58import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
59import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
60import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
61import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
62import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
63import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
64import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
65import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
66import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
67import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
68import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
69import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
70import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
71import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
72import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
73import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
74import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
75import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
76import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
77import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
78import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
79import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
80import static com.android.server.wm.WindowManagerService.H.NOTIFY_STARTING_WINDOW_DRAWN;
81import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
82import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
83import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
84import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
85import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
86import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
87import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT;
88import static com.android.server.wm.WindowManagerService.logSurface;
89import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED;
90import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
91import static com.android.server.wm.WindowSurfacePlacer.SET_TURN_ON_SCREEN;
92import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
93import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
94import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE;
95
96/** Root {@link WindowContainer} for the device. */
97// TODO: Several methods in here are accessing children of this container's children through various
98// references (WindowList I am looking at you :/). See if we can delegate instead.
99class RootWindowContainer {
100 private static final String TAG = TAG_WITH_CLASS_NAME ? "RootWindowContainer" : TAG_WM;
101
102 WindowManagerService mService;
103
104 /** All DisplayContents in the world, kept here */
105 SparseArray<DisplayContent> mDisplayContents = new SparseArray<>(2);
106
107 private boolean mWallpaperForceHidingChanged = false;
108 private Object mLastWindowFreezeSource = null;
109 private Session mHoldScreen = null;
110 private float mScreenBrightness = -1;
111 private float mButtonBrightness = -1;
112 private long mUserActivityTimeout = -1;
113 private boolean mUpdateRotation = false;
114 private boolean mObscured = false;
115 boolean mSyswin = false;
116 // Set to true when the display contains content to show the user.
117 // When false, the display manager may choose to mirror or blank the display.
118 private boolean mDisplayHasContent = false;
119 private float mPreferredRefreshRate = 0;
120 private int mPreferredModeId = 0;
121 // Following variables are for debugging screen wakelock only.
122 // Last window that requires screen wakelock
123 WindowState mHoldScreenWindow = null;
124 // Last window that obscures all windows below
125 WindowState mObsuringWindow = null;
126 // Only set while traversing the default display based on its content.
127 // Affects the behavior of mirroring on secondary displays.
128 private boolean mObscureApplicationContentOnSecondaryDisplays = false;
129
130 private boolean mSustainedPerformanceModeEnabled = false;
131 private boolean mSustainedPerformanceModeCurrent = false;
132
133 boolean mWallpaperMayChange = false;
134 boolean mOrientationChangeComplete = true;
135 boolean mWallpaperActionPending = false;
136
137 private final ArrayList<Integer> mChangedStackList = new ArrayList();
138
139 // State for the RemoteSurfaceTrace system used in testing. If this is enabled SurfaceControl
140 // instances will be replaced with an instance that writes a binary representation of all
141 // commands to mSurfaceTraceFd.
142 boolean mSurfaceTraceEnabled;
143 ParcelFileDescriptor mSurfaceTraceFd;
144 RemoteEventTrace mRemoteEventTrace;
145
146 RootWindowContainer(WindowManagerService service) {
147 mService = service;
148 }
149
150 WindowState computeFocusedWindow() {
151 final int count = mDisplayContents.size();
152 for (int i = 0; i < count; i++) {
153 final DisplayContent dc = mDisplayContents.valueAt(i);
154 final WindowState win = dc.findFocusedWindow();
155 if (win != null) {
156 return win;
157 }
158 }
159 return null;
160 }
161
162 /**
163 * Retrieve the DisplayContent for the specified displayId. Will create a new DisplayContent if
164 * there is a Display for the displayId.
165 *
166 * @param displayId The display the caller is interested in.
167 * @return The DisplayContent associated with displayId or null if there is no Display for it.
168 */
169 DisplayContent getDisplayContent(final int displayId) {
170 DisplayContent dc = mDisplayContents.get(displayId);
171 if (dc == null) {
172 final Display display = mService.mDisplayManager.getDisplay(displayId);
173 if (display != null) {
174 dc = createDisplayContent(display);
175 }
176 }
177 return dc;
178 }
179
180 private DisplayContent createDisplayContent(final Display display) {
181 DisplayContent displayContent = new DisplayContent(display, mService);
182 final int displayId = display.getDisplayId();
183 if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Adding display=" + display);
184 mDisplayContents.put(displayId, displayContent);
185
186 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
187 final Rect rect = new Rect();
188 mService.mDisplaySettings.getOverscanLocked(displayInfo.name, displayInfo.uniqueId, rect);
189 displayInfo.overscanLeft = rect.left;
190 displayInfo.overscanTop = rect.top;
191 displayInfo.overscanRight = rect.right;
192 displayInfo.overscanBottom = rect.bottom;
193 if (mService.mDisplayManagerInternal != null) {
194 mService.mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
195 displayId, displayInfo);
196 mService.configureDisplayPolicyLocked(displayContent);
197
198 // TODO(multi-display): Create an input channel for each display with touch capability.
199 if (displayId == Display.DEFAULT_DISPLAY) {
200 displayContent.mTapDetector = new TaskTapPointerEventListener(
201 mService, displayContent);
202 mService.registerPointerEventListener(displayContent.mTapDetector);
203 mService.registerPointerEventListener(mService.mMousePositionTracker);
204 }
205 }
206
207 return displayContent;
208 }
209
210 /** Adds the input stack id to the input display id and returns the bounds of the added stack.*/
211 Rect addStackToDisplay(int stackId, int displayId, boolean onTop) {
212 final DisplayContent dc = mDisplayContents.get(displayId);
213 if (dc == null) {
214 Slog.w(TAG_WM, "addStackToDisplay: Trying to add stackId=" + stackId
215 + " to unknown displayId=" + displayId + " callers=" + Debug.getCallers(6));
216 return null;
217 }
218
219 boolean attachedToDisplay = false;
220 TaskStack stack = mService.mStackIdToStack.get(stackId);
221 if (stack == null) {
222 if (DEBUG_STACK) Slog.d(TAG_WM, "attachStack: stackId=" + stackId);
223
224 stack = dc.getStackById(stackId);
225 if (stack != null) {
226 // It's already attached to the display...clear mDeferRemoval!
227 stack.mDeferRemoval = false;
228 attachedToDisplay = true;
229 } else {
230 stack = new TaskStack(mService, stackId);
231 }
232
233 mService.mStackIdToStack.put(stackId, stack);
234 if (stackId == DOCKED_STACK_ID) {
235 mService.getDefaultDisplayContentLocked().mDividerControllerLocked
236 .notifyDockedStackExistsChanged(true);
237 }
238 }
239 if (!attachedToDisplay) {
240 stack.attachDisplayContent(dc);
241 }
242 dc.attachStack(stack, onTop);
243 if (stack.getRawFullscreen()) {
244 return null;
245 }
246 Rect bounds = new Rect();
247 stack.getRawBounds(bounds);
248 return bounds;
249 }
250
251 boolean layoutNeeded() {
252 final int numDisplays = mDisplayContents.size();
253 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
254 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
255 if (displayContent.layoutNeeded) {
256 return true;
257 }
258 }
259 return false;
260 }
261
262 void getWindows(WindowList output) {
263 final int count = mDisplayContents.size();
264 for (int i = 0; i < count; ++i) {
265 final DisplayContent dc = mDisplayContents.valueAt(i);
266 output.addAll(dc.getWindowList());
267 }
268 }
269
270 void getWindows(WindowList output, boolean visibleOnly, boolean appsOnly) {
271 final int numDisplays = mDisplayContents.size();
272 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
273 final WindowList windowList = mDisplayContents.valueAt(displayNdx).getWindowList();
274 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
275 final WindowState w = windowList.get(winNdx);
276 if ((!visibleOnly || w.mWinAnimator.getShown())
277 && (!appsOnly || w.mAppToken != null)) {
278 output.add(w);
279 }
280 }
281 }
282 }
283
284 void getWindowsByName(WindowList output, String name) {
285 int objectId = 0;
286 // See if this is an object ID.
287 try {
288 objectId = Integer.parseInt(name, 16);
289 name = null;
290 } catch (RuntimeException e) {
291 }
292 final int numDisplays = mDisplayContents.size();
293 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
294 final WindowList windowList = mDisplayContents.valueAt(displayNdx).getWindowList();
295 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
296 final WindowState w = windowList.get(winNdx);
297 if (name != null) {
298 if (w.mAttrs.getTitle().toString().contains(name)) {
299 output.add(w);
300 }
301 } else if (System.identityHashCode(w) == objectId) {
302 output.add(w);
303 }
304 }
305 }
306 }
307
308 WindowState findWindow(int hashCode) {
309 final int numDisplays = mDisplayContents.size();
310 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
311 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
312 final int numWindows = windows.size();
313 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
314 final WindowState w = windows.get(winNdx);
315 if (System.identityHashCode(w) == hashCode) {
316 return w;
317 }
318 }
319 }
320
321 return null;
322 }
323
324 // TODO: Users would have their own window containers under the display container?
325 void switchUser() {
326 final int count = mDisplayContents.size();
327 for (int i = 0; i < count; ++i) {
328 final DisplayContent dc = mDisplayContents.valueAt(i);
329 dc.switchUser();
330 }
331 }
332
333 int[] onConfigurationChanged(Configuration config) {
334 prepareFreezingTaskBounds();
335 mService.mGlobalConfiguration = new Configuration(config);
336
337 mService.mPolicy.onConfigurationChanged();
338
339 mChangedStackList.clear();
340
341 final int numDisplays = mDisplayContents.size();
342 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
343 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
344 displayContent.onConfigurationChanged(mChangedStackList);
345 }
346
347 return mChangedStackList.isEmpty() ? null : ArrayUtils.convertToIntArray(mChangedStackList);
348 }
349
350 private void prepareFreezingTaskBounds() {
351 for (int i = mDisplayContents.size() - 1; i >= 0; i--) {
352 mDisplayContents.valueAt(i).prepareFreezingTaskBounds();
353 }
354 }
355
356 void setSecureSurfaceState(int userId, boolean disabled) {
357 for (int i = mDisplayContents.size() - 1; i >= 0; --i) {
358 final WindowList windows = mDisplayContents.valueAt(i).getWindowList();
359 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
360 final WindowState win = windows.get(winNdx);
361 if (win.mHasSurface && userId == UserHandle.getUserId(win.mOwnerUid)) {
362 win.mWinAnimator.setSecureLocked(disabled);
363 }
364 }
365 }
366 }
367
368 void updateAppOpsState() {
369 final int count = mDisplayContents.size();
370 for (int i = 0; i < count; ++i) {
371 final WindowList windows = mDisplayContents.valueAt(i).getWindowList();
372 final int numWindows = windows.size();
373 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
374 final WindowState win = windows.get(winNdx);
375 if (win.mAppOp == AppOpsManager.OP_NONE) {
376 continue;
377 }
378 final int mode = mService.mAppOps.checkOpNoThrow(win.mAppOp, win.getOwningUid(),
379 win.getOwningPackage());
380 win.setAppOpVisibilityLw(mode == AppOpsManager.MODE_ALLOWED ||
381 mode == AppOpsManager.MODE_DEFAULT);
382 }
383 }
384 }
385
386 boolean canShowStrictModeViolation(int pid) {
387 final int count = mDisplayContents.size();
388 for (int i = 0; i < count; ++i) {
389 final WindowList windows = mDisplayContents.valueAt(i).getWindowList();
390 final int numWindows = windows.size();
391 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
392 final WindowState ws = windows.get(winNdx);
393 if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
394 return true;
395 }
396 }
397 }
398 return false;
399 }
400
401 void closeSystemDialogs(String reason) {
402 final int count = mDisplayContents.size();
403 for (int i = 0; i < count; ++i) {
404 final WindowList windows = mDisplayContents.valueAt(i).getWindowList();
405 final int numWindows = windows.size();
406 for (int j = 0; j < numWindows; ++j) {
407 final WindowState w = windows.get(j);
408 if (w.mHasSurface) {
409 try {
410 w.mClient.closeSystemDialogs(reason);
411 } catch (RemoteException e) {
412 }
413 }
414 }
415 }
416 }
417
418 void removeReplacedWindows() {
419 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION removeReplacedWindows");
420 mService.openSurfaceTransaction();
421 try {
422 for (int i = mDisplayContents.size() - 1; i >= 0; i--) {
423 DisplayContent dc = mDisplayContents.valueAt(i);
424 final WindowList windows = dc.getWindowList();
425 for (int j = windows.size() - 1; j >= 0; j--) {
426 final WindowState win = windows.get(j);
427 final AppWindowToken aToken = win.mAppToken;
428 if (aToken != null) {
429 aToken.removeReplacedWindowIfNeeded(win);
430 }
431 }
432 }
433 } finally {
434 mService.closeSurfaceTransaction();
435 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION removeReplacedWindows");
436 }
437 }
438
439 boolean hasPendingLayoutChanges(WindowAnimator animator) {
440 boolean hasChanges = false;
441
442 final int count = mDisplayContents.size();
443 for (int i = 0; i < count; ++i) {
444 final DisplayContent dc = mDisplayContents.valueAt(i);
445 final int pendingChanges = animator.getPendingLayoutChanges(dc.getDisplayId());
446 if ((pendingChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
447 animator.mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING;
448 }
449 if (pendingChanges != 0) {
450 hasChanges = true;
451 }
452 }
453
454 return hasChanges;
455 }
456
457 void updateInputWindows(InputMonitor inputMonitor, WindowState inputFocus, boolean inDrag) {
458 boolean addInputConsumerHandle = mService.mInputConsumer != null;
459 boolean addWallpaperInputConsumerHandle = mService.mWallpaperInputConsumer != null;
460 final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
461 boolean disableWallpaperTouchEvents = false;
462
463 final int count = mDisplayContents.size();
464 for (int i = 0; i < count; ++i) {
465 final DisplayContent dc = mDisplayContents.valueAt(i);
466 final WindowList windows = dc.getWindowList();
467 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
468 final WindowState child = windows.get(winNdx);
469 final InputChannel inputChannel = child.mInputChannel;
470 final InputWindowHandle inputWindowHandle = child.mInputWindowHandle;
471 if (inputChannel == null || inputWindowHandle == null || child.mRemoved
472 || child.isAdjustedForMinimizedDock()) {
473 // Skip this window because it cannot possibly receive input.
474 continue;
475 }
476 if (addInputConsumerHandle
477 && inputWindowHandle.layer <= mService.mInputConsumer.mWindowHandle.layer) {
478 inputMonitor.addInputWindowHandle(mService.mInputConsumer.mWindowHandle);
479 addInputConsumerHandle = false;
480 }
481
482 if (addWallpaperInputConsumerHandle) {
483 if (child.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER &&
484 child.isVisibleLw()) {
485 // Add the wallpaper input consumer above the first visible wallpaper.
486 inputMonitor.addInputWindowHandle(
487 mService.mWallpaperInputConsumer.mWindowHandle);
488 addWallpaperInputConsumerHandle = false;
489 }
490 }
491
492 final int flags = child.mAttrs.flags;
493 final int privateFlags = child.mAttrs.privateFlags;
494 final int type = child.mAttrs.type;
495
496 final boolean hasFocus = child == inputFocus;
497 final boolean isVisible = child.isVisibleLw();
498 if ((privateFlags
499 & WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS)
500 != 0) {
501 disableWallpaperTouchEvents = true;
502 }
503 final boolean hasWallpaper = wallpaperController.isWallpaperTarget(child)
504 && (privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD) == 0
505 && !disableWallpaperTouchEvents;
506 final boolean onDefaultDisplay = (child.getDisplayId() == Display.DEFAULT_DISPLAY);
507
508 // If there's a drag in progress and 'child' is a potential drop target,
509 // make sure it's been told about the drag
510 if (inDrag && isVisible && onDefaultDisplay) {
511 mService.mDragState.sendDragStartedIfNeededLw(child);
512 }
513
514 inputMonitor.addInputWindowHandle(
515 inputWindowHandle, child, flags, type, isVisible, hasFocus, hasWallpaper);
516 }
517 }
518
519 if (addWallpaperInputConsumerHandle) {
520 // No visible wallpaper found, add the wallpaper input consumer at the end.
521 inputMonitor.addInputWindowHandle(mService.mWallpaperInputConsumer.mWindowHandle);
522 }
523 }
524
525 boolean reclaimSomeSurfaceMemory(WindowStateAnimator winAnimator, String operation,
526 boolean secure) {
527 final WindowSurfaceController surfaceController = winAnimator.mSurfaceController;
528 boolean leakedSurface = false;
529 boolean killedApps = false;
530
531 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
532 winAnimator.mSession.mPid, operation);
533
534 final long callingIdentity = Binder.clearCallingIdentity();
535 try {
536 // There was some problem... first, do a sanity check of the window list to make sure
537 // we haven't left any dangling surfaces around.
538
539 Slog.i(TAG_WM, "Out of memory for surface! Looking for leaks...");
540 final int numDisplays = mDisplayContents.size();
541 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
542 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
543 final int numWindows = windows.size();
544 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
545 final WindowState ws = windows.get(winNdx);
546 final WindowStateAnimator wsa = ws.mWinAnimator;
547 if (wsa.mSurfaceController == null) {
548 continue;
549 }
550 if (!mService.mSessions.contains(wsa.mSession)) {
551 Slog.w(TAG_WM, "LEAKED SURFACE (session doesn't exist): "
552 + ws + " surface=" + wsa.mSurfaceController
553 + " token=" + ws.mToken
554 + " pid=" + ws.mSession.mPid
555 + " uid=" + ws.mSession.mUid);
556 wsa.destroySurface();
557 mService.mForceRemoves.add(ws);
558 leakedSurface = true;
559 } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
560 Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): "
561 + ws + " surface=" + wsa.mSurfaceController
562 + " token=" + ws.mAppToken
563 + " saved=" + ws.hasSavedSurface());
564 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", false);
565 wsa.destroySurface();
566 leakedSurface = true;
567 }
568 }
569 }
570
571 if (!leakedSurface) {
572 Slog.w(TAG_WM, "No leaked surfaces; killing applications!");
573 SparseIntArray pidCandidates = new SparseIntArray();
574 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
575 final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
576 final int numWindows = windows.size();
577 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
578 final WindowState ws = windows.get(winNdx);
579 if (mService.mForceRemoves.contains(ws)) {
580 continue;
581 }
582 WindowStateAnimator wsa = ws.mWinAnimator;
583 if (wsa.mSurfaceController != null) {
584 pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
585 }
586 }
587 if (pidCandidates.size() > 0) {
588 int[] pids = new int[pidCandidates.size()];
589 for (int i = 0; i < pids.length; i++) {
590 pids[i] = pidCandidates.keyAt(i);
591 }
592 try {
593 if (mService.mActivityManager.killPids(pids, "Free memory", secure)) {
594 killedApps = true;
595 }
596 } catch (RemoteException e) {
597 }
598 }
599 }
600 }
601
602 if (leakedSurface || killedApps) {
603 // We managed to reclaim some memory, so get rid of the trouble surface and ask the
604 // app to request another one.
605 Slog.w(TAG_WM,
606 "Looks like we have reclaimed some memory, clearing surface for retry.");
607 if (surfaceController != null) {
608 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
609 "RECOVER DESTROY", false);
610 winAnimator.destroySurface();
611 mService.scheduleRemoveStartingWindowLocked(winAnimator.mWin.mAppToken);
612 }
613
614 try {
615 winAnimator.mWin.mClient.dispatchGetNewSurface();
616 } catch (RemoteException e) {
617 }
618 }
619 } finally {
620 Binder.restoreCallingIdentity(callingIdentity);
621 }
622
623 return leakedSurface || killedApps;
624 }
625
626 // "Something has changed! Let's make it correct now."
627 // TODO: Super crazy long method that should be broken down...
628 void performSurfacePlacement(boolean recoveringMemory) {
629 if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
630 + Debug.getCallers(3));
631
632 int i;
633 boolean updateInputWindowsNeeded = false;
634
635 if (mService.mFocusMayChange) {
636 mService.mFocusMayChange = false;
637 updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
638 UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
639 }
640
641 // Initialize state of exiting tokens.
642 final int numDisplays = mDisplayContents.size();
643 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
644 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
645 for (i = displayContent.mExitingTokens.size() - 1; i >= 0; i--) {
646 displayContent.mExitingTokens.get(i).hasVisible = false;
647 }
648 }
649
650 for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
651 // Initialize state of exiting applications.
652 final AppTokenList exitingAppTokens =
653 mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
654 for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
655 exitingAppTokens.get(tokenNdx).hasVisible = false;
656 }
657 }
658
659 mHoldScreen = null;
660 mScreenBrightness = -1;
661 mButtonBrightness = -1;
662 mUserActivityTimeout = -1;
663 mObscureApplicationContentOnSecondaryDisplays = false;
664 mSustainedPerformanceModeCurrent = false;
665 mService.mTransactionSequence++;
666
667 // TODO(multi-display):
668 final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
669 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
670 final int defaultDw = defaultInfo.logicalWidth;
671 final int defaultDh = defaultInfo.logicalHeight;
672
673 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
674 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
675 mService.openSurfaceTransaction();
676 try {
677 mService.mRoot.applySurfaceChangesTransaction(recoveringMemory, defaultDw, defaultDh);
678 } catch (RuntimeException e) {
679 Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
680 } finally {
681 mService.closeSurfaceTransaction();
682 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
683 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
684 }
685
686 final WindowList defaultWindows = defaultDisplay.getWindowList();
687 final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked;
688
689 // If we are ready to perform an app transition, check through all of the app tokens to be
690 // shown and see if they are ready to go.
691 if (mService.mAppTransition.isReady()) {
692 defaultDisplay.pendingLayoutChanges |=
693 surfacePlacer.handleAppTransitionReadyLocked(defaultWindows);
694 if (DEBUG_LAYOUT_REPEATS)
695 surfacePlacer.debugLayoutRepeats("after handleAppTransitionReadyLocked",
696 defaultDisplay.pendingLayoutChanges);
697 }
698
699 if (!mService.mAnimator.mAppWindowAnimating && mService.mAppTransition.isRunning()) {
700 // We have finished the animation of an app transition. To do this, we have delayed a
701 // lot of operations like showing and hiding apps, moving apps in Z-order, etc. The app
702 // token list reflects the correct Z-order, but the window list may now be out of sync
703 // with it. So here we will just rebuild the entire app window list. Fun!
704 defaultDisplay.pendingLayoutChanges |=
705 mService.handleAnimatingStoppedAndTransitionLocked();
706 if (DEBUG_LAYOUT_REPEATS)
707 surfacePlacer.debugLayoutRepeats("after handleAnimStopAndXitionLock",
708 defaultDisplay.pendingLayoutChanges);
709 }
710
711 if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
712 && !mService.mAppTransition.isReady()) {
713 // At this point, there was a window with a wallpaper that was force hiding other
714 // windows behind it, but now it is going away. This may be simple -- just animate away
715 // the wallpaper and its window -- or it may be hard -- the wallpaper now needs to be
716 // shown behind something that was hidden.
717 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
718 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
719 "after animateAwayWallpaperLocked", defaultDisplay.pendingLayoutChanges);
720 }
721 mWallpaperForceHidingChanged = false;
722
723 if (mWallpaperMayChange) {
724 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Wallpaper may change! Adjusting");
725 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
726 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("WallpaperMayChange",
727 defaultDisplay.pendingLayoutChanges);
728 }
729
730 if (mService.mFocusMayChange) {
731 mService.mFocusMayChange = false;
732 if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
733 false /*updateInputWindows*/)) {
734 updateInputWindowsNeeded = true;
735 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
736 }
737 }
738
739 if (layoutNeeded()) {
740 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
741 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("mLayoutNeeded",
742 defaultDisplay.pendingLayoutChanges);
743 }
744
745 for (i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
746 WindowState win = mService.mResizingWindows.get(i);
747 if (win.mAppFreezing) {
748 // Don't remove this window until rotation has completed.
749 continue;
750 }
751 // Discard the saved surface if window size is changed, it can't be reused.
752 if (win.mAppToken != null) {
753 win.mAppToken.destroySavedSurfaces();
754 }
755 win.reportResized();
756 mService.mResizingWindows.remove(i);
757 }
758
759 if (DEBUG_ORIENTATION && mService.mDisplayFrozen) Slog.v(TAG,
760 "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
761 if (mOrientationChangeComplete) {
762 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
763 mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
764 mService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
765 mService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
766 }
767 mService.stopFreezingDisplayLocked();
768 }
769
770 // Destroy the surface of any windows that are no longer visible.
771 boolean wallpaperDestroyed = false;
772 i = mService.mDestroySurface.size();
773 if (i > 0) {
774 do {
775 i--;
776 WindowState win = mService.mDestroySurface.get(i);
777 win.mDestroying = false;
778 if (mService.mInputMethodWindow == win) {
779 mService.mInputMethodWindow = null;
780 }
781 if (mService.mWallpaperControllerLocked.isWallpaperTarget(win)) {
782 wallpaperDestroyed = true;
783 }
784 win.destroyOrSaveSurface();
785 } while (i > 0);
786 mService.mDestroySurface.clear();
787 }
788
789 // Time to remove any exiting tokens?
790 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
791 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
792 ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
793 for (i = exitingTokens.size() - 1; i >= 0; i--) {
794 WindowToken token = exitingTokens.get(i);
795 if (!token.hasVisible) {
796 exitingTokens.remove(i);
797 if (token.windowType == TYPE_WALLPAPER) {
798 mService.mWallpaperControllerLocked.removeWallpaperToken(token);
799 }
800 }
801 }
802 }
803
804 // Time to remove any exiting applications?
805 for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
806 // Initialize state of exiting applications.
807 final AppTokenList exitingAppTokens =
808 mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
809 for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
810 final AppWindowToken token = exitingAppTokens.get(i);
811 if (!token.hasVisible && !mService.mClosingApps.contains(token) &&
812 (!token.mIsExiting || token.isEmpty())) {
813 // Make sure there is no animation running on this token, so any windows
814 // associated with it will be removed as soon as their animations are complete
815 token.mAppAnimator.clearAnimation();
816 token.mAppAnimator.animating = false;
817 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
818 "performLayout: App token exiting now removed" + token);
819 token.removeIfPossible();
820 }
821 }
822 }
823
824 if (wallpaperDestroyed) {
825 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
826 defaultDisplay.layoutNeeded = true;
827 }
828
829 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
830 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
831 if (displayContent.pendingLayoutChanges != 0) {
832 displayContent.layoutNeeded = true;
833 }
834 }
835
836 // Finally update all input windows now that the window changes have stabilized.
837 mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
838
839 mService.setHoldScreenLocked(mHoldScreen);
840 if (!mService.mDisplayFrozen) {
841 if (mScreenBrightness < 0 || mScreenBrightness > 1.0f) {
842 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
843 } else {
844 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
845 toBrightnessOverride(mScreenBrightness));
846 }
847 if (mButtonBrightness < 0 || mButtonBrightness > 1.0f) {
848 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
849 } else {
850 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
851 toBrightnessOverride(mButtonBrightness));
852 }
853 mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
854 mUserActivityTimeout);
855 }
856
857 if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) {
858 mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent;
859 mService.mPowerManagerInternal.powerHint(
860 mService.mPowerManagerInternal.POWER_HINT_SUSTAINED_PERFORMANCE_MODE,
861 (mSustainedPerformanceModeEnabled ? 1 : 0));
862 }
863
864 if (mService.mTurnOnScreen) {
865 if (mService.mAllowTheaterModeWakeFromLayout
866 || Settings.Global.getInt(mService.mContext.getContentResolver(),
867 Settings.Global.THEATER_MODE_ON, 0) == 0) {
868 if (DEBUG_VISIBILITY || DEBUG_POWER) {
869 Slog.v(TAG, "Turning screen on after layout!");
870 }
871 mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
872 "android.server.wm:TURN_ON");
873 }
874 mService.mTurnOnScreen = false;
875 }
876
877 if (mUpdateRotation) {
878 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
879 if (mService.updateRotationUncheckedLocked(false)) {
880 mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
881 } else {
882 mUpdateRotation = false;
883 }
884 }
885
886 if (mService.mWaitingForDrawnCallback != null ||
887 (mOrientationChangeComplete && !defaultDisplay.layoutNeeded &&
888 !mUpdateRotation)) {
889 mService.checkDrawnWindowsLocked();
890 }
891
892 final int N = mService.mPendingRemove.size();
893 if (N > 0) {
894 if (mService.mPendingRemoveTmp.length < N) {
895 mService.mPendingRemoveTmp = new WindowState[N+10];
896 }
897 mService.mPendingRemove.toArray(mService.mPendingRemoveTmp);
898 mService.mPendingRemove.clear();
899 DisplayContentList displayList = new DisplayContentList();
900 for (i = 0; i < N; i++) {
901 final WindowState w = mService.mPendingRemoveTmp[i];
902 w.removeImmediately();
903 final DisplayContent displayContent = w.getDisplayContent();
904 if (displayContent != null && !displayList.contains(displayContent)) {
905 displayList.add(displayContent);
906 }
907 }
908
909 for (DisplayContent displayContent : displayList) {
910 mService.mLayersController.assignLayersLocked(displayContent.getWindowList());
911 displayContent.layoutNeeded = true;
912 }
913 }
914
915 // Remove all deferred displays stacks, tasks, and activities.
916 for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
917 mDisplayContents.valueAt(displayNdx).checkCompleteDeferredRemoval();
918 }
919
920 if (updateInputWindowsNeeded) {
921 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
922 }
923 mService.setFocusTaskRegionLocked();
924
925 // Check to see if we are now in a state where the screen should
926 // be enabled, because the window obscured flags have changed.
927 mService.enableScreenIfNeededLocked();
928
929 mService.scheduleAnimationLocked();
930 mService.mWindowPlacerLocked.destroyPendingSurfaces();
931
932 if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
933 "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
934 }
935
936 // TODO: Super crazy long method that should be broken down...
937 void applySurfaceChangesTransaction(boolean recoveringMemory, int defaultDw, int defaultDh) {
938 mHoldScreenWindow = null;
939 mObsuringWindow = null;
940
941 if (mService.mWatermark != null) {
942 mService.mWatermark.positionSurface(defaultDw, defaultDh);
943 }
944 if (mService.mStrictModeFlash != null) {
945 mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
946 }
947 if (mService.mCircularDisplayMask != null) {
948 mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh, mService.mRotation);
949 }
950 if (mService.mEmulatorDisplayOverlay != null) {
951 mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
952 mService.mRotation);
953 }
954
955 boolean focusDisplayed = false;
956
957 final int count = mDisplayContents.size();
958 for (int j = 0; j < count; ++j) {
959 final DisplayContent dc = mDisplayContents.valueAt(j);
960 boolean updateAllDrawn = false;
961 WindowList windows = dc.getWindowList();
962 DisplayInfo displayInfo = dc.getDisplayInfo();
963 final int displayId = dc.getDisplayId();
964 final int dw = displayInfo.logicalWidth;
965 final int dh = displayInfo.logicalHeight;
966 final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
967 final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked;
968
969 // Reset for each display.
970 mDisplayHasContent = false;
971 mPreferredRefreshRate = 0;
972 mPreferredModeId = 0;
973
974 int repeats = 0;
975 do {
976 repeats++;
977 if (repeats > 6) {
978 Slog.w(TAG, "Animation repeat aborted after too many iterations");
979 dc.layoutNeeded = false;
980 break;
981 }
982
983 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
984 "On entry to LockedInner", dc.pendingLayoutChanges);
985
986 if ((dc.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0
987 && mService.mWallpaperControllerLocked.adjustWallpaperWindows()) {
988 mService.mLayersController.assignLayersLocked(windows);
989 dc.layoutNeeded = true;
990 }
991
992 if (isDefaultDisplay
993 && (dc.pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
994 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
995 if (mService.updateOrientationFromAppTokensLocked(true)) {
996 dc.layoutNeeded = true;
997 mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
998 }
999 }
1000
1001 if ((dc.pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
1002 dc.layoutNeeded = true;
1003 }
1004
1005 // FIRST LOOP: Perform a layout, if needed.
1006 if (repeats < LAYOUT_REPEAT_THRESHOLD) {
1007 surfacePlacer.performLayoutLockedInner(dc, repeats == 1,
1008 false /* updateInputWindows */);
1009 } else {
1010 Slog.w(TAG, "Layout repeat skipped after too many iterations");
1011 }
1012
1013 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
1014 // it is animating.
1015 dc.pendingLayoutChanges = 0;
1016
1017 if (isDefaultDisplay) {
1018 mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
1019 for (int i = windows.size() - 1; i >= 0; i--) {
1020 WindowState w = windows.get(i);
1021 if (w.mHasSurface) {
1022 mService.mPolicy.applyPostLayoutPolicyLw(
1023 w, w.mAttrs, w.getParentWindow());
1024 }
1025 }
1026 dc.pendingLayoutChanges |=
1027 mService.mPolicy.finishPostLayoutPolicyLw();
1028 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
1029 "after finishPostLayoutPolicyLw", dc.pendingLayoutChanges);
1030 }
1031 } while (dc.pendingLayoutChanges != 0);
1032
1033 mObscured = false;
1034 mSyswin = false;
1035 dc.resetDimming();
1036
1037 // Only used if default window
1038 final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
1039
1040 for (int i = windows.size() - 1; i >= 0; i--) {
1041 WindowState w = windows.get(i);
1042 final Task task = w.getTask();
1043 final boolean obscuredChanged = w.mObscured != mObscured;
1044
1045 // Update effect.
1046 w.mObscured = mObscured;
1047 if (!mObscured) {
1048 handleNotObscuredLocked(w, displayInfo);
1049 }
1050
1051 w.applyDimLayerIfNeeded();
1052
1053 if (isDefaultDisplay && obscuredChanged && w.isVisibleLw()
1054 && mService.mWallpaperControllerLocked.isWallpaperTarget(w)) {
1055 // This is the wallpaper target and its obscured state changed... make sure the
1056 // current wallaper's visibility has been updated accordingly.
1057 mService.mWallpaperControllerLocked.updateWallpaperVisibility();
1058 }
1059
1060 final WindowStateAnimator winAnimator = w.mWinAnimator;
1061
1062 // If the window has moved due to its containing content frame changing, then
1063 // notify the listeners and optionally animate it. Simply checking a change of
1064 // position is not enough, because being move due to dock divider is not a trigger
1065 // for animation.
1066 if (w.hasMoved()) {
1067 // Frame has moved, containing content frame has also moved, and we're not
1068 // currently animating... let's do something.
1069 final int left = w.mFrame.left;
1070 final int top = w.mFrame.top;
1071 final boolean adjustedForMinimizedDockOrIme = task != null
1072 && (task.mStack.isAdjustedForMinimizedDockedStack()
1073 || task.mStack.isAdjustedForIme());
1074 if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
1075 && !w.isDragResizing() && !adjustedForMinimizedDockOrIme
1076 && (task == null || w.getTask().mStack.hasMovementAnimations())
1077 && !w.mWinAnimator.mLastHidden) {
1078 winAnimator.setMoveAnimation(left, top);
1079 }
1080
1081 //TODO (multidisplay): Accessibility supported only for the default display.
1082 if (mService.mAccessibilityController != null
1083 && displayId == Display.DEFAULT_DISPLAY) {
1084 mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
1085 }
1086
1087 try {
1088 w.mClient.moved(left, top);
1089 } catch (RemoteException e) {
1090 }
1091 w.mMovedByResize = false;
1092 }
1093
1094 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
1095 w.mContentChanged = false;
1096
1097 // Moved from updateWindowsAndWallpaperLocked().
1098 if (w.mHasSurface) {
1099 // Take care of the window being ready to display.
1100 final boolean committed = winAnimator.commitFinishDrawingLocked();
1101 if (isDefaultDisplay && committed) {
1102 if (w.mAttrs.type == TYPE_DREAM) {
1103 // HACK: When a dream is shown, it may at that point hide the lock
1104 // screen. So we need to redo the layout to let the phone window manager
1105 // make this happen.
1106 dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
1107 if (DEBUG_LAYOUT_REPEATS) {
1108 surfacePlacer.debugLayoutRepeats(
1109 "dream and commitFinishDrawingLocked true",
1110 dc.pendingLayoutChanges);
1111 }
1112 }
1113 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
1114 if (DEBUG_WALLPAPER_LIGHT)
1115 Slog.v(TAG, "First draw done in potential wallpaper target " + w);
1116 mWallpaperMayChange = true;
1117 dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
1118 if (DEBUG_LAYOUT_REPEATS) {
1119 surfacePlacer.debugLayoutRepeats(
1120 "wallpaper and commitFinishDrawingLocked true",
1121 dc.pendingLayoutChanges);
1122 }
1123 }
1124 }
1125 if (!winAnimator.isAnimationStarting() && !winAnimator.isWaitingForOpening()) {
1126 // Updates the shown frame before we set up the surface. This is needed
1127 // because the resizing could change the top-left position (in addition to
1128 // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
1129 // position the surface.
1130 //
1131 // If an animation is being started, we can't call this method because the
1132 // animation hasn't processed its initial transformation yet, but in general
1133 // we do want to update the position if the window is animating.
1134 winAnimator.computeShownFrameLocked();
1135 }
1136 winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
1137 }
1138
1139 final AppWindowToken atoken = w.mAppToken;
1140 if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) {
1141 Slog.d(TAG, "updateWindows: starting " + w
1142 + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
1143 + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
1144 }
1145 if (atoken != null && (!atoken.allDrawn || !atoken.allDrawnExcludingSaved
1146 || atoken.mAppAnimator.freezingScreen)) {
1147 if (atoken.lastTransactionSequence != mService.mTransactionSequence) {
1148 atoken.lastTransactionSequence = mService.mTransactionSequence;
1149 atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
1150 atoken.numInterestingWindowsExcludingSaved = 0;
1151 atoken.numDrawnWindowsExcludingSaved = 0;
1152 atoken.startingDisplayed = false;
1153 }
1154 if (!atoken.allDrawn && w.mightAffectAllDrawn(false /* visibleOnly */)) {
1155 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
1156 Slog.v(TAG, "Eval win " + w + ": isDrawn="
1157 + w.isDrawnLw()
1158 + ", isAnimationSet=" + winAnimator.isAnimationSet());
1159 if (!w.isDrawnLw()) {
1160 Slog.v(TAG, "Not displayed: s="
1161 + winAnimator.mSurfaceController
1162 + " pv=" + w.mPolicyVisibility
1163 + " mDrawState=" + winAnimator.drawStateToString()
1164 + " ph=" + w.isParentWindowHidden()
1165 + " th=" + atoken.hiddenRequested
1166 + " a=" + winAnimator.mAnimating);
1167 }
1168 }
1169 if (w != atoken.startingWindow) {
1170 if (w.isInteresting()) {
1171 atoken.numInterestingWindows++;
1172 if (w.isDrawnLw()) {
1173 atoken.numDrawnWindows++;
1174 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
1175 Slog.v(TAG, "tokenMayBeDrawn: " + atoken
1176 + " w=" + w + " numInteresting="
1177 + atoken.numInterestingWindows
1178 + " freezingScreen="
1179 + atoken.mAppAnimator.freezingScreen
1180 + " mAppFreezing=" + w.mAppFreezing);
1181 updateAllDrawn = true;
1182 }
1183 }
1184 } else if (w.isDrawnLw()) {
1185 mService.mH.sendEmptyMessage(NOTIFY_STARTING_WINDOW_DRAWN);
1186 atoken.startingDisplayed = true;
1187 }
1188 }
1189 if (!atoken.allDrawnExcludingSaved
1190 && w.mightAffectAllDrawn(true /* visibleOnly */)) {
1191 if (w != atoken.startingWindow && w.isInteresting()) {
1192 atoken.numInterestingWindowsExcludingSaved++;
1193 if (w.isDrawnLw() && !w.isAnimatingWithSavedSurface()) {
1194 atoken.numDrawnWindowsExcludingSaved++;
1195 if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
1196 Slog.v(TAG, "tokenMayBeDrawnExcludingSaved: " + atoken
1197 + " w=" + w + " numInteresting="
1198 + atoken.numInterestingWindowsExcludingSaved
1199 + " freezingScreen="
1200 + atoken.mAppAnimator.freezingScreen
1201 + " mAppFreezing=" + w.mAppFreezing);
1202 updateAllDrawn = true;
1203 }
1204 }
1205 }
1206 }
1207
1208 if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
1209 && w.isDisplayedLw()) {
1210 focusDisplayed = true;
1211 }
1212
1213 mService.updateResizingWindows(w);
1214 }
1215
1216 mService.mDisplayManagerInternal.setDisplayProperties(displayId,
1217 mDisplayHasContent,
1218 mPreferredRefreshRate,
1219 mPreferredModeId,
1220 true /* inTraversal, must call performTraversalInTrans... below */);
1221
1222 dc.stopDimmingIfNeeded();
1223
1224 if (updateAllDrawn) {
1225 // See if any windows have been drawn, so they (and others associated with them)
1226 // can now be shown.
1227 dc.updateAllDrawn();
1228 }
1229 }
1230
1231 if (focusDisplayed) {
1232 mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
1233 }
1234
1235 // Give the display manager a chance to adjust properties
1236 // like display rotation if it needs to.
1237 mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
1238 }
1239
1240 /**
1241 * @param w WindowState this method is applied to.
1242 * @param dispInfo info of the display that the window's obscuring state is checked against.
1243 */
1244 private void handleNotObscuredLocked(final WindowState w, final DisplayInfo dispInfo) {
1245 final WindowManager.LayoutParams attrs = w.mAttrs;
1246 final int attrFlags = attrs.flags;
1247 final boolean canBeSeen = w.isDisplayedLw();
1248 final int privateflags = attrs.privateFlags;
1249
1250 if (canBeSeen && w.isObscuringFullscreen(dispInfo)) {
1251 // This window completely covers everything behind it,
1252 // so we want to leave all of them as undimmed (for
1253 // performance reasons).
1254 if (!mObscured) {
1255 mObsuringWindow = w;
1256 }
1257
1258 mObscured = true;
1259 }
1260
1261 if (w.mHasSurface && canBeSeen) {
1262 if ((attrFlags & FLAG_KEEP_SCREEN_ON) != 0) {
1263 mHoldScreen = w.mSession;
1264 mHoldScreenWindow = w;
1265 } else if (DEBUG_KEEP_SCREEN_ON && w == mService.mLastWakeLockHoldingWindow) {
1266 Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w + " was holding "
1267 + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by"
1268 + Debug.getCallers(10));
1269 }
1270 if (!mSyswin && w.mAttrs.screenBrightness >= 0 && mScreenBrightness < 0) {
1271 mScreenBrightness = w.mAttrs.screenBrightness;
1272 }
1273 if (!mSyswin && w.mAttrs.buttonBrightness >= 0 && mButtonBrightness < 0) {
1274 mButtonBrightness = w.mAttrs.buttonBrightness;
1275 }
1276 if (!mSyswin && w.mAttrs.userActivityTimeout >= 0 && mUserActivityTimeout < 0) {
1277 mUserActivityTimeout = w.mAttrs.userActivityTimeout;
1278 }
1279
1280 final int type = attrs.type;
1281 if (type == TYPE_SYSTEM_DIALOG || type == TYPE_SYSTEM_ERROR
1282 || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
1283 mSyswin = true;
1284 }
1285
1286 // This function assumes that the contents of the default display are processed first
1287 // before secondary displays.
1288 final DisplayContent displayContent = w.getDisplayContent();
1289 if (displayContent != null && displayContent.isDefaultDisplay) {
1290 // While a dream or keyguard is showing, obscure ordinary application content on
1291 // secondary displays (by forcibly enabling mirroring unless there is other content
1292 // we want to show) but still allow opaque keyguard dialogs to be shown.
1293 if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
1294 mObscureApplicationContentOnSecondaryDisplays = true;
1295 }
1296 mDisplayHasContent = true;
1297 } else if (displayContent != null &&
1298 (!mObscureApplicationContentOnSecondaryDisplays
1299 || (mObscured && type == TYPE_KEYGUARD_DIALOG))) {
1300 // Allow full screen keyguard presentation dialogs to be seen.
1301 mDisplayHasContent = true;
1302 }
1303 if (mPreferredRefreshRate == 0 && w.mAttrs.preferredRefreshRate != 0) {
1304 mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
1305 }
1306 if (mPreferredModeId == 0 && w.mAttrs.preferredDisplayModeId != 0) {
1307 mPreferredModeId = w.mAttrs.preferredDisplayModeId;
1308 }
1309 if ((privateflags & PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE) != 0) {
1310 mSustainedPerformanceModeCurrent = true;
1311 }
1312 }
1313 }
1314
1315 boolean copyAnimToLayoutParams() {
1316 boolean doRequest = false;
1317
1318 final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
1319 if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
1320 mUpdateRotation = true;
1321 doRequest = true;
1322 }
1323 if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
1324 mWallpaperMayChange = true;
1325 doRequest = true;
1326 }
1327 if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
1328 mWallpaperForceHidingChanged = true;
1329 doRequest = true;
1330 }
1331 if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
1332 mOrientationChangeComplete = false;
1333 } else {
1334 mOrientationChangeComplete = true;
1335 mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
1336 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
1337 doRequest = true;
1338 }
1339 }
1340 if ((bulkUpdateParams & SET_TURN_ON_SCREEN) != 0) {
1341 mService.mTurnOnScreen = true;
1342 }
1343 if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
1344 mWallpaperActionPending = true;
1345 }
1346
1347 return doRequest;
1348 }
1349
1350 private static int toBrightnessOverride(float value) {
1351 return (int)(value * PowerManager.BRIGHTNESS_ON);
1352 }
1353
1354 void enableSurfaceTrace(ParcelFileDescriptor pfd) {
1355 final FileDescriptor fd = pfd.getFileDescriptor();
1356 if (mSurfaceTraceEnabled) {
1357 disableSurfaceTrace();
1358 }
1359 mSurfaceTraceEnabled = true;
1360 mRemoteEventTrace = new RemoteEventTrace(mService, fd);
1361 mSurfaceTraceFd = pfd;
1362 for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
1363 DisplayContent dc = mDisplayContents.valueAt(displayNdx);
1364 dc.enableSurfaceTrace(fd);
1365 }
1366 }
1367
1368 void disableSurfaceTrace() {
1369 mSurfaceTraceEnabled = false;
1370 mRemoteEventTrace = null;
1371 mSurfaceTraceFd = null;
1372 for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
1373 DisplayContent dc = mDisplayContents.valueAt(displayNdx);
1374 dc.disableSurfaceTrace();
1375 }
1376 }
1377
1378 void dumpDisplayContents(PrintWriter pw) {
1379 pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)");
1380 if (mService.mDisplayReady) {
1381 final int count = mDisplayContents.size();
1382 for (int i = 0; i < count; ++i) {
1383 final DisplayContent displayContent = mDisplayContents.valueAt(i);
1384 displayContent.dump(" ", pw);
1385 }
1386 } else {
1387 pw.println(" NO DISPLAY");
1388 }
1389 }
1390
1391 void dumpLayoutNeededDisplayIds(PrintWriter pw) {
1392 if (!layoutNeeded()) {
1393 return;
1394 }
1395 pw.print(" layoutNeeded on displays=");
1396 final int count = mDisplayContents.size();
1397 for (int displayNdx = 0; displayNdx < count; ++displayNdx) {
1398 final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
1399 if (displayContent.layoutNeeded) {
1400 pw.print(displayContent.getDisplayId());
1401 }
1402 }
1403 pw.println();
1404 }
1405
1406 void dumpWindowsNoHeader(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows) {
1407 final int numDisplays = mDisplayContents.size();
1408 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
1409 final WindowList windowList = mDisplayContents.valueAt(displayNdx).getWindowList();
1410 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
1411 final WindowState w = windowList.get(winNdx);
1412 if (windows == null || windows.contains(w)) {
1413 pw.println(" Window #" + winNdx + " " + w + ":");
1414 w.dump(pw, " ", dumpAll || windows != null);
1415 }
1416 }
1417 }
1418 }
1419}