Merge "Reset and reuse Iterators and don't new() one."

This commit is contained in:
Craig Mautner
2013-02-14 22:21:52 +00:00
committed by Android (Google) Code Review
3 changed files with 152 additions and 102 deletions

View File

@ -16,6 +16,9 @@
package com.android.server.wm;
import static com.android.server.wm.WindowManagerService.FORWARD_ITERATOR;
import static com.android.server.wm.WindowManagerService.REVERSE_ITERATOR;
import android.util.SparseArray;
import android.view.Display;
import android.view.DisplayInfo;
@ -88,6 +91,8 @@ class DisplayContent {
ArrayList<TaskList> mTaskLists = new ArrayList<TaskList>();
SparseArray<TaskList> mTaskIdToTaskList = new SparseArray<TaskList>();
private final AppTokenIterator mTmpAppIterator = new AppTokenIterator();
/**
* @param display May not be null.
*/
@ -169,6 +174,18 @@ class DisplayContent {
wtoken.groupId = newTaskId;
}
/**
* Return the utility iterator so we don't have to construct new iterators every time we
* iterate.
* NOTE: Do not ever nest this call or you will have a bad time!
* @param reverse Direction of iterator.
* @return The utility iterator.
*/
AppTokenIterator getTmpAppIterator(boolean reverse) {
mTmpAppIterator.reset(reverse);
return mTmpAppIterator;
}
class TaskListsIterator implements Iterator<TaskList> {
private int mCur;
private boolean mReverse;
@ -178,9 +195,12 @@ class DisplayContent {
}
TaskListsIterator(boolean reverse) {
reset(reverse);
}
void reset(boolean reverse) {
mReverse = reverse;
int numTaskLists = mTaskLists.size();
mCur = reverse ? numTaskLists - 1 : 0;
mCur = reverse ? mTaskLists.size() - 1 : 0;
}
@Override
@ -208,18 +228,22 @@ class DisplayContent {
}
class AppTokenIterator implements Iterator<AppWindowToken> {
final TaskListsIterator mIterator;
final boolean mReverse;
final TaskListsIterator mIterator = new TaskListsIterator();
boolean mReverse;
int mCur;
TaskList mTaskList;
public AppTokenIterator() {
this(false);
this(FORWARD_ITERATOR);
}
public AppTokenIterator(boolean reverse) {
reset(reverse);
}
void reset(boolean reverse) {
mReverse = reverse;
mIterator = new TaskListsIterator(reverse);
mIterator.reset(reverse);
getNextTaskList();
}
@ -292,7 +316,7 @@ class DisplayContent {
pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight);
pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
AppTokenIterator iterator = new AppTokenIterator(true);
AppTokenIterator iterator = getTmpAppIterator(REVERSE_ITERATOR);
int ndx = iterator.size() - 1;
if (ndx >= 0) {
pw.println();

View File

@ -10,6 +10,8 @@ import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPA
import static com.android.server.wm.WindowManagerService.LayoutFields.SET_FORCE_HIDING_CHANGED;
import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE;
import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_ACTION_PENDING;
import static com.android.server.wm.WindowManagerService.FORWARD_ITERATOR;
import static com.android.server.wm.WindowManagerService.REVERSE_ITERATOR;
import android.content.Context;
import android.os.Debug;
@ -176,7 +178,7 @@ public class WindowAnimator {
private void updateAppWindowsLocked(int displayId) {
int i;
final DisplayContent displayContent = mService.getDisplayContentLocked(displayId);
AppTokenIterator iterator = displayContent.new AppTokenIterator();
AppTokenIterator iterator = displayContent.getTmpAppIterator(FORWARD_ITERATOR);
while (iterator.hasNext()) {
final AppWindowAnimator appAnimator = iterator.next().mAppAnimator;
final boolean wasAnimating = appAnimator.animation != null
@ -459,8 +461,8 @@ public class WindowAnimator {
private void testTokenMayBeDrawnLocked(int displayId) {
// See if any windows have been drawn, so they (and others
// associated with them) can now be shown.
AppTokenIterator iterator = mService.getDisplayContentLocked(displayId).new
AppTokenIterator();
AppTokenIterator iterator =
mService.getDisplayContentLocked(displayId).getTmpAppIterator(FORWARD_ITERATOR);
while (iterator.hasNext()) {
AppWindowToken wtoken = iterator.next();
AppWindowAnimator appAnimator = wtoken.mAppAnimator;

View File

@ -208,6 +208,9 @@ public class WindowManagerService extends IWindowManager.Stub
static final boolean PROFILE_ORIENTATION = false;
static final boolean localLOGV = DEBUG;
final static boolean REVERSE_ITERATOR = true;
final static boolean FORWARD_ITERATOR = false;
/** How much to multiply the policy's type layer, to reserve room
* for multiple windows of the same type and Z-ordering adjustment
* with TYPE_LAYER_OFFSET. */
@ -422,6 +425,8 @@ public class WindowManagerService extends IWindowManager.Stub
private SparseArray<DisplayContent> mTaskIdToDisplayContents =
new SparseArray<DisplayContent>();
private final AllWindowsIterator mTmpWindowsIterator = new AllWindowsIterator();
int mRotation = 0;
int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
boolean mAltOrientation = false;
@ -939,8 +944,7 @@ public class WindowManagerService extends IWindowManager.Stub
// Figure out where the window should go, based on the
// order of applications.
WindowState pos = null;
AppTokenIterator iterator =
displayContent.new AppTokenIterator(true /*reverse*/);
AppTokenIterator iterator = displayContent.getTmpAppIterator(REVERSE_ITERATOR);
while (iterator.hasNext()) {
AppWindowToken t = iterator.next();
if (t == token) {
@ -2453,9 +2457,9 @@ public class WindowManagerService extends IWindowManager.Stub
public void updateAppOpsState() {
synchronized(mWindowMap) {
AllWindowsIterator iterator = new AllWindowsIterator();
while (iterator.hasNext()) {
final WindowState win = iterator.next();
mTmpWindowsIterator.reset(FORWARD_ITERATOR);
while (mTmpWindowsIterator.hasNext()) {
final WindowState win = mTmpWindowsIterator.next();
if (win.mAppOp != AppOpsManager.OP_NONE) {
final int mode = mAppOps.checkOpNoThrow(win.mAppOp, win.getOwningUid(),
win.getOwningPackage());
@ -3101,6 +3105,7 @@ public class WindowManagerService extends IWindowManager.Stub
// -------------------------------------------------------------
public void validateAppTokens(List<TaskGroup> tasks) {
synchronized (mWindowMap) {
int t = tasks.size() - 1;
if (t < 0) {
Slog.w(TAG, "validateAppTokens: empty task list");
@ -3115,7 +3120,7 @@ public class WindowManagerService extends IWindowManager.Stub
return;
}
AppTokenIterator iterator = displayContent.new AppTokenIterator(true);
AppTokenIterator iterator = displayContent.getTmpAppIterator(REVERSE_ITERATOR);
for ( ; t >= 0; --t) {
task = tasks.get(t);
List<IApplicationToken> tokens = task.tokens;
@ -3152,6 +3157,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
}
}
boolean checkCallingPermission(String permission, String func) {
// Quick check: if the calling permission is me, it's all okay.
@ -3380,7 +3386,7 @@ public class WindowManagerService extends IWindowManager.Stub
boolean lastFullscreen = false;
// TODO: Multi window.
DisplayContent displayContent = getDefaultDisplayContentLocked();
AppTokenIterator iterator = displayContent.new AppTokenIterator(true);
AppTokenIterator iterator = displayContent.getTmpAppIterator(REVERSE_ITERATOR);
while (iterator.hasNext()) {
AppWindowToken atoken = iterator.next();
@ -4362,7 +4368,7 @@ public class WindowManagerService extends IWindowManager.Stub
while (iterator.hasNext()) {
DisplayContent displayContent = iterator.next();
Slog.v(TAG, " Display " + displayContent.getDisplayId());
AppTokenIterator appIterator = displayContent.new AppTokenIterator(true);
AppTokenIterator appIterator = displayContent.getTmpAppIterator(REVERSE_ITERATOR);
int i = appIterator.size();
while (appIterator.hasNext()) {
Slog.v(TAG, " #" + --i + ": " + appIterator.next().token);
@ -4372,9 +4378,9 @@ public class WindowManagerService extends IWindowManager.Stub
void dumpWindowsLocked() {
int i = 0;
final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
while (iterator.hasNext()) {
final WindowState w = iterator.next();
mTmpWindowsIterator.reset(REVERSE_ITERATOR);
while (mTmpWindowsIterator.hasNext()) {
final WindowState w = mTmpWindowsIterator.next();
Slog.v(TAG, " #" + i++ + ": " + w);
}
}
@ -4389,7 +4395,7 @@ public class WindowManagerService extends IWindowManager.Stub
final WindowList windows = displayContent.getWindowList();
final int NW = windows.size();
AppTokenIterator iterator = displayContent.new AppTokenIterator(true);
AppTokenIterator iterator = displayContent.getTmpAppIterator(REVERSE_ITERATOR);
while (iterator.hasNext()) {
if (iterator.next() == target) {
break;
@ -4692,9 +4698,9 @@ public class WindowManagerService extends IWindowManager.Stub
@Override
public void closeSystemDialogs(String reason) {
synchronized(mWindowMap) {
final AllWindowsIterator iterator = new AllWindowsIterator();
while (iterator.hasNext()) {
final WindowState w = iterator.next();
mTmpWindowsIterator.reset(FORWARD_ITERATOR);
while (mTmpWindowsIterator.hasNext()) {
final WindowState w = mTmpWindowsIterator.next();
if (w.mHasSurface) {
try {
w.mClient.closeSystemDialogs(reason);
@ -5088,9 +5094,9 @@ public class WindowManagerService extends IWindowManager.Stub
// the background..)
if (on) {
boolean isVisible = false;
final AllWindowsIterator iterator = new AllWindowsIterator();
while (iterator.hasNext()) {
final WindowState ws = iterator.next();
mTmpWindowsIterator.reset(FORWARD_ITERATOR);
while (mTmpWindowsIterator.hasNext()) {
final WindowState ws = mTmpWindowsIterator.next();
if (ws.mSession.mPid == pid && ws.isVisibleLw()) {
isVisible = true;
break;
@ -5966,9 +5972,9 @@ public class WindowManagerService extends IWindowManager.Stub
}
synchronized (mWindowMap) {
final AllWindowsIterator iterator = new AllWindowsIterator();
while (iterator.hasNext()) {
final WindowState w = iterator.next();
mTmpWindowsIterator.reset(FORWARD_ITERATOR);
while (mTmpWindowsIterator.hasNext()) {
final WindowState w = mTmpWindowsIterator.next();
if (System.identityHashCode(w) == hashCode) {
return w;
}
@ -6517,10 +6523,10 @@ public class WindowManagerService extends IWindowManager.Stub
// TODO(multidisplay): Call isScreenOn for each display.
private void sendScreenStatusToClientsLocked() {
final boolean on = mPowerManager.isScreenOn();
final AllWindowsIterator iterator = new AllWindowsIterator();
while (iterator.hasNext()) {
mTmpWindowsIterator.reset(FORWARD_ITERATOR);
while (mTmpWindowsIterator.hasNext()) {
try {
iterator.next().mClient.dispatchScreenState(on);
mTmpWindowsIterator.next().mClient.dispatchScreenState(on);
} catch (RemoteException e) {
// Ignored
}
@ -6861,7 +6867,8 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized (mWindowMap) {
Slog.w(TAG, "App freeze timeout expired.");
DisplayContent displayContent = getDefaultDisplayContentLocked();
AppTokenIterator iterator = displayContent.new AppTokenIterator(true);
AppTokenIterator iterator =
displayContent.getTmpAppIterator(REVERSE_ITERATOR);
while (iterator.hasNext()) {
AppWindowToken tok = iterator.next();
if (tok.mAppAnimator.freezingScreen) {
@ -7324,7 +7331,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
// And add in the still active app tokens in Z order.
AppTokenIterator iterator = displayContent.new AppTokenIterator();
AppTokenIterator iterator = displayContent.getTmpAppIterator(FORWARD_ITERATOR);
while (iterator.hasNext()) {
i = reAddAppWindowsLocked(displayContent, i, iterator.next());
}
@ -7997,7 +8004,7 @@ public class WindowManagerService extends IWindowManager.Stub
mAppTransition.setIdle();
// Restore window app tokens to the ActivityManager views
final DisplayContent displayContent = getDefaultDisplayContentLocked();
AppTokenIterator iterator = displayContent.new AppTokenIterator();
AppTokenIterator iterator = displayContent.getTmpAppIterator(FORWARD_ITERATOR);
while (iterator.hasNext()) {
iterator.next().sendingToBottom = false;
}
@ -8157,7 +8164,7 @@ public class WindowManagerService extends IWindowManager.Stub
private void updateAllDrawnLocked(DisplayContent displayContent) {
// See if any windows have been drawn, so they (and others
// associated with them) can now be shown.
AppTokenIterator iterator = displayContent.new AppTokenIterator();
AppTokenIterator iterator = displayContent.getTmpAppIterator(FORWARD_ITERATOR);
while (iterator.hasNext()) {
AppWindowToken wtoken = iterator.next();
if (!wtoken.allDrawn) {
@ -8924,10 +8931,10 @@ public class WindowManagerService extends IWindowManager.Stub
// window list to make sure we haven't left any dangling surfaces
// around.
AllWindowsIterator iterator = new AllWindowsIterator();
mTmpWindowsIterator.reset(FORWARD_ITERATOR);
Slog.i(TAG, "Out of memory for surface! Looking for leaks...");
while (iterator.hasNext()) {
WindowState ws = iterator.next();
while (mTmpWindowsIterator.hasNext()) {
WindowState ws = mTmpWindowsIterator.next();
WindowStateAnimator wsa = ws.mWinAnimator;
if (wsa.mSurface != null) {
if (!mSessions.contains(wsa.mSession)) {
@ -8960,9 +8967,9 @@ public class WindowManagerService extends IWindowManager.Stub
if (!leakedSurface) {
Slog.w(TAG, "No leaked surfaces; killing applicatons!");
SparseIntArray pidCandidates = new SparseIntArray();
iterator = new AllWindowsIterator();
while (iterator.hasNext()) {
WindowState ws = iterator.next();
mTmpWindowsIterator.reset(FORWARD_ITERATOR);
while (mTmpWindowsIterator.hasNext()) {
WindowState ws = mTmpWindowsIterator.next();
if (mForceRemoves.contains(ws)) {
continue;
}
@ -9088,7 +9095,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
private WindowState findFocusedWindowLocked(DisplayContent displayContent) {
AppTokenIterator iterator = displayContent.new AppTokenIterator(true);
AppTokenIterator iterator = displayContent.getTmpAppIterator(REVERSE_ITERATOR);
WindowToken nextApp = iterator.hasNext() ? iterator.next() : null;
final WindowList windows = displayContent.getWindowList();
@ -9552,9 +9559,9 @@ public class WindowManagerService extends IWindowManager.Stub
void dumpWindowsNoHeaderLocked(PrintWriter pw, boolean dumpAll,
ArrayList<WindowState> windows) {
int j = 0;
final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
while (iterator.hasNext()) {
final WindowState w = iterator.next();
mTmpWindowsIterator.reset(REVERSE_ITERATOR);
while (mTmpWindowsIterator.hasNext()) {
final WindowState w = mTmpWindowsIterator.next();
if (windows == null || windows.contains(w)) {
pw.print(" Window #"); pw.print(j++); pw.print(' ');
pw.print(w); pw.println(":");
@ -9749,9 +9756,9 @@ public class WindowManagerService extends IWindowManager.Stub
WindowList windows = new WindowList();
if ("visible".equals(name)) {
synchronized(mWindowMap) {
final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
while (iterator.hasNext()) {
final WindowState w = iterator.next();
mTmpWindowsIterator.reset(REVERSE_ITERATOR);
while (mTmpWindowsIterator.hasNext()) {
final WindowState w = mTmpWindowsIterator.next();
if (w.mWinAnimator.mSurfaceShown) {
windows.add(w);
}
@ -9766,9 +9773,9 @@ public class WindowManagerService extends IWindowManager.Stub
} catch (RuntimeException e) {
}
synchronized(mWindowMap) {
final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR);
while (iterator.hasNext()) {
final WindowState w = iterator.next();
mTmpWindowsIterator.reset(REVERSE_ITERATOR);
while (mTmpWindowsIterator.hasNext()) {
final WindowState w = mTmpWindowsIterator.next();
if (name != null) {
if (w.mAttrs.getTitle().toString().contains(name)) {
windows.add(w);
@ -9995,6 +10002,10 @@ public class WindowManagerService extends IWindowManager.Stub
class DisplayContentsIterator implements Iterator<DisplayContent> {
private int cur;
void reset() {
cur = 0;
}
@Override
public boolean hasNext() {
return cur < mDisplayContents.size();
@ -10014,7 +10025,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
final static boolean REVERSE_ITERATOR = true;
class AllWindowsIterator implements Iterator<WindowState> {
private DisplayContent mDisplayContent;
private DisplayContentsIterator mDisplayContentsIterator;
@ -10023,19 +10033,33 @@ public class WindowManagerService extends IWindowManager.Stub
private boolean mReverse;
AllWindowsIterator() {
mDisplayContentsIterator = new DisplayContentsIterator();
mDisplayContent = mDisplayContentsIterator.next();
mWindowList = mDisplayContent.getWindowList();
this(false);
}
AllWindowsIterator(boolean reverse) {
this();
mDisplayContentsIterator = new DisplayContentsIterator();
reset(reverse);
}
void reset(boolean reverse) {
mReverse = reverse;
mDisplayContentsIterator.reset();
if (mDisplayContentsIterator.hasNext()) {
mDisplayContent = mDisplayContentsIterator.next();
mWindowList = mDisplayContent.getWindowList();
mWindowListIndex = reverse ? mWindowList.size() - 1 : 0;
} else {
mDisplayContent = null;
mWindowList = null;
mWindowListIndex = 0;
}
}
@Override
public boolean hasNext() {
if (mDisplayContent == null) {
return false;
}
if (mReverse) {
return mWindowListIndex >= 0;
}