Loading core/java/android/app/CameraCompatTaskInfo.java +30 −8 Original line number Diff line number Diff line Loading @@ -36,20 +36,36 @@ public class CameraCompatTaskInfo implements Parcelable { public static final int CAMERA_COMPAT_FREEFORM_NONE = 0; /** * The value to use when portrait camera compat treatment should be applied to a windowed task. * The value to use when camera compat treatment should be applied to an activity requesting * portrait orientation, while a device is in landscape. Applies only to freeform tasks. */ public static final int CAMERA_COMPAT_FREEFORM_PORTRAIT = 1; public static final int CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE = 1; /** * The value to use when landscape camera compat treatment should be applied to a windowed task. * The value to use when camera compat treatment should be applied to an activity requesting * landscape orientation, while a device is in landscape. Applies only to freeform tasks. */ public static final int CAMERA_COMPAT_FREEFORM_LANDSCAPE = 2; public static final int CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE = 2; /** * The value to use when camera compat treatment should be applied to an activity requesting * portrait orientation, while a device is in portrait. Applies only to freeform tasks. */ public static final int CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT = 3; /** * The value to use when camera compat treatment should be applied to an activity requesting * landscape orientation, while a device is in portrait. Applies only to freeform tasks. */ public static final int CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT = 4; @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "CAMERA_COMPAT_FREEFORM_" }, value = { CAMERA_COMPAT_FREEFORM_NONE, CAMERA_COMPAT_FREEFORM_PORTRAIT, CAMERA_COMPAT_FREEFORM_LANDSCAPE, CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE, CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE, CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT, CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT, }) public @interface FreeformCameraCompatMode {} Loading Loading @@ -143,8 +159,14 @@ public class CameraCompatTaskInfo implements Parcelable { @FreeformCameraCompatMode int freeformCameraCompatMode) { return switch (freeformCameraCompatMode) { case CAMERA_COMPAT_FREEFORM_NONE -> "inactive"; case CAMERA_COMPAT_FREEFORM_PORTRAIT -> "portrait"; case CAMERA_COMPAT_FREEFORM_LANDSCAPE -> "landscape"; case CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE -> "app-portrait-device-landscape"; case CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE -> "app-landscape-device-landscape"; case CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT -> "app-portrait-device-portrait"; case CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT -> "app-landscape-device-portrait"; default -> throw new AssertionError( "Unexpected camera compat mode: " + freeformCameraCompatMode); }; Loading services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java +38 −6 Original line number Diff line number Diff line Loading @@ -16,20 +16,28 @@ package com.android.server.wm; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.content.res.Configuration.ORIENTATION_UNDEFINED; import static android.view.Surface.ROTATION_0; import static android.view.Surface.ROTATION_180; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.CameraCompatTaskInfo; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.view.DisplayInfo; import android.view.Surface; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.ProtoLog; Loading Loading @@ -172,11 +180,35 @@ final class CameraCompatFreeformPolicy implements CameraStateMonitor.CameraCompa } private static int getCameraCompatMode(@NonNull ActivityRecord topActivity) { return switch (topActivity.getRequestedConfigurationOrientation()) { case ORIENTATION_PORTRAIT -> CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT; case ORIENTATION_LANDSCAPE -> CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_LANDSCAPE; default -> CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE; }; final int appOrientation = topActivity.getRequestedConfigurationOrientation(); // It is very important to check the original (actual) display rotation, and not the // sandboxed rotation that camera compat treatment sets. final DisplayInfo displayInfo = topActivity.mWmService.mDisplayManagerInternal .getDisplayInfo(topActivity.getDisplayId()); // This treatment targets only devices with portrait natural orientation, which most tablets // have. // TODO(b/365725400): handle landscape natural orientation. if (displayInfo.getNaturalHeight() > displayInfo.getNaturalWidth()) { if (appOrientation == ORIENTATION_PORTRAIT) { if (isDisplayRotationPortrait(displayInfo.rotation)) { return CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT; } else { return CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE; } } else if (appOrientation == ORIENTATION_LANDSCAPE) { if (isDisplayRotationPortrait(displayInfo.rotation)) { return CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT; } else { return CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE; } } } return CAMERA_COMPAT_FREEFORM_NONE; } private static boolean isDisplayRotationPortrait(@Surface.Rotation int displayRotation) { return displayRotation == ROTATION_0 || displayRotation == ROTATION_180; } /** Loading services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java +65 −11 Original line number Diff line number Diff line Loading @@ -16,11 +16,17 @@ package com.android.server.wm; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.servertransaction.ActivityLifecycleItem.ON_PAUSE; import static android.app.servertransaction.ActivityLifecycleItem.ON_STOP; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; Loading @@ -33,10 +39,10 @@ import static com.android.window.flags.Flags.FLAG_CAMERA_COMPAT_FOR_FREEFORM; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; Loading @@ -55,6 +61,8 @@ import android.graphics.Rect; import android.hardware.camera2.CameraManager; import android.os.Handler; import android.platform.test.annotations.Presubmit; import android.view.DisplayInfo; import android.view.Surface; import androidx.test.filters.SmallTest; Loading Loading @@ -134,6 +142,7 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase { new CameraCompatFreeformPolicy(mDisplayContent, cameraStateMonitor, mActivityRefresher); setDisplayRotation(Surface.ROTATION_90); mCameraCompatFreeformPolicy.start(); cameraStateMonitor.startListeningToCameraState(); } Loading Loading @@ -162,17 +171,49 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase { } @Test public void testCameraConnected_activatesCameraCompatMode() throws Exception { public void testCameraConnected_deviceInPortrait_portraitCameraCompatMode() throws Exception { configureActivity(SCREEN_ORIENTATION_PORTRAIT); setDisplayRotation(Surface.ROTATION_0); mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); assertInCameraCompatMode(); assertInCameraCompatMode(CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT); assertActivityRefreshRequested(/* refreshRequested */ false); } @Test public void testCameraConnected_deviceInLandscape_portraitCameraCompatMode() throws Exception { configureActivity(SCREEN_ORIENTATION_PORTRAIT); setDisplayRotation(Surface.ROTATION_270); mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); assertInCameraCompatMode(CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE); assertActivityRefreshRequested(/* refreshRequested */ false); } @Test public void testCameraConnected_deviceInPortrait_landscapeCameraCompatMode() throws Exception { configureActivity(SCREEN_ORIENTATION_LANDSCAPE); setDisplayRotation(Surface.ROTATION_0); mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); assertInCameraCompatMode(CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT); assertActivityRefreshRequested(/* refreshRequested */ false); } @Test public void testCameraConnected_deviceInLandscape_landscapeCameraCompatMode() throws Exception { configureActivity(SCREEN_ORIENTATION_LANDSCAPE); setDisplayRotation(Surface.ROTATION_270); mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); assertInCameraCompatMode(CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE); assertActivityRefreshRequested(/* refreshRequested */ false); } @Test public void testCameraReconnected_cameraCompatModeAndRefresh() throws Exception { configureActivity(SCREEN_ORIENTATION_PORTRAIT); setDisplayRotation(Surface.ROTATION_270); mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); callOnActivityConfigurationChanging(mActivity); Loading @@ -180,7 +221,7 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase { mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); callOnActivityConfigurationChanging(mActivity); assertInCameraCompatMode(); assertInCameraCompatMode(CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE); assertActivityRefreshRequested(/* refreshRequested */ true); } Loading Loading @@ -285,16 +326,14 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase { doReturn(true).when(mActivity).inFreeformWindowingMode(); } private void assertInCameraCompatMode() { assertNotEquals(CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE, mActivity.mAppCompatController.getAppCompatCameraOverrides() private void assertInCameraCompatMode(@CameraCompatTaskInfo.FreeformCameraCompatMode int mode) { assertEquals(mode, mActivity.mAppCompatController.getAppCompatCameraOverrides() .getFreeformCameraCompatMode()); } private void assertNotInCameraCompatMode() { assertEquals(CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE, mActivity.mAppCompatController.getAppCompatCameraOverrides() .getFreeformCameraCompatMode()); assertEquals(CAMERA_COMPAT_FREEFORM_NONE, mActivity.mAppCompatController .getAppCompatCameraOverrides().getFreeformCameraCompatMode()); } private void assertActivityRefreshRequested(boolean refreshRequested) throws Exception { Loading Loading @@ -328,4 +367,19 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase { configuration.windowConfiguration.setAppBounds(bounds); return configuration; } private void setDisplayRotation(@Surface.Rotation int displayRotation) { doAnswer(invocation -> { DisplayInfo displayInfo = new DisplayInfo(); mDisplayContent.getDisplay().getDisplayInfo(displayInfo); displayInfo.rotation = displayRotation; // Set height so that the natural orientation (rotation is 0) is portrait. This is the // case for most standard phones and tablets. // TODO(b/365725400): handle landscape natural orientation. displayInfo.logicalHeight = displayRotation % 180 == 0 ? 800 : 600; displayInfo.logicalWidth = displayRotation % 180 == 0 ? 600 : 800; return displayInfo; }).when(mDisplayContent.mWmService.mDisplayManagerInternal) .getDisplayInfo(anyInt()); } } services/tests/wmtests/src/com/android/server/wm/TaskTests.java +5 −4 Original line number Diff line number Diff line Loading @@ -16,7 +16,9 @@ package com.android.server.wm; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; Loading Loading @@ -71,7 +73,6 @@ import static org.mockito.Mockito.never; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.CameraCompatTaskInfo; import android.app.TaskInfo; import android.app.WindowConfiguration; import android.content.ComponentName; Loading Loading @@ -2025,10 +2026,10 @@ public class TaskTests extends WindowTestsBase { public void getTaskInfoPropagatesCameraCompatMode() { final Task task = new TaskBuilder(mSupervisor).setCreateActivity(true).build(); final ActivityRecord activity = task.getTopMostActivity(); activity.mAppCompatController.getAppCompatCameraOverrides() .setFreeformCameraCompatMode(CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT); activity.mAppCompatController.getAppCompatCameraOverrides().setFreeformCameraCompatMode( CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE); assertEquals(CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT, assertEquals(CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE, task.getTaskInfo().appCompatTaskInfo.cameraCompatTaskInfo.freeformCameraCompatMode); } Loading Loading
core/java/android/app/CameraCompatTaskInfo.java +30 −8 Original line number Diff line number Diff line Loading @@ -36,20 +36,36 @@ public class CameraCompatTaskInfo implements Parcelable { public static final int CAMERA_COMPAT_FREEFORM_NONE = 0; /** * The value to use when portrait camera compat treatment should be applied to a windowed task. * The value to use when camera compat treatment should be applied to an activity requesting * portrait orientation, while a device is in landscape. Applies only to freeform tasks. */ public static final int CAMERA_COMPAT_FREEFORM_PORTRAIT = 1; public static final int CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE = 1; /** * The value to use when landscape camera compat treatment should be applied to a windowed task. * The value to use when camera compat treatment should be applied to an activity requesting * landscape orientation, while a device is in landscape. Applies only to freeform tasks. */ public static final int CAMERA_COMPAT_FREEFORM_LANDSCAPE = 2; public static final int CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE = 2; /** * The value to use when camera compat treatment should be applied to an activity requesting * portrait orientation, while a device is in portrait. Applies only to freeform tasks. */ public static final int CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT = 3; /** * The value to use when camera compat treatment should be applied to an activity requesting * landscape orientation, while a device is in portrait. Applies only to freeform tasks. */ public static final int CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT = 4; @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "CAMERA_COMPAT_FREEFORM_" }, value = { CAMERA_COMPAT_FREEFORM_NONE, CAMERA_COMPAT_FREEFORM_PORTRAIT, CAMERA_COMPAT_FREEFORM_LANDSCAPE, CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE, CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE, CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT, CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT, }) public @interface FreeformCameraCompatMode {} Loading Loading @@ -143,8 +159,14 @@ public class CameraCompatTaskInfo implements Parcelable { @FreeformCameraCompatMode int freeformCameraCompatMode) { return switch (freeformCameraCompatMode) { case CAMERA_COMPAT_FREEFORM_NONE -> "inactive"; case CAMERA_COMPAT_FREEFORM_PORTRAIT -> "portrait"; case CAMERA_COMPAT_FREEFORM_LANDSCAPE -> "landscape"; case CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE -> "app-portrait-device-landscape"; case CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE -> "app-landscape-device-landscape"; case CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT -> "app-portrait-device-portrait"; case CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT -> "app-landscape-device-portrait"; default -> throw new AssertionError( "Unexpected camera compat mode: " + freeformCameraCompatMode); }; Loading
services/core/java/com/android/server/wm/CameraCompatFreeformPolicy.java +38 −6 Original line number Diff line number Diff line Loading @@ -16,20 +16,28 @@ package com.android.server.wm; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.content.res.Configuration.ORIENTATION_UNDEFINED; import static android.view.Surface.ROTATION_0; import static android.view.Surface.ROTATION_180; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.CameraCompatTaskInfo; import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.view.DisplayInfo; import android.view.Surface; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.ProtoLog; Loading Loading @@ -172,11 +180,35 @@ final class CameraCompatFreeformPolicy implements CameraStateMonitor.CameraCompa } private static int getCameraCompatMode(@NonNull ActivityRecord topActivity) { return switch (topActivity.getRequestedConfigurationOrientation()) { case ORIENTATION_PORTRAIT -> CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT; case ORIENTATION_LANDSCAPE -> CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_LANDSCAPE; default -> CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE; }; final int appOrientation = topActivity.getRequestedConfigurationOrientation(); // It is very important to check the original (actual) display rotation, and not the // sandboxed rotation that camera compat treatment sets. final DisplayInfo displayInfo = topActivity.mWmService.mDisplayManagerInternal .getDisplayInfo(topActivity.getDisplayId()); // This treatment targets only devices with portrait natural orientation, which most tablets // have. // TODO(b/365725400): handle landscape natural orientation. if (displayInfo.getNaturalHeight() > displayInfo.getNaturalWidth()) { if (appOrientation == ORIENTATION_PORTRAIT) { if (isDisplayRotationPortrait(displayInfo.rotation)) { return CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT; } else { return CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE; } } else if (appOrientation == ORIENTATION_LANDSCAPE) { if (isDisplayRotationPortrait(displayInfo.rotation)) { return CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT; } else { return CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE; } } } return CAMERA_COMPAT_FREEFORM_NONE; } private static boolean isDisplayRotationPortrait(@Surface.Rotation int displayRotation) { return displayRotation == ROTATION_0 || displayRotation == ROTATION_180; } /** Loading
services/tests/wmtests/src/com/android/server/wm/CameraCompatFreeformPolicyTests.java +65 −11 Original line number Diff line number Diff line Loading @@ -16,11 +16,17 @@ package com.android.server.wm; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.servertransaction.ActivityLifecycleItem.ON_PAUSE; import static android.app.servertransaction.ActivityLifecycleItem.ON_STOP; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FREEFORM_WINDOWING_TREATMENT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; Loading @@ -33,10 +39,10 @@ import static com.android.window.flags.Flags.FLAG_CAMERA_COMPAT_FOR_FREEFORM; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; Loading @@ -55,6 +61,8 @@ import android.graphics.Rect; import android.hardware.camera2.CameraManager; import android.os.Handler; import android.platform.test.annotations.Presubmit; import android.view.DisplayInfo; import android.view.Surface; import androidx.test.filters.SmallTest; Loading Loading @@ -134,6 +142,7 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase { new CameraCompatFreeformPolicy(mDisplayContent, cameraStateMonitor, mActivityRefresher); setDisplayRotation(Surface.ROTATION_90); mCameraCompatFreeformPolicy.start(); cameraStateMonitor.startListeningToCameraState(); } Loading Loading @@ -162,17 +171,49 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase { } @Test public void testCameraConnected_activatesCameraCompatMode() throws Exception { public void testCameraConnected_deviceInPortrait_portraitCameraCompatMode() throws Exception { configureActivity(SCREEN_ORIENTATION_PORTRAIT); setDisplayRotation(Surface.ROTATION_0); mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); assertInCameraCompatMode(); assertInCameraCompatMode(CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_PORTRAIT); assertActivityRefreshRequested(/* refreshRequested */ false); } @Test public void testCameraConnected_deviceInLandscape_portraitCameraCompatMode() throws Exception { configureActivity(SCREEN_ORIENTATION_PORTRAIT); setDisplayRotation(Surface.ROTATION_270); mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); assertInCameraCompatMode(CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE); assertActivityRefreshRequested(/* refreshRequested */ false); } @Test public void testCameraConnected_deviceInPortrait_landscapeCameraCompatMode() throws Exception { configureActivity(SCREEN_ORIENTATION_LANDSCAPE); setDisplayRotation(Surface.ROTATION_0); mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); assertInCameraCompatMode(CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_PORTRAIT); assertActivityRefreshRequested(/* refreshRequested */ false); } @Test public void testCameraConnected_deviceInLandscape_landscapeCameraCompatMode() throws Exception { configureActivity(SCREEN_ORIENTATION_LANDSCAPE); setDisplayRotation(Surface.ROTATION_270); mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); assertInCameraCompatMode(CAMERA_COMPAT_FREEFORM_LANDSCAPE_DEVICE_IN_LANDSCAPE); assertActivityRefreshRequested(/* refreshRequested */ false); } @Test public void testCameraReconnected_cameraCompatModeAndRefresh() throws Exception { configureActivity(SCREEN_ORIENTATION_PORTRAIT); setDisplayRotation(Surface.ROTATION_270); mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); callOnActivityConfigurationChanging(mActivity); Loading @@ -180,7 +221,7 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase { mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1); callOnActivityConfigurationChanging(mActivity); assertInCameraCompatMode(); assertInCameraCompatMode(CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE); assertActivityRefreshRequested(/* refreshRequested */ true); } Loading Loading @@ -285,16 +326,14 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase { doReturn(true).when(mActivity).inFreeformWindowingMode(); } private void assertInCameraCompatMode() { assertNotEquals(CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE, mActivity.mAppCompatController.getAppCompatCameraOverrides() private void assertInCameraCompatMode(@CameraCompatTaskInfo.FreeformCameraCompatMode int mode) { assertEquals(mode, mActivity.mAppCompatController.getAppCompatCameraOverrides() .getFreeformCameraCompatMode()); } private void assertNotInCameraCompatMode() { assertEquals(CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_NONE, mActivity.mAppCompatController.getAppCompatCameraOverrides() .getFreeformCameraCompatMode()); assertEquals(CAMERA_COMPAT_FREEFORM_NONE, mActivity.mAppCompatController .getAppCompatCameraOverrides().getFreeformCameraCompatMode()); } private void assertActivityRefreshRequested(boolean refreshRequested) throws Exception { Loading Loading @@ -328,4 +367,19 @@ public class CameraCompatFreeformPolicyTests extends WindowTestsBase { configuration.windowConfiguration.setAppBounds(bounds); return configuration; } private void setDisplayRotation(@Surface.Rotation int displayRotation) { doAnswer(invocation -> { DisplayInfo displayInfo = new DisplayInfo(); mDisplayContent.getDisplay().getDisplayInfo(displayInfo); displayInfo.rotation = displayRotation; // Set height so that the natural orientation (rotation is 0) is portrait. This is the // case for most standard phones and tablets. // TODO(b/365725400): handle landscape natural orientation. displayInfo.logicalHeight = displayRotation % 180 == 0 ? 800 : 600; displayInfo.logicalWidth = displayRotation % 180 == 0 ? 600 : 800; return displayInfo; }).when(mDisplayContent.mWmService.mDisplayManagerInternal) .getDisplayInfo(anyInt()); } }
services/tests/wmtests/src/com/android/server/wm/TaskTests.java +5 −4 Original line number Diff line number Diff line Loading @@ -16,7 +16,9 @@ package com.android.server.wm; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; Loading Loading @@ -71,7 +73,6 @@ import static org.mockito.Mockito.never; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.CameraCompatTaskInfo; import android.app.TaskInfo; import android.app.WindowConfiguration; import android.content.ComponentName; Loading Loading @@ -2025,10 +2026,10 @@ public class TaskTests extends WindowTestsBase { public void getTaskInfoPropagatesCameraCompatMode() { final Task task = new TaskBuilder(mSupervisor).setCreateActivity(true).build(); final ActivityRecord activity = task.getTopMostActivity(); activity.mAppCompatController.getAppCompatCameraOverrides() .setFreeformCameraCompatMode(CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT); activity.mAppCompatController.getAppCompatCameraOverrides().setFreeformCameraCompatMode( CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE); assertEquals(CameraCompatTaskInfo.CAMERA_COMPAT_FREEFORM_PORTRAIT, assertEquals(CAMERA_COMPAT_FREEFORM_PORTRAIT_DEVICE_IN_LANDSCAPE, task.getTaskInfo().appCompatTaskInfo.cameraCompatTaskInfo.freeformCameraCompatMode); } Loading