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