Loading services/core/java/com/android/server/wm/DisplayContent.java +64 −0 Original line number Diff line number Diff line Loading @@ -26,7 +26,10 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 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_TOAST; 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_VISIBILITY; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; Loading Loading @@ -764,4 +767,65 @@ class DisplayContent { } } } WindowState findFocusedWindow() { final AppWindowToken focusedApp = mService.mFocusedApp; for (int i = mWindows.size() - 1; i >= 0; i--) { final WindowState win = mWindows.get(i); if (DEBUG_FOCUS) Slog.v(TAG_WM, "Looking for focus: " + i + " = " + win + ", flags=" + win.mAttrs.flags + ", canReceive=" + win.canReceiveKeys()); if (!win.canReceiveKeys()) { continue; } final AppWindowToken wtoken = win.mAppToken; // If this window's application has been removed, just skip it. if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) { if (DEBUG_FOCUS) Slog.v(TAG_WM, "Skipping " + wtoken + " because " + (wtoken.removed ? "removed" : "sendingToBottom")); continue; } if (focusedApp == null) { if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp=null" + " using new focus @ " + i + " = " + win); return win; } if (!focusedApp.windowsAreFocusable()) { // Current focused app windows aren't focusable... if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp windows not" + " focusable using new focus @ " + i + " = " + win); return win; } // Descend through all of the app tokens and find the first that either matches // win.mAppToken (return win) or mFocusedApp (return null). if (wtoken != null && win.mAttrs.type != TYPE_APPLICATION_STARTING) { final TaskStack focusedAppStack = focusedApp.mTask.mStack; final TaskStack appStack = wtoken.mTask.mStack; // TODO: Use WindowContainer.compareTo() once everything is using WindowContainer if ((focusedAppStack == appStack && appStack.isFirstGreaterThanSecond(focusedApp, wtoken)) || mStacks.indexOf(focusedAppStack) > mStacks.indexOf(appStack)) { // App stack below focused app stack. No focus for you!!! if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Reached focused app=" + focusedApp); return null; } } if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ " + i + " = " + win); return win; } if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: No focusable windows."); return null; } } services/core/java/com/android/server/wm/Task.java +5 −0 Original line number Diff line number Diff line Loading @@ -684,6 +684,11 @@ class Task implements DimLayer.DimLayerUser { return false; } // TODO: Use WindowContainer.compareTo() once everything is using WindowContainer boolean isFirstGreaterThanSecond(AppWindowToken first, AppWindowToken second) { return mAppTokens.indexOf(first) > mAppTokens.indexOf(second); } boolean fillsParent() { return mFullscreen || !StackId.isTaskResizeAllowed(mStack.mStackId); } Loading services/core/java/com/android/server/wm/TaskStack.java +11 −0 Original line number Diff line number Diff line Loading @@ -1309,6 +1309,17 @@ public class TaskStack implements DimLayer.DimLayerUser, } } // TODO: Use WindowContainer.compareTo() once everything is using WindowContainer boolean isFirstGreaterThanSecond(AppWindowToken first, AppWindowToken second) { final Task firstTask = first.mTask; final Task secondTask = second.mTask; if (firstTask == secondTask) { return firstTask.isFirstGreaterThanSecond(first, second); } return mTasks.indexOf(first) > mTasks.indexOf(second); } // TODO: Remove once switched to use WindowContainer int getOrientation() { if (!StackId.canSpecifyOrientation(mStackId)) { Loading services/core/java/com/android/server/wm/WindowContainer.java +66 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; * The test class is {@link WindowContainerTests} which must be kept up-to-date and ran anytime * changes are made to this class. */ class WindowContainer { class WindowContainer implements Comparable<WindowContainer> { // The parent of this window container. private WindowContainer mParent = null; Loading @@ -47,6 +47,10 @@ class WindowContainer { return mParent; } // Temp. holders for a chain of containers we are currently processing. private final LinkedList<WindowContainer> mTmpChain1 = new LinkedList(); private final LinkedList<WindowContainer> mTmpChain2 = new LinkedList(); /** * Adds the input window container has a child of this container in order based on the input * comparator. Loading Loading @@ -311,4 +315,65 @@ class WindowContainer { boolean fillsParent() { return false; } /** * Returns -1, 0, or 1 depending on if the input container is greater than, equal to, or lesser * than the input container in terms of z-order. */ @Override public int compareTo(WindowContainer other) { if (this == other) { return 0; } if (mParent != null && mParent == other.mParent) { final LinkedList<WindowContainer> list = mParent.mChildren; return list.indexOf(this) > list.indexOf(other) ? 1 : -1; } final LinkedList<WindowContainer> thisParentChain = mTmpChain1; final LinkedList<WindowContainer> otherParentChain = mTmpChain2; getParents(thisParentChain); other.getParents(otherParentChain); // Find the common ancestor of both containers. WindowContainer commonAncestor = null; WindowContainer thisTop = thisParentChain.peekLast(); WindowContainer otherTop = otherParentChain.peekLast(); while (thisTop != null && otherTop != null && thisTop == otherTop) { commonAncestor = thisParentChain.removeLast(); otherParentChain.removeLast(); thisTop = thisParentChain.peekLast(); otherTop = otherParentChain.peekLast(); } // Containers don't belong to the same hierarchy??? if (commonAncestor == null) { throw new IllegalArgumentException("No in the same hierarchy this=" + thisParentChain + " other=" + otherParentChain); } // Children are always considered greater than their parents, so if one of the containers // we are comparing it the parent of the other then whichever is the child is greater. if (commonAncestor == this) { return -1; } else if (commonAncestor == other) { return 1; } // The position of the first non-common ancestor in the common ancestor list determines // which is greater the which. final LinkedList<WindowContainer> list = commonAncestor.mChildren; return list.indexOf(thisParentChain.peekLast()) > list.indexOf(otherParentChain.peekLast()) ? 1 : -1; } private void getParents(LinkedList<WindowContainer> parents) { parents.clear(); WindowContainer current = this; do { parents.addLast(current); current = current.mParent; } while (current != null); } } services/core/java/com/android/server/wm/WindowManagerService.java +2 −64 Original line number Diff line number Diff line Loading @@ -3638,8 +3638,7 @@ public class WindowManagerService extends IWindowManager.Stub } if (mAppTransition.getAppTransition() == AppTransition.TRANSIT_TASK_OPEN_BEHIND) { // We're launchingBehind, add the launching activity to mOpeningApps. final WindowState win = findFocusedWindowLocked(getDefaultDisplayContentLocked()); final WindowState win = getDefaultDisplayContentLocked().findFocusedWindow(); if (win != null) { final AppWindowToken focusedToken = win.mAppToken; if (focusedToken != null) { Loading Loading @@ -8772,7 +8771,7 @@ public class WindowManagerService extends IWindowManager.Stub final int displayCount = mDisplayContents.size(); for (int i = 0; i < displayCount; i++) { final DisplayContent displayContent = mDisplayContents.valueAt(i); WindowState win = findFocusedWindowLocked(displayContent); final WindowState win = displayContent.findFocusedWindow(); if (win != null) { return win; } Loading @@ -8780,67 +8779,6 @@ public class WindowManagerService extends IWindowManager.Stub return null; } WindowState findFocusedWindowLocked(DisplayContent displayContent) { final WindowList windows = displayContent.getWindowList(); for (int i = windows.size() - 1; i >= 0; i--) { final WindowState win = windows.get(i); if (localLOGV || DEBUG_FOCUS) Slog.v( TAG_WM, "Looking for focus: " + i + " = " + win + ", flags=" + win.mAttrs.flags + ", canReceive=" + win.canReceiveKeys()); if (!win.canReceiveKeys()) { continue; } AppWindowToken wtoken = win.mAppToken; // If this window's application has been removed, just skip it. if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) { if (DEBUG_FOCUS) Slog.v(TAG_WM, "Skipping " + wtoken + " because " + (wtoken.removed ? "removed" : "sendingToBottom")); continue; } // Descend through all of the app tokens and find the first that either matches // win.mAppToken (return win) or mFocusedApp (return null). if (wtoken != null && win.mAttrs.type != TYPE_APPLICATION_STARTING && mFocusedApp != null) { ArrayList<Task> tasks = displayContent.getTasks(); for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { AppTokenList tokens = tasks.get(taskNdx).mAppTokens; int tokenNdx = tokens.size() - 1; for ( ; tokenNdx >= 0; --tokenNdx) { final AppWindowToken token = tokens.get(tokenNdx); if (wtoken == token) { break; } if (mFocusedApp == token && token.windowsAreFocusable()) { // Whoops, we are below the focused app whose windows are focusable... // No focus for you!!! if (localLOGV || DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Reached focused app=" + mFocusedApp); return null; } } if (tokenNdx >= 0) { // Early exit from loop, must have found the matching token. break; } } } if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ " + i + " = " + win); return win; } if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: No focusable windows."); return null; } void startFreezingDisplayLocked(boolean inTransaction, int exitAnim, int enterAnim) { if (mDisplayFrozen) { return; Loading Loading
services/core/java/com/android/server/wm/DisplayContent.java +64 −0 Original line number Diff line number Diff line Loading @@ -26,7 +26,10 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 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_TOAST; 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_VISIBILITY; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; Loading Loading @@ -764,4 +767,65 @@ class DisplayContent { } } } WindowState findFocusedWindow() { final AppWindowToken focusedApp = mService.mFocusedApp; for (int i = mWindows.size() - 1; i >= 0; i--) { final WindowState win = mWindows.get(i); if (DEBUG_FOCUS) Slog.v(TAG_WM, "Looking for focus: " + i + " = " + win + ", flags=" + win.mAttrs.flags + ", canReceive=" + win.canReceiveKeys()); if (!win.canReceiveKeys()) { continue; } final AppWindowToken wtoken = win.mAppToken; // If this window's application has been removed, just skip it. if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) { if (DEBUG_FOCUS) Slog.v(TAG_WM, "Skipping " + wtoken + " because " + (wtoken.removed ? "removed" : "sendingToBottom")); continue; } if (focusedApp == null) { if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp=null" + " using new focus @ " + i + " = " + win); return win; } if (!focusedApp.windowsAreFocusable()) { // Current focused app windows aren't focusable... if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: focusedApp windows not" + " focusable using new focus @ " + i + " = " + win); return win; } // Descend through all of the app tokens and find the first that either matches // win.mAppToken (return win) or mFocusedApp (return null). if (wtoken != null && win.mAttrs.type != TYPE_APPLICATION_STARTING) { final TaskStack focusedAppStack = focusedApp.mTask.mStack; final TaskStack appStack = wtoken.mTask.mStack; // TODO: Use WindowContainer.compareTo() once everything is using WindowContainer if ((focusedAppStack == appStack && appStack.isFirstGreaterThanSecond(focusedApp, wtoken)) || mStacks.indexOf(focusedAppStack) > mStacks.indexOf(appStack)) { // App stack below focused app stack. No focus for you!!! if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Reached focused app=" + focusedApp); return null; } } if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ " + i + " = " + win); return win; } if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: No focusable windows."); return null; } }
services/core/java/com/android/server/wm/Task.java +5 −0 Original line number Diff line number Diff line Loading @@ -684,6 +684,11 @@ class Task implements DimLayer.DimLayerUser { return false; } // TODO: Use WindowContainer.compareTo() once everything is using WindowContainer boolean isFirstGreaterThanSecond(AppWindowToken first, AppWindowToken second) { return mAppTokens.indexOf(first) > mAppTokens.indexOf(second); } boolean fillsParent() { return mFullscreen || !StackId.isTaskResizeAllowed(mStack.mStackId); } Loading
services/core/java/com/android/server/wm/TaskStack.java +11 −0 Original line number Diff line number Diff line Loading @@ -1309,6 +1309,17 @@ public class TaskStack implements DimLayer.DimLayerUser, } } // TODO: Use WindowContainer.compareTo() once everything is using WindowContainer boolean isFirstGreaterThanSecond(AppWindowToken first, AppWindowToken second) { final Task firstTask = first.mTask; final Task secondTask = second.mTask; if (firstTask == secondTask) { return firstTask.isFirstGreaterThanSecond(first, second); } return mTasks.indexOf(first) > mTasks.indexOf(second); } // TODO: Remove once switched to use WindowContainer int getOrientation() { if (!StackId.canSpecifyOrientation(mStackId)) { Loading
services/core/java/com/android/server/wm/WindowContainer.java +66 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; * The test class is {@link WindowContainerTests} which must be kept up-to-date and ran anytime * changes are made to this class. */ class WindowContainer { class WindowContainer implements Comparable<WindowContainer> { // The parent of this window container. private WindowContainer mParent = null; Loading @@ -47,6 +47,10 @@ class WindowContainer { return mParent; } // Temp. holders for a chain of containers we are currently processing. private final LinkedList<WindowContainer> mTmpChain1 = new LinkedList(); private final LinkedList<WindowContainer> mTmpChain2 = new LinkedList(); /** * Adds the input window container has a child of this container in order based on the input * comparator. Loading Loading @@ -311,4 +315,65 @@ class WindowContainer { boolean fillsParent() { return false; } /** * Returns -1, 0, or 1 depending on if the input container is greater than, equal to, or lesser * than the input container in terms of z-order. */ @Override public int compareTo(WindowContainer other) { if (this == other) { return 0; } if (mParent != null && mParent == other.mParent) { final LinkedList<WindowContainer> list = mParent.mChildren; return list.indexOf(this) > list.indexOf(other) ? 1 : -1; } final LinkedList<WindowContainer> thisParentChain = mTmpChain1; final LinkedList<WindowContainer> otherParentChain = mTmpChain2; getParents(thisParentChain); other.getParents(otherParentChain); // Find the common ancestor of both containers. WindowContainer commonAncestor = null; WindowContainer thisTop = thisParentChain.peekLast(); WindowContainer otherTop = otherParentChain.peekLast(); while (thisTop != null && otherTop != null && thisTop == otherTop) { commonAncestor = thisParentChain.removeLast(); otherParentChain.removeLast(); thisTop = thisParentChain.peekLast(); otherTop = otherParentChain.peekLast(); } // Containers don't belong to the same hierarchy??? if (commonAncestor == null) { throw new IllegalArgumentException("No in the same hierarchy this=" + thisParentChain + " other=" + otherParentChain); } // Children are always considered greater than their parents, so if one of the containers // we are comparing it the parent of the other then whichever is the child is greater. if (commonAncestor == this) { return -1; } else if (commonAncestor == other) { return 1; } // The position of the first non-common ancestor in the common ancestor list determines // which is greater the which. final LinkedList<WindowContainer> list = commonAncestor.mChildren; return list.indexOf(thisParentChain.peekLast()) > list.indexOf(otherParentChain.peekLast()) ? 1 : -1; } private void getParents(LinkedList<WindowContainer> parents) { parents.clear(); WindowContainer current = this; do { parents.addLast(current); current = current.mParent; } while (current != null); } }
services/core/java/com/android/server/wm/WindowManagerService.java +2 −64 Original line number Diff line number Diff line Loading @@ -3638,8 +3638,7 @@ public class WindowManagerService extends IWindowManager.Stub } if (mAppTransition.getAppTransition() == AppTransition.TRANSIT_TASK_OPEN_BEHIND) { // We're launchingBehind, add the launching activity to mOpeningApps. final WindowState win = findFocusedWindowLocked(getDefaultDisplayContentLocked()); final WindowState win = getDefaultDisplayContentLocked().findFocusedWindow(); if (win != null) { final AppWindowToken focusedToken = win.mAppToken; if (focusedToken != null) { Loading Loading @@ -8772,7 +8771,7 @@ public class WindowManagerService extends IWindowManager.Stub final int displayCount = mDisplayContents.size(); for (int i = 0; i < displayCount; i++) { final DisplayContent displayContent = mDisplayContents.valueAt(i); WindowState win = findFocusedWindowLocked(displayContent); final WindowState win = displayContent.findFocusedWindow(); if (win != null) { return win; } Loading @@ -8780,67 +8779,6 @@ public class WindowManagerService extends IWindowManager.Stub return null; } WindowState findFocusedWindowLocked(DisplayContent displayContent) { final WindowList windows = displayContent.getWindowList(); for (int i = windows.size() - 1; i >= 0; i--) { final WindowState win = windows.get(i); if (localLOGV || DEBUG_FOCUS) Slog.v( TAG_WM, "Looking for focus: " + i + " = " + win + ", flags=" + win.mAttrs.flags + ", canReceive=" + win.canReceiveKeys()); if (!win.canReceiveKeys()) { continue; } AppWindowToken wtoken = win.mAppToken; // If this window's application has been removed, just skip it. if (wtoken != null && (wtoken.removed || wtoken.sendingToBottom)) { if (DEBUG_FOCUS) Slog.v(TAG_WM, "Skipping " + wtoken + " because " + (wtoken.removed ? "removed" : "sendingToBottom")); continue; } // Descend through all of the app tokens and find the first that either matches // win.mAppToken (return win) or mFocusedApp (return null). if (wtoken != null && win.mAttrs.type != TYPE_APPLICATION_STARTING && mFocusedApp != null) { ArrayList<Task> tasks = displayContent.getTasks(); for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { AppTokenList tokens = tasks.get(taskNdx).mAppTokens; int tokenNdx = tokens.size() - 1; for ( ; tokenNdx >= 0; --tokenNdx) { final AppWindowToken token = tokens.get(tokenNdx); if (wtoken == token) { break; } if (mFocusedApp == token && token.windowsAreFocusable()) { // Whoops, we are below the focused app whose windows are focusable... // No focus for you!!! if (localLOGV || DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Reached focused app=" + mFocusedApp); return null; } } if (tokenNdx >= 0) { // Early exit from loop, must have found the matching token. break; } } } if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: Found new focus @ " + i + " = " + win); return win; } if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "findFocusedWindow: No focusable windows."); return null; } void startFreezingDisplayLocked(boolean inTransaction, int exitAnim, int enterAnim) { if (mDisplayFrozen) { return; Loading