OSDN Git Service

Merge "Remove RemoteSurfaceTrace functionality."
[android-x86/frameworks-base.git] / services / core / java / com / android / server / wm / RootWindowContainer.java
1 /*
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
17 package com.android.server.wm;
18
19 import android.annotation.CallSuper;
20 import android.content.res.Configuration;
21 import android.graphics.Rect;
22 import android.hardware.power.V1_0.PowerHint;
23 import android.os.Binder;
24 import android.os.Debug;
25 import android.os.Handler;
26 import android.os.IBinder;
27 import android.os.Looper;
28 import android.os.Message;
29 import android.os.ParcelFileDescriptor;
30 import android.os.PowerManager;
31 import android.os.RemoteException;
32 import android.os.UserHandle;
33 import android.util.ArraySet;
34 import android.util.EventLog;
35 import android.util.Slog;
36 import android.util.SparseIntArray;
37 import android.util.proto.ProtoOutputStream;
38 import android.view.Display;
39 import android.view.DisplayInfo;
40 import android.view.WindowManager;
41
42 import com.android.internal.util.ArrayUtils;
43 import com.android.server.EventLogTags;
44
45 import java.io.FileDescriptor;
46 import java.io.PrintWriter;
47 import java.util.ArrayList;
48 import java.util.List;
49 import java.util.function.Consumer;
50
51 import static android.view.Display.DEFAULT_DISPLAY;
52 import static android.view.Display.INVALID_DISPLAY;
53 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
54 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
55 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
56 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
57 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
58
59 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
60 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
61 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
62 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
63 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
64 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
65 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
66 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
67 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
68 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
69 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
70 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
71 import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
72 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
73 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
74 import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
75 import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
76 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
77 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
78 import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
79 import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT;
80 import static com.android.server.wm.WindowManagerService.logSurface;
81 import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED;
82 import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
83 import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
84 import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
85 import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE;
86 import static com.android.server.wm.proto.RootWindowContainerProto.DISPLAYS;
87 import static com.android.server.wm.proto.RootWindowContainerProto.WINDOWS;
88 import static com.android.server.wm.proto.RootWindowContainerProto.WINDOW_CONTAINER;
89
90 /** Root {@link WindowContainer} for the device. */
91 class RootWindowContainer extends WindowContainer<DisplayContent> {
92     private static final String TAG = TAG_WITH_CLASS_NAME ? "RootWindowContainer" : TAG_WM;
93
94     private static final int SET_SCREEN_BRIGHTNESS_OVERRIDE = 1;
95     private static final int SET_USER_ACTIVITY_TIMEOUT = 2;
96
97     private boolean mWallpaperForceHidingChanged = false;
98     private Object mLastWindowFreezeSource = null;
99     private Session mHoldScreen = null;
100     private float mScreenBrightness = -1;
101     private long mUserActivityTimeout = -1;
102     private boolean mUpdateRotation = false;
103     // Following variables are for debugging screen wakelock only.
104     // Last window that requires screen wakelock
105     WindowState mHoldScreenWindow = null;
106     // Last window that obscures all windows below
107     WindowState mObscuringWindow = null;
108     // Only set while traversing the default display based on its content.
109     // Affects the behavior of mirroring on secondary displays.
110     private boolean mObscureApplicationContentOnSecondaryDisplays = false;
111
112     private boolean mSustainedPerformanceModeEnabled = false;
113     private boolean mSustainedPerformanceModeCurrent = false;
114
115     boolean mWallpaperMayChange = false;
116     // During an orientation change, we track whether all windows have rendered
117     // at the new orientation, and this will be false from changing orientation until that occurs.
118     // For seamless rotation cases this always stays true, as the windows complete their orientation
119     // changes 1 by 1 without disturbing global state.
120     boolean mOrientationChangeComplete = true;
121     boolean mWallpaperActionPending = false;
122
123     private final ArrayList<TaskStack> mTmpStackList = new ArrayList();
124     private final ArrayList<Integer> mTmpStackIds = new ArrayList<>();
125
126     final WallpaperController mWallpaperController;
127
128     private final Handler mHandler;
129
130     private String mCloseSystemDialogsReason;
131     private final Consumer<WindowState> mCloseSystemDialogsConsumer = w -> {
132         if (w.mHasSurface) {
133             try {
134                 w.mClient.closeSystemDialogs(mCloseSystemDialogsReason);
135             } catch (RemoteException e) {
136             }
137         }
138     };
139
140     private static final Consumer<WindowState> sRemoveReplacedWindowsConsumer = w -> {
141         final AppWindowToken aToken = w.mAppToken;
142         if (aToken != null) {
143             aToken.removeReplacedWindowIfNeeded(w);
144         }
145     };
146
147     RootWindowContainer(WindowManagerService service) {
148         super(service);
149         mHandler = new MyHandler(service.mH.getLooper());
150         mWallpaperController = new WallpaperController(mService);
151     }
152
153     WindowState computeFocusedWindow() {
154         for (int i = mChildren.size() - 1; i >= 0; i--) {
155             final DisplayContent dc = mChildren.get(i);
156             final WindowState win = dc.findFocusedWindow();
157             if (win != null) {
158                 return win;
159             }
160         }
161         return null;
162     }
163
164     /**
165      * Get an array with display ids ordered by focus priority - last items should be given
166      * focus first. Sparse array just maps position to displayId.
167      */
168     void getDisplaysInFocusOrder(SparseIntArray displaysInFocusOrder) {
169         displaysInFocusOrder.clear();
170
171         final int size = mChildren.size();
172         for (int i = 0; i < size; ++i) {
173             final DisplayContent displayContent = mChildren.get(i);
174             if (displayContent.isRemovalDeferred()) {
175                 // Don't report displays that are going to be removed soon.
176                 continue;
177             }
178             displaysInFocusOrder.put(i, displayContent.getDisplayId());
179         }
180     }
181
182     DisplayContent getDisplayContent(int displayId) {
183         for (int i = mChildren.size() - 1; i >= 0; --i) {
184             final DisplayContent current = mChildren.get(i);
185             if (current.getDisplayId() == displayId) {
186                 return current;
187             }
188         }
189         return null;
190     }
191
192     DisplayContent createDisplayContent(final Display display, DisplayWindowController controller) {
193         final int displayId = display.getDisplayId();
194
195         // In select scenarios, it is possible that a DisplayContent will be created on demand
196         // rather than waiting for the controller. In this case, associate the controller and return
197         // the existing display.
198         final DisplayContent existing = getDisplayContent(displayId);
199
200         if (existing != null) {
201             existing.setController(controller);
202             return existing;
203         }
204
205         final DisplayContent dc =
206                 new DisplayContent(display, mService, mWallpaperController, controller);
207
208         if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Adding display=" + display);
209
210         final DisplayInfo displayInfo = dc.getDisplayInfo();
211         final Rect rect = new Rect();
212         mService.mDisplaySettings.getOverscanLocked(displayInfo.name, displayInfo.uniqueId, rect);
213         displayInfo.overscanLeft = rect.left;
214         displayInfo.overscanTop = rect.top;
215         displayInfo.overscanRight = rect.right;
216         displayInfo.overscanBottom = rect.bottom;
217         if (mService.mDisplayManagerInternal != null) {
218             mService.mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
219                     displayId, displayInfo);
220             dc.configureDisplayPolicy();
221
222             // Tap Listeners are supported for:
223             // 1. All physical displays (multi-display).
224             // 2. VirtualDisplays on VR, AA (and everything else).
225             if (mService.canDispatchPointerEvents()) {
226                 if (DEBUG_DISPLAY) {
227                     Slog.d(TAG,
228                             "Registering PointerEventListener for DisplayId: " + displayId);
229                 }
230                 dc.mTapDetector = new TaskTapPointerEventListener(mService, dc);
231                 mService.registerPointerEventListener(dc.mTapDetector);
232                 if (displayId == DEFAULT_DISPLAY) {
233                     mService.registerPointerEventListener(mService.mMousePositionTracker);
234                 }
235             }
236         }
237
238         return dc;
239     }
240
241     boolean isLayoutNeeded() {
242         final int numDisplays = mChildren.size();
243         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
244             final DisplayContent displayContent = mChildren.get(displayNdx);
245             if (displayContent.isLayoutNeeded()) {
246                 return true;
247             }
248         }
249         return false;
250     }
251
252     void getWindowsByName(ArrayList<WindowState> output, String name) {
253         int objectId = 0;
254         // See if this is an object ID.
255         try {
256             objectId = Integer.parseInt(name, 16);
257             name = null;
258         } catch (RuntimeException e) {
259         }
260
261         getWindowsByName(output, name, objectId);
262     }
263
264     private void getWindowsByName(ArrayList<WindowState> output, String name, int objectId) {
265         forAllWindows((w) -> {
266             if (name != null) {
267                 if (w.mAttrs.getTitle().toString().contains(name)) {
268                     output.add(w);
269                 }
270             } else if (System.identityHashCode(w) == objectId) {
271                 output.add(w);
272             }
273         }, true /* traverseTopToBottom */);
274     }
275
276     /**
277      * Returns the app window token for the input binder if it exist in the system.
278      * NOTE: Only one AppWindowToken is allowed to exist in the system for a binder token, since
279      * AppWindowToken represents an activity which can only exist on one display.
280      */
281     AppWindowToken getAppWindowToken(IBinder binder) {
282         for (int i = mChildren.size() - 1; i >= 0; --i) {
283             final DisplayContent dc = mChildren.get(i);
284             final AppWindowToken atoken = dc.getAppWindowToken(binder);
285             if (atoken != null) {
286                 return atoken;
287             }
288         }
289         return null;
290     }
291
292     /** Returns the display object the input window token is currently mapped on. */
293     DisplayContent getWindowTokenDisplay(WindowToken token) {
294         if (token == null) {
295             return null;
296         }
297
298         for (int i = mChildren.size() - 1; i >= 0; --i) {
299             final DisplayContent dc = mChildren.get(i);
300             final WindowToken current = dc.getWindowToken(token.token);
301             if (current == token) {
302                 return dc;
303             }
304         }
305
306         return null;
307     }
308
309     /**
310      * Set new display override config and return array of ids of stacks that were changed during
311      * update. If called for the default display, global configuration will also be updated. Stacks
312      * that are marked for deferred removal are excluded from the returned array.
313      */
314     int[] setDisplayOverrideConfigurationIfNeeded(Configuration newConfiguration, int displayId) {
315         final DisplayContent displayContent = getDisplayContent(displayId);
316         if (displayContent == null) {
317             throw new IllegalArgumentException("Display not found for id: " + displayId);
318         }
319
320         final Configuration currentConfig = displayContent.getOverrideConfiguration();
321         final boolean configChanged = currentConfig.diff(newConfiguration) != 0;
322         if (!configChanged) {
323             return null;
324         }
325
326         displayContent.onOverrideConfigurationChanged(newConfiguration);
327
328         mTmpStackList.clear();
329         if (displayId == DEFAULT_DISPLAY) {
330             // Override configuration of the default display duplicates global config. In this case
331             // we also want to update the global config.
332             setGlobalConfigurationIfNeeded(newConfiguration, mTmpStackList);
333         } else {
334             updateStackBoundsAfterConfigChange(displayId, mTmpStackList);
335         }
336
337         mTmpStackIds.clear();
338         final int stackCount = mTmpStackList.size();
339
340         for (int i = 0; i < stackCount; ++i) {
341             final TaskStack stack = mTmpStackList.get(i);
342
343             // We only include stacks that are not marked for removal as they do not exist outside
344             // of WindowManager at this point.
345             if (!stack.mDeferRemoval) {
346                 mTmpStackIds.add(stack.mStackId);
347             }
348         }
349
350         return mTmpStackIds.isEmpty() ? null : ArrayUtils.convertToIntArray(mTmpStackIds);
351     }
352
353     private void setGlobalConfigurationIfNeeded(Configuration newConfiguration,
354             List<TaskStack> changedStacks) {
355         final boolean configChanged = getConfiguration().diff(newConfiguration) != 0;
356         if (!configChanged) {
357             return;
358         }
359         onConfigurationChanged(newConfiguration);
360         updateStackBoundsAfterConfigChange(changedStacks);
361     }
362
363     @Override
364     public void onConfigurationChanged(Configuration newParentConfig) {
365         prepareFreezingTaskBounds();
366         super.onConfigurationChanged(newParentConfig);
367
368         mService.mPolicy.onConfigurationChanged();
369     }
370
371     /**
372      * Callback used to trigger bounds update after configuration change and get ids of stacks whose
373      * bounds were updated.
374      */
375     private void updateStackBoundsAfterConfigChange(List<TaskStack> changedStacks) {
376         final int numDisplays = mChildren.size();
377         for (int i = 0; i < numDisplays; ++i) {
378             final DisplayContent dc = mChildren.get(i);
379             dc.updateStackBoundsAfterConfigChange(changedStacks);
380         }
381     }
382
383     /** Same as {@link #updateStackBoundsAfterConfigChange()} but only for a specific display. */
384     private void updateStackBoundsAfterConfigChange(int displayId, List<TaskStack> changedStacks) {
385         final DisplayContent dc = getDisplayContent(displayId);
386         dc.updateStackBoundsAfterConfigChange(changedStacks);
387     }
388
389     private void prepareFreezingTaskBounds() {
390         for (int i = mChildren.size() - 1; i >= 0; i--) {
391             mChildren.get(i).prepareFreezingTaskBounds();
392         }
393     }
394
395     TaskStack getStack(int windowingMode, int activityType) {
396         for (int i = mChildren.size() - 1; i >= 0; i--) {
397             final DisplayContent dc = mChildren.get(i);
398             final TaskStack stack = dc.getStack(windowingMode, activityType);
399             if (stack != null) {
400                 return stack;
401             }
402         }
403         return null;
404     }
405
406     void setSecureSurfaceState(int userId, boolean disabled) {
407         forAllWindows((w) -> {
408             if (w.mHasSurface && userId == UserHandle.getUserId(w.mOwnerUid)) {
409                 w.mWinAnimator.setSecureLocked(disabled);
410             }
411         }, true /* traverseTopToBottom */);
412     }
413
414     void updateAppOpsState() {
415         forAllWindows((w) -> {
416             w.updateAppOpsState();
417         }, false /* traverseTopToBottom */);
418     }
419
420     boolean canShowStrictModeViolation(int pid) {
421         final WindowState win = getWindow((w) -> w.mSession.mPid == pid && w.isVisibleLw());
422         return win != null;
423     }
424
425     void closeSystemDialogs(String reason) {
426         mCloseSystemDialogsReason = reason;
427         forAllWindows(mCloseSystemDialogsConsumer, false /* traverseTopToBottom */);
428     }
429
430     void removeReplacedWindows() {
431         if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION removeReplacedWindows");
432         mService.openSurfaceTransaction();
433         try {
434             forAllWindows(sRemoveReplacedWindowsConsumer, true /* traverseTopToBottom */);
435         } finally {
436             mService.closeSurfaceTransaction("removeReplacedWindows");
437             if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION removeReplacedWindows");
438         }
439     }
440
441     boolean hasPendingLayoutChanges(WindowAnimator animator) {
442         boolean hasChanges = false;
443
444         final int count = mChildren.size();
445         for (int i = 0; i < count; ++i) {
446             final DisplayContent dc = mChildren.get(i);
447             final int pendingChanges = animator.getPendingLayoutChanges(dc.getDisplayId());
448             if ((pendingChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
449                 animator.mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING;
450             }
451             if (pendingChanges != 0) {
452                 hasChanges = true;
453             }
454         }
455
456         return hasChanges;
457     }
458
459     boolean reclaimSomeSurfaceMemory(WindowStateAnimator winAnimator, String operation,
460             boolean secure) {
461         final WindowSurfaceController surfaceController = winAnimator.mSurfaceController;
462         boolean leakedSurface = false;
463         boolean killedApps = false;
464
465         EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
466                 winAnimator.mSession.mPid, operation);
467
468         final long callingIdentity = Binder.clearCallingIdentity();
469         try {
470             // There was some problem...first, do a sanity check of the window list to make sure
471             // we haven't left any dangling surfaces around.
472
473             Slog.i(TAG_WM, "Out of memory for surface!  Looking for leaks...");
474             final int numDisplays = mChildren.size();
475             for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
476                 leakedSurface |= mChildren.get(displayNdx).destroyLeakedSurfaces();
477             }
478
479             if (!leakedSurface) {
480                 Slog.w(TAG_WM, "No leaked surfaces; killing applications!");
481                 final SparseIntArray pidCandidates = new SparseIntArray();
482                 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
483                     mChildren.get(displayNdx).forAllWindows((w) -> {
484                         if (mService.mForceRemoves.contains(w)) {
485                             return;
486                         }
487                         final WindowStateAnimator wsa = w.mWinAnimator;
488                         if (wsa.mSurfaceController != null) {
489                             pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
490                         }
491                     }, false /* traverseTopToBottom */);
492
493                     if (pidCandidates.size() > 0) {
494                         int[] pids = new int[pidCandidates.size()];
495                         for (int i = 0; i < pids.length; i++) {
496                             pids[i] = pidCandidates.keyAt(i);
497                         }
498                         try {
499                             if (mService.mActivityManager.killPids(pids, "Free memory", secure)) {
500                                 killedApps = true;
501                             }
502                         } catch (RemoteException e) {
503                         }
504                     }
505                 }
506             }
507
508             if (leakedSurface || killedApps) {
509                 // We managed to reclaim some memory, so get rid of the trouble surface and ask the
510                 // app to request another one.
511                 Slog.w(TAG_WM,
512                         "Looks like we have reclaimed some memory, clearing surface for retry.");
513                 if (surfaceController != null) {
514                     if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
515                             "RECOVER DESTROY", false);
516                     winAnimator.destroySurface();
517                     if (winAnimator.mWin.mAppToken != null
518                             && winAnimator.mWin.mAppToken.getController() != null) {
519                         winAnimator.mWin.mAppToken.getController().removeStartingWindow();
520                     }
521                 }
522
523                 try {
524                     winAnimator.mWin.mClient.dispatchGetNewSurface();
525                 } catch (RemoteException e) {
526                 }
527             }
528         } finally {
529             Binder.restoreCallingIdentity(callingIdentity);
530         }
531
532         return leakedSurface || killedApps;
533     }
534
535     // "Something has changed!  Let's make it correct now."
536     // TODO: Super crazy long method that should be broken down...
537     void performSurfacePlacement(boolean recoveringMemory) {
538         if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
539                 + Debug.getCallers(3));
540
541         int i;
542         boolean updateInputWindowsNeeded = false;
543
544         if (mService.mFocusMayChange) {
545             mService.mFocusMayChange = false;
546             updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
547                     UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
548         }
549
550         // Initialize state of exiting tokens.
551         final int numDisplays = mChildren.size();
552         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
553             final DisplayContent displayContent = mChildren.get(displayNdx);
554             displayContent.setExitingTokensHasVisible(false);
555         }
556
557         mHoldScreen = null;
558         mScreenBrightness = -1;
559         mUserActivityTimeout = -1;
560         mObscureApplicationContentOnSecondaryDisplays = false;
561         mSustainedPerformanceModeCurrent = false;
562         mService.mTransactionSequence++;
563
564         // TODO(multi-display):
565         final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
566         final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
567         final int defaultDw = defaultInfo.logicalWidth;
568         final int defaultDh = defaultInfo.logicalHeight;
569
570         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
571                 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
572         mService.openSurfaceTransaction();
573         try {
574             applySurfaceChangesTransaction(recoveringMemory, defaultDw, defaultDh);
575         } catch (RuntimeException e) {
576             Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
577         } finally {
578             mService.closeSurfaceTransaction("performLayoutAndPlaceSurfaces");
579             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
580                     "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
581         }
582
583         mService.mAnimator.executeAfterPrepareSurfacesRunnables();
584
585         final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked;
586
587         // If we are ready to perform an app transition, check through all of the app tokens to be
588         // shown and see if they are ready to go.
589         if (mService.mAppTransition.isReady()) {
590             // This needs to be split into two expressions, as handleAppTransitionReadyLocked may
591             // modify dc.pendingLayoutChanges, which would get lost when writing
592             // defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked()
593             final int layoutChanges = surfacePlacer.handleAppTransitionReadyLocked();
594             defaultDisplay.pendingLayoutChanges |= layoutChanges;
595             if (DEBUG_LAYOUT_REPEATS)
596                 surfacePlacer.debugLayoutRepeats("after handleAppTransitionReadyLocked",
597                         defaultDisplay.pendingLayoutChanges);
598         }
599
600         if (!isAppAnimating() && mService.mAppTransition.isRunning()) {
601             // We have finished the animation of an app transition. To do this, we have delayed a
602             // lot of operations like showing and hiding apps, moving apps in Z-order, etc. The app
603             // token list reflects the correct Z-order, but the window list may now be out of sync
604             // with it. So here we will just rebuild the entire app window list. Fun!
605             defaultDisplay.pendingLayoutChanges |=
606                     mService.handleAnimatingStoppedAndTransitionLocked();
607             if (DEBUG_LAYOUT_REPEATS)
608                 surfacePlacer.debugLayoutRepeats("after handleAnimStopAndXitionLock",
609                         defaultDisplay.pendingLayoutChanges);
610         }
611
612         // Defer starting the recents animation until the wallpaper has drawn
613         final RecentsAnimationController recentsAnimationController =
614             mService.getRecentsAnimationController();
615         if (recentsAnimationController != null) {
616             recentsAnimationController.checkAnimationReady(mWallpaperController);
617         }
618
619         if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
620                 && !mService.mAppTransition.isReady()) {
621             // At this point, there was a window with a wallpaper that was force hiding other
622             // windows behind it, but now it is going away. This may be simple -- just animate away
623             // the wallpaper and its window -- or it may be hard -- the wallpaper now needs to be
624             // shown behind something that was hidden.
625             defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
626             if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
627                     "after animateAwayWallpaperLocked", defaultDisplay.pendingLayoutChanges);
628         }
629         mWallpaperForceHidingChanged = false;
630
631         if (mWallpaperMayChange) {
632             if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Wallpaper may change!  Adjusting");
633             defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
634             if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("WallpaperMayChange",
635                     defaultDisplay.pendingLayoutChanges);
636         }
637
638         if (mService.mFocusMayChange) {
639             mService.mFocusMayChange = false;
640             if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
641                     false /*updateInputWindows*/)) {
642                 updateInputWindowsNeeded = true;
643                 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
644             }
645         }
646
647         if (isLayoutNeeded()) {
648             defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
649             if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("mLayoutNeeded",
650                     defaultDisplay.pendingLayoutChanges);
651         }
652
653         final ArraySet<DisplayContent> touchExcludeRegionUpdateDisplays = handleResizingWindows();
654
655         if (DEBUG_ORIENTATION && mService.mDisplayFrozen) Slog.v(TAG,
656                 "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
657         if (mOrientationChangeComplete) {
658             if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
659                 mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
660                 mService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
661                 mService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
662             }
663             mService.stopFreezingDisplayLocked();
664         }
665
666         // Destroy the surface of any windows that are no longer visible.
667         boolean wallpaperDestroyed = false;
668         i = mService.mDestroySurface.size();
669         if (i > 0) {
670             do {
671                 i--;
672                 WindowState win = mService.mDestroySurface.get(i);
673                 win.mDestroying = false;
674                 if (mService.mInputMethodWindow == win) {
675                     mService.setInputMethodWindowLocked(null);
676                 }
677                 if (win.getDisplayContent().mWallpaperController.isWallpaperTarget(win)) {
678                     wallpaperDestroyed = true;
679                 }
680                 win.destroySurfaceUnchecked();
681             } while (i > 0);
682             mService.mDestroySurface.clear();
683         }
684
685         // Time to remove any exiting tokens?
686         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
687             final DisplayContent displayContent = mChildren.get(displayNdx);
688             displayContent.removeExistingTokensIfPossible();
689         }
690
691         if (wallpaperDestroyed) {
692             defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
693             defaultDisplay.setLayoutNeeded();
694         }
695
696         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
697             final DisplayContent displayContent = mChildren.get(displayNdx);
698             if (displayContent.pendingLayoutChanges != 0) {
699                 displayContent.setLayoutNeeded();
700             }
701         }
702
703         // Finally update all input windows now that the window changes have stabilized.
704         mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
705
706         mService.setHoldScreenLocked(mHoldScreen);
707         if (!mService.mDisplayFrozen) {
708             final int brightness = mScreenBrightness < 0 || mScreenBrightness > 1.0f
709                     ? -1 : toBrightnessOverride(mScreenBrightness);
710
711             // Post these on a handler such that we don't call into power manager service while
712             // holding the window manager lock to avoid lock contention with power manager lock.
713             mHandler.obtainMessage(SET_SCREEN_BRIGHTNESS_OVERRIDE, brightness, 0).sendToTarget();
714             mHandler.obtainMessage(SET_USER_ACTIVITY_TIMEOUT, mUserActivityTimeout).sendToTarget();
715         }
716
717         if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) {
718             mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent;
719             mService.mPowerManagerInternal.powerHint(
720                     PowerHint.SUSTAINED_PERFORMANCE,
721                     (mSustainedPerformanceModeEnabled ? 1 : 0));
722         }
723
724         if (mUpdateRotation) {
725             if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
726             // TODO(multi-display): Update rotation for different displays separately.
727             final int displayId = defaultDisplay.getDisplayId();
728             if (defaultDisplay.updateRotationUnchecked(false /* inTransaction */)) {
729                 mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, displayId).sendToTarget();
730             } else {
731                 mUpdateRotation = false;
732             }
733             // Update rotation of VR virtual display separately. Currently this is the only kind of
734             // secondary display that can be rotated because of the single-display limitations in
735             // PhoneWindowManager.
736             final DisplayContent vrDisplay = mService.mVr2dDisplayId != INVALID_DISPLAY
737                     ? getDisplayContent(mService.mVr2dDisplayId) : null;
738             if (vrDisplay != null && vrDisplay.updateRotationUnchecked(false /* inTransaction */)) {
739                 mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, mService.mVr2dDisplayId)
740                         .sendToTarget();
741             }
742         }
743
744         if (mService.mWaitingForDrawnCallback != null ||
745                 (mOrientationChangeComplete && !defaultDisplay.isLayoutNeeded()
746                         && !mUpdateRotation)) {
747             mService.checkDrawnWindowsLocked();
748         }
749
750         final int N = mService.mPendingRemove.size();
751         if (N > 0) {
752             if (mService.mPendingRemoveTmp.length < N) {
753                 mService.mPendingRemoveTmp = new WindowState[N+10];
754             }
755             mService.mPendingRemove.toArray(mService.mPendingRemoveTmp);
756             mService.mPendingRemove.clear();
757             ArrayList<DisplayContent> displayList = new ArrayList();
758             for (i = 0; i < N; i++) {
759                 final WindowState w = mService.mPendingRemoveTmp[i];
760                 w.removeImmediately();
761                 final DisplayContent displayContent = w.getDisplayContent();
762                 if (displayContent != null && !displayList.contains(displayContent)) {
763                     displayList.add(displayContent);
764                 }
765             }
766
767             for (int j = displayList.size() - 1; j >= 0; --j) {
768                 final DisplayContent dc = displayList.get(j);
769                 dc.assignWindowLayers(true /*setLayoutNeeded*/);
770             }
771         }
772
773         // Remove all deferred displays stacks, tasks, and activities.
774         for (int displayNdx = mChildren.size() - 1; displayNdx >= 0; --displayNdx) {
775             mChildren.get(displayNdx).checkCompleteDeferredRemoval();
776         }
777
778         if (updateInputWindowsNeeded) {
779             mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
780         }
781         mService.setFocusTaskRegionLocked(null);
782         if (touchExcludeRegionUpdateDisplays != null) {
783             final DisplayContent focusedDc = mService.mFocusedApp != null
784                     ? mService.mFocusedApp.getDisplayContent() : null;
785             for (DisplayContent dc : touchExcludeRegionUpdateDisplays) {
786                 // The focused DisplayContent was recalcuated in setFocusTaskRegionLocked
787                 if (focusedDc != dc) {
788                     dc.setTouchExcludeRegion(null /* focusedTask */);
789                 }
790             }
791         }
792
793         // Check to see if we are now in a state where the screen should
794         // be enabled, because the window obscured flags have changed.
795         mService.enableScreenIfNeededLocked();
796
797         mService.scheduleAnimationLocked();
798         mService.mWindowPlacerLocked.destroyPendingSurfaces();
799
800         if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
801                 "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
802     }
803
804     private void applySurfaceChangesTransaction(boolean recoveringMemory, int defaultDw,
805             int defaultDh) {
806         mHoldScreenWindow = null;
807         mObscuringWindow = null;
808
809         // TODO(multi-display): Support these features on secondary screens.
810         if (mService.mWatermark != null) {
811             mService.mWatermark.positionSurface(defaultDw, defaultDh);
812         }
813         if (mService.mStrictModeFlash != null) {
814             mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
815         }
816         if (mService.mCircularDisplayMask != null) {
817             mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh,
818                     mService.getDefaultDisplayRotation());
819         }
820         if (mService.mEmulatorDisplayOverlay != null) {
821             mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
822                     mService.getDefaultDisplayRotation());
823         }
824
825         boolean focusDisplayed = false;
826
827         final int count = mChildren.size();
828         for (int j = 0; j < count; ++j) {
829             final DisplayContent dc = mChildren.get(j);
830             focusDisplayed |= dc.applySurfaceChangesTransaction(recoveringMemory);
831         }
832
833         if (focusDisplayed) {
834             mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
835         }
836
837         // Give the display manager a chance to adjust properties like display rotation if it needs
838         // to.
839         mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
840     }
841
842     /**
843      * Handles resizing windows during surface placement.
844      *
845      * @return A set of any DisplayContent whose touch exclude region needs to be recalculated due
846      *         to a tap-exclude window resizing, or null if no such DisplayContents were found.
847      */
848     private ArraySet<DisplayContent> handleResizingWindows() {
849         ArraySet<DisplayContent> touchExcludeRegionUpdateSet = null;
850         for (int i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
851             WindowState win = mService.mResizingWindows.get(i);
852             if (win.mAppFreezing) {
853                 // Don't remove this window until rotation has completed.
854                 continue;
855             }
856             win.reportResized();
857             mService.mResizingWindows.remove(i);
858             if (WindowManagerService.excludeWindowTypeFromTapOutTask(win.mAttrs.type)) {
859                 final DisplayContent dc = win.getDisplayContent();
860                 if (touchExcludeRegionUpdateSet == null) {
861                     touchExcludeRegionUpdateSet = new ArraySet<>();
862                 }
863                 touchExcludeRegionUpdateSet.add(dc);
864             }
865         }
866         return touchExcludeRegionUpdateSet;
867     }
868
869     /**
870      * @param w WindowState this method is applied to.
871      * @param obscured True if there is a window on top of this obscuring the display.
872      * @param syswin System window?
873      * @return True when the display contains content to show the user. When false, the display
874      *          manager may choose to mirror or blank the display.
875      */
876     boolean handleNotObscuredLocked(WindowState w, boolean obscured, boolean syswin) {
877         final WindowManager.LayoutParams attrs = w.mAttrs;
878         final int attrFlags = attrs.flags;
879         final boolean onScreen = w.isOnScreen();
880         final boolean canBeSeen = w.isDisplayedLw();
881         final int privateflags = attrs.privateFlags;
882         boolean displayHasContent = false;
883
884         if (DEBUG_KEEP_SCREEN_ON) {
885             Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked w: " + w
886                 + ", w.mHasSurface: " + w.mHasSurface
887                 + ", w.isOnScreen(): " + onScreen
888                 + ", w.isDisplayedLw(): " + w.isDisplayedLw()
889                 + ", w.mAttrs.userActivityTimeout: " + w.mAttrs.userActivityTimeout);
890         }
891         if (w.mHasSurface && onScreen) {
892             if (!syswin && w.mAttrs.userActivityTimeout >= 0 && mUserActivityTimeout < 0) {
893                 mUserActivityTimeout = w.mAttrs.userActivityTimeout;
894                 if (DEBUG_KEEP_SCREEN_ON) {
895                     Slog.d(TAG, "mUserActivityTimeout set to " + mUserActivityTimeout);
896                 }
897             }
898         }
899         if (w.mHasSurface && canBeSeen) {
900             if ((attrFlags & FLAG_KEEP_SCREEN_ON) != 0) {
901                 mHoldScreen = w.mSession;
902                 mHoldScreenWindow = w;
903             } else if (DEBUG_KEEP_SCREEN_ON && w == mService.mLastWakeLockHoldingWindow) {
904                 Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w + " was holding "
905                         + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by"
906                         + Debug.getCallers(10));
907             }
908             if (!syswin && w.mAttrs.screenBrightness >= 0 && mScreenBrightness < 0) {
909                 mScreenBrightness = w.mAttrs.screenBrightness;
910             }
911
912             final int type = attrs.type;
913             // This function assumes that the contents of the default display are processed first
914             // before secondary displays.
915             final DisplayContent displayContent = w.getDisplayContent();
916             if (displayContent != null && displayContent.isDefaultDisplay) {
917                 // While a dream or keyguard is showing, obscure ordinary application content on
918                 // secondary displays (by forcibly enabling mirroring unless there is other content
919                 // we want to show) but still allow opaque keyguard dialogs to be shown.
920                 if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
921                     mObscureApplicationContentOnSecondaryDisplays = true;
922                 }
923                 displayHasContent = true;
924             } else if (displayContent != null &&
925                     (!mObscureApplicationContentOnSecondaryDisplays
926                             || (obscured && type == TYPE_KEYGUARD_DIALOG))) {
927                 // Allow full screen keyguard presentation dialogs to be seen.
928                 displayHasContent = true;
929             }
930             if ((privateflags & PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE) != 0) {
931                 mSustainedPerformanceModeCurrent = true;
932             }
933         }
934
935         return displayHasContent;
936     }
937
938     boolean copyAnimToLayoutParams() {
939         boolean doRequest = false;
940
941         final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
942         if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
943             mUpdateRotation = true;
944             doRequest = true;
945         }
946         if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
947             mWallpaperMayChange = true;
948             doRequest = true;
949         }
950         if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
951             mWallpaperForceHidingChanged = true;
952             doRequest = true;
953         }
954         if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
955             mOrientationChangeComplete = false;
956         } else {
957             mOrientationChangeComplete = true;
958             mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
959             if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
960                 doRequest = true;
961             }
962         }
963
964         if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
965             mWallpaperActionPending = true;
966         }
967
968         return doRequest;
969     }
970
971     private static int toBrightnessOverride(float value) {
972         return (int)(value * PowerManager.BRIGHTNESS_ON);
973     }
974
975     private final class MyHandler extends Handler {
976
977         public MyHandler(Looper looper) {
978             super(looper);
979         }
980
981         @Override
982         public void handleMessage(Message msg) {
983             switch (msg.what) {
984                 case SET_SCREEN_BRIGHTNESS_OVERRIDE:
985                     mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
986                             msg.arg1);
987                     break;
988                 case SET_USER_ACTIVITY_TIMEOUT:
989                     mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
990                             (Long) msg.obj);
991                     break;
992                 default:
993                     break;
994             }
995         }
996     }
997
998     void dumpDisplayContents(PrintWriter pw) {
999         pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)");
1000         if (mService.mDisplayReady) {
1001             final int count = mChildren.size();
1002             for (int i = 0; i < count; ++i) {
1003                 final DisplayContent displayContent = mChildren.get(i);
1004                 displayContent.dump(pw, "  ", true /* dumpAll */);
1005             }
1006         } else {
1007             pw.println("  NO DISPLAY");
1008         }
1009     }
1010
1011     void dumpLayoutNeededDisplayIds(PrintWriter pw) {
1012         if (!isLayoutNeeded()) {
1013             return;
1014         }
1015         pw.print("  mLayoutNeeded on displays=");
1016         final int count = mChildren.size();
1017         for (int displayNdx = 0; displayNdx < count; ++displayNdx) {
1018             final DisplayContent displayContent = mChildren.get(displayNdx);
1019             if (displayContent.isLayoutNeeded()) {
1020                 pw.print(displayContent.getDisplayId());
1021             }
1022         }
1023         pw.println();
1024     }
1025
1026     void dumpWindowsNoHeader(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows) {
1027         final int[] index = new int[1];
1028         forAllWindows((w) -> {
1029             if (windows == null || windows.contains(w)) {
1030                 pw.println("  Window #" + index[0] + " " + w + ":");
1031                 w.dump(pw, "    ", dumpAll || windows != null);
1032                 index[0] = index[0] + 1;
1033             }
1034         }, true /* traverseTopToBottom */);
1035     }
1036
1037     void dumpTokens(PrintWriter pw, boolean dumpAll) {
1038         pw.println("  All tokens:");
1039         for (int i = mChildren.size() - 1; i >= 0; --i) {
1040             mChildren.get(i).dumpTokens(pw, dumpAll);
1041         }
1042     }
1043
1044     @CallSuper
1045     @Override
1046     public void writeToProto(ProtoOutputStream proto, long fieldId, boolean trim) {
1047         final long token = proto.start(fieldId);
1048         super.writeToProto(proto, WINDOW_CONTAINER, trim);
1049         if (mService.mDisplayReady) {
1050             final int count = mChildren.size();
1051             for (int i = 0; i < count; ++i) {
1052                 final DisplayContent displayContent = mChildren.get(i);
1053                 displayContent.writeToProto(proto, DISPLAYS, trim);
1054             }
1055         }
1056         if (!trim) {
1057             forAllWindows((w) -> {
1058                 w.writeIdentifierToProto(proto, WINDOWS);
1059             }, true);
1060         }
1061         proto.end(token);
1062     }
1063
1064     @Override
1065     String getName() {
1066         return "ROOT";
1067     }
1068
1069     @Override
1070     void scheduleAnimation() {
1071         mService.scheduleAnimationLocked();
1072     }
1073 }