Moved adding to display WindowList to DisplayContent

In prep. for using WindowContainer.

Bug: 30060889

Change-Id: Ife8e03b53ce89f5b932f765850d072194d49fcb3
This commit is contained in:
Wale Ogunwale
2016-09-08 20:18:57 -07:00
parent 63d4ecc7a5
commit ec73115b09
5 changed files with 339 additions and 308 deletions

View File

@@ -27,9 +27,14 @@ import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
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_FOCUS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -44,6 +49,7 @@ import android.util.DisplayMetrics;
import android.util.Slog;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.IWindow;
import android.view.Surface;
import android.view.animation.Animation;
@@ -828,4 +834,264 @@ class DisplayContent {
if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: No focusable windows.");
return null;
}
int addAppWindowToWindowList(final WindowState win) {
final IWindow client = win.mClient;
WindowList tokenWindowList = getTokenWindowsOnDisplay(win.mToken);
if (!tokenWindowList.isEmpty()) {
return addAppWindowExisting(win, tokenWindowList);
}
// No windows from this token on this display
if (mService.localLOGV) Slog.v(TAG_WM, "Figuring out where to add app window "
+ client.asBinder() + " (token=" + this + ")");
final WindowToken wToken = win.mToken;
// Figure out where the window should go, based on the order of applications.
final GetWindowOnDisplaySearchResults result = new GetWindowOnDisplaySearchResults();
for (int i = mStacks.size() - 1; i >= 0; --i) {
final TaskStack stack = mStacks.get(i);
stack.getWindowOnDisplayBeforeToken(this, wToken, result);
if (result.reachedToken) {
// We have reach the token we are interested in. End search.
break;
}
}
WindowState pos = result.foundWindow;
// We now know the index into the apps. If we found an app window above, that gives us the
// position; else we need to look some more.
if (pos != null) {
// Move behind any windows attached to this one.
final WindowToken atoken = mService.mTokenMap.get(pos.mClient.asBinder());
if (atoken != null) {
tokenWindowList = getTokenWindowsOnDisplay(atoken);
final int NC = tokenWindowList.size();
if (NC > 0) {
WindowState bottom = tokenWindowList.get(0);
if (bottom.mSubLayer < 0) {
pos = bottom;
}
}
}
addWindowToListBefore(win, pos);
return 0;
}
// Continue looking down until we find the first token that has windows on this display.
result.reset();
for (int i = mStacks.size() - 1; i >= 0; --i) {
final TaskStack stack = mStacks.get(i);
stack.getWindowOnDisplayAfterToken(this, wToken, result);
if (result.foundWindow != null) {
// We have found a window after the token. End search.
break;
}
}
pos = result.foundWindow;
if (pos != null) {
// Move in front of any windows attached to this one.
final WindowToken atoken = mService.mTokenMap.get(pos.mClient.asBinder());
if (atoken != null) {
final WindowState top = atoken.getTopWindow();
if (top != null && top.mSubLayer >= 0) {
pos = top;
}
}
addWindowToListAfter(win, pos);
return 0;
}
// Just search for the start of this layer.
final int myLayer = win.mBaseLayer;
int i;
for (i = mWindows.size() - 1; i >= 0; --i) {
final WindowState w = mWindows.get(i);
// Dock divider shares the base layer with application windows, but we want to always
// keep it above the application windows. The sharing of the base layer is intended
// for window animations, which need to be above the dock divider for the duration
// of the animation.
if (w.mBaseLayer <= myLayer && w.mAttrs.type != TYPE_DOCK_DIVIDER) {
break;
}
}
if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
"Based on layer: Adding window " + win + " at " + (i + 1) + " of "
+ mWindows.size());
mWindows.add(i + 1, win);
mService.mWindowsChanged = true;
return 0;
}
/** Adds this non-app window to the window list. */
void addNonAppWindowToWindowList(WindowState win) {
// Figure out where window should go, based on layer.
int i;
for (i = mWindows.size() - 1; i >= 0; i--) {
final WindowState otherWin = mWindows.get(i);
if (otherWin.getBaseType() != TYPE_WALLPAPER && otherWin.mBaseLayer <= win.mBaseLayer) {
// Wallpaper wanders through the window list, for example to position itself
// directly behind keyguard. Because of this it will break the ordering based on
// WindowState.mBaseLayer. There might windows with higher mBaseLayer behind it and
// we don't want the new window to appear above them. An example of this is adding
// of the docked stack divider. Consider a scenario with the following ordering (top
// to bottom): keyguard, wallpaper, assist preview, apps. We want the dock divider
// to land below the assist preview, so the dock divider must ignore the wallpaper,
// with which it shares the base layer.
break;
}
}
i++;
if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
"Free window: Adding window " + this + " at " + i + " of " + mWindows.size());
mWindows.add(i, win);
mService.mWindowsChanged = true;
}
void addChildWindowToWindowList(WindowState win) {
final WindowState parentWindow = win.getParentWindow();
WindowList windowsOnSameDisplay = getTokenWindowsOnDisplay(win.mToken);
// Figure out this window's ordering relative to the parent window.
final int wCount = windowsOnSameDisplay.size();
final int sublayer = win.mSubLayer;
int largestSublayer = Integer.MIN_VALUE;
WindowState windowWithLargestSublayer = null;
int i;
for (i = 0; i < wCount; i++) {
WindowState w = windowsOnSameDisplay.get(i);
final int wSublayer = w.mSubLayer;
if (wSublayer >= largestSublayer) {
largestSublayer = wSublayer;
windowWithLargestSublayer = w;
}
if (sublayer < 0) {
// For negative sublayers, we go below all windows in the same sublayer.
if (wSublayer >= sublayer) {
addWindowToListBefore(win, wSublayer >= 0 ? parentWindow : w);
break;
}
} else {
// For positive sublayers, we go above all windows in the same sublayer.
if (wSublayer > sublayer) {
addWindowToListBefore(win, w);
break;
}
}
}
if (i >= wCount) {
if (sublayer < 0) {
addWindowToListBefore(win, parentWindow);
} else {
addWindowToListAfter(win,
largestSublayer >= 0 ? windowWithLargestSublayer : parentWindow);
}
}
}
/** Return the list of Windows on this display associated with the input token. */
WindowList getTokenWindowsOnDisplay(WindowToken token) {
final WindowList windowList = new WindowList();
final int count = mWindows.size();
for (int i = 0; i < count; i++) {
final WindowState win = mWindows.get(i);
if (win.mToken == token) {
windowList.add(win);
}
}
return windowList;
}
private int addAppWindowExisting(WindowState win, WindowList tokenWindowList) {
int tokenWindowsPos;
// If this application has existing windows, we simply place the new window on top of
// them... but keep the starting window on top.
if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
// Base windows go behind everything else.
final WindowState lowestWindow = tokenWindowList.get(0);
addWindowToListBefore(win, lowestWindow);
tokenWindowsPos = win.mToken.getWindowIndex(lowestWindow);
} else {
final AppWindowToken atoken = win.mAppToken;
final int windowListPos = tokenWindowList.size();
final WindowState lastWindow = tokenWindowList.get(windowListPos - 1);
if (atoken != null && lastWindow == atoken.startingWindow) {
addWindowToListBefore(win, lastWindow);
tokenWindowsPos = win.mToken.getWindowIndex(lastWindow);
} else {
int newIdx = findIdxBasedOnAppTokens(win);
// There is a window above this one associated with the same apptoken note that the
// window could be a floating window that was created later or a window at the top
// of the list of windows associated with this token.
if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
"not Base app: Adding window " + win + " at " + (newIdx + 1) + " of "
+ mWindows.size());
mWindows.add(newIdx + 1, win);
if (newIdx < 0) {
// No window from token found on win's display.
tokenWindowsPos = 0;
} else {
tokenWindowsPos = win.mToken.getWindowIndex(mWindows.get(newIdx)) + 1;
}
mService.mWindowsChanged = true;
}
}
return tokenWindowsPos;
}
/** Places the first input window after the second input window in the window list. */
private void addWindowToListAfter(WindowState first, WindowState second) {
final int i = mWindows.indexOf(second);
if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
"Adding window " + this + " at " + (i + 1) + " of " + mWindows.size()
+ " (after " + second + ")");
mWindows.add(i + 1, first);
mService.mWindowsChanged = true;
}
/** Places the first input window before the second input window in the window list. */
private void addWindowToListBefore(WindowState first, WindowState second) {
int i = mWindows.indexOf(second);
if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
"Adding window " + this + " at " + i + " of " + mWindows.size()
+ " (before " + second + ")");
if (i < 0) {
Slog.w(TAG_WM, "addWindowToListBefore: Unable to find " + second + " in " + mWindows);
i = 0;
}
mWindows.add(i, first);
mService.mWindowsChanged = true;
}
/**
* This method finds out the index of a window that has the same app token as win. used for z
* ordering the windows in mWindows
*/
private int findIdxBasedOnAppTokens(WindowState win) {
for(int j = mWindows.size() - 1; j >= 0; j--) {
final WindowState wentry = mWindows.get(j);
if(wentry.mAppToken == win.mAppToken) {
return j;
}
}
return -1;
}
static final class GetWindowOnDisplaySearchResults {
boolean reachedToken;
WindowState foundWindow;
void reset() {
reachedToken = false;
foundWindow = null;
}
}
}

