diff options
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowManagerService.java | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index bdb1d43faf79..87c0084083be 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -32,6 +32,7 @@ import static android.app.ActivityManagerInternal.ALLOW_NON_FULL; import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW; import static android.app.StatusBarManager.DISABLE_MASK; import static android.app.WindowConfiguration.ROTATION_UNDEFINED; +import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED; import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT; import static android.content.pm.PackageManager.FEATURE_PC; @@ -9024,14 +9025,7 @@ public class WindowManagerService extends IWindowManager.Stub } clearPointerDownOutsideFocusRunnable(); - // For embedded activity that is showing side-by-side with another activity, delay - // handling the touch-outside event to prevent focus rapid changes back-n-forth. - // Otherwise, handle the touch-outside event directly. - final WindowState w = t.getWindowState(); - final ActivityRecord activity = w != null ? w.getActivityRecord() : null; - if (mFocusedInputTarget != t && mFocusedInputTarget != null - && activity != null && activity.isEmbedded() - && activity.getTaskFragment().getAdjacentTaskFragment() != null) { + if (shouldDelayTouchOutside(t)) { mPointerDownOutsideFocusRunnable = () -> handlePointerDownOutsideFocus(t); mH.postDelayed(mPointerDownOutsideFocusRunnable, POINTER_DOWN_OUTSIDE_FOCUS_TIMEOUT_MS); } else if (!fromHandler) { @@ -9044,6 +9038,33 @@ public class WindowManagerService extends IWindowManager.Stub } } + private boolean shouldDelayTouchOutside(InputTarget t) { + final WindowState w = t.getWindowState(); + final ActivityRecord activity = w != null ? w.getActivityRecord() : null; + final Task task = w != null ? w.getRootTask() : null; + + final boolean isInputTargetNotFocused = + mFocusedInputTarget != t && mFocusedInputTarget != null; + if (!isInputTargetNotFocused) { + return false; + } + + // For embedded activity that is showing side-by-side with another activity, delay + // handling the touch-outside event to prevent focus rapid changes back-n-forth. + final boolean shouldDelayTouchForEmbeddedActivity = activity != null + && activity.isEmbedded() + && activity.getTaskFragment().getAdjacentTaskFragment() != null; + + // For cases when there are multiple freeform windows where non-top windows are blocking + // the gesture zones, delay handling the touch-outside event to prevent refocusing the + // the non-top windows during the gesture. + final boolean shouldDelayTouchForFreeform = + task != null && task.getWindowingMode() == WINDOWING_MODE_FREEFORM; + + // If non of the above cases are true, handle the touch-outside event directly. + return shouldDelayTouchForEmbeddedActivity || shouldDelayTouchForFreeform; + } + private void handlePointerDownOutsideFocus(InputTarget t) { synchronized (mGlobalLock) { if (mPointerDownOutsideFocusRunnable != null |