Moved window focus calculation to DisplayContent
In prep. for using WindowContainer. Bug: 30060889 Change-Id: Ide3022b3129b3d190f631a07d7589a27c434e0c3
This commit is contained in:
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
@@ -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.
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -1569,8 +1569,7 @@ class WindowSurfacePlacer {
|
||||
private void processApplicationsAnimatingInPlace(int transit) {
|
||||
if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
|
||||
// Find the focused window
|
||||
final WindowState win = mService.findFocusedWindowLocked(
|
||||
mService.getDefaultDisplayContentLocked());
|
||||
final WindowState win = mService.getDefaultDisplayContentLocked().findFocusedWindow();
|
||||
if (win != null) {
|
||||
final AppWindowToken wtoken = win.mAppToken;
|
||||
final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
|
||||
|
||||
@@ -326,6 +326,49 @@ public class WindowContainerTests {
|
||||
assertEquals(SCREEN_ORIENTATION_PORTRAIT, root.getOrientation());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompareTo() throws Exception {
|
||||
final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
|
||||
final TestWindowContainer root = builder.setLayer(0).build();
|
||||
|
||||
final TestWindowContainer child1 = root.addChildWindow();
|
||||
final TestWindowContainer child11 = child1.addChildWindow();
|
||||
final TestWindowContainer child12 = child1.addChildWindow();
|
||||
|
||||
final TestWindowContainer child2 = root.addChildWindow();
|
||||
final TestWindowContainer child21 = child2.addChildWindow();
|
||||
final TestWindowContainer child22 = child2.addChildWindow();
|
||||
final TestWindowContainer child23 = child2.addChildWindow();
|
||||
final TestWindowContainer child221 = child22.addChildWindow();
|
||||
final TestWindowContainer child222 = child22.addChildWindow();
|
||||
final TestWindowContainer child223 = child22.addChildWindow();
|
||||
final TestWindowContainer child2221 = child222.addChildWindow();
|
||||
final TestWindowContainer child2222 = child222.addChildWindow();
|
||||
final TestWindowContainer child2223 = child222.addChildWindow();
|
||||
|
||||
final TestWindowContainer root2 = builder.setLayer(0).build();
|
||||
|
||||
assertEquals(0, root.compareTo(root));
|
||||
assertEquals(-1, child1.compareTo(child2));
|
||||
assertEquals(1, child2.compareTo(child1));
|
||||
|
||||
boolean inTheSameTree = true;
|
||||
try {
|
||||
root.compareTo(root2);
|
||||
} catch (IllegalArgumentException e) {
|
||||
inTheSameTree = false;
|
||||
}
|
||||
assertFalse(inTheSameTree);
|
||||
|
||||
assertEquals(-1, child1.compareTo(child11));
|
||||
assertEquals(1, child21.compareTo(root));
|
||||
assertEquals(1, child21.compareTo(child12));
|
||||
assertEquals(-1, child11.compareTo(child2));
|
||||
assertEquals(1, child2221.compareTo(child11));
|
||||
assertEquals(-1, child2222.compareTo(child223));
|
||||
assertEquals(1, child2223.compareTo(child21));
|
||||
}
|
||||
|
||||
/* Used so we can gain access to some protected members of the {@link WindowContainer} class */
|
||||
private class TestWindowContainer extends WindowContainer {
|
||||
private final int mLayer;
|
||||
|
||||
Reference in New Issue
Block a user