[2/n] Camera Compat: Add DeviceConfig flag
Also, refactor boolean setters to reduce code duplication in WindowManagerShellCommand. Test: manual with adb shell device_config put window_manager enable_camera_compat_treatment true Bug: 218352945 Change-Id: Ieb01afa8a1941d9a5a5979139d886592122fcd7a
This commit is contained in:
@@ -1160,7 +1160,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
updateDisplayAreaOrganizers();
|
||||
|
||||
mDisplayRotationCompatPolicy =
|
||||
DisplayRotationCompatPolicy.isTreatmentEnabled(mWmService.mContext)
|
||||
// Not checking DeviceConfig value here to allow enabling via DeviceConfig
|
||||
// without the need to restart the device.
|
||||
mWmService.mLetterboxConfiguration.isCameraCompatTreatmentEnabled(
|
||||
/* checkDeviceConfig */ false)
|
||||
? new DisplayRotationCompatPolicy(this) : null;
|
||||
|
||||
mInputMonitor = new InputMonitor(mWmService, this);
|
||||
|
||||
@@ -30,14 +30,12 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ActivityInfo.ScreenOrientation;
|
||||
import android.hardware.camera2.CameraManager;
|
||||
import android.os.Handler;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.protolog.common.ProtoLog;
|
||||
@@ -77,8 +75,6 @@ final class DisplayRotationCompatPolicy {
|
||||
private final WindowManagerService mWmService;
|
||||
private final CameraManager mCameraManager;
|
||||
private final Handler mHandler;
|
||||
// TODO(b/218352945): Add an ADB command.
|
||||
private final boolean mIsTreatmentEnabled;
|
||||
|
||||
// Bi-directional map between package names and active camera IDs since we need to 1) get a
|
||||
// camera id by a package name when determining rotation; 2) get a package name by a camera id
|
||||
@@ -114,17 +110,11 @@ final class DisplayRotationCompatPolicy {
|
||||
mHandler = handler;
|
||||
mDisplayContent = displayContent;
|
||||
mWmService = displayContent.mWmService;
|
||||
mIsTreatmentEnabled = isTreatmentEnabled(mWmService.mContext);
|
||||
mCameraManager = mWmService.mContext.getSystemService(CameraManager.class);
|
||||
mCameraManager.registerAvailabilityCallback(
|
||||
mWmService.mContext.getMainExecutor(), mAvailabilityCallback);
|
||||
}
|
||||
|
||||
static boolean isTreatmentEnabled(@NonNull Context context) {
|
||||
return context.getResources().getBoolean(
|
||||
R.bool.config_isWindowManagerCameraCompatTreatmentEnabled);
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
mCameraManager.unregisterAvailabilityCallback(mAvailabilityCallback);
|
||||
}
|
||||
@@ -190,7 +180,9 @@ final class DisplayRotationCompatPolicy {
|
||||
* </ul>
|
||||
*/
|
||||
private boolean isTreatmentEnabledForDisplay() {
|
||||
return mIsTreatmentEnabled && mDisplayContent.getIgnoreOrientationRequest()
|
||||
return mWmService.mLetterboxConfiguration.isCameraCompatTreatmentEnabled(
|
||||
/* checkDeviceConfig */ true)
|
||||
&& mDisplayContent.getIgnoreOrientationRequest()
|
||||
// TODO(b/225928882): Support camera compat rotation for external displays
|
||||
&& mDisplayContent.getDisplay().getType() == TYPE_INTERNAL;
|
||||
}
|
||||
|
||||
@@ -191,6 +191,10 @@ final class LetterboxConfiguration {
|
||||
// Allows to enable letterboxing strategy for translucent activities ignoring flags.
|
||||
private boolean mTranslucentLetterboxingOverrideEnabled;
|
||||
|
||||
// Whether camera compatibility treatment is enabled.
|
||||
// See DisplayRotationCompatPolicy for context.
|
||||
private final boolean mIsCameraCompatTreatmentEnabled;
|
||||
|
||||
LetterboxConfiguration(Context systemUiContext) {
|
||||
this(systemUiContext, new LetterboxConfigurationPersister(systemUiContext,
|
||||
() -> readLetterboxHorizontalReachabilityPositionFromConfig(systemUiContext,
|
||||
@@ -241,6 +245,8 @@ final class LetterboxConfiguration {
|
||||
R.bool.config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled);
|
||||
mTranslucentLetterboxingEnabled = mContext.getResources().getBoolean(
|
||||
R.bool.config_letterboxIsEnabledForTranslucentActivities);
|
||||
mIsCameraCompatTreatmentEnabled = mContext.getResources().getBoolean(
|
||||
R.bool.config_isWindowManagerCameraCompatTreatmentEnabled);
|
||||
mLetterboxConfigurationPersister = letterboxConfigurationPersister;
|
||||
mLetterboxConfigurationPersister.start();
|
||||
}
|
||||
@@ -947,9 +953,24 @@ final class LetterboxConfiguration {
|
||||
isDeviceInTabletopMode, nextVerticalPosition);
|
||||
}
|
||||
|
||||
// TODO(b/262378106): Cache runtime flag and implement DeviceConfig.OnPropertiesChangedListener
|
||||
// TODO(b/262378106): Cache a runtime flag and implement
|
||||
// DeviceConfig.OnPropertiesChangedListener
|
||||
static boolean isTranslucentLetterboxingAllowed() {
|
||||
return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
|
||||
"enable_translucent_activity_letterbox", false);
|
||||
}
|
||||
|
||||
/** Whether camera compatibility treatment is enabled. */
|
||||
boolean isCameraCompatTreatmentEnabled(boolean checkDeviceConfig) {
|
||||
return mIsCameraCompatTreatmentEnabled
|
||||
&& (!checkDeviceConfig || isCameraCompatTreatmentAllowed());
|
||||
}
|
||||
|
||||
// TODO(b/262977416): Cache a runtime flag and implement
|
||||
// DeviceConfig.OnPropertiesChangedListener
|
||||
private static boolean isCameraCompatTreatmentAllowed() {
|
||||
return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
|
||||
"enable_camera_compat_treatment", false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ import com.android.server.wm.LetterboxConfiguration.LetterboxVerticalReachabilit
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.ZipEntry;
|
||||
@@ -806,54 +807,6 @@ public class WindowManagerShellCommand extends ShellCommand {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int runSetLetterboxIsHorizontalReachabilityEnabled(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.setIsHorizontalReachabilityEnabled(enabled);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int runSetLetterboxIsVerticalReachabilityEnabled(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.setIsVerticalReachabilityEnabled(enabled);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int runSetLetterboxDefaultPositionForHorizontalReachability(PrintWriter pw)
|
||||
throws RemoteException {
|
||||
@LetterboxHorizontalReachabilityPosition final int position;
|
||||
@@ -916,32 +869,13 @@ 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 runSetLetterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled(PrintWriter pw)
|
||||
private int runSetBooleanFlag(PrintWriter pw, Consumer<Boolean> setter)
|
||||
throws RemoteException {
|
||||
String arg = getNextArg();
|
||||
if (arg == null) {
|
||||
getErrPrintWriter().println("Error: expected true, 1, false, 0, but got empty input.");
|
||||
return -1;
|
||||
}
|
||||
final boolean enabled;
|
||||
switch (arg) {
|
||||
case "true":
|
||||
@@ -958,30 +892,7 @@ public class WindowManagerShellCommand extends ShellCommand {
|
||||
}
|
||||
|
||||
synchronized (mInternal.mGlobalLock) {
|
||||
mLetterboxConfiguration.setIsSplitScreenAspectRatioForUnresizableAppsEnabled(enabled);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int runSetTranslucentLetterboxingEnabled(PrintWriter pw) {
|
||||
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.setTranslucentLetterboxingOverrideEnabled(enabled);
|
||||
setter.accept(enabled);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1024,10 +935,12 @@ public class WindowManagerShellCommand extends ShellCommand {
|
||||
runSetLetterboxVerticalPositionMultiplier(pw);
|
||||
break;
|
||||
case "--isHorizontalReachabilityEnabled":
|
||||
runSetLetterboxIsHorizontalReachabilityEnabled(pw);
|
||||
runSetBooleanFlag(pw, mLetterboxConfiguration
|
||||
::setIsHorizontalReachabilityEnabled);
|
||||
break;
|
||||
case "--isVerticalReachabilityEnabled":
|
||||
runSetLetterboxIsVerticalReachabilityEnabled(pw);
|
||||
runSetBooleanFlag(pw, mLetterboxConfiguration
|
||||
::setIsVerticalReachabilityEnabled);
|
||||
break;
|
||||
case "--defaultPositionForHorizontalReachability":
|
||||
runSetLetterboxDefaultPositionForHorizontalReachability(pw);
|
||||
@@ -1036,13 +949,15 @@ public class WindowManagerShellCommand extends ShellCommand {
|
||||
runSetLetterboxDefaultPositionForVerticalReachability(pw);
|
||||
break;
|
||||
case "--isEducationEnabled":
|
||||
runSetLetterboxIsEducationEnabled(pw);
|
||||
runSetBooleanFlag(pw, mLetterboxConfiguration::setIsEducationEnabled);
|
||||
break;
|
||||
case "--isSplitScreenAspectRatioForUnresizableAppsEnabled":
|
||||
runSetLetterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled(pw);
|
||||
runSetBooleanFlag(pw, mLetterboxConfiguration
|
||||
::setIsSplitScreenAspectRatioForUnresizableAppsEnabled);
|
||||
break;
|
||||
case "--isTranslucentLetterboxingEnabled":
|
||||
runSetTranslucentLetterboxingEnabled(pw);
|
||||
runSetBooleanFlag(pw, mLetterboxConfiguration
|
||||
::setTranslucentLetterboxingOverrideEnabled);
|
||||
break;
|
||||
default:
|
||||
getErrPrintWriter().println(
|
||||
@@ -1089,23 +1004,23 @@ public class WindowManagerShellCommand extends ShellCommand {
|
||||
mLetterboxConfiguration.resetLetterboxVerticalPositionMultiplier();
|
||||
break;
|
||||
case "isHorizontalReachabilityEnabled":
|
||||
mLetterboxConfiguration.getIsHorizontalReachabilityEnabled();
|
||||
mLetterboxConfiguration.resetIsHorizontalReachabilityEnabled();
|
||||
break;
|
||||
case "isVerticalReachabilityEnabled":
|
||||
mLetterboxConfiguration.getIsVerticalReachabilityEnabled();
|
||||
mLetterboxConfiguration.resetIsVerticalReachabilityEnabled();
|
||||
break;
|
||||
case "defaultPositionForHorizontalReachability":
|
||||
mLetterboxConfiguration.getDefaultPositionForHorizontalReachability();
|
||||
mLetterboxConfiguration.resetDefaultPositionForHorizontalReachability();
|
||||
break;
|
||||
case "defaultPositionForVerticalReachability":
|
||||
mLetterboxConfiguration.getDefaultPositionForVerticalReachability();
|
||||
mLetterboxConfiguration.resetDefaultPositionForVerticalReachability();
|
||||
break;
|
||||
case "isEducationEnabled":
|
||||
mLetterboxConfiguration.getIsEducationEnabled();
|
||||
mLetterboxConfiguration.resetIsEducationEnabled();
|
||||
break;
|
||||
case "isSplitScreenAspectRatioForUnresizableAppsEnabled":
|
||||
mLetterboxConfiguration
|
||||
.getIsSplitScreenAspectRatioForUnresizableAppsEnabled();
|
||||
.resetIsSplitScreenAspectRatioForUnresizableAppsEnabled();
|
||||
break;
|
||||
case "isTranslucentLetterboxingEnabled":
|
||||
mLetterboxConfiguration.resetTranslucentLetterboxingEnabled();
|
||||
@@ -1255,6 +1170,7 @@ public class WindowManagerShellCommand extends ShellCommand {
|
||||
pw.println("Is using split screen aspect ratio as aspect ratio for unresizable apps: "
|
||||
+ mLetterboxConfiguration
|
||||
.getIsSplitScreenAspectRatioForUnresizableAppsEnabled());
|
||||
|
||||
pw.println("Background type: "
|
||||
+ LetterboxConfiguration.letterboxBackgroundTypeToString(
|
||||
mLetterboxConfiguration.getLetterboxBackgroundType()));
|
||||
@@ -1464,7 +1380,6 @@ public class WindowManagerShellCommand extends ShellCommand {
|
||||
pw.println(" unresizable apps.");
|
||||
pw.println(" --isTranslucentLetterboxingEnabled [true|1|false|0]");
|
||||
pw.println(" Whether letterboxing for translucent activities is enabled.");
|
||||
|
||||
pw.println(" reset-letterbox-style [aspectRatio|cornerRadius|backgroundType");
|
||||
pw.println(" |backgroundColor|wallpaperBlurRadius|wallpaperDarkScrimAlpha");
|
||||
pw.println(" |horizontalPositionMultiplier|verticalPositionMultiplier");
|
||||
|
||||
@@ -39,7 +39,6 @@ import static org.mockito.Mockito.mock;
|
||||
import android.content.ComponentName;
|
||||
import android.content.pm.ActivityInfo.ScreenOrientation;
|
||||
import android.content.res.Configuration.Orientation;
|
||||
import android.content.res.Resources;
|
||||
import android.hardware.camera2.CameraManager;
|
||||
import android.os.Handler;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
@@ -47,8 +46,6 @@ import android.view.Display;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -73,7 +70,7 @@ public final class DisplayRotationCompatPolicyTests extends WindowTestsBase {
|
||||
|
||||
private CameraManager mMockCameraManager;
|
||||
private Handler mMockHandler;
|
||||
private Resources mResources;
|
||||
private LetterboxConfiguration mLetterboxConfiguration;
|
||||
|
||||
private DisplayRotationCompatPolicy mDisplayRotationCompatPolicy;
|
||||
private CameraManager.AvailabilityCallback mCameraAvailabilityCallback;
|
||||
@@ -83,9 +80,10 @@ public final class DisplayRotationCompatPolicyTests extends WindowTestsBase {
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mResources = mContext.getResources();
|
||||
spyOn(mResources);
|
||||
when(mResources.getBoolean(R.bool.config_isWindowManagerCameraCompatTreatmentEnabled))
|
||||
mLetterboxConfiguration = mDisplayContent.mWmService.mLetterboxConfiguration;
|
||||
spyOn(mLetterboxConfiguration);
|
||||
when(mLetterboxConfiguration.isCameraCompatTreatmentEnabled(
|
||||
/* checkDeviceConfig */ anyBoolean()))
|
||||
.thenReturn(true);
|
||||
|
||||
mMockCameraManager = mock(CameraManager.class);
|
||||
@@ -115,7 +113,22 @@ public final class DisplayRotationCompatPolicyTests extends WindowTestsBase {
|
||||
|
||||
@Test
|
||||
public void testGetOrientation_treatmentNotEnabled_returnUnspecified() {
|
||||
when(mResources.getBoolean(R.bool.config_isWindowManagerCameraCompatTreatmentEnabled))
|
||||
when(mLetterboxConfiguration.isCameraCompatTreatmentEnabled(
|
||||
/* checkDeviceConfig */ anyBoolean()))
|
||||
.thenReturn(false);
|
||||
|
||||
mDisplayRotationCompatPolicy = new DisplayRotationCompatPolicy(mDisplayContent);
|
||||
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
|
||||
mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
|
||||
|
||||
assertEquals(mDisplayRotationCompatPolicy.getOrientation(),
|
||||
SCREEN_ORIENTATION_UNSPECIFIED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetOrientation_treatmentDisabledViaDeviceConfig_returnUnspecified() {
|
||||
when(mLetterboxConfiguration.isCameraCompatTreatmentEnabled(
|
||||
/* checkDeviceConfig */ true))
|
||||
.thenReturn(false);
|
||||
|
||||
mDisplayRotationCompatPolicy = new DisplayRotationCompatPolicy(mDisplayContent);
|
||||
|
||||
Reference in New Issue
Block a user