diff options
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) |