blob: 90e27ea3f6e05cd0e134187a4bb23041c7079692 [file] [log] [blame]
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.wm;
18
19import android.app.AppOpsManager;
20import android.content.res.Configuration;
21import android.graphics.Rect;
Ruchi Kandoi0d434042016-10-03 09:12:02 -070022import android.hardware.power.V1_0.PowerHint;
Wale Ogunwalee05f5012016-09-16 16:27:29 -070023import android.os.Binder;
24import android.os.Debug;
Wale Ogunwale02319a62016-09-26 15:21:22 -070025import android.os.IBinder;
Wale Ogunwalee05f5012016-09-16 16:27:29 -070026import android.os.ParcelFileDescriptor;
27import android.os.PowerManager;
28import android.os.RemoteException;
29import android.os.SystemClock;
30import android.os.UserHandle;
31import android.provider.Settings;
32import android.util.EventLog;
33import android.util.Slog;
Wale Ogunwalee05f5012016-09-16 16:27:29 -070034import android.util.SparseIntArray;
35import android.view.Display;
36import android.view.DisplayInfo;
37import android.view.InputChannel;
38import android.view.WindowManager;
39import com.android.internal.util.ArrayUtils;
40import com.android.server.EventLogTags;
41import com.android.server.input.InputWindowHandle;
42
43import java.io.FileDescriptor;
44import java.io.PrintWriter;
45import java.util.ArrayList;
Wale Ogunwale02319a62016-09-26 15:21:22 -070046import java.util.HashMap;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -070047import java.util.LinkedList;
Wale Ogunwalee05f5012016-09-16 16:27:29 -070048
49import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
Winson41275482016-10-10 15:17:45 -070050import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
Wale Ogunwale02319a62016-09-26 15:21:22 -070051import static android.view.Display.DEFAULT_DISPLAY;
Winson41275482016-10-10 15:17:45 -070052import static android.view.WindowManager.INPUT_CONSUMER_NAVIGATION;
53import static android.view.WindowManager.INPUT_CONSUMER_PIP;
54import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER;
Wale Ogunwalee05f5012016-09-16 16:27:29 -070055import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
56import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -070057import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS;
Wale Ogunwalee05f5012016-09-16 16:27:29 -070058import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
Wale Ogunwalee05f5012016-09-16 16:27:29 -070059import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
60import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
61import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
62import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
63import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
64import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
65import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
66import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
67import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
68import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
Wale Ogunwale02319a62016-09-26 15:21:22 -070069import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
Wale Ogunwalee05f5012016-09-16 16:27:29 -070070import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
Wale Ogunwale02319a62016-09-26 15:21:22 -070071import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
Wale Ogunwalee05f5012016-09-16 16:27:29 -070072import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
Wale Ogunwale02319a62016-09-26 15:21:22 -070073import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
Wale Ogunwalee05f5012016-09-16 16:27:29 -070074import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
75import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
76import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
77import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
78import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
79import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
Wale Ogunwalee05f5012016-09-16 16:27:29 -070080import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
81import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
82import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
83import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
84import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
85import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
86import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
87import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
88import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
89import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Wale Ogunwalee05f5012016-09-16 16:27:29 -070090import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
91import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
92import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
Wale Ogunwale02319a62016-09-26 15:21:22 -070093import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
Wale Ogunwalee05f5012016-09-16 16:27:29 -070094import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
95import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
96import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
97import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT;
98import static com.android.server.wm.WindowManagerService.logSurface;
99import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED;
100import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
101import static com.android.server.wm.WindowSurfacePlacer.SET_TURN_ON_SCREEN;
102import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
103import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
104import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE;
105
106/** Root {@link WindowContainer} for the device. */
107// TODO: Several methods in here are accessing children of this container's children through various
108// references (WindowList I am looking at you :/). See if we can delegate instead.
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700109class RootWindowContainer extends WindowContainer<DisplayContent> {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700110 private static final String TAG = TAG_WITH_CLASS_NAME ? "RootWindowContainer" : TAG_WM;
111
112 WindowManagerService mService;
113
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700114 private boolean mWallpaperForceHidingChanged = false;
115 private Object mLastWindowFreezeSource = null;
116 private Session mHoldScreen = null;
117 private float mScreenBrightness = -1;
118 private float mButtonBrightness = -1;
119 private long mUserActivityTimeout = -1;
120 private boolean mUpdateRotation = false;
121 private boolean mObscured = false;
Wale Ogunwaled4a00a02016-10-10 11:29:17 -0700122 private boolean mSyswin = false;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700123 // Set to true when the display contains content to show the user.
124 // When false, the display manager may choose to mirror or blank the display.
125 private boolean mDisplayHasContent = false;
126 private float mPreferredRefreshRate = 0;
127 private int mPreferredModeId = 0;
128 // Following variables are for debugging screen wakelock only.
129 // Last window that requires screen wakelock
130 WindowState mHoldScreenWindow = null;
131 // Last window that obscures all windows below
Wale Ogunwaled4a00a02016-10-10 11:29:17 -0700132 WindowState mObscuringWindow = null;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700133 // Only set while traversing the default display based on its content.
134 // Affects the behavior of mirroring on secondary displays.
135 private boolean mObscureApplicationContentOnSecondaryDisplays = false;
136
137 private boolean mSustainedPerformanceModeEnabled = false;
138 private boolean mSustainedPerformanceModeCurrent = false;
139
140 boolean mWallpaperMayChange = false;
Robert Carr11c26c22016-09-23 12:40:27 -0700141 // During an orientation change, we track whether all windows have rendered
142 // at the new orientation, and this will be false from changing orientation until that occurs.
143 // For seamless rotation cases this always stays true, as the windows complete their orientation
144 // changes 1 by 1 without disturbing global state.
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700145 boolean mOrientationChangeComplete = true;
146 boolean mWallpaperActionPending = false;
147
148 private final ArrayList<Integer> mChangedStackList = new ArrayList();
149
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700150 private final LinkedList<AppWindowToken> mTmpUpdateAllDrawn = new LinkedList();
151
Wale Ogunwale02319a62016-09-26 15:21:22 -0700152 private final ArrayList<WindowToken> mTmpTokensList = new ArrayList();
153
154 // Collection of binder tokens mapped to their window type we are allowed to create window
155 // tokens for but that are not current attached to any display. We need to track this here
156 // because a binder token can be added through {@link WindowManagerService#addWindowToken},
157 // but we don't know what display windows for the token will be added to until
158 // {@link WindowManagerService#addWindow} is called.
159 private final HashMap<IBinder, Integer> mUnattachedBinderTokens = new HashMap();
160
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700161 // State for the RemoteSurfaceTrace system used in testing. If this is enabled SurfaceControl
162 // instances will be replaced with an instance that writes a binary representation of all
163 // commands to mSurfaceTraceFd.
164 boolean mSurfaceTraceEnabled;
165 ParcelFileDescriptor mSurfaceTraceFd;
166 RemoteEventTrace mRemoteEventTrace;
167
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700168 private final WindowLayersController mLayersController;
Wale Ogunwale0303c572016-10-20 10:16:29 -0700169 final WallpaperController mWallpaperController;
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700170
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700171 RootWindowContainer(WindowManagerService service) {
172 mService = service;
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700173 mLayersController = new WindowLayersController(mService);
Wale Ogunwale0303c572016-10-20 10:16:29 -0700174 mWallpaperController = new WallpaperController(mService);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700175 }
176
177 WindowState computeFocusedWindow() {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700178 final int count = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700179 for (int i = 0; i < count; i++) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700180 final DisplayContent dc = mChildren.get(i);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700181 final WindowState win = dc.findFocusedWindow();
182 if (win != null) {
183 return win;
184 }
185 }
186 return null;
187 }
188
189 /**
190 * Retrieve the DisplayContent for the specified displayId. Will create a new DisplayContent if
191 * there is a Display for the displayId.
192 *
193 * @param displayId The display the caller is interested in.
194 * @return The DisplayContent associated with displayId or null if there is no Display for it.
195 */
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700196 DisplayContent getDisplayContentOrCreate(int displayId) {
197 DisplayContent dc = getDisplayContent(displayId);
198
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700199 if (dc == null) {
200 final Display display = mService.mDisplayManager.getDisplay(displayId);
201 if (display != null) {
202 dc = createDisplayContent(display);
203 }
204 }
205 return dc;
206 }
207
Wale Ogunwale02319a62016-09-26 15:21:22 -0700208 DisplayContent getDisplayContent(int displayId) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700209 for (int i = mChildren.size() - 1; i >= 0; --i) {
210 final DisplayContent current = mChildren.get(i);
211 if (current.getDisplayId() == displayId) {
212 return current;
213 }
214 }
215 return null;
216 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700217
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700218 private DisplayContent createDisplayContent(final Display display) {
Wale Ogunwale0303c572016-10-20 10:16:29 -0700219 final DisplayContent dc = new DisplayContent(display, mService, mLayersController,
220 mWallpaperController);
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700221 final int displayId = display.getDisplayId();
222
223 if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Adding display=" + display);
224 addChild(dc, null);
225
226 final DisplayInfo displayInfo = dc.getDisplayInfo();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700227 final Rect rect = new Rect();
228 mService.mDisplaySettings.getOverscanLocked(displayInfo.name, displayInfo.uniqueId, rect);
229 displayInfo.overscanLeft = rect.left;
230 displayInfo.overscanTop = rect.top;
231 displayInfo.overscanRight = rect.right;
232 displayInfo.overscanBottom = rect.bottom;
233 if (mService.mDisplayManagerInternal != null) {
234 mService.mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
235 displayId, displayInfo);
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700236 mService.configureDisplayPolicyLocked(dc);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700237
238 // TODO(multi-display): Create an input channel for each display with touch capability.
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700239 if (displayId == DEFAULT_DISPLAY) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700240 dc.mTapDetector = new TaskTapPointerEventListener(
241 mService, dc);
242 mService.registerPointerEventListener(dc.mTapDetector);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700243 mService.registerPointerEventListener(mService.mMousePositionTracker);
244 }
245 }
246
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700247 return dc;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700248 }
249
250 /** Adds the input stack id to the input display id and returns the bounds of the added stack.*/
251 Rect addStackToDisplay(int stackId, int displayId, boolean onTop) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700252 final DisplayContent dc = getDisplayContent(displayId);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700253 if (dc == null) {
254 Slog.w(TAG_WM, "addStackToDisplay: Trying to add stackId=" + stackId
255 + " to unknown displayId=" + displayId + " callers=" + Debug.getCallers(6));
256 return null;
257 }
258
259 boolean attachedToDisplay = false;
260 TaskStack stack = mService.mStackIdToStack.get(stackId);
261 if (stack == null) {
262 if (DEBUG_STACK) Slog.d(TAG_WM, "attachStack: stackId=" + stackId);
263
264 stack = dc.getStackById(stackId);
265 if (stack != null) {
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700266 // It's already attached to the display...clear mDeferRemoval and move stack to
267 // appropriate z-order on display as needed.
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700268 stack.mDeferRemoval = false;
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700269 dc.moveStack(stack, onTop);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700270 attachedToDisplay = true;
271 } else {
272 stack = new TaskStack(mService, stackId);
273 }
274
275 mService.mStackIdToStack.put(stackId, stack);
276 if (stackId == DOCKED_STACK_ID) {
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700277 dc.mDividerControllerLocked.notifyDockedStackExistsChanged(true);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700278 }
279 }
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700280
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700281 if (!attachedToDisplay) {
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700282 dc.attachStack(stack, onTop);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700283 }
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700284
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700285 if (stack.getRawFullscreen()) {
286 return null;
287 }
Wale Ogunwaleba51ca22016-09-23 06:06:54 -0700288 final Rect bounds = new Rect();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700289 stack.getRawBounds(bounds);
290 return bounds;
291 }
292
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700293 boolean isLayoutNeeded() {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700294 final int numDisplays = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700295 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700296 final DisplayContent displayContent = mChildren.get(displayNdx);
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -0700297 if (displayContent.isLayoutNeeded()) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700298 return true;
299 }
300 }
301 return false;
302 }
303
304 void getWindows(WindowList output) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700305 final int count = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700306 for (int i = 0; i < count; ++i) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700307 final DisplayContent dc = mChildren.get(i);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700308 output.addAll(dc.getWindowList());
309 }
310 }
311
312 void getWindows(WindowList output, boolean visibleOnly, boolean appsOnly) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700313 final int numDisplays = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700314 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700315 final WindowList windowList = mChildren.get(displayNdx).getWindowList();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700316 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
317 final WindowState w = windowList.get(winNdx);
318 if ((!visibleOnly || w.mWinAnimator.getShown())
319 && (!appsOnly || w.mAppToken != null)) {
320 output.add(w);
321 }
322 }
323 }
324 }
325
326 void getWindowsByName(WindowList output, String name) {
327 int objectId = 0;
328 // See if this is an object ID.
329 try {
330 objectId = Integer.parseInt(name, 16);
331 name = null;
332 } catch (RuntimeException e) {
333 }
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700334 final int numDisplays = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700335 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700336 final WindowList windowList = mChildren.get(displayNdx).getWindowList();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700337 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
338 final WindowState w = windowList.get(winNdx);
339 if (name != null) {
340 if (w.mAttrs.getTitle().toString().contains(name)) {
341 output.add(w);
342 }
343 } else if (System.identityHashCode(w) == objectId) {
344 output.add(w);
345 }
346 }
347 }
348 }
349
350 WindowState findWindow(int hashCode) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700351 final int numDisplays = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700352 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700353 final WindowList windows = mChildren.get(displayNdx).getWindowList();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700354 final int numWindows = windows.size();
355 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
356 final WindowState w = windows.get(winNdx);
357 if (System.identityHashCode(w) == hashCode) {
358 return w;
359 }
360 }
361 }
362
363 return null;
364 }
365
Wale Ogunwale02319a62016-09-26 15:21:22 -0700366 /** Return the window token associated with the input binder token on the input display */
367 WindowToken getWindowToken(IBinder binder, DisplayContent dc) {
368 final WindowToken token = dc.getWindowToken(binder);
369 if (token != null) {
370 return token;
371 }
372
373 // There is no window token mapped to the binder on the display. Create and map a window
374 // token if it is currently allowed.
375 if (!mUnattachedBinderTokens.containsKey(binder)) {
376 return null;
377 }
378
379 final int type = mUnattachedBinderTokens.get(binder);
380 return new WindowToken(mService, binder, type, true, dc);
381 }
382
383 /** Returns all window tokens mapped to the input binder. */
384 ArrayList<WindowToken> getWindowTokens(IBinder binder) {
385 mTmpTokensList.clear();
386 for (int i = mChildren.size() - 1; i >= 0; --i) {
387 final DisplayContent dc = mChildren.get(i);
388 final WindowToken token = dc.getWindowToken(binder);
389 if (token != null) {
390 mTmpTokensList.add(token);
391 }
392 }
393 return mTmpTokensList;
394 }
395
396 /**
397 * Returns the app window token for the input binder if it exist in the system.
398 * NOTE: Only one AppWindowToken is allowed to exist in the system for a binder token, since
399 * AppWindowToken represents an activity which can only exist on one display.
400 */
401 AppWindowToken getAppWindowToken(IBinder binder) {
402 for (int i = mChildren.size() - 1; i >= 0; --i) {
403 final DisplayContent dc = mChildren.get(i);
404 final AppWindowToken atoken = dc.getAppWindowToken(binder);
405 if (atoken != null) {
406 return atoken;
407 }
408 }
409 return null;
410 }
411
412 /** Returns the display object the input window token is currently mapped on. */
413 DisplayContent getWindowTokenDisplay(WindowToken token) {
414 if (token == null) {
415 return null;
416 }
417
418 for (int i = mChildren.size() - 1; i >= 0; --i) {
419 final DisplayContent dc = mChildren.get(i);
420 final WindowToken current = dc.getWindowToken(token.token);
421 if (current == token) {
422 return dc;
423 }
424 }
425
426 return null;
427 }
428
429 void addWindowToken(IBinder binder, int type) {
430 if (mUnattachedBinderTokens.containsKey(binder)) {
431 Slog.w(TAG_WM, "addWindowToken: Attempted to add existing binder token: " + binder);
432 return;
433 }
434
435 final ArrayList<WindowToken> tokens = getWindowTokens(binder);
436
437 if (!tokens.isEmpty()) {
438 Slog.w(TAG_WM, "addWindowToken: Attempted to add binder token: " + binder
439 + " for already created window tokens: " + tokens);
440 return;
441 }
442
443 mUnattachedBinderTokens.put(binder, type);
444
445 // TODO(multi-display): By default we add this to the default display, but maybe we
446 // should provide an API for a token to be added to any display?
Wale Ogunwale0303c572016-10-20 10:16:29 -0700447 final DisplayContent dc = getDisplayContent(DEFAULT_DISPLAY);
448 final WindowToken token = new WindowToken(mService, binder, type, true, dc);
Wale Ogunwale02319a62016-09-26 15:21:22 -0700449 if (type == TYPE_WALLPAPER) {
Wale Ogunwale0303c572016-10-20 10:16:29 -0700450 dc.mWallpaperController.addWallpaperToken(token);
Wale Ogunwale02319a62016-09-26 15:21:22 -0700451 }
452 }
453
454 ArrayList<WindowToken> removeWindowToken(IBinder binder) {
455 mUnattachedBinderTokens.remove(binder);
456
457 mTmpTokensList.clear();
458 for (int i = mChildren.size() - 1; i >= 0; --i) {
459 final DisplayContent dc = mChildren.get(i);
460 final WindowToken token = dc.removeWindowToken(binder);
461 if (token != null) {
462 mTmpTokensList.add(token);
463 }
464 }
465 return mTmpTokensList;
466 }
467
468 /**
469 * Removed the mapping to the input binder for the system if it no longer as a window token
470 * associated with it on any display.
471 */
472 void removeWindowTokenIfPossible(IBinder binder) {
473 for (int i = mChildren.size() - 1; i >= 0; --i) {
474 final DisplayContent dc = mChildren.get(i);
475 final WindowToken token = dc.getWindowToken(binder);
476 if (token != null) {
477 return;
478 }
479 }
480
481 mUnattachedBinderTokens.remove(binder);
482 }
483
484 void removeAppToken(IBinder binder) {
485 final ArrayList<WindowToken> removedTokens = removeWindowToken(binder);
486 if (removedTokens == null || removedTokens.isEmpty()) {
487 Slog.w(TAG_WM, "removeAppToken: Attempted to remove non-existing token: " + binder);
488 return;
489 }
490
491 for (int i = removedTokens.size() - 1; i >= 0; --i) {
492 WindowToken wtoken = removedTokens.get(i);
493 AppWindowToken appToken = wtoken.asAppWindowToken();
494
495 if (appToken == null) {
496 Slog.w(TAG_WM,
497 "Attempted to remove non-App token: " + binder + " wtoken=" + wtoken);
498 continue;
499 }
500
501 AppWindowToken startingToken = null;
502
503 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app token: " + appToken);
504
505 boolean delayed = appToken.setVisibility(null, false, TRANSIT_UNSET, true,
506 appToken.voiceInteraction);
507
508 mService.mOpeningApps.remove(appToken);
509 appToken.waitingToShow = false;
510 if (mService.mClosingApps.contains(appToken)) {
511 delayed = true;
512 } else if (mService.mAppTransition.isTransitionSet()) {
513 mService.mClosingApps.add(appToken);
514 delayed = true;
515 }
516
517 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app " + appToken
518 + " delayed=" + delayed
519 + " animation=" + appToken.mAppAnimator.animation
520 + " animating=" + appToken.mAppAnimator.animating);
521
522 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, "removeAppToken: "
523 + appToken + " delayed=" + delayed + " Callers=" + Debug.getCallers(4));
524
525 final TaskStack stack = appToken.mTask.mStack;
526 if (delayed && !appToken.isEmpty()) {
527 // set the token aside because it has an active animation to be finished
528 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM,
529 "removeAppToken make exiting: " + appToken);
530 stack.mExitingAppTokens.add(appToken);
531 appToken.mIsExiting = true;
532 } else {
533 // Make sure there is no animation running on this token, so any windows associated
534 // with it will be removed as soon as their animations are complete
535 appToken.mAppAnimator.clearAnimation();
536 appToken.mAppAnimator.animating = false;
537 appToken.removeIfPossible();
538 }
539
540 appToken.removed = true;
541 if (appToken.startingData != null) {
542 startingToken = appToken;
543 }
544 appToken.stopFreezingScreen(true, true);
545 if (mService.mFocusedApp == appToken) {
546 if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + appToken);
547 mService.mFocusedApp = null;
548 mService.updateFocusedWindowLocked(
549 UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
550 mService.mInputMonitor.setFocusedAppLw(null);
551 }
552
553 if (!delayed) {
554 appToken.updateReportedVisibilityLocked();
555 }
556
557 // Will only remove if startingToken non null.
558 mService.scheduleRemoveStartingWindowLocked(startingToken);
559 }
560 }
561
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700562 // TODO: Users would have their own window containers under the display container?
563 void switchUser() {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700564 final int count = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700565 for (int i = 0; i < count; ++i) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700566 final DisplayContent dc = mChildren.get(i);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700567 dc.switchUser();
568 }
569 }
570
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700571 /**
572 * Set new display override config and return array of ids of stacks that were changed during
573 * update. If called for the default display, global configuration will also be updated.
574 */
575 int[] setDisplayOverrideConfigurationIfNeeded(Configuration newConfiguration, int displayId) {
576 final DisplayContent displayContent = getDisplayContent(displayId);
577 if (displayContent == null) {
578 throw new IllegalArgumentException("Display not found for id: " + displayId);
579 }
580
581 final Configuration currentConfig = displayContent.getOverrideConfiguration();
582 final boolean configChanged = currentConfig.diff(newConfiguration) != 0;
583 if (!configChanged) {
584 return null;
585 }
586 displayContent.onOverrideConfigurationChanged(currentConfig);
587
588 if (displayId == DEFAULT_DISPLAY) {
589 // Override configuration of the default display duplicates global config. In this case
590 // we also want to update the global config.
591 return setGlobalConfigurationIfNeeded(newConfiguration);
592 } else {
593 return updateStackBoundsAfterConfigChange(displayId);
594 }
595 }
596
597 private int[] setGlobalConfigurationIfNeeded(Configuration newConfiguration) {
Andrii Kulian441e4492016-09-29 15:25:00 -0700598 final boolean configChanged = getConfiguration().diff(newConfiguration) != 0;
599 if (!configChanged) {
600 return null;
601 }
602 onConfigurationChanged(newConfiguration);
603 return updateStackBoundsAfterConfigChange();
604 }
605
606 @Override
607 void onConfigurationChanged(Configuration newParentConfig) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700608 prepareFreezingTaskBounds();
Andrii Kulian441e4492016-09-29 15:25:00 -0700609 super.onConfigurationChanged(newParentConfig);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700610
611 mService.mPolicy.onConfigurationChanged();
Andrii Kulian441e4492016-09-29 15:25:00 -0700612 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700613
Andrii Kulian441e4492016-09-29 15:25:00 -0700614 /**
615 * Callback used to trigger bounds update after configuration change and get ids of stacks whose
616 * bounds were updated.
617 */
Wale Ogunwaled4a00a02016-10-10 11:29:17 -0700618 private int[] updateStackBoundsAfterConfigChange() {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700619 mChangedStackList.clear();
620
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700621 final int numDisplays = mChildren.size();
622 for (int i = 0; i < numDisplays; ++i) {
623 final DisplayContent dc = mChildren.get(i);
Andrii Kulian441e4492016-09-29 15:25:00 -0700624 dc.updateStackBoundsAfterConfigChange(mChangedStackList);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700625 }
626
627 return mChangedStackList.isEmpty() ? null : ArrayUtils.convertToIntArray(mChangedStackList);
628 }
629
Andrii Kulian5406e7a2016-10-21 11:55:23 -0700630 /** Same as {@link #updateStackBoundsAfterConfigChange()} but only for a specific display. */
631 private int[] updateStackBoundsAfterConfigChange(int displayId) {
632 mChangedStackList.clear();
633
634 final DisplayContent dc = getDisplayContent(displayId);
635 dc.updateStackBoundsAfterConfigChange(mChangedStackList);
636
637 return mChangedStackList.isEmpty() ? null : ArrayUtils.convertToIntArray(mChangedStackList);
638 }
639
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700640 private void prepareFreezingTaskBounds() {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700641 for (int i = mChildren.size() - 1; i >= 0; i--) {
642 mChildren.get(i).prepareFreezingTaskBounds();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700643 }
644 }
645
646 void setSecureSurfaceState(int userId, boolean disabled) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700647 for (int i = mChildren.size() - 1; i >= 0; --i) {
648 final WindowList windows = mChildren.get(i).getWindowList();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700649 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
650 final WindowState win = windows.get(winNdx);
651 if (win.mHasSurface && userId == UserHandle.getUserId(win.mOwnerUid)) {
652 win.mWinAnimator.setSecureLocked(disabled);
653 }
654 }
655 }
656 }
657
658 void updateAppOpsState() {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700659 final int count = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700660 for (int i = 0; i < count; ++i) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700661 final WindowList windows = mChildren.get(i).getWindowList();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700662 final int numWindows = windows.size();
663 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
664 final WindowState win = windows.get(winNdx);
665 if (win.mAppOp == AppOpsManager.OP_NONE) {
666 continue;
667 }
668 final int mode = mService.mAppOps.checkOpNoThrow(win.mAppOp, win.getOwningUid(),
669 win.getOwningPackage());
670 win.setAppOpVisibilityLw(mode == AppOpsManager.MODE_ALLOWED ||
671 mode == AppOpsManager.MODE_DEFAULT);
672 }
673 }
674 }
675
676 boolean canShowStrictModeViolation(int pid) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700677 final int count = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700678 for (int i = 0; i < count; ++i) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700679 final WindowList windows = mChildren.get(i).getWindowList();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700680 final int numWindows = windows.size();
681 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
682 final WindowState ws = windows.get(winNdx);
683 if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
684 return true;
685 }
686 }
687 }
688 return false;
689 }
690
691 void closeSystemDialogs(String reason) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700692 final int count = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700693 for (int i = 0; i < count; ++i) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700694 final WindowList windows = mChildren.get(i).getWindowList();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700695 final int numWindows = windows.size();
696 for (int j = 0; j < numWindows; ++j) {
697 final WindowState w = windows.get(j);
698 if (w.mHasSurface) {
699 try {
700 w.mClient.closeSystemDialogs(reason);
701 } catch (RemoteException e) {
702 }
703 }
704 }
705 }
706 }
707
708 void removeReplacedWindows() {
709 if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION removeReplacedWindows");
710 mService.openSurfaceTransaction();
711 try {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700712 for (int i = mChildren.size() - 1; i >= 0; i--) {
713 DisplayContent dc = mChildren.get(i);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700714 final WindowList windows = dc.getWindowList();
715 for (int j = windows.size() - 1; j >= 0; j--) {
716 final WindowState win = windows.get(j);
717 final AppWindowToken aToken = win.mAppToken;
718 if (aToken != null) {
719 aToken.removeReplacedWindowIfNeeded(win);
720 }
721 }
722 }
723 } finally {
724 mService.closeSurfaceTransaction();
725 if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION removeReplacedWindows");
726 }
727 }
728
729 boolean hasPendingLayoutChanges(WindowAnimator animator) {
730 boolean hasChanges = false;
731
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700732 final int count = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700733 for (int i = 0; i < count; ++i) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700734 final DisplayContent dc = mChildren.get(i);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700735 final int pendingChanges = animator.getPendingLayoutChanges(dc.getDisplayId());
736 if ((pendingChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
737 animator.mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING;
738 }
739 if (pendingChanges != 0) {
740 hasChanges = true;
741 }
742 }
743
744 return hasChanges;
745 }
746
747 void updateInputWindows(InputMonitor inputMonitor, WindowState inputFocus, boolean inDrag) {
Winson41275482016-10-10 15:17:45 -0700748 final InputConsumerImpl navInputConsumer =
749 mService.mInputMonitor.getInputConsumer(INPUT_CONSUMER_NAVIGATION);
750 final InputConsumerImpl pipInputConsumer =
751 mService.mInputMonitor.getInputConsumer(INPUT_CONSUMER_PIP);
752 final InputConsumerImpl wallpaperInputConsumer =
753 mService.mInputMonitor.getInputConsumer(INPUT_CONSUMER_WALLPAPER);
754 boolean addInputConsumerHandle = navInputConsumer != null;
755 boolean addPipInputConsumerHandle = pipInputConsumer != null;
756 boolean addWallpaperInputConsumerHandle = wallpaperInputConsumer != null;
757 final Rect pipTouchableBounds = addPipInputConsumerHandle ? new Rect() : null;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700758 boolean disableWallpaperTouchEvents = false;
759
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700760 final int count = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700761 for (int i = 0; i < count; ++i) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700762 final DisplayContent dc = mChildren.get(i);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700763 final WindowList windows = dc.getWindowList();
764 for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
765 final WindowState child = windows.get(winNdx);
766 final InputChannel inputChannel = child.mInputChannel;
767 final InputWindowHandle inputWindowHandle = child.mInputWindowHandle;
768 if (inputChannel == null || inputWindowHandle == null || child.mRemoved
769 || child.isAdjustedForMinimizedDock()) {
770 // Skip this window because it cannot possibly receive input.
771 continue;
772 }
Winson41275482016-10-10 15:17:45 -0700773
774 if (addPipInputConsumerHandle
775 && child.getStackId() == PINNED_STACK_ID
776 && inputWindowHandle.layer <= pipInputConsumer.mWindowHandle.layer) {
777 // Update the bounds of the Pip input consumer to match the Pinned stack
778 child.getStack().getBounds(pipTouchableBounds);
779 pipInputConsumer.mWindowHandle.touchableRegion.set(pipTouchableBounds);
780 inputMonitor.addInputWindowHandle(pipInputConsumer.mWindowHandle);
781 addPipInputConsumerHandle = false;
782 }
783
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700784 if (addInputConsumerHandle
Winson41275482016-10-10 15:17:45 -0700785 && inputWindowHandle.layer <= navInputConsumer.mWindowHandle.layer) {
786 inputMonitor.addInputWindowHandle(navInputConsumer.mWindowHandle);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700787 addInputConsumerHandle = false;
788 }
789
790 if (addWallpaperInputConsumerHandle) {
791 if (child.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER &&
792 child.isVisibleLw()) {
793 // Add the wallpaper input consumer above the first visible wallpaper.
Winson41275482016-10-10 15:17:45 -0700794 inputMonitor.addInputWindowHandle(wallpaperInputConsumer.mWindowHandle);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700795 addWallpaperInputConsumerHandle = false;
796 }
797 }
798
799 final int flags = child.mAttrs.flags;
800 final int privateFlags = child.mAttrs.privateFlags;
801 final int type = child.mAttrs.type;
802
803 final boolean hasFocus = child == inputFocus;
804 final boolean isVisible = child.isVisibleLw();
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700805 if ((privateFlags & PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS) != 0) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700806 disableWallpaperTouchEvents = true;
807 }
Wale Ogunwale0303c572016-10-20 10:16:29 -0700808 final boolean hasWallpaper = dc.mWallpaperController.isWallpaperTarget(child)
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700809 && (privateFlags & PRIVATE_FLAG_KEYGUARD) == 0
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700810 && !disableWallpaperTouchEvents;
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700811
812 // If there's a drag in progress and 'child' is a potential drop target,
813 // make sure it's been told about the drag
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700814 if (inDrag && isVisible && dc.isDefaultDisplay) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700815 mService.mDragState.sendDragStartedIfNeededLw(child);
816 }
817
818 inputMonitor.addInputWindowHandle(
819 inputWindowHandle, child, flags, type, isVisible, hasFocus, hasWallpaper);
820 }
821 }
822
823 if (addWallpaperInputConsumerHandle) {
824 // No visible wallpaper found, add the wallpaper input consumer at the end.
Winson41275482016-10-10 15:17:45 -0700825 inputMonitor.addInputWindowHandle(wallpaperInputConsumer.mWindowHandle);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700826 }
827 }
828
829 boolean reclaimSomeSurfaceMemory(WindowStateAnimator winAnimator, String operation,
830 boolean secure) {
831 final WindowSurfaceController surfaceController = winAnimator.mSurfaceController;
832 boolean leakedSurface = false;
833 boolean killedApps = false;
834
835 EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
836 winAnimator.mSession.mPid, operation);
837
838 final long callingIdentity = Binder.clearCallingIdentity();
839 try {
840 // There was some problem... first, do a sanity check of the window list to make sure
841 // we haven't left any dangling surfaces around.
842
843 Slog.i(TAG_WM, "Out of memory for surface! Looking for leaks...");
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700844 final int numDisplays = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700845 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700846 final WindowList windows = mChildren.get(displayNdx).getWindowList();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700847 final int numWindows = windows.size();
848 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
849 final WindowState ws = windows.get(winNdx);
850 final WindowStateAnimator wsa = ws.mWinAnimator;
851 if (wsa.mSurfaceController == null) {
852 continue;
853 }
854 if (!mService.mSessions.contains(wsa.mSession)) {
855 Slog.w(TAG_WM, "LEAKED SURFACE (session doesn't exist): "
856 + ws + " surface=" + wsa.mSurfaceController
857 + " token=" + ws.mToken
858 + " pid=" + ws.mSession.mPid
859 + " uid=" + ws.mSession.mUid);
860 wsa.destroySurface();
861 mService.mForceRemoves.add(ws);
862 leakedSurface = true;
863 } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
864 Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): "
865 + ws + " surface=" + wsa.mSurfaceController
866 + " token=" + ws.mAppToken
867 + " saved=" + ws.hasSavedSurface());
868 if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", false);
869 wsa.destroySurface();
870 leakedSurface = true;
871 }
872 }
873 }
874
875 if (!leakedSurface) {
876 Slog.w(TAG_WM, "No leaked surfaces; killing applications!");
877 SparseIntArray pidCandidates = new SparseIntArray();
878 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700879 final WindowList windows = mChildren.get(displayNdx).getWindowList();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700880 final int numWindows = windows.size();
881 for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
882 final WindowState ws = windows.get(winNdx);
883 if (mService.mForceRemoves.contains(ws)) {
884 continue;
885 }
886 WindowStateAnimator wsa = ws.mWinAnimator;
887 if (wsa.mSurfaceController != null) {
888 pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
889 }
890 }
891 if (pidCandidates.size() > 0) {
892 int[] pids = new int[pidCandidates.size()];
893 for (int i = 0; i < pids.length; i++) {
894 pids[i] = pidCandidates.keyAt(i);
895 }
896 try {
897 if (mService.mActivityManager.killPids(pids, "Free memory", secure)) {
898 killedApps = true;
899 }
900 } catch (RemoteException e) {
901 }
902 }
903 }
904 }
905
906 if (leakedSurface || killedApps) {
907 // We managed to reclaim some memory, so get rid of the trouble surface and ask the
908 // app to request another one.
909 Slog.w(TAG_WM,
910 "Looks like we have reclaimed some memory, clearing surface for retry.");
911 if (surfaceController != null) {
912 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
913 "RECOVER DESTROY", false);
914 winAnimator.destroySurface();
915 mService.scheduleRemoveStartingWindowLocked(winAnimator.mWin.mAppToken);
916 }
917
918 try {
919 winAnimator.mWin.mClient.dispatchGetNewSurface();
920 } catch (RemoteException e) {
921 }
922 }
923 } finally {
924 Binder.restoreCallingIdentity(callingIdentity);
925 }
926
927 return leakedSurface || killedApps;
928 }
929
930 // "Something has changed! Let's make it correct now."
931 // TODO: Super crazy long method that should be broken down...
932 void performSurfacePlacement(boolean recoveringMemory) {
933 if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
934 + Debug.getCallers(3));
935
936 int i;
937 boolean updateInputWindowsNeeded = false;
938
939 if (mService.mFocusMayChange) {
940 mService.mFocusMayChange = false;
941 updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
942 UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
943 }
944
945 // Initialize state of exiting tokens.
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700946 final int numDisplays = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700947 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -0700948 final DisplayContent displayContent = mChildren.get(displayNdx);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700949 for (i = displayContent.mExitingTokens.size() - 1; i >= 0; i--) {
950 displayContent.mExitingTokens.get(i).hasVisible = false;
951 }
952 }
953
954 for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
955 // Initialize state of exiting applications.
956 final AppTokenList exitingAppTokens =
957 mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
958 for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
959 exitingAppTokens.get(tokenNdx).hasVisible = false;
960 }
961 }
962
963 mHoldScreen = null;
964 mScreenBrightness = -1;
965 mButtonBrightness = -1;
966 mUserActivityTimeout = -1;
967 mObscureApplicationContentOnSecondaryDisplays = false;
968 mSustainedPerformanceModeCurrent = false;
969 mService.mTransactionSequence++;
970
971 // TODO(multi-display):
972 final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
973 final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
974 final int defaultDw = defaultInfo.logicalWidth;
975 final int defaultDh = defaultInfo.logicalHeight;
976
977 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
978 ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
979 mService.openSurfaceTransaction();
980 try {
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -0700981 applySurfaceChangesTransaction(recoveringMemory, defaultDw, defaultDh);
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700982 } catch (RuntimeException e) {
983 Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
984 } finally {
985 mService.closeSurfaceTransaction();
986 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
987 "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
988 }
989
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700990 final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked;
991
992 // If we are ready to perform an app transition, check through all of the app tokens to be
993 // shown and see if they are ready to go.
994 if (mService.mAppTransition.isReady()) {
995 defaultDisplay.pendingLayoutChanges |=
Wale Ogunwale0303c572016-10-20 10:16:29 -0700996 surfacePlacer.handleAppTransitionReadyLocked();
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700997 if (DEBUG_LAYOUT_REPEATS)
998 surfacePlacer.debugLayoutRepeats("after handleAppTransitionReadyLocked",
999 defaultDisplay.pendingLayoutChanges);
1000 }
1001
1002 if (!mService.mAnimator.mAppWindowAnimating && mService.mAppTransition.isRunning()) {
1003 // We have finished the animation of an app transition. To do this, we have delayed a
1004 // lot of operations like showing and hiding apps, moving apps in Z-order, etc. The app
1005 // token list reflects the correct Z-order, but the window list may now be out of sync
1006 // with it. So here we will just rebuild the entire app window list. Fun!
1007 defaultDisplay.pendingLayoutChanges |=
1008 mService.handleAnimatingStoppedAndTransitionLocked();
1009 if (DEBUG_LAYOUT_REPEATS)
1010 surfacePlacer.debugLayoutRepeats("after handleAnimStopAndXitionLock",
1011 defaultDisplay.pendingLayoutChanges);
1012 }
1013
1014 if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
1015 && !mService.mAppTransition.isReady()) {
1016 // At this point, there was a window with a wallpaper that was force hiding other
1017 // windows behind it, but now it is going away. This may be simple -- just animate away
1018 // the wallpaper and its window -- or it may be hard -- the wallpaper now needs to be
1019 // shown behind something that was hidden.
1020 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
1021 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
1022 "after animateAwayWallpaperLocked", defaultDisplay.pendingLayoutChanges);
1023 }
1024 mWallpaperForceHidingChanged = false;
1025
1026 if (mWallpaperMayChange) {
1027 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Wallpaper may change! Adjusting");
1028 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
1029 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("WallpaperMayChange",
1030 defaultDisplay.pendingLayoutChanges);
1031 }
1032
1033 if (mService.mFocusMayChange) {
1034 mService.mFocusMayChange = false;
1035 if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
1036 false /*updateInputWindows*/)) {
1037 updateInputWindowsNeeded = true;
1038 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
1039 }
1040 }
1041
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001042 if (isLayoutNeeded()) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001043 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
1044 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("mLayoutNeeded",
1045 defaultDisplay.pendingLayoutChanges);
1046 }
1047
1048 for (i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
1049 WindowState win = mService.mResizingWindows.get(i);
1050 if (win.mAppFreezing) {
1051 // Don't remove this window until rotation has completed.
1052 continue;
1053 }
1054 // Discard the saved surface if window size is changed, it can't be reused.
1055 if (win.mAppToken != null) {
1056 win.mAppToken.destroySavedSurfaces();
1057 }
1058 win.reportResized();
1059 mService.mResizingWindows.remove(i);
1060 }
1061
1062 if (DEBUG_ORIENTATION && mService.mDisplayFrozen) Slog.v(TAG,
1063 "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
1064 if (mOrientationChangeComplete) {
1065 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
1066 mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
1067 mService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
1068 mService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
1069 }
1070 mService.stopFreezingDisplayLocked();
1071 }
1072
1073 // Destroy the surface of any windows that are no longer visible.
1074 boolean wallpaperDestroyed = false;
1075 i = mService.mDestroySurface.size();
1076 if (i > 0) {
1077 do {
1078 i--;
1079 WindowState win = mService.mDestroySurface.get(i);
1080 win.mDestroying = false;
1081 if (mService.mInputMethodWindow == win) {
1082 mService.mInputMethodWindow = null;
1083 }
Wale Ogunwale0303c572016-10-20 10:16:29 -07001084 if (win.getDisplayContent().mWallpaperController.isWallpaperTarget(win)) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001085 wallpaperDestroyed = true;
1086 }
1087 win.destroyOrSaveSurface();
1088 } while (i > 0);
1089 mService.mDestroySurface.clear();
1090 }
1091
1092 // Time to remove any exiting tokens?
1093 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001094 final DisplayContent displayContent = mChildren.get(displayNdx);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001095 ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
1096 for (i = exitingTokens.size() - 1; i >= 0; i--) {
1097 WindowToken token = exitingTokens.get(i);
1098 if (!token.hasVisible) {
1099 exitingTokens.remove(i);
1100 if (token.windowType == TYPE_WALLPAPER) {
Wale Ogunwale0303c572016-10-20 10:16:29 -07001101 displayContent.mWallpaperController.removeWallpaperToken(token);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001102 }
1103 }
1104 }
1105 }
1106
1107 // Time to remove any exiting applications?
1108 for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
1109 // Initialize state of exiting applications.
1110 final AppTokenList exitingAppTokens =
1111 mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
1112 for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
1113 final AppWindowToken token = exitingAppTokens.get(i);
1114 if (!token.hasVisible && !mService.mClosingApps.contains(token) &&
1115 (!token.mIsExiting || token.isEmpty())) {
1116 // Make sure there is no animation running on this token, so any windows
1117 // associated with it will be removed as soon as their animations are complete
1118 token.mAppAnimator.clearAnimation();
1119 token.mAppAnimator.animating = false;
1120 if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
1121 "performLayout: App token exiting now removed" + token);
1122 token.removeIfPossible();
1123 }
1124 }
1125 }
1126
1127 if (wallpaperDestroyed) {
1128 defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001129 defaultDisplay.setLayoutNeeded();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001130 }
1131
1132 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001133 final DisplayContent displayContent = mChildren.get(displayNdx);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001134 if (displayContent.pendingLayoutChanges != 0) {
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001135 displayContent.setLayoutNeeded();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001136 }
1137 }
1138
1139 // Finally update all input windows now that the window changes have stabilized.
1140 mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
1141
1142 mService.setHoldScreenLocked(mHoldScreen);
1143 if (!mService.mDisplayFrozen) {
1144 if (mScreenBrightness < 0 || mScreenBrightness > 1.0f) {
1145 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
1146 } else {
1147 mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
1148 toBrightnessOverride(mScreenBrightness));
1149 }
1150 if (mButtonBrightness < 0 || mButtonBrightness > 1.0f) {
1151 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
1152 } else {
1153 mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
1154 toBrightnessOverride(mButtonBrightness));
1155 }
1156 mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
1157 mUserActivityTimeout);
1158 }
1159
1160 if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) {
1161 mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent;
1162 mService.mPowerManagerInternal.powerHint(
Ruchi Kandoi0d434042016-10-03 09:12:02 -07001163 PowerHint.SUSTAINED_PERFORMANCE,
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001164 (mSustainedPerformanceModeEnabled ? 1 : 0));
1165 }
1166
1167 if (mService.mTurnOnScreen) {
1168 if (mService.mAllowTheaterModeWakeFromLayout
1169 || Settings.Global.getInt(mService.mContext.getContentResolver(),
1170 Settings.Global.THEATER_MODE_ON, 0) == 0) {
1171 if (DEBUG_VISIBILITY || DEBUG_POWER) {
1172 Slog.v(TAG, "Turning screen on after layout!");
1173 }
1174 mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
1175 "android.server.wm:TURN_ON");
1176 }
1177 mService.mTurnOnScreen = false;
1178 }
1179
1180 if (mUpdateRotation) {
1181 if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
Andrii Kulian5406e7a2016-10-21 11:55:23 -07001182 // TODO(multi-display): Update rotation for different displays separately.
1183 final int displayId = defaultDisplay.getDisplayId();
1184 if (mService.updateRotationUncheckedLocked(false, displayId)) {
1185 mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, displayId).sendToTarget();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001186 } else {
1187 mUpdateRotation = false;
1188 }
1189 }
1190
1191 if (mService.mWaitingForDrawnCallback != null ||
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001192 (mOrientationChangeComplete && !defaultDisplay.isLayoutNeeded()
1193 && !mUpdateRotation)) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001194 mService.checkDrawnWindowsLocked();
1195 }
1196
1197 final int N = mService.mPendingRemove.size();
1198 if (N > 0) {
1199 if (mService.mPendingRemoveTmp.length < N) {
1200 mService.mPendingRemoveTmp = new WindowState[N+10];
1201 }
1202 mService.mPendingRemove.toArray(mService.mPendingRemoveTmp);
1203 mService.mPendingRemove.clear();
Wale Ogunwale19e452e2016-10-12 12:36:29 -07001204 ArrayList<DisplayContent> displayList = new ArrayList();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001205 for (i = 0; i < N; i++) {
1206 final WindowState w = mService.mPendingRemoveTmp[i];
1207 w.removeImmediately();
1208 final DisplayContent displayContent = w.getDisplayContent();
1209 if (displayContent != null && !displayList.contains(displayContent)) {
1210 displayList.add(displayContent);
1211 }
1212 }
1213
Wale Ogunwalec69694a2016-10-18 13:51:15 -07001214 for (int j = displayList.size() - 1; j >= 0; --j) {
1215 final DisplayContent dc = displayList.get(j);
1216 dc.assignWindowLayers(true /*setLayoutNeeded*/);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001217 }
1218 }
1219
1220 // Remove all deferred displays stacks, tasks, and activities.
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001221 for (int displayNdx = mChildren.size() - 1; displayNdx >= 0; --displayNdx) {
1222 mChildren.get(displayNdx).checkCompleteDeferredRemoval();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001223 }
1224
1225 if (updateInputWindowsNeeded) {
1226 mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
1227 }
1228 mService.setFocusTaskRegionLocked();
1229
1230 // Check to see if we are now in a state where the screen should
1231 // be enabled, because the window obscured flags have changed.
1232 mService.enableScreenIfNeededLocked();
1233
1234 mService.scheduleAnimationLocked();
1235 mService.mWindowPlacerLocked.destroyPendingSurfaces();
1236
1237 if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
1238 "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
1239 }
1240
1241 // TODO: Super crazy long method that should be broken down...
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001242 private void applySurfaceChangesTransaction(boolean recoveringMemory, int defaultDw, int defaultDh) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001243 mHoldScreenWindow = null;
Wale Ogunwaled4a00a02016-10-10 11:29:17 -07001244 mObscuringWindow = null;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001245
1246 if (mService.mWatermark != null) {
1247 mService.mWatermark.positionSurface(defaultDw, defaultDh);
1248 }
1249 if (mService.mStrictModeFlash != null) {
1250 mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
1251 }
1252 if (mService.mCircularDisplayMask != null) {
1253 mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh, mService.mRotation);
1254 }
1255 if (mService.mEmulatorDisplayOverlay != null) {
1256 mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
1257 mService.mRotation);
1258 }
1259
1260 boolean focusDisplayed = false;
1261
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001262 final int count = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001263 for (int j = 0; j < count; ++j) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001264 final DisplayContent dc = mChildren.get(j);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001265 WindowList windows = dc.getWindowList();
1266 DisplayInfo displayInfo = dc.getDisplayInfo();
1267 final int displayId = dc.getDisplayId();
1268 final int dw = displayInfo.logicalWidth;
1269 final int dh = displayInfo.logicalHeight;
Andrii Kulian5406e7a2016-10-21 11:55:23 -07001270 final boolean isDefaultDisplay = (displayId == DEFAULT_DISPLAY);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001271 final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked;
1272
1273 // Reset for each display.
1274 mDisplayHasContent = false;
1275 mPreferredRefreshRate = 0;
1276 mPreferredModeId = 0;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001277 mTmpUpdateAllDrawn.clear();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001278
1279 int repeats = 0;
1280 do {
1281 repeats++;
1282 if (repeats > 6) {
1283 Slog.w(TAG, "Animation repeat aborted after too many iterations");
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001284 dc.clearLayoutNeeded();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001285 break;
1286 }
1287
1288 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
1289 "On entry to LockedInner", dc.pendingLayoutChanges);
1290
Wale Ogunwale0303c572016-10-20 10:16:29 -07001291 if ((dc.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
1292 dc.adjustWallpaperWindows();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001293 }
1294
1295 if (isDefaultDisplay
1296 && (dc.pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
1297 if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
Andrii Kulian5406e7a2016-10-21 11:55:23 -07001298 if (mService.updateOrientationFromAppTokensLocked(true, displayId)) {
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001299 dc.setLayoutNeeded();
Andrii Kulian5406e7a2016-10-21 11:55:23 -07001300 mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, displayId).sendToTarget();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001301 }
1302 }
1303
1304 if ((dc.pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001305 dc.setLayoutNeeded();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001306 }
1307
1308 // FIRST LOOP: Perform a layout, if needed.
1309 if (repeats < LAYOUT_REPEAT_THRESHOLD) {
1310 surfacePlacer.performLayoutLockedInner(dc, repeats == 1,
1311 false /* updateInputWindows */);
1312 } else {
1313 Slog.w(TAG, "Layout repeat skipped after too many iterations");
1314 }
1315
1316 // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
1317 // it is animating.
1318 dc.pendingLayoutChanges = 0;
1319
1320 if (isDefaultDisplay) {
1321 mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
1322 for (int i = windows.size() - 1; i >= 0; i--) {
1323 WindowState w = windows.get(i);
1324 if (w.mHasSurface) {
1325 mService.mPolicy.applyPostLayoutPolicyLw(
1326 w, w.mAttrs, w.getParentWindow());
1327 }
1328 }
1329 dc.pendingLayoutChanges |=
1330 mService.mPolicy.finishPostLayoutPolicyLw();
1331 if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
1332 "after finishPostLayoutPolicyLw", dc.pendingLayoutChanges);
1333 }
1334 } while (dc.pendingLayoutChanges != 0);
1335
1336 mObscured = false;
1337 mSyswin = false;
1338 dc.resetDimming();
1339
1340 // Only used if default window
1341 final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
1342
1343 for (int i = windows.size() - 1; i >= 0; i--) {
1344 WindowState w = windows.get(i);
1345 final Task task = w.getTask();
1346 final boolean obscuredChanged = w.mObscured != mObscured;
1347
1348 // Update effect.
1349 w.mObscured = mObscured;
1350 if (!mObscured) {
1351 handleNotObscuredLocked(w, displayInfo);
1352 }
1353
1354 w.applyDimLayerIfNeeded();
1355
1356 if (isDefaultDisplay && obscuredChanged && w.isVisibleLw()
Wale Ogunwale0303c572016-10-20 10:16:29 -07001357 && dc.mWallpaperController.isWallpaperTarget(w)) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001358 // This is the wallpaper target and its obscured state changed... make sure the
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001359 // current wallpaper's visibility has been updated accordingly.
Wale Ogunwale0303c572016-10-20 10:16:29 -07001360 dc.mWallpaperController.updateWallpaperVisibility();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001361 }
1362
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001363 w.handleWindowMovedIfNeeded();
1364
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001365 final WindowStateAnimator winAnimator = w.mWinAnimator;
1366
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001367 //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
1368 w.mContentChanged = false;
1369
1370 // Moved from updateWindowsAndWallpaperLocked().
1371 if (w.mHasSurface) {
1372 // Take care of the window being ready to display.
1373 final boolean committed = winAnimator.commitFinishDrawingLocked();
1374 if (isDefaultDisplay && committed) {
1375 if (w.mAttrs.type == TYPE_DREAM) {
1376 // HACK: When a dream is shown, it may at that point hide the lock
1377 // screen. So we need to redo the layout to let the phone window manager
1378 // make this happen.
1379 dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
1380 if (DEBUG_LAYOUT_REPEATS) {
1381 surfacePlacer.debugLayoutRepeats(
1382 "dream and commitFinishDrawingLocked true",
1383 dc.pendingLayoutChanges);
1384 }
1385 }
1386 if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
1387 if (DEBUG_WALLPAPER_LIGHT)
1388 Slog.v(TAG, "First draw done in potential wallpaper target " + w);
1389 mWallpaperMayChange = true;
1390 dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
1391 if (DEBUG_LAYOUT_REPEATS) {
1392 surfacePlacer.debugLayoutRepeats(
1393 "wallpaper and commitFinishDrawingLocked true",
1394 dc.pendingLayoutChanges);
1395 }
1396 }
1397 }
1398 if (!winAnimator.isAnimationStarting() && !winAnimator.isWaitingForOpening()) {
1399 // Updates the shown frame before we set up the surface. This is needed
1400 // because the resizing could change the top-left position (in addition to
1401 // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
1402 // position the surface.
1403 //
1404 // If an animation is being started, we can't call this method because the
1405 // animation hasn't processed its initial transformation yet, but in general
1406 // we do want to update the position if the window is animating.
1407 winAnimator.computeShownFrameLocked();
1408 }
1409 winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
1410 }
1411
1412 final AppWindowToken atoken = w.mAppToken;
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001413 if (atoken != null) {
1414 final boolean updateAllDrawn = atoken.updateDrawnWindowStates(w);
1415 if (updateAllDrawn && !mTmpUpdateAllDrawn.contains(atoken)) {
1416 mTmpUpdateAllDrawn.add(atoken);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001417 }
1418 }
1419
1420 if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
1421 && w.isDisplayedLw()) {
1422 focusDisplayed = true;
1423 }
1424
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001425 w.updateResizingWindowIfNeeded();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001426 }
1427
1428 mService.mDisplayManagerInternal.setDisplayProperties(displayId,
1429 mDisplayHasContent,
1430 mPreferredRefreshRate,
1431 mPreferredModeId,
1432 true /* inTraversal, must call performTraversalInTrans... below */);
1433
1434 dc.stopDimmingIfNeeded();
1435
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001436 while (!mTmpUpdateAllDrawn.isEmpty()) {
1437 final AppWindowToken atoken = mTmpUpdateAllDrawn.removeLast();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001438 // See if any windows have been drawn, so they (and others associated with them)
1439 // can now be shown.
Wale Ogunwale9d9d8f12016-09-28 15:29:59 -07001440 atoken.updateAllDrawn(dc);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001441 }
1442 }
1443
1444 if (focusDisplayed) {
1445 mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
1446 }
1447
1448 // Give the display manager a chance to adjust properties
1449 // like display rotation if it needs to.
1450 mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
1451 }
1452
1453 /**
1454 * @param w WindowState this method is applied to.
1455 * @param dispInfo info of the display that the window's obscuring state is checked against.
1456 */
1457 private void handleNotObscuredLocked(final WindowState w, final DisplayInfo dispInfo) {
1458 final WindowManager.LayoutParams attrs = w.mAttrs;
1459 final int attrFlags = attrs.flags;
1460 final boolean canBeSeen = w.isDisplayedLw();
1461 final int privateflags = attrs.privateFlags;
1462
1463 if (canBeSeen && w.isObscuringFullscreen(dispInfo)) {
1464 // This window completely covers everything behind it,
1465 // so we want to leave all of them as undimmed (for
1466 // performance reasons).
1467 if (!mObscured) {
Wale Ogunwaled4a00a02016-10-10 11:29:17 -07001468 mObscuringWindow = w;
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001469 }
1470
1471 mObscured = true;
1472 }
1473
1474 if (w.mHasSurface && canBeSeen) {
1475 if ((attrFlags & FLAG_KEEP_SCREEN_ON) != 0) {
1476 mHoldScreen = w.mSession;
1477 mHoldScreenWindow = w;
1478 } else if (DEBUG_KEEP_SCREEN_ON && w == mService.mLastWakeLockHoldingWindow) {
1479 Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w + " was holding "
1480 + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by"
1481 + Debug.getCallers(10));
1482 }
1483 if (!mSyswin && w.mAttrs.screenBrightness >= 0 && mScreenBrightness < 0) {
1484 mScreenBrightness = w.mAttrs.screenBrightness;
1485 }
1486 if (!mSyswin && w.mAttrs.buttonBrightness >= 0 && mButtonBrightness < 0) {
1487 mButtonBrightness = w.mAttrs.buttonBrightness;
1488 }
1489 if (!mSyswin && w.mAttrs.userActivityTimeout >= 0 && mUserActivityTimeout < 0) {
1490 mUserActivityTimeout = w.mAttrs.userActivityTimeout;
1491 }
1492
1493 final int type = attrs.type;
1494 if (type == TYPE_SYSTEM_DIALOG || type == TYPE_SYSTEM_ERROR
1495 || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
1496 mSyswin = true;
1497 }
1498
1499 // This function assumes that the contents of the default display are processed first
1500 // before secondary displays.
1501 final DisplayContent displayContent = w.getDisplayContent();
1502 if (displayContent != null && displayContent.isDefaultDisplay) {
1503 // While a dream or keyguard is showing, obscure ordinary application content on
1504 // secondary displays (by forcibly enabling mirroring unless there is other content
1505 // we want to show) but still allow opaque keyguard dialogs to be shown.
1506 if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
1507 mObscureApplicationContentOnSecondaryDisplays = true;
1508 }
1509 mDisplayHasContent = true;
1510 } else if (displayContent != null &&
1511 (!mObscureApplicationContentOnSecondaryDisplays
1512 || (mObscured && type == TYPE_KEYGUARD_DIALOG))) {
1513 // Allow full screen keyguard presentation dialogs to be seen.
1514 mDisplayHasContent = true;
1515 }
1516 if (mPreferredRefreshRate == 0 && w.mAttrs.preferredRefreshRate != 0) {
1517 mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
1518 }
1519 if (mPreferredModeId == 0 && w.mAttrs.preferredDisplayModeId != 0) {
1520 mPreferredModeId = w.mAttrs.preferredDisplayModeId;
1521 }
1522 if ((privateflags & PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE) != 0) {
1523 mSustainedPerformanceModeCurrent = true;
1524 }
1525 }
1526 }
1527
1528 boolean copyAnimToLayoutParams() {
1529 boolean doRequest = false;
1530
1531 final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
1532 if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
1533 mUpdateRotation = true;
1534 doRequest = true;
1535 }
1536 if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
1537 mWallpaperMayChange = true;
1538 doRequest = true;
1539 }
1540 if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
1541 mWallpaperForceHidingChanged = true;
1542 doRequest = true;
1543 }
1544 if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
1545 mOrientationChangeComplete = false;
1546 } else {
1547 mOrientationChangeComplete = true;
1548 mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
1549 if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
1550 doRequest = true;
1551 }
1552 }
1553 if ((bulkUpdateParams & SET_TURN_ON_SCREEN) != 0) {
1554 mService.mTurnOnScreen = true;
1555 }
1556 if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
1557 mWallpaperActionPending = true;
1558 }
1559
1560 return doRequest;
1561 }
1562
1563 private static int toBrightnessOverride(float value) {
1564 return (int)(value * PowerManager.BRIGHTNESS_ON);
1565 }
1566
1567 void enableSurfaceTrace(ParcelFileDescriptor pfd) {
1568 final FileDescriptor fd = pfd.getFileDescriptor();
1569 if (mSurfaceTraceEnabled) {
1570 disableSurfaceTrace();
1571 }
1572 mSurfaceTraceEnabled = true;
1573 mRemoteEventTrace = new RemoteEventTrace(mService, fd);
1574 mSurfaceTraceFd = pfd;
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001575 for (int displayNdx = mChildren.size() - 1; displayNdx >= 0; --displayNdx) {
1576 final DisplayContent dc = mChildren.get(displayNdx);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001577 dc.enableSurfaceTrace(fd);
1578 }
1579 }
1580
1581 void disableSurfaceTrace() {
1582 mSurfaceTraceEnabled = false;
1583 mRemoteEventTrace = null;
1584 mSurfaceTraceFd = null;
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001585 for (int displayNdx = mChildren.size() - 1; displayNdx >= 0; --displayNdx) {
1586 final DisplayContent dc = mChildren.get(displayNdx);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001587 dc.disableSurfaceTrace();
1588 }
1589 }
1590
1591 void dumpDisplayContents(PrintWriter pw) {
1592 pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)");
1593 if (mService.mDisplayReady) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001594 final int count = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001595 for (int i = 0; i < count; ++i) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001596 final DisplayContent displayContent = mChildren.get(i);
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001597 displayContent.dump(" ", pw);
1598 }
1599 } else {
1600 pw.println(" NO DISPLAY");
1601 }
1602 }
1603
1604 void dumpLayoutNeededDisplayIds(PrintWriter pw) {
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001605 if (!isLayoutNeeded()) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001606 return;
1607 }
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001608 pw.print(" mLayoutNeeded on displays=");
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001609 final int count = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001610 for (int displayNdx = 0; displayNdx < count; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001611 final DisplayContent displayContent = mChildren.get(displayNdx);
Wale Ogunwale2b06bfc2016-09-28 14:17:05 -07001612 if (displayContent.isLayoutNeeded()) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001613 pw.print(displayContent.getDisplayId());
1614 }
1615 }
1616 pw.println();
1617 }
1618
1619 void dumpWindowsNoHeader(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001620 final int numDisplays = mChildren.size();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001621 for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
Wale Ogunwaleeaabfab2016-09-16 17:19:52 -07001622 final WindowList windowList = mChildren.get(displayNdx).getWindowList();
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001623 for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
1624 final WindowState w = windowList.get(winNdx);
1625 if (windows == null || windows.contains(w)) {
1626 pw.println(" Window #" + winNdx + " " + w + ":");
1627 w.dump(pw, " ", dumpAll || windows != null);
1628 }
1629 }
1630 }
1631 }
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07001632
Wale Ogunwale02319a62016-09-26 15:21:22 -07001633 void dumpTokens(PrintWriter pw, boolean dumpAll) {
1634 pw.println(" All tokens:");
1635 for (int i = mChildren.size() - 1; i >= 0; --i) {
1636 mChildren.get(i).dumpTokens(pw, dumpAll);
1637 }
1638 }
1639
Wale Ogunwaleba51ca22016-09-23 06:06:54 -07001640 @Override
1641 String getName() {
1642 return "ROOT";
1643 }
Wale Ogunwalee05f5012016-09-16 16:27:29 -07001644}