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

Commit 232e11a0 authored by Jorge Gil's avatar Jorge Gil
Browse files

Change freeform activity occluding keyguard to fullscreen

Lets WM Shell change the windowing mode of a freeform task that is
occluding the keyguard to fullscreen.
There's two scenarios/code paths that this CL changes:
1) Unsecure keyguard: when a freeform task is on top and has the
FLAG_DISMISS_KEYGUARD flag set, RootWindowContainer#applySleepTokens
starts a transition of type TRANSIT_KEYGUARD_OCCLUDE. By setting the
occluding activity as the triggerTask, WM Shell is able to intercept
the request and change the windowing mode to fullscreen before the
transition runs/animates.
2) Secure keyguard: when a freeform task is on top and after off/on,
 A) Unlocking the keyguard starts the activity. If it sets
 setShowWhenLocked==true, it used to change the windowing mode to
 fullscreen, which was unwanted behavior since the app will not be
 shown on top of the keyguard since it was unlocked and going away.
 B) If the activity starts without unlocking the keyguard (e.g. from
 quick settings), and setShowWhenLocked is set to true, then the
 windowing mode should change to fullscreen as it will be shown over
 the keyguard.
To handle both A) and B), instead of always dismissing the freeform
mode in #handleOccludedChange, add the occluding task as the trigger
task of the TRANSIT_KEYGUARD_OCCLUDE transition that is also started
in #handleOcclusionChange, so that WM Shell can intercept it and
change the windowing mode.

Bug: 261765739
Test: (1) with unsecure keyguard, open calculator, enter freeform, turn
screen off/on, verify calculator is in fullscreen on top of keyguard;
(2A) with secure keyguard, enter freeform, off/on, unlock, verify
calculator is still in freeform mode; (2B) with secure keyguard, enter
freeform, off/on, open calculator from quick settings, verify calculator
is shown on top of the keyguard in fullscreen.

Change-Id: Idac9e012d25c50b73eba8afe9088d77043c68a85
parent dfab3209
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -16,9 +16,12 @@

package com.android.wm.shell.transition;

import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
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_KEYGUARD_OCCLUDE;
import static android.view.WindowManager.TRANSIT_OPEN;
import static android.view.WindowManager.TRANSIT_SLEEP;
import static android.view.WindowManager.TRANSIT_TO_BACK;
@@ -1081,6 +1084,16 @@ public class Transitions implements RemoteCallable<Transitions>,
                }
            }
        }
        if (request.getType() == TRANSIT_KEYGUARD_OCCLUDE && 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.
            if (wct == null) {
                wct = new WindowContainerTransaction();
            }
            wct.setWindowingMode(request.getTriggerTask().token, WINDOWING_MODE_FULLSCREEN);
            wct.setBounds(request.getTriggerTask().token, null);
        }
        mOrganizer.startTransition(transitionToken, wct != null && wct.isEmpty() ? null : wct);
        active.mToken = transitionToken;
        // Currently, WMCore only does one transition at a time. If it makes a requestStart, it
