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
* 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
@@ -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
* {@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.
*/
@@ -7534,7 +7534,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return false;
}
final Task stack = getRootTask();
return stack != null && !stack.inMultiWindowMode()
return stack != null
&& mStackSupervisor.getKeyguardController().checkKeyguardVisibility(this);
}

View File

@@ -16,6 +16,7 @@
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.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
@@ -163,7 +164,7 @@ class KeyguardController {
if (keyguardChanged) {
// Irrelevant to AOD.
dismissDockedStackIfNeeded();
dismissMultiWindowModeForTaskIfNeeded(null /* currentTaskControllsingOcclusion */);
setKeyguardGoingAway(false);
if (keyguardShowing) {
mDismissalRequested = false;
@@ -328,8 +329,12 @@ class KeyguardController {
/**
* 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
// state change to secondary displays.
// For now, only default display fully supports occluded change. Other displays only
@@ -353,7 +358,7 @@ class KeyguardController {
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.
if (mKeyguardShowing && isDisplayOccluded(DEFAULT_DISPLAY)) {
// The lock screen is currently showing, but is occluded by a window that can
// 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.
final TaskDisplayArea taskDisplayArea = mRootWindowContainer
.getDefaultTaskDisplayArea();
if (!taskDisplayArea.isSplitScreenModeActivated()) {
return;
}
if (!mKeyguardShowing || !isDisplayOccluded(DEFAULT_DISPLAY)) {
return;
}
// Dismiss split screen
// The lock screen is currently showing, but is occluded by a window that can
// 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.
final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
if (taskDisplayArea.isSplitScreenModeActivated()) {
taskDisplayArea.onSplitScreenModeDismissed();
}
// Dismiss freeform windowing mode
if (currentTaskControllingOcclusion == null) {
return;
}
if (currentTaskControllingOcclusion.inFreeformWindowingMode()) {
currentTaskControllingOcclusion.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
}
}
private void updateKeyguardSleepToken() {
@@ -559,7 +575,7 @@ class KeyguardController {
}
if (lastOccluded != mOccluded) {
controller.handleOccludedChanged(mDisplayId);
controller.handleOccludedChanged(mDisplayId, task);
}
}

View File

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