Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da4c5523 authored by Mariia Sandrikova's avatar Mariia Sandrikova
Browse files

[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
parent 83c300c0
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -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);
+3 −11
Original line number Diff line number Diff line
@@ -30,14 +30,12 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ORIENTATION;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.ActivityInfo.ScreenOrientation;
import android.hardware.camera2.CameraManager;
import android.os.Handler;
import android.util.ArrayMap;
import android.util.ArraySet;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.common.ProtoLog;
@@ -77,8 +75,6 @@ final class DisplayRotationCompatPolicy {
    private final WindowManagerService mWmService;
    private final CameraManager mCameraManager;
    private final Handler mHandler;
    // TODO(b/218352945): Add an ADB command.
    private final boolean mIsTreatmentEnabled;

    // Bi-directional map between package names and active camera IDs since we need to 1) get a
    // camera id by a package name when determining rotation; 2) get a package name by a camera id
@@ -114,17 +110,11 @@ final class DisplayRotationCompatPolicy {
        mHandler = handler;
        mDisplayContent = displayContent;
        mWmService = displayContent.mWmService;
        mIsTreatmentEnabled = isTreatmentEnabled(mWmService.mContext);
        mCameraManager = mWmService.mContext.getSystemService(CameraManager.class);
        mCameraManager.registerAvailabilityCallback(
                mWmService.mContext.getMainExecutor(), mAvailabilityCallback);
    }

    static boolean isTreatmentEnabled(@NonNull Context context) {
        return context.getResources().getBoolean(
                R.bool.config_isWindowManagerCameraCompatTreatmentEnabled);
    }

    void dispose() {
        mCameraManager.unregisterAvailabilityCallback(mAvailabilityCallback);
    }
@@ -190,7 +180,9 @@ final class DisplayRotationCompatPolicy {
     * </ul>
     */
    private boolean isTreatmentEnabledForDisplay() {
        return mIsTreatmentEnabled && mDisplayContent.getIgnoreOrientationRequest()
        return mWmService.mLetterboxConfiguration.isCameraCompatTreatmentEnabled(
                    /* checkDeviceConfig */ true)
                && mDisplayContent.getIgnoreOrientationRequest()
                // TODO(b/225928882): Support camera compat rotation for external displays
                && mDisplayContent.getDisplay().getType() == TYPE_INTERNAL;
    }
+22 −1
Original line number Diff line number Diff line
@@ -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);
    }

}
+22 −107
Original line number Diff line number Diff line
@@ -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,55 +869,13 @@ public class WindowManagerShellCommand extends ShellCommand {
        return 0;
    }

    private int runSetLetterboxIsEducationEnabled(PrintWriter pw) throws RemoteException {
        String arg = getNextArg();
        final boolean enabled;
        switch (arg) {
            case "true":
            case "1":
                enabled = true;
                break;
            case "false":
            case "0":
                enabled = false;
                break;
            default:
                getErrPrintWriter().println("Error: expected true, 1, false, 0, but got " + arg);
                return -1;
        }

        synchronized (mInternal.mGlobalLock) {
            mLetterboxConfiguration.setIsEducationEnabled(enabled);
        }
        return 0;
    }

    private int runSetLetterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled(PrintWriter pw)
    private int runSetBooleanFlag(PrintWriter pw, Consumer<Boolean> setter)
            throws RemoteException {
        String arg = getNextArg();
        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);
        if (arg == null) {
            getErrPrintWriter().println("Error: expected true, 1, false, 0, but got empty input.");
            return -1;
        }

        synchronized (mInternal.mGlobalLock) {
            mLetterboxConfiguration.setIsSplitScreenAspectRatioForUnresizableAppsEnabled(enabled);
        }
        return 0;
    }

    private int runSetTranslucentLetterboxingEnabled(PrintWriter pw) {
        String arg = getNextArg();
        final boolean enabled;
        switch (arg) {
            case "true":
@@ -981,7 +892,7 @@ public class WindowManagerShellCommand extends ShellCommand {
        }

        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");
+21 −8
Original line number Diff line number Diff line
@@ -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);