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, /* force= */ false);
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, /* upToDaemon= */ true, /* force= */ false);
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, /* upToDaemon= */ false,
1221                     /* force= */ false);
1222             if (status != PolicyOperationStatus.OK) {
1223                 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(status));
1224             }
1225         } else {
1226             notifyPowerPolicyChangeToDaemon(currentPowerPolicyId, /* force= */ true);
1227         }
1228         if (currentPolicyGroupId == null || currentPolicyGroupId.isEmpty()) {
1229             int status = setCurrentPowerPolicyGroup(state.policyGroupId);
1230             if (status != PolicyOperationStatus.OK) {
1231                 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(status));
1232             }
1233         }
1234         mSilentModeHandler.init();
1235     }
1236 
1237     @PolicyOperationStatus.ErrorCode
setCurrentPowerPolicyGroup(String policyGroupId)1238     private int setCurrentPowerPolicyGroup(String policyGroupId) {
1239         if (!mPolicyReader.isPowerPolicyGroupAvailable(policyGroupId)) {
1240             int error = PolicyOperationStatus.ERROR_SET_POWER_POLICY_GROUP;
1241             Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error,
1242                     policyGroupId + " is not registered"));
1243             return error;
1244         }
1245         synchronized (mLock) {
1246             mCurrentPowerPolicyGroupId = policyGroupId;
1247         }
1248         return PolicyOperationStatus.OK;
1249     }
1250 
1251     @PolicyOperationStatus.ErrorCode
applyPowerPolicy(@ullable String policyId, boolean upToDaemon, boolean force)1252     private int applyPowerPolicy(@Nullable String policyId, boolean upToDaemon, boolean force) {
1253         CarPowerPolicy policy = mPolicyReader.getPowerPolicy(policyId);
1254         if (policy == null) {
1255             int error = PolicyOperationStatus.ERROR_APPLY_POWER_POLICY;
1256             Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error, policyId));
1257             return error;
1258         }
1259         synchronized (mLock) {
1260             if (mIsPowerPolicyLocked) {
1261                 Slogf.i(TAG, "Power policy is locked. The request policy(%s) will be applied when "
1262                         + "power policy becomes unlocked", policyId);
1263                 mPendingPowerPolicyId = policyId;
1264                 return PolicyOperationStatus.OK;
1265             }
1266             mCurrentPowerPolicyId = policyId;
1267         }
1268         mPowerComponentHandler.applyPowerPolicy(policy);
1269         notifyPowerPolicyChange(policyId, upToDaemon, force);
1270         Slogf.i(TAG, "The current power policy is %s", policyId);
1271         return PolicyOperationStatus.OK;
1272     }
1273 
1274     @PolicyOperationStatus.ErrorCode
applyPreemptivePowerPolicy(String policyId)1275     private int applyPreemptivePowerPolicy(String policyId) {
1276         CarPowerPolicy policy = mPolicyReader.getPreemptivePowerPolicy(policyId);
1277         if (policy == null) {
1278             int error = PolicyOperationStatus.ERROR_NOT_REGISTERED_POWER_POLICY_ID;
1279             Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error, policyId));
1280             return error;
1281         }
1282         synchronized (mLock) {
1283             mIsPowerPolicyLocked = true;
1284             if (!mPolicyReader.isPreemptivePowerPolicy(mCurrentPowerPolicyId)) {
1285                 mPendingPowerPolicyId = mCurrentPowerPolicyId;
1286             }
1287             mCurrentPowerPolicyId = policyId;
1288         }
1289         mPowerComponentHandler.applyPowerPolicy(policy);
1290         notifyPowerPolicyChange(policyId, /* upToDaemon= */ true, /* force= */ true);
1291         Slogf.i(TAG, "The current power policy is %s", policyId);
1292         return PolicyOperationStatus.OK;
1293     }
1294 
cancelPreemptivePowerPolicy()1295     private void cancelPreemptivePowerPolicy() {
1296         String policyId;
1297         synchronized (mLock) {
1298             if (!mIsPowerPolicyLocked) {
1299                 Slogf.w(TAG, "Failed to cancel system power policy: the current policy is not the "
1300                         + "system power policy");
1301                 return;
1302             }
1303             mIsPowerPolicyLocked = false;
1304             policyId = mPendingPowerPolicyId;
1305             mPendingPowerPolicyId = null;
1306         }
1307         int status = applyPowerPolicy(policyId, /* upToDaemon= */ true, /* force= */ true);
1308         if (status != PolicyOperationStatus.OK) {
1309             Slogf.w(TAG, "Failed to cancel system power policy: %s",
1310                     PolicyOperationStatus.errorCodeToString(status));
1311         }
1312     }
1313 
notifyPowerPolicyChangeToDaemon(String policyId, boolean force)1314     private void notifyPowerPolicyChangeToDaemon(String policyId, boolean force) {
1315         ICarPowerPolicySystemNotification daemon;
1316         boolean hadPendingPolicyNotification;
1317         synchronized (mLock) {
1318             daemon = mCarPowerPolicyDaemon;
1319             if (daemon == null) {
1320                 Slogf.e(TAG, "Failed to notify car power policy daemon: the daemon is not ready");
1321                 return;
1322             }
1323             if (!mHasControlOverDaemon) {
1324                 Slogf.w(TAG, "Notifying policy change is deferred: CPMS has not yet taken control");
1325                 return;
1326             }
1327         }
1328         try {
1329             daemon.notifyPowerPolicyChange(policyId, force);
1330         } catch (RemoteException | IllegalStateException e) {
1331             Slogf.e(TAG, e, "Failed to notify car power policy daemon of a new power policy(%s)",
1332                     policyId);
1333         }
1334     }
1335 
notifyPowerPolicyChange(String policyId, boolean upToDaemon, boolean force)1336     private void notifyPowerPolicyChange(String policyId, boolean upToDaemon, boolean force) {
1337         // Notify system clients
1338         if (upToDaemon) {
1339             notifyPowerPolicyChangeToDaemon(policyId, force);
1340         }
1341 
1342         // Notify Java clients
1343         CarPowerPolicy accumulatedPolicy = mPowerComponentHandler.getAccumulatedPolicy();
1344         CarPowerPolicy appliedPolicy = mPolicyReader.isPreemptivePowerPolicy(policyId)
1345                 ? mPolicyReader.getPreemptivePowerPolicy(policyId)
1346                 : mPolicyReader.getPowerPolicy(policyId);
1347         if (appliedPolicy == null) {
1348             Slogf.wtf(TAG, "The new power policy(%s) should exist", policyId);
1349         }
1350         int idx = mPowerPolicyListeners.beginBroadcast();
1351         while (idx-- > 0) {
1352             ICarPowerPolicyListener listener = mPowerPolicyListeners.getBroadcastItem(idx);
1353             CarPowerPolicyFilter filter =
1354                     (CarPowerPolicyFilter) mPowerPolicyListeners.getBroadcastCookie(idx);
1355             if (!mPowerComponentHandler.isComponentChanged(filter)) {
1356                 continue;
1357             }
1358             try {
1359                 listener.onPolicyChanged(appliedPolicy, accumulatedPolicy);
1360             } catch (RemoteException e) {
1361                 // It's likely the connection snapped. Let binder death handle the situation.
1362                 Slogf.e(TAG, e, "onPolicyChanged() call failed: policyId = %s", policyId);
1363             }
1364         }
1365         mPowerPolicyListeners.finishBroadcast();
1366     }
1367 
makeSureNoUserInteraction()1368     private void makeSureNoUserInteraction() {
1369         mSilentModeHandler.updateKernelSilentMode(true);
1370         int status = applyPreemptivePowerPolicy(PolicyReader.POWER_POLICY_ID_NO_USER_INTERACTION);
1371         if (status != PolicyOperationStatus.OK) {
1372             Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(status));
1373         }
1374     }
1375 
connectToPowerPolicyDaemon()1376     private void connectToPowerPolicyDaemon() {
1377         synchronized (mLock) {
1378             if (mCarPowerPolicyDaemon != null || mConnectionInProgress) {
1379                 return;
1380             }
1381             mConnectionInProgress = true;
1382         }
1383         connectToDaemonHelper(CAR_POWER_POLICY_DAEMON_BIND_MAX_RETRY);
1384     }
1385 
connectToDaemonHelper(int retryCount)1386     private void connectToDaemonHelper(int retryCount) {
1387         if (retryCount <= 0) {
1388             synchronized (mLock) {
1389                 mConnectionInProgress = false;
1390             }
1391             Slogf.e(TAG, "Cannot reconnect to car power policyd daemon after retrying %d times",
1392                     CAR_POWER_POLICY_DAEMON_BIND_MAX_RETRY);
1393             return;
1394         }
1395         if (makeBinderConnection()) {
1396             Slogf.i(TAG, "Connected to car power policy daemon");
1397             initializePowerPolicy();
1398             return;
1399         }
1400         mHandler.sendMessageDelayed(PooledLambda.obtainMessage(
1401                 CarPowerManagementService::connectToDaemonHelper,
1402                 CarPowerManagementService.this, retryCount - 1),
1403                 CAR_POWER_POLICY_DAEMON_BIND_RETRY_INTERVAL_MS);
1404     }
1405 
makeBinderConnection()1406     private boolean makeBinderConnection() {
1407         long currentTimeMs = SystemClock.uptimeMillis();
1408         IBinder binder = ServiceManager.getService(CAR_POWER_POLICY_DAEMON_INTERFACE);
1409         if (binder == null) {
1410             Slogf.w(TAG, "Finding car power policy daemon failed. Power policy management is not "
1411                     + "supported");
1412             return false;
1413         }
1414         long elapsedTimeMs = SystemClock.uptimeMillis() - currentTimeMs;
1415         if (elapsedTimeMs > CAR_POWER_POLICY_DAEMON_FIND_MARGINAL_TIME_MS) {
1416             Slogf.wtf(TAG, "Finding car power policy daemon took too long(%dms)", elapsedTimeMs);
1417         }
1418 
1419         ICarPowerPolicySystemNotification daemon =
1420                 ICarPowerPolicySystemNotification.Stub.asInterface(binder);
1421         if (daemon == null) {
1422             Slogf.w(TAG, "Getting car power policy daemon interface failed. Power policy management"
1423                     + " is not supported");
1424             return false;
1425         }
1426         synchronized (mLock) {
1427             mCarPowerPolicyDaemon = daemon;
1428             mConnectionInProgress = false;
1429         }
1430         mBinderHandler = new BinderHandler(daemon);
1431         mBinderHandler.linkToDeath();
1432         return true;
1433     }
1434 
1435     private final class BinderHandler implements IBinder.DeathRecipient {
1436         private ICarPowerPolicySystemNotification mDaemon;
1437 
BinderHandler(ICarPowerPolicySystemNotification daemon)1438         private BinderHandler(ICarPowerPolicySystemNotification daemon) {
1439             mDaemon = daemon;
1440         }
1441 
1442         @Override
binderDied()1443         public void binderDied() {
1444             Slogf.w(TAG, "Car power policy daemon died: reconnecting");
1445             unlinkToDeath();
1446             mDaemon = null;
1447             synchronized (mLock) {
1448                 mCarPowerPolicyDaemon = null;
1449                 mHasControlOverDaemon = false;
1450             }
1451             mHandler.sendMessageDelayed(PooledLambda.obtainMessage(
1452                     CarPowerManagementService::connectToDaemonHelper,
1453                     CarPowerManagementService.this, CAR_POWER_POLICY_DAEMON_BIND_MAX_RETRY),
1454                     CAR_POWER_POLICY_DAEMON_BIND_RETRY_INTERVAL_MS);
1455         }
1456 
linkToDeath()1457         private void linkToDeath() {
1458             if (mDaemon == null) {
1459                 return;
1460             }
1461             IBinder binder = mDaemon.asBinder();
1462             if (binder == null) {
1463                 Slogf.w(TAG, "Linking to binder death recipient skipped");
1464                 return;
1465             }
1466             try {
1467                 binder.linkToDeath(this, 0);
1468             } catch (RemoteException e) {
1469                 mDaemon = null;
1470                 Slogf.w(TAG, e, "Linking to binder death recipient failed: %s");
1471             }
1472         }
1473 
unlinkToDeath()1474         private void unlinkToDeath() {
1475             if (mDaemon == null) {
1476                 return;
1477             }
1478             IBinder binder = mDaemon.asBinder();
1479             if (binder == null) {
1480                 Slogf.w(TAG, "Unlinking from binder death recipient skipped");
1481                 return;
1482             }
1483             binder.unlinkToDeath(this, 0);
1484         }
1485     }
1486 
1487     private static final class PowerHandler extends Handler {
1488         private static final String TAG = PowerHandler.class.getSimpleName();
1489         private static final int MSG_POWER_STATE_CHANGE = 0;
1490         private static final int MSG_DISPLAY_BRIGHTNESS_CHANGE = 1;
1491         private static final int MSG_MAIN_DISPLAY_STATE_CHANGE = 2;
1492         private static final int MSG_PROCESSING_COMPLETE = 3;
1493 
1494         // Do not handle this immediately but with some delay as there can be a race between
1495         // display off due to rear view camera and delivery to here.
1496         private static final long MAIN_DISPLAY_EVENT_DELAY_MS = 500;
1497 
1498         private final WeakReference<CarPowerManagementService> mService;
1499 
PowerHandler(Looper looper, CarPowerManagementService service)1500         private PowerHandler(Looper looper, CarPowerManagementService service) {
1501             super(looper);
1502             mService = new WeakReference<CarPowerManagementService>(service);
1503         }
1504 
handlePowerStateChange()1505         private void handlePowerStateChange() {
1506             Message msg = obtainMessage(MSG_POWER_STATE_CHANGE);
1507             sendMessage(msg);
1508         }
1509 
handleDisplayBrightnessChange(int brightness)1510         private void handleDisplayBrightnessChange(int brightness) {
1511             Message msg = obtainMessage(MSG_DISPLAY_BRIGHTNESS_CHANGE, brightness, 0);
1512             sendMessage(msg);
1513         }
1514 
handleMainDisplayStateChange(boolean on)1515         private void handleMainDisplayStateChange(boolean on) {
1516             removeMessages(MSG_MAIN_DISPLAY_STATE_CHANGE);
1517             Message msg = obtainMessage(MSG_MAIN_DISPLAY_STATE_CHANGE, Boolean.valueOf(on));
1518             sendMessageDelayed(msg, MAIN_DISPLAY_EVENT_DELAY_MS);
1519         }
1520 
handleProcessingComplete()1521         private void handleProcessingComplete() {
1522             removeMessages(MSG_PROCESSING_COMPLETE);
1523             Message msg = obtainMessage(MSG_PROCESSING_COMPLETE);
1524             sendMessage(msg);
1525         }
1526 
cancelProcessingComplete()1527         private void cancelProcessingComplete() {
1528             removeMessages(MSG_PROCESSING_COMPLETE);
1529         }
1530 
cancelAll()1531         private void cancelAll() {
1532             removeMessages(MSG_POWER_STATE_CHANGE);
1533             removeMessages(MSG_DISPLAY_BRIGHTNESS_CHANGE);
1534             removeMessages(MSG_MAIN_DISPLAY_STATE_CHANGE);
1535             removeMessages(MSG_PROCESSING_COMPLETE);
1536         }
1537 
1538         @Override
handleMessage(Message msg)1539         public void handleMessage(Message msg) {
1540             CarPowerManagementService service = mService.get();
1541             if (service == null) {
1542                 Slogf.i(TAG, "handleMessage null service");
1543                 return;
1544             }
1545             switch (msg.what) {
1546                 case MSG_POWER_STATE_CHANGE:
1547                     service.doHandlePowerStateChange();
1548                     break;
1549                 case MSG_DISPLAY_BRIGHTNESS_CHANGE:
1550                     service.doHandleDisplayBrightnessChange(msg.arg1);
1551                     break;
1552                 case MSG_MAIN_DISPLAY_STATE_CHANGE:
1553                     service.doHandleMainDisplayStateChange((Boolean) msg.obj);
1554                     break;
1555                 case MSG_PROCESSING_COMPLETE:
1556                     service.doHandleProcessingComplete();
1557                     break;
1558             }
1559         }
1560     }
1561 
1562     private class ShutdownProcessingTimerTask extends TimerTask {
1563         private final int mExpirationCount;
1564         private int mCurrentCount;
1565 
ShutdownProcessingTimerTask(int expirationCount)1566         private ShutdownProcessingTimerTask(int expirationCount) {
1567             mExpirationCount = expirationCount;
1568             mCurrentCount = 0;
1569         }
1570 
1571         @Override
run()1572         public void run() {
1573             synchronized (mLock) {
1574                 if (!mTimerActive) {
1575                     // Ignore timer expiration since we got cancelled
1576                     return;
1577                 }
1578                 mCurrentCount++;
1579                 if (mCurrentCount > mExpirationCount) {
1580                     PowerHandler handler;
1581                     releaseTimerLocked();
1582                     handler = mHandler;
1583                     handler.handleProcessingComplete();
1584                 } else {
1585                     mHal.sendShutdownPostpone(SHUTDOWN_EXTEND_MAX_MS);
1586                 }
1587             }
1588         }
1589     }
1590 
1591     // Send the command to enter Suspend to RAM.
1592     // If the command is not successful, try again with an exponential back-off.
1593     // If it fails repeatedly, send the command to shut down.
1594     // If we decide to go to a different power state, abort this retry mechanism.
1595     // Returns true if we successfully suspended.
suspendWithRetries()1596     private boolean suspendWithRetries() {
1597         long retryIntervalMs = INITIAL_SUSPEND_RETRY_INTERVAL_MS;
1598         long totalWaitDurationMs = 0;
1599 
1600         while (true) {
1601             Slogf.i(TAG, "Entering Suspend to RAM");
1602             boolean suspendSucceeded = mSystemInterface.enterDeepSleep();
1603             if (suspendSucceeded) {
1604                 return true;
1605             }
1606             if (totalWaitDurationMs >= mMaxSuspendWaitDurationMs) {
1607                 break;
1608             }
1609             // We failed to suspend. Block the thread briefly and try again.
1610             synchronized (mLock) {
1611                 if (mPendingPowerStates.isEmpty()) {
1612                     Slogf.w(TAG, "Failed to Suspend; will retry after %dms", retryIntervalMs);
1613                     try {
1614                         mLock.wait(retryIntervalMs);
1615                     } catch (InterruptedException ignored) {
1616                         Thread.currentThread().interrupt();
1617                     }
1618                     totalWaitDurationMs += retryIntervalMs;
1619                     retryIntervalMs = Math.min(retryIntervalMs * 2, MAX_RETRY_INTERVAL_MS);
1620                 }
1621                 // Check for a new power state now, before going around the loop again
1622                 if (!mPendingPowerStates.isEmpty()) {
1623                     Slogf.i(TAG, "Terminating the attempt to Suspend to RAM");
1624                     return false;
1625                 }
1626             }
1627         }
1628         // Too many failures trying to suspend. Shut down.
1629         Slogf.w(TAG, "Could not Suspend to RAM after %dms long trial. Shutting down.",
1630                 totalWaitDurationMs);
1631         mSystemInterface.shutdown();
1632         return false;
1633     }
1634 
1635     private static class CpmsState {
1636         // NOTE: When modifying states below, make sure to update CarPowerStateChanged.State in
1637         //   frameworks/proto_logging/stats/atoms.proto also.
1638         public static final int WAIT_FOR_VHAL = 0;
1639         public static final int ON = 1;
1640         public static final int SHUTDOWN_PREPARE = 2;
1641         public static final int WAIT_FOR_FINISH = 3;
1642         public static final int SUSPEND = 4;
1643         public static final int SIMULATE_SLEEP = 5;
1644 
1645         /* Config values from AP_POWER_STATE_REQ */
1646         public final boolean mCanPostpone;
1647         public final boolean mCanSleep;
1648         /* Message sent to CarPowerStateListener in response to this state */
1649         public final int mCarPowerStateListenerState;
1650         /* One of the above state variables */
1651         public final int mState;
1652 
1653         /**
1654           * This constructor takes a PowerHalService.PowerState object and creates the corresponding
1655           * CPMS state from it.
1656           */
CpmsState(PowerState halPowerState)1657         CpmsState(PowerState halPowerState) {
1658             switch (halPowerState.mState) {
1659                 case VehicleApPowerStateReq.ON:
1660                     this.mCanPostpone = false;
1661                     this.mCanSleep = false;
1662                     this.mCarPowerStateListenerState = cpmsStateToPowerStateListenerState(ON);
1663                     this.mState = ON;
1664                     break;
1665                 case VehicleApPowerStateReq.SHUTDOWN_PREPARE:
1666                     this.mCanPostpone = halPowerState.canPostponeShutdown();
1667                     this.mCanSleep = halPowerState.canEnterDeepSleep();
1668                     this.mCarPowerStateListenerState = cpmsStateToPowerStateListenerState(
1669                             SHUTDOWN_PREPARE);
1670                     this.mState = SHUTDOWN_PREPARE;
1671                     break;
1672                 case VehicleApPowerStateReq.CANCEL_SHUTDOWN:
1673                     this.mCanPostpone = false;
1674                     this.mCanSleep = false;
1675                     this.mCarPowerStateListenerState = CarPowerStateListener.SHUTDOWN_CANCELLED;
1676                     this.mState = WAIT_FOR_VHAL;
1677                     break;
1678                 case VehicleApPowerStateReq.FINISHED:
1679                     this.mCanPostpone = false;
1680                     this.mCanSleep = false;
1681                     this.mCarPowerStateListenerState = cpmsStateToPowerStateListenerState(SUSPEND);
1682                     this.mState = SUSPEND;
1683                     break;
1684                 default:
1685                     // Illegal state from PowerState.  Throw an exception?
1686                     this.mCanPostpone = false;
1687                     this.mCanSleep = false;
1688                     this.mCarPowerStateListenerState = 0;
1689                     this.mState = 0;
1690                     break;
1691             }
1692         }
1693 
CpmsState(int state, int carPowerStateListenerState)1694         CpmsState(int state, int carPowerStateListenerState) {
1695             this.mCanPostpone = (state == SIMULATE_SLEEP);
1696             this.mCanSleep = (state == SIMULATE_SLEEP);
1697             this.mCarPowerStateListenerState = carPowerStateListenerState;
1698             this.mState = state;
1699         }
1700 
name()1701         public String name() {
1702             String baseName;
1703             switch(mState) {
1704                 case WAIT_FOR_VHAL:     baseName = "WAIT_FOR_VHAL";    break;
1705                 case ON:                baseName = "ON";               break;
1706                 case SHUTDOWN_PREPARE:  baseName = "SHUTDOWN_PREPARE"; break;
1707                 case WAIT_FOR_FINISH:   baseName = "WAIT_FOR_FINISH";  break;
1708                 case SUSPEND:           baseName = "SUSPEND";          break;
1709                 case SIMULATE_SLEEP:    baseName = "SIMULATE_SLEEP";   break;
1710                 default:                baseName = "<unknown>";        break;
1711             }
1712             return baseName + "(" + mState + ")";
1713         }
1714 
cpmsStateToPowerStateListenerState(int state)1715         private static int cpmsStateToPowerStateListenerState(int state) {
1716             int powerStateListenerState = 0;
1717 
1718             // Set the CarPowerStateListenerState based on current state
1719             switch (state) {
1720                 case ON:
1721                     powerStateListenerState = CarPowerStateListener.ON;
1722                     break;
1723                 case SHUTDOWN_PREPARE:
1724                     powerStateListenerState = CarPowerStateListener.SHUTDOWN_PREPARE;
1725                     break;
1726                 case SUSPEND:
1727                     powerStateListenerState = CarPowerStateListener.SUSPEND_ENTER;
1728                     break;
1729                 case WAIT_FOR_VHAL:
1730                 case WAIT_FOR_FINISH:
1731                 default:
1732                     // Illegal state for this constructor.  Throw an exception?
1733                     break;
1734             }
1735             return powerStateListenerState;
1736         }
1737 
1738         @Override
equals(Object o)1739         public boolean equals(Object o) {
1740             if (this == o) {
1741                 return true;
1742             }
1743             if (!(o instanceof CpmsState)) {
1744                 return false;
1745             }
1746             CpmsState that = (CpmsState) o;
1747             return this.mState == that.mState
1748                     && this.mCanSleep == that.mCanSleep
1749                     && this.mCanPostpone == that.mCanPostpone
1750                     && this.mCarPowerStateListenerState == that.mCarPowerStateListenerState;
1751         }
1752 
1753         @Override
toString()1754         public String toString() {
1755             return "CpmsState canSleep:" + mCanSleep + ", canPostpone=" + mCanPostpone
1756                     + ", carPowerStateListenerState=" + mCarPowerStateListenerState
1757                     + ", CpmsState=" + this.name();
1758         }
1759     }
1760 
1761     /**
1762      * Resume after a manually-invoked suspend.
1763      * Invoked using "adb shell dumpsys activity service com.android.car resume".
1764      */
forceSimulatedResume()1765     public void forceSimulatedResume() {
1766         PowerHandler handler;
1767         synchronized (mLock) {
1768             // Cancel Garage Mode in case it's running
1769             mPendingPowerStates.addFirst(new CpmsState(CpmsState.WAIT_FOR_VHAL,
1770                                                        CarPowerStateListener.SHUTDOWN_CANCELLED));
1771             mLock.notify();
1772             handler = mHandler;
1773         }
1774         handler.handlePowerStateChange();
1775 
1776         synchronized (mSimulationWaitObject) {
1777             mWakeFromSimulatedSleep = true;
1778             mSimulationWaitObject.notify();
1779         }
1780     }
1781 
1782     /**
1783      * Manually enter simulated suspend (Deep Sleep) mode, trigging Garage mode.
1784      * If the parameter is 'true', reboot the system when Garage Mode completes.
1785      *
1786      * Invoked using "adb shell dumpsys activity service com.android.car suspend" or
1787      * "adb shell dumpsys activity service com.android.car garage-mode reboot".
1788      * This is similar to 'onApPowerStateChange()' except that it needs to create a CpmsState
1789      * that is not directly derived from a VehicleApPowerStateReq.
1790      */
forceSuspendAndMaybeReboot(boolean shouldReboot)1791     public void forceSuspendAndMaybeReboot(boolean shouldReboot) {
1792         synchronized (mSimulationWaitObject) {
1793             mInSimulatedDeepSleepMode = true;
1794             mWakeFromSimulatedSleep = false;
1795             mGarageModeShouldExitImmediately = false;
1796         }
1797         PowerHandler handler;
1798         synchronized (mLock) {
1799             mRebootAfterGarageMode = shouldReboot;
1800             mPendingPowerStates.addFirst(new CpmsState(CpmsState.SIMULATE_SLEEP,
1801                                                        CarPowerStateListener.SHUTDOWN_PREPARE));
1802             handler = mHandler;
1803         }
1804         handler.handlePowerStateChange();
1805     }
1806 
1807     /**
1808      * Manually defines a power policy.
1809      *
1810      * <p>If the given ID already exists or specified power components are invalid, it fails.
1811      *
1812      * @return {@code true}, if successful. Otherwise, {@code false}.
1813      */
definePowerPolicyFromCommand(String[] args, IndentingPrintWriter writer)1814     public boolean definePowerPolicyFromCommand(String[] args, IndentingPrintWriter writer) {
1815         if (args.length < 2) {
1816             writer.println("Too few arguments");
1817             return false;
1818         }
1819         String powerPolicyId = args[1];
1820         int index = 2;
1821         String[] enabledComponents = new String[0];
1822         String[] disabledComponents = new String[0];
1823         while (index < args.length) {
1824             switch (args[index]) {
1825                 case "--enable":
1826                     if (index == args.length - 1) {
1827                         writer.println("No components for --enable");
1828                         return false;
1829                     }
1830                     enabledComponents = args[index + 1].split(",");
1831                     break;
1832                 case "--disable":
1833                     if (index == args.length - 1) {
1834                         writer.println("No components for --disabled");
1835                         return false;
1836                     }
1837                     disabledComponents = args[index + 1].split(",");
1838                     break;
1839                 default:
1840                     writer.printf("Unrecognized argument: %s\n", args[index]);
1841                     return false;
1842             }
1843             index += 2;
1844         }
1845         int status = definePowerPolicy(powerPolicyId, enabledComponents, disabledComponents);
1846         if (status != PolicyOperationStatus.OK) {
1847             writer.println(PolicyOperationStatus.errorCodeToString(status));
1848             return false;
1849         }
1850         writer.printf("Power policy(%s) is successfully defined.\n", powerPolicyId);
1851         return true;
1852     }
1853 
1854     /**
1855      * Defines a power policy with the given id and components.
1856      *
1857      * <p> A policy defined with this method is valid until the system is rebooted/restarted.
1858      */
1859     @VisibleForTesting
1860     @PolicyOperationStatus.ErrorCode
definePowerPolicy(String powerPolicyId, String[] enabledComponents, String[] disabledComponents)1861     public int definePowerPolicy(String powerPolicyId, String[] enabledComponents,
1862             String[] disabledComponents) {
1863         int status = mPolicyReader.definePowerPolicy(powerPolicyId,
1864                 enabledComponents, disabledComponents);
1865         if (status != PolicyOperationStatus.OK) {
1866             int error = PolicyOperationStatus.ERROR_DEFINE_POWER_POLICY;
1867             Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error));
1868             return error;
1869         }
1870         ICarPowerPolicySystemNotification daemon;
1871         synchronized (mLock) {
1872             daemon = mCarPowerPolicyDaemon;
1873         }
1874         try {
1875             daemon.notifyPowerPolicyDefinition(powerPolicyId, enabledComponents,
1876                     disabledComponents);
1877         } catch (RemoteException e) {
1878             int error = PolicyOperationStatus.ERROR_DEFINE_POWER_POLICY;
1879             Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error));
1880             return error;
1881         }
1882         return PolicyOperationStatus.OK;
1883     }
1884 
1885     /**
1886      * Manually applies a power policy.
1887      *
1888      * <p>If the given ID is not defined, it fails.
1889      *
1890      * @return {@code true}, if successful. Otherwise, {@code false}.
1891      */
applyPowerPolicyFromCommand(String[] args, IndentingPrintWriter writer)1892     public boolean applyPowerPolicyFromCommand(String[] args, IndentingPrintWriter writer) {
1893         if (args.length != 2) {
1894             writer.println("Power policy ID should be given");
1895             return false;
1896         }
1897         String powerPolicyId = args[1];
1898         if (powerPolicyId == null) {
1899             writer.println("Policy ID cannot be null");
1900             return false;
1901         }
1902         boolean isPreemptive = mPolicyReader.isPreemptivePowerPolicy(powerPolicyId);
1903         int status = isPreemptive ? applyPreemptivePowerPolicy(powerPolicyId)
1904                 : applyPowerPolicy(powerPolicyId, /* upToDaemon= */ true, /* force= */ false);
1905         if (status != PolicyOperationStatus.OK) {
1906             writer.println(PolicyOperationStatus.errorCodeToString(status));
1907             return false;
1908         }
1909         writer.printf("Power policy(%s) is successfully applied.\n", powerPolicyId);
1910         return true;
1911     }
1912 
1913     /**
1914      * Manually defines a power policy group.
1915      *
1916      * <p>If the given ID already exists, a wrong power state is given, or specified power policy ID
1917      * doesn't exist, it fails.
1918      *
1919      * @return {@code true}, if successful. Otherwise, {@code false}.
1920      */
definePowerPolicyGroupFromCommand(String[] args, IndentingPrintWriter writer)1921     public boolean definePowerPolicyGroupFromCommand(String[] args, IndentingPrintWriter writer) {
1922         if (args.length < 3 || args.length > 4) {
1923             writer.println("Invalid syntax");
1924             return false;
1925         }
1926         String policyGroupId = args[1];
1927         int index = 2;
1928         SparseArray<String> defaultPolicyPerState = new SparseArray<>();
1929         while (index < args.length) {
1930             String[] tokens = args[index].split(":");
1931             if (tokens.length != 2) {
1932                 writer.println("Invalid syntax");
1933                 return false;
1934             }
1935             int state = PolicyReader.toPowerState(tokens[0]);
1936             if (state == PolicyReader.INVALID_POWER_STATE) {
1937                 writer.printf("Invalid power state: %s\n", tokens[0]);
1938                 return false;
1939             }
1940             defaultPolicyPerState.put(state, tokens[1]);
1941             index++;
1942         }
1943         int status = mPolicyReader.definePowerPolicyGroup(policyGroupId,
1944                 defaultPolicyPerState);
1945         if (status != PolicyOperationStatus.OK) {
1946             writer.println(PolicyOperationStatus.errorCodeToString(status));
1947             return false;
1948         }
1949         writer.printf("Power policy group(%s) is successfully defined.\n", policyGroupId);
1950         return true;
1951     }
1952 
1953     /**
1954      * Manually sets a power policy group.
1955      *
1956      * <p>If the given ID is not defined, it fails.
1957      *
1958      * @return {@code true}, if successful. Otherwise, {@code false}.
1959      */
setPowerPolicyGroupFromCommand(String[] args, IndentingPrintWriter writer)1960     public boolean setPowerPolicyGroupFromCommand(String[] args, IndentingPrintWriter writer) {
1961         if (args.length != 2) {
1962             writer.println("Power policy group ID should be given");
1963             return false;
1964         }
1965         String policyGroupId = args[1];
1966         int status = setCurrentPowerPolicyGroup(policyGroupId);
1967         if (status != PolicyOperationStatus.OK) {
1968             writer.println(PolicyOperationStatus.errorCodeToString(status));
1969             return false;
1970         }
1971         writer.printf("Setting power policy group(%s) is successful.\n", policyGroupId);
1972         return true;
1973     }
1974 
1975     /**
1976      * Powers off the device, considering the given options.
1977      *
1978      * <p>The final state can be "suspend-to-RAM" or "shutdown". Attempting to go to suspend-to-RAM
1979      * on devices which do not support it may lead to an unexpected system state.
1980      */
powerOffFromCommand(boolean skipGarageMode, boolean shutdown)1981     public void powerOffFromCommand(boolean skipGarageMode, boolean shutdown) {
1982         ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER);
1983         int param = 0;
1984         if (shutdown) {
1985             param = skipGarageMode ? VehicleApPowerStateShutdownParam.SHUTDOWN_IMMEDIATELY
1986                     : VehicleApPowerStateShutdownParam.SHUTDOWN_ONLY;
1987         } else {
1988             param = skipGarageMode ? VehicleApPowerStateShutdownParam.SLEEP_IMMEDIATELY
1989                     : VehicleApPowerStateShutdownParam.CAN_SLEEP;
1990         }
1991         PowerState state = new PowerState(VehicleApPowerStateReq.SHUTDOWN_PREPARE, param);
1992         synchronized (mLock) {
1993             mRebootAfterGarageMode = false;
1994             mPendingPowerStates.addFirst(new CpmsState(state));
1995             mLock.notify();
1996         }
1997         mHandler.handlePowerStateChange();
1998     }
1999 
2000     /**
2001      * Changes Silent Mode to the given mode.
2002      */
setSilentMode(String silentMode)2003     public void setSilentMode(String silentMode) {
2004         ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER);
2005         mSilentModeHandler.setSilentMode(silentMode);
2006     }
2007 
2008     /**
2009      * Dumps the current Silent Mode.
2010      */
dumpSilentMode(IndentingPrintWriter writer)2011     public void dumpSilentMode(IndentingPrintWriter writer) {
2012         mSilentModeHandler.dump(writer);
2013     }
2014 
2015     // In a real Deep Sleep, the hardware removes power from the CPU (but retains power
2016     // on the RAM). This puts the processor to sleep. Upon some external signal, power
2017     // is re-applied to the CPU, and processing resumes right where it left off.
2018     // We simulate this behavior by calling wait().
2019     // We continue from wait() when forceSimulatedResume() is called.
simulateSleepByWaiting()2020     private void simulateSleepByWaiting() {
2021         Slogf.i(TAG, "Starting to simulate Deep Sleep by waiting");
2022         synchronized (mSimulationWaitObject) {
2023             while (!mWakeFromSimulatedSleep) {
2024                 try {
2025                     mSimulationWaitObject.wait();
2026                 } catch (InterruptedException ignored) {
2027                     Thread.currentThread().interrupt(); // Restore interrupted status
2028                 }
2029             }
2030             mInSimulatedDeepSleepMode = false;
2031         }
2032         Slogf.i(TAG, "Exit Deep Sleep simulation");
2033     }
2034 
getMaxSuspendWaitDurationConfig()2035     private int getMaxSuspendWaitDurationConfig() {
2036         return mContext.getResources().getInteger(R.integer.config_maxSuspendWaitDuration);
2037     }
2038 
getWifiAdjustmentForSuspendConfig()2039     private boolean getWifiAdjustmentForSuspendConfig() {
2040         return mContext.getResources().getBoolean(R.bool.config_wifiAdjustmentForSuspend);
2041     }
2042 }
2043