• 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 
17 package com.android.car.power;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.app.ActivityManager;
22 import android.car.Car;
23 import android.car.hardware.power.CarPowerManager.CarPowerStateListener;
24 import android.car.hardware.power.CarPowerPolicy;
25 import android.car.hardware.power.CarPowerPolicyFilter;
26 import android.car.hardware.power.ICarPower;
27 import android.car.hardware.power.ICarPowerPolicyListener;
28 import android.car.hardware.power.ICarPowerStateListener;
29 import android.content.ComponentName;
30 import android.content.Context;
31 import android.content.Intent;
32 import android.content.pm.UserInfo;
33 import android.content.res.Resources;
34 import android.frameworks.automotive.powerpolicy.internal.ICarPowerPolicySystemNotification;
35 import android.frameworks.automotive.powerpolicy.internal.PolicyState;
36 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerStateReport;
37 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerStateReq;
38 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerStateShutdownParam;
39 import android.net.wifi.WifiManager;
40 import android.os.Build;
41 import android.os.Handler;
42 import android.os.HandlerThread;
43 import android.os.IBinder;
44 import android.os.IInterface;
45 import android.os.Looper;
46 import android.os.Message;
47 import android.os.PowerManager;
48 import android.os.RemoteCallbackList;
49 import android.os.RemoteException;
50 import android.os.ServiceManager;
51 import android.os.SystemClock;
52 import android.os.SystemProperties;
53 import android.os.UserHandle;
54 import android.os.UserManager;
55 import android.util.AtomicFile;
56 import android.util.IndentingPrintWriter;
57 import android.util.SparseArray;
58 
59 import com.android.car.CarLocalServices;
60 import com.android.car.CarLog;
61 import com.android.car.CarServiceBase;
62 import com.android.car.CarServiceUtils;
63 import com.android.car.CarStatsLogHelper;
64 import com.android.car.ICarImpl;
65 import com.android.car.R;
66 import com.android.car.am.ContinuousBlankActivity;
67 import com.android.car.hal.PowerHalService;
68 import com.android.car.hal.PowerHalService.PowerState;
69 import com.android.car.systeminterface.SystemInterface;
70 import com.android.car.user.CarUserNoticeService;
71 import com.android.car.user.CarUserService;
72 import com.android.internal.annotations.GuardedBy;
73 import com.android.internal.annotations.VisibleForTesting;
74 import com.android.internal.os.IResultReceiver;
75 import com.android.internal.util.Preconditions;
76 import com.android.internal.util.function.pooled.PooledLambda;
77 import com.android.server.utils.Slogf;
78 
79 import java.io.BufferedReader;
80 import java.io.BufferedWriter;
81 import java.io.File;
82 import java.io.FileOutputStream;
83 import java.io.IOException;
84 import java.io.InputStreamReader;
85 import java.io.OutputStreamWriter;
86 import java.lang.ref.WeakReference;
87 import java.nio.charset.StandardCharsets;
88 import java.util.HashSet;
89 import java.util.LinkedList;
90 import java.util.Set;
91 import java.util.Timer;
92 import java.util.TimerTask;
93 
94 /**
95  * Power Management service class for cars. Controls the power states and interacts with other
96  * parts of the system to ensure its own state.
97  */
98 public class CarPowerManagementService extends ICarPower.Stub implements
99         CarServiceBase, PowerHalService.PowerEventListener {
100     public static final String SILENT_MODE_FORCED_SILENT =
101             SilentModeHandler.SILENT_MODE_FORCED_SILENT;
102     public static final String SILENT_MODE_FORCED_NON_SILENT =
103             SilentModeHandler.SILENT_MODE_FORCED_NON_SILENT;
104     public static final String SILENT_MODE_NON_FORCED = SilentModeHandler.SILENT_MODE_NON_FORCED;
105 
106     private static final String TAG = CarLog.tagFor(CarPowerManagementService.class);
107     private static final String WIFI_STATE_FILENAME = "wifi_state";
108     private static final String WIFI_STATE_MODIFIED = "forcibly_disabled";
109     private static final String WIFI_STATE_ORIGINAL = "original";
110     // If Suspend to RAM fails, we retry with an exponential back-off:
111     // The wait interval will be 10 msec, 20 msec, 40 msec, ...
112     // Once the wait interval goes beyond 100 msec, it is fixed at 100 msec.
113     private static final long INITIAL_SUSPEND_RETRY_INTERVAL_MS = 10;
114     private static final long MAX_RETRY_INTERVAL_MS = 100;
115     // Minimum and maximum wait duration before the system goes into Suspend to RAM.
116     private static final long MIN_SUSPEND_WAIT_DURATION_MS = 0;
117     private static final long MAX_SUSPEND_WAIT_DURATION_MS = 3 * 60 * 1000;
118 
119     private static final long CAR_POWER_POLICY_DAEMON_FIND_MARGINAL_TIME_MS = 300;
120     private static final long CAR_POWER_POLICY_DAEMON_BIND_RETRY_INTERVAL_MS = 500;
121     private static final int CAR_POWER_POLICY_DAEMON_BIND_MAX_RETRY = 3;
122     private static final String CAR_POWER_POLICY_DAEMON_INTERFACE =
123             "carpowerpolicy_system_notification";
124 
125     // TODO:  Make this OEM configurable.
126     private static final int SHUTDOWN_POLLING_INTERVAL_MS = 2000;
127     private static final int SHUTDOWN_EXTEND_MAX_MS = 5000;
128 
129     // maxGarageModeRunningDurationInSecs should be equal or greater than this. 15 min for now.
130     private static final int MIN_MAX_GARAGE_MODE_DURATION_MS = 15 * 60 * 1000;
131 
132     // in secs
133     private static final String PROP_MAX_GARAGE_MODE_DURATION_OVERRIDE =
134             "android.car.garagemodeduration";
135 
136     private final Object mLock = new Object();
137     private final Object mSimulationWaitObject = new Object();
138 
139     private final Context mContext;
140     private final PowerHalService mHal;
141     private final SystemInterface mSystemInterface;
142     // The listeners that complete simply by returning from onStateChanged()
143     private final PowerManagerCallbackList<ICarPowerStateListener> mPowerManagerListeners =
144             new PowerManagerCallbackList<>(
145                     l -> CarPowerManagementService.this.doUnregisterListener(l));
146     // The listeners that must indicate asynchronous completion by calling finished().
147     private final PowerManagerCallbackList<ICarPowerStateListener>
148             mPowerManagerListenersWithCompletion = new PowerManagerCallbackList<>(
149                     l -> CarPowerManagementService.this.doUnregisterListener(l));
150 
151     @GuardedBy("mLock")
152     private final Set<IBinder> mListenersWeAreWaitingFor = new HashSet<>();
153     @GuardedBy("mLock")
154     private final LinkedList<CpmsState> mPendingPowerStates = new LinkedList<>();
155     private final HandlerThread mHandlerThread = CarServiceUtils.getHandlerThread(
156             getClass().getSimpleName());
157     private final PowerHandler mHandler = new PowerHandler(mHandlerThread.getLooper(), this);
158 
159     private final UserManager mUserManager;
160     private final CarUserService mUserService;
161 
162     private final WifiManager mWifiManager;
163     private final AtomicFile mWifiStateFile;
164     private final boolean mWifiAdjustmentForSuspend;
165 
166     // This is a temp work-around to reduce user switching delay after wake-up.
167     private final boolean mSwitchGuestUserBeforeSleep;
168 
169     // CPMS tries to enter Suspend to RAM within the duration specified at
170     // mMaxSuspendWaitDurationMs. The default max duration is MAX_SUSPEND_WAIT_DRATION, and can be
171     // overridden by setting config_maxSuspendWaitDuration in an overrlay resource.
172     // The valid range is MIN_SUSPEND_WAIT_DRATION to MAX_SUSPEND_WAIT_DURATION.
173     private final long mMaxSuspendWaitDurationMs;
174 
175     @GuardedBy("mSimulationWaitObject")
176     private boolean mWakeFromSimulatedSleep;
177     @GuardedBy("mSimulationWaitObject")
178     private boolean mInSimulatedDeepSleepMode;
179 
180     @GuardedBy("mLock")
181     private CpmsState mCurrentState;
182     @GuardedBy("mLock")
183     private Timer mTimer;
184     @GuardedBy("mLock")
185     private long mProcessingStartTime;
186     @GuardedBy("mLock")
187     private long mLastSleepEntryTime;
188 
189     @GuardedBy("mLock")
190     private boolean mTimerActive;
191     @GuardedBy("mLock")
192     private int mNextWakeupSec;
193     @GuardedBy("mLock")
194     private boolean mShutdownOnFinish;
195     @GuardedBy("mLock")
196     private boolean mShutdownOnNextSuspend;
197     @GuardedBy("mLock")
198     private boolean mIsBooting = true;
199     @GuardedBy("mLock")
200     private int mShutdownPrepareTimeMs = MIN_MAX_GARAGE_MODE_DURATION_MS;
201     @GuardedBy("mLock")
202     private int mShutdownPollingIntervalMs = SHUTDOWN_POLLING_INTERVAL_MS;
203     @GuardedBy("mLock")
204     private boolean mRebootAfterGarageMode;
205     @GuardedBy("mLock")
206     private boolean mGarageModeShouldExitImmediately;
207 
208     @GuardedBy("mLock")
209     private ICarPowerPolicySystemNotification mCarPowerPolicyDaemon;
210     @GuardedBy("mLock")
211     private boolean mConnectionInProgress;
212     private BinderHandler mBinderHandler;
213     @GuardedBy("mLock")
214     private String mCurrentPowerPolicyId;
215     @GuardedBy("mLock")
216     private String mPendingPowerPolicyId;
217     @GuardedBy("mLock")
218     private String mCurrentPowerPolicyGroupId;
219     @GuardedBy("mLock")
220     private boolean mIsPowerPolicyLocked;
221     @GuardedBy("mLock")
222     private boolean mHasControlOverDaemon;
223 
224     @GuardedBy("mLock")
225     @Nullable
226     private IResultReceiver mFactoryResetCallback;
227 
228     private final PowerManagerCallbackList<ICarPowerPolicyListener> mPowerPolicyListeners =
229             new PowerManagerCallbackList<>(
230                     l -> CarPowerManagementService.this.mPowerPolicyListeners.unregister(l));
231 
232     private final PowerComponentHandler mPowerComponentHandler;
233     private final PolicyReader mPolicyReader = new PolicyReader();
234     private final SilentModeHandler mSilentModeHandler;
235 
236     interface ActionOnDeath<T extends IInterface> {
take(T listener)237         void take(T listener);
238     }
239 
240     private final class PowerManagerCallbackList<T extends IInterface> extends
241             RemoteCallbackList<T> {
242         private ActionOnDeath<T> mActionOnDeath;
243 
PowerManagerCallbackList(ActionOnDeath<T> action)244         PowerManagerCallbackList(ActionOnDeath<T> action) {
245             mActionOnDeath = action;
246         }
247 
248         /**
249          * Old version of {@link #onCallbackDied(E, Object)} that
250          * does not provide a cookie.
251          */
252         @Override
onCallbackDied(T listener)253         public void onCallbackDied(T listener) {
254             Slogf.i(TAG, "binderDied %s", listener.asBinder());
255             mActionOnDeath.take(listener);
256         }
257     }
258 
CarPowerManagementService(Context context, PowerHalService powerHal, SystemInterface systemInterface, CarUserService carUserService, ICarPowerPolicySystemNotification powerPolicyDaemon)259     public CarPowerManagementService(Context context, PowerHalService powerHal,
260             SystemInterface systemInterface, CarUserService carUserService,
261             ICarPowerPolicySystemNotification powerPolicyDaemon) {
262         this(context, context.getResources(), powerHal, systemInterface, UserManager.get(context),
263                 carUserService, powerPolicyDaemon,
264                 new PowerComponentHandler(context, systemInterface),
265                 /* silentModeHwStatePath= */ null, /* silentModeKernelStatePath= */ null,
266                 /* bootReason= */ null);
267     }
268 
269     @VisibleForTesting
CarPowerManagementService(Context context, Resources resources, PowerHalService powerHal, SystemInterface systemInterface, UserManager userManager, CarUserService carUserService, ICarPowerPolicySystemNotification powerPolicyDaemon, PowerComponentHandler powerComponentHandler, @Nullable String silentModeHwStatePath, @Nullable String silentModeKernelStatePath, @Nullable String bootReason)270     public CarPowerManagementService(Context context, Resources resources, PowerHalService powerHal,
271             SystemInterface systemInterface, UserManager userManager, CarUserService carUserService,
272             ICarPowerPolicySystemNotification powerPolicyDaemon,
273             PowerComponentHandler powerComponentHandler, @Nullable String silentModeHwStatePath,
274             @Nullable String silentModeKernelStatePath, @Nullable String bootReason) {
275         mContext = context;
276         mHal = powerHal;
277         mSystemInterface = systemInterface;
278         mUserManager = userManager;
279         mShutdownPrepareTimeMs = resources.getInteger(
280                 R.integer.maxGarageModeRunningDurationInSecs) * 1000;
281         mSwitchGuestUserBeforeSleep = resources.getBoolean(
282                 R.bool.config_switchGuestUserBeforeGoingSleep);
283         if (mShutdownPrepareTimeMs < MIN_MAX_GARAGE_MODE_DURATION_MS) {
284             Slogf.w(TAG,
285                     "maxGarageModeRunningDurationInSecs smaller than minimum required, "
286                     + "resource:%d(ms) while should exceed:%d(ms), Ignore resource.",
287                     mShutdownPrepareTimeMs, MIN_MAX_GARAGE_MODE_DURATION_MS);
288             mShutdownPrepareTimeMs = MIN_MAX_GARAGE_MODE_DURATION_MS;
289         }
290         mUserService = carUserService;
291         mCarPowerPolicyDaemon = powerPolicyDaemon;
292         if (powerPolicyDaemon != null) {
293             // For testing purpose
294             mHasControlOverDaemon = true;
295         }
296         mWifiManager = context.getSystemService(WifiManager.class);
297         mWifiStateFile = new AtomicFile(
298                 new File(mSystemInterface.getSystemCarDir(), WIFI_STATE_FILENAME));
299         mWifiAdjustmentForSuspend = getWifiAdjustmentForSuspendConfig();
300         mPowerComponentHandler = powerComponentHandler;
301         mSilentModeHandler = new SilentModeHandler(this, silentModeHwStatePath,
302                 silentModeKernelStatePath, bootReason);
303         mMaxSuspendWaitDurationMs = Math.max(MIN_SUSPEND_WAIT_DURATION_MS,
304                 Math.min(getMaxSuspendWaitDurationConfig(), MAX_SUSPEND_WAIT_DURATION_MS));
305     }
306 
307     /**
308      * Overrides timers to keep testing time short.
309      *
310      * <p>Passing in {@code 0} resets the value to the default.
311      */
312     @VisibleForTesting
setShutdownTimersForTest(int pollingIntervalMs, int shutdownTimeoutMs)313     public void setShutdownTimersForTest(int pollingIntervalMs, int shutdownTimeoutMs) {
314         synchronized (mLock) {
315             mShutdownPollingIntervalMs =
316                     (pollingIntervalMs == 0) ? SHUTDOWN_POLLING_INTERVAL_MS : pollingIntervalMs;
317             mShutdownPrepareTimeMs =
318                     (shutdownTimeoutMs == 0) ? SHUTDOWN_EXTEND_MAX_MS : shutdownTimeoutMs;
319         }
320     }
321 
322     @VisibleForTesting
getHandlerThread()323     protected HandlerThread getHandlerThread() {
324         return mHandlerThread;
325     }
326 
327     @Override
init()328     public void init() {
329         mPolicyReader.init();
330         mPowerComponentHandler.init();
331         mHal.setListener(this);
332         if (mHal.isPowerStateSupported()) {
333             // Initialize CPMS in WAIT_FOR_VHAL state
334             onApPowerStateChange(CpmsState.WAIT_FOR_VHAL, CarPowerStateListener.WAIT_FOR_VHAL);
335         } else {
336             Slogf.w(TAG, "Vehicle hal does not support power state yet.");
337             onApPowerStateChange(CpmsState.ON, CarPowerStateListener.ON);
338         }
339         mSystemInterface.startDisplayStateMonitoring(this);
340         connectToPowerPolicyDaemon();
341     }
342 
343     @Override
release()344     public void release() {
345         if (mBinderHandler != null) {
346             mBinderHandler.unlinkToDeath();
347         }
348         synchronized (mLock) {
349             releaseTimerLocked();
350             mCurrentState = null;
351             mCarPowerPolicyDaemon = null;
352             mHandler.cancelAll();
353             mListenersWeAreWaitingFor.clear();
354         }
355         mSystemInterface.stopDisplayStateMonitoring();
356         mPowerManagerListeners.kill();
357         mPowerPolicyListeners.kill();
358         mSystemInterface.releaseAllWakeLocks();
359     }
360 
361     @Override
dump(IndentingPrintWriter writer)362     public void dump(IndentingPrintWriter writer) {
363         synchronized (mLock) {
364             writer.println("*PowerManagementService*");
365             writer.printf("mCurrentState: %s\n", mCurrentState);
366             writer.printf("mProcessingStartTime: %d\n", mProcessingStartTime);
367             writer.printf("mLastSleepEntryTime: %d\n", mLastSleepEntryTime);
368             writer.printf("mNextWakeupSec: %d\n", mNextWakeupSec);
369             writer.printf("mShutdownOnNextSuspend: %b\n", mShutdownOnNextSuspend);
370             writer.printf("mShutdownOnFinish: %b\n", mShutdownOnFinish);
371             writer.printf("mShutdownPollingIntervalMs: %d\n", mShutdownPollingIntervalMs);
372             writer.printf("mShutdownPrepareTimeMs: %d\n", mShutdownPrepareTimeMs);
373             writer.printf("mRebootAfterGarageMode: %b\n", mRebootAfterGarageMode);
374             writer.printf("mSwitchGuestUserBeforeSleep: %b\n", mSwitchGuestUserBeforeSleep);
375             writer.printf("mCurrentPowerPolicyId: %s\n", mCurrentPowerPolicyId);
376             writer.printf("mPendingPowerPolicyId: %s\n", mPendingPowerPolicyId);
377             writer.printf("mCurrentPowerPolicyGroupId: %s\n", mCurrentPowerPolicyGroupId);
378             writer.printf("mIsPowerPolicyLocked: %b\n", mIsPowerPolicyLocked);
379             writer.printf("mMaxSuspendWaitDurationMs: %d\n", mMaxSuspendWaitDurationMs);
380             writer.printf("config_maxSuspendWaitDuration: %d\n", getMaxSuspendWaitDurationConfig());
381             writer.printf("# of power policy change listener: %d\n",
382                     mPowerPolicyListeners.getRegisteredCallbackCount());
383             writer.printf("mFactoryResetCallback: %s\n", mFactoryResetCallback);
384         }
385         mPolicyReader.dump(writer);
386         mPowerComponentHandler.dump(writer);
387         mSilentModeHandler.dump(writer);
388     }
389 
390     @Override
onApPowerStateChange(PowerState state)391     public void onApPowerStateChange(PowerState state) {
392         synchronized (mLock) {
393             mPendingPowerStates.addFirst(new CpmsState(state));
394             mLock.notify();
395         }
396         mHandler.handlePowerStateChange();
397     }
398 
399     @VisibleForTesting
setStateForWakeUp()400     void setStateForWakeUp() {
401         mSilentModeHandler.init();
402         synchronized (mLock) {
403             mIsBooting = false;
404         }
405         handleWaitForVhal(new CpmsState(CpmsState.WAIT_FOR_VHAL,
406                 CarPowerStateListener.WAIT_FOR_VHAL));
407         Slogf.d(TAG, "setStateForTesting(): mIsBooting is set to false and power state is switched "
408                 + "to Wait For Vhal");
409     }
410 
411     /**
412      * Initiate state change from CPMS directly.
413      */
onApPowerStateChange(int apState, int carPowerStateListenerState)414     private void onApPowerStateChange(int apState, int carPowerStateListenerState) {
415         CpmsState newState = new CpmsState(apState, carPowerStateListenerState);
416         synchronized (mLock) {
417             if (newState.mState == CpmsState.WAIT_FOR_FINISH) {
418                 // We are ready to shut down. Suppress this transition if
419                 // there is a request to cancel the shutdown (WAIT_FOR_VHAL).
420                 for (int idx = 0; idx < mPendingPowerStates.size(); idx++) {
421                     if (mPendingPowerStates.get(idx).mState == CpmsState.WAIT_FOR_VHAL) {
422                         // Completely ignore this WAIT_FOR_FINISH
423                         return;
424                     }
425                 }
426             }
427             mPendingPowerStates.addFirst(newState);
428             mLock.notify();
429         }
430         mHandler.handlePowerStateChange();
431     }
432 
doHandlePowerStateChange()433     private void doHandlePowerStateChange() {
434         CpmsState state;
435         synchronized (mLock) {
436             state = mPendingPowerStates.peekFirst();
437             mPendingPowerStates.clear();
438             if (state == null) {
439                 Slogf.e(TAG, "Null power state was requested");
440                 return;
441             }
442             Slogf.i(TAG, "doHandlePowerStateChange: newState=%s", state.name());
443             if (!needPowerStateChangeLocked(state)) {
444                 return;
445             }
446             // now real power change happens. Whatever was queued before should be all cancelled.
447             releaseTimerLocked();
448             mCurrentState = state;
449         }
450         mHandler.cancelProcessingComplete();
451         Slogf.i(TAG, "setCurrentState %s", state);
452         CarStatsLogHelper.logPowerState(state.mState);
453         switch (state.mState) {
454             case CpmsState.WAIT_FOR_VHAL:
455                 handleWaitForVhal(state);
456                 break;
457             case CpmsState.ON:
458                 handleOn();
459                 break;
460             case CpmsState.SHUTDOWN_PREPARE:
461                 handleShutdownPrepare(state);
462                 break;
463             case CpmsState.SIMULATE_SLEEP:
464                 simulateShutdownPrepare();
465                 break;
466             case CpmsState.WAIT_FOR_FINISH:
467                 handleWaitForFinish(state);
468                 break;
469             case CpmsState.SUSPEND:
470                 // Received FINISH from VHAL
471                 handleFinish();
472                 break;
473             default:
474                 // Illegal state
475                 // TODO:  Throw exception?
476                 break;
477         }
478     }
479 
handleWaitForVhal(CpmsState state)480     private void handleWaitForVhal(CpmsState state) {
481         int carPowerStateListenerState = state.mCarPowerStateListenerState;
482         // TODO(b/177478420): Restore Wifi, Audio, Location, and Bluetooth, if they are artificially
483         // modified for S2R.
484         mSilentModeHandler.querySilentModeHwState();
485         sendPowerManagerEvent(carPowerStateListenerState);
486         // Inspect CarPowerStateListenerState to decide which message to send via VHAL
487         switch (carPowerStateListenerState) {
488             case CarPowerStateListener.WAIT_FOR_VHAL:
489                 mHal.sendWaitForVhal();
490                 break;
491             case CarPowerStateListener.SHUTDOWN_CANCELLED:
492                 mShutdownOnNextSuspend = false; // This cancels the "NextSuspend"
493                 mHal.sendShutdownCancel();
494                 break;
495             case CarPowerStateListener.SUSPEND_EXIT:
496                 mHal.sendSleepExit();
497                 break;
498         }
499         if (mWifiAdjustmentForSuspend) restoreWifi();
500     }
501 
updateCarUserNoticeServiceIfNecessary()502     private void updateCarUserNoticeServiceIfNecessary() {
503         try {
504             int currentUserId = ActivityManager.getCurrentUser();
505             UserInfo currentUserInfo = mUserManager.getUserInfo(currentUserId);
506             CarUserNoticeService carUserNoticeService =
507                     CarLocalServices.getService(CarUserNoticeService.class);
508             if (currentUserInfo != null && currentUserInfo.isGuest()
509                     && carUserNoticeService != null) {
510                 Slogf.i(TAG, "Car user notice service will ignore all messages before user "
511                         + "switch.");
512                 Intent intent = new Intent();
513                 intent.setComponent(new ComponentName(mContext.getPackageName(),
514                         ContinuousBlankActivity.class.getName()));
515                 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
516                 mContext.startActivityAsUser(intent, UserHandle.CURRENT);
517                 carUserNoticeService.ignoreUserNotice(currentUserId);
518             }
519         } catch (Exception e) {
520             Slogf.w(TAG, e, "Cannot ignore user notice for current user");
521         }
522     }
523 
524     @VisibleForTesting
handleOn()525     void handleOn() {
526         if (factoryResetIfNeeded()) return;
527 
528         // If current user is a Guest User, we want to inform CarUserNoticeService not to show
529         // notice for current user, and show user notice only for the target user.
530         if (!mSwitchGuestUserBeforeSleep) {
531             updateCarUserNoticeServiceIfNecessary();
532         }
533 
534         boolean isPreemptive;
535         synchronized (mLock) {
536             isPreemptive = mPolicyReader.isPreemptivePowerPolicy(mCurrentPowerPolicyId);
537         }
538         if (!mSilentModeHandler.isSilentMode() && isPreemptive) {
539             cancelPreemptivePowerPolicy();
540         } else {
541             applyDefaultPowerPolicyForState(VehicleApPowerStateReport.ON,
542                     PolicyReader.POWER_POLICY_ID_ALL_ON);
543         }
544 
545         sendPowerManagerEvent(CarPowerStateListener.ON);
546 
547         mHal.sendOn();
548 
549         synchronized (mLock) {
550             if (mIsBooting) {
551                 Slogf.d(TAG, "handleOn(): called on boot");
552                 mIsBooting = false;
553                 return;
554             }
555         }
556 
557         try {
558             mUserService.onResume();
559         } catch (Exception e) {
560             Slogf.e(TAG, e, "Could not switch user on resume");
561         }
562     }
563 
factoryResetIfNeeded()564     private boolean factoryResetIfNeeded() {
565         IResultReceiver callback;
566         synchronized (mLock) {
567             if (mFactoryResetCallback == null) return false;
568             callback = mFactoryResetCallback;
569         }
570 
571         try {
572             Slogf.i(TAG, "Factory resetting as it was delayed by user");
573             callback.send(/* resultCode= */ 0, /* resultData= */ null);
574             return true;
575         } catch (Exception e) {
576             Slogf.wtf(TAG, e, "Should have factory reset, but failed");
577             return false;
578         }
579     }
580 
applyDefaultPowerPolicyForState(int state, @Nullable String fallbackPolicyId)581     private void applyDefaultPowerPolicyForState(int state, @Nullable String fallbackPolicyId) {
582         CarPowerPolicy policy;
583         synchronized (mLock) {
584             policy = mPolicyReader
585                     .getDefaultPowerPolicyForState(mCurrentPowerPolicyGroupId, state);
586         }
587         if (policy == null && fallbackPolicyId == null) {
588             Slogf.w(TAG, "No default power policy for %s is found",
589                     PolicyReader.powerStateToString(state));
590             return;
591         }
592         String policyId = policy == null ? fallbackPolicyId : policy.getPolicyId();
593         applyPowerPolicy(policyId, /* upToDaemon= */ true);
594     }
595 
596     /**
597      * Sets the callback used to factory reset the device on resume when the user delayed it.
598      */
setFactoryResetCallback(IResultReceiver callback)599     public void setFactoryResetCallback(IResultReceiver callback) {
600         synchronized (mLock) {
601             mFactoryResetCallback = callback;
602         }
603     }
604 
605     /**
606      * Tells Garage Mode if it should run normally, or just
607      * exit immediately without indicating 'idle'
608      * @return True if no idle jobs should be run
609      * @hide
610      */
garageModeShouldExitImmediately()611     public boolean garageModeShouldExitImmediately() {
612         synchronized (mLock) {
613             return mGarageModeShouldExitImmediately;
614         }
615     }
616 
handleShutdownPrepare(CpmsState newState)617     private void handleShutdownPrepare(CpmsState newState) {
618         // Shutdown on finish if the system doesn't support deep sleep or doesn't allow it.
619         synchronized (mLock) {
620             mShutdownOnFinish = mShutdownOnNextSuspend
621                     || !mHal.isDeepSleepAllowed()
622                     || !mSystemInterface.isSystemSupportingDeepSleep()
623                     || !newState.mCanSleep;
624             mGarageModeShouldExitImmediately = !newState.mCanPostpone;
625         }
626         Slogf.i(TAG,
627                 (newState.mCanPostpone
628                 ? "starting shutdown prepare with Garage Mode"
629                         : "starting shutdown prepare without Garage Mode"));
630         makeSureNoUserInteraction();
631         sendPowerManagerEvent(CarPowerStateListener.SHUTDOWN_PREPARE);
632         mHal.sendShutdownPrepare();
633         doHandlePreprocessing();
634     }
635 
636     // Simulate system shutdown to Deep Sleep
simulateShutdownPrepare()637     private void simulateShutdownPrepare() {
638         Slogf.i(TAG, "starting shutdown prepare");
639         makeSureNoUserInteraction();
640         sendPowerManagerEvent(CarPowerStateListener.SHUTDOWN_PREPARE);
641         mHal.sendShutdownPrepare();
642         doHandlePreprocessing();
643     }
644 
handleWaitForFinish(CpmsState state)645     private void handleWaitForFinish(CpmsState state) {
646         sendPowerManagerEvent(state.mCarPowerStateListenerState);
647         int wakeupSec;
648         synchronized (mLock) {
649             // If we're shutting down immediately, don't schedule
650             // a wakeup time.
651             wakeupSec = mGarageModeShouldExitImmediately ? 0 : mNextWakeupSec;
652         }
653         switch (state.mCarPowerStateListenerState) {
654             case CarPowerStateListener.SUSPEND_ENTER:
655                 mHal.sendSleepEntry(wakeupSec);
656                 break;
657             case CarPowerStateListener.SHUTDOWN_ENTER:
658                 mHal.sendShutdownStart(wakeupSec);
659                 break;
660         }
661     }
662 
handleFinish()663     private void handleFinish() {
664         boolean simulatedMode;
665         synchronized (mSimulationWaitObject) {
666             simulatedMode = mInSimulatedDeepSleepMode;
667         }
668         boolean mustShutDown;
669         boolean forceReboot;
670         synchronized (mLock) {
671             mustShutDown = mShutdownOnFinish && !simulatedMode;
672             forceReboot = mRebootAfterGarageMode;
673             mRebootAfterGarageMode = false;
674         }
675         if (forceReboot) {
676             PowerManager powerManager = mContext.getSystemService(PowerManager.class);
677             if (powerManager == null) {
678                 Slogf.wtf(TAG, "No PowerManager. Cannot reboot.");
679             } else {
680                 Slogf.i(TAG, "GarageMode has completed. Forcing reboot.");
681                 powerManager.reboot("GarageModeReboot");
682                 throw new AssertionError("Should not return from PowerManager.reboot()");
683             }
684         }
685         // To make Kernel implementation simpler when going into sleep.
686         if (mWifiAdjustmentForSuspend) disableWifi();
687 
688         if (mustShutDown) {
689             // shutdown HU
690             mSystemInterface.shutdown();
691         } else {
692             doHandleDeepSleep(simulatedMode);
693         }
694         mShutdownOnNextSuspend = false;
695     }
696 
restoreWifi()697     private void restoreWifi() {
698         boolean needToRestore = readWifiModifiedState();
699         if (needToRestore) {
700             if (!mWifiManager.isWifiEnabled()) {
701                 Slogf.i(TAG, "Wifi has been enabled to restore the last setting");
702                 mWifiManager.setWifiEnabled(true);
703             }
704             // Update the persistent data as wifi is not modified by car framework.
705             saveWifiModifiedState(false);
706         }
707     }
708 
disableWifi()709     private void disableWifi() {
710         boolean wifiEnabled = mWifiManager.isWifiEnabled();
711         boolean wifiModifiedState = readWifiModifiedState();
712         if (wifiEnabled != wifiModifiedState) {
713             saveWifiModifiedState(wifiEnabled);
714         }
715         if (!wifiEnabled) return;
716 
717         mWifiManager.setWifiEnabled(false);
718         Slogf.i(TAG, "Wifi has been disabled and the last setting was saved");
719     }
720 
saveWifiModifiedState(boolean forciblyDisabled)721     private void saveWifiModifiedState(boolean forciblyDisabled) {
722         FileOutputStream fos;
723         try {
724             fos = mWifiStateFile.startWrite();
725         } catch (IOException e) {
726             Slogf.e(TAG, e, "Cannot create %s", WIFI_STATE_FILENAME);
727             return;
728         }
729 
730         try (BufferedWriter writer = new BufferedWriter(
731                 new OutputStreamWriter(fos, StandardCharsets.UTF_8))) {
732             writer.write(forciblyDisabled ? WIFI_STATE_MODIFIED : WIFI_STATE_ORIGINAL);
733             writer.newLine();
734             writer.flush();
735             mWifiStateFile.finishWrite(fos);
736         } catch (IOException e) {
737             mWifiStateFile.failWrite(fos);
738             Slogf.e(TAG, e, "Writing %s failed", WIFI_STATE_FILENAME);
739         }
740     }
741 
readWifiModifiedState()742     private boolean readWifiModifiedState() {
743         boolean needToRestore = false;
744         boolean invalidState = false;
745 
746         try (BufferedReader reader = new BufferedReader(
747                 new InputStreamReader(mWifiStateFile.openRead(), StandardCharsets.UTF_8))) {
748             String line = reader.readLine();
749             if (line == null) {
750                 needToRestore = false;
751                 invalidState = true;
752             } else {
753                 line = line.trim();
754                 needToRestore = WIFI_STATE_MODIFIED.equals(line);
755                 invalidState = !(needToRestore || WIFI_STATE_ORIGINAL.equals(line));
756             }
757         } catch (IOException e) {
758             // If a file named wifi_state doesn't exist, we will not modify Wifi at system start.
759             Slogf.w(TAG, "Failed to read %s: %s", WIFI_STATE_FILENAME, e);
760             return false;
761         }
762         if (invalidState) {
763             mWifiStateFile.delete();
764         }
765 
766         return needToRestore;
767     }
768 
769     @GuardedBy("mLock")
releaseTimerLocked()770     private void releaseTimerLocked() {
771         if (mTimer != null) {
772             mTimer.cancel();
773         }
774         mTimer = null;
775         mTimerActive = false;
776     }
777 
doHandlePreprocessing()778     private void doHandlePreprocessing() {
779         int intervalMs;
780         int pollingCount;
781         synchronized (mLock) {
782             intervalMs = mShutdownPollingIntervalMs;
783             pollingCount = (mShutdownPrepareTimeMs / mShutdownPollingIntervalMs) + 1;
784         }
785         if (Build.IS_USERDEBUG || Build.IS_ENG) {
786             int shutdownPrepareTimeOverrideInSecs =
787                     SystemProperties.getInt(PROP_MAX_GARAGE_MODE_DURATION_OVERRIDE, -1);
788             if (shutdownPrepareTimeOverrideInSecs >= 0) {
789                 pollingCount =
790                         (shutdownPrepareTimeOverrideInSecs * 1000 / intervalMs)
791                                 + 1;
792                 Slogf.i(TAG, "Garage mode duration overridden secs: %d",
793                         shutdownPrepareTimeOverrideInSecs);
794             }
795         }
796         Slogf.i(TAG, "processing before shutdown expected for: %dms, adding polling:%d",
797                 mShutdownPrepareTimeMs, pollingCount);
798         boolean allAreComplete;
799         synchronized (mLock) {
800             mProcessingStartTime = SystemClock.elapsedRealtime();
801             releaseTimerLocked();
802             allAreComplete = mListenersWeAreWaitingFor.isEmpty();
803             if (allAreComplete) {
804                 Slogf.i(TAG, "Listener queue is empty, don't start polling");
805             } else {
806                 mTimer = new Timer();
807                 mTimerActive = true;
808                 mTimer.scheduleAtFixedRate(
809                         new ShutdownProcessingTimerTask(pollingCount),
810                         /* delay= */ 0,
811                         intervalMs);
812             }
813         }
814         if (allAreComplete) {
815             signalComplete();
816         }
817         // allowUserSwitch value doesn't matter for onSuspend = true
818         mUserService.onSuspend();
819     }
820 
sendPowerManagerEvent(int newState)821     private void sendPowerManagerEvent(int newState) {
822         // Broadcast to the listeners that do not signal completion
823         notifyListeners(mPowerManagerListeners, newState);
824 
825         // SHUTDOWN_PREPARE is the only state where we need
826         // to maintain callbacks from listener components.
827         boolean allowCompletion = (newState == CarPowerStateListener.SHUTDOWN_PREPARE);
828 
829         // Fully populate mListenersWeAreWaitingFor before calling any onStateChanged()
830         // for the listeners that signal completion.
831         // Otherwise, if the first listener calls finish() synchronously, we will
832         // see the list go empty and we will think that we are done.
833         boolean haveSomeCompleters = false;
834         PowerManagerCallbackList<ICarPowerStateListener> completingListeners =
835                 new PowerManagerCallbackList(l -> { });
836         synchronized (mLock) {
837             mListenersWeAreWaitingFor.clear();
838             int idx = mPowerManagerListenersWithCompletion.beginBroadcast();
839             while (idx-- > 0) {
840                 ICarPowerStateListener listener =
841                         mPowerManagerListenersWithCompletion.getBroadcastItem(idx);
842                 completingListeners.register(listener);
843                 if (allowCompletion) {
844                     mListenersWeAreWaitingFor.add(listener.asBinder());
845                     haveSomeCompleters = true;
846                 }
847             }
848             mPowerManagerListenersWithCompletion.finishBroadcast();
849         }
850         // Broadcast to the listeners that DO signal completion
851         notifyListeners(completingListeners, newState);
852 
853         if (allowCompletion && !haveSomeCompleters) {
854             // No jobs need to signal completion. So we are now complete.
855             signalComplete();
856         }
857     }
858 
notifyListeners(PowerManagerCallbackList<ICarPowerStateListener> listenerList, int newState)859     private void notifyListeners(PowerManagerCallbackList<ICarPowerStateListener> listenerList,
860             int newState) {
861         int idx = listenerList.beginBroadcast();
862         while (idx-- > 0) {
863             ICarPowerStateListener listener = listenerList.getBroadcastItem(idx);
864             try {
865                 listener.onStateChanged(newState);
866             } catch (RemoteException e) {
867                 // It's likely the connection snapped. Let binder death handle the situation.
868                 Slogf.e(TAG, e, "onStateChanged() call failed");
869             }
870         }
871         listenerList.finishBroadcast();
872     }
873 
doHandleDeepSleep(boolean simulatedMode)874     private void doHandleDeepSleep(boolean simulatedMode) {
875         int status = applyPreemptivePowerPolicy(PolicyReader.POWER_POLICY_ID_SUSPEND_TO_RAM);
876         if (status != PolicyOperationStatus.OK) {
877             Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(status));
878         }
879         // keep holding partial wakelock to prevent entering sleep before enterDeepSleep call
880         // enterDeepSleep should force sleep entry even if wake lock is kept.
881         mSystemInterface.switchToPartialWakeLock();
882         mHandler.cancelProcessingComplete();
883         synchronized (mLock) {
884             mLastSleepEntryTime = SystemClock.elapsedRealtime();
885         }
886         int nextListenerState;
887         if (simulatedMode) {
888             simulateSleepByWaiting();
889             nextListenerState = CarPowerStateListener.SHUTDOWN_CANCELLED;
890         } else {
891             boolean sleepSucceeded = suspendWithRetries();
892             if (!sleepSucceeded) {
893                 // Suspend failed and we shut down instead.
894                 // We either won't get here at all or we will power off very soon.
895                 return;
896             }
897             // We suspended and have now resumed
898             nextListenerState = CarPowerStateListener.SUSPEND_EXIT;
899         }
900         synchronized (mLock) {
901             // Any wakeup time from before is no longer valid.
902             mNextWakeupSec = 0;
903         }
904         Slogf.i(TAG, "Resuming after suspending");
905         mSystemInterface.refreshDisplayBrightness();
906         onApPowerStateChange(CpmsState.WAIT_FOR_VHAL, nextListenerState);
907     }
908 
needPowerStateChangeLocked(@onNull CpmsState newState)909     private boolean needPowerStateChangeLocked(@NonNull CpmsState newState) {
910         if (mCurrentState == null) {
911             return true;
912         } else if (mCurrentState.equals(newState)) {
913             Slogf.d(TAG, "Requested state is already in effect: %s", newState.name());
914             return false;
915         }
916 
917         // The following switch/case enforces the allowed state transitions.
918         boolean transitionAllowed = false;
919         switch (mCurrentState.mState) {
920             case CpmsState.WAIT_FOR_VHAL:
921                 transitionAllowed = (newState.mState == CpmsState.ON)
922                     || (newState.mState == CpmsState.SHUTDOWN_PREPARE);
923                 break;
924             case CpmsState.SUSPEND:
925                 transitionAllowed =  newState.mState == CpmsState.WAIT_FOR_VHAL;
926                 break;
927             case CpmsState.ON:
928                 transitionAllowed = (newState.mState == CpmsState.SHUTDOWN_PREPARE)
929                     || (newState.mState == CpmsState.SIMULATE_SLEEP);
930                 break;
931             case CpmsState.SHUTDOWN_PREPARE:
932                 // If VHAL sends SHUTDOWN_IMMEDIATELY or SLEEP_IMMEDIATELY while in
933                 // SHUTDOWN_PREPARE state, do it.
934                 transitionAllowed =
935                         ((newState.mState == CpmsState.SHUTDOWN_PREPARE) && !newState.mCanPostpone)
936                                 || (newState.mState == CpmsState.WAIT_FOR_FINISH)
937                                 || (newState.mState == CpmsState.WAIT_FOR_VHAL);
938                 break;
939             case CpmsState.SIMULATE_SLEEP:
940                 transitionAllowed = true;
941                 break;
942             case CpmsState.WAIT_FOR_FINISH:
943                 transitionAllowed = (newState.mState == CpmsState.SUSPEND
944                         || newState.mState == CpmsState.WAIT_FOR_VHAL);
945                 break;
946             default:
947                 Slogf.e(TAG, "Unexpected current state: currentState=%s, newState=%s",
948                         mCurrentState.name(), newState.name());
949                 transitionAllowed = true;
950         }
951         if (!transitionAllowed) {
952             Slogf.e(TAG, "Requested power transition is not allowed: %s --> %s",
953                     mCurrentState.name(), newState.name());
954         }
955         return transitionAllowed;
956     }
957 
doHandleProcessingComplete()958     private void doHandleProcessingComplete() {
959         int listenerState;
960         synchronized (mLock) {
961             releaseTimerLocked();
962             if (!mShutdownOnFinish && mLastSleepEntryTime > mProcessingStartTime) {
963                 // entered sleep after processing start. So this could be duplicate request.
964                 Slogf.w(TAG, "Duplicate sleep entry request, ignore");
965                 return;
966             }
967             listenerState = mShutdownOnFinish
968                     ? CarPowerStateListener.SHUTDOWN_ENTER : CarPowerStateListener.SUSPEND_ENTER;
969         }
970 
971         onApPowerStateChange(CpmsState.WAIT_FOR_FINISH, listenerState);
972     }
973 
974     @Override
onDisplayBrightnessChange(int brightness)975     public void onDisplayBrightnessChange(int brightness) {
976         mHandler.handleDisplayBrightnessChange(brightness);
977     }
978 
doHandleDisplayBrightnessChange(int brightness)979     private void doHandleDisplayBrightnessChange(int brightness) {
980         mSystemInterface.setDisplayBrightness(brightness);
981     }
982 
doHandleMainDisplayStateChange(boolean on)983     private void doHandleMainDisplayStateChange(boolean on) {
984         Slogf.w(TAG, "Unimplemented:  doHandleMainDisplayStateChange() - on = %b", on);
985     }
986 
987     /**
988      * Handles when a main display changes.
989      */
handleMainDisplayChanged(boolean on)990     public void handleMainDisplayChanged(boolean on) {
991         mHandler.handleMainDisplayStateChange(on);
992     }
993 
994     /**
995      * Send display brightness to VHAL.
996      * @param brightness value 0-100%
997      */
sendDisplayBrightness(int brightness)998     public void sendDisplayBrightness(int brightness) {
999         mHal.sendDisplayBrightness(brightness);
1000     }
1001 
1002     /**
1003      * Get the PowerHandler that we use to change power states
1004      */
getHandler()1005     public Handler getHandler() {
1006         return mHandler;
1007 
1008     }
1009 
1010     // Binder interface for general use.
1011     // The listener is not required (or allowed) to call finished().
1012     @Override
registerListener(ICarPowerStateListener listener)1013     public void registerListener(ICarPowerStateListener listener) {
1014         ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER);
1015         mPowerManagerListeners.register(listener);
1016     }
1017 
1018     // Binder interface for Car services only.
1019     // After the listener completes its processing, it must call finished().
1020     @Override
registerListenerWithCompletion(ICarPowerStateListener listener)1021     public void registerListenerWithCompletion(ICarPowerStateListener listener) {
1022         ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER);
1023         ICarImpl.assertCallingFromSystemProcessOrSelf();
1024 
1025         mPowerManagerListenersWithCompletion.register(listener);
1026         // TODO: Need to send current state to newly registered listener? If so, need to handle
1027         //       completion for SHUTDOWN_PREPARE state
1028     }
1029 
1030     @Override
unregisterListener(ICarPowerStateListener listener)1031     public void unregisterListener(ICarPowerStateListener listener) {
1032         ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER);
1033         doUnregisterListener(listener);
1034     }
1035 
1036     @Override
requestShutdownOnNextSuspend()1037     public void requestShutdownOnNextSuspend() {
1038         ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER);
1039         synchronized (mLock) {
1040             mShutdownOnNextSuspend = true;
1041         }
1042     }
1043 
1044     @Override
finished(ICarPowerStateListener listener)1045     public void finished(ICarPowerStateListener listener) {
1046         ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER);
1047         ICarImpl.assertCallingFromSystemProcessOrSelf();
1048         finishedImpl(listener.asBinder());
1049     }
1050 
1051     @Override
scheduleNextWakeupTime(int seconds)1052     public void scheduleNextWakeupTime(int seconds) {
1053         ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER);
1054         if (seconds < 0) {
1055             Slogf.w(TAG, "Next wake up time is negative. Ignoring!");
1056             return;
1057         }
1058         boolean timedWakeupAllowed = mHal.isTimedWakeupAllowed();
1059         synchronized (mLock) {
1060             if (!timedWakeupAllowed) {
1061                 Slogf.w(TAG, "Setting timed wakeups are disabled in HAL. Skipping");
1062                 mNextWakeupSec = 0;
1063                 return;
1064             }
1065             if (mNextWakeupSec == 0 || mNextWakeupSec > seconds) {
1066                 // The new value is sooner than the old value. Take the new value.
1067                 mNextWakeupSec = seconds;
1068             } else {
1069                 Slogf.d(TAG, "Tried to schedule next wake up, but already had shorter "
1070                         + "scheduled time");
1071             }
1072         }
1073     }
1074 
1075     @Override
getPowerState()1076     public int getPowerState() {
1077         ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER);
1078         synchronized (mLock) {
1079             return (mCurrentState == null) ? CarPowerStateListener.INVALID
1080                     : mCurrentState.mCarPowerStateListenerState;
1081         }
1082     }
1083 
1084     /**
1085      * @see android.car.hardware.power.CarPowerManager#getCurrentPowerPolicy
1086      */
1087     @Override
getCurrentPowerPolicy()1088     public CarPowerPolicy getCurrentPowerPolicy() {
1089         ICarImpl.assertPermission(mContext, Car.PERMISSION_READ_CAR_POWER_POLICY);
1090         return mPowerComponentHandler.getAccumulatedPolicy();
1091     }
1092 
1093     /**
1094      * @see android.car.hardware.power.CarPowerManager#applyPowerPolicy
1095      */
1096     @Override
applyPowerPolicy(String policyId)1097     public void applyPowerPolicy(String policyId) {
1098         ICarImpl.assertPermission(mContext, Car.PERMISSION_CONTROL_CAR_POWER_POLICY);
1099         Preconditions.checkArgument(policyId != null, "policyId cannot be null");
1100         Preconditions.checkArgument(!policyId.startsWith(PolicyReader.SYSTEM_POWER_POLICY_PREFIX),
1101                 "System power policy cannot be applied by apps");
1102         int status = applyPowerPolicy(policyId, true);
1103         if (status != PolicyOperationStatus.OK) {
1104             throw new IllegalArgumentException(PolicyOperationStatus.errorCodeToString(status));
1105         }
1106     }
1107 
1108     /**
1109      * @see android.car.hardware.power.CarPowerManager#setPowerPolicyGroup
1110      */
1111     @Override
setPowerPolicyGroup(String policyGroupId)1112     public void setPowerPolicyGroup(String policyGroupId) {
1113         ICarImpl.assertPermission(mContext, Car.PERMISSION_CONTROL_CAR_POWER_POLICY);
1114         Preconditions.checkArgument(policyGroupId != null, "policyGroupId cannot be null");
1115         int status = setCurrentPowerPolicyGroup(policyGroupId);
1116         if (status != PolicyOperationStatus.OK) {
1117             throw new IllegalArgumentException(PolicyOperationStatus.errorCodeToString(status));
1118         }
1119     }
1120 
1121     /**
1122      * @see android.car.hardware.power.CarPowerManager#addPowerPolicyListener
1123      */
1124     @Override
addPowerPolicyListener(CarPowerPolicyFilter filter, ICarPowerPolicyListener listener)1125     public void addPowerPolicyListener(CarPowerPolicyFilter filter,
1126             ICarPowerPolicyListener listener) {
1127         ICarImpl.assertPermission(mContext, Car.PERMISSION_READ_CAR_POWER_POLICY);
1128         mPowerPolicyListeners.register(listener, filter);
1129     }
1130 
1131     /**
1132      * @see android.car.hardware.power.CarPowerManager#removePowerPolicyListener
1133      */
1134     @Override
removePowerPolicyListener(ICarPowerPolicyListener listener)1135     public void removePowerPolicyListener(ICarPowerPolicyListener listener) {
1136         ICarImpl.assertPermission(mContext, Car.PERMISSION_READ_CAR_POWER_POLICY);
1137         mPowerPolicyListeners.unregister(listener);
1138     }
1139 
notifySilentModeChange(boolean silent)1140     void notifySilentModeChange(boolean silent) {
1141         Slogf.i(TAG, "Silent mode is set to %b", silent);
1142         if (silent) {
1143             applyPreemptivePowerPolicy(PolicyReader.POWER_POLICY_ID_NO_USER_INTERACTION);
1144         } else {
1145             cancelPreemptivePowerPolicy();
1146         }
1147     }
1148 
doUnregisterListener(ICarPowerStateListener listener)1149     private void doUnregisterListener(ICarPowerStateListener listener) {
1150         mPowerManagerListeners.unregister(listener);
1151         boolean found = mPowerManagerListenersWithCompletion.unregister(listener);
1152         if (found) {
1153             // Remove this from the completion list (if it's there)
1154             finishedImpl(listener.asBinder());
1155         }
1156     }
1157 
finishedImpl(IBinder binder)1158     private void finishedImpl(IBinder binder) {
1159         boolean allAreComplete;
1160         synchronized (mLock) {
1161             mListenersWeAreWaitingFor.remove(binder);
1162             allAreComplete = mListenersWeAreWaitingFor.isEmpty();
1163         }
1164         if (allAreComplete) {
1165             signalComplete();
1166         }
1167     }
1168 
signalComplete()1169     private void signalComplete() {
1170         if (mCurrentState.mState == CpmsState.SHUTDOWN_PREPARE
1171                 || mCurrentState.mState == CpmsState.SIMULATE_SLEEP) {
1172             PowerHandler powerHandler;
1173             // All apps are ready to shutdown/suspend.
1174             synchronized (mLock) {
1175                 if (!mShutdownOnFinish) {
1176                     if (mLastSleepEntryTime > mProcessingStartTime
1177                             && mLastSleepEntryTime < SystemClock.elapsedRealtime()) {
1178                         Slogf.i(TAG, "signalComplete: Already slept!");
1179                         return;
1180                     }
1181                 }
1182                 powerHandler = mHandler;
1183             }
1184             Slogf.i(TAG, "Apps are finished, call handleProcessingComplete()");
1185             powerHandler.handleProcessingComplete();
1186         }
1187     }
1188 
initializePowerPolicy()1189     private void initializePowerPolicy() {
1190         Slogf.i(TAG, "CPMS is taking control from carpowerpolicyd");
1191         ICarPowerPolicySystemNotification daemon;
1192         synchronized (mLock) {
1193             daemon = mCarPowerPolicyDaemon;
1194         }
1195         PolicyState state;
1196         if (daemon != null) {
1197             try {
1198                 state = daemon.notifyCarServiceReady();
1199             } catch (RemoteException e) {
1200                 Slogf.e(TAG, e, "Failed to tell car power policy daemon that CarService is ready");
1201                 return;
1202             }
1203         } else {
1204             Slogf.w(TAG, "Failed to notify car service is ready. car power policy daemon is not "
1205                     + "available");
1206             return;
1207         }
1208 
1209         String currentPowerPolicyId;
1210         String currentPolicyGroupId;
1211         synchronized (mLock) {
1212             mHasControlOverDaemon = true;
1213             currentPowerPolicyId = mCurrentPowerPolicyId;
1214             currentPolicyGroupId = mCurrentPowerPolicyGroupId;
1215         }
1216         // If the current power policy or the policy group has been modified by CPMS, we ignore
1217         // the power policy or the policy group passed from car power policy daemon, and notifies
1218         // the current power policy to the daemon.
1219         if (currentPowerPolicyId == null || currentPowerPolicyId.isEmpty()) {
1220             int status = applyPowerPolicy(state.policyId, false);
1221             if (status != PolicyOperationStatus.OK) {
1222                 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(status));
1223             }
1224         } else {
1225             notifyPowerPolicyChangeToDaemon(currentPowerPolicyId);
1226         }
1227         if (currentPolicyGroupId == null || currentPolicyGroupId.isEmpty()) {
1228             int status = setCurrentPowerPolicyGroup(state.policyGroupId);
1229             if (status != PolicyOperationStatus.OK) {
1230                 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(status));
1231             }
1232         }
1233         mSilentModeHandler.init();
1234     }
1235 
1236     @PolicyOperationStatus.ErrorCode
setCurrentPowerPolicyGroup(String policyGroupId)1237     private int setCurrentPowerPolicyGroup(String policyGroupId) {
1238         if (!mPolicyReader.isPowerPolicyGroupAvailable(policyGroupId)) {
1239             int error = PolicyOperationStatus.ERROR_SET_POWER_POLICY_GROUP;
1240             Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error,
1241                     policyGroupId + " is not registered"));
1242             return error;
1243         }
1244         synchronized (mLock) {
1245             mCurrentPowerPolicyGroupId = policyGroupId;
1246         }
1247         return PolicyOperationStatus.OK;
1248     }
1249 
1250     @PolicyOperationStatus.ErrorCode
applyPowerPolicy(@ullable String policyId, boolean upToDaemon)1251     private int applyPowerPolicy(@Nullable String policyId, boolean upToDaemon) {
1252         CarPowerPolicy policy = mPolicyReader.getPowerPolicy(policyId);
1253         if (policy == null) {
1254             int error = PolicyOperationStatus.ERROR_APPLY_POWER_POLICY;
1255             Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error, policyId));
1256             return error;
1257         }
1258         synchronized (mLock) {
1259             if (mIsPowerPolicyLocked) {
1260                 Slogf.i(TAG, "Power policy is locked. The request policy(%s) will be applied when "
1261                         + "power policy becomes unlocked", policyId);
1262                 mPendingPowerPolicyId = policyId;
1263                 return PolicyOperationStatus.OK;
1264             }
1265             mCurrentPowerPolicyId = policyId;
1266         }
1267         mPowerComponentHandler.applyPowerPolicy(policy);
1268         notifyPowerPolicyChange(policyId, upToDaemon);
1269         Slogf.i(TAG, "The current power policy is %s", policyId);
1270         return PolicyOperationStatus.OK;
1271     }
1272 
1273     @PolicyOperationStatus.ErrorCode
applyPreemptivePowerPolicy(String policyId)1274     private int applyPreemptivePowerPolicy(String policyId) {
1275         CarPowerPolicy policy = mPolicyReader.getPreemptivePowerPolicy(policyId);
1276         if (policy == null) {
1277             int error = PolicyOperationStatus.ERROR_NOT_REGISTERED_POWER_POLICY_ID;
1278             Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error, policyId));
1279             return error;
1280         }
1281         synchronized (mLock) {
1282             mIsPowerPolicyLocked = true;
1283             if (!mPolicyReader.isPreemptivePowerPolicy(mCurrentPowerPolicyId)) {
1284                 mPendingPowerPolicyId = mCurrentPowerPolicyId;
1285             }
1286             mCurrentPowerPolicyId = policyId;
1287         }
1288         mPowerComponentHandler.applyPowerPolicy(policy);
1289         notifyPowerPolicyChange(policyId, true);
1290         Slogf.i(TAG, "The current power policy is %s", policyId);
1291         return PolicyOperationStatus.OK;
1292     }
1293 
cancelPreemptivePowerPolicy()1294     private void cancelPreemptivePowerPolicy() {
1295         String policyId;
1296         synchronized (mLock) {
1297             if (!mIsPowerPolicyLocked) {
1298                 Slogf.w(TAG, "Failed to cancel system power policy: the current policy is not the "
1299                         + "system power policy");
1300                 return;
1301             }
1302             mIsPowerPolicyLocked = false;
1303             policyId = mPendingPowerPolicyId;
1304             mPendingPowerPolicyId = null;
1305         }
1306         int status = applyPowerPolicy(policyId, true);
1307         if (status != PolicyOperationStatus.OK) {
1308             Slogf.w(TAG, "Failed to cancel system power policy: %s",
1309                     PolicyOperationStatus.errorCodeToString(status));
1310         }
1311     }
1312 
notifyPowerPolicyChangeToDaemon(String policyId)1313     private void notifyPowerPolicyChangeToDaemon(String policyId) {
1314         ICarPowerPolicySystemNotification daemon;
1315         boolean hadPendingPolicyNotification;
1316         synchronized (mLock) {
1317             daemon = mCarPowerPolicyDaemon;
1318             if (daemon == null) {
1319                 Slogf.e(TAG, "Failed to notify car power policy daemon: the daemon is not ready");
1320                 return;
1321             }
1322             if (!mHasControlOverDaemon) {
1323                 Slogf.w(TAG, "Notifying policy change is deferred: CPMS has not yet taken control");
1324                 return;
1325             }
1326         }
1327         try {
1328             daemon.notifyPowerPolicyChange(policyId);
1329         } catch (RemoteException | IllegalStateException e) {
1330             Slogf.e(TAG, e, "Failed to notify car power policy daemon of a new power policy(%s)",
1331                     policyId);
1332         }
1333     }
1334 
notifyPowerPolicyChange(String policyId, boolean upToDaemon)1335     private void notifyPowerPolicyChange(String policyId, boolean upToDaemon) {
1336         // Notify system clients
1337         if (upToDaemon) {
1338             notifyPowerPolicyChangeToDaemon(policyId);
1339         }
1340 
1341         // Notify Java clients
1342         CarPowerPolicy accumulatedPolicy = mPowerComponentHandler.getAccumulatedPolicy();
1343         CarPowerPolicy appliedPolicy = mPolicyReader.isPreemptivePowerPolicy(policyId)
1344                 ? mPolicyReader.getPreemptivePowerPolicy(policyId)
1345                 : mPolicyReader.getPowerPolicy(policyId);
1346         if (appliedPolicy == null) {
1347             Slogf.wtf(TAG, "The new power policy(%s) should exist", policyId);
1348         }
1349         int idx = mPowerPolicyListeners.beginBroadcast();
1350         while (idx-- > 0) {
1351             ICarPowerPolicyListener listener = mPowerPolicyListeners.getBroadcastItem(idx);
1352             CarPowerPolicyFilter filter =
1353                     (CarPowerPolicyFilter) mPowerPolicyListeners.getBroadcastCookie(idx);
1354             if (!mPowerComponentHandler.isComponentChanged(filter)) {
1355                 continue;
1356             }
1357             try {
1358                 listener.onPolicyChanged(appliedPolicy, accumulatedPolicy);
1359             } catch (RemoteException e) {
1360                 // It's likely the connection snapped. Let binder death handle the situation.
1361                 Slogf.e(TAG, e, "onPolicyChanged() call failed: policyId = %s", policyId);
1362             }
1363         }
1364         mPowerPolicyListeners.finishBroadcast();
1365     }
1366 
makeSureNoUserInteraction()1367     private void makeSureNoUserInteraction() {
1368         mSilentModeHandler.updateKernelSilentMode(true);
1369         int status = applyPreemptivePowerPolicy(PolicyReader.POWER_POLICY_ID_NO_USER_INTERACTION);
1370         if (status != PolicyOperationStatus.OK) {
1371             Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(status));
1372         }
1373     }
1374 
connectToPowerPolicyDaemon()1375     private void connectToPowerPolicyDaemon() {
1376         synchronized (mLock) {
1377             if (mCarPowerPolicyDaemon != null || mConnectionInProgress) {
1378                 return;
1379             }
1380             mConnectionInProgress = true;
1381         }
1382         connectToDaemonHelper(CAR_POWER_POLICY_DAEMON_BIND_MAX_RETRY);
1383     }
1384 
connectToDaemonHelper(int retryCount)1385     private void connectToDaemonHelper(int retryCount) {
1386         if (retryCount <= 0) {
1387             synchronized (mLock) {
1388                 mConnectionInProgress = false;
1389             }
1390             Slogf.e(TAG, "Cannot reconnect to car power policyd daemon after retrying %d times",
1391                     CAR_POWER_POLICY_DAEMON_BIND_MAX_RETRY);
1392             return;
1393         }
1394         if (makeBinderConnection()) {
1395             Slogf.i(TAG, "Connected to car power policy daemon");
1396             initializePowerPolicy();
1397             return;
1398         }
1399         mHandler.sendMessageDelayed(PooledLambda.obtainMessage(
1400                 CarPowerManagementService::connectToDaemonHelper,
1401                 CarPowerManagementService.this, retryCount - 1),
1402                 CAR_POWER_POLICY_DAEMON_BIND_RETRY_INTERVAL_MS);
1403     }
1404 
makeBinderConnection()1405     private boolean makeBinderConnection() {
1406         long currentTimeMs = SystemClock.uptimeMillis();
1407         IBinder binder = ServiceManager.getService(CAR_POWER_POLICY_DAEMON_INTERFACE);
1408         if (binder == null) {
1409             Slogf.w(TAG, "Finding car power policy daemon failed. Power policy management is not "
1410                     + "supported");
1411             return false;
1412         }
1413         long elapsedTimeMs = SystemClock.uptimeMillis() - currentTimeMs;
1414         if (elapsedTimeMs > CAR_POWER_POLICY_DAEMON_FIND_MARGINAL_TIME_MS) {
1415             Slogf.wtf(TAG, "Finding car power policy daemon took too long(%dms)", elapsedTimeMs);
1416         }
1417 
1418         ICarPowerPolicySystemNotification daemon =
1419                 ICarPowerPolicySystemNotification.Stub.asInterface(binder);
1420         if (daemon == null) {
1421             Slogf.w(TAG, "Getting car power policy daemon interface failed. Power policy management"
1422                     + " is not supported");
1423             return false;
1424         }
1425         synchronized (mLock) {
1426             mCarPowerPolicyDaemon = daemon;
1427             mConnectionInProgress = false;
1428         }
1429         mBinderHandler = new BinderHandler(daemon);
1430         mBinderHandler.linkToDeath();
1431         return true;
1432     }
1433 
1434     private final class BinderHandler implements IBinder.DeathRecipient {
1435         private ICarPowerPolicySystemNotification mDaemon;
1436 
BinderHandler(ICarPowerPolicySystemNotification daemon)1437         private BinderHandler(ICarPowerPolicySystemNotification daemon) {
1438             mDaemon = daemon;
1439         }
1440 
1441         @Override
binderDied()1442         public void binderDied() {
1443             Slogf.w(TAG, "Car power policy daemon died: reconnecting");
1444             unlinkToDeath();
1445             mDaemon = null;
1446             synchronized (mLock) {
1447                 mCarPowerPolicyDaemon = null;
1448                 mHasControlOverDaemon = false;
1449             }
1450             mHandler.sendMessageDelayed(PooledLambda.obtainMessage(
1451                     CarPowerManagementService::connectToDaemonHelper,
1452                     CarPowerManagementService.this, CAR_POWER_POLICY_DAEMON_BIND_MAX_RETRY),
1453                     CAR_POWER_POLICY_DAEMON_BIND_RETRY_INTERVAL_MS);
1454         }
1455 
linkToDeath()1456         private void linkToDeath() {
1457             if (mDaemon == null) {
1458                 return;
1459             }
1460             IBinder binder = mDaemon.asBinder();
1461             if (binder == null) {
1462                 Slogf.w(TAG, "Linking to binder death recipient skipped");
1463                 return;
1464             }
1465             try {
1466                 binder.linkToDeath(this, 0);
1467             } catch (RemoteException e) {
1468                 mDaemon = null;
1469                 Slogf.w(TAG, e, "Linking to binder death recipient failed: %s");
1470             }
1471         }
1472 
unlinkToDeath()1473         private void unlinkToDeath() {
1474             if (mDaemon == null) {
1475                 return;
1476             }
1477             IBinder binder = mDaemon.asBinder();
1478             if (binder == null) {
1479                 Slogf.w(TAG, "Unlinking from binder death recipient skipped");
1480                 return;
1481             }
1482             binder.unlinkToDeath(this, 0);
1483         }
1484     }
1485 
1486     private static final class PowerHandler extends Handler {
1487         private static final String TAG = PowerHandler.class.getSimpleName();
1488         private static final int MSG_POWER_STATE_CHANGE = 0;
1489         private static final int MSG_DISPLAY_BRIGHTNESS_CHANGE = 1;
1490         private static final int MSG_MAIN_DISPLAY_STATE_CHANGE = 2;
1491         private static final int MSG_PROCESSING_COMPLETE = 3;
1492 
1493         // Do not handle this immediately but with some delay as there can be a race between
1494         // display off due to rear view camera and delivery to here.
1495         private static final long MAIN_DISPLAY_EVENT_DELAY_MS = 500;
1496 
1497         private final WeakReference<CarPowerManagementService> mService;
1498 
PowerHandler(Looper looper, CarPowerManagementService service)1499         private PowerHandler(Looper looper, CarPowerManagementService service) {
1500             super(looper);
1501             mService = new WeakReference<CarPowerManagementService>(service);
1502         }
1503 
handlePowerStateChange()1504         private void handlePowerStateChange() {
1505             Message msg = obtainMessage(MSG_POWER_STATE_CHANGE);
1506             sendMessage(msg);
1507         }
1508 
handleDisplayBrightnessChange(int brightness)1509         private void handleDisplayBrightnessChange(int brightness) {
1510             Message msg = obtainMessage(MSG_DISPLAY_BRIGHTNESS_CHANGE, brightness, 0);
1511             sendMessage(msg);
1512         }
1513 
handleMainDisplayStateChange(boolean on)1514         private void handleMainDisplayStateChange(boolean on) {
1515             removeMessages(MSG_MAIN_DISPLAY_STATE_CHANGE);
1516             Message msg = obtainMessage(MSG_MAIN_DISPLAY_STATE_CHANGE, Boolean.valueOf(on));
1517             sendMessageDelayed(msg, MAIN_DISPLAY_EVENT_DELAY_MS);
1518         }
1519 
handleProcessingComplete()1520         private void handleProcessingComplete() {
1521             removeMessages(MSG_PROCESSING_COMPLETE);
1522             Message msg = obtainMessage(MSG_PROCESSING_COMPLETE);
1523             sendMessage(msg);
1524         }
1525 
cancelProcessingComplete()1526         private void cancelProcessingComplete() {
1527             removeMessages(MSG_PROCESSING_COMPLETE);
1528         }
1529 
cancelAll()1530         private void cancelAll() {
1531             removeMessages(MSG_POWER_STATE_CHANGE);
1532             removeMessages(MSG_DISPLAY_BRIGHTNESS_CHANGE);
1533             removeMessages(MSG_MAIN_DISPLAY_STATE_CHANGE);
1534             removeMessages(MSG_PROCESSING_COMPLETE);
1535         }
1536 
1537         @Override
handleMessage(Message msg)1538         public void handleMessage(Message msg) {
1539             CarPowerManagementService service = mService.get();
1540             if (service == null) {
1541                 Slogf.i(TAG, "handleMessage null service");
1542                 return;
1543             }
1544             switch (msg.what) {
1545                 case MSG_POWER_STATE_CHANGE:
1546                     service.doHandlePowerStateChange();
1547                     break;
1548                 case MSG_DISPLAY_BRIGHTNESS_CHANGE:
1549                     service.doHandleDisplayBrightnessChange(msg.arg1);
1550                     break;
1551                 case MSG_MAIN_DISPLAY_STATE_CHANGE:
1552                     service.doHandleMainDisplayStateChange((Boolean) msg.obj);
1553                     break;
1554                 case MSG_PROCESSING_COMPLETE:
1555                     service.doHandleProcessingComplete();
1556                     break;
1557             }
1558         }
1559     }
1560 
1561     private class ShutdownProcessingTimerTask extends TimerTask {
1562         private final int mExpirationCount;
1563         private int mCurrentCount;
1564 
ShutdownProcessingTimerTask(int expirationCount)1565         private ShutdownProcessingTimerTask(int expirationCount) {
1566             mExpirationCount = expirationCount;
1567             mCurrentCount = 0;
1568         }
1569 
1570         @Override
run()1571         public void run() {
1572             synchronized (mLock) {
1573                 if (!mTimerActive) {
1574                     // Ignore timer expiration since we got cancelled
1575                     return;
1576                 }
1577                 mCurrentCount++;
1578                 if (mCurrentCount > mExpirationCount) {
1579                     PowerHandler handler;
1580                     releaseTimerLocked();
1581                     handler = mHandler;
1582                     handler.handleProcessingComplete();
1583                 } else {
1584                     mHal.sendShutdownPostpone(SHUTDOWN_EXTEND_MAX_MS);
1585                 }
1586             }
1587         }
1588     }
1589 
1590     // Send the command to enter Suspend to RAM.
1591     // If the command is not successful, try again with an exponential back-off.
1592     // If it fails repeatedly, send the command to shut down.
1593     // If we decide to go to a different power state, abort this retry mechanism.
1594     // Returns true if we successfully suspended.
suspendWithRetries()1595     private boolean suspendWithRetries() {
1596         long retryIntervalMs = INITIAL_SUSPEND_RETRY_INTERVAL_MS;
1597         long totalWaitDurationMs = 0;
1598 
1599         while (true) {
1600             Slogf.i(TAG, "Entering Suspend to RAM");
1601             boolean suspendSucceeded = mSystemInterface.enterDeepSleep();
1602             if (suspendSucceeded) {
1603                 return true;
1604             }
1605             if (totalWaitDurationMs >= mMaxSuspendWaitDurationMs) {
1606                 break;
1607             }
1608             // We failed to suspend. Block the thread briefly and try again.
1609             synchronized (mLock) {
1610                 if (mPendingPowerStates.isEmpty()) {
1611                     Slogf.w(TAG, "Failed to Suspend; will retry after %dms", retryIntervalMs);
1612                     try {
1613                         mLock.wait(retryIntervalMs);
1614                     } catch (InterruptedException ignored) {
1615                         Thread.currentThread().interrupt();
1616                     }
1617                     totalWaitDurationMs += retryIntervalMs;
1618                     retryIntervalMs = Math.min(retryIntervalMs * 2, MAX_RETRY_INTERVAL_MS);
1619                 }
1620                 // Check for a new power state now, before going around the loop again
1621                 if (!mPendingPowerStates.isEmpty()) {
1622                     Slogf.i(TAG, "Terminating the attempt to Suspend to RAM");
1623                     return false;
1624                 }
1625             }
1626         }
1627         // Too many failures trying to suspend. Shut down.
1628         Slogf.w(TAG, "Could not Suspend to RAM after %dms long trial. Shutting down.",
1629                 totalWaitDurationMs);
1630         mSystemInterface.shutdown();
1631         return false;
1632     }
1633 
1634     private static class CpmsState {
1635         // NOTE: When modifying states below, make sure to update CarPowerStateChanged.State in
1636         //   frameworks/proto_logging/stats/atoms.proto also.
1637         public static final int WAIT_FOR_VHAL = 0;
1638         public static final int ON = 1;
1639         public static final int SHUTDOWN_PREPARE = 2;
1640         public static final int WAIT_FOR_FINISH = 3;
1641         public static final int SUSPEND = 4;
1642         public static final int SIMULATE_SLEEP = 5;
1643 
1644         /* Config values from AP_POWER_STATE_REQ */
1645         public final boolean mCanPostpone;
1646         public final boolean mCanSleep;
1647         /* Message sent to CarPowerStateListener in response to this state */
1648         public final int mCarPowerStateListenerState;
1649         /* One of the above state variables */
1650         public final int mState;
1651 
1652         /**
1653           * This constructor takes a PowerHalService.PowerState object and creates the corresponding
1654           * CPMS state from it.
1655           */
CpmsState(PowerState halPowerState)1656         CpmsState(PowerState halPowerState) {
1657             switch (halPowerState.mState) {
1658                 case VehicleApPowerStateReq.ON:
1659                     this.mCanPostpone = false;
1660                     this.mCanSleep = false;
1661                     this.mCarPowerStateListenerState = cpmsStateToPowerStateListenerState(ON);
1662                     this.mState = ON;
1663                     break;
1664                 case VehicleApPowerStateReq.SHUTDOWN_PREPARE:
1665                     this.mCanPostpone = halPowerState.canPostponeShutdown();
1666                     this.mCanSleep = halPowerState.canEnterDeepSleep();
1667                     this.mCarPowerStateListenerState = cpmsStateToPowerStateListenerState(
1668                             SHUTDOWN_PREPARE);
1669                     this.mState = SHUTDOWN_PREPARE;
1670                     break;
1671                 case VehicleApPowerStateReq.CANCEL_SHUTDOWN:
1672                     this.mCanPostpone = false;
1673                     this.mCanSleep = false;
1674                     this.mCarPowerStateListenerState = CarPowerStateListener.SHUTDOWN_CANCELLED;
1675                     this.mState = WAIT_FOR_VHAL;
1676                     break;
1677                 case VehicleApPowerStateReq.FINISHED:
1678                     this.mCanPostpone = false;
1679                     this.mCanSleep = false;
1680                     this.mCarPowerStateListenerState = cpmsStateToPowerStateListenerState(SUSPEND);
1681                     this.mState = SUSPEND;
1682                     break;
1683                 default:
1684                     // Illegal state from PowerState.  Throw an exception?
1685                     this.mCanPostpone = false;
1686                     this.mCanSleep = false;
1687                     this.mCarPowerStateListenerState = 0;
1688                     this.mState = 0;
1689                     break;
1690             }
1691         }
1692 
CpmsState(int state, int carPowerStateListenerState)1693         CpmsState(int state, int carPowerStateListenerState) {
1694             this.mCanPostpone = (state == SIMULATE_SLEEP);
1695             this.mCanSleep = (state == SIMULATE_SLEEP);
1696             this.mCarPowerStateListenerState = carPowerStateListenerState;
1697             this.mState = state;
1698         }
1699 
name()1700         public String name() {
1701             String baseName;
1702             switch(mState) {
1703                 case WAIT_FOR_VHAL:     baseName = "WAIT_FOR_VHAL";    break;
1704                 case ON:                baseName = "ON";               break;
1705                 case SHUTDOWN_PREPARE:  baseName = "SHUTDOWN_PREPARE"; break;
1706                 case WAIT_FOR_FINISH:   baseName = "WAIT_FOR_FINISH";  break;
1707                 case SUSPEND:           baseName = "SUSPEND";          break;
1708                 case SIMULATE_SLEEP:    baseName = "SIMULATE_SLEEP";   break;
1709                 default:                baseName = "<unknown>";        break;
1710             }
1711             return baseName + "(" + mState + ")";
1712         }
1713 
cpmsStateToPowerStateListenerState(int state)1714         private static int cpmsStateToPowerStateListenerState(int state) {
1715             int powerStateListenerState = 0;
1716 
1717             // Set the CarPowerStateListenerState based on current state
1718             switch (state) {
1719                 case ON:
1720                     powerStateListenerState = CarPowerStateListener.ON;
1721                     break;
1722                 case SHUTDOWN_PREPARE:
1723                     powerStateListenerState = CarPowerStateListener.SHUTDOWN_PREPARE;
1724                     break;
1725                 case SUSPEND:
1726                     powerStateListenerState = CarPowerStateListener.SUSPEND_ENTER;
1727                     break;
1728                 case WAIT_FOR_VHAL:
1729                 case WAIT_FOR_FINISH:
1730                 default:
1731                     // Illegal state for this constructor.  Throw an exception?
1732                     break;
1733             }
1734             return powerStateListenerState;
1735         }
1736 
1737         @Override
equals(Object o)1738         public boolean equals(Object o) {
1739             if (this == o) {
1740                 return true;
1741             }
1742             if (!(o instanceof CpmsState)) {
1743                 return false;
1744             }
1745             CpmsState that = (CpmsState) o;
1746             return this.mState == that.mState
1747                     && this.mCanSleep == that.mCanSleep
1748                     && this.mCanPostpone == that.mCanPostpone
1749                     && this.mCarPowerStateListenerState == that.mCarPowerStateListenerState;
1750         }
1751 
1752         @Override
toString()1753         public String toString() {
1754             return "CpmsState canSleep:" + mCanSleep + ", canPostpone=" + mCanPostpone
1755                     + ", carPowerStateListenerState=" + mCarPowerStateListenerState
1756                     + ", CpmsState=" + this.name();
1757         }
1758     }
1759 
1760     /**
1761      * Resume after a manually-invoked suspend.
1762      * Invoked using "adb shell dumpsys activity service com.android.car resume".
1763      */
forceSimulatedResume()1764     public void forceSimulatedResume() {
1765         PowerHandler handler;
1766         synchronized (mLock) {
1767             // Cancel Garage Mode in case it's running
1768             mPendingPowerStates.addFirst(new CpmsState(CpmsState.WAIT_FOR_VHAL,
1769                                                        CarPowerStateListener.SHUTDOWN_CANCELLED));
1770             mLock.notify();
1771             handler = mHandler;
1772         }
1773         handler.handlePowerStateChange();
1774 
1775         synchronized (mSimulationWaitObject) {
1776             mWakeFromSimulatedSleep = true;
1777             mSimulationWaitObject.notify();
1778         }
1779     }
1780 
1781     /**
1782      * Manually enter simulated suspend (Deep Sleep) mode, trigging Garage mode.
1783      * If the parameter is 'true', reboot the system when Garage Mode completes.
1784      *
1785      * Invoked using "adb shell dumpsys activity service com.android.car suspend" or
1786      * "adb shell dumpsys activity service com.android.car garage-mode reboot".
1787      * This is similar to 'onApPowerStateChange()' except that it needs to create a CpmsState
1788      * that is not directly derived from a VehicleApPowerStateReq.
1789      */
forceSuspendAndMaybeReboot(boolean shouldReboot)1790     public void forceSuspendAndMaybeReboot(boolean shouldReboot) {
1791         synchronized (mSimulationWaitObject) {
1792             mInSimulatedDeepSleepMode = true;
1793             mWakeFromSimulatedSleep = false;
1794             mGarageModeShouldExitImmediately = false;
1795         }
1796         PowerHandler handler;
1797         synchronized (mLock) {
1798             mRebootAfterGarageMode = shouldReboot;
1799             mPendingPowerStates.addFirst(new CpmsState(CpmsState.SIMULATE_SLEEP,
1800                                                        CarPowerStateListener.SHUTDOWN_PREPARE));
1801             handler = mHandler;
1802         }
1803         handler.handlePowerStateChange();
1804     }
1805 
1806     /**
1807      * Manually defines a power policy.
1808      *
1809      * <p>If the given ID already exists or specified power components are invalid, it fails.
1810      *
1811      * @return {@code true}, if successful. Otherwise, {@code false}.
1812      */
definePowerPolicyFromCommand(String[] args, IndentingPrintWriter writer)1813     public boolean definePowerPolicyFromCommand(String[] args, IndentingPrintWriter writer) {
1814         if (args.length < 2) {
1815             writer.println("Too few arguments");
1816             return false;
1817         }
1818         String powerPolicyId = args[1];
1819         int index = 2;
1820         String[] enabledComponents = new String[0];
1821         String[] disabledComponents = new String[0];
1822         while (index < args.length) {
1823             switch (args[index]) {
1824                 case "--enable":
1825                     if (index == args.length - 1) {
1826                         writer.println("No components for --enable");
1827                         return false;
1828                     }
1829                     enabledComponents = args[index + 1].split(",");
1830                     break;
1831                 case "--disable":
1832                     if (index == args.length - 1) {
1833                         writer.println("No components for --disabled");
1834                         return false;
1835                     }
1836                     disabledComponents = args[index + 1].split(",");
1837                     break;
1838                 default:
1839                     writer.printf("Unrecognized argument: %s\n", args[index]);
1840                     return false;
1841             }
1842             index += 2;
1843         }
1844         int status = definePowerPolicy(powerPolicyId, enabledComponents, disabledComponents);
1845         if (status != PolicyOperationStatus.OK) {
1846             writer.println(PolicyOperationStatus.errorCodeToString(status));
1847             return false;
1848         }
1849         writer.printf("Power policy(%s) is successfully defined.\n", powerPolicyId);
1850         return true;
1851     }
1852 
1853     /**
1854      * Defines a power policy with the given id and components.
1855      *
1856      * <p> A policy defined with this method is valid until the system is rebooted/restarted.
1857      */
1858     @VisibleForTesting
1859     @PolicyOperationStatus.ErrorCode
definePowerPolicy(String powerPolicyId, String[] enabledComponents, String[] disabledComponents)1860     public int definePowerPolicy(String powerPolicyId, String[] enabledComponents,
1861             String[] disabledComponents) {
1862         int status = mPolicyReader.definePowerPolicy(powerPolicyId,
1863                 enabledComponents, disabledComponents);
1864         if (status != PolicyOperationStatus.OK) {
1865             int error = PolicyOperationStatus.ERROR_DEFINE_POWER_POLICY;
1866             Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error));
1867             return error;
1868         }
1869         ICarPowerPolicySystemNotification daemon;
1870         synchronized (mLock) {
1871             daemon = mCarPowerPolicyDaemon;
1872         }
1873         try {
1874             daemon.notifyPowerPolicyDefinition(powerPolicyId, enabledComponents,
1875                     disabledComponents);
1876         } catch (RemoteException e) {
1877             int error = PolicyOperationStatus.ERROR_DEFINE_POWER_POLICY;
1878             Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error));
1879             return error;
1880         }
1881         return PolicyOperationStatus.OK;
1882     }
1883 
1884     /**
1885      * Manually applies a power policy.
1886      *
1887      * <p>If the given ID is not defined, it fails.
1888      *
1889      * @return {@code true}, if successful. Otherwise, {@code false}.
1890      */
applyPowerPolicyFromCommand(String[] args, IndentingPrintWriter writer)1891     public boolean applyPowerPolicyFromCommand(String[] args, IndentingPrintWriter writer) {
1892         if (args.length != 2) {
1893             writer.println("Power policy ID should be given");
1894             return false;
1895         }
1896         String powerPolicyId = args[1];
1897         if (powerPolicyId == null) {
1898             writer.println("Policy ID cannot be null");
1899             return false;
1900         }
1901         boolean isPreemptive = mPolicyReader.isPreemptivePowerPolicy(powerPolicyId);
1902         int status = isPreemptive ? applyPreemptivePowerPolicy(powerPolicyId)
1903                 : applyPowerPolicy(powerPolicyId, true);
1904         if (status != PolicyOperationStatus.OK) {
1905             writer.println(PolicyOperationStatus.errorCodeToString(status));
1906             return false;
1907         }
1908         writer.printf("Power policy(%s) is successfully applied.\n", powerPolicyId);
1909         return true;
1910     }
1911 
1912     /**
1913      * Manually defines a power policy group.
1914      *
1915      * <p>If the given ID already exists, a wrong power state is given, or specified power policy ID
1916      * doesn't exist, it fails.
1917      *
1918      * @return {@code true}, if successful. Otherwise, {@code false}.
1919      */
definePowerPolicyGroupFromCommand(String[] args, IndentingPrintWriter writer)1920     public boolean definePowerPolicyGroupFromCommand(String[] args, IndentingPrintWriter writer) {
1921         if (args.length < 3 || args.length > 4) {
1922             writer.println("Invalid syntax");
1923             return false;
1924         }
1925         String policyGroupId = args[1];
1926         int index = 2;
1927         SparseArray<String> defaultPolicyPerState = new SparseArray<>();
1928         while (index < args.length) {
1929             String[] tokens = args[index].split(":");
1930             if (tokens.length != 2) {
1931                 writer.println("Invalid syntax");
1932                 return false;
1933             }
1934             int state = PolicyReader.toPowerState(tokens[0]);
1935             if (state == PolicyReader.INVALID_POWER_STATE) {
1936                 writer.printf("Invalid power state: %s\n", tokens[0]);
1937                 return false;
1938             }
1939             defaultPolicyPerState.put(state, tokens[1]);
1940             index++;
1941         }
1942         int status = mPolicyReader.definePowerPolicyGroup(policyGroupId,
1943                 defaultPolicyPerState);
1944         if (status != PolicyOperationStatus.OK) {
1945             writer.println(PolicyOperationStatus.errorCodeToString(status));
1946             return false;
1947         }
1948         writer.printf("Power policy group(%s) is successfully defined.\n", policyGroupId);
1949         return true;
1950     }
1951 
1952     /**
1953      * Manually sets a power policy group.
1954      *
1955      * <p>If the given ID is not defined, it fails.
1956      *
1957      * @return {@code true}, if successful. Otherwise, {@code false}.
1958      */
setPowerPolicyGroupFromCommand(String[] args, IndentingPrintWriter writer)1959     public boolean setPowerPolicyGroupFromCommand(String[] args, IndentingPrintWriter writer) {
1960         if (args.length != 2) {
1961             writer.println("Power policy group ID should be given");
1962             return false;
1963         }
1964         String policyGroupId = args[1];
1965         int status = setCurrentPowerPolicyGroup(policyGroupId);
1966         if (status != PolicyOperationStatus.OK) {
1967             writer.println(PolicyOperationStatus.errorCodeToString(status));
1968             return false;
1969         }
1970         writer.printf("Setting power policy group(%s) is successful.\n", policyGroupId);
1971         return true;
1972     }
1973 
1974     /**
1975      * Powers off the device, considering the given options.
1976      *
1977      * <p>The final state can be "suspend-to-RAM" or "shutdown". Attempting to go to suspend-to-RAM
1978      * on devices which do not support it may lead to an unexpected system state.
1979      */
powerOffFromCommand(boolean skipGarageMode, boolean shutdown)1980     public void powerOffFromCommand(boolean skipGarageMode, boolean shutdown) {
1981         ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER);
1982         int param = 0;
1983         if (shutdown) {
1984             param = skipGarageMode ? VehicleApPowerStateShutdownParam.SHUTDOWN_IMMEDIATELY
1985                     : VehicleApPowerStateShutdownParam.SHUTDOWN_ONLY;
1986         } else {
1987             param = skipGarageMode ? VehicleApPowerStateShutdownParam.SLEEP_IMMEDIATELY
1988                     : VehicleApPowerStateShutdownParam.CAN_SLEEP;
1989         }
1990         PowerState state = new PowerState(VehicleApPowerStateReq.SHUTDOWN_PREPARE, param);
1991         synchronized (mLock) {
1992             mRebootAfterGarageMode = false;
1993             mPendingPowerStates.addFirst(new CpmsState(state));
1994             mLock.notify();
1995         }
1996         mHandler.handlePowerStateChange();
1997     }
1998 
1999     /**
2000      * Changes Silent Mode to the given mode.
2001      */
setSilentMode(String silentMode)2002     public void setSilentMode(String silentMode) {
2003         ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER);
2004         mSilentModeHandler.setSilentMode(silentMode);
2005     }
2006 
2007     /**
2008      * Dumps the current Silent Mode.
2009      */
dumpSilentMode(IndentingPrintWriter writer)2010     public void dumpSilentMode(IndentingPrintWriter writer) {
2011         mSilentModeHandler.dump(writer);
2012     }
2013 
2014     // In a real Deep Sleep, the hardware removes power from the CPU (but retains power
2015     // on the RAM). This puts the processor to sleep. Upon some external signal, power
2016     // is re-applied to the CPU, and processing resumes right where it left off.
2017     // We simulate this behavior by calling wait().
2018     // We continue from wait() when forceSimulatedResume() is called.
simulateSleepByWaiting()2019     private void simulateSleepByWaiting() {
2020         Slogf.i(TAG, "Starting to simulate Deep Sleep by waiting");
2021         synchronized (mSimulationWaitObject) {
2022             while (!mWakeFromSimulatedSleep) {
2023                 try {
2024                     mSimulationWaitObject.wait();
2025                 } catch (InterruptedException ignored) {
2026                     Thread.currentThread().interrupt(); // Restore interrupted status
2027                 }
2028             }
2029             mInSimulatedDeepSleepMode = false;
2030         }
2031         Slogf.i(TAG, "Exit Deep Sleep simulation");
2032     }
2033 
getMaxSuspendWaitDurationConfig()2034     private int getMaxSuspendWaitDurationConfig() {
2035         return mContext.getResources().getInteger(R.integer.config_maxSuspendWaitDuration);
2036     }
2037 
getWifiAdjustmentForSuspendConfig()2038     private boolean getWifiAdjustmentForSuspendConfig() {
2039         return mContext.getResources().getBoolean(R.bool.config_wifiAdjustmentForSuspend);
2040     }
2041 }
2042