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