Add CTS tests for setDisplayPowerState()

Bug: 243946819
Test: atest CarPowerManagerTest
Change-Id: I83cccee2e0913d47186c331de4aa6662090f9e9c
Merged-In: I83cccee2e0913d47186c331de4aa6662090f9e9c
(cherry picked from commit 8de0754b35c07b77ee881ad53d9021441ef65cfa)
diff --git a/tests/tests/car/AndroidManifest.xml b/tests/tests/car/AndroidManifest.xml
index beda105..ec0e3ca 100644
--- a/tests/tests/car/AndroidManifest.xml
+++ b/tests/tests/car/AndroidManifest.xml
@@ -18,6 +18,7 @@
     package="android.car.cts">
     <uses-feature android:name="android.hardware.type.automotive" />
     <uses-permission android:name="android.car.permission.ACCESS_PRIVATE_DISPLAY_ID" />
+    <uses-permission android:name="android.car.permission.CAR_POWER" />
     <uses-permission android:name="android.car.permission.CAR_TEST_SERVICE" />
     <uses-permission android:name="android.car.permission.READ_CAR_POWER_POLICY" />
     <uses-permission android:name="android.car.permission.USE_CAR_TELEMETRY_SERVICE" />
@@ -58,4 +59,3 @@
             android:value="com.android.cts.runner.CtsTestRunListener" />
     </instrumentation>
 </manifest>
-
diff --git a/tests/tests/car/src/android/car/cts/CarPowerManagerTest.java b/tests/tests/car/src/android/car/cts/CarPowerManagerTest.java
index 5e5b3cd..90e97c5 100644
--- a/tests/tests/car/src/android/car/cts/CarPowerManagerTest.java
+++ b/tests/tests/car/src/android/car/cts/CarPowerManagerTest.java
@@ -16,9 +16,17 @@
 
 package android.car.cts;
 
+import static android.car.CarOccupantZoneManager.DISPLAY_TYPE_MAIN;
+import static android.car.settings.CarSettings.Global.DISPLAY_POWER_MODE;
+
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assume.assumeTrue;
+
 import android.car.Car;
+import android.car.CarOccupantZoneManager;
+import android.car.CarOccupantZoneManager.OccupantZoneInfo;
 import android.car.hardware.power.CarPowerManager;
 import android.car.hardware.power.CarPowerPolicy;
 import android.car.hardware.power.CarPowerPolicyFilter;
@@ -27,13 +35,18 @@
 import android.platform.test.annotations.AppModeFull;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
+import android.view.Display;
 
 import androidx.annotation.Nullable;
 
+import com.android.compatibility.common.util.PollingCheck;
+
 import com.google.common.base.Strings;
 
 import org.junit.After;
+import org.junit.AfterClass;
 import org.junit.Before;
+import org.junit.BeforeClass;
 import org.junit.Test;
 
 import java.util.concurrent.CountDownLatch;
@@ -45,9 +58,17 @@
 public final class CarPowerManagerTest extends AbstractCarTestCase {
     private static String TAG = CarPowerManagerTest.class.getSimpleName();
     private static final int LISTENER_WAIT_TIME_MS = 1000;
+    private static final int DISPLAY_WAIT_TIME_MS = 2000;
     private static final int NO_WAIT = 0;
 
+    private static final int DISPLAY_POWER_MODE_ON = 0;
+    private static final int DISPLAY_POWER_MODE_OFF = 1;
+    private static final int DISPLAY_POWER_MODE_ALWAYS_ON = 2;
+
+    private static String sDefaultDisplayPowerModeValue;
+
     private CarPowerManager mCarPowerManager;
+    private CarOccupantZoneManager mCarOccupantZoneManager;
     private String mInitialPowerPolicyId;
     private final Executor mExecutor = mContext.getMainExecutor();
 
@@ -61,6 +82,8 @@
     @Before
     public void setUp() throws Exception {
         mCarPowerManager = (CarPowerManager) getCar().getCarManager(Car.POWER_SERVICE);
+        mCarOccupantZoneManager = (CarOccupantZoneManager) getCar().getCarManager(
+                Car.CAR_OCCUPANT_ZONE_SERVICE);
         mInitialPowerPolicyId = mCarPowerManager.getCurrentPowerPolicy().getPolicyId();
     }
 
@@ -72,6 +95,18 @@
         }
     }
 
