Loading core/java/android/window/BackNavigationInfo.java +16 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; /** Loading Loading @@ -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. Loading core/java/android/window/flags/windowing_frontend.aconfig +11 −0 Original line number Diff line number Diff line Loading @@ -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 libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +10 −0 Original line number Diff line number Diff line Loading @@ -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) Loading services/core/java/com/android/server/wm/BackNavigationController.java +36 −2 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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()) Loading @@ -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, " Loading Loading @@ -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. */ Loading services/core/java/com/android/server/wm/EmbeddedWindowController.java +33 −3 Original line number Diff line number Diff line Loading @@ -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. * Loading Loading @@ -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) { Loading Loading @@ -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, Loading @@ -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 { Loading Loading @@ -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 Loading Loading
core/java/android/window/BackNavigationInfo.java +16 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; /** Loading Loading @@ -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. Loading
core/java/android/window/flags/windowing_frontend.aconfig +11 −0 Original line number Diff line number Diff line Loading @@ -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
libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationController.java +10 −0 Original line number Diff line number Diff line Loading @@ -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) Loading
services/core/java/com/android/server/wm/BackNavigationController.java +36 −2 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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()) Loading @@ -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, " Loading Loading @@ -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. */ Loading
services/core/java/com/android/server/wm/EmbeddedWindowController.java +33 −3 Original line number Diff line number Diff line Loading @@ -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. * Loading Loading @@ -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) { Loading Loading @@ -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, Loading @@ -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 { Loading Loading @@ -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 Loading