From da4c552378996238e899a84ddcc26be3ebb6ca29 Mon Sep 17 00:00:00 2001 From: Mariia Sandrikova Date: Sun, 21 Aug 2022 22:06:48 +0000 Subject: [PATCH] [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 --- .../com/android/server/wm/DisplayContent.java | 5 +- .../wm/DisplayRotationCompatPolicy.java | 14 +- .../server/wm/LetterboxConfiguration.java | 23 ++- .../server/wm/WindowManagerShellCommand.java | 131 +++--------------- .../wm/DisplayRotationCompatPolicyTests.java | 29 ++-- 5 files changed, 73 insertions(+), 129 deletions(-) diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index ccae0a87685a8..c97d7a97d8863 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -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); diff --git a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java index a19539d10e5e4..0d3f784849bae 100644 --- a/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java @@ -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 { * */ 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; } diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java index 3eca364ff5fc0..793a352aeec67 100644 --- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java +++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java @@ -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); + } + } diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java index 85aa9425c4fd6..554f271a31a74 100644 --- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java +++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java @@ -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 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"); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java index fda578da32354..d66215051d625 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayRotationCompatPolicyTests.java @@ -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);