• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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