From 2554fe325afb40f42905edeb30b02fc8c28a47e5 Mon Sep 17 00:00:00 2001 From: Jorge Gil Date: Thu, 24 Aug 2023 20:33:07 +0000 Subject: Reland "Dismiss freeform tasks occluding keyguard in folded transitions" This change is an enhacement of Idac9e012d25c50b73eba8afe9088d77043c68a85 where the "dismiss freeform" behavior when a task occludes the Keyguard was moved from WM Core to WM Shell. That changed looked for transitions requested with transit type OCCLUDE_KEYGUARD as a signal to change windowing mode to fullscreen. However, it didn't cover the cases where a transition is already collecting such as opening a showWhenLocked activity directly into freeform mode over the keyguard, which ends up being of transit type OPEN. To cover cases like that, two changes are made: 1) Add the transition flags to TransitionRequestInfo and use the flags to check whether there's an occluding task that needs to be dismissed. This should cover cases where the transit type is not KEYGUARD_OCCLUDE but the keyguard visibility change happens early enough that the flag is added to the collecting transition before the transition request is sent to Shell. 2) Add the dismiss behavior to the finish WCT in KeyguardTransitionHandler to cover cases where the keyguard visibility update happens after the transition request has already been sent to Shell but before the transition is ready. Bug: 261765739 Bug: 293219242 Change-Id: Id614b5a103b6eed510ff72dd2226740a1967d101 Test: atest ActivityVisibilityTests --- .../java/android/window/TransitionRequestInfo.java | 52 ++++++++++++++++------ .../shell/keyguard/KeyguardTransitionHandler.java | 32 ++++++++++++- .../android/wm/shell/transition/Transitions.java | 5 ++- .../shell/unfold/UnfoldTransitionHandlerTest.java | 6 +-- .../android/server/wm/TransitionController.java | 2 +- 5 files changed, 78 insertions(+), 19 deletions(-) diff --git a/core/java/android/window/TransitionRequestInfo.java b/core/java/android/window/TransitionRequestInfo.java index 14046945ede0..edea2978c340 100644 --- a/core/java/android/window/TransitionRequestInfo.java +++ b/core/java/android/window/TransitionRequestInfo.java @@ -16,8 +16,6 @@ package android.window; -import static android.view.WindowManager.transitTypeToString; - import android.annotation.Nullable; import android.app.ActivityManager; import android.app.WindowConfiguration; @@ -51,14 +49,26 @@ public final class TransitionRequestInfo implements Parcelable { * The reliable parts should be flags, rotation start/end (if rotating), and start/end bounds * (if size is changing). */ - private @Nullable DisplayChange mDisplayChange; + private @Nullable TransitionRequestInfo.DisplayChange mDisplayChange; + + /** The transition flags known at the time of the request. These may not be complete. */ + private final int mFlags; /** constructor override */ public TransitionRequestInfo( @WindowManager.TransitionType int type, @Nullable ActivityManager.RunningTaskInfo triggerTask, @Nullable RemoteTransition remoteTransition) { - this(type, triggerTask, remoteTransition, null /* displayChange */); + this(type, triggerTask, remoteTransition, null /* displayChange */, 0 /* flags */); + } + + /** constructor override */ + public TransitionRequestInfo( + @WindowManager.TransitionType int type, + @Nullable ActivityManager.RunningTaskInfo triggerTask, + @Nullable RemoteTransition remoteTransition, + int flags) { + this(type, triggerTask, remoteTransition, null /* displayChange */, flags); } /** Requested change to a display. */ @@ -236,7 +246,7 @@ public final class TransitionRequestInfo implements Parcelable { }; @DataClass.Generated( - time = 1648141181315L, + time = 1691627678294L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/window/TransitionRequestInfo.java", inputSignatures = "private final int mDisplayId\nprivate @android.annotation.Nullable android.graphics.Rect mStartAbsBounds\nprivate @android.annotation.Nullable android.graphics.Rect mEndAbsBounds\nprivate int mStartRotation\nprivate int mEndRotation\nprivate boolean mPhysicalDisplayChanged\nclass DisplayChange extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genSetters=true, genBuilder=false, genConstructor=false)") @@ -279,19 +289,23 @@ public final class TransitionRequestInfo implements Parcelable { * If non-null, this request was triggered by this display change. This will not be complete: * The reliable parts should be flags, rotation start/end (if rotating), and start/end bounds * (if size is changing). + * @param flags + * The transition flags known at the time of the request. These may not be complete. */ @DataClass.Generated.Member public TransitionRequestInfo( @WindowManager.TransitionType int type, @Nullable ActivityManager.RunningTaskInfo triggerTask, @Nullable RemoteTransition remoteTransition, - @Nullable DisplayChange displayChange) { + @Nullable TransitionRequestInfo.DisplayChange displayChange, + int flags) { this.mType = type; com.android.internal.util.AnnotationValidations.validate( WindowManager.TransitionType.class, null, mType); this.mTriggerTask = triggerTask; this.mRemoteTransition = remoteTransition; this.mDisplayChange = displayChange; + this.mFlags = flags; // onConstructed(); // You can define this method to get a callback } @@ -327,10 +341,18 @@ public final class TransitionRequestInfo implements Parcelable { * (if size is changing). */ @DataClass.Generated.Member - public @Nullable DisplayChange getDisplayChange() { + public @Nullable TransitionRequestInfo.DisplayChange getDisplayChange() { return mDisplayChange; } + /** + * The transition flags known at the time of the request. These may not be complete. + */ + @DataClass.Generated.Member + public int getFlags() { + return mFlags; + } + /** * If non-null, If non-null, the task containing the activity whose lifecycle change (start or * finish) has caused this transition to occur. @@ -356,7 +378,7 @@ public final class TransitionRequestInfo implements Parcelable { * (if size is changing). */ @DataClass.Generated.Member - public @android.annotation.NonNull TransitionRequestInfo setDisplayChange(@android.annotation.NonNull DisplayChange value) { + public @android.annotation.NonNull TransitionRequestInfo setDisplayChange(@android.annotation.NonNull TransitionRequestInfo.DisplayChange value) { mDisplayChange = value; return this; } @@ -368,10 +390,11 @@ public final class TransitionRequestInfo implements Parcelable { // String fieldNameToString() { ... } return "TransitionRequestInfo { " + - "type = " + transitTypeToString(mType) + ", " + + "type = " + mType + ", " + "triggerTask = " + mTriggerTask + ", " + "remoteTransition = " + mRemoteTransition + ", " + - "displayChange = " + mDisplayChange + + "displayChange = " + mDisplayChange + ", " + + "flags = " + mFlags + " }"; } @@ -390,6 +413,7 @@ public final class TransitionRequestInfo implements Parcelable { if (mTriggerTask != null) dest.writeTypedObject(mTriggerTask, flags); if (mRemoteTransition != null) dest.writeTypedObject(mRemoteTransition, flags); if (mDisplayChange != null) dest.writeTypedObject(mDisplayChange, flags); + dest.writeInt(mFlags); } @Override @@ -407,7 +431,8 @@ public final class TransitionRequestInfo implements Parcelable { int type = in.readInt(); ActivityManager.RunningTaskInfo triggerTask = (flg & 0x2) == 0 ? null : (ActivityManager.RunningTaskInfo) in.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR); RemoteTransition remoteTransition = (flg & 0x4) == 0 ? null : (RemoteTransition) in.readTypedObject(RemoteTransition.CREATOR); - DisplayChange displayChange = (flg & 0x8) == 0 ? null : (DisplayChange) in.readTypedObject(DisplayChange.CREATOR); + TransitionRequestInfo.DisplayChange displayChange = (flg & 0x8) == 0 ? null : (TransitionRequestInfo.DisplayChange) in.readTypedObject(TransitionRequestInfo.DisplayChange.CREATOR); + int flags = in.readInt(); this.mType = type; com.android.internal.util.AnnotationValidations.validate( @@ -415,6 +440,7 @@ public final class TransitionRequestInfo implements Parcelable { this.mTriggerTask = triggerTask; this.mRemoteTransition = remoteTransition; this.mDisplayChange = displayChange; + this.mFlags = flags; // onConstructed(); // You can define this method to get a callback } @@ -434,10 +460,10 @@ public final class TransitionRequestInfo implements Parcelable { }; @DataClass.Generated( - time = 1639445520938L, + time = 1691627678327L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/window/TransitionRequestInfo.java", - inputSignatures = "private final @android.view.WindowManager.TransitionType int mType\nprivate @android.annotation.Nullable android.app.ActivityManager.RunningTaskInfo mTriggerTask\nprivate @android.annotation.Nullable android.window.RemoteTransition mRemoteTransition\nprivate @android.annotation.Nullable android.window.TransitionRequestInfo.DisplayChange mDisplayChange\nclass TransitionRequestInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genSetters=true, genAidl=true)") + inputSignatures = "private final @android.view.WindowManager.TransitionType int mType\nprivate @android.annotation.Nullable android.app.ActivityManager.RunningTaskInfo mTriggerTask\nprivate @android.annotation.Nullable android.window.RemoteTransition mRemoteTransition\nprivate @android.annotation.Nullable android.window.TransitionRequestInfo.DisplayChange mDisplayChange\nprivate final int mFlags\nclass TransitionRequestInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genSetters=true, genAidl=true)") @Deprecated private void __metadata() {} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java index 2ef92adb90f5..13c0ac4bbaa7 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/keyguard/KeyguardTransitionHandler.java @@ -16,7 +16,10 @@ package com.android.wm.shell.keyguard; +import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM; +import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; +import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.WindowManager.KEYGUARD_VISIBILITY_TRANSIT_FLAGS; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_OCCLUDING; @@ -27,6 +30,7 @@ import static com.android.wm.shell.util.TransitionUtil.isOpeningType; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.ActivityManager; import android.os.Binder; import android.os.Handler; import android.os.IBinder; @@ -165,10 +169,16 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler if (sct != null) { finishTransaction.merge(sct); } + final WindowContainerTransaction mergedWct = + new WindowContainerTransaction(); + if (wct != null) { + mergedWct.merge(wct, true); + } + maybeDismissFreeformOccludingKeyguard(mergedWct, info); // Post our finish callback to let startAnimation finish first. mMainExecutor.executeDelayed(() -> { mStartedTransitions.remove(transition); - finishCallback.onTransitionFinished(wct); + finishCallback.onTransitionFinished(mergedWct); }, 0); } }); @@ -260,6 +270,26 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler } } + private void maybeDismissFreeformOccludingKeyguard( + WindowContainerTransaction wct, TransitionInfo info) { + if ((info.getFlags() & TRANSIT_FLAG_KEYGUARD_OCCLUDING) == 0) { + return; + } + // There's a window occluding the Keyguard, find it and if it's in freeform mode, change it + // to fullscreen. + for (int i = 0; i < info.getChanges().size(); i++) { + final TransitionInfo.Change change = info.getChanges().get(i); + final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo(); + if (taskInfo != null && taskInfo.taskId != INVALID_TASK_ID + && taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM + && taskInfo.isFocused && change.getContainer() != null) { + wct.setWindowingMode(change.getContainer(), WINDOWING_MODE_FULLSCREEN); + wct.setBounds(change.getContainer(), null); + return; + } + } + } + private static class FakeFinishCallback extends IRemoteTransitionFinishedCallback.Stub { @Override public void onTransitionFinished( diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java index b4d0a31dc8c1..c74b3f30e52d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java @@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_CLOSE; import static android.view.WindowManager.TRANSIT_FIRST_CUSTOM; +import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_OCCLUDING; import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE; import static android.view.WindowManager.TRANSIT_OPEN; import static android.view.WindowManager.TRANSIT_SLEEP; @@ -1104,7 +1105,9 @@ public class Transitions implements RemoteCallable, } } } - if (request.getType() == TRANSIT_KEYGUARD_OCCLUDE && request.getTriggerTask() != null + final boolean isOccludingKeyguard = request.getType() == TRANSIT_KEYGUARD_OCCLUDE + || ((request.getFlags() & TRANSIT_FLAG_KEYGUARD_OCCLUDING) != 0); + if (isOccludingKeyguard && request.getTriggerTask() != null && request.getTriggerTask().getWindowingMode() == WINDOWING_MODE_FREEFORM) { // This freeform task is on top of keyguard, so its windowing mode should be changed to // fullscreen. diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java index 63a685e0f0e6..1d94c9c31de2 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/unfold/UnfoldTransitionHandlerTest.java @@ -92,7 +92,7 @@ public class UnfoldTransitionHandlerTest { TransitionRequestInfo.DisplayChange displayChange = new TransitionRequestInfo.DisplayChange( Display.DEFAULT_DISPLAY).setPhysicalDisplayChanged(true); TransitionRequestInfo requestInfo = new TransitionRequestInfo(TRANSIT_CHANGE, - triggerTaskInfo, /* remoteTransition= */ null, displayChange); + triggerTaskInfo, /* remoteTransition= */ null, displayChange, 0 /* flags */); WindowContainerTransaction result = mUnfoldTransitionHandler.handleRequest(mTransition, requestInfo); @@ -106,7 +106,7 @@ public class UnfoldTransitionHandlerTest { TransitionRequestInfo.DisplayChange displayChange = new TransitionRequestInfo.DisplayChange( Display.DEFAULT_DISPLAY).setPhysicalDisplayChanged(false); TransitionRequestInfo requestInfo = new TransitionRequestInfo(TRANSIT_CHANGE, - triggerTaskInfo, /* remoteTransition= */ null, displayChange); + triggerTaskInfo, /* remoteTransition= */ null, displayChange, 0 /* flags */); WindowContainerTransaction result = mUnfoldTransitionHandler.handleRequest(mTransition, requestInfo); @@ -212,7 +212,7 @@ public class UnfoldTransitionHandlerTest { TransitionRequestInfo.DisplayChange displayChange = new TransitionRequestInfo.DisplayChange( Display.DEFAULT_DISPLAY).setPhysicalDisplayChanged(true); return new TransitionRequestInfo(TRANSIT_CHANGE, - triggerTaskInfo, /* remoteTransition= */ null, displayChange); + triggerTaskInfo, /* remoteTransition= */ null, displayChange, 0 /* flags */); } private static class TestShellUnfoldProgressProvider implements ShellUnfoldProgressProvider, diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java index 3eabbe763eaf..75458302586d 100644 --- a/services/core/java/com/android/server/wm/TransitionController.java +++ b/services/core/java/com/android/server/wm/TransitionController.java @@ -711,7 +711,7 @@ class TransitionController { startTask.fillTaskInfo(info); } final TransitionRequestInfo request = new TransitionRequestInfo( - transition.mType, info, remoteTransition, displayChange); + transition.mType, info, remoteTransition, displayChange, transition.getFlags()); transition.mLogger.mRequestTimeNs = SystemClock.elapsedRealtimeNanos(); transition.mLogger.mRequest = request; mTransitionPlayer.requestStartTransition(transition.getToken(), request); -- cgit v1.2.3-59-g8ed1b