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