summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/etc/services.core.protolog.json108
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java12
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java8
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java71
-rw-r--r--services/core/java/com/android/server/wm/DragDropController.java2
-rw-r--r--services/core/java/com/android/server/wm/InputManagerCallback.java5
-rw-r--r--services/core/java/com/android/server/wm/InputMonitor.java5
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java9
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java74
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java32
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java6
11 files changed, 150 insertions, 182 deletions
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 75eb7b64a444..a2a2216028ac 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -325,12 +325,6 @@
"group": "WM_DEBUG_REMOTE_ANIMATIONS",
"at": "com\/android\/server\/wm\/RemoteAnimationController.java"
},
- "-1587841219": {
- "message": "Focus moving from %s to %s displayId=%d",
- "level": "INFO",
- "group": "WM_DEBUG_FOCUS_LIGHT",
- "at": "com\/android\/server\/wm\/WindowManagerService.java"
- },
"-1568331821": {
"message": "Enabling listeners",
"level": "VERBOSE",
@@ -415,6 +409,12 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "-1438175584": {
+ "message": "Input focus has changed to %s display=%d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/InputMonitor.java"
+ },
"-1434147454": {
"message": "cleanupAnimation(): Notify animation finished mPendingAnimations=%d reorderMode=%d",
"level": "DEBUG",
@@ -565,6 +565,12 @@
"group": "WM_SHOW_TRANSACTIONS",
"at": "com\/android\/server\/wm\/WindowStateAnimator.java"
},
+ "-1142279614": {
+ "message": "Looking for focus: %s, flags=%d, canReceive=%b, reason=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_FOCUS",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
"-1130891072": {
"message": "Orientation continue waiting for draw in %s",
"level": "VERBOSE",
@@ -799,12 +805,6 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "-771282525": {
- "message": "Losing focus: %s",
- "level": "INFO",
- "group": "WM_DEBUG_FOCUS_LIGHT",
- "at": "com\/android\/server\/wm\/WindowManagerService.java"
- },
"-771177730": {
"message": "Removing focused app token:%s displayId=%d",
"level": "VERBOSE",
@@ -847,12 +847,6 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/DragState.java"
},
- "-687185281": {
- "message": "New topFocusedDisplayId=%d",
- "level": "VERBOSE",
- "group": "WM_DEBUG_FOCUS_LIGHT",
- "at": "com\/android\/server\/wm\/RootWindowContainer.java"
- },
"-668956537": {
"message": " THUMBNAIL %s: CREATE",
"level": "INFO",
@@ -877,6 +871,12 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowToken.java"
},
+ "-639217716": {
+ "message": "setFocusedApp %s displayId=%d Callers=%s",
+ "level": "INFO",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
"-635082269": {
"message": "******** booted=%b msg=%b haveBoot=%b haveApp=%b haveWall=%b wallEnabled=%b haveKeyguard=%b",
"level": "INFO",
@@ -895,12 +895,6 @@
"group": "WM_DEBUG_BOOT",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "-603199586": {
- "message": "Clearing focused app, displayId=%d",
- "level": "VERBOSE",
- "group": "WM_DEBUG_FOCUS_LIGHT",
- "at": "com\/android\/server\/wm\/DisplayContent.java"
- },
"-593535526": {
"message": "Binding proc %s with config %s",
"level": "VERBOSE",
@@ -919,6 +913,12 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/DisplayRotation.java"
},
+ "-561092364": {
+ "message": "onPointerDownOutsideFocusLocked called on %s",
+ "level": "INFO",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
"-549028919": {
"message": "enableScreenIfNeededLocked: mDisplayEnabled=%b mForceDisplayEnabled=%b mShowingBootMessages=%b mSystemBooted=%b. %s",
"level": "INFO",
@@ -1201,12 +1201,6 @@
"group": "WM_DEBUG_RECENTS_ANIMATIONS",
"at": "com\/android\/server\/wm\/RecentsAnimation.java"
},
- "-96848838": {
- "message": "Gaining focus: %s",
- "level": "INFO",
- "group": "WM_DEBUG_FOCUS_LIGHT",
- "at": "com\/android\/server\/wm\/WindowManagerService.java"
- },
"-90559682": {
"message": "Config is skipping already pausing %s",
"level": "VERBOSE",
@@ -1363,6 +1357,12 @@
"group": "WM_DEBUG_STARTING_WINDOW",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "115358443": {
+ "message": "Focus changing: %s -> %s",
+ "level": "INFO",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/WindowManagerService.java"
+ },
"123161180": {
"message": "SEVER CHILDREN",
"level": "INFO",
@@ -1495,12 +1495,6 @@
"group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
"at": "com\/android\/server\/wm\/AppTransition.java"
},
- "285317231": {
- "message": "Input focus has changed to %s",
- "level": "DEBUG",
- "group": "WM_DEBUG_FOCUS_LIGHT",
- "at": "com\/android\/server\/wm\/InputMonitor.java"
- },
"288485303": {
"message": "Attempted to set remove mode to a display that does not exist: %d",
"level": "WARN",
@@ -1537,6 +1531,12 @@
"group": "WM_SHOW_TRANSACTIONS",
"at": "com\/android\/server\/wm\/WindowSurfaceController.java"
},
+ "312030608": {
+ "message": "New topFocusedDisplayId=%d",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/RootWindowContainer.java"
+ },
"315395835": {
"message": "Trying to add window with invalid user=%d",
"level": "WARN",
@@ -1699,12 +1699,6 @@
"group": "WM_SHOW_TRANSACTIONS",
"at": "com\/android\/server\/wm\/WindowSurfaceController.java"
},
- "584499099": {
- "message": "Set focused app to: %s moveFocusNow=%b displayId=%d",
- "level": "VERBOSE",
- "group": "WM_DEBUG_FOCUS_LIGHT",
- "at": "com\/android\/server\/wm\/DisplayContent.java"
- },
"585096182": {
"message": "SURFACE isColorSpaceAgnostic=%b: %s",
"level": "INFO",
@@ -1747,6 +1741,12 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "620519522": {
+ "message": "findFocusedWindow: No focusable windows, display=%d",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
"628276090": {
"message": "Delaying app transition for screen rotation animation to finish",
"level": "VERBOSE",
@@ -1903,6 +1903,12 @@
"group": "WM_DEBUG_ADD_REMOVE",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "872933199": {
+ "message": "Changing focus from %s to %s displayId=%d Callers=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_FOCUS_LIGHT",
+ "at": "com\/android\/server\/wm\/DisplayContent.java"
+ },
"873914452": {
"message": "goodToGo()",
"level": "DEBUG",
@@ -2137,12 +2143,6 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/ScreenRotationAnimation.java"
},
- "1358462645": {
- "message": "Looking for focus: %s, flags=%d, canReceive=%b",
- "level": "VERBOSE",
- "group": "WM_DEBUG_FOCUS",
- "at": "com\/android\/server\/wm\/DisplayContent.java"
- },
"1360551978": {
"message": "Trying to update display configuration for non-existing displayId=%d",
"level": "WARN",
@@ -2233,12 +2233,6 @@
"group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
"at": "com\/android\/server\/wm\/AppTransitionController.java"
},
- "1469292670": {
- "message": "Changing focus from %s to %s displayId=%d Callers=%s",
- "level": "VERBOSE",
- "group": "WM_DEBUG_FOCUS_LIGHT",
- "at": "com\/android\/server\/wm\/DisplayContent.java"
- },
"1495525537": {
"message": "createWallpaperAnimations()",
"level": "DEBUG",
@@ -2677,12 +2671,6 @@
"group": "WM_DEBUG_IME",
"at": "com\/android\/server\/wm\/DisplayContent.java"
},
- "2128604122": {
- "message": "findFocusedWindow: No focusable windows.",
- "level": "VERBOSE",
- "group": "WM_DEBUG_FOCUS_LIGHT",
- "at": "com\/android\/server\/wm\/DisplayContent.java"
- },
"2128917433": {
"message": "onProposedRotationChanged, rotation=%d",
"level": "VERBOSE",
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 56261c4fce97..7d4d5629dacd 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -401,7 +401,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
final ActivityTaskManagerService mAtmService;
final ActivityInfo info; // activity info provided by developer in AndroidManifest
- // Non-null only for application tokens.
// TODO: rename to mActivityToken
final ActivityRecord.Token appToken;
// Which user is this running for?
@@ -5480,10 +5479,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
void updateReportedVisibilityLocked() {
- if (appToken == null) {
- return;
- }
-
if (DEBUG_VISIBILITY) Slog.v(TAG, "Update reported visibility: " + this);
final int count = mChildren.size();
@@ -6330,8 +6325,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
private void setOrientation(int requestedOrientation, boolean freezeScreenIfNeeded) {
- final IBinder binder =
- (freezeScreenIfNeeded && appToken != null) ? appToken.asBinder() : null;
+ final IBinder binder = freezeScreenIfNeeded ? appToken.asBinder() : null;
setOrientation(requestedOrientation, binder, this);
// Push the new configuration to the requested app in case where it's not pushed, e.g. when
@@ -7713,9 +7707,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
void writeNameToProto(ProtoOutputStream proto, long fieldId) {
- if (appToken != null) {
- proto.write(fieldId, appToken.getName());
- }
+ proto.write(fieldId, appToken.getName());
}
@Override
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 6a8cbfbb5840..c58b5b50d508 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -125,6 +125,7 @@ import static com.android.server.wm.Task.LOCK_TASK_AUTH_DONT_LOCK;
import static com.android.server.wm.Task.REPARENT_KEEP_STACK_AT_FRONT;
import static com.android.server.wm.Task.REPARENT_LEAVE_STACK_IN_PLACE;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
+import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
import android.Manifest;
import android.annotation.IntDef;
@@ -5465,8 +5466,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
updateResumedAppTrace(r);
mLastResumedActivity = r;
- r.getDisplay().setFocusedApp(r, true);
-
+ final boolean changed = r.getDisplay().setFocusedApp(r);
+ if (changed) {
+ mWindowManager.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
+ true /*updateInputWindows*/);
+ }
if (prevTask == null || task != prevTask) {
if (prevTask != null) {
mTaskChangeNotificationController.notifyTaskFocusChanged(prevTask.mTaskId, false);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 2f7cc69b01a7..aa8069a76330 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -115,13 +115,11 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIG
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-import static com.android.server.wm.WindowManagerService.H.REPORT_FOCUS_CHANGE;
import static com.android.server.wm.WindowManagerService.H.REPORT_HARD_KEYBOARD_STATUS_CHANGE;
import static com.android.server.wm.WindowManagerService.H.UPDATE_MULTI_WINDOW_STACKS;
import static com.android.server.wm.WindowManagerService.H.WINDOW_HIDE_TIMEOUT;
import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
import static com.android.server.wm.WindowManagerService.SEAMLESS_ROTATION_TIMEOUT_DURATION;
-import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_REMOVING_FOCUS;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_ASSIGN_LAYERS;
@@ -649,8 +647,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
private final ToBooleanFunction<WindowState> mFindFocusedWindow = w -> {
final ActivityRecord focusedApp = mFocusedApp;
- ProtoLog.v(WM_DEBUG_FOCUS, "Looking for focus: %s, flags=%d, canReceive=%b",
- w, w.mAttrs.flags, w.canReceiveKeys());
+ ProtoLog.v(WM_DEBUG_FOCUS, "Looking for focus: %s, flags=%d, canReceive=%b, reason=%s",
+ w, w.mAttrs.flags, w.canReceiveKeys(),
+ w.canReceiveKeysReason(false /* fromUserTouch */));
if (!w.canReceiveKeys()) {
return false;
@@ -3072,7 +3071,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
*/
WindowState findFocusedWindowIfNeeded(int topFocusedDisplayId) {
return (mWmService.mPerDisplayFocusEnabled || topFocusedDisplayId == INVALID_DISPLAY)
- ? findFocusedWindow() : null;
+ ? findFocusedWindow() : null;
}
WindowState findFocusedWindow() {
@@ -3081,7 +3080,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
forAllWindows(mFindFocusedWindow, true /* traverseTopToBottom */);
if (mTmpWindow == null) {
- ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "findFocusedWindow: No focusable windows.");
+ ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "findFocusedWindow: No focusable windows, display=%d",
+ getDisplayId());
return null;
}
return mTmpWindow;
@@ -3116,18 +3116,15 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
&& mode != UPDATE_FOCUS_WILL_PLACE_SURFACES) {
assignWindowLayers(false /* setLayoutNeeded */);
}
- }
- if (imWindowChanged) {
- mWmService.mWindowsChanged = true;
- setLayoutNeeded();
- newFocus = findFocusedWindowIfNeeded(topFocusedDisplayId);
- }
- if (mCurrentFocus != newFocus) {
- mWmService.mH.obtainMessage(REPORT_FOCUS_CHANGE, this).sendToTarget();
+ if (imWindowChanged) {
+ mWmService.mWindowsChanged = true;
+ setLayoutNeeded();
+ newFocus = findFocusedWindowIfNeeded(topFocusedDisplayId);
+ }
}
- ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "Changing focus from %s to %s displayId=%d Callers=%s",
+ ProtoLog.d(WM_DEBUG_FOCUS_LIGHT, "Changing focus from %s to %s displayId=%d Callers=%s",
mCurrentFocus, newFocus, getDisplayId(), Debug.getCallers(4));
final WindowState oldFocus = mCurrentFocus;
mCurrentFocus = newFocus;
@@ -3185,9 +3182,25 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
}
+
+ // Notify the accessibility manager for the change so it has the windows before the newly
+ // focused one starts firing events.
+ // TODO(b/151179149) investigate what info accessibility service needs before input can
+ // dispatch focus to clients.
+ if (mWmService.mAccessibilityController != null) {
+ mWmService.mH.sendMessage(PooledLambda.obtainMessage(
+ this::updateAccessibilityOnWindowFocusChanged,
+ mWmService.mAccessibilityController));
+ }
+
+ mLastFocus = mCurrentFocus;
return true;
}
+ void updateAccessibilityOnWindowFocusChanged(AccessibilityController accessibilityController) {
+ accessibilityController.onWindowFocusChangedNotLocked(getDisplayId());
+ }
+
private static void onWindowFocusChanged(WindowState oldFocus, WindowState newFocus) {
final Task focusedTask = newFocus != null ? newFocus.getTask() : null;
final Task unfocusedTask = oldFocus != null ? oldFocus.getTask() : null;
@@ -3219,6 +3232,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
if (mFocusedApp == newFocus) {
return false;
}
+ ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "setFocusedApp %s displayId=%d Callers=%s",
+ newFocus, getDisplayId(), Debug.getCallers(4));
mFocusedApp = newFocus;
getInputMonitor().setFocusedAppLw(newFocus);
updateTouchExcludeRegion();
@@ -4708,7 +4723,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
// Traverse all windows top down to assemble the gesture exclusion rects.
// For each window, we only take the rects that fall within its touchable region.
forAllWindows(w -> {
- if (w.cantReceiveTouchInput() || !w.isVisible()
+ if (!w.canReceiveTouchInput() || !w.isVisible()
|| (w.getAttrs().flags & FLAG_NOT_TOUCHABLE) != 0
|| unhandled.isEmpty()) {
return;
@@ -5225,30 +5240,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
&& (mAtmService.mRunningVoice == null);
}
- void setFocusedApp(ActivityRecord r, boolean moveFocusNow) {
- final ActivityRecord newFocus;
- final IBinder token = r.appToken;
- if (token == null) {
- ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "Clearing focused app, displayId=%d",
- mDisplayId);
- newFocus = null;
- } else {
- newFocus = mWmService.mRoot.getActivityRecord(token);
- if (newFocus == null) {
- Slog.w(TAG_WM, "Attempted to set focus to non-existing app token: " + token
- + ", displayId=" + mDisplayId);
- }
- ProtoLog.v(WM_DEBUG_FOCUS_LIGHT,
- "Set focused app to: %s moveFocusNow=%b displayId=%d", newFocus,
- moveFocusNow, mDisplayId);
- }
-
- final boolean changed = setFocusedApp(newFocus);
- if (moveFocusNow && changed) {
- mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
- true /*updateInputWindows*/);
- }
- }
void ensureActivitiesVisible(ActivityRecord starting, int configChanges,
boolean preserveWindows, boolean notifyClients) {
diff --git a/services/core/java/com/android/server/wm/DragDropController.java b/services/core/java/com/android/server/wm/DragDropController.java
index 999aab982816..ec62ed44c640 100644
--- a/services/core/java/com/android/server/wm/DragDropController.java
+++ b/services/core/java/com/android/server/wm/DragDropController.java
@@ -114,7 +114,7 @@ class DragDropController {
final WindowState callingWin = mService.windowForClientLocked(
null, window, false);
- if (callingWin == null || callingWin.cantReceiveTouchInput()) {
+ if (callingWin == null || !callingWin.canReceiveTouchInput()) {
Slog.w(TAG_WM, "Bad requesting window " + window);
return null; // !!! TODO: throw here?
}
diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java
index e166bfc08ad4..0978636ea502 100644
--- a/services/core/java/com/android/server/wm/InputManagerCallback.java
+++ b/services/core/java/com/android/server/wm/InputManagerCallback.java
@@ -24,6 +24,7 @@ import android.view.InputApplicationHandle;
import android.view.KeyEvent;
import android.view.WindowManager;
+import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.am.ActivityManagerService;
import com.android.server.input.InputManagerService;
import com.android.server.wm.EmbeddedWindowController.EmbeddedWindow;
@@ -252,7 +253,7 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal
// All the calls below need to happen without the WM lock held since they call into AM.
mService.mAtmInternal.saveANRState(reason);
- if (activity != null && activity.appToken != null) {
+ if (activity != null) {
// Notify the activity manager about the timeout and let it decide whether
// to abort dispatching or keep waiting.
final boolean abort = activity.keyDispatchingTimedOut(reason, windowPid);
@@ -410,6 +411,8 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal
requestRefreshConfiguration = dispatchPointerCaptureChanged(focusedWindow, false);
}
mFocusedWindow.set(newFocusedWindow);
+ mService.mH.sendMessage(PooledLambda.obtainMessage(mService::reportFocusChanged,
+ oldToken, newToken));
return requestRefreshConfiguration;
}
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index fb511e032c98..4efd687b7bb4 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -370,7 +370,8 @@ final class InputMonitor {
* Layer assignment is assumed to be complete by the time this is called.
*/
public void setInputFocusLw(WindowState newWindow, boolean updateInputWindows) {
- ProtoLog.d(WM_DEBUG_FOCUS_LIGHT, "Input focus has changed to %s", newWindow);
+ ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "Input focus has changed to %s display=%d",
+ newWindow, mDisplayId);
if (newWindow != mInputFocus) {
if (newWindow != null && newWindow.canReceiveKeys()) {
@@ -493,7 +494,7 @@ final class InputMonitor {
final int type = w.mAttrs.type;
final boolean isVisible = w.isVisibleLw();
if (inputChannel == null || inputWindowHandle == null || w.mRemoved
- || (w.cantReceiveTouchInput() && !shouldApplyRecentsInputConsumer)) {
+ || (!w.canReceiveTouchInput() && !shouldApplyRecentsInputConsumer)) {
if (w.mWinAnimator.hasSurface()) {
// Assign an InputInfo with type to the overlay window which can't receive input
// event. This is used to omit Surfaces from occlusion detection.
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 21e30ce0a495..f9e6270aec5d 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -40,7 +40,6 @@ import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_NONE;
import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY;
import static android.view.WindowManager.TRANSIT_TASK_TO_BACK;
-
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS_LIGHT;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_KEEP_SCREEN_ON;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
@@ -90,7 +89,6 @@ import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREEN
import static com.android.server.wm.WindowSurfacePlacer.SET_ORIENTATION_CHANGE_COMPLETE;
import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
-
import static java.lang.Integer.MAX_VALUE;
import android.annotation.IntDef;
@@ -129,6 +127,7 @@ import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.provider.Settings;
import android.service.voice.IVoiceInteractionSession;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.IntArray;
@@ -162,7 +161,6 @@ import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.Set;
@@ -214,7 +212,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
private int mTopFocusedDisplayId = INVALID_DISPLAY;
// Map from the PID to the top most app which has a focused window of the process.
- final HashMap<Integer, ActivityRecord> mTopFocusedAppByProcess = new HashMap<>();
+ final ArrayMap<Integer, ActivityRecord> mTopFocusedAppByProcess = new ArrayMap<>();
// Only a separate transaction until we separate the apply surface changes
// transaction from the global transaction.
@@ -480,8 +478,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
mTopFocusedDisplayId = topFocusedDisplayId;
mWmService.mInputManager.setFocusedDisplay(topFocusedDisplayId);
mWmService.mPolicy.setTopFocusedDisplay(topFocusedDisplayId);
- ProtoLog.v(WM_DEBUG_FOCUS_LIGHT, "New topFocusedDisplayId=%d",
- topFocusedDisplayId);
+ ProtoLog.d(WM_DEBUG_FOCUS_LIGHT, "New topFocusedDisplayId=%d", topFocusedDisplayId);
}
return changed;
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c45ccb6e17e3..19179a808d7c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -376,8 +376,11 @@ public class WindowManagerService extends IWindowManager.Stub
private static final String BOOT_ANIMATION_SERVICE = "bootanim";
static final int UPDATE_FOCUS_NORMAL = 0;
+ /** Caller will assign layers */
static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
+ /** Caller is performing surface placement */
static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
+ /** Caller will performSurfacePlacement */
static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
/** Indicates we are removing the focused window when updating the focus. */
static final int UPDATE_FOCUS_REMOVING_FOCUS = 4;
@@ -4730,12 +4733,30 @@ public class WindowManagerService extends IWindowManager.Stub
return false;
}
+ void reportFocusChanged(IBinder oldToken, IBinder newToken) {
+ WindowState lastFocus;
+ WindowState newFocus;
+ synchronized (mGlobalLock) {
+ lastFocus = mInputToWindowMap.get(oldToken);
+ newFocus = mInputToWindowMap.get(newToken);
+ ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Focus changing: %s -> %s", lastFocus, newFocus);
+ }
+
+ if (newFocus != null) {
+ newFocus.reportFocusChangedSerialized(true);
+ notifyFocusChanged();
+ }
+
+ if (lastFocus != null) {
+ lastFocus.reportFocusChangedSerialized(false);
+ }
+ }
+
// -------------------------------------------------------------
// Async Handler
// -------------------------------------------------------------
final class H extends android.os.Handler {
- public static final int REPORT_FOCUS_CHANGE = 2;
public static final int WINDOW_FREEZE_TIMEOUT = 11;
public static final int PERSIST_ANIMATION_SCALE = 14;
@@ -4788,50 +4809,6 @@ public class WindowManagerService extends IWindowManager.Stub
Slog.v(TAG_WM, "handleMessage: entry what=" + msg.what);
}
switch (msg.what) {
- case REPORT_FOCUS_CHANGE: {
- final DisplayContent displayContent = (DisplayContent) msg.obj;
- WindowState lastFocus;
- WindowState newFocus;
-
- AccessibilityController accessibilityController = null;
-
- synchronized (mGlobalLock) {
- if (mAccessibilityController != null) {
- accessibilityController = mAccessibilityController;
- }
-
- lastFocus = displayContent.mLastFocus;
- newFocus = displayContent.mCurrentFocus;
- if (lastFocus == newFocus) {
- // Focus is not changing, so nothing to do.
- return;
- }
- displayContent.mLastFocus = newFocus;
- ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Focus moving from %s"
- + " to %s displayId=%d", lastFocus, newFocus,
- displayContent.getDisplayId());
- }
-
- // First notify the accessibility manager for the change so it has
- // the windows before the newly focused one starts firing events.
- if (accessibilityController != null) {
- accessibilityController.onWindowFocusChangedNotLocked(
- displayContent.getDisplayId());
- }
-
- if (newFocus != null) {
- ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Gaining focus: %s", newFocus);
- newFocus.reportFocusChangedSerialized(true);
- notifyFocusChanged();
- }
-
- if (lastFocus != null) {
- ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "Losing focus: %s", lastFocus);
- lastFocus.reportFocusChangedSerialized(false);
- }
- break;
- }
-
case WINDOW_FREEZE_TIMEOUT: {
final DisplayContent displayContent = (DisplayContent) msg.obj;
synchronized (mGlobalLock) {
@@ -7994,6 +7971,8 @@ public class WindowManagerService extends IWindowManager.Stub
return;
}
+ ProtoLog.i(WM_DEBUG_FOCUS_LIGHT, "onPointerDownOutsideFocusLocked called on %s",
+ touchedWindow);
final DisplayContent displayContent = touchedWindow.getDisplayContent();
if (!displayContent.isOnTop()) {
displayContent.getParent().positionChildAt(WindowContainer.POSITION_TOP, displayContent,
@@ -8022,10 +8001,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- try {
- mActivityTaskManager.setFocusedTask(task.mTaskId);
- } catch (RemoteException e) {
- }
+ mAtmService.setFocusedTask(task.mTaskId);
}
/**
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 9ff33b18cb89..84a9c750d2d3 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2884,12 +2884,25 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return canReceiveKeys(false /* fromUserTouch */);
}
+ public String canReceiveKeysReason(boolean fromUserTouch) {
+ return "fromTouch= " + fromUserTouch
+ + " isVisibleOrAdding=" + isVisibleOrAdding()
+ + " mViewVisibility=" + mViewVisibility
+ + " mRemoveOnExit=" + mRemoveOnExit
+ + " flags=" + mAttrs.flags
+ + " appWindowsAreFocusable="
+ + (mActivityRecord == null || mActivityRecord.windowsAreFocusable(fromUserTouch))
+ + " canReceiveTouchInput=" + canReceiveTouchInput()
+ + " displayIsOnTop=" + getDisplayContent().isOnTop()
+ + " displayIsTrusted=" + getDisplayContent().isTrusted();
+ }
+
public boolean canReceiveKeys(boolean fromUserTouch) {
final boolean canReceiveKeys = isVisibleOrAdding()
&& (mViewVisibility == View.VISIBLE) && !mRemoveOnExit
&& ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0)
&& (mActivityRecord == null || mActivityRecord.windowsAreFocusable(fromUserTouch))
- && !cantReceiveTouchInput();
+ && canReceiveTouchInput();
if (!canReceiveKeys) {
return false;
}
@@ -2907,15 +2920,18 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return showBecauseOfActivity || showBecauseOfWindow;
}
- /** @return {@code false} if this window desires touch events. */
- boolean cantReceiveTouchInput() {
- if (mActivityRecord == null || mActivityRecord.getTask() == null) {
- return false;
+ /**
+ * @return {@code true} if this window can receive touches based on among other things,
+ * windowing state and recents animation state.
+ **/
+ boolean canReceiveTouchInput() {
+ if (mActivityRecord == null || mActivityRecord.getTask() == null) {
+ return true;
}
- return mActivityRecord.getTask().getRootTask().shouldIgnoreInput()
- || !mActivityRecord.mVisibleRequested
- || isRecentsAnimationConsumingAppInput();
+ return !mActivityRecord.getTask().getRootTask().shouldIgnoreInput()
+ && mActivityRecord.mVisibleRequested
+ && !isRecentsAnimationConsumingAppInput();
}
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 9603d28c286b..3106ca26c8a1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -661,14 +661,14 @@ public class WindowStateTests extends WindowTestsBase {
RecentsAnimationController recentsController = mock(RecentsAnimationController.class);
when(recentsController.shouldApplyInputConsumer(win0.mActivityRecord)).thenReturn(true);
mWm.setRecentsAnimationController(recentsController);
- assertTrue(win0.cantReceiveTouchInput());
+ assertFalse(win0.canReceiveTouchInput());
}
@Test
public void testCantReceiveTouchWhenAppTokenHiddenRequested() {
final WindowState win0 = createWindow(null, TYPE_APPLICATION, "win0");
win0.mActivityRecord.mVisibleRequested = false;
- assertTrue(win0.cantReceiveTouchInput());
+ assertFalse(win0.canReceiveTouchInput());
}
@Test
@@ -676,7 +676,7 @@ public class WindowStateTests extends WindowTestsBase {
final WindowState win0 = createWindow(null, TYPE_APPLICATION, "win0");
win0.mActivityRecord.getStack().setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
win0.mActivityRecord.getStack().setFocusable(false);
- assertTrue(win0.cantReceiveTouchInput());
+ assertFalse(win0.canReceiveTouchInput());
}
@UseTestDisplay(addWindows = W_ACTIVITY)