summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vishnu Nair <vishnun@google.com> 2020-08-15 15:03:46 -0700
committer Vishnu Nair <vishnun@google.com> 2020-08-26 10:30:39 -0700
commit904ea677246eafc20a44537eb81a99bbcc0acc17 (patch)
tree96467725271c0cb56d3c9b0b31663d9062cb7198
parentb0e58545c11ee1ad5b5277428ebb0f98069f0318 (diff)
Misc clean up before requesting focus via setFocusedWindow api
Replace focus changed callback to use the callback from InputDispatcher. Currently the system posts a message and informs accessibility services, window focus observers and window change listeners. With the exception of accessibility service (which requires to be notified before the client gets notified), the other callbacks should be synchronized with the callback from InputDispatcher. This change also cleans up null checks for ActivityRecord#appToken since it cannot be null. Test: presubmit Bug: 151179149 Change-Id: Id79553835048c090505589d62dee9cb8f38f23ff
-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)