[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:
Mariia Sandrikova
2022-08-21 22:06:48 +00:00
parent 83c300c0f9
commit da4c552378
5 changed files with 73 additions and 129 deletions

View File

@@ -1160,7 +1160,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
updateDisplayAreaOrganizers(); updateDisplayAreaOrganizers();
mDisplayRotationCompatPolicy = 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; ? new DisplayRotationCompatPolicy(this) : null;
mInputMonitor = new InputMonitor(mWmService, this); mInputMonitor = new InputMonitor(mWmService, this);

View File

@@ -30,14 +30,12 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.ActivityInfo.ScreenOrientation; import android.content.pm.ActivityInfo.ScreenOrientation;
import android.hardware.camera2.CameraManager; import android.hardware.camera2.CameraManager;
import android.os.Handler; import android.os.Handler;
import android.util.ArrayMap; import android.util.ArrayMap;
import android.util.ArraySet; import android.util.ArraySet;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog; import com.android.internal.protolog.common.ProtoLog;
@@ -77,8 +75,6 @@ final class DisplayRotationCompatPolicy {
private final WindowManagerService mWmService; private final WindowManagerService mWmService;
private final CameraManager mCameraManager; private final CameraManager mCameraManager;
private final Handler mHandler; 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 // 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 // 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; mHandler = handler;
mDisplayContent = displayContent; mDisplayContent = displayContent;
mWmService = displayContent.mWmService; mWmService = displayContent.mWmService;
mIsTreatmentEnabled = isTreatmentEnabled(mWmService.mContext);
mCameraManager = mWmService.mContext.getSystemService(CameraManager.class); mCameraManager = mWmService.mContext.getSystemService(CameraManager.class);
mCameraManager.registerAvailabilityCallback( mCameraManager.registerAvailabilityCallback(
mWmService.mContext.getMainExecutor(), mAvailabilityCallback); mWmService.mContext.getMainExecutor(), mAvailabilityCallback);
} }
static boolean isTreatmentEnabled(@NonNull Context context) {
return context.getResources().getBoolean(
R.bool.config_isWindowManagerCameraCompatTreatmentEnabled);
}
void dispose() { void dispose() {
mCameraManager.unregisterAvailabilityCallback(mAvailabilityCallback); mCameraManager.unregisterAvailabilityCallback(mAvailabilityCallback);
} }
@@ -190,7 +180,9 @@ final class DisplayRotationCompatPolicy {
* </ul> * </ul>
*/ */
private boolean isTreatmentEnabledForDisplay() { 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 // TODO(b/225928882): Support camera compat rotation for external displays
&& mDisplayContent.getDisplay().getType() == TYPE_INTERNAL; && mDisplayContent.getDisplay().getType() == TYPE_INTERNAL;
} }

View File

