Merge "Removed used of DisplayContent.getReadOnlyWindowList()"

This commit is contained in:
Wale Ogunwale
2016-11-13 01:01:06 +00:00
committed by Android (Google) Code Review
11 changed files with 162 additions and 273 deletions

View File

@@ -649,15 +649,12 @@ final class AccessibilityController {
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 @@ final class AccessibilityController {
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 {

View File

@@ -1400,14 +1400,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
/** 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 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
}
}
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) {

View File

@@ -266,10 +266,8 @@ public class DockedStackDividerController implements DimLayerUser {
}
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) {

View File

@@ -271,11 +271,8 @@ class DragState {
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

View File

@@ -219,28 +219,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> {
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 @@ class RootWindowContainer extends WindowContainer<DisplayContent> {
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 @@ class RootWindowContainer extends WindowContainer<DisplayContent> {
}
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 @@ class RootWindowContainer extends WindowContainer<DisplayContent> {
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 @@ class RootWindowContainer extends WindowContainer<DisplayContent> {
}
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) {

View File

@@ -388,7 +388,7 @@ class WallpaperController {
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 @@ class WallpaperController {
/** 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 @@ class WallpaperController {
return true;
}
private boolean updateWallpaperWindowsTargetByLayer(ReadOnlyWindowList windows,
private boolean updateWallpaperWindowsTargetByLayer(WindowList windows,
FindWallpaperTargetResult result) {
WindowState wallpaperTarget = result.wallpaperTarget;
@@ -641,7 +641,7 @@ class WallpaperController {
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 @@ class WallpaperController {
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;

View File

@@ -119,7 +119,7 @@ class WallpaperWindowToken extends WindowToken {
}
}
boolean updateWallpaperWindowsPlacement(ReadOnlyWindowList windowList,
boolean updateWallpaperWindowsPlacement(WindowList windowList,
WindowState wallpaperTarget, int wallpaperTargetIndex, boolean visible, int dw, int dh,
int wallpaperAnimLayerAdj) {
@@ -193,7 +193,7 @@ class WallpaperWindowToken extends WindowToken {
* @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);

View File

@@ -23,6 +23,7 @@ import android.view.animation.Animation;
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 @@ class WindowContainer<E extends WindowContainer> implements Comparable<WindowCon
}
}
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.

View File

@@ -60,33 +60,32 @@ class WindowLayersController {
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 @@ class WindowLayersController {
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 @@ class WindowLayersController {
mOnTopLauncherWindows.clear();
mReplacingWindows.clear();
mDockDivider = null;
mCurBaseLayer = 0;
mCurLayer = 0;
mAnyLayerChanged = false;
}
private void collectSpecialWindows(WindowState w) {

View File

@@ -4787,37 +4787,42 @@ public class WindowManagerService extends IWindowManager.Stub
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.
@@ -4849,9 +4854,9 @@ public class WindowManagerService extends IWindowManager.Stub
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);
@@ -4860,8 +4865,7 @@ public class WindowManagerService extends IWindowManager.Stub
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.
@@ -4879,9 +4883,9 @@ public class WindowManagerService extends IWindowManager.Stub
// 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");
@@ -4902,10 +4906,9 @@ public class WindowManagerService extends IWindowManager.Stub
}
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();
@@ -4918,8 +4921,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
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();
@@ -4930,7 +4932,8 @@ public class WindowManagerService extends IWindowManager.Stub
mRoot.mOrientationChangeComplete = false;
w.mLastFreezeDuration = 0;
}
}
}, true /* traverseTopToBottom */);
if (rotateSeamlessly) {
mH.removeMessages(H.SEAMLESS_ROTATION_TIMEOUT);
@@ -4948,7 +4951,7 @@ public class WindowManagerService extends IWindowManager.Stub
// 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);
}
@@ -5181,7 +5184,7 @@ public class WindowManagerService extends IWindowManager.Stub
final WindowList windows = new WindowList();
synchronized (mWindowMap) {
mRoot.getWindows(windows);
mRoot.forAllWindows(windows::add, false /* traverseTopToBottom */);
}
BufferedWriter out = null;
@@ -5408,7 +5411,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
synchronized (mWindowMap) {
return mRoot.findWindow(hashCode);
return mRoot.getWindow((w) -> System.identityHashCode(w) == hashCode);
}
}
@@ -8091,7 +8094,12 @@ public class WindowManagerService extends IWindowManager.Stub
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) {

View File

@@ -60,6 +60,7 @@ import java.util.ArrayList;
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.HAS_DRAWN;
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 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
}
WindowState getWindow(Predicate<WindowState> callback) {
if (callback.test(this)) {
return this;
}
return super.getWindow(callback);
}
boolean isWindowAnimationSet() {
if (mWinAnimator.isWindowAnimationSet()) {
return true;