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

Commit 1f9fc929 authored by Mina Granic's avatar Mina Granic
Browse files

Start DisplayRotationCompatPolicy upon creation.

Also add tests for `start()`: these policies are created and started
 in the `DisplayContent` constructor, thus we cannot spy on them
and `verify` that `start()` methods are called.

Test: atest WmTest:AppCompatCameraPolicyTest
Bug: 359099136
Flag: EXEMPT bug fix
Change-Id: Ibc9f808dbf76fa1b2e4dafe8ca48a8a57baca3df
parent 3648b316
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.content.pm.ActivityInfo.ScreenOrientation;
import android.content.res.Configuration;
import android.widget.Toast;

import com.android.internal.annotations.VisibleForTesting;
import com.android.window.flags.Flags;

/**
@@ -32,7 +33,8 @@ import com.android.window.flags.Flags;
class AppCompatCameraPolicy {

    @Nullable
    private final CameraStateMonitor mCameraStateMonitor;
    @VisibleForTesting
    final CameraStateMonitor mCameraStateMonitor;
    @Nullable
    private final ActivityRefresher mActivityRefresher;
    @Nullable
@@ -122,6 +124,9 @@ class AppCompatCameraPolicy {
    }

    void start() {
        if (mDisplayRotationCompatPolicy != null) {
            mDisplayRotationCompatPolicy.start();
        }
        if (mCameraCompatFreeformPolicy != null) {
            mCameraCompatFreeformPolicy.start();
        }
@@ -150,6 +155,10 @@ class AppCompatCameraPolicy {
        return mCameraCompatFreeformPolicy != null;
    }

    boolean hasCameraStateMonitor() {
        return mCameraStateMonitor != null;
    }

    @ScreenOrientation
    int getOrientation() {
        return mDisplayRotationCompatPolicy != null
+12 −0
Original line number Diff line number Diff line
@@ -60,6 +60,11 @@ final class CameraCompatFreeformPolicy implements CameraStateMonitor.CameraCompa
    @Nullable
    private Task mCameraTask;

    /**
     * Value toggled on {@link #start()} to {@code true} and on {@link #dispose()} to {@code false}.
     */
    private boolean mIsRunning;

    CameraCompatFreeformPolicy(@NonNull DisplayContent displayContent,
            @NonNull CameraStateMonitor cameraStateMonitor,
            @NonNull ActivityRefresher activityRefresher) {
@@ -71,12 +76,19 @@ final class CameraCompatFreeformPolicy implements CameraStateMonitor.CameraCompa
    void start() {
        mCameraStateMonitor.addCameraStateListener(this);
        mActivityRefresher.addEvaluator(this);
        mIsRunning = true;
    }

    /** Releases camera callback listener. */
    void dispose() {
        mCameraStateMonitor.removeCameraStateListener(this);
        mActivityRefresher.removeEvaluator(this);
        mIsRunning = false;
    }

    @VisibleForTesting
    boolean isRunning() {
        return mIsRunning;
    }

    // Refreshing only when configuration changes after rotation or camera split screen aspect ratio
+14 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.os.Handler;
import android.util.ArraySet;
import android.util.Slog;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.ProtoLog;

import java.util.ArrayList;
@@ -73,6 +74,12 @@ class CameraStateMonitor {

    private final ArrayList<CameraCompatStateListener> mCameraStateListeners = new ArrayList<>();

    /**
     * Value toggled on {@link #startListeningToCameraState()} to {@code true} and on {@link
     * #dispose()} to {@code false}.
     */
    private boolean mIsRunning;

    private final CameraManager.AvailabilityCallback mAvailabilityCallback =
            new  CameraManager.AvailabilityCallback() {
                @Override
@@ -101,6 +108,7 @@ class CameraStateMonitor {
    void startListeningToCameraState() {
        mCameraManager.registerAvailabilityCallback(
                mWmService.mContext.getMainExecutor(), mAvailabilityCallback);
        mIsRunning = true;
    }

    /** Releases camera callback listener. */
@@ -108,6 +116,12 @@ class CameraStateMonitor {
        if (mCameraManager != null) {
            mCameraManager.unregisterAvailabilityCallback(mAvailabilityCallback);
        }
        mIsRunning = false;
    }

    @VisibleForTesting
    boolean isRunning() {
        return mIsRunning;
    }

    void addCameraStateListener(CameraCompatStateListener listener) {
+12 −0
Original line number Diff line number Diff line
@@ -76,6 +76,11 @@ final class DisplayRotationCompatPolicy implements CameraStateMonitor.CameraComp
    @ScreenOrientation
    private int mLastReportedOrientation = SCREEN_ORIENTATION_UNSET;

    /**
     * Value toggled on {@link #start()} to {@code true} and on {@link #dispose()} to {@code false}.
     */
    private boolean mIsRunning;

    DisplayRotationCompatPolicy(@NonNull DisplayContent displayContent,
            @NonNull CameraStateMonitor cameraStateMonitor,
            @NonNull ActivityRefresher activityRefresher) {
@@ -90,12 +95,19 @@ final class DisplayRotationCompatPolicy implements CameraStateMonitor.CameraComp
    void start() {
        mCameraStateMonitor.addCameraStateListener(this);
        mActivityRefresher.addEvaluator(this);
        mIsRunning = true;
    }

    /** Releases camera state listener. */
    void dispose() {
        mCameraStateMonitor.removeCameraStateListener(this);
        mActivityRefresher.removeEvaluator(this);
        mIsRunning = false;
    }

    @VisibleForTesting
    boolean isRunning() {
        return mIsRunning;
    }

    /**
+121 −24
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.window.flags.Flags.FLAG_CAMERA_COMPAT_FOR_FREEFORM;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;

import android.compat.testing.PlatformCompatChangeRule;
@@ -29,7 +31,6 @@ import android.platform.test.annotations.Presubmit;

import androidx.annotation.NonNull;

import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
@@ -53,18 +54,28 @@ public class AppCompatCameraPolicyTest extends WindowTestsBase {
    @Test
    public void testDisplayRotationCompatPolicy_presentWhenEnabled() {
        runTestScenario((robot) -> {
            robot.conf().enableCameraCompatTreatmentAtBuildTime(true);
            robot.conf().enableCameraCompatTreatmentAtBuildTime(/* enabled= */ true);
            robot.activity().createActivityWithComponentInNewTaskAndDisplay();
            robot.checkTopActivityHasDisplayRotationCompatPolicy(true);
            robot.checkTopActivityHasDisplayRotationCompatPolicy(/* exists= */ true);
        });
    }

    @Test
    public void testDisplayRotationCompatPolicy_notPresentWhenDisabled() {
        runTestScenario((robot) -> {
            robot.conf().enableCameraCompatTreatmentAtBuildTime(false);
            robot.conf().enableCameraCompatTreatmentAtBuildTime(/* enabled= */ false);
            robot.activity().createActivityWithComponentInNewTaskAndDisplay();
            robot.checkTopActivityHasDisplayRotationCompatPolicy(false);
            robot.checkTopActivityHasDisplayRotationCompatPolicy(/* exists= */ false);
        });
    }

    @Test
    public void testDisplayRotationCompatPolicy_startedWhenEnabled() {
        runTestScenario((robot) -> {
            robot.conf().enableCameraCompatTreatmentAtBuildTime(/* enabled= */ true);
            robot.activity().createActivityWithComponentInNewTaskAndDisplay();
            robot.checkTopActivityHasDisplayRotationCompatPolicy(/* exists= */ true);
            robot.checkTopActivityDisplayRotationCompatPolicyIsRunning();
        });
    }

@@ -72,9 +83,9 @@ public class AppCompatCameraPolicyTest extends WindowTestsBase {
    @EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
    public void testCameraCompatFreeformPolicy_presentWhenEnabledAndDW() {
        runTestScenario((robot) -> {
            robot.allowEnterDesktopMode(true);
            robot.allowEnterDesktopMode(/* isAllowed= */ true);
            robot.activity().createActivityWithComponentInNewTaskAndDisplay();
            robot.checkTopActivityHasCameraCompatFreeformPolicy(true);
            robot.checkTopActivityHasCameraCompatFreeformPolicy(/* exists= */ true);
        });
    }

@@ -82,9 +93,9 @@ public class AppCompatCameraPolicyTest extends WindowTestsBase {
    @EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
    public void testCameraCompatFreeformPolicy_notPresentWhenNoDW() {
        runTestScenario((robot) -> {
            robot.allowEnterDesktopMode(false);
            robot.allowEnterDesktopMode(/* isAllowed= */ false);
            robot.activity().createActivityWithComponentInNewTaskAndDisplay();
            robot.checkTopActivityHasCameraCompatFreeformPolicy(false);
            robot.checkTopActivityHasCameraCompatFreeformPolicy(/* exists= */ false);
        });
    }

@@ -92,9 +103,9 @@ public class AppCompatCameraPolicyTest extends WindowTestsBase {
    @DisableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
    public void testCameraCompatFreeformPolicy_notPresentWhenNoFlag() {
        runTestScenario((robot) -> {
            robot.allowEnterDesktopMode(true);
            robot.allowEnterDesktopMode(/* isAllowed= */ true);
            robot.activity().createActivityWithComponentInNewTaskAndDisplay();
            robot.checkTopActivityHasCameraCompatFreeformPolicy(false);
            robot.checkTopActivityHasCameraCompatFreeformPolicy(/* exists= */ false);
        });
    }

@@ -102,19 +113,86 @@ public class AppCompatCameraPolicyTest extends WindowTestsBase {
    @EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
    public void testCameraCompatFreeformPolicy_notPresentWhenNoFlagAndNoDW() {
        runTestScenario((robot) -> {
            robot.allowEnterDesktopMode(false);
            robot.allowEnterDesktopMode(/* isAllowed= */ false);
            robot.activity().createActivityWithComponentInNewTaskAndDisplay();
            robot.checkTopActivityHasCameraCompatFreeformPolicy(/* exists= */ false);
        });
    }

    @Test
    @EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
    public void testCameraCompatFreeformPolicy_startedWhenEnabledAndDW() {
        runTestScenario((robot) -> {
            robot.allowEnterDesktopMode(/* isAllowed= */ true);
            robot.activity().createActivityWithComponentInNewTaskAndDisplay();
            robot.checkTopActivityHasCameraCompatFreeformPolicy(false);
            robot.checkTopActivityHasCameraCompatFreeformPolicy(/* exists= */ true);
            robot.checkTopActivityCameraCompatFreeformPolicyIsRunning();
        });
    }

    @Test
    @EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
    public void testCameraStateManager_existsWhenCameraCompatFreeformExists() {
        runTestScenario((robot) -> {
            robot.allowEnterDesktopMode(true);
            robot.activity().createActivityWithComponentInNewTaskAndDisplay();
            robot.checkTopActivityHasCameraCompatFreeformPolicy(/* exists= */ true);
            robot.checkTopActivityHasCameraStateMonitor(/* exists= */ true);
        });
    }

    @Test
    @EnableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
    public void testCameraStateManager_startedWhenCameraCompatFreeformExists() {
        runTestScenario((robot) -> {
            robot.allowEnterDesktopMode(true);
            robot.activity().createActivityWithComponentInNewTaskAndDisplay();
            robot.checkTopActivityHasCameraCompatFreeformPolicy(/* exists= */ true);
            robot.checkTopActivityHasCameraStateMonitor(/* exists= */ true);
            robot.checkTopActivityCameraStateMonitorIsRunning();
        });
    }

    @Test
    public void testCameraStateManager_existsWhenDisplayRotationCompatPolicyExists() {
        runTestScenario((robot) -> {
            robot.conf().enableCameraCompatTreatmentAtBuildTime(/* enabled= */ true);
            robot.activity().createActivityWithComponentInNewTaskAndDisplay();
            robot.checkTopActivityHasDisplayRotationCompatPolicy(/* exists= */ true);
            robot.checkTopActivityHasCameraStateMonitor(/* exists= */ true);
        });
    }

    @Test
    public void testCameraStateManager_startedWhenDisplayRotationCompatPolicyExists() {
        runTestScenario((robot) -> {
            robot.conf().enableCameraCompatTreatmentAtBuildTime(/* enabled= */ true);
            robot.activity().createActivityWithComponentInNewTaskAndDisplay();
            robot.checkTopActivityHasDisplayRotationCompatPolicy(/* exists= */ true);
            robot.checkTopActivityHasCameraStateMonitor(/* exists= */ true);
            robot.checkTopActivityCameraStateMonitorIsRunning();
        });
    }

    @Test
    @DisableFlags(FLAG_CAMERA_COMPAT_FOR_FREEFORM)
    public void testCameraStateManager_doesNotExistWhenNoPolicyExists() {
        runTestScenario((robot) -> {
            robot.conf().enableCameraCompatTreatmentAtBuildTime(/* enabled= */ false);
            robot.activity().createActivityWithComponentInNewTaskAndDisplay();
            robot.checkTopActivityHasDisplayRotationCompatPolicy(/* exists= */ false);
            robot.checkTopActivityHasCameraCompatFreeformPolicy(/* exists= */ false);
            robot.checkTopActivityHasCameraStateMonitor(/* exists= */ false);
        });
    }

    /**
     * Runs a test scenario providing a Robot.
     */
    void runTestScenario(@NonNull Consumer<DisplayRotationPolicyRobotTest> consumer) {
    void runTestScenario(@NonNull Consumer<AppCompatCameraPolicyRobotTest> consumer) {
        spyOn(mWm.mAppCompatConfiguration);
        final DisplayRotationPolicyRobotTest robot =
                new DisplayRotationPolicyRobotTest(mWm, mAtm, mSupervisor);
        final AppCompatCameraPolicyRobotTest robot =
                new AppCompatCameraPolicyRobotTest(mWm, mAtm, mSupervisor);
        consumer.accept(robot);
    }

@@ -142,9 +220,8 @@ public class AppCompatCameraPolicyTest extends WindowTestsBase {
        });
    }

    private static class DisplayRotationPolicyRobotTest extends AppCompatRobotBase {

        DisplayRotationPolicyRobotTest(@NonNull WindowManagerService wm,
    private static class AppCompatCameraPolicyRobotTest extends AppCompatRobotBase {
        AppCompatCameraPolicyRobotTest(@NonNull WindowManagerService wm,
                @NonNull ActivityTaskManagerService atm,
                @NonNull ActivityTaskSupervisor supervisor) {
            super(wm, atm, supervisor);
@@ -157,17 +234,37 @@ public class AppCompatCameraPolicyTest extends WindowTestsBase {
        }

        void checkTopActivityHasDisplayRotationCompatPolicy(boolean exists) {
            Assert.assertEquals(exists, activity().top().mDisplayContent
                    .mAppCompatCameraPolicy.hasDisplayRotationCompatPolicy());
            assertEquals(exists, activity().top().mDisplayContent.mAppCompatCameraPolicy
                    .hasDisplayRotationCompatPolicy());
        }

        void checkTopActivityHasCameraCompatFreeformPolicy(boolean exists) {
            Assert.assertEquals(exists, activity().top().mDisplayContent
                    .mAppCompatCameraPolicy.hasCameraCompatFreeformPolicy());
            assertEquals(exists, activity().top().mDisplayContent.mAppCompatCameraPolicy
                    .hasCameraCompatFreeformPolicy());
        }

        void checkTopActivityHasCameraStateMonitor(boolean exists) {
            assertEquals(exists, activity().top().mDisplayContent.mAppCompatCameraPolicy
                    .hasCameraStateMonitor());
        }

        void checkTopActivityDisplayRotationCompatPolicyIsRunning() {
            assertTrue(activity().top().mDisplayContent.mAppCompatCameraPolicy
                    .mDisplayRotationCompatPolicy.isRunning());
        }

        void checkTopActivityCameraCompatFreeformPolicyIsRunning() {
            assertTrue(activity().top().mDisplayContent.mAppCompatCameraPolicy
                    .mCameraCompatFreeformPolicy.isRunning());
        }

        void checkTopActivityCameraStateMonitorIsRunning() {
            assertTrue(activity().top().mDisplayContent.mAppCompatCameraPolicy
                    .mCameraStateMonitor.isRunning());
        }

        void checkIsCameraCompatTreatmentActiveForTopActivity(boolean active) {
            Assert.assertEquals(getTopAppCompatCameraPolicy()
            assertEquals(getTopAppCompatCameraPolicy()
                    .isTreatmentEnabledForActivity(activity().top()), active);
        }