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