1 /* 2 * Copyright (C) 2015 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 package com.android.car.hal; 17 18 import static android.hardware.automotive.vehicle.VehicleProperty.AP_POWER_STATE_REPORT; 19 import static android.hardware.automotive.vehicle.VehicleProperty.AP_POWER_STATE_REQ; 20 import static android.hardware.automotive.vehicle.VehicleProperty.DISPLAY_BRIGHTNESS; 21 22 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.DUMP_INFO; 23 24 import android.annotation.IntDef; 25 import android.annotation.Nullable; 26 import android.car.builtin.util.Slogf; 27 import android.hardware.automotive.vehicle.VehicleApPowerStateConfigFlag; 28 import android.hardware.automotive.vehicle.VehicleApPowerStateReport; 29 import android.hardware.automotive.vehicle.VehicleApPowerStateReq; 30 import android.hardware.automotive.vehicle.VehicleApPowerStateReqIndex; 31 import android.hardware.automotive.vehicle.VehicleApPowerStateShutdownParam; 32 import android.hardware.automotive.vehicle.VehicleProperty; 33 import android.os.ServiceSpecificException; 34 35 import com.android.car.CarLog; 36 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport; 37 import com.android.internal.annotations.GuardedBy; 38 import com.android.internal.annotations.VisibleForTesting; 39 import com.android.internal.util.Preconditions; 40 41 import java.io.PrintWriter; 42 import java.lang.annotation.Retention; 43 import java.lang.annotation.RetentionPolicy; 44 import java.util.Collection; 45 import java.util.HashMap; 46 import java.util.LinkedList; 47 import java.util.List; 48 import java.util.Objects; 49 50 /** 51 * Translates HAL power events to higher-level semantic information. 52 */ 53 public class PowerHalService extends HalServiceBase { 54 // Set display brightness from 0-100% 55 public static final int MAX_BRIGHTNESS = 100; 56 57 private static final int[] SUPPORTED_PROPERTIES = new int[]{ 58 AP_POWER_STATE_REQ, 59 AP_POWER_STATE_REPORT, 60 DISPLAY_BRIGHTNESS 61 }; 62 63 @VisibleForTesting 64 public static final int SET_WAIT_FOR_VHAL = VehicleApPowerStateReport.WAIT_FOR_VHAL; 65 @VisibleForTesting 66 public static final int SET_DEEP_SLEEP_ENTRY = VehicleApPowerStateReport.DEEP_SLEEP_ENTRY; 67 @VisibleForTesting 68 public static final int SET_DEEP_SLEEP_EXIT = VehicleApPowerStateReport.DEEP_SLEEP_EXIT; 69 @VisibleForTesting 70 public static final int SET_SHUTDOWN_POSTPONE = VehicleApPowerStateReport.SHUTDOWN_POSTPONE; 71 @VisibleForTesting 72 public static final int SET_SHUTDOWN_START = VehicleApPowerStateReport.SHUTDOWN_START; 73 @VisibleForTesting 74 public static final int SET_ON = VehicleApPowerStateReport.ON; 75 @VisibleForTesting 76 public static final int SET_SHUTDOWN_PREPARE = VehicleApPowerStateReport.SHUTDOWN_PREPARE; 77 @VisibleForTesting 78 public static final int SET_SHUTDOWN_CANCELLED = VehicleApPowerStateReport.SHUTDOWN_CANCELLED; 79 80 @VisibleForTesting 81 public static final int SHUTDOWN_CAN_SLEEP = VehicleApPowerStateShutdownParam.CAN_SLEEP; 82 @VisibleForTesting 83 public static final int SHUTDOWN_IMMEDIATELY = 84 VehicleApPowerStateShutdownParam.SHUTDOWN_IMMEDIATELY; 85 @VisibleForTesting 86 public static final int SHUTDOWN_ONLY = VehicleApPowerStateShutdownParam.SHUTDOWN_ONLY; 87 @VisibleForTesting 88 public static final int SET_HIBERNATION_ENTRY = VehicleApPowerStateReport.HIBERNATION_ENTRY; 89 @VisibleForTesting 90 public static final int SET_HIBERNATION_EXIT = VehicleApPowerStateReport.HIBERNATION_EXIT; 91 92 private final Object mLock = new Object(); 93 powerStateReportName(int state)94 private static String powerStateReportName(int state) { 95 String baseName; 96 switch(state) { 97 case SET_WAIT_FOR_VHAL: baseName = "WAIT_FOR_VHAL"; break; 98 case SET_DEEP_SLEEP_ENTRY: baseName = "DEEP_SLEEP_ENTRY"; break; 99 case SET_DEEP_SLEEP_EXIT: baseName = "DEEP_SLEEP_EXIT"; break; 100 case SET_SHUTDOWN_POSTPONE: baseName = "SHUTDOWN_POSTPONE"; break; 101 case SET_SHUTDOWN_START: baseName = "SHUTDOWN_START"; break; 102 case SET_ON: baseName = "ON"; break; 103 case SET_SHUTDOWN_PREPARE: baseName = "SHUTDOWN_PREPARE"; break; 104 case SET_SHUTDOWN_CANCELLED: baseName = "SHUTDOWN_CANCELLED"; break; 105 case SET_HIBERNATION_ENTRY: baseName = "HIBERNATION_ENTRY"; break; 106 case SET_HIBERNATION_EXIT: baseName = "HIBERNATION_EXIT"; break; 107 default: baseName = "<unknown>"; break; 108 } 109 return baseName + "(" + state + ")"; 110 } 111 powerStateReqName(int state)112 private static String powerStateReqName(int state) { 113 String baseName; 114 switch(state) { 115 case VehicleApPowerStateReq.ON: baseName = "ON"; break; 116 case VehicleApPowerStateReq.SHUTDOWN_PREPARE: baseName = "SHUTDOWN_PREPARE"; break; 117 case VehicleApPowerStateReq.CANCEL_SHUTDOWN: baseName = "CANCEL_SHUTDOWN"; break; 118 case VehicleApPowerStateReq.FINISHED: baseName = "FINISHED"; break; 119 default: baseName = "<unknown>"; break; 120 } 121 return baseName + "(" + state + ")"; 122 } 123 124 /** 125 * Interface to be implemented by any object that wants to be notified by any Vehicle's power 126 * change. 127 */ 128 public interface PowerEventListener { 129 /** 130 * Received power state change event. 131 * @param state One of STATE_* 132 */ onApPowerStateChange(PowerState state)133 void onApPowerStateChange(PowerState state); 134 135 /** 136 * Received display brightness change event. 137 * @param brightness in percentile. 100% full. 138 */ onDisplayBrightnessChange(int brightness)139 void onDisplayBrightnessChange(int brightness); 140 } 141 142 /** 143 * Contains information about the Vehicle's power state. 144 */ 145 public static final class PowerState { 146 147 @IntDef({SHUTDOWN_TYPE_UNDEFINED, SHUTDOWN_TYPE_POWER_OFF, SHUTDOWN_TYPE_DEEP_SLEEP, 148 SHUTDOWN_TYPE_HIBERNATION}) 149 @Retention(RetentionPolicy.SOURCE) 150 public @interface ShutdownType {} 151 152 public static final int SHUTDOWN_TYPE_UNDEFINED = 0; 153 public static final int SHUTDOWN_TYPE_POWER_OFF = 1; 154 public static final int SHUTDOWN_TYPE_DEEP_SLEEP = 2; 155 public static final int SHUTDOWN_TYPE_HIBERNATION = 3; 156 /** 157 * One of STATE_* 158 */ 159 public final int mState; 160 public final int mParam; 161 PowerState(int state, int param)162 public PowerState(int state, int param) { 163 this.mState = state; 164 this.mParam = param; 165 } 166 167 /** 168 * Whether the current PowerState allows postponing or not. Calling this for 169 * power state other than STATE_SHUTDOWN_PREPARE will trigger exception. 170 * @return 171 * @throws IllegalStateException 172 */ canPostponeShutdown()173 public boolean canPostponeShutdown() { 174 if (mState != VehicleApPowerStateReq.SHUTDOWN_PREPARE) { 175 throw new IllegalStateException("wrong state"); 176 } 177 return (mParam != VehicleApPowerStateShutdownParam.SHUTDOWN_IMMEDIATELY 178 && mParam != VehicleApPowerStateShutdownParam.SLEEP_IMMEDIATELY 179 && mParam != VehicleApPowerStateShutdownParam.HIBERNATE_IMMEDIATELY); 180 } 181 182 /** 183 * Gets whether the current PowerState allows suspend or not. 184 * 185 * @throws IllegalStateException if called in state other than {@code 186 * STATE_SHUTDOWN_PREPARE} 187 */ canSuspend()188 public boolean canSuspend() { 189 Preconditions.checkArgument(mState == VehicleApPowerStateReq.SHUTDOWN_PREPARE, 190 "canSuspend was called in the wrong state! State = %d", mState); 191 192 return (mParam == VehicleApPowerStateShutdownParam.CAN_HIBERNATE 193 || mParam == VehicleApPowerStateShutdownParam.HIBERNATE_IMMEDIATELY 194 || mParam == VehicleApPowerStateShutdownParam.CAN_SLEEP 195 || mParam == VehicleApPowerStateShutdownParam.SLEEP_IMMEDIATELY); 196 } 197 198 /** 199 * Gets shutdown type 200 * 201 * @return {@code ShutdownType} - type of shutdown 202 * @throws IllegalStateException if called in state other than {@code 203 * STATE_SHUTDOWN_PREPARE} 204 */ 205 @ShutdownType getShutdownType()206 public int getShutdownType() { 207 Preconditions.checkArgument(mState == VehicleApPowerStateReq.SHUTDOWN_PREPARE, 208 "getShutdownType was called in the wrong state! State = %d", mState); 209 210 int result = SHUTDOWN_TYPE_POWER_OFF; 211 if (mParam == VehicleApPowerStateShutdownParam.CAN_SLEEP 212 || mParam == VehicleApPowerStateShutdownParam.SLEEP_IMMEDIATELY) { 213 result = SHUTDOWN_TYPE_DEEP_SLEEP; 214 } else if (mParam == VehicleApPowerStateShutdownParam.CAN_HIBERNATE 215 || mParam == VehicleApPowerStateShutdownParam.HIBERNATE_IMMEDIATELY) { 216 result = SHUTDOWN_TYPE_HIBERNATION; 217 } 218 219 return result; 220 } 221 222 @Override equals(Object o)223 public boolean equals(Object o) { 224 if (this == o) { 225 return true; 226 } 227 if (!(o instanceof PowerState)) { 228 return false; 229 } 230 PowerState that = (PowerState) o; 231 return this.mState == that.mState && this.mParam == that.mParam; 232 } 233 234 @Override hashCode()235 public int hashCode() { 236 return Objects.hash(mState, mParam); 237 } 238 239 @Override toString()240 public String toString() { 241 return "PowerState state:" + mState + ", param:" + mParam; 242 } 243 } 244 245 @GuardedBy("mLock") 246 private final HashMap<Integer, HalPropConfig> mProperties = new HashMap<>(); 247 private final VehicleHal mHal; 248 @GuardedBy("mLock") 249 private LinkedList<HalPropValue> mQueuedEvents; 250 @GuardedBy("mLock") 251 private PowerEventListener mListener; 252 @GuardedBy("mLock") 253 private int mMaxDisplayBrightness; 254 PowerHalService(VehicleHal hal)255 public PowerHalService(VehicleHal hal) { 256 mHal = hal; 257 } 258 259 /** 260 * Sets the event listener to receive Vehicle's power events. 261 */ setListener(PowerEventListener listener)262 public void setListener(PowerEventListener listener) { 263 LinkedList<HalPropValue> eventsToDispatch = null; 264 synchronized (mLock) { 265 mListener = listener; 266 if (mQueuedEvents != null && mQueuedEvents.size() > 0) { 267 eventsToDispatch = mQueuedEvents; 268 } 269 mQueuedEvents = null; 270 } 271 // do this outside lock 272 if (eventsToDispatch != null) { 273 dispatchEvents(eventsToDispatch, listener); 274 } 275 } 276 277 /** 278 * Send WaitForVhal message to VHAL 279 */ sendWaitForVhal()280 public void sendWaitForVhal() { 281 Slogf.i(CarLog.TAG_POWER, "send wait for vhal"); 282 setPowerState(VehicleApPowerStateReport.WAIT_FOR_VHAL, 0); 283 } 284 285 /** 286 * Send SleepEntry message to VHAL 287 * @param wakeupTimeSec Notify VHAL when system wants to be woken from sleep. 288 */ sendSleepEntry(int wakeupTimeSec)289 public void sendSleepEntry(int wakeupTimeSec) { 290 Slogf.i(CarLog.TAG_POWER, "send sleep entry"); 291 setPowerState(VehicleApPowerStateReport.DEEP_SLEEP_ENTRY, wakeupTimeSec); 292 } 293 294 /** 295 * Send SleepExit message to VHAL 296 * Notifies VHAL when SOC has woken. 297 */ sendSleepExit()298 public void sendSleepExit() { 299 Slogf.i(CarLog.TAG_POWER, "send sleep exit"); 300 setPowerState(VehicleApPowerStateReport.DEEP_SLEEP_EXIT, 0); 301 } 302 303 /** 304 * Sends HibernationEntry message to VHAL 305 * 306 * @param wakeupTimeSec Number of seconds from now to be woken from sleep. 307 */ sendHibernationEntry(int wakeupTimeSec)308 public void sendHibernationEntry(int wakeupTimeSec) { 309 Slogf.i(CarLog.TAG_POWER, "send hibernation entry - wakeupTimeSec = %d", 310 wakeupTimeSec); 311 setPowerState(VehicleApPowerStateReport.HIBERNATION_ENTRY, wakeupTimeSec); 312 } 313 314 /** 315 * Sends HibernationExit message to VHAL 316 * 317 * Notifies VHAL after SOC woke up from hibernation. 318 */ sendHibernationExit()319 public void sendHibernationExit() { 320 Slogf.i(CarLog.TAG_POWER, "send hibernation exit"); 321 setPowerState(VehicleApPowerStateReport.HIBERNATION_EXIT, 0); 322 } 323 324 /** 325 * Send Shutdown Postpone message to VHAL 326 */ sendShutdownPostpone(int postponeTimeMs)327 public void sendShutdownPostpone(int postponeTimeMs) { 328 Slogf.i(CarLog.TAG_POWER, "send shutdown postpone, time:" + postponeTimeMs); 329 setPowerState(VehicleApPowerStateReport.SHUTDOWN_POSTPONE, postponeTimeMs); 330 } 331 332 /** 333 * Send Shutdown Start message to VHAL 334 */ sendShutdownStart(int wakeupTimeSec)335 public void sendShutdownStart(int wakeupTimeSec) { 336 Slogf.i(CarLog.TAG_POWER, "send shutdown start"); 337 setPowerState(VehicleApPowerStateReport.SHUTDOWN_START, wakeupTimeSec); 338 } 339 340 /** 341 * Send On message to VHAL 342 */ sendOn()343 public void sendOn() { 344 Slogf.i(CarLog.TAG_POWER, "send on"); 345 setPowerState(VehicleApPowerStateReport.ON, 0); 346 } 347 348 /** 349 * Send Shutdown Prepare message to VHAL 350 */ sendShutdownPrepare()351 public void sendShutdownPrepare() { 352 Slogf.i(CarLog.TAG_POWER, "send shutdown prepare"); 353 setPowerState(VehicleApPowerStateReport.SHUTDOWN_PREPARE, 0); 354 } 355 356 /** 357 * Send Shutdown Cancel message to VHAL 358 */ sendShutdownCancel()359 public void sendShutdownCancel() { 360 Slogf.i(CarLog.TAG_POWER, "send shutdown cancel"); 361 setPowerState(VehicleApPowerStateReport.SHUTDOWN_CANCELLED, 0); 362 } 363 364 /** 365 * Sets the display brightness for the vehicle. 366 * @param brightness value from 0 to 100. 367 */ sendDisplayBrightness(int brightness)368 public void sendDisplayBrightness(int brightness) { 369 if (brightness < 0) { 370 brightness = 0; 371 } else if (brightness > 100) { 372 brightness = 100; 373 } 374 synchronized (mLock) { 375 if (mProperties.get(DISPLAY_BRIGHTNESS) == null) { 376 return; 377 } 378 } 379 try { 380 mHal.set(VehicleProperty.DISPLAY_BRIGHTNESS, 0).to(brightness); 381 Slogf.i(CarLog.TAG_POWER, "send display brightness = " + brightness); 382 } catch (ServiceSpecificException | IllegalArgumentException e) { 383 Slogf.e(CarLog.TAG_POWER, "cannot set DISPLAY_BRIGHTNESS", e); 384 } 385 } 386 setPowerState(int state, int additionalParam)387 private void setPowerState(int state, int additionalParam) { 388 if (isPowerStateSupported()) { 389 int[] values = { state, additionalParam }; 390 try { 391 mHal.set(VehicleProperty.AP_POWER_STATE_REPORT, 0).to(values); 392 Slogf.i(CarLog.TAG_POWER, "setPowerState=" + powerStateReportName(state) 393 + " param=" + additionalParam); 394 } catch (ServiceSpecificException e) { 395 Slogf.e(CarLog.TAG_POWER, "cannot set to AP_POWER_STATE_REPORT", e); 396 } 397 } 398 } 399 400 /** 401 * Returns a {@link PowerState} representing the current power state for the vehicle. 402 */ 403 @Nullable getCurrentPowerState()404 public PowerState getCurrentPowerState() { 405 HalPropValue value; 406 try { 407 value = mHal.get(VehicleProperty.AP_POWER_STATE_REQ); 408 } catch (ServiceSpecificException e) { 409 Slogf.e(CarLog.TAG_POWER, "Cannot get AP_POWER_STATE_REQ", e); 410 return null; 411 } 412 return new PowerState(value.getInt32Value(VehicleApPowerStateReqIndex.STATE), 413 value.getInt32Value(VehicleApPowerStateReqIndex.ADDITIONAL)); 414 } 415 416 /** 417 * Determines if the current properties describe a valid power state 418 * @return true if both the power state request and power state report are valid 419 */ isPowerStateSupported()420 public boolean isPowerStateSupported() { 421 synchronized (mLock) { 422 return (mProperties.get(VehicleProperty.AP_POWER_STATE_REQ) != null) 423 && (mProperties.get(VehicleProperty.AP_POWER_STATE_REPORT) != null); 424 } 425 } 426 isConfigFlagSet(int flag)427 private boolean isConfigFlagSet(int flag) { 428 HalPropConfig config; 429 synchronized (mLock) { 430 config = mProperties.get(VehicleProperty.AP_POWER_STATE_REQ); 431 } 432 if (config == null) { 433 return false; 434 } 435 int[] configArray = config.getConfigArray(); 436 if (configArray.length < 1) { 437 return false; 438 } 439 return (configArray[0] & flag) != 0; 440 } 441 isDeepSleepAllowed()442 public boolean isDeepSleepAllowed() { 443 return isConfigFlagSet(VehicleApPowerStateConfigFlag.ENABLE_DEEP_SLEEP_FLAG); 444 } 445 isHibernationAllowed()446 public boolean isHibernationAllowed() { 447 return isConfigFlagSet(VehicleApPowerStateConfigFlag.ENABLE_HIBERNATION_FLAG); 448 } 449 isTimedWakeupAllowed()450 public boolean isTimedWakeupAllowed() { 451 return isConfigFlagSet(VehicleApPowerStateConfigFlag.CONFIG_SUPPORT_TIMER_POWER_ON_FLAG); 452 } 453 454 @Override init()455 public void init() { 456 synchronized (mLock) { 457 for (HalPropConfig config : mProperties.values()) { 458 if (VehicleHal.isPropertySubscribable(config)) { 459 mHal.subscribeProperty(this, config.getPropId()); 460 } 461 } 462 HalPropConfig brightnessProperty = mProperties.get(DISPLAY_BRIGHTNESS); 463 if (brightnessProperty != null) { 464 HalAreaConfig[] areaConfigs = brightnessProperty.getAreaConfigs(); 465 mMaxDisplayBrightness = areaConfigs.length > 0 466 ? areaConfigs[0].getMaxInt32Value() : 0; 467 if (mMaxDisplayBrightness <= 0) { 468 Slogf.w(CarLog.TAG_POWER, "Max display brightness from vehicle HAL is invalid:" 469 + mMaxDisplayBrightness); 470 mMaxDisplayBrightness = 1; 471 } 472 } 473 } 474 } 475 476 @Override release()477 public void release() { 478 synchronized (mLock) { 479 mProperties.clear(); 480 } 481 } 482 483 @Override getAllSupportedProperties()484 public int[] getAllSupportedProperties() { 485 return SUPPORTED_PROPERTIES; 486 } 487 488 @Override takeProperties(Collection<HalPropConfig> properties)489 public void takeProperties(Collection<HalPropConfig> properties) { 490 if (properties.isEmpty()) { 491 return; 492 } 493 synchronized (mLock) { 494 for (HalPropConfig config : properties) { 495 mProperties.put(config.getPropId(), config); 496 } 497 } 498 } 499 500 @Override onHalEvents(List<HalPropValue> values)501 public void onHalEvents(List<HalPropValue> values) { 502 PowerEventListener listener; 503 synchronized (mLock) { 504 if (mListener == null) { 505 if (mQueuedEvents == null) { 506 mQueuedEvents = new LinkedList<>(); 507 } 508 mQueuedEvents.addAll(values); 509 return; 510 } 511 listener = mListener; 512 } 513 dispatchEvents(values, listener); 514 } 515 dispatchEvents(List<HalPropValue> values, PowerEventListener listener)516 private void dispatchEvents(List<HalPropValue> values, PowerEventListener listener) { 517 for (HalPropValue v : values) { 518 switch (v.getPropId()) { 519 case AP_POWER_STATE_REPORT: 520 // Ignore this property event. It was generated inside of CarService. 521 break; 522 case AP_POWER_STATE_REQ: 523 int state; 524 int param; 525 try { 526 state = v.getInt32Value(VehicleApPowerStateReqIndex.STATE); 527 param = v.getInt32Value(VehicleApPowerStateReqIndex.ADDITIONAL); 528 } catch (IndexOutOfBoundsException e) { 529 Slogf.e(CarLog.TAG_POWER, "Received invalid event, ignore, int32Values: " 530 + v.dumpInt32Values(), e); 531 break; 532 } 533 Slogf.i(CarLog.TAG_POWER, "Received AP_POWER_STATE_REQ=" 534 + powerStateReqName(state) + " param=" + param); 535 listener.onApPowerStateChange(new PowerState(state, param)); 536 break; 537 case DISPLAY_BRIGHTNESS: 538 { 539 int maxBrightness; 540 synchronized (mLock) { 541 maxBrightness = mMaxDisplayBrightness; 542 } 543 int brightness; 544 try { 545 brightness = v.getInt32Value(0) * MAX_BRIGHTNESS / maxBrightness; 546 } catch (IndexOutOfBoundsException e) { 547 Slogf.e(CarLog.TAG_POWER, "Received invalid event, ignore, int32Values: " 548 + v.dumpInt32Values(), e); 549 break; 550 } 551 if (brightness < 0) { 552 Slogf.e(CarLog.TAG_POWER, "invalid brightness: " + brightness 553 + ", set to 0"); 554 brightness = 0; 555 } else if (brightness > MAX_BRIGHTNESS) { 556 Slogf.e(CarLog.TAG_POWER, "invalid brightness: " + brightness + ", set to " 557 + MAX_BRIGHTNESS); 558 brightness = MAX_BRIGHTNESS; 559 } 560 Slogf.i(CarLog.TAG_POWER, "Received DISPLAY_BRIGHTNESS=" + brightness); 561 listener.onDisplayBrightnessChange(brightness); 562 break; 563 } 564 } 565 } 566 } 567 568 @Override 569 @ExcludeFromCodeCoverageGeneratedReport(reason = DUMP_INFO) dump(PrintWriter writer)570 public void dump(PrintWriter writer) { 571 writer.println("*Power HAL*"); 572 writer.printf("isPowerStateSupported:%b, isDeepSleepAllowed:%b, isHibernationAllowed:%b\n", 573 isPowerStateSupported(), isDeepSleepAllowed(), isHibernationAllowed()); 574 575 } 576 } 577