Merge "[4/n] Camera Compat: per-app controls for force rotation and refresh" into tm-qpr-dev am: 6162cc7f05
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20821091 Change-Id: I4c526344409a37df6ea3b2823f8b2946176c026b Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -1057,6 +1057,41 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
@TestApi
|
||||
public static final long ALWAYS_SANDBOX_DISPLAY_APIS = 185004937L; // buganizer id
|
||||
|
||||
/**
|
||||
* This change id excludes the packages it is applied to from the camera compat force rotation
|
||||
* treatment. See com.android.server.wm.DisplayRotationCompatPolicy for context.
|
||||
* @hide
|
||||
*/
|
||||
@ChangeId
|
||||
@Overridable
|
||||
@Disabled
|
||||
public static final long OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION =
|
||||
263959004L; // buganizer id
|
||||
|
||||
/**
|
||||
* This change id excludes the packages it is applied to from activity refresh after camera
|
||||
* compat force rotation treatment. See com.android.server.wm.DisplayRotationCompatPolicy for
|
||||
* context.
|
||||
* @hide
|
||||
*/
|
||||
@ChangeId
|
||||
@Overridable
|
||||
@Disabled
|
||||
public static final long OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH = 264304459L; // buganizer id
|
||||
|
||||
/**
|
||||
* This change id makes the packages it is applied to do activity refresh after camera compat
|
||||
* force rotation treatment using "resumed -> paused -> resumed" cycle rather than "resumed ->
|
||||
* ... -> stopped -> ... -> resumed" cycle. See
|
||||
* com.android.server.wm.DisplayRotationCompatPolicy for context.
|
||||
* @hide
|
||||
*/
|
||||
@ChangeId
|
||||
@Overridable
|
||||
@Disabled
|
||||
public static final long OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE =
|
||||
264301586L; // buganizer id
|
||||
|
||||
/**
|
||||
* This change id is the gatekeeper for all treatments that force a given min aspect ratio.
|
||||
* Enabling this change will allow the following min aspect ratio treatments to be applied:
|
||||
|
||||
@@ -852,6 +852,143 @@ public interface WindowManager extends ViewManager {
|
||||
String PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION =
|
||||
"android.window.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION";
|
||||
|
||||
/**
|
||||
* Activity level {@link android.content.pm.PackageManager.Property PackageManager
|
||||
* .Property} for an app to inform the system that the activity should be excluded from the
|
||||
* camera compatibility force rotation treatment.
|
||||
*
|
||||
* <p>The camera compatibility treatment aligns orientations of portrait app window and natural
|
||||
* orientation of the device and set opposite to natural orientation for a landscape app
|
||||
* window. Mismatch between them can lead to camera issues like sideways or stretched
|
||||
* viewfinder since this is one of the strongest assumptions that apps make when they implement
|
||||
* camera previews. Since app and natural display orientations aren't guaranteed to match, the
|
||||
* rotation can cause letterboxing. The forced rotation is triggered as soon as app opens to
|
||||
* camera and is removed once camera is closed.
|
||||
*
|
||||
* <p>The camera compatibility can be enabled by device manufacturers on the displays that have
|
||||
* ignoreOrientationRequest display setting enabled (enables compatibility mode for fixed
|
||||
* orientation, see <a href="https://developer.android.com/guide/practices/enhanced-letterboxing">Enhanced letterboxing</a>
|
||||
* for more details).
|
||||
*
|
||||
* <p>With this property set to {@code true} or unset, the system may apply the force rotation
|
||||
* treatment to fixed orientation activities. Device manufacturers can exclude packages from the
|
||||
* treatment using their discretion to improve display compatibility.
|
||||
*
|
||||
* <p>With this property set to {@code false}, the system will not apply the force rotation
|
||||
* treatment.
|
||||
*
|
||||
* <p><b>Syntax:</b>
|
||||
* <pre>
|
||||
* <activity>
|
||||
* <property
|
||||
* android:name="android.window.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION"
|
||||
* android:value="true|false"/>
|
||||
* </activity>
|
||||
* </pre>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
// TODO(b/263984287): Make this public API.
|
||||
String PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION =
|
||||
"android.window.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION";
|
||||
|
||||
/**
|
||||
* Activity level {@link android.content.pm.PackageManager.Property PackageManager
|
||||
* .Property} for an app to inform the system that the activity should be excluded
|
||||
* from the activity "refresh" after the camera compatibility force rotation treatment.
|
||||
*
|
||||
* <p>The camera compatibility treatment aligns orientations of portrait app window and natural
|
||||
* orientation of the device and set opposite to natural orientation for a landscape app
|
||||
* window. Mismatch between them can lead to camera issues like sideways or stretched
|
||||
* viewfinder since this is one of the strongest assumptions that apps make when they implement
|
||||
* camera previews. Since app and natural display orientations aren't guaranteed to match, the
|
||||
* rotation can cause letterboxing. The forced rotation is triggered as soon as app opens to
|
||||
* camera and is removed once camera is closed.
|
||||
*
|
||||
* <p>Force rotation is followed by the "Refresh" of the activity by going through "resumed ->
|
||||
* ... -> stopped -> ... -> resumed" cycle (by default) or "resumed -> paused -> resumed" cycle
|
||||
* (if overridden, see {@link #PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE} for context).
|
||||
* This allows to clear cached values in apps (e.g. display or camera rotation) that influence
|
||||
* camera preview and can lead to sideways or stretching issues persisting even after force
|
||||
* rotation.
|
||||
*
|
||||
* <p>The camera compatibility can be enabled by device manufacturers on the displays that have
|
||||
* ignoreOrientationRequest display setting enabled (enables compatibility mode for fixed
|
||||
* orientation, see <a href="https://developer.android.com/guide/practices/enhanced-letterboxing">Enhanced letterboxing</a>
|
||||
* for more details).
|
||||
*
|
||||
* <p>With this property set to {@code true} or unset, the system may "refresh" activity after
|
||||
* the force rotation treatment. Device manufacturers can exclude packages from the "refresh"
|
||||
* using their discretion to improve display compatibility.
|
||||
*
|
||||
* <p>With this property set to {@code false}, the system will not "refresh" activity after the
|
||||
* force rotation treatment.
|
||||
*
|
||||
* <p><b>Syntax:</b>
|
||||
* <pre>
|
||||
* <activity>
|
||||
* <property
|
||||
* android:name="android.window.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH"
|
||||
* android:value="true|false"/>
|
||||
* </activity>
|
||||
* </pre>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
// TODO(b/263984287): Make this public API.
|
||||
String PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH =
|
||||
"android.window.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH";
|
||||
|
||||
/**
|
||||
* Activity level {@link android.content.pm.PackageManager.Property PackageManager
|
||||
* .Property} for an app to inform the system that the activity should be or shouldn't be
|
||||
* "refreshed" after the camera compatibility force rotation treatment using "paused ->
|
||||
* resumed" cycle rather than "stopped -> resumed".
|
||||
*
|
||||
* <p>The camera compatibility treatment aligns orientations of portrait app window and natural
|
||||
* orientation of the device and set opposite to natural orientation for a landscape app
|
||||
* window. Mismatch between them can lead to camera issues like sideways or stretched
|
||||
* viewfinder since this is one of the strongest assumptions that apps make when they implement
|
||||
* camera previews. Since app and natural display orientations aren't guaranteed to match, the
|
||||
* rotation can cause letterboxing. The forced rotation is triggered as soon as app opens to
|
||||
* camera and is removed once camera is closed.
|
||||
*
|
||||
* <p>Force rotation is followed by the "Refresh" of the activity by going through "resumed ->
|
||||
* ... -> stopped -> ... -> resumed" cycle (by default) or "resumed -> paused -> resumed" cycle
|
||||
* (if overridden by device manufacturers or using this property). This allows to clear cached
|
||||
* values in apps (e.g., display or camera rotation) that influence camera preview and can lead
|
||||
* to sideways or stretching issues persisting even after force rotation.
|
||||
*
|
||||
* <p>The camera compatibility can be enabled by device manufacturers on the displays that have
|
||||
* ignoreOrientationRequest display setting enabled (enables compatibility mode for fixed
|
||||
* orientation, see <a href="https://developer.android.com/guide/practices/enhanced-letterboxing">Enhanced letterboxing</a>
|
||||
* for more details).
|
||||
*
|
||||
* <p>Device manufacturers can override packages to "refresh" via "resumed -> paused -> resumed"
|
||||
* cycle using their discretion to improve display compatibility.
|
||||
*
|
||||
* <p>With this property set to {@code true}, the system will "refresh" activity after the
|
||||
* force rotation treatment using "resumed -> paused -> resumed" cycle.
|
||||
*
|
||||
* <p>With this property set to {@code false}, the system will not "refresh" activity after the
|
||||
* force rotation treatment using "resumed -> paused -> resumed" cycle even if the device
|
||||
* manufacturer adds the corresponding override.
|
||||
*
|
||||
* <p><b>Syntax:</b>
|
||||
* <pre>
|
||||
* <activity>
|
||||
* <property
|
||||
* android:name="android.window.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE"
|
||||
* android:value="true|false"/>
|
||||
* </activity>
|
||||
* </pre>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
// TODO(b/263984287): Make this public API.
|
||||
String PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE =
|
||||
"android.window.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE";
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
|
||||
@@ -203,8 +203,11 @@ final class DisplayRotationCompatPolicy {
|
||||
|| !shouldRefreshActivity(activity, newConfig, lastReportedConfig)) {
|
||||
return;
|
||||
}
|
||||
boolean cycleThroughStop = mWmService.mLetterboxConfiguration
|
||||
.isCameraCompatRefreshCycleThroughStopEnabled();
|
||||
boolean cycleThroughStop =
|
||||
mWmService.mLetterboxConfiguration
|
||||
.isCameraCompatRefreshCycleThroughStopEnabled()
|
||||
&& !activity.mLetterboxUiController
|
||||
.shouldRefreshActivityViaPauseForCameraCompat();
|
||||
try {
|
||||
activity.mLetterboxUiController.setIsRefreshAfterRotationRequested(true);
|
||||
ProtoLog.v(WM_DEBUG_STATES,
|
||||
@@ -255,7 +258,8 @@ final class DisplayRotationCompatPolicy {
|
||||
Configuration lastReportedConfig) {
|
||||
return newConfig.windowConfiguration.getDisplayRotation()
|
||||
!= lastReportedConfig.windowConfiguration.getDisplayRotation()
|
||||
&& isTreatmentEnabledForActivity(activity);
|
||||
&& isTreatmentEnabledForActivity(activity)
|
||||
&& activity.mLetterboxUiController.shouldRefreshActivityForCameraCompat();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -294,7 +298,8 @@ final class DisplayRotationCompatPolicy {
|
||||
// handle dynamic changes so we shouldn't force rotate them.
|
||||
&& activity.getRequestedOrientation() != SCREEN_ORIENTATION_NOSENSOR
|
||||
&& activity.getRequestedOrientation() != SCREEN_ORIENTATION_LOCKED
|
||||
&& mCameraIdPackageBiMap.containsPackageName(activity.packageName);
|
||||
&& mCameraIdPackageBiMap.containsPackageName(activity.packageName)
|
||||
&& activity.mLetterboxUiController.shouldForceRotateForCameraCompat();
|
||||
}
|
||||
|
||||
private synchronized void notifyCameraOpened(
|
||||
|
||||
@@ -17,12 +17,18 @@
|
||||
package com.android.server.wm;
|
||||
|
||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION;
|
||||
import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
|
||||
import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
|
||||
import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
||||
import static android.content.pm.ActivityInfo.screenOrientationToString;
|
||||
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
||||
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
|
||||
import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION;
|
||||
import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH;
|
||||
import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
|
||||
import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
|
||||
|
||||
import static com.android.internal.util.FrameworkStatsLog.APP_COMPAT_STATE_CHANGED__LETTERBOX_POSITION__BOTTOM;
|
||||
@@ -132,6 +138,15 @@ final class LetterboxUiController {
|
||||
@Nullable
|
||||
private Letterbox mLetterbox;
|
||||
|
||||
@Nullable
|
||||
private final Boolean mBooleanPropertyCameraCompatAllowForceRotation;
|
||||
|
||||
@Nullable
|
||||
private final Boolean mBooleanPropertyCameraCompatAllowRefresh;
|
||||
|
||||
@Nullable
|
||||
private final Boolean mBooleanPropertyCameraCompatEnableRefreshViaPause;
|
||||
|
||||
// Whether activity "refresh" was requested but not finished in
|
||||
// ActivityRecord#activityResumedLocked following the camera compat force rotation in
|
||||
// DisplayRotationCompatPolicy.
|
||||
@@ -154,8 +169,33 @@ final class LetterboxUiController {
|
||||
readComponentProperty(packageManager, mActivityRecord.packageName,
|
||||
mLetterboxConfiguration::isPolicyForIgnoringRequestedOrientationEnabled,
|
||||
PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION);
|
||||
mBooleanPropertyCameraCompatAllowForceRotation =
|
||||
readComponentProperty(packageManager, mActivityRecord.packageName,
|
||||
() -> mLetterboxConfiguration.isCameraCompatTreatmentEnabled(
|
||||
/* checkDeviceConfig */ true),
|
||||
PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION);
|
||||
mBooleanPropertyCameraCompatAllowRefresh =
|
||||
readComponentProperty(packageManager, mActivityRecord.packageName,
|
||||
() -> mLetterboxConfiguration.isCameraCompatTreatmentEnabled(
|
||||
/* checkDeviceConfig */ true),
|
||||
PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH);
|
||||
mBooleanPropertyCameraCompatEnableRefreshViaPause =
|
||||
readComponentProperty(packageManager, mActivityRecord.packageName,
|
||||
() -> mLetterboxConfiguration.isCameraCompatTreatmentEnabled(
|
||||
/* checkDeviceConfig */ true),
|
||||
PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a {@link Boolean} component property fot a given {@code packageName} and a {@code
|
||||
* propertyName}. Returns {@code null} if {@code gatingCondition} is {@code false} or if the
|
||||
* property isn't specified for the package.
|
||||
*
|
||||
* <p>Return value is {@link Boolean} rather than {@code boolean} so we can know when the
|
||||
* property is unset. Particularly, when this returns {@code null}, {@link
|
||||
* #shouldEnableWithOverrideAndProperty} will check the value of override for the final
|
||||
* decision.
|
||||
*/
|
||||
@Nullable
|
||||
private static Boolean readComponentProperty(PackageManager packageManager, String packageName,
|
||||
BooleanSupplier gatingCondition, String propertyName) {
|
||||
@@ -210,15 +250,11 @@ final class LetterboxUiController {
|
||||
* </ul>
|
||||
*/
|
||||
boolean shouldIgnoreRequestedOrientation(@ScreenOrientation int requestedOrientation) {
|
||||
if (!mLetterboxConfiguration.isPolicyForIgnoringRequestedOrientationEnabled()) {
|
||||
return false;
|
||||
}
|
||||
if (Boolean.FALSE.equals(mBooleanPropertyIgnoreRequestedOrientation)) {
|
||||
return false;
|
||||
}
|
||||
if (!Boolean.TRUE.equals(mBooleanPropertyIgnoreRequestedOrientation)
|
||||
&& !mActivityRecord.info.isChangeEnabled(
|
||||
OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION)) {
|
||||
if (!shouldEnableWithOverrideAndProperty(
|
||||
/* gatingCondition */ mLetterboxConfiguration
|
||||
::isPolicyForIgnoringRequestedOrientationEnabled,
|
||||
OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION,
|
||||
mBooleanPropertyIgnoreRequestedOrientation)) {
|
||||
return false;
|
||||
}
|
||||
if (mIsRelauchingAfterRequestedOrientationChanged) {
|
||||
@@ -262,6 +298,109 @@ final class LetterboxUiController {
|
||||
mIsRefreshAfterRotationRequested = isRequested;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether activity is eligible for activity "refresh" after camera compat force rotation
|
||||
* treatment. See {@link DisplayRotationCompatPolicy} for context.
|
||||
*
|
||||
* <p>This treatment is enabled when the following conditions are met:
|
||||
* <ul>
|
||||
* <li>Flag gating the camera compat treatment is enabled.
|
||||
* <li>Activity isn't opted out by the device manufacturer with override or by the app
|
||||
* developers with the component property.
|
||||
* </ul>
|
||||
*/
|
||||
boolean shouldRefreshActivityForCameraCompat() {
|
||||
return shouldEnableWithOptOutOverrideAndProperty(
|
||||
/* gatingCondition */ () -> mLetterboxConfiguration
|
||||
.isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true),
|
||||
OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH,
|
||||
mBooleanPropertyCameraCompatAllowRefresh);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether activity should be "refreshed" after the camera compat force rotation treatment
|
||||
* using the "resumed -> paused -> resumed" cycle rather than the "resumed -> ... -> stopped
|
||||
* -> ... -> resumed" cycle. See {@link DisplayRotationCompatPolicy} for context.
|
||||
*
|
||||
* <p>This treatment is enabled when the following conditions are met:
|
||||
* <ul>
|
||||
* <li>Flag gating the camera compat treatment is enabled.
|
||||
* <li>Activity "refresh" via "resumed -> paused -> resumed" cycle isn't disabled with the
|
||||
* component property by the app developers.
|
||||
* <li>Activity "refresh" via "resumed -> paused -> resumed" cycle is enabled by the device
|
||||
* manufacturer with override / by the app developers with the component property.
|
||||
* </ul>
|
||||
*/
|
||||
boolean shouldRefreshActivityViaPauseForCameraCompat() {
|
||||
return shouldEnableWithOverrideAndProperty(
|
||||
/* gatingCondition */ () -> mLetterboxConfiguration
|
||||
.isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true),
|
||||
OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE,
|
||||
mBooleanPropertyCameraCompatEnableRefreshViaPause);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether activity is eligible for camera compat force rotation treatment. See {@link
|
||||
* DisplayRotationCompatPolicy} for context.
|
||||
*
|
||||
* <p>This treatment is enabled when the following conditions are met:
|
||||
* <ul>
|
||||
* <li>Flag gating the camera compat treatment is enabled.
|
||||
* <li>Activity isn't opted out by the device manufacturer with override or by the app
|
||||
* developers with the component property.
|
||||
* </ul>
|
||||
*/
|
||||
boolean shouldForceRotateForCameraCompat() {
|
||||
return shouldEnableWithOptOutOverrideAndProperty(
|
||||
/* gatingCondition */ () -> mLetterboxConfiguration
|
||||
.isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true),
|
||||
OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION,
|
||||
mBooleanPropertyCameraCompatAllowForceRotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} when the following conditions are met:
|
||||
* <ul>
|
||||
* <li>{@code gatingCondition} isn't {@code false}
|
||||
* <li>OEM didn't opt out with a {@code overrideChangeId} override
|
||||
* <li>App developers didn't opt out with a component {@code property}
|
||||
* </ul>
|
||||
*
|
||||
* <p>This is used for the treatments that are enabled based with the heuristic but can be
|
||||
* disabled on per-app basis by OEMs or app developers.
|
||||
*/
|
||||
private boolean shouldEnableWithOptOutOverrideAndProperty(BooleanSupplier gatingCondition,
|
||||
long overrideChangeId, Boolean property) {
|
||||
if (!gatingCondition.getAsBoolean()) {
|
||||
return false;
|
||||
}
|
||||
return !Boolean.FALSE.equals(property)
|
||||
&& !mActivityRecord.info.isChangeEnabled(overrideChangeId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} when the following conditions are met:
|
||||
* <ul>
|
||||
* <li>{@code gatingCondition} isn't {@code false}
|
||||
* <li>App developers didn't opt out with a component {@code property}
|
||||
* <li>App developers opted in with a component {@code property} or an OEM opted in with a
|
||||
* component {@code property}
|
||||
* </ul>
|
||||
*
|
||||
* <p>This is used for the treatments that are enabled only on per-app basis.
|
||||
*/
|
||||
private boolean shouldEnableWithOverrideAndProperty(BooleanSupplier gatingCondition,
|
||||
long overrideChangeId, Boolean property) {
|
||||
if (!gatingCondition.getAsBoolean()) {
|
||||
return false;
|
||||
}
|
||||
if (Boolean.FALSE.equals(property)) {
|
||||
return false;
|
||||
}
|
||||
return Boolean.TRUE.equals(property)
|
||||
|| mActivityRecord.info.isChangeEnabled(overrideChangeId);
|
||||
}
|
||||
|
||||
boolean hasWallpaperBackgroundForLetterbox() {
|
||||
return mShowWallpaperForLetterboxBackground;
|
||||
}
|
||||
|
||||
@@ -154,6 +154,18 @@ public final class DisplayRotationCompatPolicyTests extends WindowTestsBase {
|
||||
assertNoForceRotationOrRefresh();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTreatmentDisabledPerApp_noForceRotationOrRefresh()
|
||||
throws Exception {
|
||||
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
|
||||
when(mActivity.mLetterboxUiController.shouldForceRotateForCameraCompat())
|
||||
.thenReturn(false);
|
||||
|
||||
mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
|
||||
|
||||
assertNoForceRotationOrRefresh();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiWindowMode_returnUnspecified_noForceRotationOrRefresh() throws Exception {
|
||||
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
|
||||
@@ -327,7 +339,21 @@ public final class DisplayRotationCompatPolicyTests extends WindowTestsBase {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnActivityConfigurationChanging_refreshDisabled_noRefresh() throws Exception {
|
||||
public void testOnActivityConfigurationChanging_refreshDisabledViaFlag_noRefresh()
|
||||
throws Exception {
|
||||
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
|
||||
when(mActivity.mLetterboxUiController.shouldRefreshActivityForCameraCompat())
|
||||
.thenReturn(false);
|
||||
|
||||
mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
|
||||
callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ true);
|
||||
|
||||
assertActivityRefreshRequested(/* refreshRequested */ false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnActivityConfigurationChanging_refreshDisabledPerApp_noRefresh()
|
||||
throws Exception {
|
||||
when(mLetterboxConfiguration.isCameraCompatRefreshEnabled()).thenReturn(false);
|
||||
|
||||
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
|
||||
@@ -362,6 +388,19 @@ public final class DisplayRotationCompatPolicyTests extends WindowTestsBase {
|
||||
assertActivityRefreshRequested(/* refreshRequested */ true, /* cycleThroughStop */ false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnActivityConfigurationChanging_cycleThroughStopDisabledForApp()
|
||||
throws Exception {
|
||||
configureActivity(SCREEN_ORIENTATION_PORTRAIT);
|
||||
when(mActivity.mLetterboxUiController.shouldRefreshActivityViaPauseForCameraCompat())
|
||||
.thenReturn(true);
|
||||
|
||||
mCameraAvailabilityCallback.onCameraOpened(CAMERA_ID_1, TEST_PACKAGE_1);
|
||||
callOnActivityConfigurationChanging(mActivity, /* isDisplayRotationChanging */ true);
|
||||
|
||||
assertActivityRefreshRequested(/* refreshRequested */ true, /* cycleThroughStop */ false);
|
||||
}
|
||||
|
||||
private void configureActivity(@ScreenOrientation int activityOrientation) {
|
||||
configureActivityAndDisplay(activityOrientation, ORIENTATION_PORTRAIT);
|
||||
}
|
||||
|
||||
@@ -16,8 +16,14 @@
|
||||
|
||||
package com.android.server.wm;
|
||||
|
||||
import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION;
|
||||
import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH;
|
||||
import static android.content.pm.ActivityInfo.OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
|
||||
import static android.content.pm.ActivityInfo.OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION;
|
||||
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
||||
import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION;
|
||||
import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH;
|
||||
import static android.view.WindowManager.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE;
|
||||
import static android.view.WindowManager.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION;
|
||||
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
|
||||
@@ -74,6 +80,8 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
|
||||
mController = new LetterboxUiController(mWm, mActivity);
|
||||
}
|
||||
|
||||
// shouldIgnoreRequestedOrientation
|
||||
|
||||
@Test
|
||||
@EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
|
||||
public void testShouldIgnoreRequestedOrientation_activityRelaunching_returnsTrue() {
|
||||
@@ -134,7 +142,7 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableCompatChanges({OVERRIDE_ENABLE_COMPAT_IGNORE_REQUESTED_ORIENTATION})
|
||||
@EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
|
||||
public void testShouldIgnoreRequestedOrientation_flagIsDisabled_returnsFalse() {
|
||||
prepareActivityThatShouldIgnoreRequestedOrientationDuringRelaunch();
|
||||
doReturn(false).when(mLetterboxConfiguration)
|
||||
@@ -143,6 +151,163 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
|
||||
assertFalse(mController.shouldIgnoreRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED));
|
||||
}
|
||||
|
||||
// shouldRefreshActivityForCameraCompat
|
||||
|
||||
@Test
|
||||
public void testShouldRefreshActivityForCameraCompat_flagIsDisabled_returnsFalse() {
|
||||
doReturn(false).when(mLetterboxConfiguration)
|
||||
.isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
|
||||
|
||||
assertFalse(mController.shouldRefreshActivityForCameraCompat());
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
|
||||
public void testShouldRefreshActivityForCameraCompat_overrideEnabled_returnsFalse() {
|
||||
doReturn(true).when(mLetterboxConfiguration)
|
||||
.isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
|
||||
|
||||
assertFalse(mController.shouldRefreshActivityForCameraCompat());
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_REFRESH})
|
||||
public void testShouldRefreshActivityForCameraCompat_propertyIsTrueAndOverride_returnsFalse()
|
||||
throws Exception {
|
||||
doReturn(true).when(mLetterboxConfiguration)
|
||||
.isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
|
||||
mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH, /* value */ true);
|
||||
|
||||
mController = new LetterboxUiController(mWm, mActivity);
|
||||
|
||||
assertFalse(mController.shouldRefreshActivityForCameraCompat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldRefreshActivityForCameraCompat_propertyIsFalse_returnsFalse()
|
||||
throws Exception {
|
||||
doReturn(true).when(mLetterboxConfiguration)
|
||||
.isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
|
||||
mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH, /* value */ false);
|
||||
|
||||
mController = new LetterboxUiController(mWm, mActivity);
|
||||
|
||||
assertFalse(mController.shouldRefreshActivityForCameraCompat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldRefreshActivityForCameraCompat_propertyIsTrue_returnsTrue()
|
||||
throws Exception {
|
||||
doReturn(true).when(mLetterboxConfiguration)
|
||||
.isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
|
||||
mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH, /* value */ true);
|
||||
|
||||
mController = new LetterboxUiController(mWm, mActivity);
|
||||
|
||||
assertTrue(mController.shouldRefreshActivityForCameraCompat());
|
||||
}
|
||||
|
||||
// shouldRefreshActivityViaPauseForCameraCompat
|
||||
|
||||
@Test
|
||||
@EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
|
||||
public void testShouldRefreshActivityViaPauseForCameraCompat_flagIsDisabled_returnsFalse() {
|
||||
doReturn(false).when(mLetterboxConfiguration)
|
||||
.isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
|
||||
|
||||
assertFalse(mController.shouldRefreshActivityViaPauseForCameraCompat());
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
|
||||
public void testShouldRefreshActivityViaPauseForCameraCompat_overrideEnabled_returnsTrue() {
|
||||
doReturn(true).when(mLetterboxConfiguration)
|
||||
.isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
|
||||
|
||||
assertTrue(mController.shouldRefreshActivityViaPauseForCameraCompat());
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE})
|
||||
public void testShouldRefreshActivityViaPauseForCameraCompat_propertyIsFalseAndOverride_returnFalse()
|
||||
throws Exception {
|
||||
doReturn(true).when(mLetterboxConfiguration)
|
||||
.isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
|
||||
mockThatProperty(PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE, /* value */ false);
|
||||
|
||||
mController = new LetterboxUiController(mWm, mActivity);
|
||||
|
||||
assertFalse(mController.shouldRefreshActivityViaPauseForCameraCompat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldRefreshActivityViaPauseForCameraCompat_propertyIsTrue_returnsTrue()
|
||||
throws Exception {
|
||||
doReturn(true).when(mLetterboxConfiguration)
|
||||
.isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
|
||||
mockThatProperty(PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE, /* value */ true);
|
||||
|
||||
mController = new LetterboxUiController(mWm, mActivity);
|
||||
|
||||
assertTrue(mController.shouldRefreshActivityViaPauseForCameraCompat());
|
||||
}
|
||||
|
||||
// shouldForceRotateForCameraCompat
|
||||
|
||||
@Test
|
||||
public void testShouldForceRotateForCameraCompat_flagIsDisabled_returnsFalse() {
|
||||
doReturn(false).when(mLetterboxConfiguration)
|
||||
.isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
|
||||
|
||||
assertFalse(mController.shouldForceRotateForCameraCompat());
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION})
|
||||
public void testShouldForceRotateForCameraCompat_overrideEnabled_returnsFalse() {
|
||||
doReturn(true).when(mLetterboxConfiguration)
|
||||
.isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
|
||||
|
||||
assertFalse(mController.shouldForceRotateForCameraCompat());
|
||||
}
|
||||
|
||||
@Test
|
||||
@EnableCompatChanges({OVERRIDE_CAMERA_COMPAT_DISABLE_FORCE_ROTATION})
|
||||
public void testShouldForceRotateForCameraCompat_propertyIsTrueAndOverride_returnsFalse()
|
||||
throws Exception {
|
||||
doReturn(true).when(mLetterboxConfiguration)
|
||||
.isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
|
||||
mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION, /* value */ true);
|
||||
|
||||
mController = new LetterboxUiController(mWm, mActivity);
|
||||
|
||||
assertFalse(mController.shouldForceRotateForCameraCompat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldForceRotateForCameraCompat_propertyIsFalse_returnsFalse()
|
||||
throws Exception {
|
||||
doReturn(true).when(mLetterboxConfiguration)
|
||||
.isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
|
||||
mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION, /* value */ false);
|
||||
|
||||
mController = new LetterboxUiController(mWm, mActivity);
|
||||
|
||||
assertFalse(mController.shouldForceRotateForCameraCompat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldForceRotateForCameraCompat_propertyIsTrue_returnsTrue()
|
||||
throws Exception {
|
||||
doReturn(true).when(mLetterboxConfiguration)
|
||||
.isCameraCompatTreatmentEnabled(/* checkDeviceConfig */ true);
|
||||
mockThatProperty(PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION, /* value */ true);
|
||||
|
||||
mController = new LetterboxUiController(mWm, mActivity);
|
||||
|
||||
assertTrue(mController.shouldForceRotateForCameraCompat());
|
||||
}
|
||||
|
||||
private void mockThatProperty(String propertyName, boolean value) throws Exception {
|
||||
Property property = new Property(propertyName, /* value */ value, /* packageName */ "",
|
||||
/* className */ "");
|
||||
|
||||
Reference in New Issue
Block a user