@@ -191,6 +191,10 @@ final class LetterboxConfiguration {
// Allows to enable letterboxing strategy for translucent activities ignoring flags. // Allows to enable letterboxing strategy for translucent activities ignoring flags.
private boolean mTranslucentLetterboxingOverrideEnabled; private boolean mTranslucentLetterboxingOverrideEnabled;
// Whether camera compatibility treatment is enabled.
// See DisplayRotationCompatPolicy for context.
private final boolean mIsCameraCompatTreatmentEnabled;
LetterboxConfiguration(Context systemUiContext) { LetterboxConfiguration(Context systemUiContext) {
this(systemUiContext, new LetterboxConfigurationPersister(systemUiContext, this(systemUiContext, new LetterboxConfigurationPersister(systemUiContext,
() -> readLetterboxHorizontalReachabilityPositionFromConfig(systemUiContext, () -> readLetterboxHorizontalReachabilityPositionFromConfig(systemUiContext,
@@ -241,6 +245,8 @@ final class LetterboxConfiguration {
R.bool.config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled); R.bool.config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled);
mTranslucentLetterboxingEnabled = mContext.getResources().getBoolean( mTranslucentLetterboxingEnabled = mContext.getResources().getBoolean(
R.bool.config_letterboxIsEnabledForTranslucentActivities); R.bool.config_letterboxIsEnabledForTranslucentActivities);
mIsCameraCompatTreatmentEnabled = mContext.getResources().getBoolean(
R.bool.config_isWindowManagerCameraCompatTreatmentEnabled);
mLetterboxConfigurationPersister = letterboxConfigurationPersister; mLetterboxConfigurationPersister = letterboxConfigurationPersister;
mLetterboxConfigurationPersister.start(); mLetterboxConfigurationPersister.start();
} }
@@ -947,9 +953,24 @@ final class LetterboxConfiguration {
isDeviceInTabletopMode, nextVerticalPosition); 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() { static boolean isTranslucentLetterboxingAllowed() {
return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER, return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_WINDOW_MANAGER,
"enable_translucent_activity_letterbox", false); "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);
}
} }

View File

@@ -53,6 +53,7 @@ import com.android.server.wm.LetterboxConfiguration.LetterboxVerticalReachabilit
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.function.Consumer;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
@@ -806,54 +807,6 @@ public class WindowManagerShellCommand extends ShellCommand {
return 0; 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) private int runSetLetterboxDefaultPositionForHorizontalReachability(PrintWriter pw)
throws RemoteException { throws RemoteException {
@LetterboxHorizontalReachabilityPosition final int position; @LetterboxHorizontalReachabilityPosition final int position;
@@ -916,32 +869,13 @@ public class WindowManagerShellCommand extends ShellCommand {
return 0; return 0;
} }
private int runSetLetterboxIsEducationEnabled(PrintWriter pw) throws RemoteException { private int runSetBooleanFlag(PrintWriter pw, Consumer<Boolean> setter)
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)
throws RemoteException { throws RemoteException {
String arg = getNextArg(); String arg = getNextArg();
if (arg == null) {
getErrPrintWriter().println("Error: expected true, 1, false, 0, but got empty input.");
return -1;
}
final boolean enabled; final boolean enabled;
switch (arg) { switch (arg) {
case "true": case "true":
@@ -958,30 +892,7 @@ public class WindowManagerShellCommand extends ShellCommand {
} }
synchronized (mInternal.mGlobalLock) { synchronized (mInternal.mGlobalLock) {
mLetterboxConfiguration.setIsSplitScreenAspectRatioForUnresizableAppsEnabled(enabled); setter.accept(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);
} }
return 0; return 0;
} }
@@ -1024,10 +935,12 @@ public class WindowManagerShellCommand extends ShellCommand {
runSetLetterboxVerticalPositionMultiplier(pw); runSetLetterboxVerticalPositionMultiplier(pw);
break; break;
case "--isHorizontalReachabilityEnabled": case "--isHorizontalReachabilityEnabled":
runSetLetterboxIsHorizontalReachabilityEnabled(pw); runSetBooleanFlag(pw, mLetterboxConfiguration
::setIsHorizontalReachabilityEnabled);
break; break;
case "--isVerticalReachabilityEnabled": case "--isVerticalReachabilityEnabled":
runSetLetterboxIsVerticalReachabilityEnabled(pw); runSetBooleanFlag(pw, mLetterboxConfiguration
::setIsVerticalReachabilityEnabled);
break; break;
case "--defaultPositionForHorizontalReachability": case "--defaultPositionForHorizontalReachability":
runSetLetterboxDefaultPositionForHorizontalReachability(pw); runSetLetterboxDefaultPositionForHorizontalReachability(pw);
@@ -1036,13 +949,15 @@ public class WindowManagerShellCommand extends ShellCommand {
runSetLetterboxDefaultPositionForVerticalReachability(pw); runSetLetterboxDefaultPositionForVerticalReachability(pw);
break; break;
case "--isEducationEnabled": case "--isEducationEnabled":
runSetLetterboxIsEducationEnabled(pw); runSetBooleanFlag(pw, mLetterboxConfiguration::setIsEducationEnabled);
break; break;
case "--isSplitScreenAspectRatioForUnresizableAppsEnabled": case "--isSplitScreenAspectRatioForUnresizableAppsEnabled":
runSetLetterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled(pw); runSetBooleanFlag(pw, mLetterboxConfiguration
::setIsSplitScreenAspectRatioForUnresizableAppsEnabled);
break; break;
case "--isTranslucentLetterboxingEnabled": case "--isTranslucentLetterboxingEnabled":
runSetTranslucentLetterboxingEnabled(pw); runSetBooleanFlag(pw, mLetterboxConfiguration
::setTranslucentLetterboxingOverrideEnabled);
break; break;
default: default:
getErrPrintWriter().println( getErrPrintWriter().println(
@@ -1089,23 +1004,23 @@ public class WindowManagerShellCommand extends ShellCommand {
mLetterboxConfiguration.resetLetterboxVerticalPositionMultiplier(); mLetterboxConfiguration.resetLetterboxVerticalPositionMultiplier();
break; break;
case "isHorizontalReachabilityEnabled": case "isHorizontalReachabilityEnabled":
mLetterboxConfiguration.getIsHorizontalReachabilityEnabled(); mLetterboxConfiguration.resetIsHorizontalReachabilityEnabled();
break; break;
case "isVerticalReachabilityEnabled": case "isVerticalReachabilityEnabled":
mLetterboxConfiguration.getIsVerticalReachabilityEnabled(); mLetterboxConfiguration.resetIsVerticalReachabilityEnabled();
break; break;
case "defaultPositionForHorizontalReachability": case "defaultPositionForHorizontalReachability":
mLetterboxConfiguration.getDefaultPositionForHorizontalReachability(); mLetterboxConfiguration.resetDefaultPositionForHorizontalReachability();
break; break;
case "defaultPositionForVerticalReachability": case "defaultPositionForVerticalReachability":
mLetterboxConfiguration.getDefaultPositionForVerticalReachability(); mLetterboxConfiguration.resetDefaultPositionForVerticalReachability();
break; break;
case "isEducationEnabled": case "isEducationEnabled":
mLetterboxConfiguration.getIsEducationEnabled(); mLetterboxConfiguration.resetIsEducationEnabled();
break; break;
case "isSplitScreenAspectRatioForUnresizableAppsEnabled": case "isSplitScreenAspectRatioForUnresizableAppsEnabled":
mLetterboxConfiguration mLetterboxConfiguration
.getIsSplitScreenAspectRatioForUnresizableAppsEnabled(); .resetIsSplitScreenAspectRatioForUnresizableAppsEnabled();
break; break;
case "isTranslucentLetterboxingEnabled": case "isTranslucentLetterboxingEnabled":
mLetterboxConfiguration.resetTranslucentLetterboxingEnabled(); 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: " pw.println("Is using split screen aspect ratio as aspect ratio for unresizable apps: "
+ mLetterboxConfiguration + mLetterboxConfiguration
.getIsSplitScreenAspectRatioForUnresizableAppsEnabled()); .getIsSplitScreenAspectRatioForUnresizableAppsEnabled());
pw.println("Background type: " pw.println("Background type: "
+ LetterboxConfiguration.letterboxBackgroundTypeToString( + LetterboxConfiguration.letterboxBackgroundTypeToString(
mLetterboxConfiguration.getLetterboxBackgroundType())); mLetterboxConfiguration.getLetterboxBackgroundType()));
@@ -1464,7 +1380,6 @@ public class WindowManagerShellCommand extends ShellCommand {
pw.println(" unresizable apps."); pw.println(" unresizable apps.");
pw.println(" --isTranslucentLetterboxingEnabled [true|1|false|0]"); pw.println(" --isTranslucentLetterboxingEnabled [true|1|false|0]");
pw.println(" Whether letterboxing for translucent activities is enabled."); pw.println(" Whether letterboxing for translucent activities is enabled.");
pw.println(" reset-letterbox-style [aspectRatio|cornerRadius|backgroundType"); pw.println(" reset-letterbox-style [aspectRatio|cornerRadius|backgroundType");
pw.println(" |backgroundColor|wallpaperBlurRadius|wallpaperDarkScrimAlpha"); pw.println(" |backgroundColor|wallpaperBlurRadius|wallpaperDarkScrimAlpha");
pw.println(" |horizontalPositionMultiplier|verticalPositionMultiplier"); pw.println(" |horizontalPositionMultiplier|verticalPositionMultiplier");

View File

@@ -39,7 +39,6 @@ import static org.mockito.Mockito.mock;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.pm.ActivityInfo.ScreenOrientation; import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.res.Configuration.Orientation; import android.content.res.Configuration.Orientation;
import android.content.res.Resources;
import android.hardware.camera2.CameraManager; import android.hardware.camera2.CameraManager;
import android.os.Handler; import android.os.Handler;
import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.Presubmit;
@@ -47,8 +46,6 @@ import android.view.Display;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import com.android.internal.R;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@@ -73,7 +70,7 @@ public final class DisplayRotationCompatPolicyTests extends WindowTestsBase {
private CameraManager mMockCameraManager; private CameraManager mMockCameraManager;
private Handler mMockHandler; private Handler mMockHandler;
private Resources mResources; private LetterboxConfiguration mLetterboxConfiguration;
private DisplayRotationCompatPolicy mDisplayRotationCompatPolicy; private DisplayRotationCompatPolicy mDisplayRotationCompatPolicy;
private CameraManager.AvailabilityCallback mCameraAvailabilityCallback; private CameraManager.AvailabilityCallback mCameraAvailabilityCallback;
@@ -83,9 +80,10 @@ public final class DisplayRotationCompatPolicyTests extends WindowTestsBase {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
mResources = mContext.getResources(); mLetterboxConfiguration = mDisplayContent.mWmService.mLetterboxConfiguration;
spyOn(mResources); spyOn(mLetterboxConfiguration);
when(mResources.getBoolean(R.bool.config_isWindowManagerCameraCompatTreatmentEnabled)) when(mLetterboxConfiguration.isCameraCompatTreatmentEnabled(
/* checkDeviceConfig */ anyBoolean()))
.thenReturn(true); .thenReturn(true);
mMockCameraManager = mock(CameraManager.class); mMockCameraManager = mock(CameraManager.class);
@@ -115,7 +113,22 @@ public final class DisplayRotationCompatPolicyTests extends WindowTestsBase {
@Test @Test
public void testGetOrientation_treatmentNotEnabled_returnUnspecified() { 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); .thenReturn(false);
mDisplayRotationCompatPolicy = new DisplayRotationCompatPolicy(mDisplayContent); mDisplayRotationCompatPolicy = new DisplayRotationCompatPolicy(mDisplayContent);