Fix show on lock for freeform mode properly

We should not only properly disallow turning on screen but also showing
on lock for non-split screen multi-window activities. This time we have
to make sure split screen stacks/activities are exempted from these
checks.

Bug: 160925539
Test: New tests in ActivityVisibilityTests passed.
Change-Id: I185962e9ad858f7a25c4b10d18e4d96dec87ab91
This commit is contained in:
Garfield Tan
2020-07-15 17:40:03 -07:00
parent 5ff6a14e9e
commit 7caf48e780
3 changed files with 37 additions and 21 deletions

View File

@@ -3582,7 +3582,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
} }
/** /**
* @return {@code true} if the activity windowing mode is not * @return {@code true} if the activity windowing mode is not in
* {@link android.app.WindowConfiguration#WINDOWING_MODE_PINNED} and a) activity * {@link android.app.WindowConfiguration#WINDOWING_MODE_PINNED} and a) activity
* contains windows that have {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} set or if the * contains windows that have {@link LayoutParams#FLAG_SHOW_WHEN_LOCKED} set or if the
* activity has set {@link #mShowWhenLocked}, or b) if the activity has set * activity has set {@link #mShowWhenLocked}, or b) if the activity has set
@@ -7525,7 +7525,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
/** /**
* Determines whether this ActivityRecord can turn the screen on. It checks whether the flag * Determines whether this ActivityRecord can turn the screen on. It checks whether the flag
* {@link ActivityRecord#getTurnScreenOnFlag} is set and checks whether the ActivityRecord * {@link ActivityRecord#getTurnScreenOnFlag} is set and checks whether the ActivityRecord
* should be visible depending on Keyguard and window state. * should be visible depending on Keyguard state.
* *
* @return true if the screen can be turned on, false otherwise. * @return true if the screen can be turned on, false otherwise.
*/ */
@@ -7534,7 +7534,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return false; return false;
} }
final Task stack = getRootTask(); final Task stack = getRootTask();
return stack != null && !stack.inMultiWindowMode() return stack != null
&& mStackSupervisor.getKeyguardController().checkKeyguardVisibility(this); && mStackSupervisor.getKeyguardController().checkKeyguardVisibility(this);
} }

View File

@@ -16,6 +16,7 @@
package com.android.server.wm; package com.android.server.wm;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION; import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
@@ -163,7 +164,7 @@ class KeyguardController {
if (keyguardChanged) { if (keyguardChanged) {
// Irrelevant to AOD. // Irrelevant to AOD.
dismissDockedStackIfNeeded(); dismissMultiWindowModeForTaskIfNeeded(null /* currentTaskControllsingOcclusion */);
setKeyguardGoingAway(false); setKeyguardGoingAway(false);
if (keyguardShowing) { if (keyguardShowing) {
mDismissalRequested = false; mDismissalRequested = false;
@@ -328,8 +329,12 @@ class KeyguardController {
/** /**
* Called when occluded state changed. * Called when occluded state changed.
*
* @param currentTaskControllingOcclusion the task that controls the state whether keyguard
* should be occluded. That is the task to be shown on top of keyguard if it requests so.
*/ */
private void handleOccludedChanged(int displayId) { private void handleOccludedChanged(
int displayId, @Nullable Task currentTaskControllingOcclusion) {
// TODO(b/113840485): Handle app transition for individual display, and apply occluded // TODO(b/113840485): Handle app transition for individual display, and apply occluded
// state change to secondary displays. // state change to secondary displays.
// For now, only default display fully supports occluded change. Other displays only // For now, only default display fully supports occluded change. Other displays only
@@ -353,7 +358,7 @@ class KeyguardController {
mService.continueWindowLayout(); mService.continueWindowLayout();
} }
} }
dismissDockedStackIfNeeded(); dismissMultiWindowModeForTaskIfNeeded(currentTaskControllingOcclusion);
} }
/** /**
@@ -414,20 +419,31 @@ class KeyguardController {
} }
} }
private void dismissDockedStackIfNeeded() { private void dismissMultiWindowModeForTaskIfNeeded(
@Nullable Task currentTaskControllingOcclusion) {
// TODO(b/113840485): Handle docked stack for individual display. // TODO(b/113840485): Handle docked stack for individual display.
if (mKeyguardShowing && isDisplayOccluded(DEFAULT_DISPLAY)) { if (!mKeyguardShowing || !isDisplayOccluded(DEFAULT_DISPLAY)) {
// The lock screen is currently showing, but is occluded by a window that can return;
// show on top of the lock screen. In this can we want to dismiss the docked }
// stack since it will be complicated/risky to try to put the activity on top
// of the lock screen in the right fullscreen configuration. // Dismiss split screen
final TaskDisplayArea taskDisplayArea = mRootWindowContainer
.getDefaultTaskDisplayArea(); // The lock screen is currently showing, but is occluded by a window that can
if (!taskDisplayArea.isSplitScreenModeActivated()) { // show on top of the lock screen. In this can we want to dismiss the docked
return; // stack since it will be complicated/risky to try to put the activity on top
} // of the lock screen in the right fullscreen configuration.
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
if (taskDisplayArea.isSplitScreenModeActivated()) {
taskDisplayArea.onSplitScreenModeDismissed(); taskDisplayArea.onSplitScreenModeDismissed();
} }
// Dismiss freeform windowing mode
if (currentTaskControllingOcclusion == null) {
return;
}
if (currentTaskControllingOcclusion.inFreeformWindowingMode()) {
currentTaskControllingOcclusion.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
}
} }
private void updateKeyguardSleepToken() { private void updateKeyguardSleepToken() {
@@ -559,7 +575,7 @@ class KeyguardController {
} }
if (lastOccluded != mOccluded) { if (lastOccluded != mOccluded) {
controller.handleOccludedChanged(mDisplayId); controller.handleOccludedChanged(mDisplayId, task);
} }
} }

View File

@@ -1668,7 +1668,7 @@ public class ActivityRecordTests extends WindowTestsBase {
} }
@Test @Test
public void testCanTurnScreenOn() { public void testFullscreenWindowCanTurnScreenOn() {
mStack.setWindowingMode(WINDOWING_MODE_FULLSCREEN); mStack.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
doReturn(true).when(mActivity).getTurnScreenOnFlag(); doReturn(true).when(mActivity).getTurnScreenOnFlag();
@@ -1676,11 +1676,11 @@ public class ActivityRecordTests extends WindowTestsBase {
} }
@Test @Test
public void testFreeformWindowCantTurnScreenOn() { public void testFreeformWindowCanTurnScreenOn() {
mStack.setWindowingMode(WINDOWING_MODE_FREEFORM); mStack.setWindowingMode(WINDOWING_MODE_FREEFORM);
doReturn(true).when(mActivity).getTurnScreenOnFlag(); doReturn(true).when(mActivity).getTurnScreenOnFlag();
assertFalse(mActivity.canTurnScreenOn()); assertTrue(mActivity.canTurnScreenOn());
} }
@Test @Test