Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f406aedc authored by Orhan Uysal's avatar Orhan Uysal
Browse files

Add slight delay to touch outside for multiwindow

Similar to ag/28169421, add a delay so that when a back gesture swipe
detected we don't rapidly change focus to freeform window at the back.

Fix: 359349899
Test: Presubmit and manual
Flag: EXEMPT Bugfix
Change-Id: I1ef354b59a1a2e31dd36fa0171a3806a36ea21df
parent fc53eaec
Loading
Loading
Loading
Loading
+29 −8
Original line number Original line Diff line number Diff line
@@ -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.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
import static android.app.StatusBarManager.DISABLE_MASK;
import static android.app.StatusBarManager.DISABLE_MASK;
import static android.app.WindowConfiguration.ROTATION_UNDEFINED;
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.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_FREEFORM_WINDOW_MANAGEMENT;
import static android.content.pm.PackageManager.FEATURE_PC;
import static android.content.pm.PackageManager.FEATURE_PC;
@@ -9024,14 +9025,7 @@ public class WindowManagerService extends IWindowManager.Stub
        }
        }
        clearPointerDownOutsideFocusRunnable();
        clearPointerDownOutsideFocusRunnable();


        // For embedded activity that is showing side-by-side with another activity, delay
        if (shouldDelayTouchOutside(t)) {
        // 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) {
            mPointerDownOutsideFocusRunnable = () -> handlePointerDownOutsideFocus(t);
            mPointerDownOutsideFocusRunnable = () -> handlePointerDownOutsideFocus(t);
            mH.postDelayed(mPointerDownOutsideFocusRunnable, POINTER_DOWN_OUTSIDE_FOCUS_TIMEOUT_MS);
            mH.postDelayed(mPointerDownOutsideFocusRunnable, POINTER_DOWN_OUTSIDE_FOCUS_TIMEOUT_MS);
        } else if (!fromHandler) {
        } 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) {
    private void handlePointerDownOutsideFocus(InputTarget t) {
        synchronized (mGlobalLock) {
        synchronized (mGlobalLock) {
            if (mPointerDownOutsideFocusRunnable != null
            if (mPointerDownOutsideFocusRunnable != null