+16 −0
Original line number Diff line number Diff line
@@ -6511,6 +6511,22 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                .getKeyguardController().isDisplayOccluded(mDisplayId);
    }

    /**
     * @return the task that is occluding the keyguard
     */
    @Nullable
    Task getTaskOccludingKeyguard() {
        final KeyguardController keyguardController = mRootWindowContainer.mTaskSupervisor
                .getKeyguardController();
        if (keyguardController.getTopOccludingActivity(mDisplayId) != null) {
            return keyguardController.getTopOccludingActivity(mDisplayId).getRootTask();
        }
        if (keyguardController.getDismissKeyguardActivity(mDisplayId) != null) {
            return keyguardController.getDismissKeyguardActivity(mDisplayId).getRootTask();
        }
        return null;
    }

    @VisibleForTesting
    void removeAllTasks() {
        forAllTasks((t) -> { t.getRootTask().removeChild(t, "removeAllTasks"); });
+16 −24
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.server.wm;

import static android.app.WindowConfiguration.ACTIVITY_TYPE_DREAM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY;
@@ -411,19 +410,20 @@ class KeyguardController {
        if (waitAppTransition) {
            mService.deferWindowLayout();
            try {
                mRootWindowContainer.getDefaultDisplay()
                        .requestTransitionAndLegacyPrepare(
                                isDisplayOccluded(DEFAULT_DISPLAY)
                                        ? TRANSIT_KEYGUARD_OCCLUDE
                                        : TRANSIT_KEYGUARD_UNOCCLUDE, 0 /* flags */);
                if (isDisplayOccluded(DEFAULT_DISPLAY)) {
                    mRootWindowContainer.getDefaultDisplay().requestTransitionAndLegacyPrepare(
                            TRANSIT_KEYGUARD_OCCLUDE,
                            topActivity != null ? topActivity.getRootTask() : null);
                } else {
                    mRootWindowContainer.getDefaultDisplay().requestTransitionAndLegacyPrepare(
                            TRANSIT_KEYGUARD_UNOCCLUDE, 0 /* flags */);
                }
                updateKeyguardSleepToken(DEFAULT_DISPLAY);
                mWindowManager.executeAppTransition();
            } finally {
                mService.continueWindowLayout();
            }
        }
        dismissMultiWindowModeForTaskIfNeeded(displayId, topActivity != null
                ? topActivity.getRootTask() : null);
    }

    /**
@@ -473,6 +473,14 @@ class KeyguardController {
        return getDisplayState(displayId).mOccluded;
    }

    ActivityRecord getTopOccludingActivity(int displayId) {
        return getDisplayState(displayId).mTopOccludesActivity;
    }

    ActivityRecord getDismissKeyguardActivity(int displayId) {
        return getDisplayState(displayId).mDismissingKeyguardActivity;
    }

    /**
     * @return true if Keyguard can be currently dismissed without entering credentials.
     */
@@ -488,22 +496,6 @@ class KeyguardController {
        return getDisplayState(DEFAULT_DISPLAY).mShowingDream;
    }

    private void dismissMultiWindowModeForTaskIfNeeded(int displayId,
            @Nullable Task currentTaskControllingOcclusion) {
        // TODO(b/113840485): Handle docked stack for individual display.
        if (!getDisplayState(displayId).mKeyguardShowing || !isDisplayOccluded(DEFAULT_DISPLAY)) {
            return;
        }

        // Dismiss freeform windowing mode
        if (currentTaskControllingOcclusion == null) {
            return;
        }
        if (currentTaskControllingOcclusion.inFreeformWindowingMode()) {
            currentTaskControllingOcclusion.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
        }
    }

    private void updateKeyguardSleepToken() {
        for (int displayNdx = mRootWindowContainer.getChildCount() - 1;
             displayNdx >= 0; displayNdx--) {
+3 −2
Original line number Diff line number Diff line
@@ -2376,6 +2376,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
            if (!displayShouldSleep && display.mTransitionController.isShellTransitionsEnabled()
                    && !display.mTransitionController.isCollecting()) {
                int transit = TRANSIT_NONE;
                Task startTask = null;
                if (!display.getDisplayPolicy().isAwake()) {
                    // Note that currently this only happens on default display because non-default
                    // display is always awake.
@@ -2383,12 +2384,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
                } else if (display.isKeyguardOccluded()) {
                    // The display was awake so this is resuming activity for occluding keyguard.
                    transit = WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
                    startTask = display.getTaskOccludingKeyguard();
                }
                if (transit != TRANSIT_NONE) {
                    display.mTransitionController.requestStartTransition(
                            display.mTransitionController.createTransition(transit),
                            null /* startTask */, null /* remoteTransition */,
                            null /* displayChange */);
                            startTask, null /* remoteTransition */, null /* displayChange */);
                }
            }
            // Set the sleeping state of the root tasks on the display.