View File

@@ -689,6 +689,46 @@ class Task implements DimLayer.DimLayerUser {
return mAppTokens.indexOf(first) > mAppTokens.indexOf(second);
}
void getWindowOnDisplayBeforeToken(DisplayContent dc, WindowToken token,
DisplayContent.GetWindowOnDisplaySearchResults result) {
for (int i = mAppTokens.size() - 1; i >= 0; --i) {
final AppWindowToken current = mAppTokens.get(i);
if (current == token) {
// We have reach the token we are interested in. End search.
result.reachedToken = true;
return;
}
// We haven't reached the token yet; if this token is not going to the bottom and
// has windows on this display, then it is a candidate for what we are looking for.
final WindowList tokenWindowList = dc.getTokenWindowsOnDisplay(current);
if (!current.sendingToBottom && tokenWindowList.size() > 0) {
result.foundWindow = tokenWindowList.get(0);
}
}
}
void getWindowOnDisplayAfterToken(DisplayContent dc, WindowToken token,
DisplayContent.GetWindowOnDisplaySearchResults result) {
for (int i = mAppTokens.size() - 1; i >= 0; --i) {
final AppWindowToken current = mAppTokens.get(i);
if (!result.reachedToken) {
if (current == token) {
// We have reached the token we are interested in. Get whichever window occurs
// after it that is on the same display.
result.reachedToken = true;
}
continue;
}
final WindowList tokenWindowList = dc.getTokenWindowsOnDisplay(current);
if (tokenWindowList.size() > 0) {
result.foundWindow = tokenWindowList.get(tokenWindowList.size() - 1);
return;
}
}
}
boolean fillsParent() {
return mFullscreen || !StackId.isTaskResizeAllowed(mStack.mStackId);
}

