1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.car; 17 18 import android.annotation.NonNull; 19 import android.annotation.UserIdInt; 20 import android.app.ActivityManager; 21 import android.car.Car; 22 import android.car.hardware.power.CarPowerManager.CarPowerStateListener; 23 import android.car.hardware.power.ICarPower; 24 import android.car.hardware.power.ICarPowerStateListener; 25 import android.car.userlib.HalCallback; 26 import android.car.userlib.InitialUserSetter; 27 import android.car.userlib.InitialUserSetter.InitialUserInfoType; 28 import android.car.userlib.UserHalHelper; 29 import android.car.userlib.UserHelper; 30 import android.content.ComponentName; 31 import android.content.Context; 32 import android.content.Intent; 33 import android.content.pm.UserInfo; 34 import android.content.res.Resources; 35 import android.hardware.automotive.vehicle.V2_0.InitialUserInfoRequestType; 36 import android.hardware.automotive.vehicle.V2_0.InitialUserInfoResponseAction; 37 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerStateReq; 38 import android.hardware.automotive.vehicle.V2_0.VehicleApPowerStateShutdownParam; 39 import android.net.wifi.WifiManager; 40 import android.os.Build; 41 import android.os.Handler; 42 import android.os.HandlerThread; 43 import android.os.IBinder; 44 import android.os.Looper; 45 import android.os.Message; 46 import android.os.PowerManager; 47 import android.os.RemoteCallbackList; 48 import android.os.RemoteException; 49 import android.os.ServiceManager; 50 import android.os.SystemClock; 51 import android.os.SystemProperties; 52 import android.os.UserHandle; 53 import android.os.UserManager; 54 import android.sysprop.CarProperties; 55 import android.util.AtomicFile; 56 import android.util.Slog; 57 58 import com.android.car.am.ContinuousBlankActivity; 59 import com.android.car.hal.PowerHalService; 60 import com.android.car.hal.PowerHalService.PowerState; 61 import com.android.car.systeminterface.SystemInterface; 62 import com.android.car.user.CarUserNoticeService; 63 import com.android.car.user.CarUserService; 64 import com.android.internal.annotations.GuardedBy; 65 import com.android.internal.annotations.VisibleForTesting; 66 import com.android.internal.app.IVoiceInteractionManagerService; 67 68 import java.io.BufferedReader; 69 import java.io.BufferedWriter; 70 import java.io.File; 71 import java.io.FileOutputStream; 72 import java.io.IOException; 73 import java.io.InputStreamReader; 74 import java.io.OutputStreamWriter; 75 import java.io.PrintWriter; 76 import java.lang.ref.WeakReference; 77 import java.nio.charset.StandardCharsets; 78 import java.util.HashSet; 79 import java.util.LinkedList; 80 import java.util.Set; 81 import java.util.Timer; 82 import java.util.TimerTask; 83 84 /** 85 * Power Management service class for cars. Controls the power states and interacts with other 86 * parts of the system to ensure its own state. 87 */ 88 public class CarPowerManagementService extends ICarPower.Stub implements 89 CarServiceBase, PowerHalService.PowerEventListener { 90 91 // TODO: replace all usage 92 private static final String TAG = CarLog.TAG_POWER; 93 private static final String WIFI_STATE_FILENAME = "wifi_state"; 94 private static final String WIFI_STATE_MODIFIED = "forcibly_disabled"; 95 private static final String WIFI_STATE_ORIGINAL = "original"; 96 // If Suspend to RAM fails, we retry with an exponential back-off: 97 // The wait interval will be 10 msec, 20 msec, 40 msec, ... 98 // Once the wait interval goes beyond 100 msec, it is fixed at 100 msec. 99 private static final long INITIAL_SUSPEND_RETRY_INTERVAL_MS = 10; 100 private static final long MAX_RETRY_INTERVAL_MS = 100; 101 // Minimum and maximum wait duration before the system goes into Suspend to RAM. 102 private static final long MIN_SUSPEND_WAIT_DURATION_MS = 0; 103 private static final long MAX_SUSPEND_WAIT_DURATION_MS = 3 * 60 * 1000; 104 105 private final Object mLock = new Object(); 106 private final Object mSimulationWaitObject = new Object(); 107 108 private final Context mContext; 109 private final PowerHalService mHal; 110 private final SystemInterface mSystemInterface; 111 // The listeners that complete simply by returning from onStateChanged() 112 private final PowerManagerCallbackList mPowerManagerListeners = new PowerManagerCallbackList(); 113 // The listeners that must indicate asynchronous completion by calling finished(). 114 private final PowerManagerCallbackList mPowerManagerListenersWithCompletion = 115 new PowerManagerCallbackList(); 116 117 @GuardedBy("mSimulationWaitObject") 118 private boolean mWakeFromSimulatedSleep; 119 @GuardedBy("mSimulationWaitObject") 120 private boolean mInSimulatedDeepSleepMode; 121 122 @GuardedBy("mLock") 123 private final Set<IBinder> mListenersWeAreWaitingFor = new HashSet<>(); 124 @GuardedBy("mLock") 125 private CpmsState mCurrentState; 126 @GuardedBy("mLock") 127 private Timer mTimer; 128 @GuardedBy("mLock") 129 private long mProcessingStartTime; 130 @GuardedBy("mLock") 131 private long mLastSleepEntryTime; 132 @GuardedBy("mLock") 133 private final LinkedList<CpmsState> mPendingPowerStates = new LinkedList<>(); 134 private final HandlerThread mHandlerThread = CarServiceUtils.getHandlerThread( 135 getClass().getSimpleName()); 136 private final PowerHandler mHandler = new PowerHandler(mHandlerThread.getLooper(), this); 137 138 @GuardedBy("mLock") 139 private boolean mTimerActive; 140 @GuardedBy("mLock") 141 private int mNextWakeupSec; 142 @GuardedBy("mLock") 143 private boolean mShutdownOnFinish; 144 @GuardedBy("mLock") 145 private boolean mShutdownOnNextSuspend; 146 @GuardedBy("mLock") 147 private boolean mIsBooting = true; 148 @GuardedBy("mLock") 149 private boolean mIsResuming; 150 @GuardedBy("mLock") 151 private int mShutdownPrepareTimeMs = MIN_MAX_GARAGE_MODE_DURATION_MS; 152 @GuardedBy("mLock") 153 private int mShutdownPollingIntervalMs = SHUTDOWN_POLLING_INTERVAL_MS; 154 @GuardedBy("mLock") 155 private boolean mRebootAfterGarageMode; 156 @GuardedBy("mLock") 157 private boolean mGarageModeShouldExitImmediately; 158 private final boolean mDisableUserSwitchDuringResume; 159 160 private final UserManager mUserManager; 161 private final CarUserService mUserService; 162 private final InitialUserSetter mInitialUserSetter; 163 164 private final IVoiceInteractionManagerService mVoiceInteractionManagerService; 165 166 private final WifiManager mWifiManager; 167 private final AtomicFile mWifiStateFile; 168 169 // TODO: Make this OEM configurable. 170 private static final int SHUTDOWN_POLLING_INTERVAL_MS = 2000; 171 private static final int SHUTDOWN_EXTEND_MAX_MS = 5000; 172 173 // maxGarageModeRunningDurationInSecs should be equal or greater than this. 15 min for now. 174 private static final int MIN_MAX_GARAGE_MODE_DURATION_MS = 15 * 60 * 1000; 175 176 // in secs 177 private static final String PROP_MAX_GARAGE_MODE_DURATION_OVERRIDE = 178 "android.car.garagemodeduration"; 179 180 // This is a temp work-around to reduce user switching delay after wake-up. 181 private final boolean mSwitchGuestUserBeforeSleep; 182 183 // CPMS tries to enter Suspend to RAM within the duration specified at 184 // mMaxSuspendWaitDurationMs. The default max duration is MAX_SUSPEND_WAIT_DURATION, and can be 185 // overridden by setting config_maxSuspendWaitDuration in an overrlay resource. 186 // The valid range is MIN_SUSPEND_WAIT_DRATION to MAX_SUSPEND_WAIT_DURATION. 187 private final long mMaxSuspendWaitDurationMs; 188 189 private class PowerManagerCallbackList extends RemoteCallbackList<ICarPowerStateListener> { 190 /** 191 * Old version of {@link #onCallbackDied(E, Object)} that 192 * does not provide a cookie. 193 */ 194 @Override onCallbackDied(ICarPowerStateListener listener)195 public void onCallbackDied(ICarPowerStateListener listener) { 196 Slog.i(TAG, "binderDied " + listener.asBinder()); 197 CarPowerManagementService.this.doUnregisterListener(listener); 198 } 199 } 200 CarPowerManagementService(Context context, PowerHalService powerHal, SystemInterface systemInterface, CarUserService carUserService)201 public CarPowerManagementService(Context context, PowerHalService powerHal, 202 SystemInterface systemInterface, CarUserService carUserService) { 203 this(context, context.getResources(), powerHal, systemInterface, UserManager.get(context), 204 carUserService, new InitialUserSetter(context, 205 (u) -> carUserService.setInitialUser(u), 206 context.getString(R.string.default_guest_name)), 207 IVoiceInteractionManagerService.Stub.asInterface( 208 ServiceManager.getService(Context.VOICE_INTERACTION_MANAGER_SERVICE))); 209 } 210 211 @VisibleForTesting CarPowerManagementService(Context context, Resources resources, PowerHalService powerHal, SystemInterface systemInterface, UserManager userManager, CarUserService carUserService, InitialUserSetter initialUserSetter, IVoiceInteractionManagerService voiceInteractionService)212 public CarPowerManagementService(Context context, Resources resources, PowerHalService powerHal, 213 SystemInterface systemInterface, UserManager userManager, CarUserService carUserService, 214 InitialUserSetter initialUserSetter, 215 IVoiceInteractionManagerService voiceInteractionService) { 216 mContext = context; 217 mHal = powerHal; 218 mSystemInterface = systemInterface; 219 mUserManager = userManager; 220 mDisableUserSwitchDuringResume = resources 221 .getBoolean(R.bool.config_disableUserSwitchDuringResume); 222 mShutdownPrepareTimeMs = resources.getInteger( 223 R.integer.maxGarageModeRunningDurationInSecs) * 1000; 224 mSwitchGuestUserBeforeSleep = resources.getBoolean( 225 R.bool.config_switchGuestUserBeforeGoingSleep); 226 if (mShutdownPrepareTimeMs < MIN_MAX_GARAGE_MODE_DURATION_MS) { 227 Slog.w(TAG, 228 "maxGarageModeRunningDurationInSecs smaller than minimum required, resource:" 229 + mShutdownPrepareTimeMs + "(ms) while should exceed:" 230 + MIN_MAX_GARAGE_MODE_DURATION_MS + "(ms), Ignore resource."); 231 mShutdownPrepareTimeMs = MIN_MAX_GARAGE_MODE_DURATION_MS; 232 } 233 mUserService = carUserService; 234 mInitialUserSetter = initialUserSetter; 235 mVoiceInteractionManagerService = voiceInteractionService; 236 mWifiManager = context.getSystemService(WifiManager.class); 237 mWifiStateFile = new AtomicFile( 238 new File(mSystemInterface.getSystemCarDir(), WIFI_STATE_FILENAME)); 239 mMaxSuspendWaitDurationMs = Math.max(MIN_SUSPEND_WAIT_DURATION_MS, 240 Math.min(getMaxSuspendWaitDurationConfig(), MAX_SUSPEND_WAIT_DURATION_MS)); 241 } 242 243 @VisibleForTesting setShutdownTimersForTest(int pollingIntervalMs, int shutdownTimeoutMs)244 public void setShutdownTimersForTest(int pollingIntervalMs, int shutdownTimeoutMs) { 245 // Override timers to keep testing time short 246 // Passing in '0' resets the value to the default 247 synchronized (mLock) { 248 mShutdownPollingIntervalMs = 249 (pollingIntervalMs == 0) ? SHUTDOWN_POLLING_INTERVAL_MS : pollingIntervalMs; 250 mShutdownPrepareTimeMs = 251 (shutdownTimeoutMs == 0) ? SHUTDOWN_EXTEND_MAX_MS : shutdownTimeoutMs; 252 } 253 } 254 255 @VisibleForTesting getHandlerThread()256 protected HandlerThread getHandlerThread() { 257 return mHandlerThread; 258 } 259 260 @Override init()261 public void init() { 262 mHal.setListener(this); 263 if (mHal.isPowerStateSupported()) { 264 // Initialize CPMS in WAIT_FOR_VHAL state 265 onApPowerStateChange(CpmsState.WAIT_FOR_VHAL, CarPowerStateListener.WAIT_FOR_VHAL); 266 } else { 267 Slog.w(TAG, "Vehicle hal does not support power state yet."); 268 onApPowerStateChange(CpmsState.ON, CarPowerStateListener.ON); 269 } 270 mSystemInterface.startDisplayStateMonitoring(this); 271 } 272 273 @Override release()274 public void release() { 275 synchronized (mLock) { 276 releaseTimerLocked(); 277 mCurrentState = null; 278 mHandler.cancelAll(); 279 mListenersWeAreWaitingFor.clear(); 280 } 281 mSystemInterface.stopDisplayStateMonitoring(); 282 mPowerManagerListeners.kill(); 283 mSystemInterface.releaseAllWakeLocks(); 284 } 285 286 @Override dump(PrintWriter writer)287 public void dump(PrintWriter writer) { 288 synchronized (mLock) { 289 writer.println("*PowerManagementService*"); 290 // TODO: split it in multiple lines 291 // TODO: lock only what's needed 292 writer.print("mCurrentState:" + mCurrentState); 293 writer.print(",mProcessingStartTime:" + mProcessingStartTime); 294 writer.print(",mLastSleepEntryTime:" + mLastSleepEntryTime); 295 writer.print(",mNextWakeupSec:" + mNextWakeupSec); 296 writer.print(",mShutdownOnNextSuspend:" + mShutdownOnNextSuspend); 297 writer.print(",mShutdownOnFinish:" + mShutdownOnFinish); 298 writer.print(",mShutdownPollingIntervalMs:" + mShutdownPollingIntervalMs); 299 writer.print(",mShutdownPrepareTimeMs:" + mShutdownPrepareTimeMs); 300 writer.print(",mDisableUserSwitchDuringResume:" + mDisableUserSwitchDuringResume); 301 writer.println(",mRebootAfterGarageMode:" + mRebootAfterGarageMode); 302 writer.println("mSwitchGuestUserBeforeSleep:" + mSwitchGuestUserBeforeSleep); 303 writer.print("mMaxSuspendWaitDurationMs:" + mMaxSuspendWaitDurationMs); 304 writer.println(", config_maxSuspendWaitDuration:" + getMaxSuspendWaitDurationConfig()); 305 } 306 mInitialUserSetter.dump(writer); 307 } 308 309 @Override onApPowerStateChange(PowerState state)310 public void onApPowerStateChange(PowerState state) { 311 synchronized (mLock) { 312 mPendingPowerStates.addFirst(new CpmsState(state)); 313 mLock.notify(); 314 } 315 mHandler.handlePowerStateChange(); 316 } 317 318 @VisibleForTesting setStateForTesting(boolean isBooting, boolean isResuming)319 void setStateForTesting(boolean isBooting, boolean isResuming) { 320 synchronized (mLock) { 321 Slog.d(TAG, "setStateForTesting():" 322 + " booting(" + mIsBooting + ">" + isBooting + ")" 323 + " resuming(" + mIsResuming + ">" + isResuming + ")"); 324 mIsBooting = isBooting; 325 mIsResuming = isResuming; 326 } 327 } 328 329 /** 330 * Initiate state change from CPMS directly. 331 */ onApPowerStateChange(int apState, int carPowerStateListenerState)332 private void onApPowerStateChange(int apState, int carPowerStateListenerState) { 333 CpmsState newState = new CpmsState(apState, carPowerStateListenerState); 334 synchronized (mLock) { 335 mPendingPowerStates.addFirst(newState); 336 mLock.notify(); 337 } 338 mHandler.handlePowerStateChange(); 339 } 340 doHandlePowerStateChange()341 private void doHandlePowerStateChange() { 342 CpmsState state; 343 synchronized (mLock) { 344 state = mPendingPowerStates.peekFirst(); 345 mPendingPowerStates.clear(); 346 if (state == null) { 347 Slog.e(TAG, "Null power state was requested"); 348 return; 349 } 350 Slog.i(TAG, "doHandlePowerStateChange: newState=" + state.name()); 351 if (!needPowerStateChangeLocked(state)) { 352 return; 353 } 354 // now real power change happens. Whatever was queued before should be all cancelled. 355 releaseTimerLocked(); 356 } 357 mHandler.cancelProcessingComplete(); 358 Slog.i(TAG, "setCurrentState " + state.toString()); 359 CarStatsLogHelper.logPowerState(state.mState); 360 mCurrentState = state; 361 switch (state.mState) { 362 case CpmsState.WAIT_FOR_VHAL: 363 handleWaitForVhal(state); 364 break; 365 case CpmsState.ON: 366 handleOn(); 367 break; 368 case CpmsState.SHUTDOWN_PREPARE: 369 handleShutdownPrepare(state); 370 break; 371 case CpmsState.SIMULATE_SLEEP: 372 simulateShutdownPrepare(); 373 break; 374 case CpmsState.WAIT_FOR_FINISH: 375 handleWaitForFinish(state); 376 break; 377 case CpmsState.SUSPEND: 378 // Received FINISH from VHAL 379 handleFinish(); 380 break; 381 default: 382 // Illegal state 383 // TODO: Throw exception? 384 break; 385 } 386 } 387 handleWaitForVhal(CpmsState state)388 private void handleWaitForVhal(CpmsState state) { 389 int carPowerStateListenerState = state.mCarPowerStateListenerState; 390 sendPowerManagerEvent(carPowerStateListenerState); 391 // Inspect CarPowerStateListenerState to decide which message to send via VHAL 392 switch (carPowerStateListenerState) { 393 case CarPowerStateListener.WAIT_FOR_VHAL: 394 mHal.sendWaitForVhal(); 395 break; 396 case CarPowerStateListener.SHUTDOWN_CANCELLED: 397 mShutdownOnNextSuspend = false; // This cancels the "NextSuspend" 398 mHal.sendShutdownCancel(); 399 break; 400 case CarPowerStateListener.SUSPEND_EXIT: 401 mHal.sendSleepExit(); 402 break; 403 } 404 restoreWifi(); 405 } 406 updateCarUserNoticeServiceIfNecessary()407 private void updateCarUserNoticeServiceIfNecessary() { 408 try { 409 int currentUserId = ActivityManager.getCurrentUser(); 410 UserInfo currentUserInfo = mUserManager.getUserInfo(currentUserId); 411 CarUserNoticeService carUserNoticeService = 412 CarLocalServices.getService(CarUserNoticeService.class); 413 if (currentUserInfo != null && currentUserInfo.isGuest() 414 && carUserNoticeService != null) { 415 Slog.i(TAG, "Car user notice service will ignore all messages before user switch."); 416 Intent intent = new Intent(); 417 intent.setComponent(new ComponentName(mContext.getPackageName(), 418 ContinuousBlankActivity.class.getName())); 419 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 420 mContext.startActivityAsUser(intent, UserHandle.CURRENT); 421 carUserNoticeService.ignoreUserNotice(currentUserId); 422 } 423 } catch (Exception e) { 424 Slog.w(TAG, "Cannot ignore user notice for current user", e); 425 } 426 } 427 handleOn()428 private void handleOn() { 429 // If current user is a Guest User, we want to inform CarUserNoticeService not to show 430 // notice for current user, and show user notice only for the target user. 431 if (!mSwitchGuestUserBeforeSleep) { 432 updateCarUserNoticeServiceIfNecessary(); 433 } 434 435 // Some OEMs have their own user-switching logic, which may not be coordinated with this 436 // code. To avoid contention, we don't switch users when we coming alive. The OEM's code 437 // should do the switch. 438 boolean allowUserSwitch = true; 439 synchronized (mLock) { 440 if (mIsBooting) { 441 // The system is booting, so don't switch users 442 allowUserSwitch = false; 443 mIsBooting = false; 444 mIsResuming = false; 445 Slog.i(TAG, "User switch disallowed while booting"); 446 } else { 447 // The system is resuming after a suspension. Optionally disable user switching. 448 allowUserSwitch = !mDisableUserSwitchDuringResume; 449 mIsBooting = false; 450 mIsResuming = false; 451 if (!allowUserSwitch) { 452 Slog.i(TAG, "User switch disallowed while resuming"); 453 } 454 } 455 } 456 457 mSystemInterface.setDisplayState(true); 458 sendPowerManagerEvent(CarPowerStateListener.ON); 459 460 mHal.sendOn(); 461 462 try { 463 switchUserOnResumeIfNecessary(allowUserSwitch); 464 } catch (Exception e) { 465 Slog.e(TAG, "Could not switch user on resume", e); 466 } 467 468 setVoiceInteractionDisabled(false); 469 } 470 471 @VisibleForTesting // Ideally it should not be exposed, but it speeds up the unit tests switchUserOnResumeIfNecessary(boolean allowSwitching)472 void switchUserOnResumeIfNecessary(boolean allowSwitching) { 473 Slog.d(TAG, "switchUserOnResumeIfNecessary(): allowSwitching=" + allowSwitching 474 + ", mSwitchGuestUserBeforeSleep=" + mSwitchGuestUserBeforeSleep); 475 if (!allowSwitching) { 476 if (mSwitchGuestUserBeforeSleep) { // already handled 477 return; 478 } 479 switchToNewGuestIfNecessary(); 480 return; 481 } 482 483 if (CarProperties.user_hal_enabled().orElse(false) && mUserService.isUserHalSupported()) { 484 switchUserOnResumeIfNecessaryUsingHal(); 485 return; 486 } 487 488 executeDefaultInitialUserBehavior(!mSwitchGuestUserBeforeSleep); 489 } 490 executeDefaultInitialUserBehavior(boolean replaceGuest)491 private void executeDefaultInitialUserBehavior(boolean replaceGuest) { 492 mInitialUserSetter.set(newInitialUserInfoBuilder(InitialUserSetter.TYPE_DEFAULT_BEHAVIOR) 493 .setReplaceGuest(replaceGuest) 494 .build()); 495 } 496 497 /** 498 * Replaces the current user if it's a guest. 499 */ switchToNewGuestIfNecessary()500 private void switchToNewGuestIfNecessary() { 501 int currentUserId = ActivityManager.getCurrentUser(); 502 UserInfo currentUser = mUserManager.getUserInfo(currentUserId); 503 504 if (!mInitialUserSetter.canReplaceGuestUser(currentUser)) return; // Not a guest 505 506 mInitialUserSetter.set(newInitialUserInfoBuilder(InitialUserSetter.TYPE_REPLACE_GUEST) 507 .build()); 508 } 509 switchUser(@serIdInt int userId, boolean replaceGuest)510 private void switchUser(@UserIdInt int userId, boolean replaceGuest) { 511 mInitialUserSetter.set(newInitialUserInfoBuilder(InitialUserSetter.TYPE_SWITCH) 512 .setSwitchUserId(userId).setReplaceGuest(replaceGuest).build()); 513 } 514 newInitialUserInfoBuilder(@nitialUserInfoType int type)515 private InitialUserSetter.Builder newInitialUserInfoBuilder(@InitialUserInfoType int type) { 516 return new InitialUserSetter.Builder(type) 517 .setSupportsOverrideUserIdProperty(!mUserService.isUserHalSupported()); 518 } 519 520 /** 521 * Tells Garage Mode if it should run normally, or just 522 * exit immediately without indicating 'idle' 523 * @return True if no idle jobs should be run 524 * @hide 525 */ garageModeShouldExitImmediately()526 public boolean garageModeShouldExitImmediately() { 527 synchronized (mLock) { 528 return mGarageModeShouldExitImmediately; 529 } 530 } 531 532 /** 533 * Switches the initial user by calling the User HAL to define the behavior. 534 */ switchUserOnResumeIfNecessaryUsingHal()535 private void switchUserOnResumeIfNecessaryUsingHal() { 536 Slog.i(TAG, "Using User HAL to define initial user behavior"); 537 mUserService.getInitialUserInfo(InitialUserInfoRequestType.RESUME, (status, response) -> { 538 switch (status) { 539 case HalCallback.STATUS_HAL_RESPONSE_TIMEOUT: 540 case HalCallback.STATUS_HAL_SET_TIMEOUT: 541 switchUserOnResumeUserHalFallback("timeout"); 542 return; 543 case HalCallback.STATUS_CONCURRENT_OPERATION: 544 switchUserOnResumeUserHalFallback("concurrent call"); 545 return; 546 case HalCallback.STATUS_WRONG_HAL_RESPONSE: 547 switchUserOnResumeUserHalFallback("wrong response"); 548 return; 549 case HalCallback.STATUS_HAL_NOT_SUPPORTED: 550 switchUserOnResumeUserHalFallback("Hal not supported"); 551 return; 552 case HalCallback.STATUS_OK: 553 if (response == null) { 554 switchUserOnResumeUserHalFallback("no response"); 555 return; 556 } 557 boolean replaceGuest = !mSwitchGuestUserBeforeSleep; 558 switch (response.action) { 559 case InitialUserInfoResponseAction.DEFAULT: 560 Slog.i(TAG, "HAL requested default initial user behavior"); 561 executeDefaultInitialUserBehavior(replaceGuest); 562 return; 563 case InitialUserInfoResponseAction.SWITCH: 564 int userId = response.userToSwitchOrCreate.userId; 565 Slog.i(TAG, "HAL requested switch to user " + userId); 566 // If guest was replaced on shutdown, it doesn't need to be replaced 567 // again 568 switchUser(userId, replaceGuest); 569 return; 570 case InitialUserInfoResponseAction.CREATE: 571 int halFlags = response.userToSwitchOrCreate.flags; 572 String name = response.userNameToCreate; 573 Slog.i(TAG, "HAL requested new user (name=" 574 + UserHelper.safeName(name) + ", flags=" 575 + UserHalHelper.userFlagsToString(halFlags) + ")"); 576 mInitialUserSetter 577 .set(newInitialUserInfoBuilder(InitialUserSetter.TYPE_CREATE) 578 .setNewUserName(name) 579 .setNewUserFlags(halFlags) 580 .build()); 581 return; 582 default: 583 switchUserOnResumeUserHalFallback( 584 "invalid response action: " + response.action); 585 return; 586 } 587 default: 588 switchUserOnResumeUserHalFallback("invalid status: " + status); 589 } 590 }); 591 } 592 593 /** 594 * Switches the initial user directly when the User HAL call failed. 595 */ switchUserOnResumeUserHalFallback(String reason)596 private void switchUserOnResumeUserHalFallback(String reason) { 597 Slog.w(TAG, "Failed to set initial user based on User Hal (" + reason 598 + "); falling back to default behavior"); 599 executeDefaultInitialUserBehavior(!mSwitchGuestUserBeforeSleep); 600 } 601 handleShutdownPrepare(CpmsState newState)602 private void handleShutdownPrepare(CpmsState newState) { 603 setVoiceInteractionDisabled(true); 604 mSystemInterface.setDisplayState(false); 605 // Shutdown on finish if the system doesn't support deep sleep or doesn't allow it. 606 synchronized (mLock) { 607 mShutdownOnFinish = mShutdownOnNextSuspend 608 || !mHal.isDeepSleepAllowed() 609 || !mSystemInterface.isSystemSupportingDeepSleep() 610 || !newState.mCanSleep; 611 mGarageModeShouldExitImmediately = !newState.mCanPostpone; 612 } 613 Slog.i(TAG, 614 (newState.mCanPostpone 615 ? "starting shutdown prepare with Garage Mode" 616 : "starting shutdown prepare without Garage Mode")); 617 sendPowerManagerEvent(CarPowerStateListener.SHUTDOWN_PREPARE); 618 mHal.sendShutdownPrepare(); 619 doHandlePreprocessing(); 620 } 621 622 // Simulate system shutdown to Deep Sleep simulateShutdownPrepare()623 private void simulateShutdownPrepare() { 624 mSystemInterface.setDisplayState(false); 625 Slog.i(TAG, "starting shutdown prepare"); 626 sendPowerManagerEvent(CarPowerStateListener.SHUTDOWN_PREPARE); 627 mHal.sendShutdownPrepare(); 628 doHandlePreprocessing(); 629 } 630 handleWaitForFinish(CpmsState state)631 private void handleWaitForFinish(CpmsState state) { 632 sendPowerManagerEvent(state.mCarPowerStateListenerState); 633 int wakeupSec; 634 synchronized (mLock) { 635 // If we're shutting down immediately, don't schedule 636 // a wakeup time. 637 wakeupSec = mGarageModeShouldExitImmediately ? 0 : mNextWakeupSec; 638 } 639 switch (state.mCarPowerStateListenerState) { 640 case CarPowerStateListener.SUSPEND_ENTER: 641 mHal.sendSleepEntry(wakeupSec); 642 break; 643 case CarPowerStateListener.SHUTDOWN_ENTER: 644 mHal.sendShutdownStart(wakeupSec); 645 break; 646 } 647 } 648 handleFinish()649 private void handleFinish() { 650 boolean simulatedMode; 651 synchronized (mSimulationWaitObject) { 652 simulatedMode = mInSimulatedDeepSleepMode; 653 } 654 boolean mustShutDown; 655 boolean forceReboot; 656 synchronized (mLock) { 657 mustShutDown = mShutdownOnFinish && !simulatedMode; 658 forceReboot = mRebootAfterGarageMode; 659 mRebootAfterGarageMode = false; 660 } 661 if (forceReboot) { 662 PowerManager powerManager = mContext.getSystemService(PowerManager.class); 663 if (powerManager == null) { 664 Slog.wtf(TAG, "No PowerManager. Cannot reboot."); 665 } else { 666 Slog.i(TAG, "GarageMode has completed. Forcing reboot."); 667 powerManager.reboot("GarageModeReboot"); 668 throw new AssertionError("Should not return from PowerManager.reboot()"); 669 } 670 } 671 setVoiceInteractionDisabled(true); 672 673 // To make Kernel implementation simpler when going into sleep. 674 disableWifi(); 675 676 if (mustShutDown) { 677 // shutdown HU 678 mSystemInterface.shutdown(); 679 } else { 680 doHandleDeepSleep(simulatedMode); 681 } 682 mShutdownOnNextSuspend = false; 683 } 684 setVoiceInteractionDisabled(boolean disabled)685 private void setVoiceInteractionDisabled(boolean disabled) { 686 try { 687 mVoiceInteractionManagerService.setDisabled(disabled); 688 } catch (RemoteException e) { 689 Slog.w(TAG, "setVoiceIntefactionDisabled(" + disabled + ") failed", e); 690 } 691 } 692 restoreWifi()693 private void restoreWifi() { 694 boolean needToRestore = readWifiModifiedState(); 695 if (needToRestore) { 696 if (!mWifiManager.isWifiEnabled()) { 697 Slog.i(TAG, "Wifi has been enabled to restore the last setting"); 698 mWifiManager.setWifiEnabled(true); 699 } 700 // Update the persistent data as wifi is not modified by car framework. 701 saveWifiModifiedState(false); 702 } 703 } 704 disableWifi()705 private void disableWifi() { 706 boolean wifiEnabled = mWifiManager.isWifiEnabled(); 707 boolean wifiModifiedState = readWifiModifiedState(); 708 if (wifiEnabled != wifiModifiedState) { 709 saveWifiModifiedState(wifiEnabled); 710 } 711 if (!wifiEnabled) return; 712 713 mWifiManager.setWifiEnabled(false); 714 wifiEnabled = mWifiManager.isWifiEnabled(); 715 Slog.i(TAG, "Wifi has been disabled and the last setting was saved"); 716 } 717 saveWifiModifiedState(boolean forciblyDisabled)718 private void saveWifiModifiedState(boolean forciblyDisabled) { 719 FileOutputStream fos; 720 try { 721 fos = mWifiStateFile.startWrite(); 722 } catch (IOException e) { 723 Slog.e(TAG, "Cannot create " + WIFI_STATE_FILENAME, e); 724 return; 725 } 726 727 try (BufferedWriter writer = new BufferedWriter( 728 new OutputStreamWriter(fos, StandardCharsets.UTF_8))) { 729 writer.write(forciblyDisabled ? WIFI_STATE_MODIFIED : WIFI_STATE_ORIGINAL); 730 writer.newLine(); 731 writer.flush(); 732 mWifiStateFile.finishWrite(fos); 733 } catch (IOException e) { 734 mWifiStateFile.failWrite(fos); 735 Slog.e(TAG, "Writing " + WIFI_STATE_FILENAME + " failed", e); 736 } 737 } 738 readWifiModifiedState()739 private boolean readWifiModifiedState() { 740 boolean needToRestore = false; 741 boolean invalidState = false; 742 743 try (BufferedReader reader = new BufferedReader( 744 new InputStreamReader(mWifiStateFile.openRead(), StandardCharsets.UTF_8))) { 745 String line = reader.readLine(); 746 if (line == null) { 747 needToRestore = false; 748 invalidState = true; 749 } else { 750 line = line.trim(); 751 needToRestore = WIFI_STATE_MODIFIED.equals(line); 752 invalidState = !(needToRestore || WIFI_STATE_ORIGINAL.equals(line)); 753 } 754 } catch (IOException e) { 755 // If a file named wifi_state doesn't exist, we will not modify Wifi at system start. 756 Slog.w(TAG, "Failed to read " + WIFI_STATE_FILENAME + ": " + e); 757 return false; 758 } 759 if (invalidState) { 760 mWifiStateFile.delete(); 761 } 762 763 return needToRestore; 764 } 765 766 @GuardedBy("mLock") releaseTimerLocked()767 private void releaseTimerLocked() { 768 if (mTimer != null) { 769 mTimer.cancel(); 770 } 771 mTimer = null; 772 mTimerActive = false; 773 } 774 doHandlePreprocessing()775 private void doHandlePreprocessing() { 776 int intervalMs; 777 int pollingCount; 778 synchronized (mLock) { 779 intervalMs = mShutdownPollingIntervalMs; 780 pollingCount = (mShutdownPrepareTimeMs / mShutdownPollingIntervalMs) + 1; 781 } 782 if (Build.IS_USERDEBUG || Build.IS_ENG) { 783 int shutdownPrepareTimeOverrideInSecs = 784 SystemProperties.getInt(PROP_MAX_GARAGE_MODE_DURATION_OVERRIDE, -1); 785 if (shutdownPrepareTimeOverrideInSecs >= 0) { 786 pollingCount = 787 (shutdownPrepareTimeOverrideInSecs * 1000 / intervalMs) 788 + 1; 789 Slog.i(TAG, "Garage mode duration overridden secs:" 790 + shutdownPrepareTimeOverrideInSecs); 791 } 792 } 793 Slog.i(TAG, "processing before shutdown expected for: " 794 + mShutdownPrepareTimeMs + " ms, adding polling:" + pollingCount); 795 synchronized (mLock) { 796 mProcessingStartTime = SystemClock.elapsedRealtime(); 797 releaseTimerLocked(); 798 mTimer = new Timer(); 799 mTimerActive = true; 800 mTimer.scheduleAtFixedRate( 801 new ShutdownProcessingTimerTask(pollingCount), 802 0 /*delay*/, 803 intervalMs); 804 } 805 if (mSwitchGuestUserBeforeSleep) { 806 switchToNewGuestIfNecessary(); 807 } 808 } 809 sendPowerManagerEvent(int newState)810 private void sendPowerManagerEvent(int newState) { 811 // Broadcast to the listeners that do not signal completion 812 notifyListeners(mPowerManagerListeners, newState); 813 814 // SHUTDOWN_PREPARE is the only state where we need 815 // to maintain callbacks from listener components. 816 boolean allowCompletion = (newState == CarPowerStateListener.SHUTDOWN_PREPARE); 817 818 // Fully populate mListenersWeAreWaitingFor before calling any onStateChanged() 819 // for the listeners that signal completion. 820 // Otherwise, if the first listener calls finish() synchronously, we will 821 // see the list go empty and we will think that we are done. 822 boolean haveSomeCompleters = false; 823 PowerManagerCallbackList completingListeners = new PowerManagerCallbackList(); 824 synchronized (mLock) { 825 mListenersWeAreWaitingFor.clear(); 826 int idx = mPowerManagerListenersWithCompletion.beginBroadcast(); 827 while (idx-- > 0) { 828 ICarPowerStateListener listener = 829 mPowerManagerListenersWithCompletion.getBroadcastItem(idx); 830 completingListeners.register(listener); 831 if (allowCompletion) { 832 mListenersWeAreWaitingFor.add(listener.asBinder()); 833 haveSomeCompleters = true; 834 } 835 } 836 mPowerManagerListenersWithCompletion.finishBroadcast(); 837 } 838 // Broadcast to the listeners that DO signal completion 839 notifyListeners(completingListeners, newState); 840 841 if (allowCompletion && !haveSomeCompleters) { 842 // No jobs need to signal completion. So we are now complete. 843 signalComplete(); 844 } 845 } 846 notifyListeners(PowerManagerCallbackList listenerList, int newState)847 private void notifyListeners(PowerManagerCallbackList listenerList, int newState) { 848 int idx = listenerList.beginBroadcast(); 849 while (idx-- > 0) { 850 ICarPowerStateListener listener = listenerList.getBroadcastItem(idx); 851 try { 852 listener.onStateChanged(newState); 853 } catch (RemoteException e) { 854 // It's likely the connection snapped. Let binder death handle the situation. 855 Slog.e(TAG, "onStateChanged() call failed", e); 856 } 857 } 858 listenerList.finishBroadcast(); 859 } 860 doHandleDeepSleep(boolean simulatedMode)861 private void doHandleDeepSleep(boolean simulatedMode) { 862 // keep holding partial wakelock to prevent entering sleep before enterDeepSleep call 863 // enterDeepSleep should force sleep entry even if wake lock is kept. 864 mSystemInterface.switchToPartialWakeLock(); 865 mHandler.cancelProcessingComplete(); 866 synchronized (mLock) { 867 mLastSleepEntryTime = SystemClock.elapsedRealtime(); 868 } 869 int nextListenerState; 870 if (simulatedMode) { 871 simulateSleepByWaiting(); 872 nextListenerState = CarPowerStateListener.SHUTDOWN_CANCELLED; 873 } else { 874 boolean sleepSucceeded = suspendWithRetries(); 875 if (!sleepSucceeded) { 876 // Suspend failed and we shut down instead. 877 // We either won't get here at all or we will power off very soon. 878 return; 879 } 880 // We suspended and have now resumed 881 nextListenerState = CarPowerStateListener.SUSPEND_EXIT; 882 } 883 synchronized (mLock) { 884 mIsResuming = true; 885 // Any wakeup time from before is no longer valid. 886 mNextWakeupSec = 0; 887 } 888 Slog.i(TAG, "Resuming after suspending"); 889 mSystemInterface.refreshDisplayBrightness(); 890 onApPowerStateChange(CpmsState.WAIT_FOR_VHAL, nextListenerState); 891 } 892 needPowerStateChangeLocked(@onNull CpmsState newState)893 private boolean needPowerStateChangeLocked(@NonNull CpmsState newState) { 894 if (mCurrentState == null) { 895 return true; 896 } else if (mCurrentState.equals(newState)) { 897 Slog.d(TAG, "Requested state is already in effect: " + newState.name()); 898 return false; 899 } 900 901 // The following switch/case enforces the allowed state transitions. 902 boolean transitionAllowed = false; 903 switch (mCurrentState.mState) { 904 case CpmsState.WAIT_FOR_VHAL: 905 transitionAllowed = (newState.mState == CpmsState.ON) 906 || (newState.mState == CpmsState.SHUTDOWN_PREPARE); 907 break; 908 case CpmsState.SUSPEND: 909 transitionAllowed = newState.mState == CpmsState.WAIT_FOR_VHAL; 910 break; 911 case CpmsState.ON: 912 transitionAllowed = (newState.mState == CpmsState.SHUTDOWN_PREPARE) 913 || (newState.mState == CpmsState.SIMULATE_SLEEP); 914 break; 915 case CpmsState.SHUTDOWN_PREPARE: 916 // If VHAL sends SHUTDOWN_IMMEDIATELY or SLEEP_IMMEDIATELY while in 917 // SHUTDOWN_PREPARE state, do it. 918 transitionAllowed = 919 ((newState.mState == CpmsState.SHUTDOWN_PREPARE) && !newState.mCanPostpone) 920 || (newState.mState == CpmsState.WAIT_FOR_FINISH) 921 || (newState.mState == CpmsState.WAIT_FOR_VHAL); 922 break; 923 case CpmsState.SIMULATE_SLEEP: 924 transitionAllowed = true; 925 break; 926 case CpmsState.WAIT_FOR_FINISH: 927 transitionAllowed = (newState.mState == CpmsState.SUSPEND 928 || newState.mState == CpmsState.WAIT_FOR_VHAL); 929 break; 930 default: 931 Slog.e(TAG, "Unexpected current state: currentState=" 932 + mCurrentState.name() + ", newState=" + newState.name()); 933 transitionAllowed = true; 934 } 935 if (!transitionAllowed) { 936 Slog.e(TAG, "Requested power transition is not allowed: " 937 + mCurrentState.name() + " --> " + newState.name()); 938 } 939 return transitionAllowed; 940 } 941 doHandleProcessingComplete()942 private void doHandleProcessingComplete() { 943 int listenerState; 944 synchronized (mLock) { 945 releaseTimerLocked(); 946 if (!mShutdownOnFinish && mLastSleepEntryTime > mProcessingStartTime) { 947 // entered sleep after processing start. So this could be duplicate request. 948 Slog.w(TAG, "Duplicate sleep entry request, ignore"); 949 return; 950 } 951 listenerState = mShutdownOnFinish 952 ? CarPowerStateListener.SHUTDOWN_ENTER : CarPowerStateListener.SUSPEND_ENTER; 953 } 954 955 onApPowerStateChange(CpmsState.WAIT_FOR_FINISH, listenerState); 956 } 957 958 @Override onDisplayBrightnessChange(int brightness)959 public void onDisplayBrightnessChange(int brightness) { 960 mHandler.handleDisplayBrightnessChange(brightness); 961 } 962 doHandleDisplayBrightnessChange(int brightness)963 private void doHandleDisplayBrightnessChange(int brightness) { 964 mSystemInterface.setDisplayBrightness(brightness); 965 } 966 doHandleMainDisplayStateChange(boolean on)967 private void doHandleMainDisplayStateChange(boolean on) { 968 Slog.w(TAG, "Unimplemented: doHandleMainDisplayStateChange() - on = " + on); 969 } 970 handleMainDisplayChanged(boolean on)971 public void handleMainDisplayChanged(boolean on) { 972 mHandler.handleMainDisplayStateChange(on); 973 } 974 975 /** 976 * Send display brightness to VHAL. 977 * @param brightness value 0-100% 978 */ sendDisplayBrightness(int brightness)979 public void sendDisplayBrightness(int brightness) { 980 mHal.sendDisplayBrightness(brightness); 981 } 982 983 /** 984 * Get the PowerHandler that we use to change power states 985 */ getHandler()986 public Handler getHandler() { 987 return mHandler; 988 989 } 990 991 // Binder interface for general use. 992 // The listener is not required (or allowed) to call finished(). 993 @Override registerListener(ICarPowerStateListener listener)994 public void registerListener(ICarPowerStateListener listener) { 995 ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 996 mPowerManagerListeners.register(listener); 997 } 998 999 // Binder interface for Car services only. 1000 // After the listener completes its processing, it must call finished(). 1001 @Override registerListenerWithCompletion(ICarPowerStateListener listener)1002 public void registerListenerWithCompletion(ICarPowerStateListener listener) { 1003 ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 1004 ICarImpl.assertCallingFromSystemProcessOrSelf(); 1005 1006 mPowerManagerListenersWithCompletion.register(listener); 1007 // TODO: Need to send current state to newly registered listener? If so, need to handle 1008 // completion for SHUTDOWN_PREPARE state 1009 } 1010 1011 @Override unregisterListener(ICarPowerStateListener listener)1012 public void unregisterListener(ICarPowerStateListener listener) { 1013 ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 1014 doUnregisterListener(listener); 1015 } 1016 doUnregisterListener(ICarPowerStateListener listener)1017 private void doUnregisterListener(ICarPowerStateListener listener) { 1018 mPowerManagerListeners.unregister(listener); 1019 boolean found = mPowerManagerListenersWithCompletion.unregister(listener); 1020 if (found) { 1021 // Remove this from the completion list (if it's there) 1022 finishedImpl(listener.asBinder()); 1023 } 1024 } 1025 1026 @Override requestShutdownOnNextSuspend()1027 public void requestShutdownOnNextSuspend() { 1028 ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 1029 synchronized (mLock) { 1030 mShutdownOnNextSuspend = true; 1031 } 1032 } 1033 1034 @Override finished(ICarPowerStateListener listener)1035 public void finished(ICarPowerStateListener listener) { 1036 ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 1037 ICarImpl.assertCallingFromSystemProcessOrSelf(); 1038 finishedImpl(listener.asBinder()); 1039 } 1040 1041 @Override scheduleNextWakeupTime(int seconds)1042 public void scheduleNextWakeupTime(int seconds) { 1043 ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 1044 if (seconds < 0) { 1045 Slog.w(TAG, "Next wake up time is negative. Ignoring!"); 1046 return; 1047 } 1048 boolean timedWakeupAllowed = mHal.isTimedWakeupAllowed(); 1049 synchronized (mLock) { 1050 if (!timedWakeupAllowed) { 1051 Slog.w(TAG, "Setting timed wakeups are disabled in HAL. Skipping"); 1052 mNextWakeupSec = 0; 1053 return; 1054 } 1055 if (mNextWakeupSec == 0 || mNextWakeupSec > seconds) { 1056 // The new value is sooner than the old value. Take the new value. 1057 mNextWakeupSec = seconds; 1058 } else { 1059 Slog.d(TAG, "Tried to schedule next wake up, but already had shorter " 1060 + "scheduled time"); 1061 } 1062 } 1063 } 1064 1065 @Override getPowerState()1066 public int getPowerState() { 1067 ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 1068 synchronized (mLock) { 1069 return (mCurrentState == null) ? CarPowerStateListener.INVALID 1070 : mCurrentState.mCarPowerStateListenerState; 1071 } 1072 } 1073 finishedImpl(IBinder binder)1074 private void finishedImpl(IBinder binder) { 1075 boolean allAreComplete; 1076 synchronized (mLock) { 1077 mListenersWeAreWaitingFor.remove(binder); 1078 allAreComplete = mListenersWeAreWaitingFor.isEmpty(); 1079 } 1080 if (allAreComplete) { 1081 signalComplete(); 1082 } 1083 } 1084 signalComplete()1085 private void signalComplete() { 1086 if (mCurrentState.mState == CpmsState.SHUTDOWN_PREPARE 1087 || mCurrentState.mState == CpmsState.SIMULATE_SLEEP) { 1088 PowerHandler powerHandler; 1089 // All apps are ready to shutdown/suspend. 1090 synchronized (mLock) { 1091 if (!mShutdownOnFinish) { 1092 if (mLastSleepEntryTime > mProcessingStartTime 1093 && mLastSleepEntryTime < SystemClock.elapsedRealtime()) { 1094 Slog.i(TAG, "signalComplete: Already slept!"); 1095 return; 1096 } 1097 } 1098 powerHandler = mHandler; 1099 } 1100 Slog.i(TAG, "Apps are finished, call handleProcessingComplete()"); 1101 powerHandler.handleProcessingComplete(); 1102 } 1103 } 1104 1105 private static final class PowerHandler extends Handler { 1106 private static final String TAG = PowerHandler.class.getSimpleName(); 1107 1108 private final int MSG_POWER_STATE_CHANGE = 0; 1109 private final int MSG_DISPLAY_BRIGHTNESS_CHANGE = 1; 1110 private final int MSG_MAIN_DISPLAY_STATE_CHANGE = 2; 1111 private final int MSG_PROCESSING_COMPLETE = 3; 1112 1113 // Do not handle this immediately but with some delay as there can be a race between 1114 // display off due to rear view camera and delivery to here. 1115 private final long MAIN_DISPLAY_EVENT_DELAY_MS = 500; 1116 1117 private final WeakReference<CarPowerManagementService> mService; 1118 PowerHandler(Looper looper, CarPowerManagementService service)1119 private PowerHandler(Looper looper, CarPowerManagementService service) { 1120 super(looper); 1121 mService = new WeakReference<CarPowerManagementService>(service); 1122 } 1123 handlePowerStateChange()1124 private void handlePowerStateChange() { 1125 Message msg = obtainMessage(MSG_POWER_STATE_CHANGE); 1126 sendMessage(msg); 1127 } 1128 handleDisplayBrightnessChange(int brightness)1129 private void handleDisplayBrightnessChange(int brightness) { 1130 Message msg = obtainMessage(MSG_DISPLAY_BRIGHTNESS_CHANGE, brightness, 0); 1131 sendMessage(msg); 1132 } 1133 handleMainDisplayStateChange(boolean on)1134 private void handleMainDisplayStateChange(boolean on) { 1135 removeMessages(MSG_MAIN_DISPLAY_STATE_CHANGE); 1136 Message msg = obtainMessage(MSG_MAIN_DISPLAY_STATE_CHANGE, Boolean.valueOf(on)); 1137 sendMessageDelayed(msg, MAIN_DISPLAY_EVENT_DELAY_MS); 1138 } 1139 handleProcessingComplete()1140 private void handleProcessingComplete() { 1141 removeMessages(MSG_PROCESSING_COMPLETE); 1142 Message msg = obtainMessage(MSG_PROCESSING_COMPLETE); 1143 sendMessage(msg); 1144 } 1145 cancelProcessingComplete()1146 private void cancelProcessingComplete() { 1147 removeMessages(MSG_PROCESSING_COMPLETE); 1148 } 1149 cancelAll()1150 private void cancelAll() { 1151 removeMessages(MSG_POWER_STATE_CHANGE); 1152 removeMessages(MSG_DISPLAY_BRIGHTNESS_CHANGE); 1153 removeMessages(MSG_MAIN_DISPLAY_STATE_CHANGE); 1154 removeMessages(MSG_PROCESSING_COMPLETE); 1155 } 1156 1157 @Override handleMessage(Message msg)1158 public void handleMessage(Message msg) { 1159 CarPowerManagementService service = mService.get(); 1160 if (service == null) { 1161 Slog.i(TAG, "handleMessage null service"); 1162 return; 1163 } 1164 switch (msg.what) { 1165 case MSG_POWER_STATE_CHANGE: 1166 service.doHandlePowerStateChange(); 1167 break; 1168 case MSG_DISPLAY_BRIGHTNESS_CHANGE: 1169 service.doHandleDisplayBrightnessChange(msg.arg1); 1170 break; 1171 case MSG_MAIN_DISPLAY_STATE_CHANGE: 1172 service.doHandleMainDisplayStateChange((Boolean) msg.obj); 1173 break; 1174 case MSG_PROCESSING_COMPLETE: 1175 service.doHandleProcessingComplete(); 1176 break; 1177 } 1178 } 1179 } 1180 1181 private class ShutdownProcessingTimerTask extends TimerTask { 1182 private final int mExpirationCount; 1183 private int mCurrentCount; 1184 ShutdownProcessingTimerTask(int expirationCount)1185 private ShutdownProcessingTimerTask(int expirationCount) { 1186 mExpirationCount = expirationCount; 1187 mCurrentCount = 0; 1188 } 1189 1190 @Override run()1191 public void run() { 1192 synchronized (mLock) { 1193 if (!mTimerActive) { 1194 // Ignore timer expiration since we got cancelled 1195 return; 1196 } 1197 mCurrentCount++; 1198 if (mCurrentCount > mExpirationCount) { 1199 PowerHandler handler; 1200 releaseTimerLocked(); 1201 handler = mHandler; 1202 handler.handleProcessingComplete(); 1203 } else { 1204 mHal.sendShutdownPostpone(SHUTDOWN_EXTEND_MAX_MS); 1205 } 1206 } 1207 } 1208 } 1209 1210 // Send the command to enter Suspend to RAM. 1211 // If the command is not successful, try again with an exponential back-off. 1212 // If it fails repeatedly, send the command to shut down. 1213 // If we decide to go to a different power state, abort this retry mechanism. 1214 // Returns true if we successfully suspended. suspendWithRetries()1215 private boolean suspendWithRetries() { 1216 long retryIntervalMs = INITIAL_SUSPEND_RETRY_INTERVAL_MS; 1217 long totalWaitDurationMs = 0; 1218 1219 while (true) { 1220 Slog.i(TAG, "Entering Suspend to RAM"); 1221 boolean suspendSucceeded = mSystemInterface.enterDeepSleep(); 1222 if (suspendSucceeded) { 1223 return true; 1224 } 1225 if (totalWaitDurationMs >= mMaxSuspendWaitDurationMs) { 1226 break; 1227 } 1228 // We failed to suspend. Block the thread briefly and try again. 1229 synchronized (mLock) { 1230 if (mPendingPowerStates.isEmpty()) { 1231 Slog.w(TAG, "Failed to Suspend; will retry after " + retryIntervalMs + "ms."); 1232 try { 1233 mLock.wait(retryIntervalMs); 1234 } catch (InterruptedException ignored) { 1235 Thread.currentThread().interrupt(); 1236 } 1237 totalWaitDurationMs += retryIntervalMs; 1238 retryIntervalMs = Math.min(retryIntervalMs * 2, MAX_RETRY_INTERVAL_MS); 1239 } 1240 // Check for a new power state now, before going around the loop again 1241 if (!mPendingPowerStates.isEmpty()) { 1242 Slog.i(TAG, "Terminating the attempt to Suspend to RAM"); 1243 return false; 1244 } 1245 } 1246 } 1247 // Too many failures trying to suspend. Shut down. 1248 Slog.w(TAG, "Could not Suspend to RAM after " + totalWaitDurationMs 1249 + "ms long trial. Shutting down."); 1250 mSystemInterface.shutdown(); 1251 return false; 1252 } 1253 1254 private static class CpmsState { 1255 // NOTE: When modifying states below, make sure to update CarPowerStateChanged.State in 1256 // frameworks/base/cmds/statsd/src/atoms.proto also. 1257 public static final int WAIT_FOR_VHAL = 0; 1258 public static final int ON = 1; 1259 public static final int SHUTDOWN_PREPARE = 2; 1260 public static final int WAIT_FOR_FINISH = 3; 1261 public static final int SUSPEND = 4; 1262 public static final int SIMULATE_SLEEP = 5; 1263 1264 /* Config values from AP_POWER_STATE_REQ */ 1265 public final boolean mCanPostpone; 1266 public final boolean mCanSleep; 1267 /* Message sent to CarPowerStateListener in response to this state */ 1268 public final int mCarPowerStateListenerState; 1269 /* One of the above state variables */ 1270 public final int mState; 1271 1272 /** 1273 * This constructor takes a PowerHalService.PowerState object and creates the corresponding 1274 * CPMS state from it. 1275 */ CpmsState(PowerState halPowerState)1276 CpmsState(PowerState halPowerState) { 1277 switch (halPowerState.mState) { 1278 case VehicleApPowerStateReq.ON: 1279 this.mCanPostpone = false; 1280 this.mCanSleep = false; 1281 this.mCarPowerStateListenerState = cpmsStateToPowerStateListenerState(ON); 1282 this.mState = ON; 1283 break; 1284 case VehicleApPowerStateReq.SHUTDOWN_PREPARE: 1285 this.mCanPostpone = halPowerState.canPostponeShutdown(); 1286 this.mCanSleep = halPowerState.canEnterDeepSleep(); 1287 this.mCarPowerStateListenerState = cpmsStateToPowerStateListenerState( 1288 SHUTDOWN_PREPARE); 1289 this.mState = SHUTDOWN_PREPARE; 1290 break; 1291 case VehicleApPowerStateReq.CANCEL_SHUTDOWN: 1292 this.mCanPostpone = false; 1293 this.mCanSleep = false; 1294 this.mCarPowerStateListenerState = CarPowerStateListener.SHUTDOWN_CANCELLED; 1295 this.mState = WAIT_FOR_VHAL; 1296 break; 1297 case VehicleApPowerStateReq.FINISHED: 1298 this.mCanPostpone = false; 1299 this.mCanSleep = false; 1300 this.mCarPowerStateListenerState = cpmsStateToPowerStateListenerState(SUSPEND); 1301 this.mState = SUSPEND; 1302 break; 1303 default: 1304 // Illegal state from PowerState. Throw an exception? 1305 this.mCanPostpone = false; 1306 this.mCanSleep = false; 1307 this.mCarPowerStateListenerState = 0; 1308 this.mState = 0; 1309 break; 1310 } 1311 } 1312 CpmsState(int state)1313 CpmsState(int state) { 1314 this(state, cpmsStateToPowerStateListenerState(state)); 1315 } 1316 CpmsState(int state, int carPowerStateListenerState)1317 CpmsState(int state, int carPowerStateListenerState) { 1318 this.mCanPostpone = (state == SIMULATE_SLEEP); 1319 this.mCanSleep = (state == SIMULATE_SLEEP); 1320 this.mCarPowerStateListenerState = carPowerStateListenerState; 1321 this.mState = state; 1322 } 1323 name()1324 public String name() { 1325 String baseName; 1326 switch(mState) { 1327 case WAIT_FOR_VHAL: baseName = "WAIT_FOR_VHAL"; break; 1328 case ON: baseName = "ON"; break; 1329 case SHUTDOWN_PREPARE: baseName = "SHUTDOWN_PREPARE"; break; 1330 case WAIT_FOR_FINISH: baseName = "WAIT_FOR_FINISH"; break; 1331 case SUSPEND: baseName = "SUSPEND"; break; 1332 case SIMULATE_SLEEP: baseName = "SIMULATE_SLEEP"; break; 1333 default: baseName = "<unknown>"; break; 1334 } 1335 return baseName + "(" + mState + ")"; 1336 } 1337 cpmsStateToPowerStateListenerState(int state)1338 private static int cpmsStateToPowerStateListenerState(int state) { 1339 int powerStateListenerState = 0; 1340 1341 // Set the CarPowerStateListenerState based on current state 1342 switch (state) { 1343 case ON: 1344 powerStateListenerState = CarPowerStateListener.ON; 1345 break; 1346 case SHUTDOWN_PREPARE: 1347 powerStateListenerState = CarPowerStateListener.SHUTDOWN_PREPARE; 1348 break; 1349 case SUSPEND: 1350 powerStateListenerState = CarPowerStateListener.SUSPEND_ENTER; 1351 break; 1352 case WAIT_FOR_VHAL: 1353 case WAIT_FOR_FINISH: 1354 default: 1355 // Illegal state for this constructor. Throw an exception? 1356 break; 1357 } 1358 return powerStateListenerState; 1359 } 1360 1361 @Override equals(Object o)1362 public boolean equals(Object o) { 1363 if (this == o) { 1364 return true; 1365 } 1366 if (!(o instanceof CpmsState)) { 1367 return false; 1368 } 1369 CpmsState that = (CpmsState) o; 1370 return this.mState == that.mState 1371 && this.mCanSleep == that.mCanSleep 1372 && this.mCanPostpone == that.mCanPostpone 1373 && this.mCarPowerStateListenerState == that.mCarPowerStateListenerState; 1374 } 1375 1376 @Override toString()1377 public String toString() { 1378 return "CpmsState canSleep:" + mCanSleep + ", canPostpone=" + mCanPostpone 1379 + ", carPowerStateListenerState=" + mCarPowerStateListenerState 1380 + ", CpmsState=" + this.name(); 1381 } 1382 } 1383 1384 /** 1385 * Resume after a manually-invoked suspend. 1386 * Invoked using "adb shell dumpsys activity service com.android.car resume". 1387 */ forceSimulatedResume()1388 public void forceSimulatedResume() { 1389 PowerHandler handler; 1390 synchronized (mLock) { 1391 // Cancel Garage Mode in case it's running 1392 mPendingPowerStates.addFirst(new CpmsState(CpmsState.WAIT_FOR_VHAL, 1393 CarPowerStateListener.SHUTDOWN_CANCELLED)); 1394 mLock.notify(); 1395 handler = mHandler; 1396 } 1397 handler.handlePowerStateChange(); 1398 1399 synchronized (mSimulationWaitObject) { 1400 mWakeFromSimulatedSleep = true; 1401 mSimulationWaitObject.notify(); 1402 } 1403 } 1404 1405 /** 1406 * Manually enter simulated suspend (Deep Sleep) mode, trigging Garage mode. 1407 * If the parameter is 'true', reboot the system when Garage Mode completes. 1408 * 1409 * Invoked using "adb shell dumpsys activity service com.android.car suspend" or 1410 * "adb shell dumpsys activity service com.android.car garage-mode reboot". 1411 * This is similar to 'onApPowerStateChange()' except that it needs to create a CpmsState 1412 * that is not directly derived from a VehicleApPowerStateReq. 1413 */ 1414 @VisibleForTesting forceSuspendAndMaybeReboot(boolean shouldReboot)1415 void forceSuspendAndMaybeReboot(boolean shouldReboot) { 1416 synchronized (mSimulationWaitObject) { 1417 mInSimulatedDeepSleepMode = true; 1418 mWakeFromSimulatedSleep = false; 1419 mGarageModeShouldExitImmediately = false; 1420 } 1421 PowerHandler handler; 1422 synchronized (mLock) { 1423 mRebootAfterGarageMode = shouldReboot; 1424 mPendingPowerStates.addFirst(new CpmsState(CpmsState.SIMULATE_SLEEP, 1425 CarPowerStateListener.SHUTDOWN_PREPARE)); 1426 handler = mHandler; 1427 } 1428 handler.handlePowerStateChange(); 1429 } 1430 1431 /** 1432 * Powers off the device, considering the given options. 1433 * 1434 * <p>The final state can be "suspend-to-RAM" or "shutdown". Attempting to go to suspend-to-RAM 1435 * on devices which do not support it may lead to an unexpected system state. 1436 */ powerOffFromCommand(boolean skipGarageMode, boolean shutdown)1437 public void powerOffFromCommand(boolean skipGarageMode, boolean shutdown) { 1438 ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 1439 int param = 0; 1440 if (shutdown) { 1441 param = skipGarageMode ? VehicleApPowerStateShutdownParam.SHUTDOWN_IMMEDIATELY 1442 : VehicleApPowerStateShutdownParam.SHUTDOWN_ONLY; 1443 } else { 1444 param = skipGarageMode ? VehicleApPowerStateShutdownParam.SLEEP_IMMEDIATELY 1445 : VehicleApPowerStateShutdownParam.CAN_SLEEP; 1446 } 1447 PowerState state = new PowerState(VehicleApPowerStateReq.SHUTDOWN_PREPARE, param); 1448 synchronized (mLock) { 1449 mRebootAfterGarageMode = false; 1450 mPendingPowerStates.addFirst(new CpmsState(state)); 1451 mLock.notify(); 1452 } 1453 mHandler.handlePowerStateChange(); 1454 } 1455 1456 // In a real Deep Sleep, the hardware removes power from the CPU (but retains power 1457 // on the RAM). This puts the processor to sleep. Upon some external signal, power 1458 // is re-applied to the CPU, and processing resumes right where it left off. 1459 // We simulate this behavior by calling wait(). 1460 // We continue from wait() when forceSimulatedResume() is called. simulateSleepByWaiting()1461 private void simulateSleepByWaiting() { 1462 Slog.i(TAG, "Starting to simulate Deep Sleep by waiting"); 1463 synchronized (mSimulationWaitObject) { 1464 while (!mWakeFromSimulatedSleep) { 1465 try { 1466 mSimulationWaitObject.wait(); 1467 } catch (InterruptedException ignored) { 1468 Thread.currentThread().interrupt(); // Restore interrupted status 1469 } 1470 } 1471 mInSimulatedDeepSleepMode = false; 1472 } 1473 Slog.i(TAG, "Exit Deep Sleep simulation"); 1474 } 1475 getMaxSuspendWaitDurationConfig()1476 private int getMaxSuspendWaitDurationConfig() { 1477 return mContext.getResources().getInteger(R.integer.config_maxSuspendWaitDuration); 1478 } 1479 } 1480