[2/n] Letterbox Education: Add information about fixed orientation letterbox to TaskInfo
Bug: 207010227 Test: atest WmTests:ActivityRecordTests Test: atest WmTests:SizeCompatTests Test: atest WMShellUnitTests:ShellTaskOrganizerTests Change-Id: I04e82eb494c84bd78c269dd244bdd4a3e4d5fcc8
This commit is contained in:
@@ -213,6 +213,12 @@ public class TaskInfo {
|
||||
*/
|
||||
public boolean topActivityInSizeCompat;
|
||||
|
||||
/**
|
||||
* Whether the direct top activity is eligible for letterbox education.
|
||||
* @hide
|
||||
*/
|
||||
public boolean topActivityEligibleForLetterboxEducation;
|
||||
|
||||
/**
|
||||
* Whether this task is resizable. Unlike {@link #resizeMode} (which is what the top activity
|
||||
* supports), this is what the system actually uses for resizability based on other policy and
|
||||
@@ -398,7 +404,8 @@ public class TaskInfo {
|
||||
|
||||
/** @hide */
|
||||
public boolean hasCompatUI() {
|
||||
return hasCameraCompatControl() || topActivityInSizeCompat;
|
||||
return hasCameraCompatControl() || topActivityInSizeCompat
|
||||
|| topActivityEligibleForLetterboxEducation;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -460,6 +467,8 @@ public class TaskInfo {
|
||||
return displayId == that.displayId
|
||||
&& taskId == that.taskId
|
||||
&& topActivityInSizeCompat == that.topActivityInSizeCompat
|
||||
&& topActivityEligibleForLetterboxEducation
|
||||
== that.topActivityEligibleForLetterboxEducation
|
||||
&& cameraCompatControlState == that.cameraCompatControlState
|
||||
// Bounds are important if top activity has compat controls.
|
||||
&& (!hasCompatUI() || configuration.windowConfiguration.getBounds()
|
||||
@@ -507,6 +516,7 @@ public class TaskInfo {
|
||||
isVisible = source.readBoolean();
|
||||
isSleeping = source.readBoolean();
|
||||
topActivityInSizeCompat = source.readBoolean();
|
||||
topActivityEligibleForLetterboxEducation = source.readBoolean();
|
||||
mTopActivityLocusId = source.readTypedObject(LocusId.CREATOR);
|
||||
displayAreaFeatureId = source.readInt();
|
||||
cameraCompatControlState = source.readInt();
|
||||
@@ -551,6 +561,7 @@ public class TaskInfo {
|
||||
dest.writeBoolean(isVisible);
|
||||
dest.writeBoolean(isSleeping);
|
||||
dest.writeBoolean(topActivityInSizeCompat);
|
||||
dest.writeBoolean(topActivityEligibleForLetterboxEducation);
|
||||
dest.writeTypedObject(mTopActivityLocusId, flags);
|
||||
dest.writeInt(displayAreaFeatureId);
|
||||
dest.writeInt(cameraCompatControlState);
|
||||
@@ -585,6 +596,8 @@ public class TaskInfo {
|
||||
+ " isVisible=" + isVisible
|
||||
+ " isSleeping=" + isSleeping
|
||||
+ " topActivityInSizeCompat=" + topActivityInSizeCompat
|
||||
+ " topActivityEligibleForLetterboxEducation= "
|
||||
+ topActivityEligibleForLetterboxEducation
|
||||
+ " locusId=" + mTopActivityLocusId
|
||||
+ " displayAreaFeatureId=" + displayAreaFeatureId
|
||||
+ " cameraCompatControlState="
|
||||
|
||||
@@ -5134,6 +5134,9 @@
|
||||
If given value is outside of this range, the option 1 (center) is assummed. -->
|
||||
<integer name="config_letterboxDefaultPositionForReachability">1</integer>
|
||||
|
||||
<!-- Whether displaying letterbox education is enabled for letterboxed fullscreen apps. -->
|
||||
<bool name="config_letterboxIsEducationEnabled">false</bool>
|
||||
|
||||
<!-- Whether a camera compat controller is enabled to allow the user to apply or revert
|
||||
treatment for stretched issues in camera viewfinder. -->
|
||||
<bool name="config_isCameraCompatControlForStretchedIssuesEnabled">false</bool>
|
||||
|
||||
@@ -4323,6 +4323,7 @@
|
||||
<java-symbol type="dimen" name="config_letterboxHorizontalPositionMultiplier" />
|
||||
<java-symbol type="bool" name="config_letterboxIsReachabilityEnabled" />
|
||||
<java-symbol type="integer" name="config_letterboxDefaultPositionForReachability" />
|
||||
<java-symbol type="bool" name="config_letterboxIsEducationEnabled" />
|
||||
<java-symbol type="bool" name="config_isCameraCompatControlForStretchedIssuesEnabled" />
|
||||
|
||||
<java-symbol type="bool" name="config_hideDisplayCutoutWithDisplayArea" />
|
||||
|
||||
@@ -362,6 +362,45 @@ public class ShellTaskOrganizerTests {
|
||||
verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnEligibleForLetterboxEducationActivityChanged() {
|
||||
final RunningTaskInfo taskInfo1 = createTaskInfo(12, WINDOWING_MODE_FULLSCREEN);
|
||||
taskInfo1.displayId = DEFAULT_DISPLAY;
|
||||
taskInfo1.topActivityEligibleForLetterboxEducation = false;
|
||||
final TrackingTaskListener taskListener = new TrackingTaskListener();
|
||||
mOrganizer.addListenerForType(taskListener, TASK_LISTENER_TYPE_FULLSCREEN);
|
||||
mOrganizer.onTaskAppeared(taskInfo1, null);
|
||||
|
||||
// Task listener sent to compat UI is null if top activity isn't eligible for letterbox
|
||||
// education.
|
||||
verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
|
||||
|
||||
// Task listener is non-null if top activity is eligible for letterbox education and task
|
||||
// is visible.
|
||||
clearInvocations(mCompatUI);
|
||||
final RunningTaskInfo taskInfo2 =
|
||||
createTaskInfo(taskInfo1.taskId, WINDOWING_MODE_FULLSCREEN);
|
||||
taskInfo2.displayId = taskInfo1.displayId;
|
||||
taskInfo2.topActivityEligibleForLetterboxEducation = true;
|
||||
taskInfo2.isVisible = true;
|
||||
mOrganizer.onTaskInfoChanged(taskInfo2);
|
||||
verify(mCompatUI).onCompatInfoChanged(taskInfo2, taskListener);
|
||||
|
||||
// Task listener is null if task is invisible.
|
||||
clearInvocations(mCompatUI);
|
||||
final RunningTaskInfo taskInfo3 =
|
||||
createTaskInfo(taskInfo1.taskId, WINDOWING_MODE_FULLSCREEN);
|
||||
taskInfo3.displayId = taskInfo1.displayId;
|
||||
taskInfo3.topActivityEligibleForLetterboxEducation = true;
|
||||
taskInfo3.isVisible = false;
|
||||
mOrganizer.onTaskInfoChanged(taskInfo3);
|
||||
verify(mCompatUI).onCompatInfoChanged(taskInfo3, null /* taskListener */);
|
||||
|
||||
clearInvocations(mCompatUI);
|
||||
mOrganizer.onTaskVanished(taskInfo1);
|
||||
verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnCameraCompatActivityChanged() {
|
||||
final RunningTaskInfo taskInfo1 = createTaskInfo(1, WINDOWING_MODE_FULLSCREEN);
|
||||
@@ -375,7 +414,7 @@ public class ShellTaskOrganizerTests {
|
||||
// compat control.
|
||||
verify(mCompatUI).onCompatInfoChanged(taskInfo1, null /* taskListener */);
|
||||
|
||||
// Task linster is non-null when request a camera compat control for a visible task.
|
||||
// Task listener is non-null when request a camera compat control for a visible task.
|
||||
clearInvocations(mCompatUI);
|
||||
final RunningTaskInfo taskInfo2 =
|
||||
createTaskInfo(taskInfo1.taskId, taskInfo1.getWindowingMode());
|
||||
|
||||
@@ -715,6 +715,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
@Nullable
|
||||
private Rect mLetterboxBoundsForFixedOrientationAndAspectRatio;
|
||||
|
||||
// Whether the activity is eligible to be letterboxed for fixed orientation with respect to its
|
||||
// requested orientation, even when it's letterbox for another reason (e.g., size compat mode)
|
||||
// and therefore #isLetterboxedForFixedOrientationAndAspectRatio returns false.
|
||||
private boolean mIsEligibleForFixedOrientationLetterbox;
|
||||
|
||||
// State of the Camera app compat control which is used to correct stretched viewfinder
|
||||
// in apps that don't handle all possible configurations and changes between them correctly.
|
||||
@CameraCompatControlState
|
||||
@@ -7616,6 +7621,24 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
return mLetterboxBoundsForFixedOrientationAndAspectRatio != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this activity is eligible for letterbox eduction.
|
||||
*
|
||||
* <p>Conditions that need to be met:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@link LetterboxConfiguration#getIsEducationEnabled} is true.
|
||||
* <li>The activity is eligible for fixed orientation letterbox.
|
||||
* <li>The activity is in fullscreen.
|
||||
* </ul>
|
||||
*/
|
||||
// TODO(b/215316431): Add tests
|
||||
boolean isEligibleForLetterboxEducation() {
|
||||
return mWmService.mLetterboxConfiguration.getIsEducationEnabled()
|
||||
&& mIsEligibleForFixedOrientationLetterbox
|
||||
&& getWindowingMode() == WINDOWING_MODE_FULLSCREEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* In some cases, applying insets to bounds changes the orientation. For example, if a
|
||||
* close-to-square display rotates to portrait to respect a portrait orientation activity, after
|
||||
@@ -7678,6 +7701,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
private void resolveFixedOrientationConfiguration(@NonNull Configuration newParentConfig,
|
||||
int windowingMode) {
|
||||
mLetterboxBoundsForFixedOrientationAndAspectRatio = null;
|
||||
mIsEligibleForFixedOrientationLetterbox = false;
|
||||
final Rect parentBounds = newParentConfig.windowConfiguration.getBounds();
|
||||
final Rect stableBounds = new Rect();
|
||||
// If orientation is respected when insets are applied, then stableBounds will be empty.
|
||||
@@ -7717,8 +7741,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
// make it fit the available bounds by scaling down its bounds.
|
||||
final int forcedOrientation = getRequestedConfigurationOrientation();
|
||||
|
||||
if (forcedOrientation == ORIENTATION_UNDEFINED
|
||||
|| (forcedOrientation == parentOrientation && orientationRespectedWithInsets)) {
|
||||
mIsEligibleForFixedOrientationLetterbox = forcedOrientation != ORIENTATION_UNDEFINED
|
||||
&& forcedOrientation != parentOrientation;
|
||||
|
||||
if (!mIsEligibleForFixedOrientationLetterbox && (forcedOrientation == ORIENTATION_UNDEFINED
|
||||
|| orientationRespectedWithInsets)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -126,6 +126,9 @@ final class LetterboxConfiguration {
|
||||
@LetterboxReachabilityPosition
|
||||
private volatile int mLetterboxPositionForReachability;
|
||||
|
||||
// Whether education is allowed for letterboxed fullscreen apps.
|
||||
private boolean mIsEducationEnabled;
|
||||
|
||||
LetterboxConfiguration(Context systemUiContext) {
|
||||
mContext = systemUiContext;
|
||||
mFixedOrientationLetterboxAspectRatio = mContext.getResources().getFloat(
|
||||
@@ -143,6 +146,8 @@ final class LetterboxConfiguration {
|
||||
R.bool.config_letterboxIsReachabilityEnabled);
|
||||
mDefaultPositionForReachability = readLetterboxReachabilityPositionFromConfig(mContext);
|
||||
mLetterboxPositionForReachability = mDefaultPositionForReachability;
|
||||
mIsEducationEnabled = mContext.getResources().getBoolean(
|
||||
R.bool.config_letterboxIsEducationEnabled);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -501,4 +506,27 @@ final class LetterboxConfiguration {
|
||||
mLetterboxPositionForReachability = Math.max(mLetterboxPositionForReachability - 1, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether education is allowed for letterboxed fullscreen apps.
|
||||
*/
|
||||
boolean getIsEducationEnabled() {
|
||||
return mIsEducationEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides whether education is allowed for letterboxed fullscreen apps.
|
||||
*/
|
||||
void setIsEducationEnabled(boolean enabled) {
|
||||
mIsEducationEnabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets whether education is allowed for letterboxed fullscreen apps to
|
||||
* {@link R.bool.config_letterboxIsEducationEnabled}.
|
||||
*/
|
||||
void resetIsEducationEnabled() {
|
||||
mIsEducationEnabled = mContext.getResources().getBoolean(
|
||||
R.bool.config_letterboxIsEducationEnabled);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3434,6 +3434,9 @@ class Task extends TaskFragment {
|
||||
// Whether the direct top activity is in size compat mode on foreground.
|
||||
info.topActivityInSizeCompat = isTopActivityResumed
|
||||
&& mReuseActivitiesReport.top.inSizeCompatMode();
|
||||
// Whether the direct top activity is eligible for letterbox education.
|
||||
info.topActivityEligibleForLetterboxEducation = isTopActivityResumed
|
||||
&& mReuseActivitiesReport.top.isEligibleForLetterboxEducation();
|
||||
// Whether the direct top activity requested showing camera compat control.
|
||||
info.cameraCompatControlState = isTopActivityResumed
|
||||
? mReuseActivitiesReport.top.getCameraCompatControlState()
|
||||
|
||||
@@ -822,6 +822,29 @@ public class WindowManagerShellCommand extends ShellCommand {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int runSetLetterboxIsEducationEnabled(PrintWriter pw) throws RemoteException {
|
||||
String arg = getNextArg();
|
||||
final boolean enabled;
|
||||
switch (arg) {
|
||||
case "true":
|
||||
case "1":
|
||||
enabled = true;
|
||||
break;
|
||||
case "false":
|
||||
case "0":
|
||||
enabled = false;
|
||||
break;
|
||||
default:
|
||||
getErrPrintWriter().println("Error: expected true, 1, false, 0, but got " + arg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
synchronized (mInternal.mGlobalLock) {
|
||||
mLetterboxConfiguration.setIsEducationEnabled(enabled);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int runSetLetterboxStyle(PrintWriter pw) throws RemoteException {
|
||||
if (peekNextArg() == null) {
|
||||
getErrPrintWriter().println("Error: No arguments provided.");
|
||||
@@ -859,6 +882,9 @@ public class WindowManagerShellCommand extends ShellCommand {
|
||||
case "--defaultPositionForReachability":
|
||||
runSetLetterboxDefaultPositionForReachability(pw);
|
||||
break;
|
||||
case "--isEducationEnabled":
|
||||
runSetLetterboxIsEducationEnabled(pw);
|
||||
break;
|
||||
default:
|
||||
getErrPrintWriter().println(
|
||||
"Error: Unrecognized letterbox style option: " + arg);
|
||||
@@ -903,6 +929,9 @@ public class WindowManagerShellCommand extends ShellCommand {
|
||||
case "defaultPositionForReachability":
|
||||
mLetterboxConfiguration.getDefaultPositionForReachability();
|
||||
break;
|
||||
case "isEducationEnabled":
|
||||
mLetterboxConfiguration.getIsEducationEnabled();
|
||||
break;
|
||||
default:
|
||||
getErrPrintWriter().println(
|
||||
"Error: Unrecognized letterbox style option: " + arg);
|
||||
@@ -998,6 +1027,7 @@ public class WindowManagerShellCommand extends ShellCommand {
|
||||
mLetterboxConfiguration.resetLetterboxHorizontalPositionMultiplier();
|
||||
mLetterboxConfiguration.resetIsReachabilityEnabled();
|
||||
mLetterboxConfiguration.resetDefaultPositionForReachability();
|
||||
mLetterboxConfiguration.resetIsEducationEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1014,6 +1044,8 @@ public class WindowManagerShellCommand extends ShellCommand {
|
||||
pw.println("Default position for reachability: "
|
||||
+ LetterboxConfiguration.letterboxReachabilityPositionToString(
|
||||
mLetterboxConfiguration.getDefaultPositionForReachability()));
|
||||
pw.println("Is education enabled: "
|
||||
+ mLetterboxConfiguration.getIsEducationEnabled());
|
||||
|
||||
pw.println("Background type: "
|
||||
+ LetterboxConfiguration.letterboxBackgroundTypeToString(
|
||||
@@ -1154,10 +1186,12 @@ public class WindowManagerShellCommand extends ShellCommand {
|
||||
pw.println(" --defaultPositionForReachability [left|center|right]");
|
||||
pw.println(" Default horizontal position of app window when reachability is.");
|
||||
pw.println(" enabled.");
|
||||
pw.println(" --isEducationEnabled [true|1|false|0]");
|
||||
pw.println(" Whether education is allowed for letterboxed fullscreen apps.");
|
||||
pw.println(" reset-letterbox-style [aspectRatio|cornerRadius|backgroundType");
|
||||
pw.println(" |backgroundColor|wallpaperBlurRadius|wallpaperDarkScrimAlpha");
|
||||
pw.println(" |horizontalPositionMultiplier|isReachabilityEnabled");
|
||||
pw.println(" |defaultPositionMultiplierForReachability]");
|
||||
pw.println(" isEducationEnabled||defaultPositionMultiplierForReachability]");
|
||||
pw.println(" Resets overrides to default values for specified properties separated");
|
||||
pw.println(" by space, e.g. 'reset-letterbox-style aspectRatio cornerRadius'.");
|
||||
pw.println(" If no arguments provided, all values will be reset.");
|
||||
|
||||
Reference in New Issue
Block a user