1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.car.cts; 18 19 import android.car.cts.powerpolicy.CpmsFrameworkLayerStateInfo; 20 import android.car.cts.powerpolicy.CpmsSystemLayerStateInfo; 21 import android.car.cts.powerpolicy.LocationInfo; 22 import android.car.cts.powerpolicy.PowerPolicyConstants; 23 import android.car.cts.powerpolicy.PowerPolicyDef; 24 import android.car.cts.powerpolicy.PowerPolicyGroups; 25 import android.car.cts.powerpolicy.PowerPolicyTestAnalyzer; 26 import android.car.cts.powerpolicy.PowerPolicyTestHelper; 27 import android.car.cts.powerpolicy.PowerPolicyTestResult; 28 import android.car.cts.powerpolicy.SilentModeInfo; 29 import android.car.cts.powerpolicy.SystemInfoParser; 30 import android.car.cts.powerpolicy.WifiInfo; 31 32 import com.android.compatibility.common.util.CommonTestUtils; 33 import com.android.tradefed.log.LogUtil.CLog; 34 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; 35 36 import org.junit.After; 37 import org.junit.Assume; 38 import org.junit.Before; 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 42 import java.lang.reflect.Method; 43 44 @RunWith(DeviceJUnit4ClassRunner.class) 45 public final class PowerPolicyHostTest extends CarHostJUnit4TestCase { 46 private static final String ANDROID_CLIENT_PKG = "android.car.cts.app"; 47 private static final String ANDROID_CLIENT_ACTIVITY = ANDROID_CLIENT_PKG 48 + "/.PowerPolicyTestActivity"; 49 private static final String TEST_COMMAND_HEADER = 50 "am start -n " + ANDROID_CLIENT_ACTIVITY + " --es powerpolicy "; 51 52 private static final int DEFAULT_TIMEOUT_SEC = 20; 53 54 private final PowerPolicyTestAnalyzer mTestAnalyzer = new PowerPolicyTestAnalyzer(this); 55 56 @Before checkPrecondition()57 public void checkPrecondition() throws Exception { 58 checkDefaultPowerPolicySet("pre-condition"); 59 } 60 61 @After restoreInitCondition()62 public void restoreInitCondition() throws Exception { 63 applyPowerPolicy(PowerPolicyDef.IdSet.DEFAULT_ALL_ON); 64 } 65 66 @Test testPowerPolicySilentMode()67 public void testPowerPolicySilentMode() throws Exception { 68 String testcase = "testPowerPolicySilentModeFull:"; 69 String teststep; 70 PowerPolicyTestHelper testHelper; 71 72 SilentModeInfo smInfo = getSilentModeInfo(); 73 Assume.assumeTrue("HW does not support silent mode. Skip the test", 74 smInfo.getMonitoringHWStateSignal()); 75 76 teststep = "switch to forced silent"; 77 enterForcedSilentMode(); 78 testHelper = getTestHelper(testcase, 1, teststep); 79 testHelper.checkCurrentState(PowerPolicyConstants.CarPowerState.ON); 80 testHelper.checkCurrentPolicy(PowerPolicyDef.IdSet.NO_USER_INTERACTION); 81 testHelper.checkSilentModeStatus(true); 82 testHelper.checkSilentModeFull(SilentModeInfo.FORCED_SILENT); 83 testHelper.checkCurrentPowerComponents(PowerPolicyDef.PolicySet.NO_USER_INTERACT); 84 85 teststep = "restore to normal mode"; 86 leaveForcedSilentMode(); 87 testHelper = getTestHelper(testcase, 2, teststep); 88 testHelper.checkCurrentState(PowerPolicyConstants.CarPowerState.ON); 89 testHelper.checkCurrentPolicy(PowerPolicyDef.IdSet.DEFAULT_ALL_ON); 90 testHelper.checkSilentModeStatus(false); 91 testHelper.checkSilentModeFull(SilentModeInfo.NO_SILENT); 92 testHelper.checkCurrentPowerComponents(PowerPolicyDef.PolicySet.DEFAULT_ALL_ON); 93 } 94 95 /** 96 * Tests the error conditions for CPMS at the ON state. 97 * 98 * <p>All other VHAL events but {@code SHUTDOWN_PREPARE} shall not have any impact 99 * to CPMS power state. 100 */ 101 @Test testDefaultStateMachineAtONState()102 public void testDefaultStateMachineAtONState() throws Exception { 103 String testcase = "testDefaultStateMachineAtONState:"; 104 String[] stepNames = { 105 "trigger VHAL ON event", 106 "trigger VHAL CANCEL_SHUTDOWN", 107 "trigger VHAL FINISHED" 108 }; 109 int[] vhalReqs = { 110 PowerPolicyConstants.VhalPowerStateReq.ON, 111 PowerPolicyConstants.VhalPowerStateReq.CANCEL_SHUTDOWN, 112 PowerPolicyConstants.VhalPowerStateReq.FINISHED 113 }; 114 115 for (int i = 0; i < stepNames.length; i++) { 116 triggerVhalPowerStateReq(vhalReqs[i], PowerPolicyConstants.ShutdownParam.NOT_USED); 117 PowerPolicyTestHelper testHelper = getTestHelper(testcase, i + 1, stepNames[i]); 118 testHelper.checkCurrentState(PowerPolicyConstants.CarPowerState.ON); 119 testHelper.checkCurrentPolicy(PowerPolicyDef.IdSet.DEFAULT_ALL_ON); 120 } 121 } 122 123 @Test testPowerPolicyChange()124 public void testPowerPolicyChange() throws Exception { 125 String testcase = "testPowerPolicyChange:"; 126 int expectedTotalPolicies = PowerPolicyDef.PolicySet.TOTAL_DEFAULT_REGISTERED_POLICIES; 127 int stepNo = 0; 128 String teststep; 129 PowerPolicyTestHelper testHelper; 130 131 teststep = "check the inital power policies"; 132 testHelper = getTestHelper(testcase, stepNo++, teststep); 133 testHelper.checkCurrentState(PowerPolicyConstants.CarPowerState.ON); 134 testHelper.checkCurrentPolicy(PowerPolicyDef.IdSet.DEFAULT_ALL_ON); 135 testHelper.checkTotalRegisteredPolicies(expectedTotalPolicies); 136 137 // create two power policies, test1 and test2, for power policy change test 138 defineAndCheckPolicyTest1(testcase, stepNo++, ++expectedTotalPolicies); 139 defineAndCheckPolicyTest2(testcase, stepNo++, ++expectedTotalPolicies); 140 141 teststep = "apply power policy test1"; 142 applyPowerPolicy(PowerPolicyDef.IdSet.TEST1); 143 testHelper = getTestHelper(testcase, stepNo++, teststep); 144 testHelper.checkCurrentPolicy(PowerPolicyDef.IdSet.TEST1); 145 146 teststep = "apply power policy test2"; 147 applyPowerPolicy(PowerPolicyDef.IdSet.TEST2); 148 testHelper = getTestHelper(testcase, stepNo++, teststep); 149 testHelper.checkCurrentPolicy(PowerPolicyDef.IdSet.TEST2); 150 151 teststep = "revert power policy back to the default"; 152 applyPowerPolicy(PowerPolicyDef.IdSet.DEFAULT_ALL_ON); 153 testHelper = getTestHelper(testcase, stepNo++, teststep); 154 testHelper.checkCurrentPolicy(PowerPolicyDef.IdSet.DEFAULT_ALL_ON); 155 156 // add "test power policy listener" here so that one reboot clears all 157 defineAndCheckPolicyListenerTest(testcase, stepNo++, ++expectedTotalPolicies); 158 String clientTestcase = "PowerPolicyListenerTest"; 159 PowerPolicyTestResult testResult = new PowerPolicyTestResult(mTestAnalyzer); 160 String clientAction = "DUMP_LISTENER"; 161 String component = "AUDIO"; 162 163 setClientTestcase(clientTestcase); 164 int currentNumberListeners = getNumberPolicyListeners(); 165 registerPowerPolicyListener(component); 166 resetPowerPolicyListeners(); 167 waitUntilNumberPolicyListenersEquals(++currentNumberListeners); 168 applyPowerPolicy(PowerPolicyDef.IdSet.LISTENER_TEST); 169 waitPowerPolicyListenersUpdated(); 170 171 dumpPowerPolicyListener(component); 172 testResult.checkLastTestResultEntry(clientTestcase, clientAction, 173 component, PowerPolicyDef.PolicySet.LISTENER_TEST); 174 175 unregisterPowerPolicyListener(component); 176 applyPowerPolicy(PowerPolicyDef.IdSet.DEFAULT_ALL_ON); 177 waitPowerPolicyListenersUpdated(); 178 179 dumpPowerPolicyListener(component); 180 testResult.checkLastTestResultEntry(clientTestcase, clientAction, 181 component, "not_registered"); 182 clearClientTestcase(); 183 184 // add respect to user setting test case here to utilize a single device reboot 185 testPowerPolicyAndComponentUserSetting(); 186 187 // add power policy group test here to utilize added test1 and test2 policies 188 teststep = "check default power policy group"; 189 PowerPolicyGroups emptyGroups = new PowerPolicyGroups(); 190 testHelper = getTestHelper(testcase, stepNo++, teststep); 191 testHelper.checkCurrentPolicyGroupId(null); 192 testHelper.checkPowerPolicyGroups(emptyGroups); 193 194 teststep = "define power policy group"; 195 definePowerPolicyGroup(PowerPolicyGroups.TestSet.POLICY_GROUP_DEF1.toShellCommandString()); 196 definePowerPolicyGroup(PowerPolicyGroups.TestSet.POLICY_GROUP_DEF2.toShellCommandString()); 197 testHelper = getTestHelper(testcase, stepNo++, teststep); 198 testHelper.checkPowerPolicyGroups(PowerPolicyGroups.TestSet.POLICY_GROUPS1); 199 200 teststep = "set power policy group"; 201 setPowerPolicyGroup(PowerPolicyGroups.TestSet.GROUP_ID1); 202 testHelper = getTestHelper(testcase, stepNo++, teststep); 203 testHelper.checkCurrentPolicyGroupId(PowerPolicyGroups.TestSet.GROUP_ID1); 204 205 // reboot device to clear created TEST1 and TEST2 test cases. 206 // need to find a way to move reboot device into AfterAll 207 rebootDevice(); 208 teststep = "reboot to clear added test power policies"; 209 testHelper = getTestHelper(testcase, stepNo++, teststep); 210 expectedTotalPolicies = PowerPolicyDef.PolicySet.TOTAL_DEFAULT_REGISTERED_POLICIES; 211 testHelper.checkCurrentState(PowerPolicyConstants.CarPowerState.ON); 212 testHelper.checkCurrentPolicy(PowerPolicyDef.IdSet.DEFAULT_ALL_ON); 213 testHelper.checkTotalRegisteredPolicies(expectedTotalPolicies); 214 } 215 fetchActivityDumpsys()216 public String fetchActivityDumpsys() throws Exception { 217 return executeCommand("dumpsys activity %s", ANDROID_CLIENT_ACTIVITY); 218 } 219 getTestHelper(String testcase, int stepNo, String stepName)220 private PowerPolicyTestHelper getTestHelper(String testcase, int stepNo, String stepName) 221 throws Exception { 222 CpmsSystemLayerStateInfo cpmsSystemInfo = getCpmsSystemLayerStateInfo(); 223 CpmsFrameworkLayerStateInfo cpmsFrameworkInfo = getCpmsFrameworkLayerStateInfo(); 224 String normalizedStepName = String.format("%d. %s", stepNo, stepName); 225 return new PowerPolicyTestHelper(testcase, normalizedStepName, 226 cpmsFrameworkInfo, cpmsSystemInfo, getSilentModeInfo()); 227 } 228 triggerVhalPowerStateReq(int reqNo, int param)229 private void triggerVhalPowerStateReq(int reqNo, int param) throws Exception { 230 executeCommand("cmd car_service inject-vhal-event %d %d,%d", 231 PowerPolicyConstants.VHAL_POWER_STATE_REQ_PROPERTY_ID, reqNo, param); 232 } 233 getSilentModeInfo()234 private SilentModeInfo getSilentModeInfo() throws Exception { 235 return executeAndParseCommand( 236 new SystemInfoParser<SilentModeInfo>(SilentModeInfo.class), 237 SilentModeInfo.COMMAND); 238 } 239 getCpmsFrameworkLayerStateInfo()240 private CpmsFrameworkLayerStateInfo getCpmsFrameworkLayerStateInfo() throws Exception { 241 return executeAndParseCommand(new SystemInfoParser<CpmsFrameworkLayerStateInfo>( 242 CpmsFrameworkLayerStateInfo.class), CpmsFrameworkLayerStateInfo.COMMAND); 243 } 244 getCpmsSystemLayerStateInfo()245 private CpmsSystemLayerStateInfo getCpmsSystemLayerStateInfo() throws Exception { 246 return executeAndParseCommand(new SystemInfoParser<CpmsSystemLayerStateInfo>( 247 CpmsSystemLayerStateInfo.class), CpmsSystemLayerStateInfo.COMMAND); 248 } 249 rebootDevice()250 private void rebootDevice() throws Exception { 251 executeCommand("svc power reboot"); 252 waitForDeviceAvailable(); 253 } 254 enterForcedSilentMode()255 private void enterForcedSilentMode() throws Exception { 256 executeCommand("cmd car_service silent-mode forced-silent"); 257 waitUntilForcedSilentModeChangeTo(true); 258 } 259 leaveForcedSilentMode()260 private void leaveForcedSilentMode() throws Exception { 261 executeCommand("cmd car_service silent-mode forced-non-silent"); 262 executeCommand("cmd car_service silent-mode non-forced-silent-mode"); 263 waitUntilForcedSilentModeChangeTo(false); 264 } 265 definePowerPolicy(String policyStr)266 private void definePowerPolicy(String policyStr) throws Exception { 267 CLog.d("definePowerPolicy: %s", policyStr); 268 executeCommand("cmd car_service define-power-policy %s", policyStr); 269 } 270 applyPowerPolicy(String policyId)271 private void applyPowerPolicy(String policyId) throws Exception { 272 executeCommand("cmd car_service apply-power-policy %s", policyId); 273 } 274 definePowerPolicyGroup(String policyGroupStr)275 private void definePowerPolicyGroup(String policyGroupStr) throws Exception { 276 executeCommand("cmd car_service define-power-policy-group %s", policyGroupStr); 277 } 278 setPowerPolicyGroup(String policyGroupId)279 private void setPowerPolicyGroup(String policyGroupId) throws Exception { 280 executeCommand("cmd car_service set-power-policy-group %s", policyGroupId); 281 } 282 setClientTestcase(String testcase)283 private void setClientTestcase(String testcase) throws Exception { 284 executeCommand("%s settest,%s", TEST_COMMAND_HEADER, testcase); 285 } 286 clearClientTestcase()287 private void clearClientTestcase() throws Exception { 288 executeCommand("%s cleartest", TEST_COMMAND_HEADER); 289 } 290 registerPowerPolicyListener(String componentName)291 private void registerPowerPolicyListener(String componentName) throws Exception { 292 executeCommand("%s addlistener,%s", TEST_COMMAND_HEADER, componentName); 293 } 294 unregisterPowerPolicyListener(String componentName)295 private void unregisterPowerPolicyListener(String componentName) throws Exception { 296 executeCommand("%s removelistener,%s", TEST_COMMAND_HEADER, componentName); 297 } 298 dumpPowerPolicyListener(String componentName)299 private void dumpPowerPolicyListener(String componentName) throws Exception { 300 executeCommand("%s dumplistener,%s", TEST_COMMAND_HEADER, componentName); 301 } 302 waitPowerPolicyListenersUpdated()303 private void waitPowerPolicyListenersUpdated() throws Exception { 304 executeCommand("%s waitlisteners", TEST_COMMAND_HEADER); 305 } 306 resetPowerPolicyListeners()307 private void resetPowerPolicyListeners() throws Exception { 308 executeCommand("%s resetlisteners", TEST_COMMAND_HEADER); 309 } 310 getNumberPolicyListeners()311 private int getNumberPolicyListeners() throws Exception { 312 return getCpmsFrameworkLayerStateInfo().getNumberPolicyListeners(); 313 } 314 waitUntilNumberPolicyListenersEquals(int numListeners)315 private void waitUntilNumberPolicyListenersEquals(int numListeners) throws Exception { 316 CommonTestUtils.waitUntil("timed out (" + DEFAULT_TIMEOUT_SEC 317 + "s) getting number policy listeners", DEFAULT_TIMEOUT_SEC, 318 () -> (getNumberPolicyListeners() == numListeners)); 319 } 320 waitUntilForcedSilentModeChangeTo(boolean expected)321 private void waitUntilForcedSilentModeChangeTo(boolean expected) throws Exception { 322 String timeoutMsg = String.format("timed out (%ds) waiting for forced silent mode " 323 + "to be %b", DEFAULT_TIMEOUT_SEC, expected); 324 CommonTestUtils.waitUntil(timeoutMsg, DEFAULT_TIMEOUT_SEC, 325 () -> { 326 SilentModeInfo silentInfo = getSilentModeInfo(); 327 CpmsFrameworkLayerStateInfo cpmsInfo = getCpmsFrameworkLayerStateInfo(); 328 return (silentInfo.getForcedSilentMode() == expected) 329 && (cpmsInfo.getForcedSilentMode() == expected); 330 }); 331 } 332 waitForDeviceAvailable()333 private void waitForDeviceAvailable() throws Exception { 334 try { 335 getDevice().waitForDeviceAvailable(); 336 } catch (Exception e) { 337 CLog.w("device is not available, trying one more time"); 338 getDevice().waitForDeviceAvailable(); 339 } 340 } 341 checkDefaultPowerPolicySet(String testcase)342 private void checkDefaultPowerPolicySet(String testcase) throws Exception { 343 String teststep = "check if the car power is on the ON state"; 344 PowerPolicyTestHelper testHelper = new PowerPolicyTestHelper(testcase, teststep, 345 getCpmsFrameworkLayerStateInfo(), getCpmsSystemLayerStateInfo(), null); 346 testHelper.checkCurrentState(PowerPolicyConstants.CarPowerState.ON); 347 testHelper.checkRegisteredPolicy(PowerPolicyDef.PolicySet.INITIAL_ALL_ON); 348 testHelper.checkRegisteredPolicy(PowerPolicyDef.PolicySet.DEFAULT_ALL_ON); 349 testHelper.checkCurrentPolicy(PowerPolicyDef.IdSet.DEFAULT_ALL_ON); 350 } 351 defineAndCheckPolicyTest1(String testcase, int stepNo, int expectedTotalPolicies)352 private void defineAndCheckPolicyTest1(String testcase, int stepNo, 353 int expectedTotalPolicies) throws Exception { 354 String teststep = stepNo + ". define a new power policy with id test1"; 355 definePowerPolicy(PowerPolicyDef.PolicySet.TEST1.toString()); 356 PowerPolicyTestHelper testHelper = getTestHelper(testcase, stepNo, teststep); 357 testHelper.checkRegisteredPolicy(PowerPolicyDef.PolicySet.TEST1); 358 testHelper.checkTotalRegisteredPolicies(expectedTotalPolicies); 359 } 360 defineAndCheckPolicyTest2(String testcase, int stepNo, int expectedTotalPolicies)361 private void defineAndCheckPolicyTest2(String testcase, int stepNo, 362 int expectedTotalPolicies) throws Exception { 363 String teststep = stepNo + ". define a new power policy with id test2"; 364 definePowerPolicy(PowerPolicyDef.PolicySet.TEST2.toString()); 365 PowerPolicyTestHelper testHelper = getTestHelper(testcase, stepNo, teststep); 366 testHelper.checkRegisteredPolicy(PowerPolicyDef.PolicySet.TEST2); 367 testHelper.checkTotalRegisteredPolicies(expectedTotalPolicies); 368 } 369 defineAndCheckPolicyListenerTest(String testcase, int stepNo, int expectedTotalPolicies)370 private void defineAndCheckPolicyListenerTest(String testcase, int stepNo, 371 int expectedTotalPolicies) throws Exception { 372 String teststep = stepNo + ". define a new power policy with id listener_test"; 373 definePowerPolicy(PowerPolicyDef.PolicySet.LISTENER_TEST.toString()); 374 PowerPolicyTestHelper testHelper = getTestHelper(testcase, stepNo, teststep); 375 testHelper.checkRegisteredPolicy(PowerPolicyDef.PolicySet.LISTENER_TEST); 376 testHelper.checkTotalRegisteredPolicies(expectedTotalPolicies); 377 } 378 testPowerPolicyAndComponentUserSetting()379 private void testPowerPolicyAndComponentUserSetting() throws Exception { 380 ComponentTestHelper[] testHelpers = { 381 new ComponentTestHelper<WifiInfo>(this, "WIFI", WifiInfo.class), 382 new ComponentTestHelper<LocationInfo>(this, "LOCATION", LocationInfo.class), 383 }; 384 385 for (int i = 0; i < testHelpers.length; i++) { 386 testComponent(testHelpers[i]); 387 } 388 } 389 390 private static final class ComponentTestHelper<T> { 391 private final PowerPolicyHostTest mHostTest; 392 private final String mComponentName; 393 private final String mInfoRetrieveCommand; 394 private final String[] mEnableCommands; 395 private final String[] mDisableCommands; 396 private final Class mTypeClass; 397 ComponentTestHelper(PowerPolicyHostTest hostTest, String componentName, Class typeClass)398 ComponentTestHelper(PowerPolicyHostTest hostTest, String componentName, Class typeClass) 399 throws Exception { 400 mHostTest = hostTest; 401 mComponentName = componentName; 402 mTypeClass = typeClass; 403 mInfoRetrieveCommand = (String) mTypeClass.getField("COMMAND").get(null); 404 mEnableCommands = (String[]) mTypeClass.getField("ENABLE_COMMANDS").get(null); 405 mDisableCommands = (String[]) mTypeClass.getField("DISABLE_COMMANDS").get(null); 406 } 407 turnOnComponent()408 private void turnOnComponent() throws Exception { 409 for (int i = 0; i < mEnableCommands.length; i++) { 410 mHostTest.executeCommand(mEnableCommands[i]); 411 } 412 } 413 turnOffComponent()414 private void turnOffComponent() throws Exception { 415 for (int i = 0; i < mDisableCommands.length; i++) { 416 mHostTest.executeCommand(mDisableCommands[i]); 417 } 418 } 419 tryGetComponentInfo()420 private T tryGetComponentInfo() throws Exception { 421 return mHostTest.executeAndParseCommand(new SystemInfoParser<T>(mTypeClass), 422 mInfoRetrieveCommand); 423 } 424 waitUntilPowerStateChangeTo(boolean expected)425 private void waitUntilPowerStateChangeTo(boolean expected) throws Exception { 426 CommonTestUtils.waitUntil("timed out with " + mComponentName 427 + "enabled expected: " + expected, DEFAULT_TIMEOUT_SEC, 428 () -> { 429 T info = tryGetComponentInfo(); 430 if (info != null) { 431 Method isPowerOn = mTypeClass.getMethod("isPowerOn"); 432 Boolean result = (Boolean) isPowerOn.invoke(info); 433 return result.booleanValue() == expected; 434 } 435 return false; 436 }); 437 } 438 } 439 testComponent(ComponentTestHelper testHelper)440 private void testComponent(ComponentTestHelper testHelper) 441 throws Exception { 442 PowerPolicyDef powerOffPolicy = 443 PowerPolicyDef.createWithComponentOff(testHelper.mComponentName); 444 definePowerPolicy(powerOffPolicy.toString()); 445 446 testHelper.turnOffComponent(); 447 testHelper.waitUntilPowerStateChangeTo(false); 448 449 testHelper.turnOnComponent(); 450 testHelper.waitUntilPowerStateChangeTo(true); 451 452 applyPowerPolicy(powerOffPolicy.getPolicyId()); 453 testHelper.turnOnComponent(); 454 testHelper.waitUntilPowerStateChangeTo(true); 455 456 testHelper.turnOffComponent(); 457 testHelper.waitUntilPowerStateChangeTo(false); 458 } 459 } 460