summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jorge Gil <jorgegil@google.com> 2023-04-03 19:11:31 +0000
committer Jorge Gil <jorgegil@google.com> 2023-05-25 00:32:34 +0000
commit232e11a05734c2b86e39b6ee959efd28e93b03fb (patch)
tree3a46ae9922da72fc32f419520d7cd6e3762a58a2
parentdfab3209ea3bcdbf52353ab8727c792ac189cc5a (diff)
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
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java13
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java16
-rw-r--r--services/core/java/com/android/server/wm/KeyguardController.java40
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java5
4 files changed, 48 insertions, 26 deletions
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 3b306e793640..e6d4603db10d 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
@@ -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
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index e44d27911262..6aec96988a77 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -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"); });
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 5f6d66011768..99878a3d0ffe 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -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--) {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 536915929e88..7e839596c59b 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -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.