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

Commit 428aef40 authored by Wei Sheng Shih's avatar Wei Sheng Shih Committed by Android (Google) Code Review
Browse files

Merge "Pilfer pointers when touch gesture transferred to embedded." into main

parents 63473a23 b7a11da4
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -87,6 +87,13 @@ public final class BackNavigationInfo implements Parcelable {
     */
    public static final String KEY_GESTURE_FINISHED = "GestureFinished";

    /**
     * Touch gestured has transferred to embedded window, Shell should pilfer pointers so the
     * embedded won't receive motion events.
     * @hide
     */
    public static final String KEY_TOUCH_GESTURE_TRANSFERRED = "TouchGestureTransferred";


    /**
     * Defines the type of back destinations a back even can lead to. This is used to define the
@@ -119,7 +126,7 @@ public final class BackNavigationInfo implements Parcelable {
    @NonNull
    private final Rect mTouchableRegion;

    private final boolean mAppProgressGenerationAllowed;
    private boolean mAppProgressGenerationAllowed;
    private final int mFocusedTaskId;

    /**
@@ -252,6 +259,14 @@ public final class BackNavigationInfo implements Parcelable {
        return mFocusedTaskId;
    }

    /**
     * Force disable app to intercept back progress event.
     * @hide
     */
    public void disableAppProgressGenerationAllowed() {
        mAppProgressGenerationAllowed = false;
    }

    /**
     * Callback to be called when the back preview is finished in order to notify the server that
     * it can clean up the resources created for the animation.
+11 −0
Original line number Diff line number Diff line
@@ -348,3 +348,14 @@ flag {
  bug: "372230928"
  is_fixed_read_only: true
}

flag {
  name: "disallow_app_progress_embedded_window"
  namespace: "windowing_frontend"
  description: "Pilfer pointers when app transfer input gesture to embedded window."
  bug: "365504126"
  is_fixed_read_only: true
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}
 No newline at end of file
+10 −0
Original line number Diff line number Diff line
@@ -191,6 +191,16 @@ public class BackAnimationController implements RemoteCallable<BackAnimationCont
                @Override
                public void onResult(@Nullable Bundle result) {
                    mShellExecutor.execute(() -> {
                        if (mBackGestureStarted && result != null && result.getBoolean(
                                BackNavigationInfo.KEY_TOUCH_GESTURE_TRANSFERRED)) {
                            // Host app won't able to process motion event anymore, so pilfer
                            // pointers anyway.
                            if (mBackNavigationInfo != null) {
                                mBackNavigationInfo.disableAppProgressGenerationAllowed();
                            }
                            tryPilferPointers();
                            return;
                        }
                        if (!mBackGestureStarted || mPostCommitAnimationInProgress) {
                            // If an uninterruptible animation is already in progress, we should
                            // ignore this due to it may cause focus lost. (alpha = 0)
+36 −2
Original line number Diff line number Diff line
@@ -107,6 +107,12 @@ class BackNavigationController {
        mNavigationMonitor.onFocusWindowChanged(newFocus);
    }

    void onEmbeddedWindowGestureTransferred(@NonNull WindowState host) {
        if (Flags.disallowAppProgressEmbeddedWindow()) {
            mNavigationMonitor.onEmbeddedWindowGestureTransferred(host);
        }
    }

    /**
     * Set up the necessary leashes and build a {@link BackNavigationInfo} instance for an upcoming
     * back gesture animation.
@@ -178,6 +184,9 @@ class BackNavigationController {
                return null;
            }

            final ArrayList<EmbeddedWindowController.EmbeddedWindow> embeddedWindows = wmService
                    .mEmbeddedWindowController.getByHostWindow(window);

            currentActivity = window.mActivityRecord;
            currentTask = window.getTask();
            if ((currentTask != null && !currentTask.isVisibleRequested())
@@ -199,11 +208,22 @@ class BackNavigationController {
            infoBuilder.setOnBackInvokedCallback(callbackInfo.getCallback());
            infoBuilder.setAnimationCallback(callbackInfo.isAnimationCallback());
            infoBuilder.setTouchableRegion(window.getFrame());
            infoBuilder.setAppProgressAllowed((window.getAttrs().privateFlags
                    & PRIVATE_FLAG_APP_PROGRESS_GENERATION_ALLOWED) != 0);
            if (currentTask != null) {
                infoBuilder.setFocusedTaskId(currentTask.mTaskId);
            }
            boolean transferGestureToEmbedded = false;
            if (Flags.disallowAppProgressEmbeddedWindow() && embeddedWindows != null) {
                for (int i = embeddedWindows.size() - 1; i >= 0; --i) {
                    if (embeddedWindows.get(i).mGestureToEmbedded) {
                        transferGestureToEmbedded = true;
                        break;
                    }
                }
            }
            final boolean canInterruptInView = (window.getAttrs().privateFlags
                    & PRIVATE_FLAG_APP_PROGRESS_GENERATION_ALLOWED) != 0;
            infoBuilder.setAppProgressAllowed(canInterruptInView && !transferGestureToEmbedded
                    && callbackInfo.isAnimationCallback());
            mNavigationMonitor.startMonitor(window, navigationObserver);

            ProtoLog.d(WM_DEBUG_BACK_PREVIEW, "startBackNavigation currentTask=%s, "
@@ -741,6 +761,20 @@ class BackNavigationController {
            }
        }

        /**
         * Notify focus window has transferred touch gesture to embedded window. Shell should pilfer
         * pointers so embedded process won't receive motion event.
         *
         */
        void onEmbeddedWindowGestureTransferred(@NonNull WindowState host) {
            if (!isMonitorForRemote() || host != mNavigatingWindow) {
                return;
            }
            final Bundle result = new Bundle();
            result.putBoolean(BackNavigationInfo.KEY_TOUCH_GESTURE_TRANSFERRED, true);
            mObserver.sendResult(result);
        }

        /**
         * Notify an unexpected transition has happened during back navigation.
         */
+33 −3
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@ import android.window.InputTransferToken;
import com.android.internal.protolog.ProtoLog;
import com.android.server.input.InputManagerService;

import java.util.ArrayList;

/**
 * Keeps track of embedded windows.
 *
@@ -146,6 +148,20 @@ class EmbeddedWindowController {
        return mWindowsByWindowToken.get(windowToken);
    }

    @Nullable ArrayList<EmbeddedWindow> getByHostWindow(WindowState host) {
        ArrayList<EmbeddedWindow> windows = null;
        for (int i = mWindows.size() - 1; i >= 0; i--) {
            final EmbeddedWindow ew = mWindows.valueAt(i);
            if (ew.mHostWindowState == host) {
                if (windows == null) {
                    windows = new ArrayList<>();
                }
                windows.add(ew);
            }
        }
        return windows;
    }

    private boolean isValidTouchGestureParams(WindowState hostWindowState,
            EmbeddedWindow embeddedWindow) {
        if (embeddedWindow == null) {
@@ -191,8 +207,12 @@ class EmbeddedWindowController {
            throw new SecurityException(
                    "Transfer request must originate from owner of transferFromToken");
        }
        return mInputManagerService.transferTouchGesture(ew.getInputChannelToken(),
                transferToHostWindowState.mInputChannelToken);
        final boolean didTransfer = mInputManagerService.transferTouchGesture(
                ew.getInputChannelToken(), transferToHostWindowState.mInputChannelToken);
        if (didTransfer) {
            ew.mGestureToEmbedded = false;
        }
        return didTransfer;
    }

    boolean transferToEmbedded(int callingUid, WindowState hostWindowState,
@@ -205,8 +225,15 @@ class EmbeddedWindowController {
            throw new SecurityException(
                    "Transfer request must originate from owner of transferFromToken");
        }
        return mInputManagerService.transferTouchGesture(hostWindowState.mInputChannelToken,
        final boolean didTransfer = mInputManagerService.transferTouchGesture(
                hostWindowState.mInputChannelToken,
                ew.getInputChannelToken());
        if (didTransfer) {
            ew.mGestureToEmbedded = true;
            mAtmService.mBackNavigationController.onEmbeddedWindowGestureTransferred(
                    hostWindowState);
        }
        return didTransfer;
    }

    static class EmbeddedWindow implements InputTarget {
@@ -235,6 +262,9 @@ class EmbeddedWindowController {
        // the host window.
        private @WindowInsets.Type.InsetsType int mRequestedVisibleTypes = 0;

        /** Whether the gesture is transferred to embedded window. */
        boolean mGestureToEmbedded = false;

        /**
         * @param session  calling session to check ownership of the window
         * @param clientToken client token used to clean up the map if the embedding process dies