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 static android.car.hardware.power.CarPowerManager.STATE_PRE_SHUTDOWN_PREPARE; 20 import static android.car.hardware.power.CarPowerManager.STATE_SHUTDOWN_PREPARE; 21 import static android.net.ConnectivityManager.TETHERING_WIFI; 22 23 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.DUMP_INFO; 24 25 import android.annotation.NonNull; 26 import android.annotation.Nullable; 27 import android.app.ActivityManager; 28 import android.car.Car; 29 import android.car.ICarResultReceiver; 30 import android.car.builtin.os.BuildHelper; 31 import android.car.builtin.os.ServiceManagerHelper; 32 import android.car.builtin.util.EventLogHelper; 33 import android.car.builtin.util.Slogf; 34 import android.car.hardware.power.CarPowerManager; 35 import android.car.hardware.power.CarPowerPolicy; 36 import android.car.hardware.power.CarPowerPolicyFilter; 37 import android.car.hardware.power.ICarPower; 38 import android.car.hardware.power.ICarPowerPolicyListener; 39 import android.car.hardware.power.ICarPowerStateListener; 40 import android.content.ComponentName; 41 import android.content.Context; 42 import android.content.Intent; 43 import android.content.res.Resources; 44 import android.frameworks.automotive.powerpolicy.internal.ICarPowerPolicySystemNotification; 45 import android.frameworks.automotive.powerpolicy.internal.PolicyState; 46 import android.hardware.automotive.vehicle.VehicleApPowerStateReport; 47 import android.hardware.automotive.vehicle.VehicleApPowerStateReq; 48 import android.hardware.automotive.vehicle.VehicleApPowerStateShutdownParam; 49 import android.net.TetheringManager; 50 import android.net.TetheringManager.TetheringRequest; 51 import android.net.wifi.WifiManager; 52 import android.os.Handler; 53 import android.os.HandlerThread; 54 import android.os.IBinder; 55 import android.os.IInterface; 56 import android.os.Looper; 57 import android.os.Message; 58 import android.os.PowerManager; 59 import android.os.RemoteCallbackList; 60 import android.os.RemoteException; 61 import android.os.SystemClock; 62 import android.os.SystemProperties; 63 import android.os.UserHandle; 64 import android.os.UserManager; 65 import android.util.ArraySet; 66 import android.util.AtomicFile; 67 import android.util.SparseArray; 68 69 import com.android.car.CarLocalServices; 70 import com.android.car.CarLog; 71 import com.android.car.CarServiceBase; 72 import com.android.car.CarServiceUtils; 73 import com.android.car.CarStatsLogHelper; 74 import com.android.car.R; 75 import com.android.car.hal.PowerHalService; 76 import com.android.car.hal.PowerHalService.PowerState; 77 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport; 78 import com.android.car.internal.util.DebugUtils; 79 import com.android.car.internal.util.IndentingPrintWriter; 80 import com.android.car.systeminterface.SystemInterface; 81 import com.android.car.user.CarUserNoticeService; 82 import com.android.car.user.CarUserService; 83 import com.android.car.user.UserHandleHelper; 84 import com.android.internal.annotations.GuardedBy; 85 import com.android.internal.annotations.VisibleForTesting; 86 import com.android.internal.util.Preconditions; 87 88 import java.io.BufferedReader; 89 import java.io.BufferedWriter; 90 import java.io.File; 91 import java.io.FileOutputStream; 92 import java.io.IOException; 93 import java.io.InputStreamReader; 94 import java.io.OutputStreamWriter; 95 import java.lang.ref.WeakReference; 96 import java.nio.charset.StandardCharsets; 97 import java.util.ArrayList; 98 import java.util.LinkedList; 99 import java.util.concurrent.ExecutorService; 100 import java.util.concurrent.Executors; 101 import java.util.concurrent.Semaphore; 102 import java.util.concurrent.TimeUnit; 103 import java.util.concurrent.atomic.AtomicBoolean; 104 import java.util.function.BiFunction; 105 106 /** 107 * Power Management service class for cars. Controls the power states and interacts with other 108 * parts of the system to ensure its own state. 109 */ 110 public class CarPowerManagementService extends ICarPower.Stub implements 111 CarServiceBase, PowerHalService.PowerEventListener { 112 public static final String SILENT_MODE_FORCED_SILENT = 113 SilentModeHandler.SILENT_MODE_FORCED_SILENT; 114 public static final String SILENT_MODE_FORCED_NON_SILENT = 115 SilentModeHandler.SILENT_MODE_FORCED_NON_SILENT; 116 public static final String SILENT_MODE_NON_FORCED = SilentModeHandler.SILENT_MODE_NON_FORCED; 117 118 public static final long INVALID_TIMEOUT = -1L; 119 120 public static final int NO_WAKEUP_BY_TIMER = -1; 121 122 static final String TAG = CarLog.tagFor(CarPowerManagementService.class); 123 124 private static final String WIFI_STATE_FILENAME = "wifi_state"; 125 private static final String TETHERING_STATE_FILENAME = "tethering_state"; 126 private static final String COMPONENT_STATE_MODIFIED = "forcibly_disabled"; 127 private static final String COMPONENT_STATE_ORIGINAL = "original"; 128 // If Suspend to RAM fails, we retry with an exponential back-off: 129 // The wait interval will be 10 msec, 20 msec, 40 msec, ... 130 // Once the wait interval goes beyond 100 msec, it is fixed at 100 msec. 131 private static final long INITIAL_SUSPEND_RETRY_INTERVAL_MS = 10; 132 private static final long MAX_RETRY_INTERVAL_MS = 100; 133 // Minimum and maximum wait duration before the system goes into Suspend to RAM. 134 private static final long MIN_SUSPEND_WAIT_DURATION_MS = 0; 135 private static final long MAX_SUSPEND_WAIT_DURATION_MS = 3 * 60 * 1000; 136 137 private static final long CAR_POWER_POLICY_DAEMON_FIND_MARGINAL_TIME_MS = 300; 138 private static final long CAR_POWER_POLICY_DAEMON_BIND_RETRY_INTERVAL_MS = 500; 139 private static final int CAR_POWER_POLICY_DAEMON_BIND_MAX_RETRY = 3; 140 private static final String CAR_POWER_POLICY_DAEMON_INTERFACE = 141 "android.frameworks.automotive.powerpolicy.internal.ICarPowerPolicySystemNotification/" 142 + "default"; 143 144 // TODO: Make this OEM configurable. 145 private static final int SHUTDOWN_POLLING_INTERVAL_MS = 2000; 146 private static final int SHUTDOWN_EXTEND_MAX_MS = 5000; 147 148 // maxGarageModeRunningDurationInSecs should be equal or greater than this. 15 min for now. 149 private static final int MIN_MAX_GARAGE_MODE_DURATION_MS = 15 * 60 * 1000; 150 151 // in secs 152 private static final String PROP_MAX_GARAGE_MODE_DURATION_OVERRIDE = 153 "android.car.garagemodeduration"; 154 // Constants for action on finish 155 private static final int ACTION_ON_FINISH_SHUTDOWN = 0; 156 private static final int ACTION_ON_FINISH_DEEP_SLEEP = 1; 157 private static final int ACTION_ON_FINISH_HIBERNATION = 2; 158 159 // Default timeout for listener completion during shutdown. 160 private static final int DEFAULT_COMPLETION_WAIT_TIMEOUT = 5_000; 161 162 private final Object mLock = new Object(); 163 private final Object mSimulationWaitObject = new Object(); 164 165 private final Context mContext; 166 private final PowerHalService mHal; 167 private final SystemInterface mSystemInterface; 168 // The listeners that complete simply by returning from onStateChanged() 169 private final PowerManagerCallbackList<ICarPowerStateListener> mPowerManagerListeners = 170 new PowerManagerCallbackList<>( 171 l -> CarPowerManagementService.this.doUnregisterListener(l)); 172 // The listeners that must indicate asynchronous completion by calling finished(). 173 private final PowerManagerCallbackList<ICarPowerStateListener> 174 mPowerManagerListenersWithCompletion = new PowerManagerCallbackList<>( 175 l -> CarPowerManagementService.this.doUnregisterListener(l)); 176 // The internal listeners that must indicates asynchronous completion by calling 177 // completeStateChangeHandling(). Note that they are not binder objects. 178 @GuardedBy("mLock") 179 private final ArrayList<ICarPowerStateListener> mInternalPowerListeners = new ArrayList<>(); 180 181 @GuardedBy("mLock") 182 private final ArraySet<IBinder> mListenersWeAreWaitingFor = new ArraySet<>(); 183 @GuardedBy("mLock") 184 private final LinkedList<CpmsState> mPendingPowerStates = new LinkedList<>(); 185 private final HandlerThread mHandlerThread = CarServiceUtils.getHandlerThread( 186 getClass().getSimpleName()); 187 private final PowerHandler mHandler = new PowerHandler(mHandlerThread.getLooper(), this); 188 189 private final UserManager mUserManager; 190 private final CarUserService mUserService; 191 192 private final WifiManager mWifiManager; 193 private final TetheringManager mTetheringManager; 194 private final AtomicFile mWifiStateFile; 195 private final AtomicFile mTetheringStateFile; 196 private final boolean mWifiAdjustmentForSuspend; 197 198 // This is a temp work-around to reduce user switching delay after wake-up. 199 private final boolean mSwitchGuestUserBeforeSleep; 200 201 // CPMS tries to enter Suspend to RAM within the duration specified at 202 // mMaxSuspendWaitDurationMs. The default max duration is MAX_SUSPEND_WAIT_DRATION, and can be 203 // overridden by setting config_maxSuspendWaitDuration in an overrlay resource. 204 // The valid range is MIN_SUSPEND_WAIT_DRATION to MAX_SUSPEND_WAIT_DURATION. 205 private final long mMaxSuspendWaitDurationMs; 206 207 @GuardedBy("mSimulationWaitObject") 208 private boolean mWakeFromSimulatedSleep; 209 @GuardedBy("mSimulationWaitObject") 210 private boolean mInSimulatedDeepSleepMode; 211 @GuardedBy("mSimulationWaitObject") 212 private int mResumeDelayFromSimulatedSuspendSec = NO_WAKEUP_BY_TIMER; 213 214 @GuardedBy("mLock") 215 private CpmsState mCurrentState; 216 @GuardedBy("mLock") 217 private long mShutdownStartTime; 218 @GuardedBy("mLock") 219 private long mLastSleepEntryTime; 220 221 @GuardedBy("mLock") 222 private int mNextWakeupSec; 223 @GuardedBy("mLock") 224 private int mActionOnFinish; 225 @GuardedBy("mLock") 226 private boolean mShutdownOnNextSuspend; 227 @GuardedBy("mLock") 228 private boolean mIsBooting = true; 229 @GuardedBy("mLock") 230 private int mShutdownPrepareTimeMs = MIN_MAX_GARAGE_MODE_DURATION_MS; 231 @GuardedBy("mLock") 232 private int mShutdownPollingIntervalMs = SHUTDOWN_POLLING_INTERVAL_MS; 233 @GuardedBy("mLock") 234 private boolean mRebootAfterGarageMode; 235 @GuardedBy("mLock") 236 private boolean mGarageModeShouldExitImmediately; 237 238 @GuardedBy("mLock") 239 private ICarPowerPolicySystemNotification mCarPowerPolicyDaemon; 240 @GuardedBy("mLock") 241 private boolean mConnectionInProgress; 242 private BinderHandler mBinderHandler; 243 @GuardedBy("mLock") 244 private String mCurrentPowerPolicyId; 245 @GuardedBy("mLock") 246 private String mPendingPowerPolicyId; 247 @GuardedBy("mLock") 248 private String mCurrentPowerPolicyGroupId; 249 @GuardedBy("mLock") 250 private boolean mIsPowerPolicyLocked; 251 @GuardedBy("mLock") 252 private boolean mHasControlOverDaemon; 253 private AtomicBoolean mIsListenerWaitingCancelled = new AtomicBoolean(false); 254 private final Semaphore mListenerCompletionSem = new Semaphore(/* permits= */ 0); 255 @GuardedBy("mLock") 256 @CarPowerManager.CarPowerState 257 private int mStateForCompletion = CarPowerManager.STATE_INVALID; 258 259 @GuardedBy("mLock") 260 @Nullable 261 private ICarResultReceiver mFactoryResetCallback; 262 263 private final PowerManagerCallbackList<ICarPowerPolicyListener> mPowerPolicyListeners = 264 new PowerManagerCallbackList<>( 265 l -> CarPowerManagementService.this.mPowerPolicyListeners.unregister(l)); 266 267 private final PowerComponentHandler mPowerComponentHandler; 268 private final PolicyReader mPolicyReader = new PolicyReader(); 269 private final SilentModeHandler mSilentModeHandler; 270 271 interface ActionOnDeath<T extends IInterface> { take(T listener)272 void take(T listener); 273 } 274 275 private final class PowerManagerCallbackList<T extends IInterface> extends 276 RemoteCallbackList<T> { 277 private ActionOnDeath<T> mActionOnDeath; 278 PowerManagerCallbackList(ActionOnDeath<T> action)279 PowerManagerCallbackList(ActionOnDeath<T> action) { 280 mActionOnDeath = action; 281 } 282 283 /** 284 * Old version of {@link #onCallbackDied(E, Object)} that 285 * does not provide a cookie. 286 */ 287 @Override onCallbackDied(T listener)288 public void onCallbackDied(T listener) { 289 Slogf.i(TAG, "binderDied %s", listener.asBinder()); 290 mActionOnDeath.take(listener); 291 } 292 } 293 CarPowerManagementService(Context context, PowerHalService powerHal, SystemInterface systemInterface, CarUserService carUserService, ICarPowerPolicySystemNotification powerPolicyDaemon)294 public CarPowerManagementService(Context context, PowerHalService powerHal, 295 SystemInterface systemInterface, CarUserService carUserService, 296 ICarPowerPolicySystemNotification powerPolicyDaemon) { 297 this(context, context.getResources(), powerHal, systemInterface, 298 context.getSystemService(UserManager.class), 299 carUserService, powerPolicyDaemon, 300 new PowerComponentHandler(context, systemInterface), 301 /* silentModeHwStatePath= */ null, /* silentModeKernelStatePath= */ null, 302 /* bootReason= */ null); 303 } 304 305 @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)306 public CarPowerManagementService(Context context, Resources resources, PowerHalService powerHal, 307 SystemInterface systemInterface, UserManager userManager, CarUserService carUserService, 308 ICarPowerPolicySystemNotification powerPolicyDaemon, 309 PowerComponentHandler powerComponentHandler, @Nullable String silentModeHwStatePath, 310 @Nullable String silentModeKernelStatePath, @Nullable String bootReason) { 311 mContext = context; 312 mHal = powerHal; 313 mSystemInterface = systemInterface; 314 mUserManager = userManager; 315 mShutdownPrepareTimeMs = resources.getInteger( 316 R.integer.maxGarageModeRunningDurationInSecs) * 1000; 317 mSwitchGuestUserBeforeSleep = resources.getBoolean( 318 R.bool.config_switchGuestUserBeforeGoingSleep); 319 if (mShutdownPrepareTimeMs < MIN_MAX_GARAGE_MODE_DURATION_MS) { 320 Slogf.w(TAG, 321 "maxGarageModeRunningDurationInSecs smaller than minimum required, " 322 + "resource:%d(ms) while should exceed:%d(ms), Ignore resource.", 323 mShutdownPrepareTimeMs, MIN_MAX_GARAGE_MODE_DURATION_MS); 324 mShutdownPrepareTimeMs = MIN_MAX_GARAGE_MODE_DURATION_MS; 325 } 326 mUserService = carUserService; 327 mCarPowerPolicyDaemon = powerPolicyDaemon; 328 if (powerPolicyDaemon != null) { 329 // For testing purpose 330 mHasControlOverDaemon = true; 331 } 332 mWifiManager = context.getSystemService(WifiManager.class); 333 mTetheringManager = mContext.getSystemService(TetheringManager.class); 334 mWifiStateFile = new AtomicFile( 335 new File(mSystemInterface.getSystemCarDir(), WIFI_STATE_FILENAME)); 336 mTetheringStateFile = new AtomicFile( 337 new File(mSystemInterface.getSystemCarDir(), TETHERING_STATE_FILENAME)); 338 mWifiAdjustmentForSuspend = isWifiAdjustmentForSuspendConfig(); 339 mPowerComponentHandler = powerComponentHandler; 340 mSilentModeHandler = new SilentModeHandler(this, silentModeHwStatePath, 341 silentModeKernelStatePath, bootReason); 342 mMaxSuspendWaitDurationMs = Math.max(MIN_SUSPEND_WAIT_DURATION_MS, 343 Math.min(getMaxSuspendWaitDurationConfig(), MAX_SUSPEND_WAIT_DURATION_MS)); 344 } 345 346 /** 347 * Overrides timers to keep testing time short. 348 * 349 * <p>Passing in {@code 0} resets the value to the default. 350 */ 351 @VisibleForTesting setShutdownTimersForTest(int pollingIntervalMs, int shutdownTimeoutMs)352 public void setShutdownTimersForTest(int pollingIntervalMs, int shutdownTimeoutMs) { 353 synchronized (mLock) { 354 mShutdownPollingIntervalMs = 355 (pollingIntervalMs == 0) ? SHUTDOWN_POLLING_INTERVAL_MS : pollingIntervalMs; 356 mShutdownPrepareTimeMs = 357 (shutdownTimeoutMs == 0) ? SHUTDOWN_EXTEND_MAX_MS : shutdownTimeoutMs; 358 } 359 } 360 361 @VisibleForTesting getHandlerThread()362 protected HandlerThread getHandlerThread() { 363 return mHandlerThread; 364 } 365 366 @Override init()367 public void init() { 368 mPolicyReader.init(); 369 mPowerComponentHandler.init(); 370 mHal.setListener(this); 371 if (mHal.isPowerStateSupported()) { 372 // Initialize CPMS in WAIT_FOR_VHAL state 373 onApPowerStateChange(CpmsState.WAIT_FOR_VHAL, CarPowerManager.STATE_WAIT_FOR_VHAL); 374 } else { 375 Slogf.w(TAG, "Vehicle hal does not support power state yet."); 376 onApPowerStateChange(CpmsState.ON, CarPowerManager.STATE_ON); 377 } 378 mSystemInterface.init(this, mUserService); 379 mSystemInterface.startDisplayStateMonitoring(); 380 connectToPowerPolicyDaemon(); 381 } 382 383 @Override release()384 public void release() { 385 if (mBinderHandler != null) { 386 mBinderHandler.unlinkToDeath(); 387 } 388 synchronized (mLock) { 389 clearWaitingForCompletion(/*clearQueue=*/false); 390 mCurrentState = null; 391 mCarPowerPolicyDaemon = null; 392 mHandler.cancelAll(); 393 mListenersWeAreWaitingFor.clear(); 394 } 395 mSystemInterface.stopDisplayStateMonitoring(); 396 mPowerManagerListeners.kill(); 397 mPowerPolicyListeners.kill(); 398 mSystemInterface.releaseAllWakeLocks(); 399 } 400 401 @Override 402 @ExcludeFromCodeCoverageGeneratedReport(reason = DUMP_INFO) dump(IndentingPrintWriter writer)403 public void dump(IndentingPrintWriter writer) { 404 synchronized (mLock) { 405 writer.println("*PowerManagementService*"); 406 writer.printf("mCurrentState: %s\n", mCurrentState); 407 writer.printf("mShutdownStartTime: %d\n", mShutdownStartTime); 408 writer.printf("mLastSleepEntryTime: %d\n", mLastSleepEntryTime); 409 writer.printf("mNextWakeupSec: %d\n", mNextWakeupSec); 410 writer.printf("mShutdownOnNextSuspend: %b\n", mShutdownOnNextSuspend); 411 writer.printf("mActionOnFinish: %s\n", actionOnFinishToString(mActionOnFinish)); 412 writer.printf("mShutdownPollingIntervalMs: %d\n", mShutdownPollingIntervalMs); 413 writer.printf("mShutdownPrepareTimeMs: %d\n", mShutdownPrepareTimeMs); 414 writer.printf("mRebootAfterGarageMode: %b\n", mRebootAfterGarageMode); 415 writer.printf("mSwitchGuestUserBeforeSleep: %b\n", mSwitchGuestUserBeforeSleep); 416 writer.printf("mCurrentPowerPolicyId: %s\n", mCurrentPowerPolicyId); 417 writer.printf("mPendingPowerPolicyId: %s\n", mPendingPowerPolicyId); 418 writer.printf("mCurrentPowerPolicyGroupId: %s\n", mCurrentPowerPolicyGroupId); 419 writer.printf("mIsPowerPolicyLocked: %b\n", mIsPowerPolicyLocked); 420 writer.printf("mMaxSuspendWaitDurationMs: %d\n", mMaxSuspendWaitDurationMs); 421 writer.printf("config_maxSuspendWaitDuration: %d\n", getMaxSuspendWaitDurationConfig()); 422 writer.printf("mWifiStateFile: %s\n", mWifiStateFile); 423 writer.printf("mTetheringStateFile: %s\n", mTetheringStateFile); 424 writer.printf("mWifiAdjustmentForSuspend: %b\n", mWifiAdjustmentForSuspend); 425 writer.printf("# of power policy change listener: %d\n", 426 mPowerPolicyListeners.getRegisteredCallbackCount()); 427 writer.printf("mFactoryResetCallback: %s\n", mFactoryResetCallback); 428 writer.printf("mIsListenerWaitingCancelled: %b\n", mIsListenerWaitingCancelled.get()); 429 writer.printf("kernel support S2R: %b\n", 430 mSystemInterface.isSystemSupportingDeepSleep()); 431 writer.printf("kernel support S2D: %b\n", 432 mSystemInterface.isSystemSupportingHibernation()); 433 } 434 mPolicyReader.dump(writer); 435 mPowerComponentHandler.dump(writer); 436 mSilentModeHandler.dump(writer); 437 } 438 439 @Override onApPowerStateChange(PowerState state)440 public void onApPowerStateChange(PowerState state) { 441 EventLogHelper.writeCarPowerManagerStateRequest(state.mState, state.mParam); 442 synchronized (mLock) { 443 mPendingPowerStates.addFirst(new CpmsState(state)); 444 mLock.notify(); 445 } 446 mHandler.handlePowerStateChange(); 447 } 448 449 @VisibleForTesting setStateForWakeUp()450 void setStateForWakeUp() { 451 mSilentModeHandler.init(); 452 synchronized (mLock) { 453 mIsBooting = false; 454 } 455 handleWaitForVhal(new CpmsState(CpmsState.WAIT_FOR_VHAL, 456 CarPowerManager.STATE_WAIT_FOR_VHAL, /* canPostpone= */ false)); 457 Slogf.d(TAG, "setStateForTesting(): mIsBooting is set to false and power state is switched " 458 + "to Wait For Vhal"); 459 } 460 461 /** 462 * Initiate state change from CPMS directly. 463 */ onApPowerStateChange(int apState, @CarPowerManager.CarPowerState int carPowerStateListenerState)464 private void onApPowerStateChange(int apState, 465 @CarPowerManager.CarPowerState int carPowerStateListenerState) { 466 CpmsState newState = new CpmsState(apState, carPowerStateListenerState, 467 /* canPostpone= */ false); 468 BiFunction<CpmsState, CpmsState, Boolean> eventFilter = null; 469 470 // We are ready to shut down. Suppress this transition if 471 // there is a request to cancel the shutdown (WAIT_FOR_VHAL). 472 // Completely ignore this WAIT_FOR_FINISH 473 if (newState.mState == CpmsState.WAIT_FOR_FINISH) { 474 eventFilter = (stateToAdd, pendingSate) -> 475 stateToAdd.mState == CpmsState.WAIT_FOR_FINISH 476 && pendingSate.mState == CpmsState.WAIT_FOR_VHAL; 477 } 478 479 // Check if there is another pending SHUTDOWN_PREPARE. 480 // This could happen, when another SHUTDOWN_PREPARE request is received from VHAL 481 // while notifying PRE_SHUTDOWN_PREPARE. 482 // If SHUTDOWN_PREPARE request already exist in the queue, and it skips Garage Mode, 483 // then newState is ignored . 484 if (newState.mState == CpmsState.SHUTDOWN_PREPARE) { 485 eventFilter = (stateToAdd, pendingState) -> 486 pendingState.mState == CpmsState.SHUTDOWN_PREPARE 487 && !pendingState.mCanPostpone 488 && pendingState.mCarPowerStateListenerState 489 == STATE_PRE_SHUTDOWN_PREPARE; 490 } 491 492 synchronized (mLock) { 493 // If eventFilter exists, lets check if event that satisfies filter is in queue. 494 if (eventFilter != null) { 495 for (int idx = 0; idx < mPendingPowerStates.size(); idx++) { 496 CpmsState pendingState = mPendingPowerStates.get(idx); 497 if (eventFilter.apply(newState, pendingState)) { 498 return; 499 } 500 } 501 } 502 mPendingPowerStates.addFirst(newState); 503 mLock.notify(); 504 } 505 mHandler.handlePowerStateChange(); 506 } 507 doHandlePowerStateChange()508 private void doHandlePowerStateChange() { 509 CpmsState newState; 510 CpmsState prevState; 511 synchronized (mLock) { 512 prevState = mCurrentState; 513 newState = mPendingPowerStates.pollFirst(); 514 if (newState == null) { 515 Slogf.w(TAG, "No more power state to process"); 516 return; 517 } 518 Slogf.i(TAG, "doHandlePowerStateChange: newState=%s", newState.name()); 519 if (!needPowerStateChangeLocked(newState)) { 520 // We may need to process the pending power state request. 521 if (!mPendingPowerStates.isEmpty()) { 522 Slogf.i(TAG, "There is a pending power state change request. requesting the " 523 + "processing..."); 524 mHandler.handlePowerStateChange(); 525 } 526 return; 527 } 528 529 // now real power change happens. Whatever was queued before should be all cancelled. 530 mPendingPowerStates.clear(); 531 532 // Received updated SHUTDOWN_PREPARE there could be several reasons for that 533 // 1. CPMS is in SHUTDOWN_PREPARE, and received state change to perform transition 534 // from PRE_SHUTDOWN_PREPARE into SHUTDOWN_PREPARE 535 // 2. New SHUTDOWN_PREPARE request is received, and it is different from existing one. 536 if (newState.mState == CpmsState.SHUTDOWN_PREPARE && newState.mState == prevState.mState 537 && newState.mCarPowerStateListenerState == STATE_PRE_SHUTDOWN_PREPARE) { 538 // Nothing to do here, skipping clearing completion queue 539 } else { 540 clearWaitingForCompletion(/*clearQueue=*/false); 541 } 542 543 mCurrentState = newState; 544 } 545 mHandler.cancelProcessingComplete(); 546 547 Slogf.i(TAG, "setCurrentState %s", newState); 548 CarStatsLogHelper.logPowerState(newState.mState); 549 EventLogHelper.writeCarPowerManagerStateChange(newState.mState); 550 switch (newState.mState) { 551 case CpmsState.WAIT_FOR_VHAL: 552 handleWaitForVhal(newState); 553 break; 554 case CpmsState.ON: 555 handleOn(); 556 break; 557 case CpmsState.SHUTDOWN_PREPARE: 558 handleShutdownPrepare(newState, prevState); 559 break; 560 case CpmsState.SIMULATE_SLEEP: 561 case CpmsState.SIMULATE_HIBERNATION: 562 simulateShutdownPrepare(newState, prevState); 563 break; 564 case CpmsState.WAIT_FOR_FINISH: 565 handleWaitForFinish(newState); 566 break; 567 case CpmsState.SUSPEND: 568 // Received FINISH from VHAL 569 handleFinish(); 570 break; 571 default: 572 // Illegal state 573 // TODO(b/202414427): Add handling of illegal state 574 break; 575 } 576 } 577 handleWaitForVhal(CpmsState state)578 private void handleWaitForVhal(CpmsState state) { 579 @CarPowerManager.CarPowerState int carPowerStateListenerState = 580 state.mCarPowerStateListenerState; 581 // TODO(b/177478420): Restore Wifi, Audio, Location, and Bluetooth, if they are artificially 582 // modified for S2R. 583 mSilentModeHandler.querySilentModeHwState(); 584 585 applyDefaultPowerPolicyForState(CarPowerManager.STATE_WAIT_FOR_VHAL, 586 PolicyReader.POWER_POLICY_ID_INITIAL_ON); 587 588 if (!mSilentModeHandler.isSilentMode()) { 589 cancelPreemptivePowerPolicy(); 590 } 591 592 sendPowerManagerEvent(carPowerStateListenerState, INVALID_TIMEOUT); 593 // Inspect CarPowerStateListenerState to decide which message to send via VHAL 594 switch (carPowerStateListenerState) { 595 case CarPowerManager.STATE_WAIT_FOR_VHAL: 596 mHal.sendWaitForVhal(); 597 break; 598 case CarPowerManager.STATE_SHUTDOWN_CANCELLED: 599 synchronized (mLock) { 600 mShutdownOnNextSuspend = false; // This cancels the "NextSuspend" 601 } 602 mHal.sendShutdownCancel(); 603 break; 604 case CarPowerManager.STATE_SUSPEND_EXIT: 605 mHal.sendSleepExit(); 606 break; 607 case CarPowerManager.STATE_HIBERNATION_EXIT: 608 mHal.sendHibernationExit(); 609 break; 610 } 611 if (mWifiAdjustmentForSuspend) { 612 restoreWifiFully(); 613 } 614 } 615 updateCarUserNoticeServiceIfNecessary()616 private void updateCarUserNoticeServiceIfNecessary() { 617 try { 618 int currentUserId = ActivityManager.getCurrentUser(); 619 UserHandleHelper userHandleHelper = new UserHandleHelper(mContext, mUserManager); 620 UserHandle currentUser = userHandleHelper.getExistingUserHandle(currentUserId); 621 CarUserNoticeService carUserNoticeService = 622 CarLocalServices.getService(CarUserNoticeService.class); 623 if (currentUser != null && userHandleHelper.isGuestUser(currentUser) 624 && carUserNoticeService != null) { 625 Slogf.i(TAG, "Car user notice service will ignore all messages before user " 626 + "switch."); 627 Intent intent = new Intent(); 628 intent.setComponent(ComponentName.unflattenFromString( 629 mContext.getResources().getString(R.string.continuousBlankActivity))); 630 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 631 mContext.startActivityAsUser(intent, UserHandle.CURRENT); 632 carUserNoticeService.ignoreUserNotice(currentUserId); 633 } 634 } catch (Exception e) { 635 Slogf.w(TAG, e, "Cannot ignore user notice for current user"); 636 } 637 } 638 639 @VisibleForTesting handleOn()640 void handleOn() { 641 if (factoryResetIfNeeded()) return; 642 643 // If current user is a Guest User, we want to inform CarUserNoticeService not to show 644 // notice for current user, and show user notice only for the target user. 645 if (!mSwitchGuestUserBeforeSleep) { 646 updateCarUserNoticeServiceIfNecessary(); 647 } 648 649 if (!mSilentModeHandler.isSilentMode()) { 650 cancelPreemptivePowerPolicy(); 651 } 652 applyDefaultPowerPolicyForState(VehicleApPowerStateReport.ON, 653 PolicyReader.POWER_POLICY_ID_ALL_ON); 654 655 sendPowerManagerEvent(CarPowerManager.STATE_ON, INVALID_TIMEOUT); 656 657 mHal.sendOn(); 658 659 synchronized (mLock) { 660 if (mIsBooting) { 661 Slogf.d(TAG, "handleOn(): called on boot"); 662 mIsBooting = false; 663 return; 664 } 665 } 666 667 try { 668 mUserService.onResume(); 669 } catch (Exception e) { 670 Slogf.e(TAG, e, "Could not switch user on resume"); 671 } 672 } 673 factoryResetIfNeeded()674 private boolean factoryResetIfNeeded() { 675 ICarResultReceiver callback; 676 synchronized (mLock) { 677 if (mFactoryResetCallback == null) return false; 678 callback = mFactoryResetCallback; 679 } 680 681 try { 682 Slogf.i(TAG, "Factory resetting as it was delayed by user"); 683 callback.send(/* resultCode= */ 0, /* resultData= */ null); 684 return true; 685 } catch (Exception e) { 686 Slogf.wtf(TAG, e, "Should have factory reset, but failed"); 687 return false; 688 } 689 } 690 applyDefaultPowerPolicyForState(@arPowerManager.CarPowerState int state, @Nullable String fallbackPolicyId)691 private void applyDefaultPowerPolicyForState(@CarPowerManager.CarPowerState int state, 692 @Nullable String fallbackPolicyId) { 693 Slogf.i(TAG, "Applying the default power policy for %s (fallback policy = %s)", 694 powerStateToString(state), fallbackPolicyId); 695 CarPowerPolicy policy; 696 synchronized (mLock) { 697 policy = mPolicyReader 698 .getDefaultPowerPolicyForState(mCurrentPowerPolicyGroupId, state); 699 } 700 if (policy == null && fallbackPolicyId == null) { 701 Slogf.w(TAG, "No default power policy for %s is found", powerStateToString(state)); 702 return; 703 } 704 String policyId = policy == null ? fallbackPolicyId : policy.getPolicyId(); 705 applyPowerPolicy(policyId, /* delayNotification= */ false, /* upToDaemon= */ true, 706 /* force= */ false); 707 } 708 709 /** 710 * Sets the callback used to factory reset the device on resume when the user delayed it. 711 */ setFactoryResetCallback(ICarResultReceiver callback)712 public void setFactoryResetCallback(ICarResultReceiver callback) { 713 synchronized (mLock) { 714 mFactoryResetCallback = callback; 715 } 716 } 717 718 /** 719 * Tells Garage Mode if it should run normally, or just 720 * exit immediately without indicating 'idle' 721 * @return True if no idle jobs should be run 722 * @hide 723 */ garageModeShouldExitImmediately()724 public boolean garageModeShouldExitImmediately() { 725 synchronized (mLock) { 726 return mGarageModeShouldExitImmediately; 727 } 728 } 729 handleShutdownPrepare(CpmsState currentState, CpmsState prevState)730 private void handleShutdownPrepare(CpmsState currentState, CpmsState prevState) { 731 switch (currentState.mCarPowerStateListenerState) { 732 case CarPowerManager.STATE_PRE_SHUTDOWN_PREPARE: 733 updateShutdownPrepareStatus(currentState); 734 if (prevState.mCarPowerStateListenerState == STATE_SHUTDOWN_PREPARE) { 735 // Received request to update SHUTDOWN target 736 currentState = new CpmsState(currentState.mState, 737 prevState.mCarPowerStateListenerState, 738 prevState.mCanPostpone, currentState.mShutdownType); 739 synchronized (mLock) { 740 mCurrentState = currentState; 741 } 742 clearWaitingForCompletion(/*clearQueue=*/true); 743 } else if (prevState.mCarPowerStateListenerState == STATE_PRE_SHUTDOWN_PREPARE) { 744 // Update of state occurred while in PRE_SHUTDOWN_PREPARE 745 boolean areListenersEmpty; 746 synchronized (mLock) { 747 areListenersEmpty = mListenersWeAreWaitingFor.isEmpty(); 748 } 749 if (areListenersEmpty) { 750 handleCoreShutdownPrepare(); 751 } else { 752 // PRE_SHUTDOWN_PREPARE is still being processed, no actions required 753 return; 754 } 755 } else { 756 handlePreShutdownPrepare(); 757 } 758 break; 759 case CarPowerManager.STATE_SHUTDOWN_PREPARE: 760 handleCoreShutdownPrepare(); 761 break; 762 default: 763 Slogf.w(TAG, "Not supported listener state(%d)", 764 currentState.mCarPowerStateListenerState); 765 } 766 } 767 updateShutdownPrepareStatus(CpmsState newState)768 private void updateShutdownPrepareStatus(CpmsState newState) { 769 // Shutdown on finish if the system doesn't support deep sleep/hibernation 770 // or doesn't allow it. 771 int intervalMs; 772 synchronized (mLock) { 773 if (mShutdownOnNextSuspend 774 || newState.mShutdownType == PowerState.SHUTDOWN_TYPE_POWER_OFF) { 775 mActionOnFinish = ACTION_ON_FINISH_SHUTDOWN; 776 } else if (newState.mShutdownType == PowerState.SHUTDOWN_TYPE_DEEP_SLEEP) { 777 boolean isDeepSleepOnFinish = 778 isDeepSleepAvailable() || newState.mState == CpmsState.SIMULATE_SLEEP; 779 mActionOnFinish = isDeepSleepOnFinish ? ACTION_ON_FINISH_DEEP_SLEEP 780 : ACTION_ON_FINISH_SHUTDOWN; 781 } else if (newState.mShutdownType == PowerState.SHUTDOWN_TYPE_HIBERNATION) { 782 boolean isHibernationOnFinish = isHibernationAvailable() 783 || newState.mState == CpmsState.SIMULATE_HIBERNATION; 784 mActionOnFinish = isHibernationOnFinish ? ACTION_ON_FINISH_HIBERNATION 785 : ACTION_ON_FINISH_SHUTDOWN; 786 } else { 787 Slogf.wtf(TAG, "handleShutdownPrepare - incorrect state " + newState); 788 } 789 mGarageModeShouldExitImmediately = !newState.mCanPostpone; 790 intervalMs = mShutdownPollingIntervalMs; 791 } 792 } 793 handlePreShutdownPrepare()794 private void handlePreShutdownPrepare() { 795 int intervalMs; 796 synchronized (mLock) { 797 intervalMs = mShutdownPollingIntervalMs; 798 Slogf.i(TAG, 799 mGarageModeShouldExitImmediately ? "starting shutdown prepare with Garage Mode" 800 : "starting shutdown prepare without Garage Mode"); 801 } 802 803 long timeoutMs = getPreShutdownPrepareTimeoutConfig(); 804 int state = CarPowerManager.STATE_PRE_SHUTDOWN_PREPARE; 805 sendPowerManagerEvent(state, timeoutMs); 806 Runnable taskAtCompletion = () -> { 807 // The next power state is still SHUTDOWN_PREPARE, and the listener state is 808 // SHUTDOW_PREPARE. 809 Slogf.i(TAG, "All listeners completed for %s", powerStateToString(state)); 810 onApPowerStateChange(CpmsState.SHUTDOWN_PREPARE, 811 CarPowerManager.STATE_SHUTDOWN_PREPARE); 812 }; 813 814 waitForCompletionWithShutdownPostpone(state, timeoutMs, taskAtCompletion, intervalMs); 815 } 816 handleCoreShutdownPrepare()817 private void handleCoreShutdownPrepare() { 818 Slogf.i(TAG, "Handling core part of shutdown prepare"); 819 doShutdownPrepare(); 820 } 821 822 // Simulates system shutdown to suspend simulateShutdownPrepare(CpmsState newState, CpmsState oldState)823 private void simulateShutdownPrepare(CpmsState newState, CpmsState oldState) { 824 Slogf.i(TAG, "Simulating shutdown prepare"); 825 handleShutdownPrepare(newState, oldState); 826 } 827 doShutdownPrepare()828 private void doShutdownPrepare() { 829 long timeoutMs; 830 long intervalMs; 831 synchronized (mLock) { 832 timeoutMs = mShutdownPrepareTimeMs; 833 intervalMs = mShutdownPollingIntervalMs; 834 mShutdownStartTime = SystemClock.elapsedRealtime(); 835 } 836 if (BuildHelper.isUserDebugBuild() || BuildHelper.isEngBuild()) { 837 int shutdownPrepareTimeOverrideInSecs = 838 SystemProperties.getInt(PROP_MAX_GARAGE_MODE_DURATION_OVERRIDE, -1); 839 if (shutdownPrepareTimeOverrideInSecs >= 0) { 840 timeoutMs = shutdownPrepareTimeOverrideInSecs * 1000L; 841 } 842 } 843 makeSureNoUserInteraction(); 844 sendPowerManagerEvent(CarPowerManager.STATE_SHUTDOWN_PREPARE, timeoutMs); 845 mHal.sendShutdownPrepare(); 846 waitForShutdownPrepareListenersToComplete(timeoutMs, intervalMs); 847 } 848 handleWaitForFinish(CpmsState state)849 private void handleWaitForFinish(CpmsState state) { 850 int timeoutMs = getShutdownEnterTimeoutConfig(); 851 sendPowerManagerEvent(state.mCarPowerStateListenerState, timeoutMs); 852 Runnable taskAtCompletion = () -> { 853 Slogf.i(TAG, "All listeners completed for %s", 854 powerStateToString(state.mCarPowerStateListenerState)); 855 int wakeupSec; 856 synchronized (mLock) { 857 // If we're shutting down immediately, don't schedule a wakeup time. 858 wakeupSec = mGarageModeShouldExitImmediately ? 0 : mNextWakeupSec; 859 } 860 switch (state.mCarPowerStateListenerState) { 861 case CarPowerManager.STATE_SUSPEND_ENTER: 862 mHal.sendSleepEntry(wakeupSec); 863 break; 864 case CarPowerManager.STATE_SHUTDOWN_ENTER: 865 mHal.sendShutdownStart(wakeupSec); 866 break; 867 case CarPowerManager.STATE_HIBERNATION_ENTER: 868 mHal.sendHibernationEntry(wakeupSec); 869 break; 870 } 871 }; 872 873 int intervalMs; 874 synchronized (mLock) { 875 intervalMs = mShutdownPollingIntervalMs; 876 } 877 878 waitForCompletionWithShutdownPostpone(state.mCarPowerStateListenerState, timeoutMs, 879 taskAtCompletion, intervalMs); 880 } 881 handleFinish()882 private void handleFinish() { 883 int listenerState; 884 synchronized (mLock) { 885 switch (mActionOnFinish) { 886 case ACTION_ON_FINISH_SHUTDOWN: 887 listenerState = CarPowerManager.STATE_POST_SHUTDOWN_ENTER; 888 break; 889 case ACTION_ON_FINISH_DEEP_SLEEP: 890 listenerState = CarPowerManager.STATE_POST_SUSPEND_ENTER; 891 break; 892 case ACTION_ON_FINISH_HIBERNATION: 893 listenerState = CarPowerManager.STATE_POST_HIBERNATION_ENTER; 894 break; 895 default: 896 Slogf.w(TAG, "Invalid action on finish: %d", mActionOnFinish); 897 return; 898 } 899 } 900 int timeoutMs = getPostShutdownEnterTimeoutConfig(); 901 sendPowerManagerEvent(listenerState, timeoutMs); 902 Runnable taskAtCompletion = () -> { 903 Slogf.i(TAG, "All listeners completed for %s", powerStateToString(listenerState)); 904 doHandleFinish(); 905 }; 906 Slogf.i(TAG, "Start waiting for listener completion for %s", 907 powerStateToString(listenerState)); 908 waitForCompletion(taskAtCompletion, /* taskAtInterval= */ null, timeoutMs, 909 /* intervalMs= */ -1); 910 } 911 doHandleFinish()912 private void doHandleFinish() { 913 boolean simulatedMode; 914 synchronized (mSimulationWaitObject) { 915 simulatedMode = mInSimulatedDeepSleepMode; 916 } 917 boolean mustShutDown; 918 boolean forceReboot; 919 synchronized (mLock) { 920 mustShutDown = (mActionOnFinish == ACTION_ON_FINISH_SHUTDOWN) && !simulatedMode; 921 forceReboot = mRebootAfterGarageMode; 922 mRebootAfterGarageMode = false; 923 } 924 if (forceReboot) { 925 PowerManager powerManager = mContext.getSystemService(PowerManager.class); 926 if (powerManager == null) { 927 Slogf.wtf(TAG, "No PowerManager. Cannot reboot."); 928 } else { 929 Slogf.i(TAG, "GarageMode has completed. Forcing reboot."); 930 powerManager.reboot("GarageModeReboot"); 931 throw new AssertionError("Should not return from PowerManager.reboot()"); 932 } 933 } 934 // To make Kernel implementation simpler when going into sleep. 935 if (mWifiAdjustmentForSuspend) { 936 disableWifiFully(); 937 } 938 939 if (mustShutDown) { 940 // shutdown HU 941 mSystemInterface.shutdown(); 942 } else { 943 doHandleDeepSleep(simulatedMode); 944 } 945 synchronized (mLock) { 946 mShutdownOnNextSuspend = false; 947 } 948 } 949 disableWifiFully()950 private void disableWifiFully() { 951 disableWifi(); 952 disableTethering(); 953 } 954 restoreWifiFully()955 private void restoreWifiFully() { 956 restoreTethering(); 957 restoreWifi(); 958 } 959 restoreWifi()960 private void restoreWifi() { 961 boolean needToRestore = readWifiModifiedState(mWifiStateFile); 962 if (!needToRestore) return; 963 if (!mWifiManager.isWifiEnabled()) { 964 Slogf.i(TAG, "Wifi has been enabled to restore the last setting"); 965 mWifiManager.setWifiEnabled(true); 966 } 967 // Update the persistent data as wifi is not modified by car framework. 968 saveWifiModifiedState(mWifiStateFile, /* forciblyDisabled= */ false); 969 } 970 disableWifi()971 private void disableWifi() { 972 boolean wifiEnabled = mWifiManager.isWifiEnabled(); 973 boolean wifiModifiedState = readWifiModifiedState(mWifiStateFile); 974 if (wifiEnabled != wifiModifiedState) { 975 Slogf.i(TAG, "Saving the current Wifi state"); 976 saveWifiModifiedState(mWifiStateFile, wifiEnabled); 977 } 978 979 // In some devices, enabling a tether temporarily turns off Wifi. To make sure that Wifi is 980 // disabled, we call this method in all cases. 981 mWifiManager.setWifiEnabled(false); 982 Slogf.i(TAG, "Wifi has been disabled and the last setting was saved"); 983 } 984 restoreTethering()985 private void restoreTethering() { 986 boolean needToRestore = readWifiModifiedState(mTetheringStateFile); 987 if (!needToRestore) return; 988 if (!mWifiManager.isWifiApEnabled()) { 989 Slogf.i(TAG, "Tethering has been enabled to restore the last setting"); 990 startTethering(); 991 } 992 // Update the persistent data as wifi is not modified by car framework. 993 saveWifiModifiedState(mTetheringStateFile, /*forciblyDisabled= */ false); 994 } 995 disableTethering()996 private void disableTethering() { 997 boolean tetheringEnabled = mWifiManager.isWifiApEnabled(); 998 boolean tetheringModifiedState = readWifiModifiedState(mTetheringStateFile); 999 if (tetheringEnabled != tetheringModifiedState) { 1000 Slogf.i(TAG, "Saving the current tethering state: tetheringEnabled=%b", 1001 tetheringEnabled); 1002 saveWifiModifiedState(mTetheringStateFile, tetheringEnabled); 1003 } 1004 if (!tetheringEnabled) return; 1005 1006 mTetheringManager.stopTethering(TETHERING_WIFI); 1007 Slogf.i(TAG, "Tethering has been disabled and the last setting was saved"); 1008 } 1009 saveWifiModifiedState(AtomicFile file, boolean forciblyDisabled)1010 private void saveWifiModifiedState(AtomicFile file, boolean forciblyDisabled) { 1011 FileOutputStream fos; 1012 try { 1013 fos = file.startWrite(); 1014 } catch (IOException e) { 1015 Slogf.e(TAG, e, "Cannot create %s", file); 1016 return; 1017 } 1018 1019 try (BufferedWriter writer = new BufferedWriter( 1020 new OutputStreamWriter(fos, StandardCharsets.UTF_8))) { 1021 writer.write(forciblyDisabled ? COMPONENT_STATE_MODIFIED : COMPONENT_STATE_ORIGINAL); 1022 writer.newLine(); 1023 writer.flush(); 1024 file.finishWrite(fos); 1025 } catch (IOException e) { 1026 file.failWrite(fos); 1027 Slogf.e(TAG, e, "Writing %s failed", file); 1028 } 1029 } 1030 readWifiModifiedState(AtomicFile file)1031 private boolean readWifiModifiedState(AtomicFile file) { 1032 boolean needToRestore = false; 1033 boolean invalidState = false; 1034 1035 try (BufferedReader reader = new BufferedReader( 1036 new InputStreamReader(file.openRead(), StandardCharsets.UTF_8))) { 1037 String line = reader.readLine(); 1038 if (line == null) { 1039 needToRestore = false; 1040 invalidState = true; 1041 } else { 1042 line = line.trim(); 1043 needToRestore = COMPONENT_STATE_MODIFIED.equals(line); 1044 invalidState = !(needToRestore || COMPONENT_STATE_ORIGINAL.equals(line)); 1045 } 1046 } catch (IOException e) { 1047 // If a file named wifi_state doesn't exist, we will not modify Wifi at system start. 1048 Slogf.w(TAG, "Failed to read %s: %s", file, e); 1049 return false; 1050 } 1051 if (invalidState) { 1052 file.delete(); 1053 } 1054 1055 return needToRestore; 1056 } 1057 startTethering()1058 private void startTethering() { 1059 TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI) 1060 .setShouldShowEntitlementUi(false).build(); 1061 mTetheringManager.startTethering(request, mContext.getMainExecutor(), 1062 new TetheringManager.StartTetheringCallback() { 1063 @Override 1064 public void onTetheringFailed(int error) { 1065 Slogf.w(TAG, "Starting tethering failed: %d", error); 1066 } 1067 }); 1068 } 1069 waitForShutdownPrepareListenersToComplete(long timeoutMs, long intervalMs)1070 private void waitForShutdownPrepareListenersToComplete(long timeoutMs, long intervalMs) { 1071 int state = CarPowerManager.STATE_SHUTDOWN_PREPARE; 1072 Runnable taskAtCompletion = () -> { 1073 finishShutdownPrepare(); 1074 Slogf.i(TAG, "All listeners completed for %s", powerStateToString(state)); 1075 }; 1076 1077 waitForCompletionWithShutdownPostpone(state, timeoutMs, taskAtCompletion, intervalMs); 1078 1079 // allowUserSwitch value doesn't matter for onSuspend = true 1080 mUserService.onSuspend(); 1081 } 1082 waitForCompletion(Runnable taskAtCompletion, Runnable taskAtInterval, long timeoutMs, long intervalMs)1083 private void waitForCompletion(Runnable taskAtCompletion, Runnable taskAtInterval, 1084 long timeoutMs, long intervalMs) { 1085 boolean isComplete = false; 1086 synchronized (mLock) { 1087 isComplete = mListenersWeAreWaitingFor.isEmpty(); 1088 } 1089 if (isComplete) { 1090 taskAtCompletion.run(); 1091 } else { 1092 // Reset a flag to signal that waiting for completion is cancelled. 1093 mIsListenerWaitingCancelled.set(false); 1094 waitForCompletionAsync(taskAtCompletion, taskAtInterval, timeoutMs, intervalMs); 1095 } 1096 } 1097 1098 // Waits for listeners to complete. 1099 // If {@code intervalMs} is non-positive value, it is ignored and the method waits up to 1100 // {@code timeoutMs}. waitForCompletionAsync(Runnable taskAtCompletion, Runnable taskAtInterval, long timeoutMs, long intervalMs)1101 private void waitForCompletionAsync(Runnable taskAtCompletion, Runnable taskAtInterval, 1102 long timeoutMs, long intervalMs) { 1103 ExecutorService executor = Executors.newSingleThreadExecutor(); 1104 executor.submit(() -> { 1105 long startTimeMs = SystemClock.elapsedRealtime(); 1106 while (true) { 1107 try { 1108 long waitTimeMs = timeoutMs - (SystemClock.elapsedRealtime() - startTimeMs); 1109 boolean isLastWait = true; 1110 if (intervalMs > 0 && waitTimeMs > intervalMs) { 1111 isLastWait = false; 1112 waitTimeMs = intervalMs; 1113 } 1114 boolean isNotified = mListenerCompletionSem.tryAcquire(waitTimeMs, 1115 TimeUnit.MILLISECONDS); 1116 mListenerCompletionSem.drainPermits(); 1117 if (!isNotified) { 1118 if (isLastWait) { 1119 Slogf.w(TAG, "Waiting for listener completion is timeout(%d)", 1120 waitTimeMs); 1121 taskAtCompletion.run(); 1122 return; 1123 } else if (taskAtInterval != null) { 1124 taskAtInterval.run(); 1125 } 1126 } 1127 boolean isComplete = false; 1128 synchronized (mLock) { 1129 if (mIsListenerWaitingCancelled.get()) { 1130 Slogf.i(TAG, "Waiting for listener completion is cancelled"); 1131 mIsListenerWaitingCancelled.set(false); 1132 return; 1133 } 1134 isComplete = mListenersWeAreWaitingFor.isEmpty(); 1135 } 1136 if (isComplete) { 1137 Slogf.i(TAG, "All listeners completed"); 1138 taskAtCompletion.run(); 1139 mIsListenerWaitingCancelled.set(false); 1140 return; 1141 } 1142 } catch (InterruptedException e) { 1143 Slogf.w(TAG, e, "Thread interrupted while waiting for listener completion"); 1144 Thread.currentThread().interrupt(); 1145 } 1146 } 1147 }); 1148 executor.shutdown(); 1149 } 1150 clearWaitingForCompletion(boolean clearQueue)1151 private void clearWaitingForCompletion(boolean clearQueue) { 1152 if (clearQueue) { 1153 synchronized (mLock) { 1154 mListenersWeAreWaitingFor.clear(); 1155 } 1156 } else { 1157 mIsListenerWaitingCancelled.set(true); 1158 } 1159 1160 mListenerCompletionSem.release(); 1161 } 1162 sendPowerManagerEvent(@arPowerManager.CarPowerState int newState, long timeoutMs)1163 private void sendPowerManagerEvent(@CarPowerManager.CarPowerState int newState, 1164 long timeoutMs) { 1165 // Broadcasts to the listeners that do not signal completion. 1166 notifyListeners(mPowerManagerListeners, newState, INVALID_TIMEOUT); 1167 1168 boolean allowCompletion = false; 1169 boolean isShutdownPrepare = newState == CarPowerManager.STATE_SHUTDOWN_PREPARE; 1170 long internalListenerExpirationTimeMs = INVALID_TIMEOUT; 1171 long binderListenerExpirationTimeMs = INVALID_TIMEOUT; 1172 1173 // Fully populates mListenersWeAreWaitingFor before calling any onStateChanged() 1174 // for the listeners that signal completion. 1175 // Otherwise, if the first listener calls finish() synchronously, we will 1176 // see the list go empty and we will think that we are done. 1177 PowerManagerCallbackList<ICarPowerStateListener> completingInternalListeners = 1178 new PowerManagerCallbackList(l -> { }); 1179 PowerManagerCallbackList<ICarPowerStateListener> completingBinderListeners = 1180 new PowerManagerCallbackList(l -> { }); 1181 synchronized (mLock) { 1182 if (isCompletionAllowed(newState)) { 1183 if (timeoutMs < 0) { 1184 Slogf.wtf(TAG, "Completion timeout(%d) for state(%d) should be " 1185 + "non-negative", timeoutMs, newState); 1186 return; 1187 } 1188 mStateForCompletion = newState; 1189 allowCompletion = true; 1190 internalListenerExpirationTimeMs = SystemClock.elapsedRealtime() + timeoutMs; 1191 binderListenerExpirationTimeMs = 1192 isShutdownPrepare ? INVALID_TIMEOUT : internalListenerExpirationTimeMs; 1193 } else { 1194 mStateForCompletion = CarPowerManager.STATE_INVALID; 1195 } 1196 1197 mListenersWeAreWaitingFor.clear(); 1198 for (int i = 0; i < mInternalPowerListeners.size(); i++) { 1199 ICarPowerStateListener listener = mInternalPowerListeners.get(i); 1200 completingInternalListeners.register(listener); 1201 if (allowCompletion) { 1202 mListenersWeAreWaitingFor.add(listener.asBinder()); 1203 } 1204 } 1205 int idx = mPowerManagerListenersWithCompletion.beginBroadcast(); 1206 while (idx-- > 0) { 1207 ICarPowerStateListener listener = 1208 mPowerManagerListenersWithCompletion.getBroadcastItem(idx); 1209 completingBinderListeners.register(listener); 1210 // For binder listeners, listener completion is not allowed for SHUTDOWN_PREPARE. 1211 if (allowCompletion && !isShutdownPrepare) { 1212 mListenersWeAreWaitingFor.add(listener.asBinder()); 1213 } 1214 } 1215 mPowerManagerListenersWithCompletion.finishBroadcast(); 1216 } 1217 // Resets the semaphore's available permits to 0. 1218 mListenerCompletionSem.drainPermits(); 1219 // Broadcasts to the listeners that DO signal completion. 1220 notifyListeners(completingInternalListeners, newState, internalListenerExpirationTimeMs); 1221 notifyListeners(completingBinderListeners, newState, binderListenerExpirationTimeMs); 1222 } 1223 notifyListeners(PowerManagerCallbackList<ICarPowerStateListener> listenerList, @CarPowerManager.CarPowerState int newState, long expirationTimeMs)1224 private void notifyListeners(PowerManagerCallbackList<ICarPowerStateListener> listenerList, 1225 @CarPowerManager.CarPowerState int newState, long expirationTimeMs) { 1226 int idx = listenerList.beginBroadcast(); 1227 while (idx-- > 0) { 1228 ICarPowerStateListener listener = listenerList.getBroadcastItem(idx); 1229 try { 1230 listener.onStateChanged(newState, expirationTimeMs); 1231 } catch (RemoteException e) { 1232 // It's likely the connection snapped. Let binder death handle the situation. 1233 Slogf.e(TAG, e, "onStateChanged() call failed"); 1234 } 1235 } 1236 listenerList.finishBroadcast(); 1237 } 1238 doHandleDeepSleep(boolean simulatedMode)1239 private void doHandleDeepSleep(boolean simulatedMode) { 1240 int status = applyPreemptivePowerPolicy(PolicyReader.POWER_POLICY_ID_SUSPEND_PREP); 1241 if (status != PolicyOperationStatus.OK) { 1242 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(status)); 1243 } 1244 // Keeps holding partial wakelock to prevent entering sleep before enterDeepSleep call. 1245 // enterDeepSleep should force sleep entry even if wake lock is kept. 1246 mSystemInterface.switchToPartialWakeLock(); 1247 mHandler.cancelProcessingComplete(); 1248 synchronized (mLock) { 1249 mLastSleepEntryTime = SystemClock.elapsedRealtime(); 1250 } 1251 @CarPowerManager.CarPowerState int nextListenerState; 1252 if (simulatedMode) { 1253 simulateSleepByWaiting(); 1254 nextListenerState = CarPowerManager.STATE_SHUTDOWN_CANCELLED; 1255 } else { 1256 boolean sleepSucceeded = suspendWithRetries(); 1257 if (!sleepSucceeded) { 1258 // Suspend failed and we shut down instead. 1259 // We either won't get here at all or we will power off very soon. 1260 return; 1261 } 1262 synchronized (mLock) { 1263 // We suspended and have now resumed 1264 nextListenerState = (mActionOnFinish == ACTION_ON_FINISH_DEEP_SLEEP) 1265 ? CarPowerManager.STATE_SUSPEND_EXIT 1266 : CarPowerManager.STATE_HIBERNATION_EXIT; 1267 } 1268 } 1269 synchronized (mLock) { 1270 // Any wakeup time from before is no longer valid. 1271 mNextWakeupSec = 0; 1272 } 1273 Slogf.i(TAG, "Resuming after suspending"); 1274 mSystemInterface.refreshDisplayBrightness(); 1275 onApPowerStateChange(CpmsState.WAIT_FOR_VHAL, nextListenerState); 1276 } 1277 1278 @GuardedBy("mLock") needPowerStateChangeLocked(@onNull CpmsState newState)1279 private boolean needPowerStateChangeLocked(@NonNull CpmsState newState) { 1280 if (mCurrentState == null) { 1281 return true; 1282 } else if (mCurrentState.equals(newState)) { 1283 Slogf.d(TAG, "Requested state is already in effect: %s", newState.name()); 1284 return false; 1285 } 1286 1287 // The following switch/case enforces the allowed state transitions. 1288 boolean transitionAllowed = false; 1289 switch (mCurrentState.mState) { 1290 case CpmsState.WAIT_FOR_VHAL: 1291 transitionAllowed = (newState.mState == CpmsState.ON) 1292 || (newState.mState == CpmsState.SHUTDOWN_PREPARE); 1293 break; 1294 case CpmsState.SUSPEND: 1295 transitionAllowed = newState.mState == CpmsState.WAIT_FOR_VHAL; 1296 break; 1297 case CpmsState.ON: 1298 transitionAllowed = (newState.mState == CpmsState.SHUTDOWN_PREPARE) 1299 || (newState.mState == CpmsState.SIMULATE_SLEEP) 1300 || (newState.mState == CpmsState.SIMULATE_HIBERNATION); 1301 break; 1302 case CpmsState.SHUTDOWN_PREPARE: 1303 // If VHAL sends SHUTDOWN_IMMEDIATELY or SLEEP_IMMEDIATELY while in 1304 // SHUTDOWN_PREPARE state, do it. 1305 transitionAllowed = 1306 ((newState.mState == CpmsState.SHUTDOWN_PREPARE) && !newState.mCanPostpone) 1307 || (newState.mState == CpmsState.WAIT_FOR_FINISH) 1308 || (newState.mState == CpmsState.WAIT_FOR_VHAL); 1309 break; 1310 case CpmsState.SIMULATE_SLEEP: 1311 case CpmsState.SIMULATE_HIBERNATION: 1312 transitionAllowed = true; 1313 break; 1314 case CpmsState.WAIT_FOR_FINISH: 1315 transitionAllowed = (newState.mState == CpmsState.SUSPEND 1316 || newState.mState == CpmsState.WAIT_FOR_VHAL); 1317 break; 1318 default: 1319 Slogf.e(TAG, "Unexpected current state: currentState=%s, newState=%s", 1320 mCurrentState.name(), newState.name()); 1321 transitionAllowed = true; 1322 } 1323 if (!transitionAllowed) { 1324 Slogf.e(TAG, "Requested power transition is not allowed: %s --> %s", 1325 mCurrentState.name(), newState.name()); 1326 } 1327 return transitionAllowed; 1328 } 1329 doHandleProcessingComplete()1330 private void doHandleProcessingComplete() { 1331 int listenerState = CarPowerManager.STATE_SHUTDOWN_ENTER; 1332 synchronized (mLock) { 1333 clearWaitingForCompletion(/*clearQueue=*/false); 1334 boolean shutdownOnFinish = (mActionOnFinish == ACTION_ON_FINISH_SHUTDOWN); 1335 if (!shutdownOnFinish && mLastSleepEntryTime > mShutdownStartTime) { 1336 // entered sleep after processing start. So this could be duplicate request. 1337 Slogf.w(TAG, "Duplicate sleep entry request, ignore"); 1338 return; 1339 } 1340 if (shutdownOnFinish) { 1341 listenerState = CarPowerManager.STATE_SHUTDOWN_ENTER; 1342 } else if (mActionOnFinish == ACTION_ON_FINISH_DEEP_SLEEP) { 1343 listenerState = CarPowerManager.STATE_SUSPEND_ENTER; 1344 } else if (mActionOnFinish == ACTION_ON_FINISH_HIBERNATION) { 1345 listenerState = CarPowerManager.STATE_HIBERNATION_ENTER; 1346 } 1347 } 1348 1349 onApPowerStateChange(CpmsState.WAIT_FOR_FINISH, listenerState); 1350 } 1351 1352 @Override onDisplayBrightnessChange(int brightness)1353 public void onDisplayBrightnessChange(int brightness) { 1354 mHandler.handleDisplayBrightnessChange(brightness); 1355 } 1356 doHandleDisplayBrightnessChange(int brightness)1357 private void doHandleDisplayBrightnessChange(int brightness) { 1358 mSystemInterface.setDisplayBrightness(brightness); 1359 } 1360 doHandleMainDisplayStateChange(boolean on)1361 private void doHandleMainDisplayStateChange(boolean on) { 1362 Slogf.w(TAG, "Unimplemented: doHandleMainDisplayStateChange() - on = %b", on); 1363 } 1364 doHandlePowerPolicyNotification(String policyId)1365 private void doHandlePowerPolicyNotification(String policyId) { 1366 // Sending notification of power policy change triggered through CarPowerManager API. 1367 notifyPowerPolicyChange(policyId, /* upToDaemon= */ true, /* force= */ false); 1368 } 1369 1370 /** 1371 * Handles when a main display changes. 1372 */ handleMainDisplayChanged(boolean on)1373 public void handleMainDisplayChanged(boolean on) { 1374 mHandler.handleMainDisplayStateChange(on); 1375 } 1376 1377 /** 1378 * Sends display brightness to VHAL. 1379 * @param brightness value 0-100% 1380 */ sendDisplayBrightness(int brightness)1381 public void sendDisplayBrightness(int brightness) { 1382 mHal.sendDisplayBrightness(brightness); 1383 } 1384 1385 /** 1386 * Gets the PowerHandler that we use to change power states 1387 */ getHandler()1388 public Handler getHandler() { 1389 return mHandler; 1390 1391 } 1392 1393 /** 1394 * Registers power state change listeners running in CarService, which is not a binder 1395 * interfaces. 1396 */ registerInternalListener(ICarPowerStateListener listener)1397 public void registerInternalListener(ICarPowerStateListener listener) { 1398 CarServiceUtils.assertCallingFromSystemProcessOrSelf(); 1399 synchronized (mLock) { 1400 mInternalPowerListeners.add(listener); 1401 } 1402 } 1403 1404 /** 1405 * Unregisters power state change listeners running in CarService, which is not a binder 1406 * interface. 1407 */ unregisterInternalListener(ICarPowerStateListener listener)1408 public void unregisterInternalListener(ICarPowerStateListener listener) { 1409 CarServiceUtils.assertCallingFromSystemProcessOrSelf(); 1410 boolean found = false; 1411 synchronized (mLock) { 1412 found = mInternalPowerListeners.remove(listener); 1413 } 1414 if (found) { 1415 removeListenerFromWaitingList(listener.asBinder()); 1416 } 1417 } 1418 1419 /** 1420 * Tells {@link CarPowerManagementService} that the listener running in CarService completes 1421 * handling power state change. 1422 */ completeHandlingPowerStateChange(int state, ICarPowerStateListener listener)1423 public void completeHandlingPowerStateChange(int state, ICarPowerStateListener listener) { 1424 CarServiceUtils.assertCallingFromSystemProcessOrSelf(); 1425 handleListenerCompletion(state, listener, 1426 new ArraySet(new Integer[] {CarPowerManager.STATE_INVALID})); 1427 } 1428 1429 // Binder interface for general use. 1430 // The listener is not required (or allowed) to call finished(). 1431 @Override registerListener(ICarPowerStateListener listener)1432 public void registerListener(ICarPowerStateListener listener) { 1433 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 1434 mPowerManagerListeners.register(listener); 1435 } 1436 1437 // Binder interface for Car services only. 1438 // After the listener completes its processing, it must call finished(). 1439 @Override registerListenerWithCompletion(ICarPowerStateListener listener)1440 public void registerListenerWithCompletion(ICarPowerStateListener listener) { 1441 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CONTROL_SHUTDOWN_PROCESS); 1442 1443 mPowerManagerListenersWithCompletion.register(listener); 1444 // TODO: Need to send current state to newly registered listener? If so, need to handle 1445 // completion for SHUTDOWN_PREPARE state 1446 } 1447 1448 @Override unregisterListener(ICarPowerStateListener listener)1449 public void unregisterListener(ICarPowerStateListener listener) { 1450 CarServiceUtils.assertAnyPermission(mContext, Car.PERMISSION_CAR_POWER, 1451 Car.PERMISSION_CONTROL_SHUTDOWN_PROCESS); 1452 doUnregisterListener(listener); 1453 } 1454 1455 @Override requestShutdownOnNextSuspend()1456 public void requestShutdownOnNextSuspend() { 1457 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 1458 synchronized (mLock) { 1459 mShutdownOnNextSuspend = true; 1460 } 1461 } 1462 1463 @Override finished(int state, ICarPowerStateListener listener)1464 public void finished(int state, ICarPowerStateListener listener) { 1465 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CONTROL_SHUTDOWN_PROCESS); 1466 handleListenerCompletion(state, listener, new ArraySet(new Integer[] 1467 {CarPowerManager.STATE_INVALID, CarPowerManager.STATE_SHUTDOWN_PREPARE})); 1468 } 1469 1470 @Override scheduleNextWakeupTime(int seconds)1471 public void scheduleNextWakeupTime(int seconds) { 1472 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 1473 if (seconds < 0) { 1474 Slogf.w(TAG, "Next wake up time is negative. Ignoring!"); 1475 return; 1476 } 1477 boolean timedWakeupAllowed = mHal.isTimedWakeupAllowed(); 1478 synchronized (mLock) { 1479 if (!timedWakeupAllowed) { 1480 Slogf.w(TAG, "Setting timed wakeups are disabled in HAL. Skipping"); 1481 mNextWakeupSec = 0; 1482 return; 1483 } 1484 if (mNextWakeupSec == 0 || mNextWakeupSec > seconds) { 1485 // The new value is sooner than the old value. Take the new value. 1486 mNextWakeupSec = seconds; 1487 } else { 1488 Slogf.d(TAG, "Tried to schedule next wake up, but already had shorter " 1489 + "scheduled time"); 1490 } 1491 } 1492 } 1493 1494 @Override getPowerState()1495 public @CarPowerManager.CarPowerState int getPowerState() { 1496 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 1497 synchronized (mLock) { 1498 return (mCurrentState == null) ? CarPowerManager.STATE_INVALID 1499 : mCurrentState.mCarPowerStateListenerState; 1500 } 1501 } 1502 1503 /** 1504 * @see android.car.hardware.power.CarPowerManager#getCurrentPowerPolicy 1505 */ 1506 @Override getCurrentPowerPolicy()1507 public CarPowerPolicy getCurrentPowerPolicy() { 1508 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_READ_CAR_POWER_POLICY); 1509 return mPowerComponentHandler.getAccumulatedPolicy(); 1510 } 1511 1512 /** 1513 * @see android.car.hardware.power.CarPowerManager#applyPowerPolicy 1514 */ 1515 @Override applyPowerPolicy(String policyId)1516 public void applyPowerPolicy(String policyId) { 1517 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CONTROL_CAR_POWER_POLICY); 1518 Preconditions.checkArgument(policyId != null, "policyId cannot be null"); 1519 Preconditions.checkArgument(!policyId.startsWith(PolicyReader.SYSTEM_POWER_POLICY_PREFIX), 1520 "System power policy cannot be applied by apps"); 1521 int status = applyPowerPolicy(policyId, /* delayNotification= */ true, 1522 /* upToDaemon= */ true, /* force= */ false); 1523 if (status != PolicyOperationStatus.OK) { 1524 throw new IllegalArgumentException(PolicyOperationStatus.errorCodeToString(status)); 1525 } 1526 Slogf.d(TAG, "Queueing power policy notification (id: %s) in the handler", policyId); 1527 mHandler.handlePowerPolicyNotification(policyId); 1528 } 1529 1530 /** 1531 * @see android.car.hardware.power.CarPowerManager#setPowerPolicyGroup 1532 */ 1533 @Override setPowerPolicyGroup(String policyGroupId)1534 public void setPowerPolicyGroup(String policyGroupId) { 1535 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CONTROL_CAR_POWER_POLICY); 1536 Preconditions.checkArgument(policyGroupId != null, "policyGroupId cannot be null"); 1537 int status = setCurrentPowerPolicyGroup(policyGroupId); 1538 if (status != PolicyOperationStatus.OK) { 1539 throw new IllegalArgumentException(PolicyOperationStatus.errorCodeToString(status)); 1540 } 1541 } 1542 1543 /** 1544 * @see android.car.hardware.power.CarPowerManager#addPowerPolicyListener 1545 */ 1546 @Override addPowerPolicyListener(CarPowerPolicyFilter filter, ICarPowerPolicyListener listener)1547 public void addPowerPolicyListener(CarPowerPolicyFilter filter, 1548 ICarPowerPolicyListener listener) { 1549 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_READ_CAR_POWER_POLICY); 1550 mPowerPolicyListeners.register(listener, filter); 1551 } 1552 1553 /** 1554 * @see android.car.hardware.power.CarPowerManager#removePowerPolicyListener 1555 */ 1556 @Override removePowerPolicyListener(ICarPowerPolicyListener listener)1557 public void removePowerPolicyListener(ICarPowerPolicyListener listener) { 1558 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_READ_CAR_POWER_POLICY); 1559 mPowerPolicyListeners.unregister(listener); 1560 } 1561 notifySilentModeChange(boolean silent)1562 void notifySilentModeChange(boolean silent) { 1563 Slogf.i(TAG, "Silent mode is set to %b", silent); 1564 if (silent) { 1565 applyPreemptivePowerPolicy(PolicyReader.POWER_POLICY_ID_NO_USER_INTERACTION); 1566 } else { 1567 cancelPreemptivePowerPolicy(); 1568 } 1569 } 1570 handleListenerCompletion(int state, ICarPowerStateListener listener, ArraySet<Integer> notAllowedStates)1571 private void handleListenerCompletion(int state, ICarPowerStateListener listener, 1572 ArraySet<Integer> notAllowedStates) { 1573 synchronized (mLock) { 1574 if (notAllowedStates.contains(mStateForCompletion)) { 1575 Slogf.w(TAG, "The current state(%d) doesn't allow listener completion", 1576 mStateForCompletion); 1577 return; 1578 } 1579 if (state != mStateForCompletion) { 1580 Slogf.w(TAG, "Given state(%d) doesn't match the current state(%d) for completion", 1581 state, mStateForCompletion); 1582 return; 1583 } 1584 } 1585 removeListenerFromWaitingList(listener.asBinder()); 1586 } 1587 1588 doUnregisterListener(ICarPowerStateListener listener)1589 private void doUnregisterListener(ICarPowerStateListener listener) { 1590 mPowerManagerListeners.unregister(listener); 1591 boolean found = mPowerManagerListenersWithCompletion.unregister(listener); 1592 if (found) { 1593 // Remove this from the completion list (if it's there) 1594 removeListenerFromWaitingList(listener.asBinder()); 1595 } 1596 } 1597 removeListenerFromWaitingList(IBinder binderListener)1598 private void removeListenerFromWaitingList(IBinder binderListener) { 1599 synchronized (mLock) { 1600 mListenersWeAreWaitingFor.remove(binderListener); 1601 } 1602 // Signals a thread to check if all listeners complete. 1603 mListenerCompletionSem.release(); 1604 } 1605 finishShutdownPrepare()1606 private void finishShutdownPrepare() { 1607 boolean shouldHandleProcessingComplete = false; 1608 synchronized (mLock) { 1609 if (mCurrentState != null 1610 && (mCurrentState.mState == CpmsState.SHUTDOWN_PREPARE 1611 || mCurrentState.mState == CpmsState.SIMULATE_SLEEP 1612 || mCurrentState.mState == CpmsState.SIMULATE_HIBERNATION)) { 1613 // All apps are ready to shutdown/suspend. 1614 if (mActionOnFinish != ACTION_ON_FINISH_SHUTDOWN) { 1615 if (mLastSleepEntryTime > mShutdownStartTime 1616 && mLastSleepEntryTime < SystemClock.elapsedRealtime()) { 1617 Slogf.d(TAG, "finishShutdownPrepare: Already slept!"); 1618 return; 1619 } 1620 } 1621 shouldHandleProcessingComplete = true; 1622 } 1623 } 1624 1625 if (shouldHandleProcessingComplete) { 1626 Slogf.i(TAG, "Apps are finished, call handleProcessingComplete()"); 1627 mHandler.handleProcessingComplete(); 1628 } 1629 } 1630 initializePowerPolicy()1631 private void initializePowerPolicy() { 1632 Slogf.i(TAG, "CPMS is taking control from carpowerpolicyd"); 1633 ICarPowerPolicySystemNotification daemon; 1634 synchronized (mLock) { 1635 daemon = mCarPowerPolicyDaemon; 1636 } 1637 PolicyState state; 1638 if (daemon != null) { 1639 try { 1640 state = daemon.notifyCarServiceReady(); 1641 } catch (RemoteException e) { 1642 Slogf.e(TAG, e, "Failed to tell car power policy daemon that CarService is ready"); 1643 return; 1644 } 1645 } else { 1646 Slogf.w(TAG, "Failed to notify car service is ready. car power policy daemon is not " 1647 + "available"); 1648 return; 1649 } 1650 1651 String currentPowerPolicyId; 1652 String currentPolicyGroupId; 1653 synchronized (mLock) { 1654 mHasControlOverDaemon = true; 1655 currentPowerPolicyId = mCurrentPowerPolicyId; 1656 currentPolicyGroupId = mCurrentPowerPolicyGroupId; 1657 } 1658 // If the current power policy or the policy group has been modified by CPMS, we ignore 1659 // the power policy or the policy group passed from car power policy daemon, and notifies 1660 // the current power policy to the daemon. 1661 if (currentPowerPolicyId == null || currentPowerPolicyId.isEmpty()) { 1662 Slogf.i(TAG, "Attempting to apply the power policy(%s) from the daemon", 1663 state.policyId); 1664 int status = applyPowerPolicy(state.policyId, /* delayNotification= */ false, 1665 /* upToDaemon= */ false, /* force= */ false); 1666 if (status != PolicyOperationStatus.OK) { 1667 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(status)); 1668 } 1669 } else { 1670 Slogf.i(TAG, "CPMS applied power policy(%s) before connecting to the daemon. Notifying " 1671 + "to the daemon...", currentPowerPolicyId); 1672 notifyPowerPolicyChangeToDaemon(currentPowerPolicyId, /* force= */ true); 1673 } 1674 if (currentPolicyGroupId == null || currentPolicyGroupId.isEmpty()) { 1675 int status = setCurrentPowerPolicyGroup(state.policyGroupId); 1676 if (status != PolicyOperationStatus.OK) { 1677 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(status)); 1678 } 1679 } 1680 mSilentModeHandler.init(); 1681 } 1682 1683 @PolicyOperationStatus.ErrorCode setCurrentPowerPolicyGroup(String policyGroupId)1684 private int setCurrentPowerPolicyGroup(String policyGroupId) { 1685 if (!mPolicyReader.isPowerPolicyGroupAvailable(policyGroupId)) { 1686 int error = PolicyOperationStatus.ERROR_SET_POWER_POLICY_GROUP; 1687 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error, 1688 policyGroupId + " is not registered")); 1689 return error; 1690 } 1691 synchronized (mLock) { 1692 mCurrentPowerPolicyGroupId = policyGroupId; 1693 } 1694 return PolicyOperationStatus.OK; 1695 } 1696 1697 @PolicyOperationStatus.ErrorCode applyPowerPolicy(@ullable String policyId, boolean delayNotification, boolean upToDaemon, boolean force)1698 private int applyPowerPolicy(@Nullable String policyId, boolean delayNotification, 1699 boolean upToDaemon, boolean force) { 1700 CarPowerPolicy policy = mPolicyReader.getPowerPolicy(policyId); 1701 if (policy == null) { 1702 int error = PolicyOperationStatus.ERROR_NOT_REGISTERED_POWER_POLICY_ID; 1703 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error, policyId)); 1704 return error; 1705 } 1706 synchronized (mLock) { 1707 if (mIsPowerPolicyLocked) { 1708 Slogf.i(TAG, "Power policy is locked. The request policy(%s) will be applied when " 1709 + "power policy becomes unlocked", policyId); 1710 mPendingPowerPolicyId = policyId; 1711 return PolicyOperationStatus.OK; 1712 } 1713 mCurrentPowerPolicyId = policyId; 1714 } 1715 mPowerComponentHandler.applyPowerPolicy(policy); 1716 if (!delayNotification) { 1717 notifyPowerPolicyChange(policyId, upToDaemon, force); 1718 } 1719 Slogf.i(TAG, "The current power policy is %s", policyId); 1720 return PolicyOperationStatus.OK; 1721 } 1722 1723 @PolicyOperationStatus.ErrorCode applyPreemptivePowerPolicy(String policyId)1724 private int applyPreemptivePowerPolicy(String policyId) { 1725 CarPowerPolicy policy = mPolicyReader.getPreemptivePowerPolicy(policyId); 1726 if (policy == null) { 1727 int error = PolicyOperationStatus.ERROR_NOT_REGISTERED_POWER_POLICY_ID; 1728 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error, policyId)); 1729 return error; 1730 } 1731 synchronized (mLock) { 1732 mIsPowerPolicyLocked = true; 1733 if (!mPolicyReader.isPreemptivePowerPolicy(mCurrentPowerPolicyId)) { 1734 mPendingPowerPolicyId = mCurrentPowerPolicyId; 1735 } 1736 mCurrentPowerPolicyId = policyId; 1737 } 1738 mPowerComponentHandler.applyPowerPolicy(policy); 1739 notifyPowerPolicyChange(policyId, /* upToDaemon= */ true, /* force= */ true); 1740 Slogf.i(TAG, "The current power policy is %s", policyId); 1741 return PolicyOperationStatus.OK; 1742 } 1743 cancelPreemptivePowerPolicy()1744 private void cancelPreemptivePowerPolicy() { 1745 String policyId; 1746 synchronized (mLock) { 1747 if (!mIsPowerPolicyLocked) { 1748 Slogf.w(TAG, "Failed to cancel system power policy: the current policy is not the " 1749 + "system power policy"); 1750 return; 1751 } 1752 mIsPowerPolicyLocked = false; 1753 policyId = mPendingPowerPolicyId; 1754 mPendingPowerPolicyId = null; 1755 } 1756 if (policyId != null) { // Pending policy exist 1757 int status = applyPowerPolicy(policyId, /* delayNotification= */ false, 1758 /* upToDaemon= */ true, /* force= */ true); 1759 if (status != PolicyOperationStatus.OK) { 1760 Slogf.w(TAG, "Failed to cancel system power policy: %s", 1761 PolicyOperationStatus.errorCodeToString(status)); 1762 } 1763 } else { 1764 Slogf.w(TAG, "cancelPreemptivePowerPolicy(), no pending power policy"); 1765 } 1766 } 1767 notifyPowerPolicyChangeToDaemon(String policyId, boolean force)1768 private void notifyPowerPolicyChangeToDaemon(String policyId, boolean force) { 1769 ICarPowerPolicySystemNotification daemon; 1770 boolean hadPendingPolicyNotification; 1771 synchronized (mLock) { 1772 daemon = mCarPowerPolicyDaemon; 1773 if (daemon == null) { 1774 Slogf.e(TAG, "Failed to notify car power policy daemon: the daemon is not ready"); 1775 return; 1776 } 1777 if (!mHasControlOverDaemon) { 1778 Slogf.w(TAG, "Notifying policy change is deferred: CPMS has not yet taken control"); 1779 return; 1780 } 1781 } 1782 try { 1783 daemon.notifyPowerPolicyChange(policyId, force); 1784 } catch (RemoteException | IllegalStateException e) { 1785 Slogf.e(TAG, e, "Failed to notify car power policy daemon of a new power policy(%s)", 1786 policyId); 1787 } 1788 } 1789 notifyPowerPolicyChange(String policyId, boolean upToDaemon, boolean force)1790 private void notifyPowerPolicyChange(String policyId, boolean upToDaemon, boolean force) { 1791 EventLogHelper.writePowerPolicyChange(policyId); 1792 // Notify system clients 1793 if (upToDaemon) { 1794 notifyPowerPolicyChangeToDaemon(policyId, force); 1795 } 1796 1797 // Notify Java clients 1798 CarPowerPolicy accumulatedPolicy = mPowerComponentHandler.getAccumulatedPolicy(); 1799 CarPowerPolicy appliedPolicy = mPolicyReader.isPreemptivePowerPolicy(policyId) 1800 ? mPolicyReader.getPreemptivePowerPolicy(policyId) 1801 : mPolicyReader.getPowerPolicy(policyId); 1802 if (appliedPolicy == null) { 1803 Slogf.wtf(TAG, "The new power policy(%s) should exist", policyId); 1804 } 1805 int idx = mPowerPolicyListeners.beginBroadcast(); 1806 while (idx-- > 0) { 1807 ICarPowerPolicyListener listener = mPowerPolicyListeners.getBroadcastItem(idx); 1808 CarPowerPolicyFilter filter = 1809 (CarPowerPolicyFilter) mPowerPolicyListeners.getBroadcastCookie(idx); 1810 if (!mPowerComponentHandler.isComponentChanged(filter)) { 1811 continue; 1812 } 1813 try { 1814 listener.onPolicyChanged(appliedPolicy, accumulatedPolicy); 1815 } catch (RemoteException e) { 1816 // It's likely the connection snapped. Let binder death handle the situation. 1817 Slogf.e(TAG, e, "onPolicyChanged() call failed: policyId = %s", policyId); 1818 } 1819 } 1820 mPowerPolicyListeners.finishBroadcast(); 1821 } 1822 makeSureNoUserInteraction()1823 private void makeSureNoUserInteraction() { 1824 mSilentModeHandler.updateKernelSilentMode(true); 1825 int status = applyPreemptivePowerPolicy(PolicyReader.POWER_POLICY_ID_NO_USER_INTERACTION); 1826 if (status != PolicyOperationStatus.OK) { 1827 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(status)); 1828 } 1829 } 1830 connectToPowerPolicyDaemon()1831 private void connectToPowerPolicyDaemon() { 1832 synchronized (mLock) { 1833 if (mCarPowerPolicyDaemon != null || mConnectionInProgress) { 1834 return; 1835 } 1836 mConnectionInProgress = true; 1837 } 1838 connectToDaemonHelper(CAR_POWER_POLICY_DAEMON_BIND_MAX_RETRY); 1839 } 1840 connectToDaemonHelper(int retryCount)1841 private void connectToDaemonHelper(int retryCount) { 1842 if (retryCount <= 0) { 1843 synchronized (mLock) { 1844 mConnectionInProgress = false; 1845 } 1846 Slogf.e(TAG, "Cannot reconnect to car power policyd daemon after retrying %d times", 1847 CAR_POWER_POLICY_DAEMON_BIND_MAX_RETRY); 1848 return; 1849 } 1850 if (makeBinderConnection()) { 1851 Slogf.i(TAG, "Connected to car power policy daemon"); 1852 initializePowerPolicy(); 1853 return; 1854 } 1855 final int numRetry = retryCount - 1; 1856 mHandler.postDelayed(() -> connectToDaemonHelper(numRetry), 1857 CAR_POWER_POLICY_DAEMON_BIND_RETRY_INTERVAL_MS); 1858 } 1859 makeBinderConnection()1860 private boolean makeBinderConnection() { 1861 long currentTimeMs = SystemClock.uptimeMillis(); 1862 IBinder binder = ServiceManagerHelper.getService(CAR_POWER_POLICY_DAEMON_INTERFACE); 1863 if (binder == null) { 1864 Slogf.w(TAG, "Finding car power policy daemon failed. Power policy management is not " 1865 + "supported"); 1866 return false; 1867 } 1868 long elapsedTimeMs = SystemClock.uptimeMillis() - currentTimeMs; 1869 if (elapsedTimeMs > CAR_POWER_POLICY_DAEMON_FIND_MARGINAL_TIME_MS) { 1870 Slogf.wtf(TAG, "Finding car power policy daemon took too long(%dms)", elapsedTimeMs); 1871 } 1872 1873 ICarPowerPolicySystemNotification daemon = 1874 ICarPowerPolicySystemNotification.Stub.asInterface(binder); 1875 if (daemon == null) { 1876 Slogf.w(TAG, "Getting car power policy daemon interface failed. Power policy management" 1877 + " is not supported"); 1878 return false; 1879 } 1880 synchronized (mLock) { 1881 mCarPowerPolicyDaemon = daemon; 1882 mConnectionInProgress = false; 1883 } 1884 mBinderHandler = new BinderHandler(daemon); 1885 mBinderHandler.linkToDeath(); 1886 return true; 1887 } 1888 1889 private final class BinderHandler implements IBinder.DeathRecipient { 1890 private ICarPowerPolicySystemNotification mDaemon; 1891 BinderHandler(ICarPowerPolicySystemNotification daemon)1892 private BinderHandler(ICarPowerPolicySystemNotification daemon) { 1893 mDaemon = daemon; 1894 } 1895 1896 @Override binderDied()1897 public void binderDied() { 1898 Slogf.w(TAG, "Car power policy daemon died: reconnecting"); 1899 unlinkToDeath(); 1900 mDaemon = null; 1901 synchronized (mLock) { 1902 mCarPowerPolicyDaemon = null; 1903 mHasControlOverDaemon = false; 1904 } 1905 mHandler.postDelayed( 1906 () -> connectToDaemonHelper(CAR_POWER_POLICY_DAEMON_BIND_MAX_RETRY), 1907 CAR_POWER_POLICY_DAEMON_BIND_RETRY_INTERVAL_MS); 1908 } 1909 linkToDeath()1910 private void linkToDeath() { 1911 if (mDaemon == null) { 1912 return; 1913 } 1914 IBinder binder = mDaemon.asBinder(); 1915 if (binder == null) { 1916 Slogf.w(TAG, "Linking to binder death recipient skipped"); 1917 return; 1918 } 1919 try { 1920 binder.linkToDeath(this, 0); 1921 } catch (RemoteException e) { 1922 mDaemon = null; 1923 Slogf.w(TAG, e, "Linking to binder death recipient failed: %s"); 1924 } 1925 } 1926 unlinkToDeath()1927 private void unlinkToDeath() { 1928 if (mDaemon == null) { 1929 return; 1930 } 1931 IBinder binder = mDaemon.asBinder(); 1932 if (binder == null) { 1933 Slogf.w(TAG, "Unlinking from binder death recipient skipped"); 1934 return; 1935 } 1936 binder.unlinkToDeath(this, 0); 1937 } 1938 } 1939 1940 private static final class PowerHandler extends Handler { 1941 private static final String TAG = PowerHandler.class.getSimpleName(); 1942 private static final int MSG_POWER_STATE_CHANGE = 0; 1943 private static final int MSG_DISPLAY_BRIGHTNESS_CHANGE = 1; 1944 private static final int MSG_MAIN_DISPLAY_STATE_CHANGE = 2; 1945 private static final int MSG_PROCESSING_COMPLETE = 3; 1946 private static final int MSG_POWER_POLICY_NOTIFICATION = 4; 1947 1948 // Do not handle this immediately but with some delay as there can be a race between 1949 // display off due to rear view camera and delivery to here. 1950 private static final long MAIN_DISPLAY_EVENT_DELAY_MS = 500; 1951 1952 private final WeakReference<CarPowerManagementService> mService; 1953 PowerHandler(Looper looper, CarPowerManagementService service)1954 private PowerHandler(Looper looper, CarPowerManagementService service) { 1955 super(looper); 1956 mService = new WeakReference<CarPowerManagementService>(service); 1957 } 1958 handlePowerStateChange()1959 private void handlePowerStateChange() { 1960 Message msg = obtainMessage(MSG_POWER_STATE_CHANGE); 1961 sendMessage(msg); 1962 } 1963 handleDisplayBrightnessChange(int brightness)1964 private void handleDisplayBrightnessChange(int brightness) { 1965 Message msg = obtainMessage(MSG_DISPLAY_BRIGHTNESS_CHANGE, brightness, 0); 1966 sendMessage(msg); 1967 } 1968 handleMainDisplayStateChange(boolean on)1969 private void handleMainDisplayStateChange(boolean on) { 1970 removeMessages(MSG_MAIN_DISPLAY_STATE_CHANGE); 1971 Message msg = obtainMessage(MSG_MAIN_DISPLAY_STATE_CHANGE, Boolean.valueOf(on)); 1972 sendMessageDelayed(msg, MAIN_DISPLAY_EVENT_DELAY_MS); 1973 } 1974 handleProcessingComplete()1975 private void handleProcessingComplete() { 1976 removeMessages(MSG_PROCESSING_COMPLETE); 1977 Message msg = obtainMessage(MSG_PROCESSING_COMPLETE); 1978 sendMessage(msg); 1979 } 1980 cancelProcessingComplete()1981 private void cancelProcessingComplete() { 1982 removeMessages(MSG_PROCESSING_COMPLETE); 1983 } 1984 handlePowerPolicyNotification(String policyId)1985 private void handlePowerPolicyNotification(String policyId) { 1986 Message msg = obtainMessage(MSG_POWER_POLICY_NOTIFICATION, policyId); 1987 sendMessage(msg); 1988 } 1989 cancelAll()1990 private void cancelAll() { 1991 removeMessages(MSG_POWER_STATE_CHANGE); 1992 removeMessages(MSG_DISPLAY_BRIGHTNESS_CHANGE); 1993 removeMessages(MSG_MAIN_DISPLAY_STATE_CHANGE); 1994 removeMessages(MSG_PROCESSING_COMPLETE); 1995 removeMessages(MSG_POWER_POLICY_NOTIFICATION); 1996 } 1997 1998 @Override handleMessage(Message msg)1999 public void handleMessage(Message msg) { 2000 CarPowerManagementService service = mService.get(); 2001 if (service == null) { 2002 Slogf.i(TAG, "handleMessage null service"); 2003 return; 2004 } 2005 switch (msg.what) { 2006 case MSG_POWER_STATE_CHANGE: 2007 service.doHandlePowerStateChange(); 2008 break; 2009 case MSG_DISPLAY_BRIGHTNESS_CHANGE: 2010 service.doHandleDisplayBrightnessChange(msg.arg1); 2011 break; 2012 case MSG_MAIN_DISPLAY_STATE_CHANGE: 2013 service.doHandleMainDisplayStateChange((Boolean) msg.obj); 2014 break; 2015 case MSG_PROCESSING_COMPLETE: 2016 service.doHandleProcessingComplete(); 2017 break; 2018 case MSG_POWER_POLICY_NOTIFICATION: 2019 service.doHandlePowerPolicyNotification((String) msg.obj); 2020 break; 2021 } 2022 } 2023 } 2024 2025 // Send the command to enter Suspend to RAM. 2026 // If the command is not successful, try again with an exponential back-off. 2027 // If it fails repeatedly, send the command to shut down. 2028 // If we decide to go to a different power state, abort this retry mechanism. 2029 // Returns true if we successfully suspended. suspendWithRetries()2030 private boolean suspendWithRetries() { 2031 boolean isDeepSleep; 2032 synchronized (mLock) { 2033 isDeepSleep = (mActionOnFinish == ACTION_ON_FINISH_DEEP_SLEEP); 2034 } 2035 2036 String suspendTarget = isDeepSleep ? "Suspend-to-RAM" : "Suspend-to-Disk"; 2037 long retryIntervalMs = INITIAL_SUSPEND_RETRY_INTERVAL_MS; 2038 long totalWaitDurationMs = 0; 2039 while (true) { 2040 Slogf.i(TAG, "Entering %s", suspendTarget); 2041 boolean suspendSucceeded = isDeepSleep ? mSystemInterface.enterDeepSleep() 2042 : mSystemInterface.enterHibernation(); 2043 2044 if (suspendSucceeded) { 2045 return true; 2046 } 2047 if (totalWaitDurationMs >= mMaxSuspendWaitDurationMs) { 2048 break; 2049 } 2050 // We failed to suspend. Block the thread briefly and try again. 2051 synchronized (mLock) { 2052 if (!mPendingPowerStates.isEmpty()) { 2053 // Check for a new power state now, before going around the loop again. 2054 CpmsState state = mPendingPowerStates.peekFirst(); 2055 if (state != null && needPowerStateChangeLocked(state)) { 2056 Slogf.i(TAG, "Terminating the attempt to suspend target = %s," 2057 + " currentState = %s, pendingState = %s", suspendTarget, 2058 mCurrentState.stateToString(), state.stateToString()); 2059 return false; 2060 } 2061 } 2062 2063 Slogf.w(TAG, "Failed to Suspend; will retry after %dms", retryIntervalMs); 2064 try { 2065 mLock.wait(retryIntervalMs); 2066 } catch (InterruptedException ignored) { 2067 Thread.currentThread().interrupt(); 2068 } 2069 totalWaitDurationMs += retryIntervalMs; 2070 retryIntervalMs = Math.min(retryIntervalMs * 2, MAX_RETRY_INTERVAL_MS); 2071 } 2072 } 2073 // Too many failures trying to suspend. Shut down. 2074 Slogf.w(TAG, "Could not %s after %dms long trial. Shutting down.", suspendTarget, 2075 totalWaitDurationMs); 2076 mSystemInterface.shutdown(); 2077 return false; 2078 } 2079 2080 private static final class CpmsState { 2081 // NOTE: When modifying states below, make sure to update CarPowerStateChanged.State in 2082 // frameworks/proto_logging/stats/atoms.proto also. 2083 public static final int WAIT_FOR_VHAL = 0; 2084 public static final int ON = 1; 2085 public static final int SHUTDOWN_PREPARE = 2; 2086 public static final int WAIT_FOR_FINISH = 3; 2087 public static final int SUSPEND = 4; 2088 public static final int SIMULATE_SLEEP = 5; 2089 public static final int SIMULATE_HIBERNATION = 6; 2090 2091 /* Config values from AP_POWER_STATE_REQ */ 2092 public final boolean mCanPostpone; 2093 2094 @PowerState.ShutdownType 2095 public final int mShutdownType; 2096 2097 /* Message sent to CarPowerStateListener in response to this state */ 2098 @CarPowerManager.CarPowerState 2099 public final int mCarPowerStateListenerState; 2100 /* One of the above state variables */ 2101 public final int mState; 2102 2103 /** 2104 * This constructor takes a PowerHalService.PowerState object and creates the corresponding 2105 * CPMS state from it. 2106 */ CpmsState(PowerState halPowerState)2107 CpmsState(PowerState halPowerState) { 2108 switch (halPowerState.mState) { 2109 case VehicleApPowerStateReq.ON: 2110 this.mCanPostpone = false; 2111 this.mShutdownType = PowerState.SHUTDOWN_TYPE_UNDEFINED; 2112 this.mCarPowerStateListenerState = cpmsStateToPowerStateListenerState(ON); 2113 this.mState = ON; 2114 break; 2115 case VehicleApPowerStateReq.SHUTDOWN_PREPARE: 2116 this.mCanPostpone = halPowerState.canPostponeShutdown(); 2117 this.mShutdownType = halPowerState.getShutdownType(); 2118 this.mCarPowerStateListenerState = cpmsStateToPowerStateListenerState( 2119 SHUTDOWN_PREPARE); 2120 this.mState = SHUTDOWN_PREPARE; 2121 break; 2122 case VehicleApPowerStateReq.CANCEL_SHUTDOWN: 2123 this.mCanPostpone = false; 2124 this.mShutdownType = PowerState.SHUTDOWN_TYPE_UNDEFINED; 2125 this.mCarPowerStateListenerState = CarPowerManager.STATE_SHUTDOWN_CANCELLED; 2126 this.mState = WAIT_FOR_VHAL; 2127 break; 2128 case VehicleApPowerStateReq.FINISHED: 2129 this.mCanPostpone = false; 2130 this.mShutdownType = PowerState.SHUTDOWN_TYPE_UNDEFINED; 2131 this.mCarPowerStateListenerState = cpmsStateToPowerStateListenerState(SUSPEND); 2132 this.mState = SUSPEND; 2133 break; 2134 default: 2135 // Illegal state from PowerState. Throw an exception? 2136 // TODO(b/202414427): Add handling of illegal state 2137 this.mCanPostpone = false; 2138 this.mShutdownType = PowerState.SHUTDOWN_TYPE_UNDEFINED; 2139 this.mCarPowerStateListenerState = 0; 2140 this.mState = 0; 2141 break; 2142 } 2143 } 2144 CpmsState(int state, int carPowerStateListenerState, boolean canPostpone)2145 CpmsState(int state, int carPowerStateListenerState, boolean canPostpone) { 2146 this.mCanPostpone = canPostpone; 2147 this.mCarPowerStateListenerState = carPowerStateListenerState; 2148 this.mState = state; 2149 this.mShutdownType = state == SIMULATE_SLEEP ? PowerState.SHUTDOWN_TYPE_DEEP_SLEEP : 2150 (state == SIMULATE_HIBERNATION ? PowerState.SHUTDOWN_TYPE_HIBERNATION 2151 : PowerState.SHUTDOWN_TYPE_POWER_OFF); 2152 } 2153 CpmsState(int state, int carPowerStateListenerState, boolean canPostpone, int shutdownType)2154 CpmsState(int state, int carPowerStateListenerState, boolean canPostpone, 2155 int shutdownType) { 2156 this.mCanPostpone = canPostpone; 2157 this.mCarPowerStateListenerState = carPowerStateListenerState; 2158 this.mState = state; 2159 this.mShutdownType = shutdownType; 2160 } 2161 name()2162 public String name() { 2163 return new StringBuilder() 2164 .append(stateToString()) 2165 .append('(') 2166 .append(mState) 2167 .append(')') 2168 .toString(); 2169 } 2170 stateToString()2171 private String stateToString() { 2172 String baseName; 2173 switch(mState) { 2174 case WAIT_FOR_VHAL: baseName = "WAIT_FOR_VHAL"; break; 2175 case ON: baseName = "ON"; break; 2176 case SHUTDOWN_PREPARE: baseName = "SHUTDOWN_PREPARE"; break; 2177 case WAIT_FOR_FINISH: baseName = "WAIT_FOR_FINISH"; break; 2178 case SUSPEND: baseName = "SUSPEND"; break; 2179 case SIMULATE_SLEEP: baseName = "SIMULATE_SLEEP"; break; 2180 case SIMULATE_HIBERNATION: baseName = "SIMULATE_HIBERNATION"; break; 2181 default: baseName = "<unknown>"; break; 2182 } 2183 return baseName; 2184 } 2185 cpmsStateToPowerStateListenerState(int state)2186 private static int cpmsStateToPowerStateListenerState(int state) { 2187 int powerStateListenerState = 0; 2188 2189 // Set the CarPowerStateListenerState based on current state 2190 switch (state) { 2191 case ON: 2192 powerStateListenerState = CarPowerManager.STATE_ON; 2193 break; 2194 case SHUTDOWN_PREPARE: 2195 powerStateListenerState = CarPowerManager.STATE_PRE_SHUTDOWN_PREPARE; 2196 break; 2197 case SUSPEND: 2198 powerStateListenerState = CarPowerManager.STATE_SUSPEND_ENTER; 2199 break; 2200 case WAIT_FOR_VHAL: 2201 case WAIT_FOR_FINISH: 2202 default: 2203 // Illegal state for this constructor. Throw an exception? 2204 break; 2205 } 2206 return powerStateListenerState; 2207 } 2208 2209 @Override equals(Object o)2210 public boolean equals(Object o) { 2211 if (this == o) { 2212 return true; 2213 } 2214 if (!(o instanceof CpmsState)) { 2215 return false; 2216 } 2217 CpmsState that = (CpmsState) o; 2218 return this.mState == that.mState 2219 && this.mShutdownType == that.mShutdownType 2220 && this.mCanPostpone == that.mCanPostpone 2221 && this.mCarPowerStateListenerState == that.mCarPowerStateListenerState; 2222 } 2223 2224 // PowerPolicyHostTest uses the dump output of {@code CarPowerManagementService}. If the 2225 // {@code CpmsState.toString} is modifed, PowerPolicyHostTest should be updated accordingly. 2226 // TODO(b/184862429): Remove the above comment once dump in proto buffer is done. 2227 @Override toString()2228 public String toString() { 2229 return "CpmsState canPostpone=" + mCanPostpone 2230 + ", carPowerStateListenerState=" + mCarPowerStateListenerState 2231 + ", mShutdownType=" + mShutdownType 2232 + ", CpmsState=" + name(); 2233 } 2234 } 2235 2236 /** 2237 * Resume after a manually-invoked suspend. 2238 * Invoked using "adb shell dumpsys cmd car_service resume". 2239 */ forceSimulatedResume()2240 public void forceSimulatedResume() { 2241 synchronized (mLock) { 2242 // Cancel Garage Mode in case it's running 2243 mPendingPowerStates.addFirst(new CpmsState(CpmsState.WAIT_FOR_VHAL, 2244 CarPowerManager.STATE_SHUTDOWN_CANCELLED, /* canPostpone= */ false)); 2245 mLock.notify(); 2246 } 2247 mHandler.handlePowerStateChange(); 2248 2249 synchronized (mSimulationWaitObject) { 2250 mWakeFromSimulatedSleep = true; 2251 mSimulationWaitObject.notify(); 2252 } 2253 } 2254 2255 /** 2256 * Manually enters simulated suspend (deep sleep or hibernation) mode, trigging Garage mode. 2257 * 2258 * <p>If {@code shouldReboot} is 'true', reboots the system when Garage Mode completes. 2259 * 2260 * Can be invoked using 2261 * {@code "adb shell cmd car_service suspend --simulate"} or 2262 * {@code "adb shell cmd car_service hibernate --simulate"} or 2263 * {@code "adb shell cmd car_service garage-mode reboot"}. 2264 * 2265 * This is similar to {@code 'onApPowerStateChange()'} except that it needs to create a 2266 * {@code CpmsState} that is not directly derived from a {@code VehicleApPowerStateReq}. 2267 */ simulateSuspendAndMaybeReboot(@owerState.ShutdownType int shutdownType, boolean shouldReboot, boolean skipGarageMode, int wakeupAfter)2268 public void simulateSuspendAndMaybeReboot(@PowerState.ShutdownType int shutdownType, 2269 boolean shouldReboot, boolean skipGarageMode, int wakeupAfter) { 2270 boolean isDeepSleep = shutdownType == PowerState.SHUTDOWN_TYPE_DEEP_SLEEP; 2271 synchronized (mSimulationWaitObject) { 2272 mInSimulatedDeepSleepMode = true; 2273 mWakeFromSimulatedSleep = false; 2274 mResumeDelayFromSimulatedSuspendSec = wakeupAfter; 2275 } 2276 synchronized (mLock) { 2277 mRebootAfterGarageMode = shouldReboot; 2278 mPendingPowerStates.addFirst(new CpmsState(isDeepSleep ? CpmsState.SIMULATE_SLEEP 2279 : CpmsState.SIMULATE_HIBERNATION, 2280 CarPowerManager.STATE_PRE_SHUTDOWN_PREPARE, !skipGarageMode)); 2281 } 2282 mHandler.handlePowerStateChange(); 2283 } 2284 2285 /** 2286 * Manually defines a power policy. 2287 * 2288 * <p>If the given ID already exists or specified power components are invalid, it fails. 2289 * 2290 * @return {@code true}, if successful. Otherwise, {@code false}. 2291 */ definePowerPolicyFromCommand(String[] args, IndentingPrintWriter writer)2292 public boolean definePowerPolicyFromCommand(String[] args, IndentingPrintWriter writer) { 2293 if (args.length < 2) { 2294 writer.println("Too few arguments"); 2295 return false; 2296 } 2297 String powerPolicyId = args[1]; 2298 int index = 2; 2299 String[] enabledComponents = new String[0]; 2300 String[] disabledComponents = new String[0]; 2301 while (index < args.length) { 2302 switch (args[index]) { 2303 case "--enable": 2304 if (index == args.length - 1) { 2305 writer.println("No components for --enable"); 2306 return false; 2307 } 2308 enabledComponents = args[index + 1].split(","); 2309 break; 2310 case "--disable": 2311 if (index == args.length - 1) { 2312 writer.println("No components for --disabled"); 2313 return false; 2314 } 2315 disabledComponents = args[index + 1].split(","); 2316 break; 2317 default: 2318 writer.printf("Unrecognized argument: %s\n", args[index]); 2319 return false; 2320 } 2321 index += 2; 2322 } 2323 int status = definePowerPolicy(powerPolicyId, enabledComponents, disabledComponents); 2324 if (status != PolicyOperationStatus.OK) { 2325 writer.println(PolicyOperationStatus.errorCodeToString(status)); 2326 return false; 2327 } 2328 writer.printf("Power policy(%s) is successfully defined.\n", powerPolicyId); 2329 return true; 2330 } 2331 2332 /** 2333 * Defines a power policy with the given id and components. 2334 * 2335 * <p> A policy defined with this method is valid until the system is rebooted/restarted. 2336 */ 2337 @VisibleForTesting 2338 @PolicyOperationStatus.ErrorCode definePowerPolicy(String powerPolicyId, String[] enabledComponents, String[] disabledComponents)2339 public int definePowerPolicy(String powerPolicyId, String[] enabledComponents, 2340 String[] disabledComponents) { 2341 int status = mPolicyReader.definePowerPolicy(powerPolicyId, 2342 enabledComponents, disabledComponents); 2343 if (status != PolicyOperationStatus.OK) { 2344 int error = PolicyOperationStatus.ERROR_DEFINE_POWER_POLICY; 2345 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error)); 2346 return error; 2347 } 2348 ICarPowerPolicySystemNotification daemon; 2349 synchronized (mLock) { 2350 daemon = mCarPowerPolicyDaemon; 2351 } 2352 try { 2353 daemon.notifyPowerPolicyDefinition(powerPolicyId, enabledComponents, 2354 disabledComponents); 2355 } catch (RemoteException e) { 2356 int error = PolicyOperationStatus.ERROR_DEFINE_POWER_POLICY; 2357 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error)); 2358 return error; 2359 } 2360 return PolicyOperationStatus.OK; 2361 } 2362 2363 /** 2364 * Manually applies a power policy. 2365 * 2366 * <p>If the given ID is not defined, it fails. 2367 * 2368 * @return {@code true}, if successful. Otherwise, {@code false}. 2369 */ applyPowerPolicyFromCommand(String[] args, IndentingPrintWriter writer)2370 public boolean applyPowerPolicyFromCommand(String[] args, IndentingPrintWriter writer) { 2371 if (args.length != 2) { 2372 writer.println("Power policy ID should be given"); 2373 return false; 2374 } 2375 String powerPolicyId = args[1]; 2376 if (powerPolicyId == null) { 2377 writer.println("Policy ID cannot be null"); 2378 return false; 2379 } 2380 boolean isPreemptive = mPolicyReader.isPreemptivePowerPolicy(powerPolicyId); 2381 int status = isPreemptive ? applyPreemptivePowerPolicy(powerPolicyId) 2382 : applyPowerPolicy(powerPolicyId, /* delayNotification= */ false, 2383 /* upToDaemon= */ true, /* force= */ false); 2384 if (status != PolicyOperationStatus.OK) { 2385 writer.println(PolicyOperationStatus.errorCodeToString(status)); 2386 return false; 2387 } 2388 writer.printf("Power policy(%s) is successfully applied.\n", powerPolicyId); 2389 return true; 2390 } 2391 2392 /** 2393 * Manually defines a power policy group. 2394 * 2395 * <p>If the given ID already exists, a wrong power state is given, or specified power policy ID 2396 * doesn't exist, it fails. 2397 * 2398 * @return {@code true}, if successful. Otherwise, {@code false}. 2399 */ definePowerPolicyGroupFromCommand(String[] args, IndentingPrintWriter writer)2400 public boolean definePowerPolicyGroupFromCommand(String[] args, IndentingPrintWriter writer) { 2401 if (args.length < 3 || args.length > 4) { 2402 writer.println("Invalid syntax"); 2403 return false; 2404 } 2405 String policyGroupId = args[1]; 2406 int index = 2; 2407 SparseArray<String> defaultPolicyPerState = new SparseArray<>(); 2408 while (index < args.length) { 2409 String[] tokens = args[index].split(":"); 2410 if (tokens.length != 2) { 2411 writer.println("Invalid syntax"); 2412 return false; 2413 } 2414 int state = PolicyReader.toPowerState(tokens[0]); 2415 if (state == PolicyReader.INVALID_POWER_STATE) { 2416 writer.printf("Invalid power state: %s\n", tokens[0]); 2417 return false; 2418 } 2419 defaultPolicyPerState.put(state, tokens[1]); 2420 index++; 2421 } 2422 int status = mPolicyReader.definePowerPolicyGroup(policyGroupId, 2423 defaultPolicyPerState); 2424 if (status != PolicyOperationStatus.OK) { 2425 writer.println(PolicyOperationStatus.errorCodeToString(status)); 2426 return false; 2427 } 2428 writer.printf("Power policy group(%s) is successfully defined.\n", policyGroupId); 2429 return true; 2430 } 2431 2432 /** 2433 * Manually sets a power policy group. 2434 * 2435 * <p>If the given ID is not defined, it fails. 2436 * 2437 * @return {@code true}, if successful. Otherwise, {@code false}. 2438 */ setPowerPolicyGroupFromCommand(String[] args, IndentingPrintWriter writer)2439 public boolean setPowerPolicyGroupFromCommand(String[] args, IndentingPrintWriter writer) { 2440 if (args.length != 2) { 2441 writer.println("Power policy group ID should be given"); 2442 return false; 2443 } 2444 String policyGroupId = args[1]; 2445 int status = setCurrentPowerPolicyGroup(policyGroupId); 2446 if (status != PolicyOperationStatus.OK) { 2447 writer.println(PolicyOperationStatus.errorCodeToString(status)); 2448 return false; 2449 } 2450 writer.printf("Setting power policy group(%s) is successful.\n", policyGroupId); 2451 return true; 2452 } 2453 2454 /** 2455 * Suspends the device. 2456 * 2457 * <p>According to the argument, the device is suspended to RAM or disk. 2458 */ suspendFromCommand(boolean isHibernation, boolean skipGarageMode)2459 public void suspendFromCommand(boolean isHibernation, boolean skipGarageMode) { 2460 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 2461 int param = 0; 2462 if (isHibernation) { 2463 if (!isHibernationAvailable()) { 2464 throw new IllegalStateException("The device doesn't support hibernation"); 2465 } 2466 param = skipGarageMode ? VehicleApPowerStateShutdownParam.HIBERNATE_IMMEDIATELY 2467 : VehicleApPowerStateShutdownParam.CAN_HIBERNATE; 2468 } else { 2469 if (!isDeepSleepAvailable()) { 2470 throw new IllegalStateException("The device doesn't support deep sleep"); 2471 } 2472 param = skipGarageMode ? VehicleApPowerStateShutdownParam.SLEEP_IMMEDIATELY 2473 : VehicleApPowerStateShutdownParam.CAN_SLEEP; 2474 } 2475 PowerState state = new PowerState(VehicleApPowerStateReq.SHUTDOWN_PREPARE, param); 2476 synchronized (mLock) { 2477 mRebootAfterGarageMode = false; 2478 mPendingPowerStates.addFirst(new CpmsState(state)); 2479 mLock.notify(); 2480 } 2481 mHandler.handlePowerStateChange(); 2482 } 2483 2484 /** 2485 * Powers off the device. 2486 */ powerOffFromCommand(boolean skipGarageMode, boolean reboot)2487 public void powerOffFromCommand(boolean skipGarageMode, boolean reboot) { 2488 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 2489 Slogf.i(TAG, "%s %s Garage Mode", reboot ? "Rebooting" : "Powering off", 2490 skipGarageMode ? "with" : "without"); 2491 int param = skipGarageMode ? VehicleApPowerStateShutdownParam.SHUTDOWN_IMMEDIATELY 2492 : VehicleApPowerStateShutdownParam.SHUTDOWN_ONLY; 2493 PowerState state = new PowerState(VehicleApPowerStateReq.SHUTDOWN_PREPARE, param); 2494 synchronized (mLock) { 2495 mRebootAfterGarageMode = reboot; 2496 mPendingPowerStates.addFirst(new CpmsState(state)); 2497 mLock.notify(); 2498 } 2499 mHandler.handlePowerStateChange(); 2500 } 2501 2502 /** 2503 * Changes Silent Mode to the given mode. 2504 */ setSilentMode(String silentMode)2505 public void setSilentMode(String silentMode) { 2506 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 2507 mSilentModeHandler.setSilentMode(silentMode); 2508 } 2509 2510 /** 2511 * Dumps the current Silent Mode. 2512 */ dumpSilentMode(IndentingPrintWriter writer)2513 public void dumpSilentMode(IndentingPrintWriter writer) { 2514 mSilentModeHandler.dump(writer); 2515 } 2516 2517 /** 2518 * Returns whether a listener completion is allowed for the given state. 2519 * 2520 * <p>This method is used internally and is different from 2521 * {@link CarPowerManager.isCompletionAllowed} in that listener completion is allowed for 2522 * SHUTDOWN_PREPARE. 2523 */ isCompletionAllowed(@arPowerManager.CarPowerState int state)2524 public static boolean isCompletionAllowed(@CarPowerManager.CarPowerState int state) { 2525 return CarPowerManager.isCompletionAllowed(state); 2526 } 2527 2528 /** 2529 * Returns a corresponding string of the given power state. 2530 */ powerStateToString(int state)2531 public static String powerStateToString(int state) { 2532 return DebugUtils.valueToString(CarPowerManager.class, "STATE_", state); 2533 } 2534 2535 /** 2536 * Returns whether suspend (deep sleep or hibernation) is available on the device. 2537 */ isSuspendAvailable(boolean isHibernation)2538 public boolean isSuspendAvailable(boolean isHibernation) { 2539 return isHibernation ? isHibernationAvailable() : isDeepSleepAvailable(); 2540 } 2541 isDeepSleepAvailable()2542 private boolean isDeepSleepAvailable() { 2543 return mHal.isDeepSleepAllowed() && mSystemInterface.isSystemSupportingDeepSleep(); 2544 } 2545 isHibernationAvailable()2546 private boolean isHibernationAvailable() { 2547 return mHal.isHibernationAllowed() && mSystemInterface.isSystemSupportingHibernation(); 2548 } 2549 2550 // In a real Deep Sleep, the hardware removes power from the CPU (but retains power 2551 // on the RAM). This puts the processor to sleep. Upon some external signal, power 2552 // is re-applied to the CPU, and processing resumes right where it left off. 2553 // We simulate this behavior by calling wait(). 2554 // We continue from wait() when forceSimulatedResume() is called. simulateSleepByWaiting()2555 private void simulateSleepByWaiting() { 2556 Slogf.i(TAG, "Starting to simulate Deep Sleep by waiting"); 2557 synchronized (mSimulationWaitObject) { 2558 if (mResumeDelayFromSimulatedSuspendSec >= 0) { 2559 Slogf.i(TAG, "Scheduling a wakeup after %d seconds", 2560 mResumeDelayFromSimulatedSuspendSec); 2561 Handler handler = new Handler(Looper.getMainLooper()); 2562 handler.postDelayed(() -> forceSimulatedResume(), 2563 mResumeDelayFromSimulatedSuspendSec * 1000); 2564 } 2565 while (!mWakeFromSimulatedSleep) { 2566 try { 2567 mSimulationWaitObject.wait(); 2568 } catch (InterruptedException ignored) { 2569 Thread.currentThread().interrupt(); // Restore interrupted status 2570 } 2571 } 2572 mInSimulatedDeepSleepMode = false; 2573 } 2574 Slogf.i(TAG, "Exit Deep Sleep simulation"); 2575 } 2576 getMaxSuspendWaitDurationConfig()2577 private int getMaxSuspendWaitDurationConfig() { 2578 return mContext.getResources().getInteger(R.integer.config_maxSuspendWaitDuration); 2579 } 2580 isWifiAdjustmentForSuspendConfig()2581 private boolean isWifiAdjustmentForSuspendConfig() { 2582 return mContext.getResources().getBoolean(R.bool.config_wifiAdjustmentForSuspend); 2583 } 2584 getPreShutdownPrepareTimeoutConfig()2585 private int getPreShutdownPrepareTimeoutConfig() { 2586 return getCompletionWaitTimeoutConfig(R.integer.config_preShutdownPrepareTimeout); 2587 } 2588 getShutdownEnterTimeoutConfig()2589 private int getShutdownEnterTimeoutConfig() { 2590 return getCompletionWaitTimeoutConfig(R.integer.config_shutdownEnterTimeout); 2591 } 2592 getPostShutdownEnterTimeoutConfig()2593 private int getPostShutdownEnterTimeoutConfig() { 2594 return getCompletionWaitTimeoutConfig(R.integer.config_postShutdownEnterTimeout); 2595 } 2596 getCompletionWaitTimeoutConfig(int resourceId)2597 private int getCompletionWaitTimeoutConfig(int resourceId) { 2598 int timeout = mContext.getResources().getInteger(resourceId); 2599 return timeout >= 0 ? timeout : DEFAULT_COMPLETION_WAIT_TIMEOUT; 2600 } 2601 actionOnFinishToString(int actionOnFinish)2602 private static String actionOnFinishToString(int actionOnFinish) { 2603 switch (actionOnFinish) { 2604 case ACTION_ON_FINISH_SHUTDOWN: 2605 return "Shutdown"; 2606 case ACTION_ON_FINISH_DEEP_SLEEP: 2607 return "Deep sleep"; 2608 case ACTION_ON_FINISH_HIBERNATION: 2609 return "Hibernation"; 2610 default: 2611 return "Unknown"; 2612 } 2613 } 2614 waitForCompletionWithShutdownPostpone( @arPowerManager.CarPowerState int carPowerStateListenerState, long timeoutMs, Runnable taskAtCompletion, long intervalMs)2615 private void waitForCompletionWithShutdownPostpone( 2616 @CarPowerManager.CarPowerState int carPowerStateListenerState, long timeoutMs, 2617 Runnable taskAtCompletion, long intervalMs) { 2618 Runnable taskAtInterval = () -> { 2619 mHal.sendShutdownPostpone(SHUTDOWN_EXTEND_MAX_MS); 2620 }; 2621 2622 Slogf.i(TAG, "Start waiting for listener completion for %s", 2623 powerStateToString(carPowerStateListenerState)); 2624 2625 waitForCompletion(taskAtCompletion, taskAtInterval, timeoutMs, intervalMs); 2626 } 2627 } 2628