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