Removed used of DisplayContent.getReadOnlyWindowList()
Changed the call points to use DisplayContent.forAllWindows() to
get windows on the display.
Test: Existing tests pass.
Change-Id: I6f8bf15ba246fac69c4a496ebb1d9e0b9b6a95a2
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 869e207..49ffa22 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -649,15 +649,12 @@
private void populateWindowsOnScreenLocked(SparseArray<WindowState> outWindows) {
final DisplayContent dc = mWindowManagerService.getDefaultDisplayContentLocked();
- final ReadOnlyWindowList windowList = dc.getReadOnlyWindowList();
- final int windowCount = windowList.size();
- for (int i = 0; i < windowCount; i++) {
- final WindowState windowState = windowList.get(i);
- if (windowState.isOnScreen() && windowState.isVisibleLw() &&
- !windowState.mWinAnimator.mEnterAnimationPending) {
- outWindows.put(windowState.mLayer, windowState);
+ dc.forAllWindows((w) -> {
+ if (w.isOnScreen() && w.isVisibleLw()
+ && !w.mWinAnimator.mEnterAnimationPending) {
+ outWindows.put(w.mLayer, w);
}
- }
+ }, false /* traverseTopToBottom */ );
}
private final class ViewportWindow {
@@ -1296,14 +1293,11 @@
private void populateVisibleWindowsOnScreenLocked(SparseArray<WindowState> outWindows) {
final DisplayContent dc = mWindowManagerService.getDefaultDisplayContentLocked();
- final ReadOnlyWindowList windowList = dc.getReadOnlyWindowList();
- final int windowCount = windowList.size();
- for (int i = 0; i < windowCount; i++) {
- final WindowState windowState = windowList.get(i);
- if (windowState.isVisibleLw()) {
- outWindows.put(windowState.mLayer, windowState);
+ dc.forAllWindows((w) -> {
+ if (w.isVisibleLw()) {
+ outWindows.put(w.mLayer, w);
}
- }
+ }, false /* traverseTopToBottom */ );
}
private class MyHandler extends Handler {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 6a625f4..ff39853 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1400,14 +1400,14 @@
/** Updates the layer assignment of windows on this display. */
void assignWindowLayers(boolean setLayoutNeeded) {
- mLayersController.assignWindowLayers(mWindows.getReadOnly());
+ mLayersController.assignWindowLayers(this);
if (setLayoutNeeded) {
setLayoutNeeded();
}
}
void adjustWallpaperWindows() {
- if (mWallpaperController.adjustWallpaperWindows(mWindows.getReadOnly())) {
+ if (mWallpaperController.adjustWallpaperWindows(mWindows)) {
assignWindowLayers(true /*setLayoutNeeded*/);
}
}
@@ -2457,14 +2457,6 @@
}
}
- ReadOnlyWindowList getReadOnlyWindowList() {
- return mWindows.getReadOnly();
- }
-
- void getWindows(WindowList output) {
- output.addAll(mWindows);
- }
-
// TODO: Super crazy long method that should be broken down...
boolean applySurfaceChangesTransaction(boolean recoveringMemory) {
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 6326148..c56f6b8 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -266,10 +266,8 @@
}
private void resetDragResizingChangeReported() {
- final ReadOnlyWindowList windowList = mDisplayContent.getReadOnlyWindowList();
- for (int i = windowList.size() - 1; i >= 0; i--) {
- windowList.get(i).resetDragResizingChangeReported();
- }
+ mDisplayContent.forAllWindows(WindowState::resetDragResizingChangeReported,
+ true /* traverseTopToBottom */ );
}
void setWindow(WindowState window) {
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index d52168c..4d195e8 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -271,11 +271,8 @@
Slog.d(TAG_WM, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
}
- final ReadOnlyWindowList windows = mDisplayContent.getReadOnlyWindowList();
- final int N = windows.size();
- for (int i = 0; i < N; i++) {
- sendDragStartedLw(windows.get(i), touchX, touchY, mDataDescription);
- }
+ mDisplayContent.forAllWindows((w) -> sendDragStartedLw(w, touchX, touchY, mDataDescription),
+ false /* traverseTopToBottom */ );
}
/* helper - send a ACTION_DRAG_STARTED event, if the
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 299fa05..88986e3 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -219,28 +219,6 @@
return false;
}
- void getWindows(WindowList output) {
- final int count = mChildren.size();
- for (int i = 0; i < count; ++i) {
- final DisplayContent dc = mChildren.get(i);
- dc.getWindows(output);
- }
- }
-
- void getWindows(WindowList output, boolean visibleOnly, boolean appsOnly) {
- final int numDisplays = mChildren.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final ReadOnlyWindowList windowList = mChildren.get(displayNdx).getReadOnlyWindowList();
- 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.
@@ -249,36 +227,20 @@
name = null;
} catch (RuntimeException e) {
}
- final int numDisplays = mChildren.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final ReadOnlyWindowList windowList = mChildren.get(displayNdx).getReadOnlyWindowList();
- 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);
- }
- }
- }
+
+ getWindowsByName(output, name, objectId);
}
- WindowState findWindow(int hashCode) {
- final int numDisplays = mChildren.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final ReadOnlyWindowList windows = mChildren.get(displayNdx).getReadOnlyWindowList();
- 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;
+ private void getWindowsByName(WindowList output, String name, int objectId) {
+ forAllWindows((w) -> {
+ if (name != null) {
+ if (w.mAttrs.getTitle().toString().contains(name)) {
+ output.add(w);
}
+ } else if (System.identityHashCode(w) == objectId) {
+ output.add(w);
}
- }
-
- return null;
+ }, true /* traverseTopToBottom */);
}
/**
@@ -399,81 +361,50 @@
}
void setSecureSurfaceState(int userId, boolean disabled) {
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- final ReadOnlyWindowList windows = mChildren.get(i).getReadOnlyWindowList();
- 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);
- }
+ forAllWindows((w) -> {
+ if (w.mHasSurface && userId == UserHandle.getUserId(w.mOwnerUid)) {
+ w.mWinAnimator.setSecureLocked(disabled);
}
- }
+ }, true /* traverseTopToBottom */);
}
void updateAppOpsState() {
- final int count = mChildren.size();
- for (int i = 0; i < count; ++i) {
- final ReadOnlyWindowList windows = mChildren.get(i).getReadOnlyWindowList();
- final int numWindows = windows.size();
- for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
- final WindowState win = windows.get(winNdx);
- if (win.mAppOp == OP_NONE) {
- continue;
- }
- final int mode = mService.mAppOps.checkOpNoThrow(win.mAppOp, win.getOwningUid(),
- win.getOwningPackage());
- win.setAppOpVisibilityLw(mode == MODE_ALLOWED || mode == MODE_DEFAULT);
+ forAllWindows((w) -> {
+ if (w.mAppOp == OP_NONE) {
+ return;
}
- }
+ final int mode = mService.mAppOps.checkOpNoThrow(w.mAppOp, w.getOwningUid(),
+ w.getOwningPackage());
+ w.setAppOpVisibilityLw(mode == MODE_ALLOWED || mode == MODE_DEFAULT);
+ }, false /* traverseTopToBottom */);
}
boolean canShowStrictModeViolation(int pid) {
- final int count = mChildren.size();
- for (int i = 0; i < count; ++i) {
- final ReadOnlyWindowList windows = mChildren.get(i).getReadOnlyWindowList();
- 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;
+ final WindowState win = getWindow((w) -> w.mSession.mPid == pid && w.isVisibleLw());
+ return win != null;
}
void closeSystemDialogs(String reason) {
- final int count = mChildren.size();
- for (int i = 0; i < count; ++i) {
- final ReadOnlyWindowList windows = mChildren.get(i).getReadOnlyWindowList();
- 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) {
- }
+ forAllWindows((w) -> {
+ if (w.mHasSurface) {
+ try {
+ w.mClient.closeSystemDialogs(reason);
+ } catch (RemoteException e) {
}
}
- }
+ }, false /* traverseTopToBottom */);
}
void removeReplacedWindows() {
if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION removeReplacedWindows");
mService.openSurfaceTransaction();
try {
- for (int i = mChildren.size() - 1; i >= 0; i--) {
- DisplayContent dc = mChildren.get(i);
- final ReadOnlyWindowList windows = mChildren.get(i).getReadOnlyWindowList();
- 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);
- }
+ forAllWindows((w) -> {
+ final AppWindowToken aToken = w.mAppToken;
+ if (aToken != null) {
+ aToken.removeReplacedWindowIfNeeded(w);
}
- }
+ }, true /* traverseTopToBottom */);
} finally {
mService.closeSurfaceTransaction();
if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION removeReplacedWindows");
@@ -530,19 +461,15 @@
Slog.w(TAG_WM, "No leaked surfaces; killing applications!");
final SparseIntArray pidCandidates = new SparseIntArray();
for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final ReadOnlyWindowList windows =
- mChildren.get(displayNdx).getReadOnlyWindowList();
- final int numWindows = windows.size();
- for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
- final WindowState ws = windows.get(winNdx);
- if (mService.mForceRemoves.contains(ws)) {
- continue;
+ mChildren.get(displayNdx).forAllWindows((w) -> {
+ if (mService.mForceRemoves.contains(w)) {
+ return;
}
- final WindowStateAnimator wsa = ws.mWinAnimator;
+ final WindowStateAnimator wsa = w.mWinAnimator;
if (wsa.mSurfaceController != null) {
pidCandidates.append(wsa.mSession.mPid, wsa.mSession.mPid);
}
- }
+ }, false /* traverseTopToBottom */);
if (pidCandidates.size() > 0) {
int[] pids = new int[pidCandidates.size()];
@@ -1078,17 +1005,14 @@
}
void dumpWindowsNoHeader(PrintWriter pw, boolean dumpAll, ArrayList<WindowState> windows) {
- final int numDisplays = mChildren.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final ReadOnlyWindowList windowList = mChildren.get(displayNdx).getReadOnlyWindowList();
- 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);
- }
+ final int[] index = new int[1];
+ forAllWindows((w) -> {
+ if (windows == null || windows.contains(w)) {
+ pw.println(" Window #" + index[0] + " " + w + ":");
+ w.dump(pw, " ", dumpAll || windows != null);
+ index[0] = index[0] + 1;
}
- }
+ }, true /* traverseTopToBottom */);
}
void dumpTokens(PrintWriter pw, boolean dumpAll) {
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 178fbe7..d3e8e8e 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -388,7 +388,7 @@
return mWallpaperAnimLayerAdjustment;
}
- private void findWallpaperTarget(ReadOnlyWindowList windows, FindWallpaperTargetResult result) {
+ private void findWallpaperTarget(WindowList windows, FindWallpaperTargetResult result) {
final WindowAnimator winAnimator = mService.mAnimator;
result.reset();
WindowState w = null;
@@ -489,7 +489,7 @@
/** Updates the target wallpaper if needed and returns true if an update happened. */
private boolean updateWallpaperWindowsTarget(
- ReadOnlyWindowList windows, FindWallpaperTargetResult result) {
+ WindowList windows, FindWallpaperTargetResult result) {
WindowState wallpaperTarget = result.wallpaperTarget;
int wallpaperTargetIndex = result.wallpaperTargetIndex;
@@ -590,7 +590,7 @@
return true;
}
- private boolean updateWallpaperWindowsTargetByLayer(ReadOnlyWindowList windows,
+ private boolean updateWallpaperWindowsTargetByLayer(WindowList windows,
FindWallpaperTargetResult result) {
WindowState wallpaperTarget = result.wallpaperTarget;
@@ -641,7 +641,7 @@
return visible;
}
- private boolean updateWallpaperWindowsPlacement(ReadOnlyWindowList windows,
+ private boolean updateWallpaperWindowsPlacement(WindowList windows,
WindowState wallpaperTarget, int wallpaperTargetIndex, boolean visible) {
// TODO(multidisplay): Wallpapers on main screen only.
@@ -660,7 +660,7 @@
return changed;
}
- boolean adjustWallpaperWindows(ReadOnlyWindowList windows) {
+ boolean adjustWallpaperWindows(WindowList windows) {
mService.mRoot.mWallpaperMayChange = false;
// 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/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
index fdefcfe..3a76cd4 100644
--- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java
+++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
@@ -119,7 +119,7 @@
}
}
- boolean updateWallpaperWindowsPlacement(ReadOnlyWindowList windowList,
+ boolean updateWallpaperWindowsPlacement(WindowList windowList,
WindowState wallpaperTarget, int wallpaperTargetIndex, boolean visible, int dw, int dh,
int wallpaperAnimLayerAdj) {
@@ -193,7 +193,7 @@
* @return The index in {@param windows} of the lowest window that is currently on screen and
* not hidden by the policy.
*/
- private int findLowestWindowOnScreen(ReadOnlyWindowList windowList) {
+ private int findLowestWindowOnScreen(WindowList windowList) {
final int size = windowList.size();
for (int index = 0; index < size; index++) {
final WindowState win = windowList.get(index);
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 62ad217..150160c 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -23,6 +23,7 @@
import java.util.Comparator;
import java.util.LinkedList;
import java.util.function.Consumer;
+import java.util.function.Predicate;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
@@ -508,6 +509,17 @@
}
}
+ WindowState getWindow(Predicate<WindowState> callback) {
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ final WindowState w = mChildren.get(i).getWindow(callback);
+ if (w != null) {
+ return w;
+ }
+ }
+
+ return null;
+ }
+
/**
* Returns 1, 0, or -1 depending on if this container is greater than, equal to, or lesser than
* the input container in terms of z-order.
diff --git a/services/core/java/com/android/server/wm/WindowLayersController.java b/services/core/java/com/android/server/wm/WindowLayersController.java
index d94094a..c06e5cc 100644
--- a/services/core/java/com/android/server/wm/WindowLayersController.java
+++ b/services/core/java/com/android/server/wm/WindowLayersController.java
@@ -60,33 +60,32 @@
private ArrayDeque<WindowState> mOnTopLauncherWindows = new ArrayDeque<>();
private WindowState mDockDivider = null;
private ArrayDeque<WindowState> mReplacingWindows = new ArrayDeque<>();
+ private int mCurBaseLayer;
+ private int mCurLayer;
+ private boolean mAnyLayerChanged;
- final void assignWindowLayers(ReadOnlyWindowList windows) {
- if (DEBUG_LAYERS) Slog.v(TAG_WM, "Assigning layers based on windows=" + windows,
+ final void assignWindowLayers(DisplayContent dc) {
+ if (DEBUG_LAYERS) Slog.v(TAG_WM, "Assigning layers based",
new RuntimeException("here").fillInStackTrace());
clear();
- int curBaseLayer = 0;
- int curLayer = 0;
- boolean anyLayerChanged = false;
- for (int i = 0, windowCount = windows.size(); i < windowCount; i++) {
- final WindowState w = windows.get(i);
+ dc.forAllWindows((w) -> {
boolean layerChanged = false;
int oldLayer = w.mLayer;
- if (w.mBaseLayer == curBaseLayer || w.mIsImWindow || (i > 0 && w.mIsWallpaper)) {
- curLayer += WINDOW_LAYER_MULTIPLIER;
+ if (w.mBaseLayer == mCurBaseLayer || w.mIsImWindow) {
+ mCurLayer += WINDOW_LAYER_MULTIPLIER;
} else {
- curBaseLayer = curLayer = w.mBaseLayer;
+ mCurBaseLayer = mCurLayer = w.mBaseLayer;
}
- assignAnimLayer(w, curLayer);
+ assignAnimLayer(w, mCurLayer);
- // TODO: Preserved old behavior of code here but not sure comparing
- // oldLayer to mAnimLayer and mLayer makes sense...though the
- // worst case would be unintentional layer reassignment.
+ // TODO: Preserved old behavior of code here but not sure comparing oldLayer to
+ // mAnimLayer and mLayer makes sense...though the worst case would be unintentional
+ // layer reassignment.
if (w.mLayer != oldLayer || w.mWinAnimator.mAnimLayer != oldLayer) {
layerChanged = true;
- anyLayerChanged = true;
+ mAnyLayerChanged = true;
}
if (w.mAppToken != null) {
@@ -98,28 +97,27 @@
if (layerChanged) {
w.scheduleAnimationIfDimming();
}
- }
+ }, false /* traverseTopToBottom */);
adjustSpecialWindows();
//TODO (multidisplay): Magnification is supported only for the default display.
- if (mService.mAccessibilityController != null && anyLayerChanged
- && windows.get(windows.size() - 1).getDisplayId() == Display.DEFAULT_DISPLAY) {
+ if (mService.mAccessibilityController != null && mAnyLayerChanged
+ && dc.getDisplayId() == Display.DEFAULT_DISPLAY) {
mService.mAccessibilityController.onWindowLayersChangedLocked();
}
- if (DEBUG_LAYERS) logDebugLayers(windows);
+ if (DEBUG_LAYERS) logDebugLayers(dc);
}
- private void logDebugLayers(ReadOnlyWindowList windows) {
- for (int i = 0, n = windows.size(); i < n; i++) {
- final WindowState w = windows.get(i);
+ private void logDebugLayers(DisplayContent dc) {
+ dc.forAllWindows((w) -> {
final WindowStateAnimator winAnimator = w.mWinAnimator;
Slog.v(TAG_WM, "Assign layer " + w + ": " + "mBase=" + w.mBaseLayer
+ " mLayer=" + w.mLayer + (w.mAppToken == null
? "" : " mAppLayer=" + w.mAppToken.mAppAnimator.animLayerAdjustment)
+ " =mAnimLayer=" + winAnimator.mAnimLayer);
- }
+ }, false /* traverseTopToBottom */);
}
private void clear() {
@@ -130,6 +128,10 @@
mOnTopLauncherWindows.clear();
mReplacingWindows.clear();
mDockDivider = null;
+
+ mCurBaseLayer = 0;
+ mCurLayer = 0;
+ mAnyLayerChanged = false;
}
private void collectSpecialWindows(WindowState w) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 8486e52..a7ac35e 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4747,37 +4747,42 @@
return false;
}
- final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
- final ReadOnlyWindowList windows = displayContent.getReadOnlyWindowList();
+ final DisplayContent dc = mRoot.getDisplayContent(displayId);
final int oldRotation = mRotation;
int rotation = mPolicy.rotationForOrientationLw(mLastOrientation, mRotation);
- boolean rotateSeamlessly = mPolicy.shouldRotateSeamlessly(oldRotation, rotation);
+ final boolean rotateSeamlessly;
- if (rotateSeamlessly) {
- for (int i = windows.size() - 1; i >= 0; i--) {
- WindowState w = windows.get(i);
+ if (mPolicy.shouldRotateSeamlessly(oldRotation, rotation)) {
+ final WindowState seamlessRotated = dc.getWindow((w) -> w.mSeamlesslyRotated);
+ if (seamlessRotated != null) {
// We can't rotate (seamlessly or not) while waiting for the last seamless rotation
// to complete (that is, waiting for windows to redraw). It's tempting to check
- // w.mSeamlessRotationCount but that could be incorrect in the case of window-removal.
- if (w.mSeamlesslyRotated) {
- return false;
- }
- // In what can only be called an unfortunate workaround we require
- // seamlessly rotated child windows to have the TRANSFORM_TO_DISPLAY_INVERSE
- // flag. Due to limitations in the client API, there is no way for
- // the client to set this flag in a race free fashion. If we seamlessly rotate
- // a window which does not have this flag, but then gains it, we will get
- // an incorrect visual result (rotated viewfinder). This means if we want to
- // support seamlessly rotating windows which could gain this flag, we can't
- // rotate windows without it. This limits seamless rotation in N to camera framework
- // users, windows without children, and native code. This is unfortunate but
- // having the camera work is our primary goal.
- if (w.isChildWindow() & w.isVisibleNow() &&
- !w.mWinAnimator.mSurfaceController.getTransformToDisplayInverse()) {
- rotateSeamlessly = false;
- }
+ // w.mSeamlessRotationCount but that could be incorrect in the case of
+ // window-removal.
+ return false;
}
+
+ final WindowState cantSeamlesslyRotate = dc.getWindow((w) ->
+ w.isChildWindow() && w.isVisibleNow()
+ && !w.mWinAnimator.mSurfaceController.getTransformToDisplayInverse());
+ if (cantSeamlesslyRotate != null) {
+ // In what can only be called an unfortunate workaround we require seamlessly
+ // rotated child windows to have the TRANSFORM_TO_DISPLAY_INVERSE flag. Due to
+ // limitations in the client API, there is no way for the client to set this flag in
+ // a race free fashion. If we seamlessly rotate a window which does not have this
+ // flag, but then gains it, we will get an incorrect visual result
+ // (rotated viewfinder). This means if we want to support seamlessly rotating
+ // windows which could gain this flag, we can't rotate windows without it. This
+ // limits seamless rotation in N to camera framework users, windows without
+ // children, and native code. This is unfortunate but having the camera work is our
+ // primary goal.
+ rotateSeamlessly = false;
+ } else {
+ rotateSeamlessly = true;
+ }
+ } else {
+ rotateSeamlessly = false;
}
// TODO: Implement forced rotation changes.
@@ -4809,9 +4814,9 @@
mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
mH.sendEmptyMessageDelayed(H.WINDOW_FREEZE_TIMEOUT, WINDOW_FREEZE_TIMEOUT_DURATION);
mWaitingForConfig = true;
- displayContent.setLayoutNeeded();
+ dc.setLayoutNeeded();
final int[] anim = new int[2];
- if (displayContent.isDimming()) {
+ if (dc.isDimming()) {
anim[0] = anim[1] = 0;
} else {
mPolicy.selectRotationAnimationLw(anim);
@@ -4820,8 +4825,7 @@
if (!rotateSeamlessly) {
startFreezingDisplayLocked(inTransaction, anim[0], anim[1]);
// startFreezingDisplayLocked can reset the ScreenRotationAnimation.
- screenRotationAnimation =
- mAnimator.getScreenRotationAnimationLocked(displayId);
+ screenRotationAnimation = mAnimator.getScreenRotationAnimationLocked(displayId);
} else {
// The screen rotation animation uses a screenshot to freeze the screen
// while windows resize underneath.
@@ -4839,9 +4843,9 @@
// the top of the method, the caller is obligated to call computeNewConfigurationLocked().
// By updating the Display info here it will be available to
// computeScreenConfigurationLocked later.
- updateDisplayAndOrientationLocked(displayContent.getConfiguration().uiMode, displayId);
+ updateDisplayAndOrientationLocked(dc.getConfiguration().uiMode, displayId);
- final DisplayInfo displayInfo = displayContent.getDisplayInfo();
+ final DisplayInfo displayInfo = dc.getDisplayInfo();
if (!inTransaction) {
if (SHOW_TRANSACTIONS) {
Slog.i(TAG_WM, ">>> OPEN TRANSACTION setRotationUnchecked");
@@ -4862,10 +4866,9 @@
}
if (rotateSeamlessly) {
- for (int i = windows.size() - 1; i >= 0; i--) {
- WindowState w = windows.get(i);
- w.mWinAnimator.seamlesslyRotateWindow(oldRotation, mRotation);
- }
+ dc.forAllWindows((w) ->
+ w.mWinAnimator.seamlesslyRotateWindow(oldRotation, mRotation),
+ true /* traverseTopToBottom */);
}
mDisplayManagerInternal.performTraversalInTransactionFromWindowManager();
@@ -4878,8 +4881,7 @@
}
}
- for (int i = windows.size() - 1; i >= 0; i--) {
- WindowState w = windows.get(i);
+ dc.forAllWindows((w) -> {
// Discard surface after orientation change, these can't be reused.
if (w.mAppToken != null) {
w.mAppToken.destroySavedSurfaces();
@@ -4890,7 +4892,8 @@
mRoot.mOrientationChangeComplete = false;
w.mLastFreezeDuration = 0;
}
- }
+
+ }, true /* traverseTopToBottom */);
if (rotateSeamlessly) {
mH.removeMessages(H.SEAMLESS_ROTATION_TIMEOUT);
@@ -4908,7 +4911,7 @@
// Announce rotation only if we will not animate as we already have the
// windows in final state. Otherwise, we make this call at the rotation end.
if (screenRotationAnimation == null && mAccessibilityController != null
- && displayContent.getDisplayId() == DEFAULT_DISPLAY) {
+ && dc.getDisplayId() == DEFAULT_DISPLAY) {
mAccessibilityController.onRotationChangedLocked(getDefaultDisplayContentLocked(),
rotation);
}
@@ -5141,7 +5144,7 @@
final WindowList windows = new WindowList();
synchronized (mWindowMap) {
- mRoot.getWindows(windows);
+ mRoot.forAllWindows(windows::add, false /* traverseTopToBottom */);
}
BufferedWriter out = null;
@@ -5368,7 +5371,7 @@
}
synchronized (mWindowMap) {
- return mRoot.findWindow(hashCode);
+ return mRoot.getWindow((w) -> System.identityHashCode(w) == hashCode);
}
}
@@ -8051,7 +8054,12 @@
mRoot.dumpDisplayContents(pw);
}
- mRoot.getWindows(windows, visibleOnly, appsOnly);
+ mRoot.forAllWindows((w) -> {
+ if ((!visibleOnly || w.mWinAnimator.getShown())
+ && (!appsOnly || w.mAppToken != null)) {
+ windows.add(w);
+ }
+ }, true /* traverseTopToBottom */);
}
} else {
synchronized(mWindowMap) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 1a56518..5e65aec 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -60,6 +60,7 @@
import java.util.Comparator;
import java.util.LinkedList;
import java.util.function.Consumer;
+import java.util.function.Predicate;
import static android.app.ActivityManager.StackId;
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
@@ -138,52 +139,6 @@
import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
class WindowList extends ArrayList<WindowState> {
-
- /**
- * Read-only interface for the window list that the creator of the window list can pass-out to
- * other users to prevent them from modifying the window list.
- */
- private ReadOnlyWindowList mReadOnly;
-
- WindowList() {
- mReadOnly = new ReadOnlyWindowList(this);
- }
-
- /** Returns the read-only interface for this window list. */
- ReadOnlyWindowList getReadOnly() {
- return mReadOnly;
- }
-}
-
-/**
- * Read-only interface for a list of windows. It is common for the owner of a list of windows to
- * want to provide a way for external classes to iterate of its windows, but prevent them from
- * modifying the list in any way. This call provides a way for them to do that by wrapping the
- * original window list and only exposing the read-only APIs.
- */
-final class ReadOnlyWindowList {
- // List of windows this read-only class is tied to.
- private final WindowList mWindows;
-
- ReadOnlyWindowList(WindowList windows) {
- mWindows = windows;
- }
-
- WindowState get(int index) {
- return mWindows.get(index);
- }
-
- int indexOf(WindowState w) {
- return mWindows.indexOf(w);
- }
-
- int size() {
- return mWindows.size();
- }
-
- boolean isEmpty() {
- return mWindows.isEmpty();
- }
}
/** A window in the window manager. */
@@ -3949,6 +3904,13 @@
}
}
+ WindowState getWindow(Predicate<WindowState> callback) {
+ if (callback.test(this)) {
+ return this;
+ }
+ return super.getWindow(callback);
+ }
+
boolean isWindowAnimationSet() {
if (mWinAnimator.isWindowAnimationSet()) {
return true;