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