Added RootWindowContainer
RootWindowContainer will be the root/head of the window hierarchy.
Also, moved all access of DisplayContent into RootWindowContainer.
Bug: 30060889
Test: Manual testing and existing tests still pass.
Change-Id: Icdf80a4c053578fb91221e6f2b672e197054a6bf
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 4d12ba9..2ae4b2a 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -1055,7 +1055,7 @@
@Override
void updateAllDrawn(int displayId) {
- final DisplayContent displayContent = mService.getDisplayContentLocked(displayId);
+ final DisplayContent displayContent = mService.mRoot.getDisplayContent(displayId);
if (!allDrawn) {
final int numInteresting = numInterestingWindows;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 1c83a9b..54e3058 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -432,7 +432,7 @@
}
}
- void switchUserStacks() {
+ void switchUser() {
final WindowList windows = getWindowList();
for (int i = 0; i < windows.size(); i++) {
final WindowState win = windows.get(i);
@@ -485,7 +485,8 @@
void removeImmediately() {
super.removeImmediately();
if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this);
- mService.mDisplayContents.delete(mDisplayId);
+ // TODO: remove this line once RootWindowContainer is online.
+ mService.mRoot.mDisplayContents.delete(mDisplayId);
mDimLayerController.close();
if (mDisplayId == Display.DEFAULT_DISPLAY) {
mService.unregisterPointerEventListener(mTapDetector);
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 535ce9d..a5387bd 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -165,7 +165,7 @@
return 0; // abort dispatching
}
- private void addInputWindowHandleLw(final InputWindowHandle windowHandle) {
+ void addInputWindowHandle(final InputWindowHandle windowHandle) {
if (mInputWindowHandles == null) {
mInputWindowHandles = new InputWindowHandle[16];
}
@@ -176,7 +176,7 @@
mInputWindowHandles[mInputWindowHandleCount++] = windowHandle;
}
- private void addInputWindowHandleLw(final InputWindowHandle inputWindowHandle,
+ void addInputWindowHandle(final InputWindowHandle inputWindowHandle,
final WindowState child, int flags, final int type, final boolean isVisible,
final boolean hasFocus, final boolean hasWallpaper) {
// Add a window to our list of input windows.
@@ -214,7 +214,7 @@
Slog.d(TAG_WM, "addInputWindowHandle: "
+ child + ", " + inputWindowHandle);
}
- addInputWindowHandleLw(inputWindowHandle);
+ addInputWindowHandle(inputWindowHandle);
}
private void clearInputWindowHandlesLw() {
@@ -241,9 +241,8 @@
// As an optimization, we could try to prune the list of windows but this turns
// out to be difficult because only the native code knows for sure which window
// currently has touch focus.
- boolean disableWallpaperTouchEvents = false;
- // If there's a drag in flight, provide a pseudowindow to catch drag input
+ // If there's a drag in flight, provide a pseudo-window to catch drag input
final boolean inDrag = (mService.mDragState != null);
if (inDrag) {
if (DEBUG_DRAG) {
@@ -251,7 +250,7 @@
}
final InputWindowHandle dragWindowHandle = mService.mDragState.getInputWindowHandle();
if (dragWindowHandle != null) {
- addInputWindowHandleLw(dragWindowHandle);
+ addInputWindowHandle(dragWindowHandle);
} else {
Slog.w(TAG_WM, "Drag is in progress but there is no "
+ "drag window handle.");
@@ -265,78 +264,15 @@
}
final InputWindowHandle dragWindowHandle = mService.mTaskPositioner.mDragWindowHandle;
if (dragWindowHandle != null) {
- addInputWindowHandleLw(dragWindowHandle);
+ addInputWindowHandle(dragWindowHandle);
} else {
Slog.e(TAG_WM,
"Repositioning is in progress but there is no drag window handle.");
}
}
- boolean addInputConsumerHandle = mService.mInputConsumer != null;
-
- boolean addWallpaperInputConsumerHandle = mService.mWallpaperInputConsumer != null;
-
// Add all windows on the default display.
- final int numDisplays = mService.mDisplayContents.size();
- final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
- final WindowList windows = displayContent.getWindowList();
- for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
- final WindowState child = windows.get(winNdx);
- final InputChannel inputChannel = child.mInputChannel;
- final InputWindowHandle inputWindowHandle = child.mInputWindowHandle;
- if (inputChannel == null || inputWindowHandle == null || child.mRemoved
- || child.isAdjustedForMinimizedDock()) {
- // Skip this window because it cannot possibly receive input.
- continue;
- }
- if (addInputConsumerHandle
- && inputWindowHandle.layer <= mService.mInputConsumer.mWindowHandle.layer) {
- addInputWindowHandleLw(mService.mInputConsumer.mWindowHandle);
- addInputConsumerHandle = false;
- }
-
- if (addWallpaperInputConsumerHandle) {
- if (child.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER &&
- child.isVisibleLw()) {
- // Add the wallpaper input consumer above the first visible wallpaper.
- addInputWindowHandleLw(mService.mWallpaperInputConsumer.mWindowHandle);
- addWallpaperInputConsumerHandle = false;
- }
- }
-
- final int flags = child.mAttrs.flags;
- final int privateFlags = child.mAttrs.privateFlags;
- final int type = child.mAttrs.type;
-
- final boolean hasFocus = (child == mInputFocus);
- final boolean isVisible = child.isVisibleLw();
- if ((privateFlags
- & WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS)
- != 0) {
- disableWallpaperTouchEvents = true;
- }
- final boolean hasWallpaper = wallpaperController.isWallpaperTarget(child)
- && (privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD) == 0
- && !disableWallpaperTouchEvents;
- final boolean onDefaultDisplay = (child.getDisplayId() == Display.DEFAULT_DISPLAY);
-
- // If there's a drag in progress and 'child' is a potential drop target,
- // make sure it's been told about the drag
- if (inDrag && isVisible && onDefaultDisplay) {
- mService.mDragState.sendDragStartedIfNeededLw(child);
- }
-
- addInputWindowHandleLw(
- inputWindowHandle, child, flags, type, isVisible, hasFocus, hasWallpaper);
- }
- }
-
- if (addWallpaperInputConsumerHandle) {
- // No visible wallpaper found, add the wallpaper input consumer at the end.
- addInputWindowHandleLw(mService.mWallpaperInputConsumer.mWindowHandle);
- }
+ mService.mRoot.updateInputWindows(this, mInputFocus, inDrag);
// Send windows to native code.
mService.mInputManager.setInputWindows(mInputWindowHandles);
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
new file mode 100644
index 0000000..d119fb7a
--- /dev/null
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -0,0 +1,1419 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import android.app.AppOpsManager;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.Binder;
+import android.os.Debug;
+import android.os.ParcelFileDescriptor;
+import android.os.PowerManager;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.EventLog;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
+import android.view.Display;
+import android.view.DisplayInfo;
+import android.view.InputChannel;
+import android.view.WindowManager;
+import com.android.internal.util.ArrayUtils;
+import com.android.server.EventLogTags;
+import com.android.server.input.InputWindowHandle;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
+import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
+import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
+import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.WindowManagerService.H.NOTIFY_STARTING_WINDOW_DRAWN;
+import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
+import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
+import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
+import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
+import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
+import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
+import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT;
+import static com.android.server.wm.WindowManagerService.logSurface;
+import static com.android.server.wm.WindowSurfacePlacer.SET_FORCE_HIDING_CHANGED;
+import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
+import static com.android.server.wm.WindowSurfacePlacer.SET_TURN_ON_SCREEN;
+import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
+import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
+import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE;
+
+/** Root {@link WindowContainer} for the device. */
+// TODO: Several methods in here are accessing children of this container's children through various
+// references (WindowList I am looking at you :/). See if we can delegate instead.
+class RootWindowContainer {
+ private static final String TAG = TAG_WITH_CLASS_NAME ? "RootWindowContainer" : TAG_WM;
+
+ WindowManagerService mService;
+
+ /** All DisplayContents in the world, kept here */
+ SparseArray<DisplayContent> mDisplayContents = new SparseArray<>(2);
+
+ private boolean mWallpaperForceHidingChanged = false;
+ private Object mLastWindowFreezeSource = null;
+ private Session mHoldScreen = null;
+ private float mScreenBrightness = -1;
+ private float mButtonBrightness = -1;
+ private long mUserActivityTimeout = -1;
+ private boolean mUpdateRotation = false;
+ private boolean mObscured = false;
+ boolean mSyswin = false;
+ // Set to true when the display contains content to show the user.
+ // When false, the display manager may choose to mirror or blank the display.
+ private boolean mDisplayHasContent = false;
+ private float mPreferredRefreshRate = 0;
+ private int mPreferredModeId = 0;
+ // Following variables are for debugging screen wakelock only.
+ // Last window that requires screen wakelock
+ WindowState mHoldScreenWindow = null;
+ // Last window that obscures all windows below
+ WindowState mObsuringWindow = null;
+ // Only set while traversing the default display based on its content.
+ // Affects the behavior of mirroring on secondary displays.
+ private boolean mObscureApplicationContentOnSecondaryDisplays = false;
+
+ private boolean mSustainedPerformanceModeEnabled = false;
+ private boolean mSustainedPerformanceModeCurrent = false;
+
+ boolean mWallpaperMayChange = false;
+ boolean mOrientationChangeComplete = true;
+ boolean mWallpaperActionPending = false;
+
+ private final ArrayList<Integer> mChangedStackList = new ArrayList();
+
+ // State for the RemoteSurfaceTrace system used in testing. If this is enabled SurfaceControl
+ // instances will be replaced with an instance that writes a binary representation of all
+ // commands to mSurfaceTraceFd.
+ boolean mSurfaceTraceEnabled;
+ ParcelFileDescriptor mSurfaceTraceFd;
+ RemoteEventTrace mRemoteEventTrace;
+
+ RootWindowContainer(WindowManagerService service) {
+ mService = service;
+ }
+
+ WindowState computeFocusedWindow() {
+ final int count = mDisplayContents.size();
+ for (int i = 0; i < count; i++) {
+ final DisplayContent dc = mDisplayContents.valueAt(i);
+ final WindowState win = dc.findFocusedWindow();
+ if (win != null) {
+ return win;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Retrieve the DisplayContent for the specified displayId. Will create a new DisplayContent if
+ * there is a Display for the displayId.
+ *
+ * @param displayId The display the caller is interested in.
+ * @return The DisplayContent associated with displayId or null if there is no Display for it.
+ */
+ DisplayContent getDisplayContent(final int displayId) {
+ DisplayContent dc = mDisplayContents.get(displayId);
+ if (dc == null) {
+ final Display display = mService.mDisplayManager.getDisplay(displayId);
+ if (display != null) {
+ dc = createDisplayContent(display);
+ }
+ }
+ return dc;
+ }
+
+ private DisplayContent createDisplayContent(final Display display) {
+ DisplayContent displayContent = new DisplayContent(display, mService);
+ final int displayId = display.getDisplayId();
+ if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Adding display=" + display);
+ mDisplayContents.put(displayId, displayContent);
+
+ final DisplayInfo displayInfo = displayContent.getDisplayInfo();
+ final Rect rect = new Rect();
+ mService.mDisplaySettings.getOverscanLocked(displayInfo.name, displayInfo.uniqueId, rect);
+ displayInfo.overscanLeft = rect.left;
+ displayInfo.overscanTop = rect.top;
+ displayInfo.overscanRight = rect.right;
+ displayInfo.overscanBottom = rect.bottom;
+ if (mService.mDisplayManagerInternal != null) {
+ mService.mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
+ displayId, displayInfo);
+ mService.configureDisplayPolicyLocked(displayContent);
+
+ // TODO(multi-display): Create an input channel for each display with touch capability.
+ if (displayId == Display.DEFAULT_DISPLAY) {
+ displayContent.mTapDetector = new TaskTapPointerEventListener(
+ mService, displayContent);
+ mService.registerPointerEventListener(displayContent.mTapDetector);
+ mService.registerPointerEventListener(mService.mMousePositionTracker);
+ }
+ }
+
+ return displayContent;
+ }
+
+ /** Adds the input stack id to the input display id and returns the bounds of the added stack.*/
+ Rect addStackToDisplay(int stackId, int displayId, boolean onTop) {
+ final DisplayContent dc = mDisplayContents.get(displayId);
+ if (dc == null) {
+ Slog.w(TAG_WM, "addStackToDisplay: Trying to add stackId=" + stackId
+ + " to unknown displayId=" + displayId + " callers=" + Debug.getCallers(6));
+ return null;
+ }
+
+ boolean attachedToDisplay = false;
+ TaskStack stack = mService.mStackIdToStack.get(stackId);
+ if (stack == null) {
+ if (DEBUG_STACK) Slog.d(TAG_WM, "attachStack: stackId=" + stackId);
+
+ stack = dc.getStackById(stackId);
+ if (stack != null) {
+ // It's already attached to the display...clear mDeferRemoval!
+ stack.mDeferRemoval = false;
+ attachedToDisplay = true;
+ } else {
+ stack = new TaskStack(mService, stackId);
+ }
+
+ mService.mStackIdToStack.put(stackId, stack);
+ if (stackId == DOCKED_STACK_ID) {
+ mService.getDefaultDisplayContentLocked().mDividerControllerLocked
+ .notifyDockedStackExistsChanged(true);
+ }
+ }
+ if (!attachedToDisplay) {
+ stack.attachDisplayContent(dc);
+ }
+ dc.attachStack(stack, onTop);
+ if (stack.getRawFullscreen()) {
+ return null;
+ }
+ Rect bounds = new Rect();
+ stack.getRawBounds(bounds);
+ return bounds;
+ }
+
+ boolean layoutNeeded() {
+ final int numDisplays = mDisplayContents.size();
+ for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+ final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
+ if (displayContent.layoutNeeded) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void getWindows(WindowList output) {
+ final int count = mDisplayContents.size();
+ for (int i = 0; i < count; ++i) {
+ final DisplayContent dc = mDisplayContents.valueAt(i);
+ output.addAll(dc.getWindowList());
+ }
+ }
+
+ void getWindows(WindowList output, boolean visibleOnly, boolean appsOnly) {
+ final int numDisplays = mDisplayContents.size();
+ for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+ final WindowList windowList = mDisplayContents.valueAt(displayNdx).getWindowList();
+ for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
+ final WindowState w = windowList.get(winNdx);
+ if ((!visibleOnly || w.mWinAnimator.getShown())
+ && (!appsOnly || w.mAppToken != null)) {
+ output.add(w);
+ }
+ }
+ }
+ }
+
+ void getWindowsByName(WindowList output, String name) {
+ int objectId = 0;
+ // See if this is an object ID.
+ try {
+ objectId = Integer.parseInt(name, 16);
+ name = null;
+ } catch (RuntimeException e) {
+ }
+ final int numDisplays = mDisplayContents.size();
+ for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+ final WindowList windowList = mDisplayContents.valueAt(displayNdx).getWindowList();
+ for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
+ final WindowState w = windowList.get(winNdx);
+ if (name != null) {
+ if (w.mAttrs.getTitle().toString().contains(name)) {
+ output.add(w);
+ }
+ } else if (System.identityHashCode(w) == objectId) {
+ output.add(w);
+ }
+ }
+ }
+ }
+
+ WindowState findWindow(int hashCode) {
+ final int numDisplays = mDisplayContents.size();
+ for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+ final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
+ final int numWindows = windows.size();
+ for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
+ final WindowState w = windows.get(winNdx);
+ if (System.identityHashCode(w) == hashCode) {
+ return w;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ // TODO: Users would have their own window containers under the display container?
+ void switchUser() {
+ final int count = mDisplayContents.size();
+ for (int i = 0; i < count; ++i) {
+ final DisplayContent dc = mDisplayContents.valueAt(i);
+ dc.switchUser();
+ }
+ }
+
+ int[] onConfigurationChanged(Configuration config) {
+ prepareFreezingTaskBounds();
+ mService.mGlobalConfiguration = new Configuration(config);
+
+ mService.mPolicy.onConfigurationChanged();
+
+ mChangedStackList.clear();
+
+ final int numDisplays = mDisplayContents.size();
+ for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+ final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
+ displayContent.onConfigurationChanged(mChangedStackList);
+ }
+
+ return mChangedStackList.isEmpty() ? null : ArrayUtils.convertToIntArray(mChangedStackList);
+ }
+
+ private void prepareFreezingTaskBounds() {
+ for (int i = mDisplayContents.size() - 1; i >= 0; i--) {
+ mDisplayContents.valueAt(i).prepareFreezingTaskBounds();
+ }
+ }
+
+ void setSecureSurfaceState(int userId, boolean disabled) {
+ for (int i = mDisplayContents.size() - 1; i >= 0; --i) {
+ final WindowList windows = mDisplayContents.valueAt(i).getWindowList();
+ for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+ final WindowState win = windows.get(winNdx);
+ if (win.mHasSurface && userId == UserHandle.getUserId(win.mOwnerUid)) {
+ win.mWinAnimator.setSecureLocked(disabled);
+ }
+ }
+ }
+ }
+
+ void updateAppOpsState() {
+ final int count = mDisplayContents.size();
+ for (int i = 0; i < count; ++i) {
+ final WindowList windows = mDisplayContents.valueAt(i).getWindowList();
+ final int numWindows = windows.size();
+ for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
+ final WindowState win = windows.get(winNdx);
+ if (win.mAppOp == AppOpsManager.OP_NONE) {
+ continue;
+ }
+ final int mode = mService.mAppOps.checkOpNoThrow(win.mAppOp, win.getOwningUid(),
+ win.getOwningPackage());
+ win.setAppOpVisibilityLw(mode == AppOpsManager.MODE_ALLOWED ||
+ mode == AppOpsManager.MODE_DEFAULT);
+ }
+ }
+ }
+
+ boolean canShowStrictModeViolation(int pid) {
+ final int count = mDisplayContents.size();
+ for (int i = 0; i < count; ++i) {
+ final WindowList windows = mDisplayContents.valueAt(i).getWindowList();
+ final int numWindows = windows.size();
+ for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
+ final WindowState ws = windows.get(winNdx);
+ if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ void closeSystemDialogs(String reason) {
+ final int count = mDisplayContents.size();
+ for (int i = 0; i < count; ++i) {
+ final WindowList windows = mDisplayContents.valueAt(i).getWindowList();
+ final int numWindows = windows.size();
+ for (int j = 0; j < numWindows; ++j) {
+ final WindowState w = windows.get(j);
+ if (w.mHasSurface) {
+ try {
+ w.mClient.closeSystemDialogs(reason);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ }
+ }
+
+ void removeReplacedWindows() {
+ if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION removeReplacedWindows");
+ mService.openSurfaceTransaction();
+ try {
+ for (int i = mDisplayContents.size() - 1; i >= 0; i--) {
+ DisplayContent dc = mDisplayContents.valueAt(i);
+ final WindowList windows = dc.getWindowList();
+ for (int j = windows.size() - 1; j >= 0; j--) {
+ final WindowState win = windows.get(j);
+ final AppWindowToken aToken = win.mAppToken;
+ if (aToken != null) {
+ aToken.removeReplacedWindowIfNeeded(win);
+ }
+ }
+ }
+ } finally {
+ mService.closeSurfaceTransaction();
+ if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION removeReplacedWindows");
+ }
+ }
+
+ boolean hasPendingLayoutChanges(WindowAnimator animator) {
+ boolean hasChanges = false;
+
+ final int count = mDisplayContents.size();
+ for (int i = 0; i < count; ++i) {
+ final DisplayContent dc = mDisplayContents.valueAt(i);
+ final int pendingChanges = animator.getPendingLayoutChanges(dc.getDisplayId());
+ if ((pendingChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
+ animator.mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING;
+ }
+ if (pendingChanges != 0) {
+ hasChanges = true;
+ }
+ }
+
+ return hasChanges;
+ }
+
+ void updateInputWindows(InputMonitor inputMonitor, WindowState inputFocus, boolean inDrag) {
+ boolean addInputConsumerHandle = mService.mInputConsumer != null;
+ boolean addWallpaperInputConsumerHandle = mService.mWallpaperInputConsumer != null;
+ final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
+ boolean disableWallpaperTouchEvents = false;
+
+ final int count = mDisplayContents.size();
+ for (int i = 0; i < count; ++i) {
+ final DisplayContent dc = mDisplayContents.valueAt(i);
+ final WindowList windows = dc.getWindowList();
+ for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
+ final WindowState child = windows.get(winNdx);
+ final InputChannel inputChannel = child.mInputChannel;
+ final InputWindowHandle inputWindowHandle = child.mInputWindowHandle;
+ if (inputChannel == null || inputWindowHandle == null || child.mRemoved
+ || child.isAdjustedForMinimizedDock()) {
+ // Skip this window because it cannot possibly receive input.
+ continue;
+ }
+ if (addInputConsumerHandle
+ && inputWindowHandle.layer <= mService.mInputConsumer.mWindowHandle.layer) {
+ inputMonitor.addInputWindowHandle(mService.mInputConsumer.mWindowHandle);
+ addInputConsumerHandle = false;
+ }
+
+ if (addWallpaperInputConsumerHandle) {
+ if (child.mAttrs.type == WindowManager.LayoutParams.TYPE_WALLPAPER &&
+ child.isVisibleLw()) {
+ // Add the wallpaper input consumer above the first visible wallpaper.
+ inputMonitor.addInputWindowHandle(
+ mService.mWallpaperInputConsumer.mWindowHandle);
+ addWallpaperInputConsumerHandle = false;
+ }
+ }
+
+ final int flags = child.mAttrs.flags;
+ final int privateFlags = child.mAttrs.privateFlags;
+ final int type = child.mAttrs.type;
+
+ final boolean hasFocus = child == inputFocus;
+ final boolean isVisible = child.isVisibleLw();
+ if ((privateFlags
+ & WindowManager.LayoutParams.PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS)
+ != 0) {
+ disableWallpaperTouchEvents = true;
+ }
+ final boolean hasWallpaper = wallpaperController.isWallpaperTarget(child)
+ && (privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD) == 0
+ && !disableWallpaperTouchEvents;
+ final boolean onDefaultDisplay = (child.getDisplayId() == Display.DEFAULT_DISPLAY);
+
+ // If there's a drag in progress and 'child' is a potential drop target,
+ // make sure it's been told about the drag
+ if (inDrag && isVisible && onDefaultDisplay) {
+ mService.mDragState.sendDragStartedIfNeededLw(child);
+ }
+
+ inputMonitor.addInputWindowHandle(
+ inputWindowHandle, child, flags, type, isVisible, hasFocus, hasWallpaper);
+ }
+ }
+
+ if (addWallpaperInputConsumerHandle) {
+ // No visible wallpaper found, add the wallpaper input consumer at the end.
+ inputMonitor.addInputWindowHandle(mService.mWallpaperInputConsumer.mWindowHandle);
+ }
+ }
+
+ boolean reclaimSomeSurfaceMemory(WindowStateAnimator winAnimator, String operation,
+ boolean secure) {
+ final WindowSurfaceController surfaceController = winAnimator.mSurfaceController;
+ boolean leakedSurface = false;
+ boolean killedApps = false;
+
+ EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
+ winAnimator.mSession.mPid, operation);
+
+ final long callingIdentity = Binder.clearCallingIdentity();
+ try {
+ // There was some problem... first, do a sanity check of the window list to make sure
+ // we haven't left any dangling surfaces around.
+
+ Slog.i(TAG_WM, "Out of memory for surface! Looking for leaks...");
+ final int numDisplays = mDisplayContents.size();
+ for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+ final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
+ final int numWindows = windows.size();
+ for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
+ final WindowState ws = windows.get(winNdx);
+ final WindowStateAnimator wsa = ws.mWinAnimator;
+ if (wsa.mSurfaceController == null) {
+ continue;
+ }
+ if (!mService.mSessions.contains(wsa.mSession)) {
+ Slog.w(TAG_WM, "LEAKED SURFACE (session doesn't exist): "
+ + ws + " surface=" + wsa.mSurfaceController
+ + " token=" + ws.mToken
+ + " pid=" + ws.mSession.mPid
+ + " uid=" + ws.mSession.mUid);
+ wsa.destroySurface();
+ mService.mForceRemoves.add(ws);
+ leakedSurface = true;
+ } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
+ Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): "
+ + ws + " surface=" + wsa.mSurfaceController
+ + " token=" + ws.mAppToken
+ + " saved=" + ws.hasSavedSurface());
+ if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", false);
+ wsa.destroySurface();
+ leakedSurface = true;
+ }
+ }
+ }
+
+ if (!leakedSurface) {
+ Slog.w(TAG_WM, "No leaked surfaces; killing applications!");
+ SparseIntArray pidCandidates = new SparseIntArray();
+ for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+ final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
+ final int numWindows = windows.size();
+ for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
+ final WindowState ws = windows.get(winNdx);
+ if (mService.mForceRemoves.contains(ws)) {
+ continue;
+ }
+ WindowStateAnimator wsa = ws.mWinAnimator;
+ if (wsa.mSurfaceController != null) {
+ pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
+ }
+ }
+ if (pidCandidates.size() > 0) {
+ int[] pids = new int[pidCandidates.size()];
+ for (int i = 0; i < pids.length; i++) {
+ pids[i] = pidCandidates.keyAt(i);
+ }
+ try {
+ if (mService.mActivityManager.killPids(pids, "Free memory", secure)) {
+ killedApps = true;
+ }
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ }
+
+ if (leakedSurface || killedApps) {
+ // We managed to reclaim some memory, so get rid of the trouble surface and ask the
+ // app to request another one.
+ Slog.w(TAG_WM,
+ "Looks like we have reclaimed some memory, clearing surface for retry.");
+ if (surfaceController != null) {
+ if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
+ "RECOVER DESTROY", false);
+ winAnimator.destroySurface();
+ mService.scheduleRemoveStartingWindowLocked(winAnimator.mWin.mAppToken);
+ }
+
+ try {
+ winAnimator.mWin.mClient.dispatchGetNewSurface();
+ } catch (RemoteException e) {
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentity);
+ }
+
+ return leakedSurface || killedApps;
+ }
+
+ // "Something has changed! Let's make it correct now."
+ // TODO: Super crazy long method that should be broken down...
+ void performSurfacePlacement(boolean recoveringMemory) {
+ if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
+ + Debug.getCallers(3));
+
+ int i;
+ boolean updateInputWindowsNeeded = false;
+
+ if (mService.mFocusMayChange) {
+ mService.mFocusMayChange = false;
+ updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
+ UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
+ }
+
+ // Initialize state of exiting tokens.
+ final int numDisplays = mDisplayContents.size();
+ for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+ final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
+ for (i = displayContent.mExitingTokens.size() - 1; i >= 0; i--) {
+ displayContent.mExitingTokens.get(i).hasVisible = false;
+ }
+ }
+
+ for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
+ // Initialize state of exiting applications.
+ final AppTokenList exitingAppTokens =
+ mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
+ for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
+ exitingAppTokens.get(tokenNdx).hasVisible = false;
+ }
+ }
+
+ mHoldScreen = null;
+ mScreenBrightness = -1;
+ mButtonBrightness = -1;
+ mUserActivityTimeout = -1;
+ mObscureApplicationContentOnSecondaryDisplays = false;
+ mSustainedPerformanceModeCurrent = false;
+ mService.mTransactionSequence++;
+
+ // TODO(multi-display):
+ final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
+ final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
+ final int defaultDw = defaultInfo.logicalWidth;
+ final int defaultDh = defaultInfo.logicalHeight;
+
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+ ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
+ mService.openSurfaceTransaction();
+ try {
+ mService.mRoot.applySurfaceChangesTransaction(recoveringMemory, defaultDw, defaultDh);
+ } catch (RuntimeException e) {
+ Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
+ } finally {
+ mService.closeSurfaceTransaction();
+ if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
+ "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
+ }
+
+ final WindowList defaultWindows = defaultDisplay.getWindowList();
+ final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked;
+
+ // If we are ready to perform an app transition, check through all of the app tokens to be
+ // shown and see if they are ready to go.
+ if (mService.mAppTransition.isReady()) {
+ defaultDisplay.pendingLayoutChanges |=
+ surfacePlacer.handleAppTransitionReadyLocked(defaultWindows);
+ if (DEBUG_LAYOUT_REPEATS)
+ surfacePlacer.debugLayoutRepeats("after handleAppTransitionReadyLocked",
+ defaultDisplay.pendingLayoutChanges);
+ }
+
+ if (!mService.mAnimator.mAppWindowAnimating && mService.mAppTransition.isRunning()) {
+ // We have finished the animation of an app transition. To do this, we have delayed a
+ // lot of operations like showing and hiding apps, moving apps in Z-order, etc. The app
+ // token list reflects the correct Z-order, but the window list may now be out of sync
+ // with it. So here we will just rebuild the entire app window list. Fun!
+ defaultDisplay.pendingLayoutChanges |=
+ mService.handleAnimatingStoppedAndTransitionLocked();
+ if (DEBUG_LAYOUT_REPEATS)
+ surfacePlacer.debugLayoutRepeats("after handleAnimStopAndXitionLock",
+ defaultDisplay.pendingLayoutChanges);
+ }
+
+ if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
+ && !mService.mAppTransition.isReady()) {
+ // At this point, there was a window with a wallpaper that was force hiding other
+ // windows behind it, but now it is going away. This may be simple -- just animate away
+ // the wallpaper and its window -- or it may be hard -- the wallpaper now needs to be
+ // shown behind something that was hidden.
+ defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
+ if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
+ "after animateAwayWallpaperLocked", defaultDisplay.pendingLayoutChanges);
+ }
+ mWallpaperForceHidingChanged = false;
+
+ if (mWallpaperMayChange) {
+ if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Wallpaper may change! Adjusting");
+ defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
+ if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("WallpaperMayChange",
+ defaultDisplay.pendingLayoutChanges);
+ }
+
+ if (mService.mFocusMayChange) {
+ mService.mFocusMayChange = false;
+ if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
+ false /*updateInputWindows*/)) {
+ updateInputWindowsNeeded = true;
+ defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
+ }
+ }
+
+ if (layoutNeeded()) {
+ defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
+ if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats("mLayoutNeeded",
+ defaultDisplay.pendingLayoutChanges);
+ }
+
+ for (i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
+ WindowState win = mService.mResizingWindows.get(i);
+ if (win.mAppFreezing) {
+ // Don't remove this window until rotation has completed.
+ continue;
+ }
+ // Discard the saved surface if window size is changed, it can't be reused.
+ if (win.mAppToken != null) {
+ win.mAppToken.destroySavedSurfaces();
+ }
+ win.reportResized();
+ mService.mResizingWindows.remove(i);
+ }
+
+ if (DEBUG_ORIENTATION && mService.mDisplayFrozen) Slog.v(TAG,
+ "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
+ if (mOrientationChangeComplete) {
+ if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
+ mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
+ mService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
+ mService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
+ }
+ mService.stopFreezingDisplayLocked();
+ }
+
+ // Destroy the surface of any windows that are no longer visible.
+ boolean wallpaperDestroyed = false;
+ i = mService.mDestroySurface.size();
+ if (i > 0) {
+ do {
+ i--;
+ WindowState win = mService.mDestroySurface.get(i);
+ win.mDestroying = false;
+ if (mService.mInputMethodWindow == win) {
+ mService.mInputMethodWindow = null;
+ }
+ if (mService.mWallpaperControllerLocked.isWallpaperTarget(win)) {
+ wallpaperDestroyed = true;
+ }
+ win.destroyOrSaveSurface();
+ } while (i > 0);
+ mService.mDestroySurface.clear();
+ }
+
+ // Time to remove any exiting tokens?
+ for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+ final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
+ ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
+ for (i = exitingTokens.size() - 1; i >= 0; i--) {
+ WindowToken token = exitingTokens.get(i);
+ if (!token.hasVisible) {
+ exitingTokens.remove(i);
+ if (token.windowType == TYPE_WALLPAPER) {
+ mService.mWallpaperControllerLocked.removeWallpaperToken(token);
+ }
+ }
+ }
+ }
+
+ // Time to remove any exiting applications?
+ for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
+ // Initialize state of exiting applications.
+ final AppTokenList exitingAppTokens =
+ mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
+ for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
+ final AppWindowToken token = exitingAppTokens.get(i);
+ if (!token.hasVisible && !mService.mClosingApps.contains(token) &&
+ (!token.mIsExiting || token.isEmpty())) {
+ // Make sure there is no animation running on this token, so any windows
+ // associated with it will be removed as soon as their animations are complete
+ token.mAppAnimator.clearAnimation();
+ token.mAppAnimator.animating = false;
+ if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
+ "performLayout: App token exiting now removed" + token);
+ token.removeIfPossible();
+ }
+ }
+ }
+
+ if (wallpaperDestroyed) {
+ defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
+ defaultDisplay.layoutNeeded = true;
+ }
+
+ for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+ final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
+ if (displayContent.pendingLayoutChanges != 0) {
+ displayContent.layoutNeeded = true;
+ }
+ }
+
+ // Finally update all input windows now that the window changes have stabilized.
+ mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
+
+ mService.setHoldScreenLocked(mHoldScreen);
+ if (!mService.mDisplayFrozen) {
+ if (mScreenBrightness < 0 || mScreenBrightness > 1.0f) {
+ mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
+ } else {
+ mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
+ toBrightnessOverride(mScreenBrightness));
+ }
+ if (mButtonBrightness < 0 || mButtonBrightness > 1.0f) {
+ mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
+ } else {
+ mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
+ toBrightnessOverride(mButtonBrightness));
+ }
+ mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
+ mUserActivityTimeout);
+ }
+
+ if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) {
+ mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent;
+ mService.mPowerManagerInternal.powerHint(
+ mService.mPowerManagerInternal.POWER_HINT_SUSTAINED_PERFORMANCE_MODE,
+ (mSustainedPerformanceModeEnabled ? 1 : 0));
+ }
+
+ if (mService.mTurnOnScreen) {
+ if (mService.mAllowTheaterModeWakeFromLayout
+ || Settings.Global.getInt(mService.mContext.getContentResolver(),
+ Settings.Global.THEATER_MODE_ON, 0) == 0) {
+ if (DEBUG_VISIBILITY || DEBUG_POWER) {
+ Slog.v(TAG, "Turning screen on after layout!");
+ }
+ mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
+ "android.server.wm:TURN_ON");
+ }
+ mService.mTurnOnScreen = false;
+ }
+
+ if (mUpdateRotation) {
+ if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
+ if (mService.updateRotationUncheckedLocked(false)) {
+ mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
+ } else {
+ mUpdateRotation = false;
+ }
+ }
+
+ if (mService.mWaitingForDrawnCallback != null ||
+ (mOrientationChangeComplete && !defaultDisplay.layoutNeeded &&
+ !mUpdateRotation)) {
+ mService.checkDrawnWindowsLocked();
+ }
+
+ final int N = mService.mPendingRemove.size();
+ if (N > 0) {
+ if (mService.mPendingRemoveTmp.length < N) {
+ mService.mPendingRemoveTmp = new WindowState[N+10];
+ }
+ mService.mPendingRemove.toArray(mService.mPendingRemoveTmp);
+ mService.mPendingRemove.clear();
+ DisplayContentList displayList = new DisplayContentList();
+ for (i = 0; i < N; i++) {
+ final WindowState w = mService.mPendingRemoveTmp[i];
+ w.removeImmediately();
+ final DisplayContent displayContent = w.getDisplayContent();
+ if (displayContent != null && !displayList.contains(displayContent)) {
+ displayList.add(displayContent);
+ }
+ }
+
+ for (DisplayContent displayContent : displayList) {
+ mService.mLayersController.assignLayersLocked(displayContent.getWindowList());
+ displayContent.layoutNeeded = true;
+ }
+ }
+
+ // Remove all deferred displays stacks, tasks, and activities.
+ for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
+ mDisplayContents.valueAt(displayNdx).checkCompleteDeferredRemoval();
+ }
+
+ if (updateInputWindowsNeeded) {
+ mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
+ }
+ mService.setFocusTaskRegionLocked();
+
+ // Check to see if we are now in a state where the screen should
+ // be enabled, because the window obscured flags have changed.
+ mService.enableScreenIfNeededLocked();
+
+ mService.scheduleAnimationLocked();
+ mService.mWindowPlacerLocked.destroyPendingSurfaces();
+
+ if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
+ "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
+ }
+
+ // TODO: Super crazy long method that should be broken down...
+ void applySurfaceChangesTransaction(boolean recoveringMemory, int defaultDw, int defaultDh) {
+ mHoldScreenWindow = null;
+ mObsuringWindow = null;
+
+ if (mService.mWatermark != null) {
+ mService.mWatermark.positionSurface(defaultDw, defaultDh);
+ }
+ if (mService.mStrictModeFlash != null) {
+ mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
+ }
+ if (mService.mCircularDisplayMask != null) {
+ mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh, mService.mRotation);
+ }
+ if (mService.mEmulatorDisplayOverlay != null) {
+ mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
+ mService.mRotation);
+ }
+
+ boolean focusDisplayed = false;
+
+ final int count = mDisplayContents.size();
+ for (int j = 0; j < count; ++j) {
+ final DisplayContent dc = mDisplayContents.valueAt(j);
+ boolean updateAllDrawn = false;
+ WindowList windows = dc.getWindowList();
+ DisplayInfo displayInfo = dc.getDisplayInfo();
+ final int displayId = dc.getDisplayId();
+ final int dw = displayInfo.logicalWidth;
+ final int dh = displayInfo.logicalHeight;
+ final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
+ final WindowSurfacePlacer surfacePlacer = mService.mWindowPlacerLocked;
+
+ // Reset for each display.
+ mDisplayHasContent = false;
+ mPreferredRefreshRate = 0;
+ mPreferredModeId = 0;
+
+ int repeats = 0;
+ do {
+ repeats++;
+ if (repeats > 6) {
+ Slog.w(TAG, "Animation repeat aborted after too many iterations");
+ dc.layoutNeeded = false;
+ break;
+ }
+
+ if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
+ "On entry to LockedInner", dc.pendingLayoutChanges);
+
+ if ((dc.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0
+ && mService.mWallpaperControllerLocked.adjustWallpaperWindows()) {
+ mService.mLayersController.assignLayersLocked(windows);
+ dc.layoutNeeded = true;
+ }
+
+ if (isDefaultDisplay
+ && (dc.pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
+ if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
+ if (mService.updateOrientationFromAppTokensLocked(true)) {
+ dc.layoutNeeded = true;
+ mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
+ }
+ }
+
+ if ((dc.pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
+ dc.layoutNeeded = true;
+ }
+
+ // FIRST LOOP: Perform a layout, if needed.
+ if (repeats < LAYOUT_REPEAT_THRESHOLD) {
+ surfacePlacer.performLayoutLockedInner(dc, repeats == 1,
+ false /* updateInputWindows */);
+ } else {
+ Slog.w(TAG, "Layout repeat skipped after too many iterations");
+ }
+
+ // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
+ // it is animating.
+ dc.pendingLayoutChanges = 0;
+
+ if (isDefaultDisplay) {
+ mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ WindowState w = windows.get(i);
+ if (w.mHasSurface) {
+ mService.mPolicy.applyPostLayoutPolicyLw(
+ w, w.mAttrs, w.getParentWindow());
+ }
+ }
+ dc.pendingLayoutChanges |=
+ mService.mPolicy.finishPostLayoutPolicyLw();
+ if (DEBUG_LAYOUT_REPEATS) surfacePlacer.debugLayoutRepeats(
+ "after finishPostLayoutPolicyLw", dc.pendingLayoutChanges);
+ }
+ } while (dc.pendingLayoutChanges != 0);
+
+ mObscured = false;
+ mSyswin = false;
+ dc.resetDimming();
+
+ // Only used if default window
+ final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
+
+ for (int i = windows.size() - 1; i >= 0; i--) {
+ WindowState w = windows.get(i);
+ final Task task = w.getTask();
+ final boolean obscuredChanged = w.mObscured != mObscured;
+
+ // Update effect.
+ w.mObscured = mObscured;
+ if (!mObscured) {
+ handleNotObscuredLocked(w, displayInfo);
+ }
+
+ w.applyDimLayerIfNeeded();
+
+ if (isDefaultDisplay && obscuredChanged && w.isVisibleLw()
+ && mService.mWallpaperControllerLocked.isWallpaperTarget(w)) {
+ // This is the wallpaper target and its obscured state changed... make sure the
+ // current wallaper's visibility has been updated accordingly.
+ mService.mWallpaperControllerLocked.updateWallpaperVisibility();
+ }
+
+ final WindowStateAnimator winAnimator = w.mWinAnimator;
+
+ // If the window has moved due to its containing content frame changing, then
+ // notify the listeners and optionally animate it. Simply checking a change of
+ // position is not enough, because being move due to dock divider is not a trigger
+ // for animation.
+ if (w.hasMoved()) {
+ // Frame has moved, containing content frame has also moved, and we're not
+ // currently animating... let's do something.
+ final int left = w.mFrame.left;
+ final int top = w.mFrame.top;
+ final boolean adjustedForMinimizedDockOrIme = task != null
+ && (task.mStack.isAdjustedForMinimizedDockedStack()
+ || task.mStack.isAdjustedForIme());
+ if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
+ && !w.isDragResizing() && !adjustedForMinimizedDockOrIme
+ && (task == null || w.getTask().mStack.hasMovementAnimations())
+ && !w.mWinAnimator.mLastHidden) {
+ winAnimator.setMoveAnimation(left, top);
+ }
+
+ //TODO (multidisplay): Accessibility supported only for the default display.
+ if (mService.mAccessibilityController != null
+ && displayId == Display.DEFAULT_DISPLAY) {
+ mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
+ }
+
+ try {
+ w.mClient.moved(left, top);
+ } catch (RemoteException e) {
+ }
+ w.mMovedByResize = false;
+ }
+
+ //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
+ w.mContentChanged = false;
+
+ // Moved from updateWindowsAndWallpaperLocked().
+ if (w.mHasSurface) {
+ // Take care of the window being ready to display.
+ final boolean committed = winAnimator.commitFinishDrawingLocked();
+ if (isDefaultDisplay && committed) {
+ if (w.mAttrs.type == TYPE_DREAM) {
+ // HACK: When a dream is shown, it may at that point hide the lock
+ // screen. So we need to redo the layout to let the phone window manager
+ // make this happen.
+ dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
+ if (DEBUG_LAYOUT_REPEATS) {
+ surfacePlacer.debugLayoutRepeats(
+ "dream and commitFinishDrawingLocked true",
+ dc.pendingLayoutChanges);
+ }
+ }
+ if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
+ if (DEBUG_WALLPAPER_LIGHT)
+ Slog.v(TAG, "First draw done in potential wallpaper target " + w);
+ mWallpaperMayChange = true;
+ dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
+ if (DEBUG_LAYOUT_REPEATS) {
+ surfacePlacer.debugLayoutRepeats(
+ "wallpaper and commitFinishDrawingLocked true",
+ dc.pendingLayoutChanges);
+ }
+ }
+ }
+ if (!winAnimator.isAnimationStarting() && !winAnimator.isWaitingForOpening()) {
+ // Updates the shown frame before we set up the surface. This is needed
+ // because the resizing could change the top-left position (in addition to
+ // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
+ // position the surface.
+ //
+ // If an animation is being started, we can't call this method because the
+ // animation hasn't processed its initial transformation yet, but in general
+ // we do want to update the position if the window is animating.
+ winAnimator.computeShownFrameLocked();
+ }
+ winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
+ }
+
+ final AppWindowToken atoken = w.mAppToken;
+ if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) {
+ Slog.d(TAG, "updateWindows: starting " + w
+ + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
+ + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
+ }
+ if (atoken != null && (!atoken.allDrawn || !atoken.allDrawnExcludingSaved
+ || atoken.mAppAnimator.freezingScreen)) {
+ if (atoken.lastTransactionSequence != mService.mTransactionSequence) {
+ atoken.lastTransactionSequence = mService.mTransactionSequence;
+ atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
+ atoken.numInterestingWindowsExcludingSaved = 0;
+ atoken.numDrawnWindowsExcludingSaved = 0;
+ atoken.startingDisplayed = false;
+ }
+ if (!atoken.allDrawn && w.mightAffectAllDrawn(false /* visibleOnly */)) {
+ if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
+ Slog.v(TAG, "Eval win " + w + ": isDrawn="
+ + w.isDrawnLw()
+ + ", isAnimationSet=" + winAnimator.isAnimationSet());
+ if (!w.isDrawnLw()) {
+ Slog.v(TAG, "Not displayed: s="
+ + winAnimator.mSurfaceController
+ + " pv=" + w.mPolicyVisibility
+ + " mDrawState=" + winAnimator.drawStateToString()
+ + " ph=" + w.isParentWindowHidden()
+ + " th=" + atoken.hiddenRequested
+ + " a=" + winAnimator.mAnimating);
+ }
+ }
+ if (w != atoken.startingWindow) {
+ if (w.isInteresting()) {
+ atoken.numInterestingWindows++;
+ if (w.isDrawnLw()) {
+ atoken.numDrawnWindows++;
+ if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
+ Slog.v(TAG, "tokenMayBeDrawn: " + atoken
+ + " w=" + w + " numInteresting="
+ + atoken.numInterestingWindows
+ + " freezingScreen="
+ + atoken.mAppAnimator.freezingScreen
+ + " mAppFreezing=" + w.mAppFreezing);
+ updateAllDrawn = true;
+ }
+ }
+ } else if (w.isDrawnLw()) {
+ mService.mH.sendEmptyMessage(NOTIFY_STARTING_WINDOW_DRAWN);
+ atoken.startingDisplayed = true;
+ }
+ }
+ if (!atoken.allDrawnExcludingSaved
+ && w.mightAffectAllDrawn(true /* visibleOnly */)) {
+ if (w != atoken.startingWindow && w.isInteresting()) {
+ atoken.numInterestingWindowsExcludingSaved++;
+ if (w.isDrawnLw() && !w.isAnimatingWithSavedSurface()) {
+ atoken.numDrawnWindowsExcludingSaved++;
+ if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
+ Slog.v(TAG, "tokenMayBeDrawnExcludingSaved: " + atoken
+ + " w=" + w + " numInteresting="
+ + atoken.numInterestingWindowsExcludingSaved
+ + " freezingScreen="
+ + atoken.mAppAnimator.freezingScreen
+ + " mAppFreezing=" + w.mAppFreezing);
+ updateAllDrawn = true;
+ }
+ }
+ }
+ }
+
+ if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
+ && w.isDisplayedLw()) {
+ focusDisplayed = true;
+ }
+
+ mService.updateResizingWindows(w);
+ }
+
+ mService.mDisplayManagerInternal.setDisplayProperties(displayId,
+ mDisplayHasContent,
+ mPreferredRefreshRate,
+ mPreferredModeId,
+ true /* inTraversal, must call performTraversalInTrans... below */);
+
+ dc.stopDimmingIfNeeded();
+
+ if (updateAllDrawn) {
+ // See if any windows have been drawn, so they (and others associated with them)
+ // can now be shown.
+ dc.updateAllDrawn();
+ }
+ }
+
+ if (focusDisplayed) {
+ mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
+ }
+
+ // Give the display manager a chance to adjust properties
+ // like display rotation if it needs to.
+ mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
+ }
+
+ /**
+ * @param w WindowState this method is applied to.
+ * @param dispInfo info of the display that the window's obscuring state is checked against.
+ */
+ private void handleNotObscuredLocked(final WindowState w, final DisplayInfo dispInfo) {
+ final WindowManager.LayoutParams attrs = w.mAttrs;
+ final int attrFlags = attrs.flags;
+ final boolean canBeSeen = w.isDisplayedLw();
+ final int privateflags = attrs.privateFlags;
+
+ if (canBeSeen && w.isObscuringFullscreen(dispInfo)) {
+ // This window completely covers everything behind it,
+ // so we want to leave all of them as undimmed (for
+ // performance reasons).
+ if (!mObscured) {
+ mObsuringWindow = w;
+ }
+
+ mObscured = true;
+ }
+
+ if (w.mHasSurface && canBeSeen) {
+ if ((attrFlags & FLAG_KEEP_SCREEN_ON) != 0) {
+ mHoldScreen = w.mSession;
+ mHoldScreenWindow = w;
+ } else if (DEBUG_KEEP_SCREEN_ON && w == mService.mLastWakeLockHoldingWindow) {
+ Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w + " was holding "
+ + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by"
+ + Debug.getCallers(10));
+ }
+ if (!mSyswin && w.mAttrs.screenBrightness >= 0 && mScreenBrightness < 0) {
+ mScreenBrightness = w.mAttrs.screenBrightness;
+ }
+ if (!mSyswin && w.mAttrs.buttonBrightness >= 0 && mButtonBrightness < 0) {
+ mButtonBrightness = w.mAttrs.buttonBrightness;
+ }
+ if (!mSyswin && w.mAttrs.userActivityTimeout >= 0 && mUserActivityTimeout < 0) {
+ mUserActivityTimeout = w.mAttrs.userActivityTimeout;
+ }
+
+ final int type = attrs.type;
+ if (type == TYPE_SYSTEM_DIALOG || type == TYPE_SYSTEM_ERROR
+ || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
+ mSyswin = true;
+ }
+
+ // This function assumes that the contents of the default display are processed first
+ // before secondary displays.
+ final DisplayContent displayContent = w.getDisplayContent();
+ if (displayContent != null && displayContent.isDefaultDisplay) {
+ // While a dream or keyguard is showing, obscure ordinary application content on
+ // secondary displays (by forcibly enabling mirroring unless there is other content
+ // we want to show) but still allow opaque keyguard dialogs to be shown.
+ if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
+ mObscureApplicationContentOnSecondaryDisplays = true;
+ }
+ mDisplayHasContent = true;
+ } else if (displayContent != null &&
+ (!mObscureApplicationContentOnSecondaryDisplays
+ || (mObscured && type == TYPE_KEYGUARD_DIALOG))) {
+ // Allow full screen keyguard presentation dialogs to be seen.
+ mDisplayHasContent = true;
+ }
+ if (mPreferredRefreshRate == 0 && w.mAttrs.preferredRefreshRate != 0) {
+ mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
+ }
+ if (mPreferredModeId == 0 && w.mAttrs.preferredDisplayModeId != 0) {
+ mPreferredModeId = w.mAttrs.preferredDisplayModeId;
+ }
+ if ((privateflags & PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE) != 0) {
+ mSustainedPerformanceModeCurrent = true;
+ }
+ }
+ }
+
+ boolean copyAnimToLayoutParams() {
+ boolean doRequest = false;
+
+ final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
+ if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
+ mUpdateRotation = true;
+ doRequest = true;
+ }
+ if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
+ mWallpaperMayChange = true;
+ doRequest = true;
+ }
+ if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
+ mWallpaperForceHidingChanged = true;
+ doRequest = true;
+ }
+ if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
+ mOrientationChangeComplete = false;
+ } else {
+ mOrientationChangeComplete = true;
+ mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
+ if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
+ doRequest = true;
+ }
+ }
+ if ((bulkUpdateParams & SET_TURN_ON_SCREEN) != 0) {
+ mService.mTurnOnScreen = true;
+ }
+ if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
+ mWallpaperActionPending = true;
+ }
+
+ return doRequest;
+ }
+
+ private static int toBrightnessOverride(float value) {
+ return (int)(value * PowerManager.BRIGHTNESS_ON);
+ }
+
+ void enableSurfaceTrace(ParcelFileDescriptor pfd) {
+ final FileDescriptor fd = pfd.getFileDescriptor();
+ if (mSurfaceTraceEnabled) {
+ disableSurfaceTrace();
+ }
+ mSurfaceTraceEnabled = true;
+ mRemoteEventTrace = new RemoteEventTrace(mService, fd);
+ mSurfaceTraceFd = pfd;
+ for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
+ DisplayContent dc = mDisplayContents.valueAt(displayNdx);
+ dc.enableSurfaceTrace(fd);
+ }
+ }
+
+ void disableSurfaceTrace() {
+ mSurfaceTraceEnabled = false;
+ mRemoteEventTrace = null;
+ mSurfaceTraceFd = null;
+ for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
+ DisplayContent dc = mDisplayContents.valueAt(displayNdx);
+ dc.disableSurfaceTrace();
+ }
+ }
+
+ void dumpDisplayContents(PrintWriter pw) {
+ pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)");
+ if (mService.mDisplayReady) {
+ final int count = mDisplayContents.size();
+ for (int i = 0; i < count; ++i) {
+ final DisplayContent displayContent = mDisplayContents.valueAt(i);
+ displayContent.dump(" ", pw);
+ }
+ } else {
+ pw.println(" NO DISPLAY");
+ }
+ }
+
+ void dumpLayoutNeededDisplayIds(PrintWriter pw) {
+ if (!layoutNeeded()) {
+ return;
+ }
+ pw.print(" layoutNeeded on displays=");
+ final int count = mDisplayContents.size();
+ for (int displayNdx = 0; displayNdx < count; ++displayNdx) {
+ final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
+ if (displayContent.layoutNeeded) {
+ pw.print(displayContent.getDisplayId());
+ }
+ }
+ pw.println();
+ }
+
+ void dumpWindowsNoHeader(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows) {
+ final int numDisplays = mDisplayContents.size();
+ for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
+ final WindowList windowList = mDisplayContents.valueAt(displayNdx).getWindowList();
+ for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
+ final WindowState w = windowList.get(winNdx);
+ if (windows == null || windows.contains(w)) {
+ pw.println(" Window #" + winNdx + " " + w + ":");
+ w.dump(pw, " ", dumpAll || windows != null);
+ }
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index b269d4c..58439eb 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -641,7 +641,7 @@
}
boolean adjustWallpaperWindows() {
- mService.mWindowPlacerLocked.mWallpaperMayChange = false;
+ mService.mRoot.mWallpaperMayChange = false;
final WindowList windows = mService.getDefaultWindowListLocked();
// First find top-most window that has asked to be on top of the wallpaper;
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index a13b6a1..28b5424 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -528,7 +528,7 @@
}
private void updateWallpaperLocked(int displayId) {
- mService.getDisplayContentLocked(displayId).resetAnimationBackgroundAnimator();
+ mService.mRoot.getDisplayContent(displayId).resetAnimationBackgroundAnimator();
final WindowList windows = mService.getWindowListLocked(displayId);
WindowState detachedWallpaper = null;
@@ -615,7 +615,7 @@
final int numDisplays = mDisplayContentsAnimators.size();
for (int i = 0; i < numDisplays; i++) {
final int displayId = mDisplayContentsAnimators.keyAt(i);
- final DisplayContent displayContent = mService.getDisplayContentLocked(displayId);
+ final DisplayContent displayContent = mService.mRoot.getDisplayContent(displayId);
displayContent.stepAppWindowsAnimation(mCurrentTime);
DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);
@@ -654,7 +654,7 @@
for (int i = 0; i < numDisplays; i++) {
final int displayId = mDisplayContentsAnimators.keyAt(i);
- final DisplayContent displayContent = mService.getDisplayContentLocked(displayId);
+ final DisplayContent displayContent = mService.mRoot.getDisplayContent(displayId);
displayContent.checkAppWindowsReadyToShow();
@@ -691,22 +691,10 @@
TAG, "<<< CLOSE TRANSACTION animateLocked");
}
- boolean hasPendingLayoutChanges = false;
- final int numDisplays = mService.mDisplayContents.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
- final int pendingChanges = getPendingLayoutChanges(displayContent.getDisplayId());
- if ((pendingChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
- mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING;
- }
- if (pendingChanges != 0) {
- hasPendingLayoutChanges = true;
- }
- }
-
+ boolean hasPendingLayoutChanges = mService.mRoot.hasPendingLayoutChanges(this);
boolean doRequest = false;
if (mBulkUpdateParams != 0) {
- doRequest = mWindowPlacerLocked.copyAnimToLayoutParamsLocked();
+ doRequest = mService.mRoot.copyAnimToLayoutParams();
}
if (hasPendingLayoutChanges || doRequest) {
@@ -725,7 +713,8 @@
}
if (mRemoveReplacedWindows) {
- removeReplacedWindowsLocked();
+ mService.mRoot.removeReplacedWindows();
+ mRemoveReplacedWindows = false;
}
mService.stopUsingSavedSurfaceLocked();
@@ -740,28 +729,6 @@
}
}
- private void removeReplacedWindowsLocked() {
- if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION removeReplacedWindows");
- mService.openSurfaceTransaction();
- try {
- for (int i = mService.mDisplayContents.size() - 1; i >= 0; i--) {
- DisplayContent display = mService.mDisplayContents.valueAt(i);
- final WindowList windows = mService.getWindowListLocked(display.getDisplayId());
- for (int j = windows.size() - 1; j >= 0; j--) {
- final WindowState win = windows.get(j);
- final AppWindowToken aToken = win.mAppToken;
- if (aToken != null) {
- aToken.removeReplacedWindowIfNeeded(win);
- }
- }
- }
- } finally {
- mService.closeSurfaceTransaction();
- if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION removeReplacedWindows");
- }
- mRemoveReplacedWindows = false;
- }
-
private static String bulkUpdateParamsToString(int bulkUpdateParams) {
StringBuilder builder = new StringBuilder(128);
if ((bulkUpdateParams & WindowSurfacePlacer.SET_UPDATE_ROTATION) != 0) {
@@ -832,7 +799,7 @@
if (displayId < 0) {
return 0;
}
- final DisplayContent displayContent = mService.getDisplayContentLocked(displayId);
+ final DisplayContent displayContent = mService.mRoot.getDisplayContent(displayId);
return (displayContent != null) ? displayContent.pendingLayoutChanges : 0;
}
@@ -840,7 +807,7 @@
if (displayId < 0) {
return;
}
- final DisplayContent displayContent = mService.getDisplayContentLocked(displayId);
+ final DisplayContent displayContent = mService.mRoot.getDisplayContent(displayId);
if (displayContent != null) {
displayContent.pendingLayoutChanges |= changes;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index e4f6c27..f54add1 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -129,7 +129,6 @@
import com.android.internal.app.IAssistScreenshotReceiver;
import com.android.internal.os.IResultReceiver;
import com.android.internal.policy.IShortcutService;
-import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodClient;
@@ -215,7 +214,6 @@
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
@@ -238,7 +236,6 @@
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_VERBOSE_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
@@ -532,9 +529,10 @@
* LAST_ANR_LIFETIME_DURATION_MSECS */
String mLastANRState;
- /** All DisplayContents in the world, kept here */
- SparseArray<DisplayContent> mDisplayContents = new SparseArray<>(2);
+ // The root of the device window hierarchy.
+ RootWindowContainer mRoot;
+ // TODO: Move several of this states to the RootWindowContainer
int mRotation = 0;
int mLastOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
boolean mAltOrientation = false;
@@ -546,8 +544,6 @@
private final SparseIntArray mTmpTaskIds = new SparseIntArray();
- private final ArrayList<Integer> mChangedStackList = new ArrayList();
-
boolean mForceResizableTasks = false;
int getDragLayerLocked() {
@@ -701,6 +697,7 @@
boolean mAnimateWallpaperWithTarget;
+ // TODO: Move to RootWindowContainer
AppWindowToken mFocusedApp = null;
PowerManager mPowerManager;
@@ -745,6 +742,7 @@
/** All of the TaskStacks in the window manager, unordered. For an ordered list call
* DisplayContent.getStacks(). */
+ // TODO: Don't believe this is needed with the WindowContainer model.
SparseArray<TaskStack> mStackIdToStack = new SparseArray<>();
private final PointerEventDispatcher mPointerEventDispatcher;
@@ -884,17 +882,11 @@
// since they won't be notified through the app window animator.
final List<IBinder> mNoAnimationNotifyOnTransitionFinished = new ArrayList<>();
- // State for the RemoteSurfaceTrace system used in testing. If this is enabled SurfaceControl
- // instances will be replaced with an instance that writes a binary representation of all
- // commands to mSurfaceTraceFd.
- boolean mSurfaceTraceEnabled;
- ParcelFileDescriptor mSurfaceTraceFd;
- RemoteEventTrace mRemoteEventTrace;
void openSurfaceTransaction() {
synchronized (mWindowMap) {
- if (mSurfaceTraceEnabled) {
- mRemoteEventTrace.openSurfaceTransaction();
+ if (mRoot.mSurfaceTraceEnabled) {
+ mRoot.mRemoteEventTrace.openSurfaceTransaction();
}
SurfaceControl.openTransaction();
}
@@ -902,8 +894,8 @@
void closeSurfaceTransaction() {
synchronized (mWindowMap) {
- if (mSurfaceTraceEnabled) {
- mRemoteEventTrace.closeSurfaceTransaction();
+ if (mRoot.mSurfaceTraceEnabled) {
+ mRoot.mRemoteEventTrace.closeSurfaceTransaction();
}
SurfaceControl.closeTransaction();
}
@@ -976,6 +968,7 @@
private WindowManagerService(Context context, InputManagerService inputManager,
boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore,
WindowManagerPolicy policy) {
+ mRoot = new RootWindowContainer(this);
mContext = context;
mHaveInputMethods = haveInputMethods;
mAllowBootMessages = showBootMsgs;
@@ -1502,7 +1495,7 @@
throw new IllegalStateException("Display has not been initialialized");
}
- final DisplayContent displayContent = getDisplayContentLocked(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent == null) {
Slog.w(TAG_WM, "Attempted to add window to a display that does not exist: "
+ displayId + ". Aborting.");
@@ -1953,39 +1946,25 @@
@Override
public void enableSurfaceTrace(ParcelFileDescriptor pfd) {
- int callingUid = Binder.getCallingUid();
+ final int callingUid = Binder.getCallingUid();
if (callingUid != Process.SHELL_UID && callingUid != Process.ROOT_UID) {
throw new SecurityException("Only shell can call enableSurfaceTrace");
}
- final FileDescriptor fd = pfd.getFileDescriptor();
synchronized (mWindowMap) {
- if (mSurfaceTraceEnabled) {
- disableSurfaceTrace();
- }
- mSurfaceTraceEnabled = true;
- mRemoteEventTrace = new RemoteEventTrace(this, fd);
- mSurfaceTraceFd = pfd;
- for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
- DisplayContent dc = mDisplayContents.valueAt(displayNdx);
- dc.enableSurfaceTrace(fd);
- }
+ mRoot.enableSurfaceTrace(pfd);
}
}
@Override
public void disableSurfaceTrace() {
- int callingUid = Binder.getCallingUid();
+ final int callingUid = Binder.getCallingUid();
if (callingUid != Process.SHELL_UID && callingUid != Process.ROOT_UID &&
callingUid != Process.SYSTEM_UID) {
throw new SecurityException("Only shell can call disableSurfaceTrace");
}
- mSurfaceTraceEnabled = false;
- mRemoteEventTrace = null;
- mSurfaceTraceFd = null;
- for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
- DisplayContent dc = mDisplayContents.valueAt(displayNdx);
- dc.disableSurfaceTrace();
+ synchronized (mWindowMap) {
+ mRoot.disableSurfaceTrace();
}
}
@@ -2002,15 +1981,7 @@
synchronized(mWindowMap) {
mScreenCaptureDisabled.put(userId, disabled);
// Update secure surface for all windows belonging to this user.
- for (int displayNdx = mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
- WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
- for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
- final WindowState win = windows.get(winNdx);
- if (win.mHasSurface && userId == UserHandle.getUserId(win.mOwnerUid)) {
- win.mWinAnimator.setSecureLocked(disabled);
- }
- }
- }
+ mRoot.setSecureSurfaceState(userId, disabled);
}
}
@@ -2093,20 +2064,7 @@
public void updateAppOpsState() {
synchronized(mWindowMap) {
- final int numDisplays = mDisplayContents.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
- final int numWindows = windows.size();
- for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
- final WindowState win = windows.get(winNdx);
- if (win.mAppOp != AppOpsManager.OP_NONE) {
- final int mode = mAppOps.checkOpNoThrow(win.mAppOp, win.getOwningUid(),
- win.getOwningPackage());
- win.setAppOpVisibilityLw(mode == AppOpsManager.MODE_ALLOWED ||
- mode == AppOpsManager.MODE_DEFAULT);
- }
- }
- }
+ mRoot.updateAppOpsState();
}
}
@@ -2672,7 +2630,7 @@
}
public boolean outOfMemoryWindow(Session session, IWindow client) {
- long origId = Binder.clearCallingIdentity();
+ final long origId = Binder.clearCallingIdentity();
try {
synchronized (mWindowMap) {
@@ -2680,7 +2638,7 @@
if (win == null) {
return false;
}
- return reclaimSomeSurfaceMemoryLocked(win.mWinAnimator, "from-client", false);
+ return mRoot.reclaimSomeSurfaceMemory(win.mWinAnimator, "from-client", false);
}
} finally {
Binder.restoreCallingIdentity(origId);
@@ -3129,13 +3087,11 @@
mWaitingForConfig = false;
mLastFinishedFreezeSource = "new-config";
}
- boolean configChanged = mGlobalConfiguration.diff(config) != 0;
+ final boolean configChanged = mGlobalConfiguration.diff(config) != 0;
if (!configChanged) {
return null;
}
- prepareFreezingAllTaskBounds();
- mGlobalConfiguration = new Configuration(config);
- return onConfigurationChanged();
+ return mRoot.onConfigurationChanged(config);
}
}
@@ -3149,26 +3105,6 @@
}
}
- private void prepareFreezingAllTaskBounds() {
- for (int i = mDisplayContents.size() - 1; i >= 0; i--) {
- mDisplayContents.valueAt(i).prepareFreezingTaskBounds();
- }
- }
-
- private int[] onConfigurationChanged() {
- mPolicy.onConfigurationChanged();
-
- mChangedStackList.clear();
-
- final int numDisplays = mDisplayContents.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
- displayContent.onConfigurationChanged(mChangedStackList);
- }
-
- return mChangedStackList.isEmpty() ? null : ArrayUtils.convertToIntArray(mChangedStackList);
- }
-
@Override
public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
@@ -3970,44 +3906,11 @@
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mWindowMap) {
- final DisplayContent displayContent = mDisplayContents.get(displayId);
- boolean attachedToDisplay = false;
- if (displayContent != null) {
- TaskStack stack = mStackIdToStack.get(stackId);
- if (stack == null) {
- if (DEBUG_STACK) Slog.d(TAG_WM, "attachStack: stackId=" + stackId);
-
- stack = displayContent.getStackById(stackId);
- if (stack != null) {
- // It's already attached to the display...clear mDeferRemoval!
- stack.mDeferRemoval = false;
- attachedToDisplay = true;
- } else {
- stack = new TaskStack(this, stackId);
- }
-
- mStackIdToStack.put(stackId, stack);
- if (stackId == DOCKED_STACK_ID) {
- getDefaultDisplayContentLocked().mDividerControllerLocked
- .notifyDockedStackExistsChanged(true);
- }
- }
- if (!attachedToDisplay) {
- stack.attachDisplayContent(displayContent);
- }
- displayContent.attachStack(stack, onTop);
- if (stack.getRawFullscreen()) {
- return null;
- }
- Rect bounds = new Rect();
- stack.getRawBounds(bounds);
- return bounds;
- }
+ return mRoot.addStackToDisplay(stackId, displayId, onTop);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
- return null;
}
public void detachStack(int stackId) {
@@ -4475,20 +4378,7 @@
@Override
public void closeSystemDialogs(String reason) {
synchronized(mWindowMap) {
- final int numDisplays = mDisplayContents.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
- final int numWindows = windows.size();
- for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
- final WindowState w = windows.get(winNdx);
- if (w.mHasSurface) {
- try {
- w.mClient.closeSystemDialogs(reason);
- } catch (RemoteException e) {
- }
- }
- }
- }
+ mRoot.closeSystemDialogs(reason);
}
}
@@ -4677,11 +4567,7 @@
mPolicy.enableKeyguard(true);
// Hide windows that should not be seen by the new user.
- final int numDisplays = mDisplayContents.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
- displayContent.switchUserStacks();
- }
+ mRoot.switchUser();
mWindowPlacerLocked.performSurfacePlacement();
// Notify whether the docked stack exists for the current user
@@ -5066,26 +4952,10 @@
private void showStrictModeViolation(int arg, int pid) {
final boolean on = arg != 0;
synchronized(mWindowMap) {
- // Ignoring requests to enable the red border from clients
- // which aren't on screen. (e.g. Broadcast Receivers in
- // the background..)
- if (on) {
- boolean isVisible = false;
- final int numDisplays = mDisplayContents.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
- final int numWindows = windows.size();
- for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
- final WindowState ws = windows.get(winNdx);
- if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
- isVisible = true;
- break;
- }
- }
- }
- if (!isVisible) {
- return;
- }
+ // Ignoring requests to enable the red border from clients which aren't on screen.
+ // (e.g. Broadcast Receivers in the background..)
+ if (on && !mRoot.canShowStrictModeViolation(pid)) {
+ return;
}
if (SHOW_VERBOSE_TRANSACTIONS) Slog.i(TAG_WM,
@@ -5220,7 +5090,7 @@
boolean wallpaperOnly) {
final DisplayContent displayContent;
synchronized(mWindowMap) {
- displayContent = getDisplayContentLocked(displayId);
+ displayContent = mRoot.getDisplayContent(displayId);
if (displayContent == null) {
if (DEBUG_SCREENSHOT) Slog.i(TAG_WM, "Screenshot of " + appToken
+ ": returning null. No Display for displayId=" + displayId);
@@ -5773,7 +5643,7 @@
if (w.mHasSurface && !rotateSeamlessly) {
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Set mOrientationChanging of " + w);
w.mOrientationChanging = true;
- mWindowPlacerLocked.mOrientationChangeComplete = false;
+ mRoot.mOrientationChangeComplete = false;
w.mLastFreezeDuration = 0;
}
}
@@ -6010,13 +5880,12 @@
}
/**
- * Lists all availble windows in the system. The listing is written in the
- * specified Socket's output stream with the following syntax:
- * windowHashCodeInHexadecimal windowName
- * Each line of the ouput represents a different window.
+ * Lists all available windows in the system. The listing is written in the specified Socket's
+ * output stream with the following syntax: windowHashCodeInHexadecimal windowName
+ * Each line of the output represents a different window.
*
* @param client The remote client to send the listing to.
- * @return False if an error occured, true otherwise.
+ * @return false if an error occurred, true otherwise.
*/
boolean viewServerListWindows(Socket client) {
if (isSystemSecure()) {
@@ -6025,14 +5894,9 @@
boolean result = true;
- WindowList windows = new WindowList();
+ final WindowList windows = new WindowList();
synchronized (mWindowMap) {
- //noinspection unchecked
- final int numDisplays = mDisplayContents.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
- windows.addAll(displayContent.getWindowList());
- }
+ mRoot.getWindows(windows);
}
BufferedWriter out = null;
@@ -6259,20 +6123,8 @@
}
synchronized (mWindowMap) {
- final int numDisplays = mDisplayContents.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
- final int numWindows = windows.size();
- for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
- final WindowState w = windows.get(winNdx);
- if (System.identityHashCode(w) == hashCode) {
- return w;
- }
- }
- }
+ return mRoot.findWindow(hashCode);
}
-
- return null;
}
/**
@@ -6930,7 +6782,7 @@
private void displayReady(int displayId) {
synchronized(mWindowMap) {
- final DisplayContent displayContent = getDisplayContentLocked(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null) {
mAnimator.addDisplayLocked(displayId);
displayContent.initializeDisplayBaseInfo();
@@ -7771,7 +7623,7 @@
@Override
public void getInitialDisplaySize(int displayId, Point size) {
synchronized (mWindowMap) {
- final DisplayContent displayContent = getDisplayContentLocked(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
size.x = displayContent.mInitialDisplayWidth;
size.y = displayContent.mInitialDisplayHeight;
@@ -7782,7 +7634,7 @@
@Override
public void getBaseDisplaySize(int displayId, Point size) {
synchronized (mWindowMap) {
- final DisplayContent displayContent = getDisplayContentLocked(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
size.x = displayContent.mBaseDisplayWidth;
size.y = displayContent.mBaseDisplayHeight;
@@ -7809,7 +7661,7 @@
final int MIN_WIDTH = 200;
final int MIN_HEIGHT = 200;
final int MAX_SCALE = 2;
- final DisplayContent displayContent = getDisplayContentLocked(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null) {
width = Math.min(Math.max(width, MIN_WIDTH),
displayContent.mInitialDisplayWidth * MAX_SCALE);
@@ -7839,7 +7691,7 @@
final long ident = Binder.clearCallingIdentity();
try {
synchronized(mWindowMap) {
- final DisplayContent displayContent = getDisplayContentLocked(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null) {
if (mode < 0 || mode > 1) {
mode = 0;
@@ -7922,7 +7774,7 @@
final long ident = Binder.clearCallingIdentity();
try {
synchronized(mWindowMap) {
- final DisplayContent displayContent = getDisplayContentLocked(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null) {
setForcedDisplaySizeLocked(displayContent, displayContent.mInitialDisplayWidth,
displayContent.mInitialDisplayHeight);
@@ -7938,7 +7790,7 @@
@Override
public int getInitialDisplayDensity(int displayId) {
synchronized (mWindowMap) {
- final DisplayContent displayContent = getDisplayContentLocked(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
return displayContent.mInitialDisplayDensity;
}
@@ -7949,7 +7801,7 @@
@Override
public int getBaseDisplayDensity(int displayId) {
synchronized (mWindowMap) {
- final DisplayContent displayContent = getDisplayContentLocked(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null && displayContent.hasAccess(Binder.getCallingUid())) {
return displayContent.mBaseDisplayDensity;
}
@@ -7975,7 +7827,7 @@
final long ident = Binder.clearCallingIdentity();
try {
synchronized(mWindowMap) {
- final DisplayContent displayContent = getDisplayContentLocked(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null && mCurrentUserId == targetUserId) {
setForcedDisplayDensityLocked(displayContent, density);
}
@@ -8006,7 +7858,7 @@
final long ident = Binder.clearCallingIdentity();
try {
synchronized(mWindowMap) {
- final DisplayContent displayContent = getDisplayContentLocked(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null && mCurrentUserId == callingUserId) {
setForcedDisplayDensityLocked(displayContent,
displayContent.mInitialDisplayDensity);
@@ -8072,7 +7924,7 @@
mWindowPlacerLocked.performSurfacePlacement();
}
- private void configureDisplayPolicyLocked(DisplayContent displayContent) {
+ void configureDisplayPolicyLocked(DisplayContent displayContent) {
mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
displayContent.mBaseDisplayWidth,
displayContent.mBaseDisplayHeight,
@@ -8095,7 +7947,7 @@
final long ident = Binder.clearCallingIdentity();
try {
synchronized(mWindowMap) {
- DisplayContent displayContent = getDisplayContentLocked(displayId);
+ DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null) {
setOverscanLocked(displayContent, left, top, right, bottom);
}
@@ -8162,7 +8014,7 @@
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Changing surface while display frozen: " + w);
w.mOrientationChanging = true;
w.mLastFreezeDuration = 0;
- mWindowPlacerLocked.mOrientationChangeComplete = false;
+ mRoot.mOrientationChangeComplete = false;
if (mWindowsFreezingScreen == WINDOWS_FREEZING_SCREENS_NONE) {
mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE;
// XXX should probably keep timeout from
@@ -8196,7 +8048,7 @@
if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG_WM,
"Wallpaper layer changed: assigning layers + relayout");
moveInputMethodWindowsIfNeededLocked(true);
- mWindowPlacerLocked.mWallpaperMayChange = true;
+ mRoot.mWallpaperMayChange = true;
// Since the window list has been rebuilt, focus might have to be recomputed since the
// actual order of windows might have changed again.
mFocusMayChange = true;
@@ -8345,20 +8197,20 @@
if (hold != state) {
if (hold) {
if (DEBUG_KEEP_SCREEN_ON) {
- Slog.d(TAG_KEEP_SCREEN_ON, "Acquiring screen wakelock due to " +
- mWindowPlacerLocked.mHoldScreenWindow);
+ Slog.d(TAG_KEEP_SCREEN_ON, "Acquiring screen wakelock due to "
+ + mRoot.mHoldScreenWindow);
}
- mLastWakeLockHoldingWindow = mWindowPlacerLocked.mHoldScreenWindow;
+ mLastWakeLockHoldingWindow = mRoot.mHoldScreenWindow;
mLastWakeLockObscuringWindow = null;
mHoldingScreenWakeLock.acquire();
mPolicy.keepScreenOnStartedLw();
} else {
if (DEBUG_KEEP_SCREEN_ON) {
- Slog.d(TAG_KEEP_SCREEN_ON, "Releasing screen wakelock, obscured by " +
- mWindowPlacerLocked.mObsuringWindow);
+ Slog.d(TAG_KEEP_SCREEN_ON, "Releasing screen wakelock, obscured by "
+ + mRoot.mObsuringWindow);
}
mLastWakeLockHoldingWindow = null;
- mLastWakeLockObscuringWindow = mWindowPlacerLocked.mObsuringWindow;
+ mLastWakeLockObscuringWindow = mRoot.mObsuringWindow;
mPolicy.keepScreenOnStoppedLw();
mHoldingScreenWakeLock.release();
}
@@ -8379,17 +8231,6 @@
}
}
- boolean needsLayout() {
- final int numDisplays = mDisplayContents.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
- if (displayContent.layoutNeeded) {
- return true;
- }
- }
- return false;
- }
-
/** If a window that has an animation specifying a colored background and the current wallpaper
* is visible, then the color goes *below* the wallpaper so we don't cause the wallpaper to
* suddenly disappear. */
@@ -8404,108 +8245,8 @@
return winAnimator.mAnimLayer;
}
- boolean reclaimSomeSurfaceMemoryLocked(WindowStateAnimator winAnimator, String operation,
- boolean secure) {
- final WindowSurfaceController surfaceController = winAnimator.mSurfaceController;
- boolean leakedSurface = false;
- boolean killedApps = false;
-
- EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
- winAnimator.mSession.mPid, operation);
-
- final long callingIdentity = Binder.clearCallingIdentity();
- try {
- // There was some problem... first, do a sanity check of the window list to make sure
- // we haven't left any dangling surfaces around.
-
- Slog.i(TAG_WM, "Out of memory for surface! Looking for leaks...");
- final int numDisplays = mDisplayContents.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
- final int numWindows = windows.size();
- for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
- final WindowState ws = windows.get(winNdx);
- final WindowStateAnimator wsa = ws.mWinAnimator;
- if (wsa.mSurfaceController == null) {
- continue;
- }
- if (!mSessions.contains(wsa.mSession)) {
- Slog.w(TAG_WM, "LEAKED SURFACE (session doesn't exist): "
- + ws + " surface=" + wsa.mSurfaceController
- + " token=" + ws.mToken
- + " pid=" + ws.mSession.mPid
- + " uid=" + ws.mSession.mUid);
- wsa.destroySurface();
- mForceRemoves.add(ws);
- leakedSurface = true;
- } else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
- Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): "
- + ws + " surface=" + wsa.mSurfaceController
- + " token=" + ws.mAppToken
- + " saved=" + ws.hasSavedSurface());
- if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", false);
- wsa.destroySurface();
- leakedSurface = true;
- }
- }
- }
-
- if (!leakedSurface) {
- Slog.w(TAG_WM, "No leaked surfaces; killing applicatons!");
- SparseIntArray pidCandidates = new SparseIntArray();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList();
- final int numWindows = windows.size();
- for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
- final WindowState ws = windows.get(winNdx);
- if (mForceRemoves.contains(ws)) {
- continue;
- }
- WindowStateAnimator wsa = ws.mWinAnimator;
- if (wsa.mSurfaceController != null) {
- pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
- }
- }
- if (pidCandidates.size() > 0) {
- int[] pids = new int[pidCandidates.size()];
- for (int i=0; i<pids.length; i++) {
- pids[i] = pidCandidates.keyAt(i);
- }
- try {
- if (mActivityManager.killPids(pids, "Free memory", secure)) {
- killedApps = true;
- }
- } catch (RemoteException e) {
- }
- }
- }
- }
-
- if (leakedSurface || killedApps) {
- // We managed to reclaim some memory, so get rid of the trouble
- // surface and ask the app to request another one.
- Slog.w(TAG_WM, "Looks like we have reclaimed some memory, clearing surface for retry.");
- if (surfaceController != null) {
- if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
- "RECOVER DESTROY", false);
- winAnimator.destroySurface();
- scheduleRemoveStartingWindowLocked(winAnimator.mWin.mAppToken);
- }
-
- try {
- winAnimator.mWin.mClient.dispatchGetNewSurface();
- } catch (RemoteException e) {
- }
- }
- } finally {
- Binder.restoreCallingIdentity(callingIdentity);
- }
-
- return leakedSurface || killedApps;
- }
-
boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
- WindowState newFocus = computeFocusedWindowLocked();
+ WindowState newFocus = mRoot.computeFocusedWindow();
if (mCurrentFocus != newFocus) {
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
// This check makes sure that we don't already have the focus
@@ -8519,7 +8260,7 @@
&& mode != UPDATE_FOCUS_WILL_PLACE_SURFACES);
if (imWindowChanged) {
displayContent.layoutNeeded = true;
- newFocus = computeFocusedWindowLocked();
+ newFocus = mRoot.computeFocusedWindow();
}
if (DEBUG_FOCUS_LIGHT || localLOGV) Slog.v(TAG_WM, "Changing focus from " +
@@ -8572,18 +8313,6 @@
return false;
}
- private WindowState computeFocusedWindowLocked() {
- final int displayCount = mDisplayContents.size();
- for (int i = 0; i < displayCount; i++) {
- final DisplayContent displayContent = mDisplayContents.valueAt(i);
- final WindowState win = displayContent.findFocusedWindow();
- if (win != null) {
- return win;
- }
- }
- return null;
- }
-
void startFreezingDisplayLocked(boolean inTransaction, int exitAnim, int enterAnim) {
if (mDisplayFrozen) {
return;
@@ -9118,19 +8847,6 @@
}
}
- void dumpDisplayContentsLocked(PrintWriter pw, boolean dumpAll) {
- pw.println("WINDOW MANAGER DISPLAY CONTENTS (dumpsys window displays)");
- if (mDisplayReady) {
- final int numDisplays = mDisplayContents.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
- displayContent.dump(" ", pw);
- }
- } else {
- pw.println(" NO DISPLAY");
- }
- }
-
void dumpWindowsLocked(PrintWriter pw, boolean dumpAll,
ArrayList<WindowState> windows) {
pw.println("WINDOW MANAGER WINDOWS (dumpsys window windows)");
@@ -9139,18 +8855,8 @@
void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll,
ArrayList<WindowState> windows) {
- final int numDisplays = mDisplayContents.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final WindowList windowList = mDisplayContents.valueAt(displayNdx).getWindowList();
- for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
- final WindowState w = windowList.get(winNdx);
- if (windows == null || windows.contains(w)) {
- pw.print(" Window #"); pw.print(winNdx); pw.print(' ');
- pw.print(w); pw.println(":");
- w.dump(pw, " ", dumpAll || windows != null);
- }
- }
- }
+ mRoot.dumpWindowsNoHeader(pw, dumpAll, windows);
+
if (mInputMethodDialogs.size() > 0) {
pw.println();
pw.println(" Input method dialogs:");
@@ -9293,16 +8999,9 @@
mLayersController.dump(pw, " ");
pw.print(" mSystemBooted="); pw.print(mSystemBooted);
pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
- if (needsLayout()) {
- pw.print(" layoutNeeded on displays=");
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx);
- if (displayContent.layoutNeeded) {
- pw.print(displayContent.getDisplayId());
- }
- }
- pw.println();
- }
+
+ mRoot.dumpLayoutNeededDisplayIds(pw);
+
pw.print(" mTransactionSequence="); pw.println(mTransactionSequence);
pw.print(" mDisplayFrozen="); pw.print(mDisplayFrozen);
pw.print(" windows="); pw.print(mWindowsFreezingScreen);
@@ -9324,54 +9023,21 @@
}
}
- boolean dumpWindows(PrintWriter pw, String name, String[] args,
- int opti, boolean dumpAll) {
+ boolean dumpWindows(PrintWriter pw, String name, String[] args, int opti, boolean dumpAll) {
WindowList windows = new WindowList();
if ("apps".equals(name) || "visible".equals(name) || "visible-apps".equals(name)) {
final boolean appsOnly = name.contains("apps");
final boolean visibleOnly = name.contains("visible");
synchronized(mWindowMap) {
if (appsOnly) {
- dumpDisplayContentsLocked(pw, true);
+ mRoot.dumpDisplayContents(pw);
}
- final int numDisplays = mDisplayContents.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final WindowList windowList =
- mDisplayContents.valueAt(displayNdx).getWindowList();
- for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
- final WindowState w = windowList.get(winNdx);
- if ((!visibleOnly || w.mWinAnimator.getShown())
- && (!appsOnly || w.mAppToken != null)) {
- windows.add(w);
- }
- }
- }
+ mRoot.getWindows(windows, visibleOnly, appsOnly);
}
} else {
- int objectId = 0;
- // See if this is an object ID.
- try {
- objectId = Integer.parseInt(name, 16);
- name = null;
- } catch (RuntimeException e) {
- }
synchronized(mWindowMap) {
- final int numDisplays = mDisplayContents.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final WindowList windowList =
- mDisplayContents.valueAt(displayNdx).getWindowList();
- for (int winNdx = windowList.size() - 1; winNdx >= 0; --winNdx) {
- final WindowState w = windowList.get(winNdx);
- if (name != null) {
- if (w.mAttrs.getTitle().toString().contains(name)) {
- windows.add(w);
- }
- } else if (System.identityHashCode(w) == objectId) {
- windows.add(w);
- }
- }
- }
+ mRoot.getWindowsByName(windows, name);
}
}
@@ -9421,7 +9087,7 @@
dumpWindowsNoHeaderLocked(pw, true, null);
pw.println();
pw.println("Last ANR continued");
- dumpDisplayContentsLocked(pw, true);
+ mRoot.dumpDisplayContents(pw);
pw.close();
mLastANRState = sw.toString();
@@ -9506,7 +9172,7 @@
return;
} else if ("displays".equals(cmd) || "d".equals(cmd)) {
synchronized(mWindowMap) {
- dumpDisplayContentsLocked(pw, true);
+ mRoot.dumpDisplayContents(pw);
}
return;
} else if ("tokens".equals(cmd) || "t".equals(cmd)) {
@@ -9566,7 +9232,7 @@
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
}
- dumpDisplayContentsLocked(pw, dumpAll);
+ mRoot.dumpDisplayContents(pw);
pw.println();
if (dumpAll) {
pw.println("-------------------------------------------------------------------------------");
@@ -9586,61 +9252,17 @@
synchronized (mWindowMap) { }
}
- private DisplayContent newDisplayContentLocked(final Display display) {
- DisplayContent displayContent = new DisplayContent(display, this);
- final int displayId = display.getDisplayId();
- if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Adding display=" + display);
- mDisplayContents.put(displayId, displayContent);
-
- DisplayInfo displayInfo = displayContent.getDisplayInfo();
- final Rect rect = new Rect();
- mDisplaySettings.getOverscanLocked(displayInfo.name, displayInfo.uniqueId, rect);
- displayInfo.overscanLeft = rect.left;
- displayInfo.overscanTop = rect.top;
- displayInfo.overscanRight = rect.right;
- displayInfo.overscanBottom = rect.bottom;
- if (mDisplayManagerInternal != null) {
- mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(displayId, displayInfo);
- configureDisplayPolicyLocked(displayContent);
-
- // TODO: Create an input channel for each display with touch capability.
- if (displayId == Display.DEFAULT_DISPLAY) {
- displayContent.mTapDetector = new TaskTapPointerEventListener(this, displayContent);
- registerPointerEventListener(displayContent.mTapDetector);
- registerPointerEventListener(mMousePositionTracker);
- }
- }
-
- return displayContent;
- }
-
+ // TODO: All the display method below should probably be moved into the RootWindowContainer...
public void createDisplayContentLocked(final Display display) {
if (display == null) {
throw new IllegalArgumentException("getDisplayContent: display must not be null");
}
- getDisplayContentLocked(display.getDisplayId());
- }
-
- /**
- * Retrieve the DisplayContent for the specified displayId. Will create a new DisplayContent if
- * there is a Display for the displayId.
- * @param displayId The display the caller is interested in.
- * @return The DisplayContent associated with displayId or null if there is no Display for it.
- */
- public DisplayContent getDisplayContentLocked(final int displayId) {
- DisplayContent displayContent = mDisplayContents.get(displayId);
- if (displayContent == null) {
- final Display display = mDisplayManager.getDisplay(displayId);
- if (display != null) {
- displayContent = newDisplayContentLocked(display);
- }
- }
- return displayContent;
+ mRoot.getDisplayContent(display.getDisplayId());
}
// There is an inherent assumption that this will never return null.
public DisplayContent getDefaultDisplayContentLocked() {
- return getDisplayContentLocked(Display.DEFAULT_DISPLAY);
+ return mRoot.getDisplayContent(Display.DEFAULT_DISPLAY);
}
public WindowList getDefaultWindowListLocked() {
@@ -9653,20 +9275,11 @@
/**
* Return the list of WindowStates associated on the passed display.
- * @param display The screen to return windows from.
- * @return The list of WindowStates on the screen, or null if the there is no screen.
- */
- public WindowList getWindowListLocked(final Display display) {
- return getWindowListLocked(display.getDisplayId());
- }
-
- /**
- * Return the list of WindowStates associated on the passed display.
* @param displayId The screen to return windows from.
* @return The list of WindowStates on the screen, or null if the there is no screen.
*/
- public WindowList getWindowListLocked(final int displayId) {
- final DisplayContent displayContent = getDisplayContentLocked(displayId);
+ WindowList getWindowListLocked(final int displayId) {
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
return displayContent != null ? displayContent.getWindowList() : null;
}
@@ -9690,7 +9303,7 @@
}
private void handleDisplayRemovedLocked(int displayId) {
- final DisplayContent displayContent = getDisplayContentLocked(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null) {
displayContent.removeIfPossible();
}
@@ -9703,7 +9316,7 @@
}
private void handleDisplayChangedLocked(int displayId) {
- final DisplayContent displayContent = getDisplayContentLocked(displayId);
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
if (displayContent != null) {
displayContent.updateDisplayInfo();
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 1c0d830..637adb9 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2507,7 +2507,7 @@
&& mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "set mOrientationChanging of " + this);
mOrientationChanging = true;
- mService.mWindowPlacerLocked.mOrientationChangeComplete = false;
+ mService.mRoot.mOrientationChangeComplete = false;
}
mLastFreezeDuration = 0;
setDisplayLayoutNeeded();
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index ce101e7..cbb5040 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -685,7 +685,7 @@
}
} catch (OutOfResourcesException e) {
Slog.w(TAG, "OutOfResourcesException creating surface");
- mService.reclaimSomeSurfaceMemoryLocked(this, "create", true);
+ mService.mRoot.reclaimSomeSurfaceMemory(this, "create", true);
mDrawState = NO_SURFACE;
return null;
} catch (Exception e) {
@@ -1020,7 +1020,7 @@
+ " screen=" + (screenAnimation ?
screenRotationAnimation.getEnterTransformation().getAlpha() : "null"));
return;
- } else if (mIsWallpaper && mService.mWindowPlacerLocked.mWallpaperActionPending) {
+ } else if (mIsWallpaper && mService.mRoot.mWallpaperActionPending) {
return;
} else if (mWin.isDragResizeChanged()) {
// This window is awaiting a relayout because user just started (or ended)
@@ -1850,7 +1850,7 @@
}
void reclaimSomeSurfaceMemory(String operation, boolean secure) {
- mService.reclaimSomeSurfaceMemoryLocked(this, operation, secure);
+ mService.mRoot.reclaimSomeSurfaceMemory(this, operation, secure);
}
boolean getShown() {
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index cc72352..368484a 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -101,8 +101,9 @@
s, name, w, h, format, flags);
}
- if (mService.mSurfaceTraceEnabled) {
- mSurfaceControl = new RemoteSurfaceTrace(mService.mSurfaceTraceFd.getFileDescriptor(),
+ if (mService.mRoot.mSurfaceTraceEnabled) {
+ mSurfaceControl = new RemoteSurfaceTrace(
+ mService.mRoot.mSurfaceTraceFd.getFileDescriptor(),
mSurfaceControl, animator.mWin);
}
}
@@ -116,7 +117,7 @@
}
- void logSurface(String msg, RuntimeException where) {
+ private void logSurface(String msg, RuntimeException where) {
String str = " SURFACE " + msg + ": " + title;
if (where != null) {
Slog.i(TAG, str, where);
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 13d3501..a66a49b 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -1,65 +1,36 @@
+
package com.android.server.wm;
import static android.app.ActivityManagerInternal.APP_TRANSITION_SAVED_SURFACE;
import static android.app.ActivityManagerInternal.APP_TRANSITION_STARTING_WINDOW;
import static android.app.ActivityManagerInternal.APP_TRANSITION_TIMEOUT;
import static android.app.ActivityManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;
-import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
-import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
-import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
-import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
-import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_POWER;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.H.DO_TRAVERSAL;
import static com.android.server.wm.WindowManagerService.H.NOTIFY_APP_TRANSITION_STARTING;
-import static com.android.server.wm.WindowManagerService.H.NOTIFY_STARTING_WINDOW_DRAWN;
-import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS;
import static com.android.server.wm.WindowManagerService.H.REPORT_WINDOWS_CHANGE;
-import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
import static com.android.server.wm.WindowManagerService.H.UPDATE_DOCKED_STACK_DIVIDER;
-import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT;
import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
-import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
-import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.Debug;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.SystemClock;
import android.os.Trace;
-import android.provider.Settings;
import android.util.ArraySet;
import android.util.Slog;
import android.view.Display;
@@ -98,46 +69,12 @@
static final int SET_TURN_ON_SCREEN = 1 << 4;
static final int SET_WALLPAPER_ACTION_PENDING = 1 << 5;
- boolean mWallpaperMayChange = false;
- boolean mOrientationChangeComplete = true;
- boolean mWallpaperActionPending = false;
-
- private boolean mWallpaperForceHidingChanged = false;
- private Object mLastWindowFreezeSource = null;
- private Session mHoldScreen = null;
- private boolean mObscured = false;
- private boolean mSyswin = false;
- private float mScreenBrightness = -1;
- private float mButtonBrightness = -1;
- private long mUserActivityTimeout = -1;
- private boolean mUpdateRotation = false;
private final Rect mTmpStartRect = new Rect();
private final Rect mTmpContentRect = new Rect();
- // Set to true when the display contains content to show the user.
- // When false, the display manager may choose to mirror or blank the display.
- private boolean mDisplayHasContent = false;
-
- // Only set while traversing the default display based on its content.
- // Affects the behavior of mirroring on secondary displays.
- private boolean mObscureApplicationContentOnSecondaryDisplays = false;
-
- private float mPreferredRefreshRate = 0;
-
- private int mPreferredModeId = 0;
-
private boolean mTraversalScheduled;
private int mDeferDepth = 0;
- private boolean mSustainedPerformanceModeEnabled = false;
- private boolean mSustainedPerformanceModeCurrent = false;
-
- // Following variables are for debugging screen wakelock only.
- // Last window that requires screen wakelock
- WindowState mHoldScreenWindow = null;
- // Last window that obscures all windows below
- WindowState mObsuringWindow = null;
-
private static final class LayerAndToken {
public int layer;
public AppWindowToken token;
@@ -179,7 +116,7 @@
mService.mH.removeMessages(DO_TRAVERSAL);
loopCount--;
} while (mTraversalScheduled && loopCount > 0);
- mWallpaperActionPending = false;
+ mService.mRoot.mWallpaperActionPending = false;
}
private void performSurfacePlacementLoop() {
@@ -227,11 +164,11 @@
}
try {
- performSurfacePlacementInner(recoveringMemory);
+ mService.mRoot.performSurfacePlacement(recoveringMemory);
mInLayout = false;
- if (mService.needsLayout()) {
+ if (mService.mRoot.layoutNeeded()) {
if (++mLayoutRepeatCount < 6) {
requestTraversal();
} else {
@@ -261,625 +198,6 @@
}
}
- // "Something has changed! Let's make it correct now."
- private void performSurfacePlacementInner(boolean recoveringMemory) {
- if (DEBUG_WINDOW_TRACE) Slog.v(TAG, "performSurfacePlacementInner: entry. Called by "
- + Debug.getCallers(3));
-
- int i;
- boolean updateInputWindowsNeeded = false;
-
- if (mService.mFocusMayChange) {
- mService.mFocusMayChange = false;
- updateInputWindowsNeeded = mService.updateFocusedWindowLocked(
- UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
- }
-
- // Initialize state of exiting tokens.
- final int numDisplays = mService.mDisplayContents.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
- for (i=displayContent.mExitingTokens.size()-1; i>=0; i--) {
- displayContent.mExitingTokens.get(i).hasVisible = false;
- }
- }
-
- for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
- // Initialize state of exiting applications.
- final AppTokenList exitingAppTokens =
- mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
- for (int tokenNdx = exitingAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
- exitingAppTokens.get(tokenNdx).hasVisible = false;
- }
- }
-
- mHoldScreen = null;
- mHoldScreenWindow = null;
- mObsuringWindow = null;
- mScreenBrightness = -1;
- mButtonBrightness = -1;
- mUserActivityTimeout = -1;
- mObscureApplicationContentOnSecondaryDisplays = false;
- mSustainedPerformanceModeCurrent = false;
- mService.mTransactionSequence++;
-
- // TODO(multi-display): Perform same actions on all displays.
- final DisplayContent defaultDisplay = mService.getDefaultDisplayContentLocked();
- final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo();
- final int defaultDw = defaultInfo.logicalWidth;
- final int defaultDh = defaultInfo.logicalHeight;
-
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
- ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces");
- mService.openSurfaceTransaction();
- try {
- applySurfaceChangesTransaction(recoveringMemory, numDisplays, defaultDw, defaultDh);
- } catch (RuntimeException e) {
- Slog.wtf(TAG, "Unhandled exception in Window Manager", e);
- } finally {
- mService.closeSurfaceTransaction();
- if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
- "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces");
- }
-
- final WindowList defaultWindows = defaultDisplay.getWindowList();
-
- // If we are ready to perform an app transition, check through
- // all of the app tokens to be shown and see if they are ready
- // to go.
- if (mService.mAppTransition.isReady()) {
- defaultDisplay.pendingLayoutChanges |= handleAppTransitionReadyLocked(defaultWindows);
- if (DEBUG_LAYOUT_REPEATS)
- debugLayoutRepeats("after handleAppTransitionReadyLocked",
- defaultDisplay.pendingLayoutChanges);
- }
-
- if (!mService.mAnimator.mAppWindowAnimating && mService.mAppTransition.isRunning()) {
- // We have finished the animation of an app transition. To do
- // this, we have delayed a lot of operations like showing and
- // hiding apps, moving apps in Z-order, etc. The app token list
- // reflects the correct Z-order, but the window list may now
- // be out of sync with it. So here we will just rebuild the
- // entire app window list. Fun!
- defaultDisplay.pendingLayoutChanges |=
- mService.handleAnimatingStoppedAndTransitionLocked();
- if (DEBUG_LAYOUT_REPEATS)
- debugLayoutRepeats("after handleAnimStopAndXitionLock",
- defaultDisplay.pendingLayoutChanges);
- }
-
- if (mWallpaperForceHidingChanged && defaultDisplay.pendingLayoutChanges == 0
- && !mService.mAppTransition.isReady()) {
- // At this point, there was a window with a wallpaper that
- // was force hiding other windows behind it, but now it
- // is going away. This may be simple -- just animate
- // away the wallpaper and its window -- or it may be
- // hard -- the wallpaper now needs to be shown behind
- // something that was hidden.
- defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
- if (DEBUG_LAYOUT_REPEATS)
- debugLayoutRepeats("after animateAwayWallpaperLocked",
- defaultDisplay.pendingLayoutChanges);
- }
- mWallpaperForceHidingChanged = false;
-
- if (mWallpaperMayChange) {
- if (DEBUG_WALLPAPER_LIGHT)
- Slog.v(TAG, "Wallpaper may change! Adjusting");
- defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
- if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("WallpaperMayChange",
- defaultDisplay.pendingLayoutChanges);
- }
-
- if (mService.mFocusMayChange) {
- mService.mFocusMayChange = false;
- if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
- false /*updateInputWindows*/)) {
- updateInputWindowsNeeded = true;
- defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
- }
- }
-
- if (mService.needsLayout()) {
- defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_LAYOUT;
- if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("mLayoutNeeded",
- defaultDisplay.pendingLayoutChanges);
- }
-
- for (i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
- WindowState win = mService.mResizingWindows.get(i);
- if (win.mAppFreezing) {
- // Don't remove this window until rotation has completed.
- continue;
- }
- // Discard the saved surface if window size is changed, it can't be reused.
- if (win.mAppToken != null) {
- win.mAppToken.destroySavedSurfaces();
- }
- win.reportResized();
- mService.mResizingWindows.remove(i);
- }
-
- if (DEBUG_ORIENTATION && mService.mDisplayFrozen) Slog.v(TAG,
- "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
- if (mOrientationChangeComplete) {
- if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
- mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_NONE;
- mService.mLastFinishedFreezeSource = mLastWindowFreezeSource;
- mService.mH.removeMessages(WINDOW_FREEZE_TIMEOUT);
- }
- mService.stopFreezingDisplayLocked();
- }
-
- // Destroy the surface of any windows that are no longer visible.
- boolean wallpaperDestroyed = false;
- i = mService.mDestroySurface.size();
- if (i > 0) {
- do {
- i--;
- WindowState win = mService.mDestroySurface.get(i);
- win.mDestroying = false;
- if (mService.mInputMethodWindow == win) {
- mService.mInputMethodWindow = null;
- }
- if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
- wallpaperDestroyed = true;
- }
- win.destroyOrSaveSurface();
- } while (i > 0);
- mService.mDestroySurface.clear();
- }
-
- // Time to remove any exiting tokens?
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
- ArrayList<WindowToken> exitingTokens = displayContent.mExitingTokens;
- for (i = exitingTokens.size() - 1; i >= 0; i--) {
- WindowToken token = exitingTokens.get(i);
- if (!token.hasVisible) {
- exitingTokens.remove(i);
- if (token.windowType == TYPE_WALLPAPER) {
- mWallpaperControllerLocked.removeWallpaperToken(token);
- }
- }
- }
- }
-
- // Time to remove any exiting applications?
- for (int stackNdx = mService.mStackIdToStack.size() - 1; stackNdx >= 0; --stackNdx) {
- // Initialize state of exiting applications.
- final AppTokenList exitingAppTokens =
- mService.mStackIdToStack.valueAt(stackNdx).mExitingAppTokens;
- for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
- AppWindowToken token = exitingAppTokens.get(i);
- if (!token.hasVisible && !mService.mClosingApps.contains(token) &&
- (!token.mIsExiting || token.isEmpty())) {
- // Make sure there is no animation running on this token,
- // so any windows associated with it will be removed as
- // soon as their animations are complete
- token.mAppAnimator.clearAnimation();
- token.mAppAnimator.animating = false;
- if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG,
- "performLayout: App token exiting now removed" + token);
- token.removeIfPossible();
- }
- }
- }
-
- if (wallpaperDestroyed) {
- defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
- defaultDisplay.layoutNeeded = true;
- }
-
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
- if (displayContent.pendingLayoutChanges != 0) {
- displayContent.layoutNeeded = true;
- }
- }
-
- // Finally update all input windows now that the window changes have stabilized.
- mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
-
- mService.setHoldScreenLocked(mHoldScreen);
- if (!mService.mDisplayFrozen) {
- if (mScreenBrightness < 0 || mScreenBrightness > 1.0f) {
- mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(-1);
- } else {
- mService.mPowerManagerInternal.setScreenBrightnessOverrideFromWindowManager(
- toBrightnessOverride(mScreenBrightness));
- }
- if (mButtonBrightness < 0
- || mButtonBrightness > 1.0f) {
- mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(-1);
- } else {
- mService.mPowerManagerInternal.setButtonBrightnessOverrideFromWindowManager(
- toBrightnessOverride(mButtonBrightness));
- }
- mService.mPowerManagerInternal.setUserActivityTimeoutOverrideFromWindowManager(
- mUserActivityTimeout);
- }
-
- if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) {
- mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent;
- mService.mPowerManagerInternal.powerHint(
- mService.mPowerManagerInternal.POWER_HINT_SUSTAINED_PERFORMANCE_MODE,
- (mSustainedPerformanceModeEnabled ? 1 : 0));
- }
-
- if (mService.mTurnOnScreen) {
- if (mService.mAllowTheaterModeWakeFromLayout
- || Settings.Global.getInt(mService.mContext.getContentResolver(),
- Settings.Global.THEATER_MODE_ON, 0) == 0) {
- if (DEBUG_VISIBILITY || DEBUG_POWER) {
- Slog.v(TAG, "Turning screen on after layout!");
- }
- mService.mPowerManager.wakeUp(SystemClock.uptimeMillis(),
- "android.server.wm:TURN_ON");
- }
- mService.mTurnOnScreen = false;
- }
-
- if (mUpdateRotation) {
- if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
- if (mService.updateRotationUncheckedLocked(false)) {
- mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
- } else {
- mUpdateRotation = false;
- }
- }
-
- if (mService.mWaitingForDrawnCallback != null ||
- (mOrientationChangeComplete && !defaultDisplay.layoutNeeded &&
- !mUpdateRotation)) {
- mService.checkDrawnWindowsLocked();
- }
-
- final int N = mService.mPendingRemove.size();
- if (N > 0) {
- if (mService.mPendingRemoveTmp.length < N) {
- mService.mPendingRemoveTmp = new WindowState[N+10];
- }
- mService.mPendingRemove.toArray(mService.mPendingRemoveTmp);
- mService.mPendingRemove.clear();
- DisplayContentList displayList = new DisplayContentList();
- for (i = 0; i < N; i++) {
- final WindowState w = mService.mPendingRemoveTmp[i];
- w.removeImmediately();
- final DisplayContent displayContent = w.getDisplayContent();
- if (displayContent != null && !displayList.contains(displayContent)) {
- displayList.add(displayContent);
- }
- }
-
- for (DisplayContent displayContent : displayList) {
- mService.mLayersController.assignLayersLocked(displayContent.getWindowList());
- displayContent.layoutNeeded = true;
- }
- }
-
- // Remove all deferred displays stacks, tasks, and activities.
- for (int displayNdx = mService.mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) {
- mService.mDisplayContents.valueAt(displayNdx).checkCompleteDeferredRemoval();
- }
-
- if (updateInputWindowsNeeded) {
- mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
- }
- mService.setFocusTaskRegionLocked();
-
- // Check to see if we are now in a state where the screen should
- // be enabled, because the window obscured flags have changed.
- mService.enableScreenIfNeededLocked();
-
- mService.scheduleAnimationLocked();
- mService.mWindowPlacerLocked.destroyPendingSurfaces();
-
- if (DEBUG_WINDOW_TRACE) Slog.e(TAG,
- "performSurfacePlacementInner exit: animating=" + mService.mAnimator.isAnimating());
- }
-
- private void applySurfaceChangesTransaction(boolean recoveringMemory, int numDisplays,
- int defaultDw, int defaultDh) {
- if (mService.mWatermark != null) {
- mService.mWatermark.positionSurface(defaultDw, defaultDh);
- }
- if (mService.mStrictModeFlash != null) {
- mService.mStrictModeFlash.positionSurface(defaultDw, defaultDh);
- }
- if (mService.mCircularDisplayMask != null) {
- mService.mCircularDisplayMask.positionSurface(defaultDw, defaultDh,
- mService.mRotation);
- }
- if (mService.mEmulatorDisplayOverlay != null) {
- mService.mEmulatorDisplayOverlay.positionSurface(defaultDw, defaultDh,
- mService.mRotation);
- }
-
- boolean focusDisplayed = false;
-
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);
- boolean updateAllDrawn = false;
- WindowList windows = displayContent.getWindowList();
- DisplayInfo displayInfo = displayContent.getDisplayInfo();
- final int displayId = displayContent.getDisplayId();
- final int dw = displayInfo.logicalWidth;
- final int dh = displayInfo.logicalHeight;
- final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
-
- // Reset for each display.
- mDisplayHasContent = false;
- mPreferredRefreshRate = 0;
- mPreferredModeId = 0;
-
- int repeats = 0;
- do {
- repeats++;
- if (repeats > 6) {
- Slog.w(TAG, "Animation repeat aborted after too many iterations");
- displayContent.layoutNeeded = false;
- break;
- }
-
- if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats(
- "On entry to LockedInner", displayContent.pendingLayoutChanges);
-
- if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
- mWallpaperControllerLocked.adjustWallpaperWindows()) {
- mService.mLayersController.assignLayersLocked(windows);
- displayContent.layoutNeeded = true;
- }
-
- if (isDefaultDisplay
- && (displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_CONFIG) != 0) {
- if (DEBUG_LAYOUT) Slog.v(TAG, "Computing new config from layout");
- if (mService.updateOrientationFromAppTokensLocked(true)) {
- displayContent.layoutNeeded = true;
- mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
- }
- }
-
- if ((displayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
- displayContent.layoutNeeded = true;
- }
-
- // FIRST LOOP: Perform a layout, if needed.
- if (repeats < LAYOUT_REPEAT_THRESHOLD) {
- performLayoutLockedInner(displayContent, repeats == 1,
- false /* updateInputWindows */);
- } else {
- Slog.w(TAG, "Layout repeat skipped after too many iterations");
- }
-
- // FIRST AND ONE HALF LOOP: Make WindowManagerPolicy think
- // it is animating.
- displayContent.pendingLayoutChanges = 0;
-
- if (isDefaultDisplay) {
- mService.mPolicy.beginPostLayoutPolicyLw(dw, dh);
- for (int i = windows.size() - 1; i >= 0; i--) {
- WindowState w = windows.get(i);
- if (w.mHasSurface) {
- mService.mPolicy.applyPostLayoutPolicyLw(
- w, w.mAttrs, w.getParentWindow());
- }
- }
- displayContent.pendingLayoutChanges |=
- mService.mPolicy.finishPostLayoutPolicyLw();
- if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after finishPostLayoutPolicyLw",
- displayContent.pendingLayoutChanges);
- }
- } while (displayContent.pendingLayoutChanges != 0);
-
- mObscured = false;
- mSyswin = false;
- displayContent.resetDimming();
-
- // Only used if default window
- final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
-
- for (int i = windows.size() - 1; i >= 0; i--) {
- WindowState w = windows.get(i);
- final Task task = w.getTask();
- final boolean obscuredChanged = w.mObscured != mObscured;
-
- // Update effect.
- w.mObscured = mObscured;
- if (!mObscured) {
- handleNotObscuredLocked(w, displayInfo);
- }
-
- w.applyDimLayerIfNeeded();
-
- if (isDefaultDisplay && obscuredChanged
- && mWallpaperControllerLocked.isWallpaperTarget(w) && w.isVisibleLw()) {
- // This is the wallpaper target and its obscured state
- // changed... make sure the current wallaper's visibility
- // has been updated accordingly.
- mWallpaperControllerLocked.updateWallpaperVisibility();
- }
-
- final WindowStateAnimator winAnimator = w.mWinAnimator;
-
- // If the window has moved due to its containing content frame changing, then
- // notify the listeners and optionally animate it. Simply checking a change of
- // position is not enough, because being move due to dock divider is not a trigger
- // for animation.
- if (w.hasMoved()) {
- // Frame has moved, containing content frame has also moved, and we're not
- // currently animating... let's do something.
- final int left = w.mFrame.left;
- final int top = w.mFrame.top;
- final boolean adjustedForMinimizedDockOrIme = task != null
- && (task.mStack.isAdjustedForMinimizedDockedStack()
- || task.mStack.isAdjustedForIme());
- if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
- && !w.isDragResizing() && !adjustedForMinimizedDockOrIme
- && (task == null || w.getTask().mStack.hasMovementAnimations())
- && !w.mWinAnimator.mLastHidden) {
- winAnimator.setMoveAnimation(left, top);
- }
-
- //TODO (multidisplay): Accessibility supported only for the default display.
- if (mService.mAccessibilityController != null
- && displayId == Display.DEFAULT_DISPLAY) {
- mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
- }
-
- try {
- w.mClient.moved(left, top);
- } catch (RemoteException e) {
- }
- w.mMovedByResize = false;
- }
-
- //Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
- w.mContentChanged = false;
-
- // Moved from updateWindowsAndWallpaperLocked().
- if (w.mHasSurface) {
- // Take care of the window being ready to display.
- final boolean committed = winAnimator.commitFinishDrawingLocked();
- if (isDefaultDisplay && committed) {
- if (w.mAttrs.type == TYPE_DREAM) {
- // HACK: When a dream is shown, it may at that
- // point hide the lock screen. So we need to
- // redo the layout to let the phone window manager
- // make this happen.
- displayContent.pendingLayoutChanges |=
- FINISH_LAYOUT_REDO_LAYOUT;
- if (DEBUG_LAYOUT_REPEATS) {
- debugLayoutRepeats("dream and commitFinishDrawingLocked true",
- displayContent.pendingLayoutChanges);
- }
- }
- if ((w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
- if (DEBUG_WALLPAPER_LIGHT)
- Slog.v(TAG, "First draw done in potential wallpaper target " + w);
- mWallpaperMayChange = true;
- displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
- if (DEBUG_LAYOUT_REPEATS) {
- debugLayoutRepeats("wallpaper and commitFinishDrawingLocked true",
- displayContent.pendingLayoutChanges);
- }
- }
- }
- if (!winAnimator.isAnimationStarting() && !winAnimator.isWaitingForOpening()) {
- // Updates the shown frame before we set up the surface. This is needed
- // because the resizing could change the top-left position (in addition to
- // size) of the window. setSurfaceBoundariesLocked uses mShownPosition to
- // position the surface.
- //
- // If an animation is being started, we can't call this method because the
- // animation hasn't processed its initial transformation yet, but in general
- // we do want to update the position if the window is animating.
- winAnimator.computeShownFrameLocked();
- }
- winAnimator.setSurfaceBoundariesLocked(recoveringMemory);
- }
-
- final AppWindowToken atoken = w.mAppToken;
- if (DEBUG_STARTING_WINDOW && atoken != null && w == atoken.startingWindow) {
- Slog.d(TAG, "updateWindows: starting " + w
- + " isOnScreen=" + w.isOnScreen() + " allDrawn=" + atoken.allDrawn
- + " freezingScreen=" + atoken.mAppAnimator.freezingScreen);
- }
- if (atoken != null && (!atoken.allDrawn || !atoken.allDrawnExcludingSaved
- || atoken.mAppAnimator.freezingScreen)) {
- if (atoken.lastTransactionSequence != mService.mTransactionSequence) {
- atoken.lastTransactionSequence = mService.mTransactionSequence;
- atoken.numInterestingWindows = atoken.numDrawnWindows = 0;
- atoken.numInterestingWindowsExcludingSaved = 0;
- atoken.numDrawnWindowsExcludingSaved = 0;
- atoken.startingDisplayed = false;
- }
- if (!atoken.allDrawn && w.mightAffectAllDrawn(false /* visibleOnly */)) {
- if (DEBUG_VISIBILITY || DEBUG_ORIENTATION) {
- Slog.v(TAG, "Eval win " + w + ": isDrawn="
- + w.isDrawnLw()
- + ", isAnimationSet=" + winAnimator.isAnimationSet());
- if (!w.isDrawnLw()) {
- Slog.v(TAG, "Not displayed: s="
- + winAnimator.mSurfaceController
- + " pv=" + w.mPolicyVisibility
- + " mDrawState=" + winAnimator.drawStateToString()
- + " ph=" + w.isParentWindowHidden()
- + " th=" + atoken.hiddenRequested
- + " a=" + winAnimator.mAnimating);
- }
- }
- if (w != atoken.startingWindow) {
- if (w.isInteresting()) {
- atoken.numInterestingWindows++;
- if (w.isDrawnLw()) {
- atoken.numDrawnWindows++;
- if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
- Slog.v(TAG, "tokenMayBeDrawn: " + atoken
- + " w=" + w + " numInteresting="
- + atoken.numInterestingWindows
- + " freezingScreen="
- + atoken.mAppAnimator.freezingScreen
- + " mAppFreezing=" + w.mAppFreezing);
- updateAllDrawn = true;
- }
- }
- } else if (w.isDrawnLw()) {
- mService.mH.sendEmptyMessage(NOTIFY_STARTING_WINDOW_DRAWN);
- atoken.startingDisplayed = true;
- }
- }
- if (!atoken.allDrawnExcludingSaved
- && w.mightAffectAllDrawn(true /* visibleOnly */)) {
- if (w != atoken.startingWindow && w.isInteresting()) {
- atoken.numInterestingWindowsExcludingSaved++;
- if (w.isDrawnLw() && !w.isAnimatingWithSavedSurface()) {
- atoken.numDrawnWindowsExcludingSaved++;
- if (DEBUG_VISIBILITY || DEBUG_ORIENTATION)
- Slog.v(TAG, "tokenMayBeDrawnExcludingSaved: " + atoken
- + " w=" + w + " numInteresting="
- + atoken.numInterestingWindowsExcludingSaved
- + " freezingScreen="
- + atoken.mAppAnimator.freezingScreen
- + " mAppFreezing=" + w.mAppFreezing);
- updateAllDrawn = true;
- }
- }
- }
- }
-
- if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
- && w.isDisplayedLw()) {
- focusDisplayed = true;
- }
-
- mService.updateResizingWindows(w);
- }
-
- mService.mDisplayManagerInternal.setDisplayProperties(displayId,
- mDisplayHasContent,
- mPreferredRefreshRate,
- mPreferredModeId,
- true /* inTraversal, must call performTraversalInTrans... below */);
-
- displayContent.stopDimmingIfNeeded();
-
- if (updateAllDrawn) {
- // See if any windows have been drawn, so they (and others associated with them)
- // can now be shown.
- displayContent.updateAllDrawn();
- }
- }
-
- if (focusDisplayed) {
- mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
- }
-
- // Give the display manager a chance to adjust properties
- // like display rotation if it needs to.
- mService.mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
- }
-
boolean isInLayout() {
return mInLayout;
}
@@ -1064,7 +382,7 @@
* @param windows List of windows on default display.
* @return bitmap indicating if another pass through layout must be made.
*/
- private int handleAppTransitionReadyLocked(WindowList windows) {
+ int handleAppTransitionReadyLocked(WindowList windows) {
int appsCount = mService.mOpeningApps.size();
if (!transitionGoodToGo(appsCount)) {
return 0;
@@ -1084,7 +402,7 @@
final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
displayContent.rebuildAppWindowList();
- mWallpaperMayChange = false;
+ mService.mRoot.mWallpaperMayChange = false;
// The top-most window will supply the layout params,
// and we will determine it below.
@@ -1437,91 +755,6 @@
return transit;
}
- /**
- * @param w WindowState this method is applied to.
- * @param dispInfo info of the display that the window's obscuring state is checked against.
- */
- private void handleNotObscuredLocked(final WindowState w, final DisplayInfo dispInfo) {
- final LayoutParams attrs = w.mAttrs;
- final int attrFlags = attrs.flags;
- final boolean canBeSeen = w.isDisplayedLw();
- final int privateflags = attrs.privateFlags;
-
- if (canBeSeen && w.isObscuringFullscreen(dispInfo)) {
- // This window completely covers everything behind it,
- // so we want to leave all of them as undimmed (for
- // performance reasons).
- if (!mObscured) {
- mObsuringWindow = w;
- }
-
- mObscured = true;
- }
-
- if (w.mHasSurface && canBeSeen) {
- if ((attrFlags&FLAG_KEEP_SCREEN_ON) != 0) {
- mHoldScreen = w.mSession;
- mHoldScreenWindow = w;
- } else if (DEBUG_KEEP_SCREEN_ON && w == mService.mLastWakeLockHoldingWindow) {
- Slog.d(TAG_KEEP_SCREEN_ON, "handleNotObscuredLocked: " + w + " was holding "
- + "screen wakelock but no longer has FLAG_KEEP_SCREEN_ON!!! called by"
- + Debug.getCallers(10));
- }
- if (!mSyswin && w.mAttrs.screenBrightness >= 0
- && mScreenBrightness < 0) {
- mScreenBrightness = w.mAttrs.screenBrightness;
- }
- if (!mSyswin && w.mAttrs.buttonBrightness >= 0
- && mButtonBrightness < 0) {
- mButtonBrightness = w.mAttrs.buttonBrightness;
- }
- if (!mSyswin && w.mAttrs.userActivityTimeout >= 0
- && mUserActivityTimeout < 0) {
- mUserActivityTimeout = w.mAttrs.userActivityTimeout;
- }
-
- final int type = attrs.type;
- if (type == TYPE_SYSTEM_DIALOG || type == TYPE_SYSTEM_ERROR
- || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
- mSyswin = true;
- }
-
- // This function assumes that the contents of the default display are
- // processed first before secondary displays.
- final DisplayContent displayContent = w.getDisplayContent();
- if (displayContent != null && displayContent.isDefaultDisplay) {
- // While a dream or keyguard is showing, obscure ordinary application
- // content on secondary displays (by forcibly enabling mirroring unless
- // there is other content we want to show) but still allow opaque
- // keyguard dialogs to be shown.
- if (type == TYPE_DREAM || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
- mObscureApplicationContentOnSecondaryDisplays = true;
- }
- mDisplayHasContent = true;
- } else if (displayContent != null &&
- (!mObscureApplicationContentOnSecondaryDisplays
- || (mObscured && type == TYPE_KEYGUARD_DIALOG))) {
- // Allow full screen keyguard presentation dialogs to be seen.
- mDisplayHasContent = true;
- }
- if (mPreferredRefreshRate == 0
- && w.mAttrs.preferredRefreshRate != 0) {
- mPreferredRefreshRate = w.mAttrs.preferredRefreshRate;
- }
- if (mPreferredModeId == 0
- && w.mAttrs.preferredDisplayModeId != 0) {
- mPreferredModeId = w.mAttrs.preferredDisplayModeId;
- }
- if ((privateflags & PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE) != 0) {
- mSustainedPerformanceModeCurrent = true;
- }
- }
- }
-
- private static int toBrightnessOverride(float value) {
- return (int)(value * PowerManager.BRIGHTNESS_ON);
- }
-
private void processApplicationsAnimatingInPlace(int transit) {
if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
// Find the focused window
@@ -1618,41 +851,6 @@
}
}
- boolean copyAnimToLayoutParamsLocked() {
- boolean doRequest = false;
-
- final int bulkUpdateParams = mService.mAnimator.mBulkUpdateParams;
- if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
- mUpdateRotation = true;
- doRequest = true;
- }
- if ((bulkUpdateParams & SET_WALLPAPER_MAY_CHANGE) != 0) {
- mWallpaperMayChange = true;
- doRequest = true;
- }
- if ((bulkUpdateParams & SET_FORCE_HIDING_CHANGED) != 0) {
- mWallpaperForceHidingChanged = true;
- doRequest = true;
- }
- if ((bulkUpdateParams & SET_ORIENTATION_CHANGE_COMPLETE) == 0) {
- mOrientationChangeComplete = false;
- } else {
- mOrientationChangeComplete = true;
- mLastWindowFreezeSource = mService.mAnimator.mLastWindowFreezeSource;
- if (mService.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_NONE) {
- doRequest = true;
- }
- }
- if ((bulkUpdateParams & SET_TURN_ON_SCREEN) != 0) {
- mService.mTurnOnScreen = true;
- }
- if ((bulkUpdateParams & SET_WALLPAPER_ACTION_PENDING) != 0) {
- mWallpaperActionPending = true;
- }
-
- return doRequest;
- }
-
void requestTraversal() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
@@ -1680,8 +878,8 @@
}
public void dump(PrintWriter pw, String prefix) {
- pw.print(prefix); pw.print("mTraversalScheduled="); pw.println(mTraversalScheduled);
- pw.print(prefix); pw.print("mHoldScreenWindow="); pw.println(mHoldScreenWindow);
- pw.print(prefix); pw.print("mObsuringWindow="); pw.println(mObsuringWindow);
+ pw.println(prefix + "mTraversalScheduled=" + mTraversalScheduled);
+ pw.println(prefix + "mHoldScreenWindow=" + mService.mRoot.mHoldScreenWindow);
+ pw.println(prefix + "mObsuringWindow=" + mService.mRoot.mObsuringWindow);
}
}