+    @BeforeClass
+    public static void loadDefaultDisplayPowerMode() throws Exception {
+        sDefaultDisplayPowerModeValue = executeShellCommand(
+                "settings get global %s ", DISPLAY_POWER_MODE);
+    }
+
+    @AfterClass
+    public static void restoreDisplayPowerMode() throws Exception {
+        executeShellCommand(
+                "settings put global %s %s", DISPLAY_POWER_MODE, sDefaultDisplayPowerModeValue);
+    }
+
     /**
      * This test verifies 1) if the current power policy is set to applied one, 2) if proper power
      * policy change listeners are invoked, 3) unrelated power policy listeners are not invoked,
@@ -117,6 +152,152 @@
         applyPowerPolicy(mInitialPowerPolicyId);
     }
 
+    @Test
+    public void testSetDisplayPowerState_driverDisplayMustNotBeSupported() throws Exception {
+        assumeTrue("No driver zone", mCarOccupantZoneManager.hasDriverZone());
+
+        OccupantZoneInfo zoneInfo = mCarOccupantZoneManager.getOccupantZone(
+                CarOccupantZoneManager.OCCUPANT_TYPE_DRIVER, /* seat= */ 0);
+        assertWithMessage("Driver zone").that(zoneInfo).isNotNull();
+
+        Display display = mCarOccupantZoneManager.getDisplayForOccupant(
+                zoneInfo, DISPLAY_TYPE_MAIN);
+        assertWithMessage("Driver display").that(display).isNotNull();
+
+        int displayId = display.getDisplayId();
+        assertThrows(UnsupportedOperationException.class, () ->
+                mCarPowerManager.setDisplayPowerState(displayId, false));
+
+        assertThrows(UnsupportedOperationException.class, () ->
+                mCarPowerManager.setDisplayPowerState(displayId, true));
+    }
+
+    @Test
+    public void testSetDisplayPowerState_passengerDisplays_modeOn() throws Exception {
+        assumeTrue("No passenger zones", mCarOccupantZoneManager.hasPassengerZones());
+
+        updateDisplayPowerModeSetting(DISPLAY_POWER_MODE_ON);
+
+        for (OccupantZoneInfo zoneInfo : mCarOccupantZoneManager.getAllOccupantZones()) {
+            if (zoneInfo.occupantType == CarOccupantZoneManager.OCCUPANT_TYPE_DRIVER) {
+                continue;
+            }
+
+            Display display = mCarOccupantZoneManager.getDisplayForOccupant(
+                    zoneInfo, DISPLAY_TYPE_MAIN);
+            if (display == null) {
+                continue;
+            }
+
+            int displayId = display.getDisplayId();
+            mCarPowerManager.setDisplayPowerState(displayId, true);
+            PollingCheck.waitFor(DISPLAY_WAIT_TIME_MS, () -> {
+                return display.getState() == Display.STATE_ON;
+            });
+
+            mCarPowerManager.setDisplayPowerState(displayId, false);
+            PollingCheck.waitFor(DISPLAY_WAIT_TIME_MS, () -> {
+                return display.getState() == Display.STATE_OFF;
+            });
+
+            mCarPowerManager.setDisplayPowerState(displayId, true);
+            PollingCheck.waitFor(DISPLAY_WAIT_TIME_MS, () -> {
+                return display.getState() == Display.STATE_ON;
+            });
+        }
+    }
+
+    @Test
+    public void testSetDisplayPowerState_passengerDisplays_modeOff() throws Exception {
+        assumeTrue("No passenger zones", mCarOccupantZoneManager.hasPassengerZones());
+
+        updateDisplayPowerModeSetting(DISPLAY_POWER_MODE_OFF);
+
+        for (OccupantZoneInfo zoneInfo : mCarOccupantZoneManager.getAllOccupantZones()) {
+            if (zoneInfo.occupantType == CarOccupantZoneManager.OCCUPANT_TYPE_DRIVER) {
+                continue;
+            }
+
+            Display display = mCarOccupantZoneManager.getDisplayForOccupant(
+                    zoneInfo, DISPLAY_TYPE_MAIN);
+            if (display == null) {
+                continue;
+            }
+
+            int displayId = display.getDisplayId();
+            mCarPowerManager.setDisplayPowerState(displayId, true);
+            PollingCheck.waitFor(DISPLAY_WAIT_TIME_MS, () -> {
+                return display.getState() == Display.STATE_OFF;
+            });
+
+            mCarPowerManager.setDisplayPowerState(displayId, false);
+            PollingCheck.waitFor(DISPLAY_WAIT_TIME_MS, () -> {
+                return display.getState() == Display.STATE_OFF;
+            });
+
+            mCarPowerManager.setDisplayPowerState(displayId, true);
+            PollingCheck.waitFor(DISPLAY_WAIT_TIME_MS, () -> {
+                return display.getState() == Display.STATE_OFF;
+            });
+        }
+    }
+
+    @Test
+    public void testSetDisplayPowerState_passengerDisplays_modeAlwaysOn() throws Exception {
+        assumeTrue("No passenger zones", mCarOccupantZoneManager.hasPassengerZones());
+
+        updateDisplayPowerModeSetting(DISPLAY_POWER_MODE_ALWAYS_ON);
+
+        for (OccupantZoneInfo zoneInfo : mCarOccupantZoneManager.getAllOccupantZones()) {
+            if (zoneInfo.occupantType == CarOccupantZoneManager.OCCUPANT_TYPE_DRIVER) {
+                continue;
+            }
+
+            Display display = mCarOccupantZoneManager.getDisplayForOccupant(
+                    zoneInfo, DISPLAY_TYPE_MAIN);
+            if (display == null) {
+                continue;
+            }
+
+            int displayId = display.getDisplayId();
+            mCarPowerManager.setDisplayPowerState(displayId, true);
+            PollingCheck.waitFor(DISPLAY_WAIT_TIME_MS, () -> {
+                return display.getState() == Display.STATE_ON;
+            });
+
+            mCarPowerManager.setDisplayPowerState(displayId, false);
+            PollingCheck.waitFor(DISPLAY_WAIT_TIME_MS, () -> {
+                return display.getState() == Display.STATE_OFF;
+            });
+
+            mCarPowerManager.setDisplayPowerState(displayId, true);
+            PollingCheck.waitFor(DISPLAY_WAIT_TIME_MS, () -> {
+                return display.getState() == Display.STATE_ON;
+            });
+        }
+    }
+
+    private void updateDisplayPowerModeSetting(int mode) throws Exception {
+        StringBuilder value = new StringBuilder();
+
+        for (OccupantZoneInfo zoneInfo : mCarOccupantZoneManager.getAllOccupantZones()) {
+            Display display = mCarOccupantZoneManager.getDisplayForOccupant(
+                    zoneInfo, DISPLAY_TYPE_MAIN);
+            int displayId = display.getDisplayId();
+            int newMode = mode;
+            if (zoneInfo.occupantType == CarOccupantZoneManager.OCCUPANT_TYPE_DRIVER) {
+                newMode = DISPLAY_POWER_MODE_ALWAYS_ON;
+            }
+            if (value.length() != 0) {
+                value.append(",");
+            }
+            value.append(displayId).append(":").append(newMode);
+        }
+
+        executeShellCommand(
+                "settings put global %s %s", DISPLAY_POWER_MODE, value.toString());
+    }
+
     private void makeSureExecutorReady() throws Exception {
         CountDownLatch latch = new CountDownLatch(1);
         mExecutor.execute(() -> {