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

Commit 2554fe32 authored by Jorge Gil's avatar Jorge Gil
Browse files

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
parent b31e95af
Loading
Loading
Loading
Loading
+39 −13
Original line number Original line Diff line number Diff line
@@ -16,8 +16,6 @@


package android.window;
package android.window;


import static android.view.WindowManager.transitTypeToString;

import android.annotation.Nullable;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManager;
import android.app.WindowConfiguration;
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
     * The reliable parts should be flags, rotation start/end (if rotating), and start/end bounds
     * (if size is changing).
     * (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 */
    /** constructor override */
    public TransitionRequestInfo(
    public TransitionRequestInfo(
            @WindowManager.TransitionType int type,
            @WindowManager.TransitionType int type,
            @Nullable ActivityManager.RunningTaskInfo triggerTask,
            @Nullable ActivityManager.RunningTaskInfo triggerTask,
            @Nullable RemoteTransition remoteTransition) {
            @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. */
    /** Requested change to a display. */
@@ -236,7 +246,7 @@ public final class TransitionRequestInfo implements Parcelable {
        };
        };


        @DataClass.Generated(
        @DataClass.Generated(
                time = 1648141181315L,
                time = 1691627678294L,
                codegenVersion = "1.0.23",
                codegenVersion = "1.0.23",
                sourceFile = "frameworks/base/core/java/android/window/TransitionRequestInfo.java",
                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)")
                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:
     *   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
     *   The reliable parts should be flags, rotation start/end (if rotating), and start/end bounds
     *   (if size is changing).
     *   (if size is changing).
     * @param flags
     *   The transition flags known at the time of the request. These may not be complete.
     */
     */
    @DataClass.Generated.Member
    @DataClass.Generated.Member
    public TransitionRequestInfo(
    public TransitionRequestInfo(
            @WindowManager.TransitionType int type,
            @WindowManager.TransitionType int type,
            @Nullable ActivityManager.RunningTaskInfo triggerTask,
            @Nullable ActivityManager.RunningTaskInfo triggerTask,
            @Nullable RemoteTransition remoteTransition,
            @Nullable RemoteTransition remoteTransition,
            @Nullable DisplayChange displayChange) {
            @Nullable TransitionRequestInfo.DisplayChange displayChange,
            int flags) {
        this.mType = type;
        this.mType = type;
        com.android.internal.util.AnnotationValidations.validate(
        com.android.internal.util.AnnotationValidations.validate(
                WindowManager.TransitionType.class, null, mType);
                WindowManager.TransitionType.class, null, mType);
        this.mTriggerTask = triggerTask;
        this.mTriggerTask = triggerTask;
        this.mRemoteTransition = remoteTransition;
        this.mRemoteTransition = remoteTransition;
        this.mDisplayChange = displayChange;
        this.mDisplayChange = displayChange;
        this.mFlags = flags;


        // onConstructed(); // You can define this method to get a callback
        // onConstructed(); // You can define this method to get a callback
    }
    }
@@ -327,10 +341,18 @@ public final class TransitionRequestInfo implements Parcelable {
     * (if size is changing).
     * (if size is changing).
     */
     */
    @DataClass.Generated.Member
    @DataClass.Generated.Member
    public @Nullable DisplayChange getDisplayChange() {
    public @Nullable TransitionRequestInfo.DisplayChange getDisplayChange() {
        return mDisplayChange;
        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
     * If non-null, If non-null, the task containing the activity whose lifecycle change (start or
     * finish) has caused this transition to occur.
     * finish) has caused this transition to occur.
@@ -356,7 +378,7 @@ public final class TransitionRequestInfo implements Parcelable {
     * (if size is changing).
     * (if size is changing).
     */
     */
    @DataClass.Generated.Member
    @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;
        mDisplayChange = value;
        return this;
        return this;
    }
    }
@@ -368,10 +390,11 @@ public final class TransitionRequestInfo implements Parcelable {
        // String fieldNameToString() { ... }
        // String fieldNameToString() { ... }


        return "TransitionRequestInfo { " +
        return "TransitionRequestInfo { " +
                "type = " + transitTypeToString(mType) + ", " +
                "type = " + mType + ", " +
                "triggerTask = " + mTriggerTask + ", " +
                "triggerTask = " + mTriggerTask + ", " +
                "remoteTransition = " + mRemoteTransition + ", " +
                "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 (mTriggerTask != null) dest.writeTypedObject(mTriggerTask, flags);
        if (mRemoteTransition != null) dest.writeTypedObject(mRemoteTransition, flags);
        if (mRemoteTransition != null) dest.writeTypedObject(mRemoteTransition, flags);
        if (mDisplayChange != null) dest.writeTypedObject(mDisplayChange, flags);
        if (mDisplayChange != null) dest.writeTypedObject(mDisplayChange, flags);
        dest.writeInt(mFlags);
    }
    }


    @Override
    @Override
@@ -407,7 +431,8 @@ public final class TransitionRequestInfo implements Parcelable {
        int type = in.readInt();
        int type = in.readInt();
        ActivityManager.RunningTaskInfo triggerTask = (flg & 0x2) == 0 ? null : (ActivityManager.RunningTaskInfo) in.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR);
        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);
        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;
        this.mType = type;
        com.android.internal.util.AnnotationValidations.validate(
        com.android.internal.util.AnnotationValidations.validate(
@@ -415,6 +440,7 @@ public final class TransitionRequestInfo implements Parcelable {
        this.mTriggerTask = triggerTask;
        this.mTriggerTask = triggerTask;
        this.mRemoteTransition = remoteTransition;
        this.mRemoteTransition = remoteTransition;
        this.mDisplayChange = displayChange;
        this.mDisplayChange = displayChange;
        this.mFlags = flags;


        // onConstructed(); // You can define this method to get a callback
        // onConstructed(); // You can define this method to get a callback
    }
    }
@@ -434,10 +460,10 @@ public final class TransitionRequestInfo implements Parcelable {
    };
    };


    @DataClass.Generated(
    @DataClass.Generated(
            time = 1639445520938L,
            time = 1691627678327L,
            codegenVersion = "1.0.23",
            codegenVersion = "1.0.23",
            sourceFile = "frameworks/base/core/java/android/window/TransitionRequestInfo.java",
            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
    @Deprecated
    private void __metadata() {}
    private void __metadata() {}


+31 −1
Original line number Original line Diff line number Diff line
@@ -16,7 +16,10 @@


package com.android.wm.shell.keyguard;
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.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.KEYGUARD_VISIBILITY_TRANSIT_FLAGS;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_OCCLUDING;
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.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.os.Binder;
import android.os.Binder;
import android.os.Handler;
import android.os.Handler;
import android.os.IBinder;
import android.os.IBinder;
@@ -165,10 +169,16 @@ public class KeyguardTransitionHandler implements Transitions.TransitionHandler
                            if (sct != null) {
                            if (sct != null) {
                                finishTransaction.merge(sct);
                                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.
                            // Post our finish callback to let startAnimation finish first.
                            mMainExecutor.executeDelayed(() -> {
                            mMainExecutor.executeDelayed(() -> {
                                mStartedTransitions.remove(transition);
                                mStartedTransitions.remove(transition);
                                finishCallback.onTransitionFinished(wct);
                                finishCallback.onTransitionFinished(mergedWct);
                            }, 0);
                            }, 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 {
    private static class FakeFinishCallback extends IRemoteTransitionFinishedCallback.Stub {
        @Override
        @Override
        public void onTransitionFinished(
        public void onTransitionFinished(
+4 −1
Original line number Original line Diff line number Diff line
@@ -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_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FIRST_CUSTOM;
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_KEYGUARD_OCCLUDE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_SLEEP;
import static android.view.WindowManager.TRANSIT_SLEEP;
@@ -1104,7 +1105,9 @@ public class Transitions implements RemoteCallable<Transitions>,
                }
                }
            }
            }
        }
        }
        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) {
                && request.getTriggerTask().getWindowingMode() == WINDOWING_MODE_FREEFORM) {
            // This freeform task is on top of keyguard, so its windowing mode should be changed to
            // This freeform task is on top of keyguard, so its windowing mode should be changed to
            // fullscreen.
            // fullscreen.
+3 −3
Original line number Original line Diff line number Diff line
@@ -92,7 +92,7 @@ public class UnfoldTransitionHandlerTest {
        TransitionRequestInfo.DisplayChange displayChange = new TransitionRequestInfo.DisplayChange(
        TransitionRequestInfo.DisplayChange displayChange = new TransitionRequestInfo.DisplayChange(
                Display.DEFAULT_DISPLAY).setPhysicalDisplayChanged(true);
                Display.DEFAULT_DISPLAY).setPhysicalDisplayChanged(true);
        TransitionRequestInfo requestInfo = new TransitionRequestInfo(TRANSIT_CHANGE,
        TransitionRequestInfo requestInfo = new TransitionRequestInfo(TRANSIT_CHANGE,
                triggerTaskInfo, /* remoteTransition= */ null, displayChange);
                triggerTaskInfo, /* remoteTransition= */ null, displayChange, 0 /* flags */);


        WindowContainerTransaction result = mUnfoldTransitionHandler.handleRequest(mTransition,
        WindowContainerTransaction result = mUnfoldTransitionHandler.handleRequest(mTransition,
                requestInfo);
                requestInfo);
@@ -106,7 +106,7 @@ public class UnfoldTransitionHandlerTest {
        TransitionRequestInfo.DisplayChange displayChange = new TransitionRequestInfo.DisplayChange(
        TransitionRequestInfo.DisplayChange displayChange = new TransitionRequestInfo.DisplayChange(
                Display.DEFAULT_DISPLAY).setPhysicalDisplayChanged(false);
                Display.DEFAULT_DISPLAY).setPhysicalDisplayChanged(false);
        TransitionRequestInfo requestInfo = new TransitionRequestInfo(TRANSIT_CHANGE,
        TransitionRequestInfo requestInfo = new TransitionRequestInfo(TRANSIT_CHANGE,
                triggerTaskInfo, /* remoteTransition= */ null, displayChange);
                triggerTaskInfo, /* remoteTransition= */ null, displayChange, 0 /* flags */);


        WindowContainerTransaction result = mUnfoldTransitionHandler.handleRequest(mTransition,
        WindowContainerTransaction result = mUnfoldTransitionHandler.handleRequest(mTransition,
                requestInfo);
                requestInfo);
@@ -212,7 +212,7 @@ public class UnfoldTransitionHandlerTest {
        TransitionRequestInfo.DisplayChange displayChange = new TransitionRequestInfo.DisplayChange(
        TransitionRequestInfo.DisplayChange displayChange = new TransitionRequestInfo.DisplayChange(
                Display.DEFAULT_DISPLAY).setPhysicalDisplayChanged(true);
                Display.DEFAULT_DISPLAY).setPhysicalDisplayChanged(true);
        return new TransitionRequestInfo(TRANSIT_CHANGE,
        return new TransitionRequestInfo(TRANSIT_CHANGE,
                triggerTaskInfo, /* remoteTransition= */ null, displayChange);
                triggerTaskInfo, /* remoteTransition= */ null, displayChange, 0 /* flags */);
    }
    }


    private static class TestShellUnfoldProgressProvider implements ShellUnfoldProgressProvider,
    private static class TestShellUnfoldProgressProvider implements ShellUnfoldProgressProvider,
+1 −1
Original line number Original line Diff line number Diff line
@@ -711,7 +711,7 @@ class TransitionController {
                startTask.fillTaskInfo(info);
                startTask.fillTaskInfo(info);
            }
            }
            final TransitionRequestInfo request = new TransitionRequestInfo(
            final TransitionRequestInfo request = new TransitionRequestInfo(
                    transition.mType, info, remoteTransition, displayChange);
                    transition.mType, info, remoteTransition, displayChange, transition.getFlags());
            transition.mLogger.mRequestTimeNs = SystemClock.elapsedRealtimeNanos();
            transition.mLogger.mRequestTimeNs = SystemClock.elapsedRealtimeNanos();
            transition.mLogger.mRequest = request;
            transition.mLogger.mRequest = request;
            mTransitionPlayer.requestStartTransition(transition.getToken(), request);
            mTransitionPlayer.requestStartTransition(transition.getToken(), request);