View File

@@ -1320,6 +1320,30 @@ public class TaskStack implements DimLayer.DimLayerUser,
return mTasks.indexOf(first) > mTasks.indexOf(second);
}
void getWindowOnDisplayBeforeToken(DisplayContent dc, WindowToken token,
DisplayContent.GetWindowOnDisplaySearchResults result) {
for (int i = mTasks.size() - 1; i >= 0; --i) {
final Task task = mTasks.get(i);
task.getWindowOnDisplayBeforeToken(dc, token, result);
if (result.reachedToken) {
// We have reach the token we are interested in. End search.
return;
}
}
}
void getWindowOnDisplayAfterToken(DisplayContent dc, WindowToken token,
DisplayContent.GetWindowOnDisplaySearchResults result) {
for (int i = mTasks.size() - 1; i >= 0; --i) {
final Task task = mTasks.get(i);
task.getWindowOnDisplayAfterToken(dc, token, result);
if (result.foundWindow != null) {
// We have found a window after the token. End search.
return;
}
}
}
// TODO: Remove once switched to use WindowContainer
int getOrientation() {
if (!StackId.canSpecifyOrientation(mStackId)) {

View File

@@ -3980,60 +3980,6 @@ class WindowState extends WindowContainer implements WindowManagerPolicy.WindowS
return false;
}
/** Places this window after the input window in the window list. */
void addWindowToListAfter(WindowState pos) {
final WindowList windows = pos.getWindowList();
final int i = windows.indexOf(pos);
if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
"Adding window " + this + " at " + (i+1) + " of " + windows.size()
+ " (after " + pos + ")");
windows.add(i+1, this);
mService.mWindowsChanged = true;
}
/** Places this window before the input window in the window list. */
void addWindowToListBefore(WindowState pos) {
final WindowList windows = pos.getWindowList();
int i = windows.indexOf(pos);
if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
"Adding window " + this + " at " + i + " of " + windows.size()
+ " (before " + pos + ")");
if (i < 0) {
Slog.w(TAG_WM, "addWindowToListBefore: Unable to find " + pos + " in " + windows);
i = 0;
}
windows.add(i, this);
mService.mWindowsChanged = true;
}
/** Adds this non-app window to the window list. */
void addNonAppWindowToList() {
final WindowList windows = getWindowList();
// Figure out where window should go, based on layer.
int i;
for (i = windows.size() - 1; i >= 0; i--) {
final WindowState otherWin = windows.get(i);
if (otherWin.getBaseType() != TYPE_WALLPAPER && otherWin.mBaseLayer <= mBaseLayer) {
// Wallpaper wanders through the window list, for example to position itself
// directly behind keyguard. Because of this it will break the ordering based on
// WindowState.mBaseLayer. There might windows with higher mBaseLayer behind it and
// we don't want the new window to appear above them. An example of this is adding
// of the docked stack divider. Consider a scenario with the following ordering (top
// to bottom): keyguard, wallpaper, assist preview, apps. We want the dock divider
// to land below the assist preview, so the dock divider must ignore the wallpaper,
// with which it shares the base layer.
break;
}
}
i++;
if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
"Free window: Adding window " + this + " at " + i + " of " + windows.size());
windows.add(i, this);
mService.mWindowsChanged = true;
}
void updateReportedVisibility(UpdateReportedVisibilityResults results) {
for (int i = mChildren.size() - 1; i >= 0; --i) {
final WindowState c = (WindowState) mChildren.get(i);

View File

@@ -147,7 +147,6 @@ class WindowToken extends WindowContainer {
return highestAnimLayer;
}
/* package level access for test. */
WindowState getTopWindow() {
if (mChildren.isEmpty()) {
return null;
@@ -160,7 +159,6 @@ class WindowToken extends WindowContainer {
* @param target The window to search for.
* @return The index of win in windows or of the window that is an ancestor of win.
*/
/* package level access for test. */
int getWindowIndex(WindowState target) {
for (int i = mChildren.size() - 1; i >= 0; --i) {
final WindowState w = (WindowState) mChildren.get(i);
@@ -171,256 +169,28 @@ class WindowToken extends WindowContainer {
return -1;
}
/**
* Return the list of Windows in this token on the given Display.
* @param displayContent The display we are interested in.
* @return List of windows from token that are on displayContent.
*/
private WindowList getTokenWindowsOnDisplay(DisplayContent displayContent) {
final WindowList windowList = new WindowList();
final WindowList displayWindows = displayContent.getWindowList();
final int count = displayWindows.size();
for (int i = 0; i < count; i++) {
final WindowState win = displayWindows.get(i);
if (win.mToken == this) {
windowList.add(win);
}
}
return windowList;
}
// TODO: Now that we are no longer adding child windows to token directly, the rest of the code
// in this method doesn't really belong here, but is it difficult to move at the moment. Need to
// re-evaluate when figuring-out what to do about display window list.
private void addChildWindow(final WindowState win) {
final DisplayContent displayContent = win.getDisplayContent();
if (displayContent == null) {
return;
}
final WindowState parentWindow = win.getParentWindow();
WindowList windowsOnSameDisplay = getTokenWindowsOnDisplay(displayContent);
// Figure out this window's ordering relative to the parent window.
final int wCount = windowsOnSameDisplay.size();
final int sublayer = win.mSubLayer;
int largestSublayer = Integer.MIN_VALUE;
WindowState windowWithLargestSublayer = null;
int i;
for (i = 0; i < wCount; i++) {
WindowState w = windowsOnSameDisplay.get(i);
final int wSublayer = w.mSubLayer;
if (wSublayer >= largestSublayer) {
largestSublayer = wSublayer;
windowWithLargestSublayer = w;
}
if (sublayer < 0) {
// For negative sublayers, we go below all windows in the same sublayer.
if (wSublayer >= sublayer) {
win.addWindowToListBefore(wSublayer >= 0 ? parentWindow : w);
break;
}
} else {
// For positive sublayers, we go above all windows in the same sublayer.
if (wSublayer > sublayer) {
win.addWindowToListBefore(w);
break;
}
}
}
if (i >= wCount) {
if (sublayer < 0) {
win.addWindowToListBefore(parentWindow);
} else {
win.addWindowToListAfter(
largestSublayer >= 0 ? windowWithLargestSublayer : parentWindow);
}
}
}
void addWindow(final WindowState win) {
if (DEBUG_FOCUS) Slog.d(TAG_WM, "addWindow: win=" + win + " Callers=" + Debug.getCallers(5));
final DisplayContent dc = win.getDisplayContent();
if (!win.isChildWindow()) {
int tokenWindowsPos = 0;
if (asAppWindowToken() != null) {
tokenWindowsPos = addAppWindow(win);
} else {
win.addNonAppWindowToList();
if (dc != null) {
if (asAppWindowToken() != null) {
tokenWindowsPos = dc.addAppWindowToWindowList(win);
} else {
dc.addNonAppWindowToWindowList(win);
}
}
if (!mChildren.contains(win)) {
if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Adding " + win + " to " + this);
mChildren.add(tokenWindowsPos, win);
}
} else {
addChildWindow(win);
} else if (dc != null) {
dc.addChildWindowToWindowList(win);
}
}
private int addAppWindow(final WindowState win) {
final DisplayContent displayContent = win.getDisplayContent();
if (displayContent == null) {
// It doesn't matter this display is going away.
return 0;
}
final IWindow client = win.mClient;
final WindowList windows = displayContent.getWindowList();
WindowList tokenWindowList = getTokenWindowsOnDisplay(displayContent);
int tokenWindowsPos = 0;
if (!tokenWindowList.isEmpty()) {
return addAppWindowExisting(win, windows, tokenWindowList);
}
// No windows from this token on this display
if (mService.localLOGV) Slog.v(TAG_WM, "Figuring out where to add app window "
+ client.asBinder() + " (token=" + this + ")");
// Figure out where the window should go, based on the order of applications.
WindowState pos = null;
final ArrayList<Task> tasks = displayContent.getTasks();
int taskNdx;
int tokenNdx = -1;
for (taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
for (tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) {
final AppWindowToken t = tokens.get(tokenNdx);
if (t == this) {
--tokenNdx;
if (tokenNdx < 0) {
--taskNdx;
if (taskNdx >= 0) {
tokenNdx = tasks.get(taskNdx).mAppTokens.size() - 1;
}
}
break;
}
// We haven't reached the token yet; if this token is not going to the bottom and
// has windows on this display, we can use it as an anchor for when we do reach the
// token.
tokenWindowList = getTokenWindowsOnDisplay(displayContent);
if (!t.sendingToBottom && tokenWindowList.size() > 0) {
pos = tokenWindowList.get(0);
}
}
if (tokenNdx >= 0) {
// early exit
break;
}
}
// We now know the index into the apps. If we found an app window above, that gives us the
// position; else we need to look some more.
if (pos != null) {
// Move behind any windows attached to this one.
final WindowToken atoken = mService.mTokenMap.get(pos.mClient.asBinder());
if (atoken != null) {
tokenWindowList = atoken.getTokenWindowsOnDisplay(displayContent);
final int NC = tokenWindowList.size();
if (NC > 0) {
WindowState bottom = tokenWindowList.get(0);
if (bottom.mSubLayer < 0) {
pos = bottom;
}
}
}
win.addWindowToListBefore(pos);
return tokenWindowsPos;
}
// Continue looking down until we find the first token that has windows on this display.
for ( ; taskNdx >= 0; --taskNdx) {
AppTokenList tokens = tasks.get(taskNdx).mAppTokens;
for ( ; tokenNdx >= 0; --tokenNdx) {
final WindowToken t = tokens.get(tokenNdx);
tokenWindowList = t.getTokenWindowsOnDisplay(displayContent);
final int NW = tokenWindowList.size();
if (NW > 0) {
pos = tokenWindowList.get(NW-1);
break;
}
}
if (tokenNdx >= 0) {
// found
break;
}
}
if (pos != null) {
// Move in front of any windows attached to this one.
final WindowToken atoken = mService.mTokenMap.get(pos.mClient.asBinder());
if (atoken != null) {
final WindowState top = atoken.getTopWindow();
if (top != null && top.mSubLayer >= 0) {
pos = top;
}
}
win.addWindowToListAfter(pos);
return tokenWindowsPos;
}
// Just search for the start of this layer.
final int myLayer = win.mBaseLayer;
int i;
for (i = windows.size() - 1; i >= 0; --i) {
WindowState w = windows.get(i);
// Dock divider shares the base layer with application windows, but we want to always
// keep it above the application windows. The sharing of the base layer is intended
// for window animations, which need to be above the dock divider for the duration
// of the animation.
if (w.mBaseLayer <= myLayer && w.mAttrs.type != TYPE_DOCK_DIVIDER) {
break;
}
}
if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
"Based on layer: Adding window " + win + " at " + (i + 1) + " of "
+ windows.size());
windows.add(i + 1, win);
mService.mWindowsChanged = true;
return tokenWindowsPos;
}
private int addAppWindowExisting(
WindowState win, WindowList windowList, WindowList tokenWindowList) {
int tokenWindowsPos;
// If this application has existing windows, we simply place the new window on top of
// them... but keep the starting window on top.
if (win.mAttrs.type == TYPE_BASE_APPLICATION) {
// Base windows go behind everything else.
final WindowState lowestWindow = tokenWindowList.get(0);
win.addWindowToListBefore(lowestWindow);
tokenWindowsPos = getWindowIndex(lowestWindow);
} else {
final AppWindowToken atoken = win.mAppToken;
final int windowListPos = tokenWindowList.size();
final WindowState lastWindow = tokenWindowList.get(windowListPos - 1);
if (atoken != null && lastWindow == atoken.startingWindow) {
win.addWindowToListBefore(lastWindow);
tokenWindowsPos = getWindowIndex(lastWindow);
} else {
int newIdx = findIdxBasedOnAppTokens(win);
// There is a window above this one associated with the same apptoken note that the
// window could be a floating window that was created later or a window at the top
// of the list of windows associated with this token.
if (DEBUG_FOCUS || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
"not Base app: Adding window " + win + " at " + (newIdx + 1) + " of "
+ windowList.size());
windowList.add(newIdx + 1, win);
if (newIdx < 0) {
// No window from token found on win's display.
tokenWindowsPos = 0;
} else {
tokenWindowsPos = getWindowIndex(windowList.get(newIdx)) + 1;
}
mService.mWindowsChanged = true;
}
}
return tokenWindowsPos;
}
int reAddAppWindows(DisplayContent displayContent, int index) {
final int count = mChildren.size();
for (int i = 0; i < count; i++) {
@@ -434,21 +204,6 @@ class WindowToken extends WindowContainer {
return index;
}
/**
* This method finds out the index of a window that has the same app token as win. used for z
* ordering the windows in mWindows
*/
private int findIdxBasedOnAppTokens(WindowState win) {
final WindowList windows = win.getWindowList();
for(int j = windows.size() - 1; j >= 0; j--) {
final WindowState wentry = windows.get(j);
if(wentry.mAppToken == win.mAppToken) {
return j;
}
}
return -1;
}
/** Return the first window in the token window list that isn't a starting window or null. */
WindowState getFirstNonStartingWindow() {
final int count = mChildren.size();