OSDN Git Service

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