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.car.hardware.power.PowerComponentUtil.FIRST_POWER_COMPONENT; 22 import static android.car.hardware.power.PowerComponentUtil.LAST_POWER_COMPONENT; 23 import static android.net.ConnectivityManager.TETHERING_WIFI; 24 25 import static com.android.car.hal.PowerHalService.BOOTUP_REASON_SYSTEM_ENTER_GARAGE_MODE; 26 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.DUMP_INFO; 27 28 import android.annotation.NonNull; 29 import android.annotation.Nullable; 30 import android.app.ActivityManager; 31 import android.automotive.powerpolicy.internal.ICarPowerPolicyDelegate; 32 import android.automotive.powerpolicy.internal.ICarPowerPolicyDelegateCallback; 33 import android.automotive.powerpolicy.internal.PowerPolicyFailureReason; 34 import android.automotive.powerpolicy.internal.PowerPolicyInitData; 35 import android.car.Car; 36 import android.car.CarOccupantZoneManager; 37 import android.car.ICarResultReceiver; 38 import android.car.builtin.app.ActivityManagerHelper; 39 import android.car.builtin.content.pm.PackageManagerHelper; 40 import android.car.builtin.os.BuildHelper; 41 import android.car.builtin.os.HandlerHelper; 42 import android.car.builtin.os.ServiceManagerHelper; 43 import android.car.builtin.os.UserManagerHelper; 44 import android.car.builtin.util.EventLogHelper; 45 import android.car.builtin.util.Slogf; 46 import android.car.feature.FeatureFlags; 47 import android.car.feature.FeatureFlagsImpl; 48 import android.car.hardware.power.CarPowerManager; 49 import android.car.hardware.power.CarPowerPolicy; 50 import android.car.hardware.power.CarPowerPolicyFilter; 51 import android.car.hardware.power.ICarPower; 52 import android.car.hardware.power.ICarPowerPolicyListener; 53 import android.car.hardware.power.ICarPowerStateListener; 54 import android.car.hardware.power.PowerComponentUtil; 55 import android.car.remoteaccess.CarRemoteAccessManager; 56 import android.content.ComponentName; 57 import android.content.Context; 58 import android.content.Intent; 59 import android.content.res.Resources; 60 import android.frameworks.automotive.powerpolicy.internal.ICarPowerPolicySystemNotification; 61 import android.frameworks.automotive.powerpolicy.internal.PolicyState; 62 import android.hardware.automotive.vehicle.VehicleApPowerStateReport; 63 import android.hardware.automotive.vehicle.VehicleApPowerStateReq; 64 import android.hardware.automotive.vehicle.VehicleApPowerStateShutdownParam; 65 import android.hardware.display.DisplayManager; 66 import android.net.TetheringManager; 67 import android.net.TetheringManager.TetheringRequest; 68 import android.net.wifi.WifiManager; 69 import android.os.Binder; 70 import android.os.Handler; 71 import android.os.HandlerThread; 72 import android.os.IBinder; 73 import android.os.IInterface; 74 import android.os.Looper; 75 import android.os.Message; 76 import android.os.PowerManager; 77 import android.os.Process; 78 import android.os.RemoteCallbackList; 79 import android.os.RemoteException; 80 import android.os.SystemClock; 81 import android.os.SystemProperties; 82 import android.os.UserHandle; 83 import android.os.UserManager; 84 import android.util.ArraySet; 85 import android.util.AtomicFile; 86 import android.util.SparseArray; 87 import android.util.proto.ProtoOutputStream; 88 import android.view.Display; 89 90 import com.android.car.CarLocalServices; 91 import com.android.car.CarLog; 92 import com.android.car.CarOccupantZoneService; 93 import com.android.car.CarServiceBase; 94 import com.android.car.CarServiceUtils; 95 import com.android.car.CarStatsLogHelper; 96 import com.android.car.ICarImpl; 97 import com.android.car.R; 98 import com.android.car.hal.PowerHalService; 99 import com.android.car.hal.PowerHalService.BootupReason; 100 import com.android.car.hal.PowerHalService.PowerState; 101 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport; 102 import com.android.car.internal.util.DebugUtils; 103 import com.android.car.internal.util.IndentingPrintWriter; 104 import com.android.car.internal.util.Lists; 105 import com.android.car.power.CarPowerDumpProto.CpmsStateProto; 106 import com.android.car.systeminterface.SystemInterface; 107 import com.android.car.user.CarUserNoticeService; 108 import com.android.car.user.CarUserService; 109 import com.android.car.user.UserHandleHelper; 110 import com.android.internal.annotations.GuardedBy; 111 import com.android.internal.annotations.VisibleForTesting; 112 import com.android.internal.util.Preconditions; 113 114 import org.xmlpull.v1.XmlPullParserException; 115 116 import java.io.BufferedReader; 117 import java.io.BufferedWriter; 118 import java.io.File; 119 import java.io.FileOutputStream; 120 import java.io.IOException; 121 import java.io.InputStream; 122 import java.io.InputStreamReader; 123 import java.io.OutputStreamWriter; 124 import java.lang.ref.WeakReference; 125 import java.nio.charset.StandardCharsets; 126 import java.util.ArrayList; 127 import java.util.Collection; 128 import java.util.LinkedList; 129 import java.util.List; 130 import java.util.Objects; 131 import java.util.concurrent.CountDownLatch; 132 import java.util.concurrent.ExecutorService; 133 import java.util.concurrent.Executors; 134 import java.util.concurrent.Semaphore; 135 import java.util.concurrent.TimeUnit; 136 import java.util.concurrent.atomic.AtomicBoolean; 137 import java.util.concurrent.atomic.AtomicInteger; 138 import java.util.function.BiFunction; 139 import java.util.function.Consumer; 140 141 /** 142 * Power Management service class for cars. Controls the power states and interacts with other 143 * parts of the system to ensure its own state. 144 */ 145 public class CarPowerManagementService extends ICarPower.Stub implements 146 CarServiceBase, PowerHalService.PowerEventListener { 147 public static final String SILENT_MODE_FORCED_SILENT = 148 SilentModeHandler.SILENT_MODE_FORCED_SILENT; 149 public static final String SILENT_MODE_FORCED_NON_SILENT = 150 SilentModeHandler.SILENT_MODE_FORCED_NON_SILENT; 151 public static final String SILENT_MODE_NON_FORCED = SilentModeHandler.SILENT_MODE_NON_FORCED; 152 153 public static final long INVALID_TIMEOUT = -1L; 154 155 public static final int NO_WAKEUP_BY_TIMER = -1; 156 157 static final String TAG = CarLog.tagFor(CarPowerManagementService.class); 158 159 private static final String WIFI_STATE_FILENAME = "wifi_state"; 160 private static final String TETHERING_STATE_FILENAME = "tethering_state"; 161 private static final String COMPONENT_STATE_MODIFIED = "forcibly_disabled"; 162 private static final String COMPONENT_STATE_ORIGINAL = "original"; 163 // If Suspend to RAM fails, we retry with an exponential back-off: 164 // The wait interval will be 10 msec, 20 msec, 40 msec, ... 165 // Once the wait interval goes beyond 100 msec, it is fixed at 100 msec. 166 private static final long INITIAL_SUSPEND_RETRY_INTERVAL_MS = 10; 167 private static final long MAX_RETRY_INTERVAL_MS = 100; 168 // Minimum and maximum wait duration before the system goes into Suspend to RAM. 169 private static final long MIN_SUSPEND_WAIT_DURATION_MS = 0; 170 private static final long MAX_SUSPEND_WAIT_DURATION_MS = 3 * 60 * 1000; 171 172 private static final long CAR_POWER_POLICY_DAEMON_FIND_MARGINAL_TIME_MS = 300; 173 private static final long CAR_POWER_POLICY_DAEMON_BIND_RETRY_INTERVAL_MS = 500; 174 private static final int CAR_POWER_POLICY_DAEMON_BIND_MAX_RETRY = 3; 175 private static final long CAR_POWER_POLICY_DEFINITION_TIMEOUT_MS = 500; 176 // TODO(b/286303350): remove once power policy refactor complete, replace w/refactored version 177 private static final String CAR_POWER_POLICY_DAEMON_INTERFACE = 178 "android.frameworks.automotive.powerpolicy.internal.ICarPowerPolicySystemNotification/" 179 + "default"; 180 private static final String REFACTORED_CAR_POWER_POLICY_DAEMON_INTERFACE = 181 "android.automotive.powerpolicy.internal.ICarPowerPolicyDelegate/default"; 182 183 // TODO: Make this OEM configurable. 184 private static final int SHUTDOWN_POLLING_INTERVAL_MS = 2000; 185 private static final int SHUTDOWN_EXTEND_MAX_MS = 5000; 186 187 // maxGarageModeRunningDurationInSecs should be equal or greater than this. 15 min for now. 188 private static final int MIN_MAX_GARAGE_MODE_DURATION_MS = 15 * 60 * 1000; 189 190 // in secs 191 private static final String PROP_MAX_GARAGE_MODE_DURATION_OVERRIDE = 192 "android.car.garagemodeduration"; 193 // Constants for action on finish 194 private static final int ACTION_ON_FINISH_SHUTDOWN = 0; 195 private static final int ACTION_ON_FINISH_DEEP_SLEEP = 1; 196 private static final int ACTION_ON_FINISH_HIBERNATION = 2; 197 198 // Default timeout for listener completion during shutdown. 199 private static final int DEFAULT_COMPLETION_WAIT_TIMEOUT = 5_000; 200 201 // Default timeout for power policy change requests 202 private static final int DEFAULT_POWER_POLICY_REQUEST_TIMEOUT_MS = 5_000; 203 204 private static final int INDEX_WAIT_FOR_VHAL = 0; 205 private static final int INDEX_ON = 1; 206 207 private final Object mLock = new Object(); 208 private final Object mSimulationWaitObject = new Object(); 209 210 private final Context mContext; 211 private final PowerHalService mHal; 212 private final SystemInterface mSystemInterface; 213 private final HandlerThread mHandlerThread = CarServiceUtils.getHandlerThread( 214 getClass().getSimpleName()); 215 private final PowerHandler mHandler = new PowerHandler(mHandlerThread.getLooper(), this); 216 private final HandlerThread mBroadcastHandlerThread = CarServiceUtils.getHandlerThread( 217 getClass().getSimpleName() + " broadcasts"); 218 private final Handler mBroadcastHandler = new Handler(mBroadcastHandlerThread.getLooper()); 219 // The listeners that complete simply by returning from onStateChanged() 220 private final PowerManagerCallbackList<ICarPowerStateListener> mPowerManagerListeners = 221 new PowerManagerCallbackList<>( 222 l -> CarPowerManagementService.this.doUnregisterListener(l)); 223 // The listeners that must indicate asynchronous completion by calling finished(). 224 private final PowerManagerCallbackList<ICarPowerStateListener> 225 mPowerManagerListenersWithCompletion = new PowerManagerCallbackList<>( 226 l -> CarPowerManagementService.this.doUnregisterListener(l)); 227 private final AtomicInteger mPolicyRequestIdCounter = new AtomicInteger(0); 228 // The internal listeners that must indicates asynchronous completion by calling 229 // completeStateChangeHandling(). Note that they are not binder objects. 230 @GuardedBy("mLock") 231 private final ArrayList<ICarPowerStateListener> mInternalPowerListeners = new ArrayList<>(); 232 233 @GuardedBy("mLock") 234 private final ArraySet<IBinder> mListenersWeAreWaitingFor = new ArraySet<>(); 235 @GuardedBy("mLock") 236 private final LinkedList<CpmsState> mPendingPowerStates = new LinkedList<>(); 237 @GuardedBy("mLock") 238 private final SparseArray<AsyncPolicyRequest> mRequestIdToPolicyRequest = new SparseArray<>(); 239 private final UserManager mUserManager; 240 private final CarUserService mUserService; 241 private final WifiManager mWifiManager; 242 private final TetheringManager mTetheringManager; 243 private final AtomicFile mWifiStateFile; 244 private final AtomicFile mTetheringStateFile; 245 private final boolean mWifiAdjustmentForSuspend; 246 247 // This is a temp work-around to reduce user switching delay after wake-up. 248 private final boolean mSwitchGuestUserBeforeSleep; 249 250 // CPMS tries to enter Suspend to RAM within the duration specified at 251 // mMaxSuspendWaitDurationMs. The default max duration is MAX_SUSPEND_WAIT_DRATION, and can be 252 // overridden by setting config_maxSuspendWaitDuration in an overrlay resource. 253 // The valid range is MIN_SUSPEND_WAIT_DRATION to MAX_SUSPEND_WAIT_DURATION. 254 private final long mMaxSuspendWaitDurationMs; 255 256 @GuardedBy("mSimulationWaitObject") 257 private boolean mWakeFromSimulatedSleep; 258 @GuardedBy("mSimulationWaitObject") 259 private boolean mInSimulatedDeepSleepMode; 260 @GuardedBy("mSimulationWaitObject") 261 private int mResumeDelayFromSimulatedSuspendSec = NO_WAKEUP_BY_TIMER; 262 @GuardedBy("mSimulationWaitObject") 263 private int mCancelDelayFromSimulatedSuspendSec = NO_WAKEUP_BY_TIMER; 264 @GuardedBy("mSimulationWaitObject") 265 private boolean mFreeMemoryBeforeSuspend; 266 267 @GuardedBy("mLock") 268 private CpmsState mCurrentState; 269 @GuardedBy("mLock") 270 private long mShutdownStartTime; 271 @GuardedBy("mLock") 272 private long mLastSleepEntryTime; 273 274 @GuardedBy("mLock") 275 private int mNextWakeupSec; 276 @GuardedBy("mLock") 277 private int mActionOnFinish; 278 @GuardedBy("mLock") 279 private boolean mShutdownOnNextSuspend; 280 @GuardedBy("mLock") 281 private boolean mShouldResumeUserService; 282 @GuardedBy("mLock") 283 private int mShutdownPrepareTimeMs = MIN_MAX_GARAGE_MODE_DURATION_MS; 284 @GuardedBy("mLock") 285 private int mShutdownPollingIntervalMs = SHUTDOWN_POLLING_INTERVAL_MS; 286 @GuardedBy("mLock") 287 private boolean mRebootAfterGarageMode; 288 @GuardedBy("mLock") 289 private boolean mGarageModeShouldExitImmediately; 290 // TODO(b/286303350): remove once power policy refactor complete 291 @GuardedBy("mLock") 292 private ICarPowerPolicySystemNotification mCarPowerPolicyDaemon; 293 // TODO(b/286303350): rename "mCarPowerPolicyDaemon" once power policy refactor complete 294 @GuardedBy("mLock") 295 private ICarPowerPolicyDelegate mRefactoredCarPowerPolicyDaemon; 296 @GuardedBy("mLock") 297 private boolean mConnectionInProgress; 298 // After ICarPowerPolicyDelegateCallback is set, mReadyForCallback is set to true; 299 private AtomicBoolean mReadyForCallback = new AtomicBoolean(false); 300 private BinderHandler mBinderHandler; 301 private boolean mPowerPoliciesInitialized; 302 // TODO(b/286303350): remove after policy refactor, since daemon will be source of truth 303 @GuardedBy("mLock") 304 private String mCurrentPowerPolicyId; 305 // TODO(b/286303350): remove after policy refactor, since daemon will control power policy 306 @GuardedBy("mLock") 307 private String mPendingPowerPolicyId; 308 @GuardedBy("mLock") 309 private String mCurrentPowerPolicyGroupId; 310 @GuardedBy("mLock") 311 private boolean mIsPowerPolicyLocked; 312 // TODO(b/286303350): remove after policy refactor, since daemon will control power policy 313 @GuardedBy("mLock") 314 private boolean mHasControlOverDaemon; 315 private final CountDownLatch mPowerPolicyInitializationLatch = new CountDownLatch(1); 316 @GuardedBy("mLock") 317 private CarPowerPolicy mCurrentAccumulatedPowerPolicy = getInitialAccumulatedPowerPolicy(); 318 private AtomicBoolean mIsListenerWaitingCancelled = new AtomicBoolean(false); 319 private final Semaphore mListenerCompletionSem = new Semaphore(/* permits= */ 0); 320 @GuardedBy("mLock") 321 @CarPowerManager.CarPowerState 322 private int mStateForCompletion = CarPowerManager.STATE_INVALID; 323 @GuardedBy("mLock") 324 @CarRemoteAccessManager.NextPowerState 325 private int mLastShutdownState = CarRemoteAccessManager.NEXT_POWER_STATE_OFF; 326 327 @GuardedBy("mLock") 328 @Nullable 329 private ICarResultReceiver mFactoryResetCallback; 330 @GuardedBy("mLock") 331 private boolean mIsEmergencyShutdown; 332 333 private final PowerManagerCallbackList<ICarPowerPolicyListener> mPowerPolicyListeners = 334 new PowerManagerCallbackList<>( 335 l -> CarPowerManagementService.this.mPowerPolicyListeners.unregister(l)); 336 337 private final PowerComponentHandler mPowerComponentHandler; 338 private final PolicyReader mPolicyReader = new PolicyReader(); 339 private final SilentModeHandler mSilentModeHandler; 340 private final ScreenOffHandler mScreenOffHandler; 341 342 // Allows for injecting feature flag values during testing 343 private FeatureFlags mFeatureFlags = new FeatureFlagsImpl(); 344 @GuardedBy("mSimulationWaitObject") 345 private boolean mBlockFromSimulatedCancelEvent; 346 347 @VisibleForTesting readPowerPolicyFromXml(InputStream inputStream)348 void readPowerPolicyFromXml(InputStream inputStream) 349 throws IOException, PolicyReader.PolicyXmlException, XmlPullParserException { 350 mPolicyReader.readPowerPolicyFromXml(inputStream); 351 Integer[] customComponents = 352 new Integer[mPolicyReader.getCustomComponents().values().size()]; 353 mPolicyReader.getCustomComponents().values().toArray(customComponents); 354 mPowerComponentHandler.registerCustomComponents(customComponents); 355 } 356 357 interface ActionOnDeath<T extends IInterface> { take(T listener)358 void take(T listener); 359 } 360 361 private static final class PowerManagerCallbackList<T extends IInterface> extends 362 RemoteCallbackList<T> { 363 private ActionOnDeath<T> mActionOnDeath; 364 PowerManagerCallbackList(ActionOnDeath<T> action)365 PowerManagerCallbackList(ActionOnDeath<T> action) { 366 mActionOnDeath = action; 367 } 368 369 /** 370 * Old version of {@link #onCallbackDied(E, Object)} that 371 * does not provide a cookie. 372 */ 373 @Override onCallbackDied(T listener)374 public void onCallbackDied(T listener) { 375 Slogf.i(TAG, "binderDied %s", listener.asBinder()); 376 mActionOnDeath.take(listener); 377 } 378 } 379 380 /** 381 * Builder for {@link android.car.power.CarPowerManagementService}. 382 */ 383 public static final class Builder { 384 private Context mContext; 385 private PowerHalService mPowerHalService; 386 private SystemInterface mSystemInterface; 387 private UserManager mUserManager; 388 private CarUserService mCarUserService; 389 private PowerComponentHandler mPowerComponentHandler; 390 private @Nullable IInterface mPowerPolicyDaemon; 391 private @Nullable FeatureFlags mFeatureFlags; 392 private @Nullable ScreenOffHandler mScreenOffHandler; 393 private @Nullable String mSilentModeHwStatePath; 394 private @Nullable String mSilentModeKernelStatePath; 395 private @Nullable String mBootReason; 396 private Resources mResources; 397 private boolean mBuilt; 398 399 /** 400 * Sets the {@link Context}. 401 */ setContext(Context context)402 public Builder setContext(Context context) { 403 mContext = context; 404 return this; 405 } 406 407 /** 408 * Sets the {@link PowerHalService}. 409 */ setPowerHalService(PowerHalService powerHalService)410 public Builder setPowerHalService(PowerHalService powerHalService) { 411 mPowerHalService = powerHalService; 412 return this; 413 } 414 415 /** 416 * Sets the {@link SystemInterface}. 417 */ setSystemInterface(SystemInterface systemInterface)418 public Builder setSystemInterface(SystemInterface systemInterface) { 419 mSystemInterface = systemInterface; 420 return this; 421 } 422 423 /** 424 * Sets the {@link CarUserService}. 425 */ setCarUserService(CarUserService carUserService)426 public Builder setCarUserService(CarUserService carUserService) { 427 mCarUserService = carUserService; 428 return this; 429 } 430 431 /** 432 * Sets the {@link IInterface} for power policy daemon. 433 */ setPowerPolicyDaemon(@ullable IInterface powerPolicyDaemon)434 public Builder setPowerPolicyDaemon(@Nullable IInterface powerPolicyDaemon) { 435 mPowerPolicyDaemon = powerPolicyDaemon; 436 return this; 437 } 438 439 /** 440 * Builds the object. 441 */ build()442 public CarPowerManagementService build() { 443 if (mBuilt) { 444 throw new IllegalStateException("Only allowed to be built once"); 445 } 446 mBuilt = true; 447 return new CarPowerManagementService(this); 448 } 449 450 /** 451 * Sets the {@link PowerComponentHandler}. 452 */ 453 @VisibleForTesting setPowerComponentHandler(PowerComponentHandler powerComponentHandler)454 public Builder setPowerComponentHandler(PowerComponentHandler powerComponentHandler) { 455 mPowerComponentHandler = powerComponentHandler; 456 return this; 457 } 458 459 /** 460 * Sets the {@link UserManager}. 461 */ 462 @VisibleForTesting setUserManager(UserManager userManager)463 public Builder setUserManager(UserManager userManager) { 464 mUserManager = userManager; 465 return this; 466 } 467 468 /** 469 * Sets the {@link FeatureFlags}. 470 */ 471 @VisibleForTesting setFeatureFlags(FeatureFlags featureFlags)472 public Builder setFeatureFlags(FeatureFlags featureFlags) { 473 mFeatureFlags = featureFlags; 474 return this; 475 } 476 477 /** 478 * Sets the {@link ScreenOffHandler}. 479 */ 480 @VisibleForTesting setScreenOffHandler(ScreenOffHandler screenOffHandler)481 public Builder setScreenOffHandler(ScreenOffHandler screenOffHandler) { 482 mScreenOffHandler = screenOffHandler; 483 return this; 484 } 485 486 /** 487 * Sets the silent mode hardware state path. 488 */ 489 @VisibleForTesting setSilentModeHwStatePath(String silentModeHwStatePath)490 public Builder setSilentModeHwStatePath(String silentModeHwStatePath) { 491 mSilentModeHwStatePath = silentModeHwStatePath; 492 return this; 493 } 494 495 /** 496 * Sets the silent mode kernel state path. 497 */ 498 @VisibleForTesting setSilentModeKernelStatePath(String silentModeKernelStatePath)499 public Builder setSilentModeKernelStatePath(String silentModeKernelStatePath) { 500 mSilentModeKernelStatePath = silentModeKernelStatePath; 501 return this; 502 } 503 504 /** 505 * Sets the boot reason. 506 */ 507 @VisibleForTesting setBootReason(String bootReason)508 public Builder setBootReason(String bootReason) { 509 mBootReason = bootReason; 510 return this; 511 } 512 513 /** 514 * Sets the {@link Resources}. 515 */ 516 @VisibleForTesting setResources(Resources resources)517 public Builder setResources(Resources resources) { 518 mResources = resources; 519 return this; 520 } 521 } 522 CarPowerManagementService(Context context, PowerHalService powerHalService, SystemInterface systemInterface, CarUserService carUserService, IInterface powerPolicyDaemon)523 public CarPowerManagementService(Context context, PowerHalService powerHalService, 524 SystemInterface systemInterface, CarUserService carUserService, 525 IInterface powerPolicyDaemon) { 526 this(new Builder().setContext(context).setPowerHalService(powerHalService) 527 .setSystemInterface(systemInterface).setCarUserService(carUserService) 528 .setPowerPolicyDaemon(powerPolicyDaemon)); 529 } 530 CarPowerManagementService(Builder builder)531 private CarPowerManagementService(Builder builder) { 532 mContext = Objects.requireNonNull(builder.mContext); 533 mHal = Objects.requireNonNull(builder.mPowerHalService); 534 mSystemInterface = Objects.requireNonNull(builder.mSystemInterface); 535 mUserManager = Objects.requireNonNullElseGet(builder.mUserManager, 536 () -> builder.mContext.getSystemService(UserManager.class)); 537 Resources resources = Objects.requireNonNullElseGet(builder.mResources, 538 () -> builder.mContext.getResources()); 539 mShutdownPrepareTimeMs = resources.getInteger( 540 R.integer.maxGarageModeRunningDurationInSecs) * 1000; 541 mSwitchGuestUserBeforeSleep = resources.getBoolean( 542 R.bool.config_switchGuestUserBeforeGoingSleep); 543 if (mShutdownPrepareTimeMs < MIN_MAX_GARAGE_MODE_DURATION_MS) { 544 Slogf.w(TAG, 545 "maxGarageModeRunningDurationInSecs smaller than minimum required, " 546 + "resource:%d(ms) while should exceed:%d(ms), Ignore resource.", 547 mShutdownPrepareTimeMs, MIN_MAX_GARAGE_MODE_DURATION_MS); 548 mShutdownPrepareTimeMs = MIN_MAX_GARAGE_MODE_DURATION_MS; 549 } 550 mUserService = Objects.requireNonNull(builder.mCarUserService); 551 if (builder.mFeatureFlags != null) { 552 mFeatureFlags = builder.mFeatureFlags; 553 } 554 // In a real situation, this should be null. 555 IInterface powerPolicyDaemon = builder.mPowerPolicyDaemon; 556 if (mFeatureFlags.carPowerPolicyRefactoring()) { 557 mRefactoredCarPowerPolicyDaemon = (ICarPowerPolicyDelegate) powerPolicyDaemon; 558 mPowerPoliciesInitialized = false; 559 } else { 560 mCarPowerPolicyDaemon = (ICarPowerPolicySystemNotification) powerPolicyDaemon; 561 if (powerPolicyDaemon != null) { 562 // For testing purpose 563 mHasControlOverDaemon = true; 564 } 565 } 566 mWifiManager = mContext.getSystemService(WifiManager.class); 567 mTetheringManager = mContext.getSystemService(TetheringManager.class); 568 mWifiStateFile = new AtomicFile( 569 new File(mSystemInterface.getSystemCarDir(), WIFI_STATE_FILENAME)); 570 mTetheringStateFile = new AtomicFile( 571 new File(mSystemInterface.getSystemCarDir(), TETHERING_STATE_FILENAME)); 572 mWifiAdjustmentForSuspend = isWifiAdjustmentForSuspendConfig(); 573 mPowerComponentHandler = Objects.requireNonNullElseGet(builder.mPowerComponentHandler, 574 () -> new PowerComponentHandler(mContext, mSystemInterface)); 575 mSilentModeHandler = new SilentModeHandler(this, mFeatureFlags, 576 builder.mSilentModeHwStatePath, builder.mSilentModeKernelStatePath, 577 builder.mBootReason); 578 mMaxSuspendWaitDurationMs = Math.max(MIN_SUSPEND_WAIT_DURATION_MS, 579 Math.min(getMaxSuspendWaitDurationConfig(), MAX_SUSPEND_WAIT_DURATION_MS)); 580 mScreenOffHandler = Objects.requireNonNullElseGet(builder.mScreenOffHandler, () -> 581 new ScreenOffHandler(mContext, mSystemInterface, mHandler.getLooper())); 582 } 583 584 /** 585 * Overrides timers to keep testing time short. 586 * 587 * <p>Passing in {@code 0} resets the value to the default. 588 */ 589 @VisibleForTesting setShutdownTimersForTest(int pollingIntervalMs, int shutdownTimeoutMs)590 public void setShutdownTimersForTest(int pollingIntervalMs, int shutdownTimeoutMs) { 591 synchronized (mLock) { 592 mShutdownPollingIntervalMs = 593 (pollingIntervalMs == 0) ? SHUTDOWN_POLLING_INTERVAL_MS : pollingIntervalMs; 594 mShutdownPrepareTimeMs = 595 (shutdownTimeoutMs == 0) ? SHUTDOWN_EXTEND_MAX_MS : shutdownTimeoutMs; 596 } 597 } 598 599 @VisibleForTesting getHandlerThread()600 protected HandlerThread getHandlerThread() { 601 return mHandlerThread; 602 } 603 604 @Override init()605 public void init() { 606 mPolicyReader.init(mFeatureFlags); 607 mPowerComponentHandler.init(mPolicyReader.getCustomComponents()); 608 mHal.setListener(this); 609 mSystemInterface.init(this, mUserService); 610 mScreenOffHandler.init(); 611 if (mHal.isPowerStateSupported()) { 612 // Initialize CPMS in WAIT_FOR_VHAL state 613 onApPowerStateChange(CpmsState.WAIT_FOR_VHAL, CarPowerManager.STATE_WAIT_FOR_VHAL); 614 } else { 615 Slogf.w(TAG, "Vehicle hal does not support power state yet."); 616 onApPowerStateChange(CpmsState.ON, CarPowerManager.STATE_ON); 617 } 618 mSystemInterface.startDisplayStateMonitoring(); 619 connectToPowerPolicyDaemon(); 620 } 621 622 @Override release()623 public void release() { 624 if (mBinderHandler != null) { 625 mBinderHandler.unlinkToDeath(); 626 } 627 mReadyForCallback.set(false); 628 synchronized (mLock) { 629 clearWaitingForCompletion(/*clearQueue=*/false); 630 mCurrentState = null; 631 if (mFeatureFlags.carPowerPolicyRefactoring()) { 632 mRefactoredCarPowerPolicyDaemon = null; 633 } else { 634 mCarPowerPolicyDaemon = null; 635 } 636 mHandler.cancelAll(); 637 mListenersWeAreWaitingFor.clear(); 638 } 639 mSystemInterface.stopDisplayStateMonitoring(); 640 mPowerManagerListeners.kill(); 641 mPowerPolicyListeners.kill(); 642 forEachDisplay(mContext, mSystemInterface::releaseAllWakeLocks); 643 } 644 645 @Override 646 @ExcludeFromCodeCoverageGeneratedReport(reason = DUMP_INFO) dump(IndentingPrintWriter writer)647 public void dump(IndentingPrintWriter writer) { 648 synchronized (mLock) { 649 writer.println("*CarPowerManagementService*"); 650 writer.printf("mCurrentState: %s\n", mCurrentState); 651 writer.printf("mShutdownStartTime: %d\n", mShutdownStartTime); 652 writer.printf("mLastSleepEntryTime: %d\n", mLastSleepEntryTime); 653 writer.printf("mNextWakeupSec: %d\n", mNextWakeupSec); 654 writer.printf("mShutdownOnNextSuspend: %b\n", mShutdownOnNextSuspend); 655 writer.printf("mActionOnFinish: %s\n", actionOnFinishToString(mActionOnFinish)); 656 writer.printf("mShutdownPollingIntervalMs: %d\n", mShutdownPollingIntervalMs); 657 writer.printf("mShutdownPrepareTimeMs: %d\n", mShutdownPrepareTimeMs); 658 writer.printf("mRebootAfterGarageMode: %b\n", mRebootAfterGarageMode); 659 writer.printf("mSwitchGuestUserBeforeSleep: %b\n", mSwitchGuestUserBeforeSleep); 660 writer.printf("mCurrentPowerPolicyId: %s\n", mCurrentPowerPolicyId); 661 writer.printf("mPendingPowerPolicyId: %s\n", mPendingPowerPolicyId); 662 writer.printf("mCurrentPowerPolicyGroupId: %s\n", mCurrentPowerPolicyGroupId); 663 writer.printf("mIsPowerPolicyLocked: %b\n", mIsPowerPolicyLocked); 664 writer.printf("mMaxSuspendWaitDurationMs: %d\n", mMaxSuspendWaitDurationMs); 665 writer.printf("config_maxSuspendWaitDuration: %d\n", getMaxSuspendWaitDurationConfig()); 666 writer.printf("mWifiStateFile: %s\n", mWifiStateFile); 667 writer.printf("mTetheringStateFile: %s\n", mTetheringStateFile); 668 writer.printf("mWifiAdjustmentForSuspend: %b\n", mWifiAdjustmentForSuspend); 669 writer.printf("# of power policy change listener: %d\n", 670 mPowerPolicyListeners.getRegisteredCallbackCount()); 671 writer.printf("mFactoryResetCallback: %s\n", mFactoryResetCallback); 672 writer.printf("mIsListenerWaitingCancelled: %b\n", mIsListenerWaitingCancelled.get()); 673 writer.printf("kernel support S2R: %b\n", 674 mSystemInterface.isSystemSupportingDeepSleep()); 675 writer.printf("kernel support S2D: %b\n", 676 mSystemInterface.isSystemSupportingHibernation()); 677 writer.printf("mLastShutdownState: %d\n", mLastShutdownState); 678 writer.printf("mReadyForCallback: %b\n", mReadyForCallback.get()); 679 } 680 681 synchronized (mSimulationWaitObject) { 682 writer.printf("mWakeFromSimulatedSleep: %b\n", mWakeFromSimulatedSleep); 683 writer.printf("mInSimulatedDeepSleepMode: %b\n", mInSimulatedDeepSleepMode); 684 writer.printf("mResumeDelayFromSimulatedSuspendSec: %d\n", 685 mResumeDelayFromSimulatedSuspendSec); 686 writer.printf("mFreeMemoryBeforeSuspend: %b\n", mFreeMemoryBeforeSuspend); 687 } 688 689 mPolicyReader.dump(writer); 690 mPowerComponentHandler.dump(writer); 691 mSilentModeHandler.dump(writer); 692 mScreenOffHandler.dump(writer); 693 } 694 695 @Override 696 @ExcludeFromCodeCoverageGeneratedReport(reason = DUMP_INFO) dumpProto(ProtoOutputStream proto)697 public void dumpProto(ProtoOutputStream proto) { 698 synchronized (mLock) { 699 long currentStateToken = proto.start(CarPowerDumpProto.CURRENT_STATE); 700 proto.write(CpmsStateProto.CAN_POSTPONE, mCurrentState.mCanPostpone); 701 proto.write(CpmsStateProto.CAR_POWER_MANAGER_STATE, 702 mCurrentState.mCarPowerStateListenerState); 703 proto.write(CpmsStateProto.SHUTDOWN_TYPE, mCurrentState.mShutdownType); 704 proto.write(CpmsStateProto.STATE, mCurrentState.mState); 705 proto.write(CpmsStateProto.STATE_NAME, mCurrentState.stateToString()); 706 proto.end(currentStateToken); 707 proto.write(CarPowerDumpProto.SHUTDOWN_START_TIME, mShutdownStartTime); 708 proto.write(CarPowerDumpProto.LAST_SLEEP_ENTRY_TIME, mLastSleepEntryTime); 709 proto.write(CarPowerDumpProto.NEXT_WAKEUP_SEC, mNextWakeupSec); 710 proto.write(CarPowerDumpProto.SHUTDOWN_ON_NEXT_SUSPEND, mShutdownOnNextSuspend); 711 proto.write( 712 CarPowerDumpProto.ACTION_ON_FINISH, actionOnFinishToString(mActionOnFinish)); 713 proto.write(CarPowerDumpProto.SHUTDOWN_POLLING_INTERVAL_MS, mShutdownPollingIntervalMs); 714 proto.write(CarPowerDumpProto.SHUTDOWN_PREPARE_TIME_MS, mShutdownPrepareTimeMs); 715 proto.write(CarPowerDumpProto.REBOOT_AFTER_GARAGE_MODE, mRebootAfterGarageMode); 716 proto.write( 717 CarPowerDumpProto.SWITCH_GUEST_USER_BEFORE_SLEEP, mSwitchGuestUserBeforeSleep); 718 proto.write(CarPowerDumpProto.CURRENT_POWER_POLICY_ID, mCurrentPowerPolicyId); 719 proto.write(CarPowerDumpProto.PENDING_POWER_POLICY_ID, mPendingPowerPolicyId); 720 proto.write( 721 CarPowerDumpProto.CURRENT_POWER_POLICY_GROUP_ID, mCurrentPowerPolicyGroupId); 722 proto.write(CarPowerDumpProto.IS_POWER_POLICY_LOCKED, mIsPowerPolicyLocked); 723 proto.write(CarPowerDumpProto.MAX_SUSPEND_WAIT_DURATION_MS, mMaxSuspendWaitDurationMs); 724 proto.write(CarPowerDumpProto.MAX_SUSPEND_WAIT_DURATION_CONFIG, 725 getMaxSuspendWaitDurationConfig()); 726 proto.write(CarPowerDumpProto.WIFI_STATE_FILE, mWifiStateFile.toString()); 727 proto.write(CarPowerDumpProto.TETHERING_STATE_FILE, mTetheringStateFile.toString()); 728 proto.write(CarPowerDumpProto.WIFI_ADJUSTMENT_FOR_SUSPEND, mWifiAdjustmentForSuspend); 729 proto.write(CarPowerDumpProto.POWER_POLICY_LISTENERS, 730 mPowerPolicyListeners.getRegisteredCallbackCount()); 731 proto.write(CarPowerDumpProto.FACTORY_RESET_CALLBACK, 732 mFactoryResetCallback != null ? mFactoryResetCallback.toString() : ""); 733 proto.write(CarPowerDumpProto.IS_LISTENER_WAITING_CANCELLED, 734 mIsListenerWaitingCancelled.get()); 735 proto.write(CarPowerDumpProto.KERNEL_SUPPORTS_DEEP_SLEEP, 736 mSystemInterface.isSystemSupportingDeepSleep()); 737 proto.write(CarPowerDumpProto.KERNEL_SUPPORTS_HIBERNATION, 738 mSystemInterface.isSystemSupportingHibernation()); 739 } 740 741 synchronized (mSimulationWaitObject) { 742 proto.write(CarPowerDumpProto.WAKE_FROM_SIMULATED_SLEEP, mWakeFromSimulatedSleep); 743 proto.write(CarPowerDumpProto.IN_SIMULATED_DEEP_SLEEP_MODE, mInSimulatedDeepSleepMode); 744 proto.write(CarPowerDumpProto.RESUME_DELAY_FROM_SIMULATED_SUSPEND_SEC, 745 mResumeDelayFromSimulatedSuspendSec); 746 proto.write(CarPowerDumpProto.FREE_MEMORY_BEFORE_SUSPEND, mFreeMemoryBeforeSuspend); 747 } 748 749 mPolicyReader.dumpProto(proto); 750 mPowerComponentHandler.dumpProto(proto); 751 mSilentModeHandler.dumpProto(proto); 752 mScreenOffHandler.dumpProto(proto); 753 } 754 755 @Override onApPowerStateChange(PowerState state)756 public void onApPowerStateChange(PowerState state) { 757 EventLogHelper.writeCarPowerManagerStateRequest(state.mState, state.mParam); 758 synchronized (mLock) { 759 mPendingPowerStates.addFirst(new CpmsState(state)); 760 mLock.notifyAll(); 761 } 762 mHandler.handlePowerStateChange(); 763 } 764 765 @VisibleForTesting setStateForWakeUp()766 void setStateForWakeUp() { 767 mSilentModeHandler.init(); 768 synchronized (mLock) { 769 mShouldResumeUserService = true; 770 } 771 handleWaitForVhal(new CpmsState(CpmsState.WAIT_FOR_VHAL, 772 CarPowerManager.STATE_WAIT_FOR_VHAL, /* canPostpone= */ false)); 773 Slogf.d(TAG, 774 "setStateForTesting(): mShouldResumeUserService is set to false and power state " 775 + "is switched " 776 + "to Wait For Vhal"); 777 } 778 779 /** 780 * Initiate state change from CPMS directly. 781 */ onApPowerStateChange(int apState, @CarPowerManager.CarPowerState int carPowerStateListenerState)782 private void onApPowerStateChange(int apState, 783 @CarPowerManager.CarPowerState int carPowerStateListenerState) { 784 CpmsState newState = new CpmsState(apState, carPowerStateListenerState, 785 /* canPostpone= */ false); 786 BiFunction<CpmsState, CpmsState, Boolean> eventFilter = null; 787 788 // We are ready to shut down. Suppress this transition if 789 // there is a request to cancel the shutdown (WAIT_FOR_VHAL). 790 // Completely ignore this WAIT_FOR_FINISH 791 if (newState.mState == CpmsState.WAIT_FOR_FINISH) { 792 eventFilter = (stateToAdd, pendingSate) -> 793 stateToAdd.mState == CpmsState.WAIT_FOR_FINISH 794 && pendingSate.mState == CpmsState.WAIT_FOR_VHAL; 795 } 796 797 // Check if there is another pending SHUTDOWN_PREPARE. 798 // This could happen, when another SHUTDOWN_PREPARE request is received from VHAL 799 // while notifying PRE_SHUTDOWN_PREPARE. 800 // If SHUTDOWN_PREPARE request already exist in the queue, and it skips Garage Mode, 801 // then newState is ignored . 802 if (newState.mState == CpmsState.SHUTDOWN_PREPARE) { 803 eventFilter = (stateToAdd, pendingState) -> 804 pendingState.mState == CpmsState.SHUTDOWN_PREPARE 805 && !pendingState.mCanPostpone 806 && pendingState.mCarPowerStateListenerState 807 == STATE_PRE_SHUTDOWN_PREPARE; 808 } 809 810 synchronized (mLock) { 811 // If eventFilter exists, lets check if event that satisfies filter is in queue. 812 if (eventFilter != null) { 813 for (int idx = 0; idx < mPendingPowerStates.size(); idx++) { 814 CpmsState pendingState = mPendingPowerStates.get(idx); 815 if (eventFilter.apply(newState, pendingState)) { 816 return; 817 } 818 } 819 } 820 mPendingPowerStates.addFirst(newState); 821 mLock.notifyAll(); 822 } 823 mHandler.handlePowerStateChange(); 824 } 825 doHandlePowerStateChange()826 private void doHandlePowerStateChange() { 827 CpmsState newState; 828 CpmsState prevState; 829 synchronized (mLock) { 830 prevState = mCurrentState; 831 newState = mPendingPowerStates.pollFirst(); 832 if (newState == null) { 833 Slogf.w(TAG, "No more power state to process"); 834 return; 835 } 836 Slogf.i(TAG, "doHandlePowerStateChange: newState=%s", newState.name()); 837 if (!needPowerStateChangeLocked(newState)) { 838 // We may need to process the pending power state request. 839 if (!mPendingPowerStates.isEmpty()) { 840 Slogf.i(TAG, "There is a pending power state change request. requesting the " 841 + "processing..."); 842 mHandler.handlePowerStateChange(); 843 } 844 return; 845 } 846 847 // now real power change happens. Whatever was queued before should be all cancelled. 848 mPendingPowerStates.clear(); 849 850 // Received updated SHUTDOWN_PREPARE there could be several reasons for that 851 // 1. CPMS is in SHUTDOWN_PREPARE, and received state change to perform transition 852 // from PRE_SHUTDOWN_PREPARE into SHUTDOWN_PREPARE 853 // 2. New SHUTDOWN_PREPARE request is received, and it is different from existing one. 854 if (newState.mState == CpmsState.SHUTDOWN_PREPARE && newState.mState == prevState.mState 855 && newState.mCarPowerStateListenerState == STATE_PRE_SHUTDOWN_PREPARE) { 856 // Nothing to do here, skipping clearing completion queue 857 } else { 858 clearWaitingForCompletion(/*clearQueue=*/false); 859 } 860 861 mCurrentState = newState; 862 } 863 mHandler.cancelProcessingComplete(); 864 865 Slogf.i(TAG, "setCurrentState %s", newState); 866 CarStatsLogHelper.logPowerState(newState.mState); 867 EventLogHelper.writeCarPowerManagerStateChange(newState.mState); 868 switch (newState.mState) { 869 case CpmsState.WAIT_FOR_VHAL: 870 handleWaitForVhal(newState); 871 break; 872 case CpmsState.ON: 873 handleOn(); 874 break; 875 case CpmsState.SHUTDOWN_PREPARE: 876 handleShutdownPrepare(newState, prevState); 877 break; 878 case CpmsState.SIMULATE_SLEEP: 879 case CpmsState.SIMULATE_HIBERNATION: 880 simulateShutdownPrepare(newState, prevState); 881 break; 882 case CpmsState.WAIT_FOR_FINISH: 883 handleWaitForFinish(newState); 884 break; 885 case CpmsState.SUSPEND: 886 // Received FINISH from VHAL 887 handleFinish(); 888 break; 889 default: 890 // Illegal state 891 // TODO(b/202414427): Add handling of illegal state 892 break; 893 } 894 } 895 notifyPowerStateChangeToDaemon(@arPowerManager.CarPowerState int powerState)896 private void notifyPowerStateChangeToDaemon(@CarPowerManager.CarPowerState int powerState) { 897 ICarPowerPolicyDelegate daemon; 898 synchronized (mLock) { 899 daemon = mRefactoredCarPowerPolicyDaemon; 900 } 901 if (daemon == null) { 902 Slogf.e(TAG, "Failed to notify car power policy daemon of power state change, " 903 + "daemon unavailable"); 904 return; 905 } 906 notifyPowerStateChangeToDaemon(daemon, powerState); 907 } 908 notifyPowerStateChangeToDaemon(ICarPowerPolicyDelegate daemon, @CarPowerManager.CarPowerState int powerState)909 private void notifyPowerStateChangeToDaemon(ICarPowerPolicyDelegate daemon, 910 @CarPowerManager.CarPowerState int powerState) { 911 Slogf.i(TAG, "Notifying CPPD of power state(%s)", powerStateToString(powerState)); 912 913 String powerStateName = powerStateToString(powerState); 914 if (!mReadyForCallback.get()) { 915 Slogf.w(TAG, "Cannot notify power state(%S) of CPPD: not ready for calling to CPPD", 916 powerStateName); 917 return; 918 } 919 AsyncPolicyRequest request = generateAsyncPolicyRequest( 920 DEFAULT_POWER_POLICY_REQUEST_TIMEOUT_MS); 921 int requestId = request.getRequestId(); 922 synchronized (mLock) { 923 mRequestIdToPolicyRequest.put(requestId, request); 924 } 925 try { 926 Slogf.i(TAG, "Request(%d) of applying power policy for power state(%s) to CPPD in " 927 + "async", requestId, powerStateName); 928 daemon.applyPowerPolicyPerPowerStateChangeAsync(requestId, (byte) powerState); 929 boolean policyRequestServed = request.await(); 930 if (!policyRequestServed) { 931 Slogf.w(TAG, "Power policy request (ID: %d) for power state(%s) timed out after %d " 932 + "ms", requestId, powerStateName, DEFAULT_POWER_POLICY_REQUEST_TIMEOUT_MS); 933 return; 934 } 935 } catch (IllegalArgumentException e) { 936 Slogf.w(TAG, e, "Failed to apply power policy for power state(%s)", powerStateName); 937 return; 938 } catch (InterruptedException e) { 939 Slogf.w(TAG, e, "Wait for power policy change request for power state(%s) interrupted", 940 powerStateName); 941 Thread.currentThread().interrupt(); 942 return; 943 } catch (RemoteException e) { 944 Slogf.w(TAG, e, "Failed to apply power policy for power state(%s), connection issue", 945 powerStateName); 946 return; 947 } finally { 948 synchronized (mLock) { 949 mRequestIdToPolicyRequest.remove(requestId); 950 } 951 } 952 if (!request.isSuccessful()) { 953 Slogf.w(TAG, "Failed to apply power policy for power state(%s), failure reason = %d", 954 powerStateName, request.getFailureReason()); 955 return; 956 } 957 if (request.isDeferred()) { 958 Slogf.i(TAG, "Applying power policy for power state(%s) is deferred", powerStateName); 959 return; 960 } 961 CarPowerPolicy accumulatedPolicy = request.getAccumulatedPolicy(); 962 updateCurrentPowerPolicy(accumulatedPolicy); 963 notifyPowerPolicyChange(accumulatedPolicy); 964 } 965 handleWaitForVhal(CpmsState state)966 private void handleWaitForVhal(CpmsState state) { 967 @CarPowerManager.CarPowerState int carPowerStateListenerState = 968 state.mCarPowerStateListenerState; 969 // TODO(b/177478420): Restore Wifi, Audio, Location, and Bluetooth, if they are artificially 970 // modified for S2R. 971 mSilentModeHandler.querySilentModeHwState(); 972 973 if (mFeatureFlags.carPowerPolicyRefactoring()) { 974 notifyPowerStateChangeToDaemon(CarPowerManager.STATE_WAIT_FOR_VHAL); 975 } else { 976 applyDefaultPowerPolicyForState(CarPowerManager.STATE_WAIT_FOR_VHAL, 977 PolicyReader.POWER_POLICY_ID_INITIAL_ON); 978 if (!mSilentModeHandler.isSilentMode()) { 979 cancelPreemptivePowerPolicy(); 980 } 981 } 982 983 sendPowerManagerEvent(carPowerStateListenerState, INVALID_TIMEOUT); 984 // Inspect CarPowerStateListenerState to decide which message to send via VHAL 985 int lastShutdownState = CarRemoteAccessManager.NEXT_POWER_STATE_OFF; 986 switch (carPowerStateListenerState) { 987 case CarPowerManager.STATE_WAIT_FOR_VHAL: 988 lastShutdownState = CarRemoteAccessManager.NEXT_POWER_STATE_OFF; 989 mHal.sendWaitForVhal(); 990 break; 991 case CarPowerManager.STATE_SHUTDOWN_CANCELLED: 992 synchronized (mLock) { 993 mShutdownOnNextSuspend = false; // This cancels the "NextSuspend" 994 mIsEmergencyShutdown = false; // TODO add cancel test 995 } 996 mHal.sendShutdownCancel(); 997 Slogf.d(TAG, "reset mIsEmergencyShutdown"); 998 break; 999 case CarPowerManager.STATE_SUSPEND_EXIT: 1000 lastShutdownState = CarRemoteAccessManager.NEXT_POWER_STATE_SUSPEND_TO_RAM; 1001 mHal.sendSleepExit(); 1002 break; 1003 case CarPowerManager.STATE_HIBERNATION_EXIT: 1004 lastShutdownState = CarRemoteAccessManager.NEXT_POWER_STATE_SUSPEND_TO_DISK; 1005 mHal.sendHibernationExit(); 1006 break; 1007 default: 1008 Slogf.w(TAG, "Invalid action when handling wait for VHAL: %d", 1009 carPowerStateListenerState); 1010 break; 1011 } 1012 synchronized (mLock) { 1013 mLastShutdownState = lastShutdownState; 1014 } 1015 if (mWifiAdjustmentForSuspend) { 1016 restoreWifiFully(); 1017 } 1018 } 1019 updateCarUserNoticeServiceIfNecessary()1020 private void updateCarUserNoticeServiceIfNecessary() { 1021 try { 1022 int currentUserId = ActivityManager.getCurrentUser(); 1023 UserHandleHelper userHandleHelper = new UserHandleHelper(mContext, mUserManager); 1024 UserHandle currentUser = userHandleHelper.getExistingUserHandle(currentUserId); 1025 CarUserNoticeService carUserNoticeService = 1026 CarLocalServices.getService(CarUserNoticeService.class); 1027 if (currentUser != null && userHandleHelper.isGuestUser(currentUser) 1028 && carUserNoticeService != null) { 1029 Slogf.i(TAG, "Car user notice service will ignore all messages before user " 1030 + "switch."); 1031 Intent intent = new Intent(); 1032 intent.setComponent(ComponentName.unflattenFromString( 1033 mContext.getResources().getString(R.string.continuousBlankActivity))); 1034 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1035 mContext.startActivityAsUser(intent, UserHandle.CURRENT); 1036 carUserNoticeService.ignoreUserNotice(currentUserId); 1037 } 1038 } catch (Exception e) { 1039 Slogf.w(TAG, e, "Cannot ignore user notice for current user"); 1040 } 1041 } 1042 1043 @VisibleForTesting handleOn()1044 void handleOn() { 1045 if (factoryResetIfNeeded()) return; 1046 1047 // If current user is a Guest User, we want to inform CarUserNoticeService not to show 1048 // notice for current user, and show user notice only for the target user. 1049 if (!mSwitchGuestUserBeforeSleep) { 1050 updateCarUserNoticeServiceIfNecessary(); 1051 } 1052 1053 if (mFeatureFlags.carPowerPolicyRefactoring()) { 1054 notifyPowerStateChangeToDaemon(CarPowerManager.STATE_ON); 1055 } else { 1056 if (!mSilentModeHandler.isSilentMode()) { 1057 cancelPreemptivePowerPolicy(); 1058 } 1059 applyDefaultPowerPolicyForState(VehicleApPowerStateReport.ON, 1060 PolicyReader.POWER_POLICY_ID_ALL_ON); 1061 } 1062 1063 sendPowerManagerEvent(CarPowerManager.STATE_ON, INVALID_TIMEOUT); 1064 1065 mHal.sendOn(); 1066 1067 synchronized (mLock) { 1068 if (!mShouldResumeUserService) { 1069 Slogf.d(TAG, "handleOn(): called on boot"); 1070 return; 1071 } else { 1072 mShouldResumeUserService = false; 1073 } 1074 } 1075 1076 try { 1077 mUserService.onResume(); 1078 } catch (Exception e) { 1079 Slogf.e(TAG, e, "Could not switch user on resume"); 1080 } 1081 } 1082 factoryResetIfNeeded()1083 private boolean factoryResetIfNeeded() { 1084 ICarResultReceiver callback; 1085 synchronized (mLock) { 1086 if (mFactoryResetCallback == null) return false; 1087 callback = mFactoryResetCallback; 1088 } 1089 1090 try { 1091 Slogf.i(TAG, "Factory resetting as it was delayed by user"); 1092 callback.send(/* resultCode= */ 0, /* resultData= */ null); 1093 return true; 1094 } catch (Exception e) { 1095 Slogf.wtf(TAG, e, "Should have factory reset, but failed"); 1096 return false; 1097 } 1098 } 1099 1100 // TODO(b/286303350): remove once power policy refactor is complete, CPPD will handle applying 1101 // default power policies according to state applyDefaultPowerPolicyForState(@arPowerManager.CarPowerState int state, @Nullable String fallbackPolicyId)1102 private void applyDefaultPowerPolicyForState(@CarPowerManager.CarPowerState int state, 1103 @Nullable String fallbackPolicyId) { 1104 Slogf.i(TAG, "Applying the default power policy for %s", powerStateToString(state)); 1105 CarPowerPolicy policy; 1106 synchronized (mLock) { 1107 policy = mPolicyReader 1108 .getDefaultPowerPolicyForState(mCurrentPowerPolicyGroupId, state); 1109 } 1110 if (policy == null && fallbackPolicyId == null) { 1111 Slogf.w(TAG, "No default power policy for %s is found", powerStateToString(state)); 1112 return; 1113 } 1114 String policyId = policy == null ? fallbackPolicyId : policy.getPolicyId(); 1115 applyPowerPolicy(policyId, /* delayNotification= */ false, /* upToDaemon= */ true, 1116 /* force= */ false); 1117 } 1118 1119 /** 1120 * Sets the callback used to factory reset the device on resume when the user delayed it. 1121 */ setFactoryResetCallback(ICarResultReceiver callback)1122 public void setFactoryResetCallback(ICarResultReceiver callback) { 1123 synchronized (mLock) { 1124 mFactoryResetCallback = callback; 1125 } 1126 } 1127 1128 /** 1129 * Tells Garage Mode if it should run normally, or just 1130 * exit immediately without indicating 'idle' 1131 * @return True if no idle jobs should be run 1132 * @hide 1133 */ garageModeShouldExitImmediately()1134 public boolean garageModeShouldExitImmediately() { 1135 synchronized (mLock) { 1136 return mGarageModeShouldExitImmediately; 1137 } 1138 } 1139 1140 /** 1141 * This method is required for testing 1142 * Gets {@code PolicyReader} that reads {@code power_policy.xml}. 1143 * @return {@link PolicyReader} 1144 */ 1145 @VisibleForTesting getPolicyReader()1146 public PolicyReader getPolicyReader() { 1147 return mPolicyReader; 1148 } 1149 handleShutdownPrepare(CpmsState currentState, CpmsState prevState)1150 private void handleShutdownPrepare(CpmsState currentState, CpmsState prevState) { 1151 switch (currentState.mCarPowerStateListenerState) { 1152 case CarPowerManager.STATE_PRE_SHUTDOWN_PREPARE: 1153 updateShutdownPrepareStatus(currentState); 1154 if (prevState.mCarPowerStateListenerState == STATE_SHUTDOWN_PREPARE) { 1155 // Received request to update SHUTDOWN target 1156 currentState = new CpmsState(currentState.mState, 1157 prevState.mCarPowerStateListenerState, 1158 prevState.mCanPostpone, currentState.mShutdownType); 1159 synchronized (mLock) { 1160 mCurrentState = currentState; 1161 } 1162 clearWaitingForCompletion(/*clearQueue=*/true); 1163 } else if (prevState.mCarPowerStateListenerState == STATE_PRE_SHUTDOWN_PREPARE) { 1164 // Update of state occurred while in PRE_SHUTDOWN_PREPARE 1165 boolean areListenersEmpty; 1166 synchronized (mLock) { 1167 areListenersEmpty = mListenersWeAreWaitingFor.isEmpty(); 1168 } 1169 if (areListenersEmpty) { 1170 handleCoreShutdownPrepare(); 1171 } else { 1172 // PRE_SHUTDOWN_PREPARE is still being processed, no actions required 1173 return; 1174 } 1175 } else { 1176 handlePreShutdownPrepare(); 1177 } 1178 break; 1179 case CarPowerManager.STATE_SHUTDOWN_PREPARE: 1180 handleCoreShutdownPrepare(); 1181 break; 1182 default: 1183 Slogf.w(TAG, "Not supported listener state(%d)", 1184 currentState.mCarPowerStateListenerState); 1185 } 1186 } 1187 updateShutdownPrepareStatus(CpmsState newState)1188 private void updateShutdownPrepareStatus(CpmsState newState) { 1189 // Shutdown on finish if the system doesn't support deep sleep/hibernation 1190 // or doesn't allow it. 1191 synchronized (mLock) { 1192 if (mShutdownOnNextSuspend || ( 1193 newState.mShutdownType == PowerState.SHUTDOWN_TYPE_POWER_OFF 1194 || newState.mShutdownType == PowerState.SHUTDOWN_TYPE_EMERGENCY)) { 1195 mActionOnFinish = ACTION_ON_FINISH_SHUTDOWN; 1196 } else if (newState.mShutdownType == PowerState.SHUTDOWN_TYPE_DEEP_SLEEP) { 1197 boolean isDeepSleepOnFinish = 1198 isDeepSleepAvailable() || newState.mState == CpmsState.SIMULATE_SLEEP; 1199 mActionOnFinish = isDeepSleepOnFinish ? ACTION_ON_FINISH_DEEP_SLEEP 1200 : ACTION_ON_FINISH_SHUTDOWN; 1201 } else if (newState.mShutdownType == PowerState.SHUTDOWN_TYPE_HIBERNATION) { 1202 boolean isHibernationOnFinish = isHibernationAvailable() 1203 || newState.mState == CpmsState.SIMULATE_HIBERNATION; 1204 mActionOnFinish = isHibernationOnFinish ? ACTION_ON_FINISH_HIBERNATION 1205 : ACTION_ON_FINISH_SHUTDOWN; 1206 } else { 1207 Slogf.wtf(TAG, "handleShutdownPrepare - incorrect state " + newState); 1208 } 1209 mGarageModeShouldExitImmediately = !newState.mCanPostpone; 1210 if (!mIsEmergencyShutdown) { 1211 mIsEmergencyShutdown = newState.mShutdownType == PowerState.SHUTDOWN_TYPE_EMERGENCY; 1212 Slogf.d(TAG, "set mIsEmergencyShutdown to " + mIsEmergencyShutdown); 1213 } else { 1214 // Emergency shutdown can be cancelled only via SHUTDOWN_CANCEL request"); 1215 Slogf.d(TAG, "mIsEmergencyShutdown is already set"); 1216 } 1217 } 1218 } 1219 handlePreShutdownPrepare()1220 private void handlePreShutdownPrepare() { 1221 int intervalMs; 1222 long timeoutMs; 1223 synchronized (mLock) { 1224 intervalMs = mShutdownPollingIntervalMs; 1225 Slogf.i(TAG, mGarageModeShouldExitImmediately 1226 ? "starting shutdown prepare without Garage Mode" 1227 : "starting shutdown prepare with Garage Mode"); 1228 1229 // in case of emergency shutdown CPMS will not wait for 1230 timeoutMs = mIsEmergencyShutdown ? 0 : getPreShutdownPrepareTimeoutConfig(); 1231 } 1232 1233 int state = CarPowerManager.STATE_PRE_SHUTDOWN_PREPARE; 1234 sendPowerManagerEvent(state, timeoutMs); 1235 Runnable taskAtCompletion = () -> { 1236 // The next power state is still SHUTDOWN_PREPARE, and the listener state is 1237 // SHUTDOW_PREPARE. 1238 Slogf.i(TAG, "All listeners completed for %s", powerStateToString(state)); 1239 onApPowerStateChange(CpmsState.SHUTDOWN_PREPARE, 1240 CarPowerManager.STATE_SHUTDOWN_PREPARE); 1241 }; 1242 1243 waitForCompletionWithShutdownPostpone(state, timeoutMs, taskAtCompletion, intervalMs); 1244 } 1245 handleCoreShutdownPrepare()1246 private void handleCoreShutdownPrepare() { 1247 Slogf.i(TAG, "Handling core part of shutdown prepare"); 1248 doShutdownPrepare(); 1249 } 1250 1251 // Simulates system shutdown to suspend simulateShutdownPrepare(CpmsState newState, CpmsState oldState)1252 private void simulateShutdownPrepare(CpmsState newState, CpmsState oldState) { 1253 Slogf.i(TAG, "Simulating shutdown prepare"); 1254 handleShutdownPrepare(newState, oldState); 1255 } 1256 doShutdownPrepare()1257 private void doShutdownPrepare() { 1258 long timeoutMs; 1259 long intervalMs; 1260 boolean isEmergencyShutdown; 1261 synchronized (mLock) { 1262 timeoutMs = mShutdownPrepareTimeMs; 1263 intervalMs = mShutdownPollingIntervalMs; 1264 mShutdownStartTime = SystemClock.elapsedRealtime(); 1265 isEmergencyShutdown = mIsEmergencyShutdown; 1266 } 1267 1268 if (isEmergencyShutdown) { 1269 timeoutMs = 0; // do not wait for listeners to complete during emergency shutdown 1270 } else if (BuildHelper.isUserDebugBuild() || BuildHelper.isEngBuild()) { 1271 int shutdownPrepareTimeOverrideInSecs = 1272 SystemProperties.getInt(PROP_MAX_GARAGE_MODE_DURATION_OVERRIDE, -1); 1273 if (shutdownPrepareTimeOverrideInSecs >= 0) { 1274 timeoutMs = shutdownPrepareTimeOverrideInSecs * 1000L; 1275 } 1276 } 1277 makeSureNoUserInteraction(); 1278 sendPowerManagerEvent(CarPowerManager.STATE_SHUTDOWN_PREPARE, timeoutMs); 1279 mHal.sendShutdownPrepare(); 1280 waitForShutdownPrepareListenersToComplete(timeoutMs, intervalMs); 1281 } 1282 forceSimulatedCancel()1283 private void forceSimulatedCancel() { 1284 synchronized (mLock) { 1285 mPendingPowerStates.addFirst(new CpmsState(CpmsState.WAIT_FOR_VHAL, 1286 CarPowerManager.STATE_SHUTDOWN_CANCELLED, 1287 /* canPostpone= */ false)); 1288 } 1289 mHandler.handlePowerStateChange(); 1290 synchronized (mSimulationWaitObject) { 1291 mBlockFromSimulatedCancelEvent = true; 1292 mSimulationWaitObject.notifyAll(); 1293 } 1294 } 1295 handleWaitForFinish(CpmsState state)1296 private void handleWaitForFinish(CpmsState state) { 1297 int timeoutMs = getShutdownEnterTimeoutConfig(); 1298 sendPowerManagerEvent(state.mCarPowerStateListenerState, timeoutMs); 1299 Runnable taskAtCompletion = () -> { 1300 Slogf.i(TAG, "All listeners completed for %s", 1301 powerStateToString(state.mCarPowerStateListenerState)); 1302 if (mFeatureFlags.carPowerCancelShellCommand()) { 1303 synchronized (mSimulationWaitObject) { 1304 if (mInSimulatedDeepSleepMode && mCancelDelayFromSimulatedSuspendSec >= 0) { 1305 mHandler.postDelayed(() -> forceSimulatedCancel(), 1306 mCancelDelayFromSimulatedSuspendSec * 1000L); 1307 while (!mBlockFromSimulatedCancelEvent) { 1308 try { 1309 mSimulationWaitObject.wait(); 1310 } catch (InterruptedException ignored) { 1311 Thread.currentThread().interrupt(); // Restore interrupted status 1312 } 1313 } 1314 mInSimulatedDeepSleepMode = false; 1315 return; 1316 } 1317 } 1318 } 1319 int wakeupSec; 1320 synchronized (mLock) { 1321 // If we're shutting down immediately, don't schedule a wakeup time. 1322 wakeupSec = mGarageModeShouldExitImmediately ? 0 : mNextWakeupSec; 1323 } 1324 switch (state.mCarPowerStateListenerState) { 1325 case CarPowerManager.STATE_SUSPEND_ENTER: 1326 mHal.sendSleepEntry(wakeupSec); 1327 break; 1328 case CarPowerManager.STATE_SHUTDOWN_ENTER: 1329 mHal.sendShutdownStart(wakeupSec); 1330 break; 1331 case CarPowerManager.STATE_HIBERNATION_ENTER: 1332 mHal.sendHibernationEntry(wakeupSec); 1333 break; 1334 default: 1335 Slogf.w(TAG, "Invalid action when handling wait for finish: %d", 1336 state.mCarPowerStateListenerState); 1337 break; 1338 } 1339 }; 1340 1341 int intervalMs; 1342 synchronized (mLock) { 1343 intervalMs = mShutdownPollingIntervalMs; 1344 } 1345 1346 waitForCompletionWithShutdownPostpone(state.mCarPowerStateListenerState, timeoutMs, 1347 taskAtCompletion, intervalMs); 1348 } 1349 handleFinish()1350 private void handleFinish() { 1351 int listenerState; 1352 synchronized (mLock) { 1353 switch (mActionOnFinish) { 1354 case ACTION_ON_FINISH_SHUTDOWN: 1355 listenerState = CarPowerManager.STATE_POST_SHUTDOWN_ENTER; 1356 break; 1357 case ACTION_ON_FINISH_DEEP_SLEEP: 1358 listenerState = CarPowerManager.STATE_POST_SUSPEND_ENTER; 1359 break; 1360 case ACTION_ON_FINISH_HIBERNATION: 1361 listenerState = CarPowerManager.STATE_POST_HIBERNATION_ENTER; 1362 break; 1363 default: 1364 Slogf.w(TAG, "Invalid action on finish: %d", mActionOnFinish); 1365 return; 1366 } 1367 } 1368 int timeoutMs = getPostShutdownEnterTimeoutConfig(); 1369 sendPowerManagerEvent(listenerState, timeoutMs); 1370 Runnable taskAtCompletion = () -> { 1371 Slogf.i(TAG, "All listeners completed for %s", powerStateToString(listenerState)); 1372 doHandleFinish(); 1373 }; 1374 Slogf.i(TAG, "Start waiting for listener completion for %s", 1375 powerStateToString(listenerState)); 1376 waitForCompletion(taskAtCompletion, /* taskAtInterval= */ null, timeoutMs, 1377 /* intervalMs= */ -1); 1378 } 1379 doHandleFinish()1380 private void doHandleFinish() { 1381 boolean simulatedMode; 1382 synchronized (mSimulationWaitObject) { 1383 simulatedMode = mInSimulatedDeepSleepMode; 1384 } 1385 boolean mustShutDown; 1386 boolean forceReboot; 1387 synchronized (mLock) { 1388 mustShutDown = (mActionOnFinish == ACTION_ON_FINISH_SHUTDOWN) && !simulatedMode; 1389 forceReboot = mRebootAfterGarageMode; 1390 mRebootAfterGarageMode = false; 1391 } 1392 if (forceReboot) { 1393 PowerManager powerManager = mContext.getSystemService(PowerManager.class); 1394 if (powerManager == null) { 1395 Slogf.wtf(TAG, "No PowerManager. Cannot reboot."); 1396 } else { 1397 Slogf.i(TAG, "GarageMode has completed. Forcing reboot."); 1398 powerManager.reboot("GarageModeReboot"); 1399 throw new AssertionError("Should not return from PowerManager.reboot()"); 1400 } 1401 } 1402 // To make Kernel implementation simpler when going into sleep. 1403 if (mWifiAdjustmentForSuspend) { 1404 disableWifiFully(); 1405 } 1406 1407 if (mustShutDown) { 1408 // shutdown HU 1409 mSystemInterface.shutdown(); 1410 } else { 1411 doHandleSuspend(simulatedMode); 1412 } 1413 synchronized (mLock) { 1414 mShutdownOnNextSuspend = false; 1415 } 1416 } 1417 disableWifiFully()1418 private void disableWifiFully() { 1419 disableWifi(); 1420 disableTethering(); 1421 } 1422 restoreWifiFully()1423 private void restoreWifiFully() { 1424 restoreTethering(); 1425 restoreWifi(); 1426 } 1427 restoreWifi()1428 private void restoreWifi() { 1429 boolean needToRestore = readWifiModifiedState(mWifiStateFile); 1430 if (!needToRestore) return; 1431 if (!mWifiManager.isWifiEnabled()) { 1432 Slogf.i(TAG, "Wifi has been enabled to restore the last setting"); 1433 mWifiManager.setWifiEnabled(true); 1434 } 1435 // Update the persistent data as wifi is not modified by car framework. 1436 saveWifiModifiedState(mWifiStateFile, /* forciblyDisabled= */ false); 1437 } 1438 disableWifi()1439 private void disableWifi() { 1440 boolean wifiEnabled = mWifiManager.isWifiEnabled(); 1441 boolean wifiModifiedState = readWifiModifiedState(mWifiStateFile); 1442 if (wifiEnabled != wifiModifiedState) { 1443 Slogf.i(TAG, "Saving the current Wifi state"); 1444 saveWifiModifiedState(mWifiStateFile, wifiEnabled); 1445 } 1446 1447 // In some devices, enabling a tether temporarily turns off Wifi. To make sure that Wifi is 1448 // disabled, we call this method in all cases. 1449 mWifiManager.setWifiEnabled(false); 1450 Slogf.i(TAG, "Wifi has been disabled and the last setting was saved"); 1451 } 1452 restoreTethering()1453 private void restoreTethering() { 1454 boolean needToRestore = readWifiModifiedState(mTetheringStateFile); 1455 if (!needToRestore) return; 1456 if (!mWifiManager.isWifiApEnabled()) { 1457 Slogf.i(TAG, "Tethering has been enabled to restore the last setting"); 1458 startTethering(); 1459 } 1460 // Update the persistent data as wifi is not modified by car framework. 1461 saveWifiModifiedState(mTetheringStateFile, /*forciblyDisabled= */ false); 1462 } 1463 disableTethering()1464 private void disableTethering() { 1465 boolean tetheringEnabled = mWifiManager.isWifiApEnabled(); 1466 boolean tetheringModifiedState = readWifiModifiedState(mTetheringStateFile); 1467 if (tetheringEnabled != tetheringModifiedState) { 1468 Slogf.i(TAG, "Saving the current tethering state: tetheringEnabled=%b", 1469 tetheringEnabled); 1470 saveWifiModifiedState(mTetheringStateFile, tetheringEnabled); 1471 } 1472 if (!tetheringEnabled) return; 1473 1474 mTetheringManager.stopTethering(TETHERING_WIFI); 1475 Slogf.i(TAG, "Tethering has been disabled and the last setting was saved"); 1476 } 1477 saveWifiModifiedState(AtomicFile file, boolean forciblyDisabled)1478 private void saveWifiModifiedState(AtomicFile file, boolean forciblyDisabled) { 1479 FileOutputStream fos; 1480 try { 1481 fos = file.startWrite(); 1482 } catch (IOException e) { 1483 Slogf.e(TAG, e, "Cannot create %s", file); 1484 return; 1485 } 1486 1487 try (BufferedWriter writer = new BufferedWriter( 1488 new OutputStreamWriter(fos, StandardCharsets.UTF_8))) { 1489 writer.write(forciblyDisabled ? COMPONENT_STATE_MODIFIED : COMPONENT_STATE_ORIGINAL); 1490 writer.newLine(); 1491 writer.flush(); 1492 file.finishWrite(fos); 1493 } catch (IOException e) { 1494 file.failWrite(fos); 1495 Slogf.e(TAG, e, "Writing %s failed", file); 1496 } 1497 } 1498 readWifiModifiedState(AtomicFile file)1499 private boolean readWifiModifiedState(AtomicFile file) { 1500 boolean needToRestore = false; 1501 boolean invalidState = false; 1502 1503 try (BufferedReader reader = new BufferedReader( 1504 new InputStreamReader(file.openRead(), StandardCharsets.UTF_8))) { 1505 String line = reader.readLine(); 1506 if (line == null) { 1507 needToRestore = false; 1508 invalidState = true; 1509 } else { 1510 line = line.trim(); 1511 needToRestore = COMPONENT_STATE_MODIFIED.equals(line); 1512 invalidState = !(needToRestore || COMPONENT_STATE_ORIGINAL.equals(line)); 1513 } 1514 } catch (IOException e) { 1515 // If a file named wifi_state doesn't exist, we will not modify Wifi at system start. 1516 Slogf.w(TAG, "Failed to read %s: %s", file, e); 1517 return false; 1518 } 1519 if (invalidState) { 1520 file.delete(); 1521 } 1522 1523 return needToRestore; 1524 } 1525 startTethering()1526 private void startTethering() { 1527 TetheringRequest request = new TetheringRequest.Builder(TETHERING_WIFI) 1528 .setShouldShowEntitlementUi(false).build(); 1529 mTetheringManager.startTethering(request, mContext.getMainExecutor(), 1530 new TetheringManager.StartTetheringCallback() { 1531 @Override 1532 public void onTetheringFailed(int error) { 1533 Slogf.w(TAG, "Starting tethering failed: %d", error); 1534 } 1535 }); 1536 } 1537 waitForShutdownPrepareListenersToComplete(long timeoutMs, long intervalMs)1538 private void waitForShutdownPrepareListenersToComplete(long timeoutMs, long intervalMs) { 1539 int state = CarPowerManager.STATE_SHUTDOWN_PREPARE; 1540 Runnable taskAtCompletion = () -> { 1541 finishShutdownPrepare(); 1542 Slogf.i(TAG, "All listeners completed for %s", powerStateToString(state)); 1543 }; 1544 1545 waitForCompletionWithShutdownPostpone(state, timeoutMs, taskAtCompletion, intervalMs); 1546 1547 // allowUserSwitch value doesn't matter for onSuspend = true 1548 mUserService.onSuspend(); 1549 synchronized (mLock) { 1550 mShouldResumeUserService = true; 1551 } 1552 } 1553 waitForCompletion(Runnable taskAtCompletion, Runnable taskAtInterval, long timeoutMs, long intervalMs)1554 private void waitForCompletion(Runnable taskAtCompletion, Runnable taskAtInterval, 1555 long timeoutMs, long intervalMs) { 1556 boolean isComplete = false; 1557 synchronized (mLock) { 1558 isComplete = mListenersWeAreWaitingFor.isEmpty(); 1559 } 1560 if (isComplete) { 1561 taskAtCompletion.run(); 1562 } else { 1563 // Reset a flag to signal that waiting for completion is cancelled. 1564 mIsListenerWaitingCancelled.set(false); 1565 waitForCompletionAsync(taskAtCompletion, taskAtInterval, timeoutMs, intervalMs); 1566 } 1567 } 1568 1569 // Waits for listeners to complete. 1570 // If {@code intervalMs} is non-positive value, it is ignored and the method waits up to 1571 // {@code timeoutMs}. waitForCompletionAsync(Runnable taskAtCompletion, Runnable taskAtInterval, long timeoutMs, long intervalMs)1572 private void waitForCompletionAsync(Runnable taskAtCompletion, Runnable taskAtInterval, 1573 long timeoutMs, long intervalMs) { 1574 ExecutorService executor = Executors.newSingleThreadExecutor(); 1575 executor.submit(() -> { 1576 long startTimeMs = SystemClock.elapsedRealtime(); 1577 while (true) { 1578 try { 1579 long waitTimeMs = timeoutMs - (SystemClock.elapsedRealtime() - startTimeMs); 1580 boolean isLastWait = true; 1581 if (intervalMs > 0 && waitTimeMs > intervalMs) { 1582 isLastWait = false; 1583 waitTimeMs = intervalMs; 1584 } 1585 boolean isNotified = mListenerCompletionSem.tryAcquire(waitTimeMs, 1586 TimeUnit.MILLISECONDS); 1587 mListenerCompletionSem.drainPermits(); 1588 if (!isNotified) { 1589 if (isLastWait) { 1590 Slogf.w(TAG, "Waiting for listener completion is timeout(%d)", 1591 waitTimeMs); 1592 taskAtCompletion.run(); 1593 return; 1594 } else if (taskAtInterval != null) { 1595 taskAtInterval.run(); 1596 } 1597 } 1598 boolean isComplete = false; 1599 synchronized (mLock) { 1600 if (mIsListenerWaitingCancelled.get()) { 1601 Slogf.i(TAG, "Waiting for listener completion is cancelled"); 1602 mIsListenerWaitingCancelled.set(false); 1603 return; 1604 } 1605 isComplete = mListenersWeAreWaitingFor.isEmpty(); 1606 } 1607 if (isComplete) { 1608 Slogf.i(TAG, "All listeners completed"); 1609 taskAtCompletion.run(); 1610 mIsListenerWaitingCancelled.set(false); 1611 return; 1612 } 1613 } catch (InterruptedException e) { 1614 Slogf.w(TAG, e, "Thread interrupted while waiting for listener completion"); 1615 Thread.currentThread().interrupt(); 1616 } 1617 } 1618 }); 1619 executor.shutdown(); 1620 } 1621 clearWaitingForCompletion(boolean clearQueue)1622 private void clearWaitingForCompletion(boolean clearQueue) { 1623 if (clearQueue) { 1624 synchronized (mLock) { 1625 mListenersWeAreWaitingFor.clear(); 1626 } 1627 } else { 1628 mIsListenerWaitingCancelled.set(true); 1629 } 1630 1631 mListenerCompletionSem.release(); 1632 } 1633 sendPowerManagerEvent(@arPowerManager.CarPowerState int newState, long timeoutMs)1634 private void sendPowerManagerEvent(@CarPowerManager.CarPowerState int newState, 1635 long timeoutMs) { 1636 // Broadcasts to the listeners that do not signal completion. 1637 notifyListeners(mPowerManagerListeners, newState, INVALID_TIMEOUT); 1638 1639 boolean allowCompletion; 1640 boolean isShutdownPrepare = newState == CarPowerManager.STATE_SHUTDOWN_PREPARE; 1641 long internalListenerExpirationTimeMs = INVALID_TIMEOUT; 1642 long binderListenerExpirationTimeMs = INVALID_TIMEOUT; 1643 1644 // Fully populates mListenersWeAreWaitingFor before calling any onStateChanged() 1645 // for the listeners that signal completion. 1646 // Otherwise, if the first listener calls finish() synchronously, we will 1647 // see the list go empty and we will think that we are done. 1648 PowerManagerCallbackList<ICarPowerStateListener> completingInternalListeners = 1649 new PowerManagerCallbackList(l -> { 1650 }); 1651 PowerManagerCallbackList<ICarPowerStateListener> completingBinderListeners = 1652 new PowerManagerCallbackList(l -> { 1653 }); 1654 synchronized (mLock) { 1655 if (isCompletionAllowed(newState)) { 1656 if (timeoutMs < 0) { 1657 Slogf.wtf(TAG, "Completion timeout(%d) for state(%d) should be " 1658 + "non-negative", timeoutMs, newState); 1659 return; 1660 } 1661 mStateForCompletion = newState; 1662 allowCompletion = true; 1663 internalListenerExpirationTimeMs = SystemClock.elapsedRealtime() + timeoutMs; 1664 binderListenerExpirationTimeMs = 1665 isShutdownPrepare ? INVALID_TIMEOUT : internalListenerExpirationTimeMs; 1666 } else { 1667 allowCompletion = false; 1668 mStateForCompletion = CarPowerManager.STATE_INVALID; 1669 } 1670 1671 mListenersWeAreWaitingFor.clear(); 1672 for (int i = 0; i < mInternalPowerListeners.size(); i++) { 1673 ICarPowerStateListener listener = mInternalPowerListeners.get(i); 1674 completingInternalListeners.register(listener); 1675 if (allowCompletion) { 1676 mListenersWeAreWaitingFor.add(listener.asBinder()); 1677 } 1678 } 1679 mBroadcastHandler.post(() -> { 1680 int idx = mPowerManagerListenersWithCompletion.beginBroadcast(); 1681 while (idx-- > 0) { 1682 ICarPowerStateListener listener = 1683 mPowerManagerListenersWithCompletion.getBroadcastItem(idx); 1684 completingBinderListeners.register(listener); 1685 // For binder listeners, listener completion is not allowed for SHUTDOWN_PREPARE 1686 if (allowCompletion && !isShutdownPrepare) { 1687 synchronized (mLock) { 1688 mListenersWeAreWaitingFor.add(listener.asBinder()); 1689 } 1690 } 1691 } 1692 mPowerManagerListenersWithCompletion.finishBroadcast(); 1693 }); 1694 } 1695 // Resets the semaphore's available permits to 0. 1696 mListenerCompletionSem.drainPermits(); 1697 // Broadcasts to the listeners that DO signal completion. 1698 notifyListeners(completingInternalListeners, newState, internalListenerExpirationTimeMs); 1699 notifyListeners(completingBinderListeners, newState, binderListenerExpirationTimeMs); 1700 1701 // Call unlinkToDeath inside RemoteCallbackList 1702 completingInternalListeners.kill(); 1703 completingBinderListeners.kill(); 1704 } 1705 notifyListeners(PowerManagerCallbackList<ICarPowerStateListener> listenerList, @CarPowerManager.CarPowerState int newState, long expirationTimeMs)1706 private void notifyListeners(PowerManagerCallbackList<ICarPowerStateListener> listenerList, 1707 @CarPowerManager.CarPowerState int newState, long expirationTimeMs) { 1708 CountDownLatch listenerLatch = new CountDownLatch(1); 1709 mBroadcastHandler.post(() -> { 1710 int idx = listenerList.beginBroadcast(); 1711 while (idx-- > 0) { 1712 ICarPowerStateListener listener = listenerList.getBroadcastItem(idx); 1713 try { 1714 listener.onStateChanged(newState, expirationTimeMs); 1715 } catch (RemoteException e) { 1716 // It's likely the connection snapped. Let binder death handle the situation. 1717 Slogf.e(TAG, e, "onStateChanged() call failed"); 1718 } 1719 } 1720 listenerList.finishBroadcast(); 1721 listenerLatch.countDown(); 1722 }); 1723 try { 1724 listenerLatch.await(DEFAULT_COMPLETION_WAIT_TIMEOUT, TimeUnit.MILLISECONDS); 1725 } catch (InterruptedException e) { 1726 Slogf.w(TAG, e, "Wait for power state listener completion interrupted"); 1727 Thread.currentThread().interrupt(); 1728 } 1729 } 1730 doHandleSuspend(boolean simulatedMode)1731 private void doHandleSuspend(boolean simulatedMode) { 1732 int status; 1733 if (mFeatureFlags.carPowerPolicyRefactoring()) { 1734 status = applyPowerPolicy(PolicyReader.POWER_POLICY_ID_SUSPEND_PREP, 1735 /* delayNotification= */ false, /* upToDaemon= */ false, /* force= */ true); 1736 } else { 1737 status = applyPreemptivePowerPolicy(PolicyReader.POWER_POLICY_ID_SUSPEND_PREP); 1738 } 1739 if (status != PolicyOperationStatus.OK) { 1740 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(status)); 1741 } 1742 // Keeps holding partial wakelock to prevent entering sleep before enterDeepSleep/ 1743 // enterHibernation call. enterDeepSleep/enterHibernation should force sleep entry even if 1744 // wake lock is kept. 1745 forEachDisplay(mContext, mSystemInterface::switchToPartialWakeLock); 1746 mHandler.cancelProcessingComplete(); 1747 synchronized (mLock) { 1748 mLastSleepEntryTime = SystemClock.elapsedRealtime(); 1749 } 1750 if (simulatedMode) { 1751 simulateSleepByWaiting(); 1752 } else { 1753 boolean sleepSucceeded = suspendWithRetries(); 1754 if (!sleepSucceeded) { 1755 // Suspend failed and we shut down instead. 1756 // We either won't get here at all or we will power off very soon. 1757 return; 1758 } 1759 } 1760 @CarPowerManager.CarPowerState int nextListenerState; 1761 synchronized (mLock) { 1762 nextListenerState = (mActionOnFinish == ACTION_ON_FINISH_DEEP_SLEEP) 1763 ? CarPowerManager.STATE_SUSPEND_EXIT 1764 : CarPowerManager.STATE_HIBERNATION_EXIT; 1765 // Any wakeup time from before is no longer valid. 1766 mNextWakeupSec = 0; 1767 } 1768 Slogf.i(TAG, "Resuming after suspending"); 1769 forEachDisplay(mContext, mSystemInterface::refreshDisplayBrightness); 1770 onApPowerStateChange(CpmsState.WAIT_FOR_VHAL, nextListenerState); 1771 } 1772 1773 @GuardedBy("mLock") needPowerStateChangeLocked(@onNull CpmsState newState)1774 private boolean needPowerStateChangeLocked(@NonNull CpmsState newState) { 1775 if (mCurrentState == null) { 1776 return true; 1777 } else if (mCurrentState.equals(newState)) { 1778 Slogf.d(TAG, "Requested state is already in effect: %s", newState.name()); 1779 return false; 1780 } 1781 1782 // The following switch/case enforces the allowed state transitions. 1783 boolean transitionAllowed = false; 1784 switch (mCurrentState.mState) { 1785 case CpmsState.WAIT_FOR_VHAL: 1786 transitionAllowed = (newState.mState == CpmsState.ON) 1787 || (newState.mState == CpmsState.SHUTDOWN_PREPARE); 1788 break; 1789 case CpmsState.SUSPEND: 1790 transitionAllowed = newState.mState == CpmsState.WAIT_FOR_VHAL; 1791 break; 1792 case CpmsState.ON: 1793 transitionAllowed = (newState.mState == CpmsState.SHUTDOWN_PREPARE) 1794 || (newState.mState == CpmsState.SIMULATE_SLEEP) 1795 || (newState.mState == CpmsState.SIMULATE_HIBERNATION); 1796 break; 1797 case CpmsState.SHUTDOWN_PREPARE: 1798 // If VHAL sends SHUTDOWN_IMMEDIATELY or SLEEP_IMMEDIATELY while in 1799 // SHUTDOWN_PREPARE state, do it. 1800 transitionAllowed = 1801 ((newState.mState == CpmsState.SHUTDOWN_PREPARE) && !newState.mCanPostpone) 1802 || (newState.mState == CpmsState.WAIT_FOR_FINISH) 1803 || (newState.mState == CpmsState.WAIT_FOR_VHAL); 1804 break; 1805 case CpmsState.SIMULATE_SLEEP: 1806 case CpmsState.SIMULATE_HIBERNATION: 1807 transitionAllowed = true; 1808 break; 1809 case CpmsState.WAIT_FOR_FINISH: 1810 transitionAllowed = (newState.mState == CpmsState.SUSPEND 1811 || newState.mState == CpmsState.WAIT_FOR_VHAL); 1812 break; 1813 default: 1814 Slogf.e(TAG, "Unexpected current state: currentState=%s, newState=%s", 1815 mCurrentState.name(), newState.name()); 1816 transitionAllowed = true; 1817 } 1818 if (!transitionAllowed) { 1819 Slogf.e(TAG, "Requested power transition is not allowed: %s --> %s", 1820 mCurrentState.name(), newState.name()); 1821 } 1822 return transitionAllowed; 1823 } 1824 doHandleProcessingComplete()1825 private void doHandleProcessingComplete() { 1826 int listenerState = CarPowerManager.STATE_SHUTDOWN_ENTER; 1827 synchronized (mLock) { 1828 clearWaitingForCompletion(/*clearQueue=*/false); 1829 boolean shutdownOnFinish = (mActionOnFinish == ACTION_ON_FINISH_SHUTDOWN); 1830 if (!shutdownOnFinish && mLastSleepEntryTime > mShutdownStartTime) { 1831 // entered sleep after processing start. So this could be duplicate request. 1832 Slogf.w(TAG, "Duplicate sleep entry request, ignore"); 1833 return; 1834 } 1835 if (shutdownOnFinish) { 1836 listenerState = CarPowerManager.STATE_SHUTDOWN_ENTER; 1837 } else if (mActionOnFinish == ACTION_ON_FINISH_DEEP_SLEEP) { 1838 listenerState = CarPowerManager.STATE_SUSPEND_ENTER; 1839 } else if (mActionOnFinish == ACTION_ON_FINISH_HIBERNATION) { 1840 listenerState = CarPowerManager.STATE_HIBERNATION_ENTER; 1841 } 1842 } 1843 1844 onApPowerStateChange(CpmsState.WAIT_FOR_FINISH, listenerState); 1845 } 1846 1847 @Override onDisplayBrightnessChange(int brightness)1848 public void onDisplayBrightnessChange(int brightness) { 1849 mHandler.handleDisplayBrightnessChange(Display.DEFAULT_DISPLAY, brightness); 1850 } 1851 1852 @Override onDisplayBrightnessChange(int displayId, int brightness)1853 public void onDisplayBrightnessChange(int displayId, int brightness) { 1854 mHandler.handleDisplayBrightnessChange(displayId, brightness); 1855 } 1856 doHandleDisplayBrightnessChange(int displayId, int brightness)1857 private void doHandleDisplayBrightnessChange(int displayId, int brightness) { 1858 mSystemInterface.setDisplayBrightness(displayId, brightness); 1859 } 1860 doHandleDisplayStateChange(int displayId, boolean on)1861 private void doHandleDisplayStateChange(int displayId, boolean on) { 1862 mScreenOffHandler.handleDisplayStateChange(displayId, on); 1863 } 1864 doHandlePowerPolicyNotification(String policyId)1865 private void doHandlePowerPolicyNotification(String policyId) { 1866 // Sending notification of power policy change triggered through CarPowerManager API. 1867 notifyPowerPolicyChange(policyId, /* upToDaemon= */ true, /* force= */ false); 1868 } 1869 doHandlePowerPolicyNotification(CarPowerPolicy accumulatedPolicy)1870 private void doHandlePowerPolicyNotification(CarPowerPolicy accumulatedPolicy) { 1871 notifyPowerPolicyChange(accumulatedPolicy); 1872 } 1873 1874 /** 1875 * Handles when display changes. 1876 */ handleDisplayChanged(int displayId, boolean on)1877 public void handleDisplayChanged(int displayId, boolean on) { 1878 mHandler.handleDisplayStateChange(displayId, on); 1879 } 1880 1881 /** 1882 * Gets display display power mode to turn on display. 1883 * 1884 * @return {@code false}, if the display power mode is OFF. Otherwise, {@code true}. 1885 */ canTurnOnDisplay(int displayId)1886 public boolean canTurnOnDisplay(int displayId) { 1887 return mScreenOffHandler.canTurnOnDisplay(displayId); 1888 } 1889 1890 /** 1891 * Notifies that user activity has happened. 1892 */ notifyUserActivity(int displayId, long eventTime)1893 public void notifyUserActivity(int displayId, long eventTime) { 1894 mScreenOffHandler.updateUserActivity(displayId, eventTime); 1895 } 1896 1897 @Override notifyUserActivity(int displayId)1898 public void notifyUserActivity(int displayId) { 1899 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 1900 notifyUserActivity(displayId, SystemClock.uptimeMillis()); 1901 } 1902 1903 /** 1904 * Sends display brightness to VHAL. 1905 * @param brightness value 0-100% 1906 */ sendDisplayBrightness(int brightness)1907 public void sendDisplayBrightness(int brightness) { 1908 mHal.sendDisplayBrightness(brightness); 1909 } 1910 1911 /** 1912 * Sends display brightness to VHAL. 1913 * @param displayId the target display 1914 * @param brightness value 0-100% 1915 */ sendDisplayBrightness(int displayId, int brightness)1916 public void sendDisplayBrightness(int displayId, int brightness) { 1917 mHal.sendDisplayBrightness(displayId, brightness); 1918 } 1919 1920 /** 1921 * Gets the PowerHandler that we use to change power states 1922 */ getHandler()1923 public Handler getHandler() { 1924 return mHandler; 1925 1926 } 1927 1928 /** 1929 * Registers power state change listeners running in CarService, which is not a binder 1930 * interfaces. 1931 */ registerInternalListener(ICarPowerStateListener listener)1932 public void registerInternalListener(ICarPowerStateListener listener) { 1933 CarServiceUtils.assertCallingFromSystemProcessOrSelf(); 1934 synchronized (mLock) { 1935 mInternalPowerListeners.add(listener); 1936 } 1937 } 1938 1939 /** 1940 * Unregisters power state change listeners running in CarService, which is not a binder 1941 * interface. 1942 */ unregisterInternalListener(ICarPowerStateListener listener)1943 public void unregisterInternalListener(ICarPowerStateListener listener) { 1944 CarServiceUtils.assertCallingFromSystemProcessOrSelf(); 1945 boolean found = false; 1946 synchronized (mLock) { 1947 found = mInternalPowerListeners.remove(listener); 1948 } 1949 if (found) { 1950 removeListenerFromWaitingList(listener.asBinder()); 1951 } 1952 } 1953 1954 /** 1955 * Tells {@link CarPowerManagementService} that the listener running in CarService completes 1956 * handling power state change. 1957 */ completeHandlingPowerStateChange(int state, ICarPowerStateListener listener)1958 public void completeHandlingPowerStateChange(int state, ICarPowerStateListener listener) { 1959 CarServiceUtils.assertCallingFromSystemProcessOrSelf(); 1960 handleListenerCompletion(state, listener, 1961 new ArraySet(new Integer[] {CarPowerManager.STATE_INVALID})); 1962 } 1963 1964 // Binder interface for general use. 1965 // The listener is not required (or allowed) to call finished(). 1966 @Override registerListener(ICarPowerStateListener listener)1967 public void registerListener(ICarPowerStateListener listener) { 1968 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 1969 mPowerManagerListeners.register(listener); 1970 } 1971 1972 // Binder interface for Car services only. 1973 // After the listener completes its processing, it must call finished(). 1974 @Override registerListenerWithCompletion(ICarPowerStateListener listener)1975 public void registerListenerWithCompletion(ICarPowerStateListener listener) { 1976 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CONTROL_SHUTDOWN_PROCESS); 1977 1978 mPowerManagerListenersWithCompletion.register(listener); 1979 // TODO: Need to send current state to newly registered listener? If so, need to handle 1980 // completion for SHUTDOWN_PREPARE state 1981 } 1982 1983 @Override unregisterListener(ICarPowerStateListener listener)1984 public void unregisterListener(ICarPowerStateListener listener) { 1985 CarServiceUtils.assertAnyPermission(mContext, Car.PERMISSION_CAR_POWER, 1986 Car.PERMISSION_CONTROL_SHUTDOWN_PROCESS); 1987 doUnregisterListener(listener); 1988 } 1989 1990 @Override requestShutdownOnNextSuspend()1991 public void requestShutdownOnNextSuspend() { 1992 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 1993 synchronized (mLock) { 1994 mShutdownOnNextSuspend = true; 1995 } 1996 } 1997 1998 @Override finished(int state, ICarPowerStateListener listener)1999 public void finished(int state, ICarPowerStateListener listener) { 2000 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CONTROL_SHUTDOWN_PROCESS); 2001 handleListenerCompletion(state, listener, new ArraySet(new Integer[] 2002 {CarPowerManager.STATE_INVALID, CarPowerManager.STATE_SHUTDOWN_PREPARE})); 2003 } 2004 2005 @Override scheduleNextWakeupTime(int seconds)2006 public void scheduleNextWakeupTime(int seconds) { 2007 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 2008 if (seconds < 0) { 2009 Slogf.w(TAG, "Next wake up time is negative. Ignoring!"); 2010 return; 2011 } 2012 boolean timedWakeupAllowed = mHal.isTimedWakeupAllowed(); 2013 synchronized (mLock) { 2014 if (!timedWakeupAllowed) { 2015 Slogf.w(TAG, "Setting timed wakeups are disabled in HAL. Skipping"); 2016 mNextWakeupSec = 0; 2017 return; 2018 } 2019 if (mNextWakeupSec == 0 || mNextWakeupSec > seconds) { 2020 // The new value is sooner than the old value. Take the new value. 2021 mNextWakeupSec = seconds; 2022 } else { 2023 Slogf.d(TAG, "Tried to schedule next wake up, but already had shorter " 2024 + "scheduled time"); 2025 } 2026 } 2027 } 2028 2029 @Override getPowerState()2030 public @CarPowerManager.CarPowerState int getPowerState() { 2031 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 2032 synchronized (mLock) { 2033 return (mCurrentState == null) ? CarPowerManager.STATE_INVALID 2034 : mCurrentState.mCarPowerStateListenerState; 2035 } 2036 } 2037 2038 /** 2039 * @see android.car.hardware.power.CarPowerManager#getCurrentPowerPolicy 2040 */ 2041 @Override getCurrentPowerPolicy()2042 public CarPowerPolicy getCurrentPowerPolicy() { 2043 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_READ_CAR_POWER_POLICY); 2044 if (mFeatureFlags.carPowerPolicyRefactoring()) { 2045 synchronized (mLock) { 2046 return mCurrentAccumulatedPowerPolicy; 2047 } 2048 } else { 2049 return mPowerComponentHandler.getAccumulatedPolicy(); 2050 } 2051 } 2052 2053 /** 2054 * @see android.car.hardware.power.CarPowerManager#applyPowerPolicy 2055 */ 2056 @Override applyPowerPolicy(String policyId)2057 public void applyPowerPolicy(String policyId) { 2058 Slogf.i(TAG, "applyPowerPolicy(%s) from binder", policyId); 2059 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CONTROL_CAR_POWER_POLICY); 2060 Preconditions.checkArgument(policyId != null, "policyId cannot be null"); 2061 Preconditions.checkArgument(!policyId.startsWith(PolicyReader.SYSTEM_POWER_POLICY_PREFIX), 2062 "System power policy cannot be applied by apps"); 2063 // notify daemon of power policy change not needed after policy refactor 2064 boolean upToDaemon = !mFeatureFlags.carPowerPolicyRefactoring(); 2065 int status = applyPowerPolicy(policyId, /* delayNotification= */ true, upToDaemon, 2066 /* force= */ false); 2067 if (status != PolicyOperationStatus.OK) { 2068 throw new IllegalArgumentException(PolicyOperationStatus.errorCodeToString(status)); 2069 } 2070 } 2071 2072 /** 2073 * @see android.car.hardware.power.CarPowerManager#setPowerPolicyGroup 2074 */ 2075 @Override setPowerPolicyGroup(String policyGroupId)2076 public void setPowerPolicyGroup(String policyGroupId) throws RemoteException { 2077 Slogf.i(TAG, "setPowerPolicyGroup(%s)", policyGroupId); 2078 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CONTROL_CAR_POWER_POLICY); 2079 Preconditions.checkArgument(policyGroupId != null, "policyGroupId cannot be null"); 2080 if (mFeatureFlags.carPowerPolicyRefactoring()) { 2081 ICarPowerPolicyDelegate daemon; 2082 synchronized (mLock) { 2083 daemon = mRefactoredCarPowerPolicyDaemon; 2084 } 2085 try { 2086 daemon.setPowerPolicyGroup(policyGroupId); 2087 } catch (IllegalArgumentException e) { 2088 throw new IllegalArgumentException("Policy group ID is invalid"); 2089 } catch (SecurityException e) { 2090 Slogf.e(TAG, e, "Failed to set power policy group, insufficient permissions"); 2091 } 2092 synchronized (mLock) { 2093 mCurrentPowerPolicyGroupId = policyGroupId; 2094 } 2095 } else { 2096 int status = setCurrentPowerPolicyGroup(policyGroupId); 2097 if (status != PolicyOperationStatus.OK) { 2098 throw new IllegalArgumentException(PolicyOperationStatus.errorCodeToString(status)); 2099 } 2100 } 2101 } 2102 2103 @VisibleForTesting getCurrentPowerPolicyGroupId()2104 String getCurrentPowerPolicyGroupId() { 2105 synchronized (mLock) { 2106 return mCurrentPowerPolicyGroupId; 2107 } 2108 } 2109 2110 @VisibleForTesting getNumberOfCurrentPolicyRequests()2111 int getNumberOfCurrentPolicyRequests() { 2112 synchronized (mLock) { 2113 return mRequestIdToPolicyRequest.size(); 2114 } 2115 } 2116 2117 /** 2118 * @see android.car.hardware.power.CarPowerManager#addPowerPolicyListener 2119 */ 2120 @Override addPowerPolicyListener(CarPowerPolicyFilter filter, ICarPowerPolicyListener listener)2121 public void addPowerPolicyListener(CarPowerPolicyFilter filter, 2122 ICarPowerPolicyListener listener) { 2123 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_READ_CAR_POWER_POLICY); 2124 mPowerPolicyListeners.register(listener, filter); 2125 } 2126 2127 /** 2128 * @see android.car.hardware.power.CarPowerManager#removePowerPolicyListener 2129 */ 2130 @Override removePowerPolicyListener(ICarPowerPolicyListener listener)2131 public void removePowerPolicyListener(ICarPowerPolicyListener listener) { 2132 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_READ_CAR_POWER_POLICY); 2133 mPowerPolicyListeners.unregister(listener); 2134 } 2135 2136 /** 2137 * @see android.car.hardware.power.CarPowerManager#setDisplayPowerState 2138 */ 2139 @Override setDisplayPowerState(int displayId, boolean enable)2140 public void setDisplayPowerState(int displayId, boolean enable) { 2141 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 2142 boolean isNotSelf = Binder.getCallingUid() != Process.myUid(); 2143 CarOccupantZoneService occupantZoneService = 2144 CarLocalServices.getService(CarOccupantZoneService.class); 2145 long token = Binder.clearCallingIdentity(); 2146 try { 2147 int driverDisplayId = occupantZoneService.getDisplayIdForDriver( 2148 CarOccupantZoneManager.DISPLAY_TYPE_MAIN); 2149 if (displayId == driverDisplayId && isNotSelf) { 2150 throw new UnsupportedOperationException("Driver display control is not supported"); 2151 } 2152 } finally { 2153 Binder.restoreCallingIdentity(token); 2154 } 2155 mSystemInterface.setDisplayState(displayId, enable); 2156 } 2157 2158 // TODO(b/286303350): remove once power policy refactor complete; CPPD will handle power policy 2159 // change in response to silent mode status changes notifySilentModeChange(boolean silent)2160 void notifySilentModeChange(boolean silent) { 2161 Slogf.i(TAG, "Silent mode is set to %b", silent); 2162 if (silent) { 2163 applyPreemptivePowerPolicy(PolicyReader.POWER_POLICY_ID_NO_USER_INTERACTION); 2164 } else { 2165 cancelPreemptivePowerPolicy(); 2166 } 2167 } 2168 handleListenerCompletion(int state, ICarPowerStateListener listener, ArraySet<Integer> notAllowedStates)2169 private void handleListenerCompletion(int state, ICarPowerStateListener listener, 2170 ArraySet<Integer> notAllowedStates) { 2171 synchronized (mLock) { 2172 if (notAllowedStates.contains(mStateForCompletion)) { 2173 Slogf.w(TAG, "The current state(%d) doesn't allow listener completion", 2174 mStateForCompletion); 2175 return; 2176 } 2177 if (state != mStateForCompletion) { 2178 Slogf.w(TAG, "Given state(%d) doesn't match the current state(%d) for completion", 2179 state, mStateForCompletion); 2180 return; 2181 } 2182 } 2183 removeListenerFromWaitingList(listener.asBinder()); 2184 } 2185 2186 doUnregisterListener(ICarPowerStateListener listener)2187 private void doUnregisterListener(ICarPowerStateListener listener) { 2188 mPowerManagerListeners.unregister(listener); 2189 boolean found = mPowerManagerListenersWithCompletion.unregister(listener); 2190 if (found) { 2191 // Remove this from the completion list (if it's there) 2192 removeListenerFromWaitingList(listener.asBinder()); 2193 } 2194 } 2195 removeListenerFromWaitingList(IBinder binderListener)2196 private void removeListenerFromWaitingList(IBinder binderListener) { 2197 synchronized (mLock) { 2198 mListenersWeAreWaitingFor.remove(binderListener); 2199 } 2200 // Signals a thread to check if all listeners complete. 2201 mListenerCompletionSem.release(); 2202 } 2203 finishShutdownPrepare()2204 private void finishShutdownPrepare() { 2205 boolean shouldHandleProcessingComplete = false; 2206 synchronized (mLock) { 2207 if (mCurrentState != null 2208 && (mCurrentState.mState == CpmsState.SHUTDOWN_PREPARE 2209 || mCurrentState.mState == CpmsState.SIMULATE_SLEEP 2210 || mCurrentState.mState == CpmsState.SIMULATE_HIBERNATION)) { 2211 // All apps are ready to shutdown/suspend. 2212 if (mActionOnFinish != ACTION_ON_FINISH_SHUTDOWN) { 2213 if (mLastSleepEntryTime > mShutdownStartTime 2214 && mLastSleepEntryTime < SystemClock.elapsedRealtime()) { 2215 Slogf.d(TAG, "finishShutdownPrepare: Already slept!"); 2216 return; 2217 } 2218 } 2219 shouldHandleProcessingComplete = true; 2220 } 2221 } 2222 2223 if (shouldHandleProcessingComplete) { 2224 Slogf.i(TAG, "Apps are finished, call handleProcessingComplete()"); 2225 mHandler.handleProcessingComplete(); 2226 } 2227 } 2228 2229 /** 2230 * Converts a given power policy from power policy type returned by the car power policy daemon 2231 * to the one used within car service. 2232 * @param policy of type android.frameworks.automotive.powerpolicy.CarPowerPolicy 2233 * @return policy converted to type android.car.hardware.power.CarPowerPolicy 2234 */ convertPowerPolicyFromDaemon( android.frameworks.automotive.powerpolicy.CarPowerPolicy policy)2235 private CarPowerPolicy convertPowerPolicyFromDaemon( 2236 android.frameworks.automotive.powerpolicy.CarPowerPolicy policy) { 2237 return new CarPowerPolicy(policy.policyId, policy.enabledComponents, 2238 policy.disabledComponents); 2239 } 2240 2241 private final class PowerPolicyCallback extends ICarPowerPolicyDelegateCallback.Stub { 2242 @Override updatePowerComponents( android.frameworks.automotive.powerpolicy.CarPowerPolicy policy)2243 public void updatePowerComponents( 2244 android.frameworks.automotive.powerpolicy.CarPowerPolicy policy) { 2245 mPowerComponentHandler.applyPowerPolicy(convertPowerPolicyFromDaemon(policy)); 2246 } 2247 2248 @Override onApplyPowerPolicySucceeded(int requestId, android.frameworks.automotive.powerpolicy.CarPowerPolicy accumulatedPolicy, boolean deferred)2249 public void onApplyPowerPolicySucceeded(int requestId, 2250 android.frameworks.automotive.powerpolicy.CarPowerPolicy accumulatedPolicy, 2251 boolean deferred) { 2252 Slogf.i(TAG, "onApplyPowerPolicySucceeded: requestId = %d, policyId = %s, " 2253 + "deferred = %b", requestId, accumulatedPolicy.policyId, deferred); 2254 AsyncPolicyRequest policyRequest; 2255 synchronized (mLock) { 2256 policyRequest = mRequestIdToPolicyRequest.get(requestId); 2257 } 2258 if (policyRequest == null) { 2259 Slogf.e(TAG, "No power policy request exists for request ID %d", requestId); 2260 return; 2261 } 2262 CarPowerPolicy accumulatedPowerPolicy = convertPowerPolicyFromDaemon(accumulatedPolicy); 2263 policyRequest.onPolicyRequestSucceeded(accumulatedPowerPolicy, deferred); 2264 } 2265 2266 @Override onApplyPowerPolicyFailed(int requestId, int reason)2267 public void onApplyPowerPolicyFailed(int requestId, int reason) { 2268 Slogf.i(TAG, "onApplyPowerPolicyFailed: requestId = %d, reason = %d", requestId, 2269 reason); 2270 AsyncPolicyRequest policyRequest; 2271 synchronized (mLock) { 2272 policyRequest = mRequestIdToPolicyRequest.get(requestId); 2273 } 2274 if (policyRequest == null) { 2275 Slogf.e(TAG, "No power policy request exists for request ID %d", requestId); 2276 return; 2277 } 2278 policyRequest.onPolicyRequestFailed(reason); 2279 } 2280 2281 @Override onPowerPolicyChanged( android.frameworks.automotive.powerpolicy.CarPowerPolicy accumulatedPolicy)2282 public void onPowerPolicyChanged( 2283 android.frameworks.automotive.powerpolicy.CarPowerPolicy accumulatedPolicy) { 2284 CarPowerPolicy currentAccumulatedPolicy = 2285 convertPowerPolicyFromDaemon(accumulatedPolicy); 2286 updateCurrentPowerPolicy(currentAccumulatedPolicy); 2287 String policyId = accumulatedPolicy.policyId; 2288 Slogf.i(TAG, "Queueing power policy notification (ID: %s) in the handler", policyId); 2289 mHandler.handlePowerPolicyNotification(currentAccumulatedPolicy); 2290 } 2291 2292 @Override getInterfaceHash()2293 public String getInterfaceHash() { 2294 return ICarPowerPolicyDelegateCallback.HASH; 2295 } 2296 2297 @Override getInterfaceVersion()2298 public int getInterfaceVersion() { 2299 return ICarPowerPolicyDelegateCallback.VERSION; 2300 } 2301 } 2302 getInitialAccumulatedPowerPolicy()2303 private static CarPowerPolicy getInitialAccumulatedPowerPolicy() { 2304 String initialPolicyId = ""; 2305 int[] enabledComponents = new int[0]; 2306 int[] disabledComponents = new int[LAST_POWER_COMPONENT - FIRST_POWER_COMPONENT + 1]; 2307 int disabledIndex = 0; 2308 for (int component = FIRST_POWER_COMPONENT; component <= LAST_POWER_COMPONENT; 2309 component++) { 2310 disabledComponents[disabledIndex++] = component; 2311 } 2312 return new CarPowerPolicy(initialPolicyId, enabledComponents, disabledComponents); 2313 } 2314 initializeRegisteredPowerPolicies( android.frameworks.automotive.powerpolicy.CarPowerPolicy[] policies)2315 private void initializeRegisteredPowerPolicies( 2316 android.frameworks.automotive.powerpolicy.CarPowerPolicy[] policies) { 2317 for (int i = 0; i < policies.length; i++) { 2318 CarPowerPolicy policy = convertPowerPolicyFromDaemon(policies[i]); 2319 List<String> enabledComponents = PowerComponentUtil.powerComponentsToStrings( 2320 Lists.asImmutableList(policy.getEnabledComponents())); 2321 List<String> disabledComponents = PowerComponentUtil.powerComponentsToStrings( 2322 Lists.asImmutableList(policy.getDisabledComponents())); 2323 mPolicyReader.definePowerPolicy(policy.getPolicyId(), 2324 enabledComponents.toArray(String[]::new), 2325 disabledComponents.toArray(String[]::new)); 2326 } 2327 mPowerPoliciesInitialized = true; 2328 mPowerPolicyInitializationLatch.countDown(); 2329 } 2330 2331 @VisibleForTesting initializePowerPolicy()2332 public void initializePowerPolicy() { 2333 if (mFeatureFlags.carPowerPolicyRefactoring()) { 2334 ICarPowerPolicyDelegate daemon; 2335 synchronized (mLock) { 2336 daemon = mRefactoredCarPowerPolicyDaemon; 2337 } 2338 PowerPolicyInitData powerPolicyInitData; 2339 if (daemon != null) { 2340 try { 2341 PowerPolicyCallback powerPolicyCallback = new PowerPolicyCallback(); 2342 powerPolicyInitData = daemon.notifyCarServiceReady(powerPolicyCallback); 2343 } catch (RemoteException e) { 2344 Slogf.e(TAG, e, "Failed to tell car power policy daemon that CarService is" 2345 + " ready"); 2346 return; 2347 } 2348 } else { 2349 Slogf.w(TAG, "Failed to notify car service is ready, car power policy daemon" 2350 + " is not available"); 2351 return; 2352 } 2353 mReadyForCallback.set(true); 2354 int[] registeredCustomComponents = powerPolicyInitData.registeredCustomComponents; 2355 Integer[] customComponents = new Integer[registeredCustomComponents.length]; 2356 for (int i = 0; i < customComponents.length; i++) { 2357 customComponents[i] = registeredCustomComponents[i]; 2358 } 2359 mPowerComponentHandler.registerCustomComponents(customComponents); 2360 initializeRegisteredPowerPolicies(powerPolicyInitData.registeredPolicies); 2361 CarPowerPolicy currentPowerPolicy = convertPowerPolicyFromDaemon( 2362 powerPolicyInitData.currentPowerPolicy); 2363 updateCurrentPowerPolicy(currentPowerPolicy); 2364 mPowerComponentHandler.applyPowerPolicy(currentPowerPolicy); 2365 notifyPowerPolicyChange(currentPowerPolicy); 2366 // To cover the case where power state changed before connecting to CPPD. 2367 int currentPowerState = getPowerState(); 2368 if (currentPowerState != CarPowerManager.STATE_WAIT_FOR_VHAL 2369 && currentPowerState != CarPowerManager.STATE_ON) { 2370 Slogf.w(TAG, "Current power state is %s, doesn't correspond to wait for VHAL " 2371 + "or on state, skipping notification of power state to daemon.", 2372 powerStateToString(currentPowerState)); 2373 } else { 2374 notifyPowerStateChangeToDaemon(daemon, currentPowerState); 2375 } 2376 } else { 2377 Slogf.i(TAG, "CPMS is taking control from carpowerpolicyd"); 2378 ICarPowerPolicySystemNotification daemon; 2379 synchronized (mLock) { 2380 daemon = mCarPowerPolicyDaemon; 2381 } 2382 PolicyState state; 2383 if (daemon != null) { 2384 try { 2385 state = daemon.notifyCarServiceReady(); 2386 } catch (RemoteException e) { 2387 Slogf.e(TAG, e, 2388 "Failed to tell car power policy daemon that CarService is ready"); 2389 return; 2390 } 2391 } else { 2392 Slogf.w(TAG, 2393 "Failed to notify car service is ready. car power policy daemon is not " 2394 + "available"); 2395 return; 2396 } 2397 2398 String currentPowerPolicyId; 2399 String currentPolicyGroupId; 2400 synchronized (mLock) { 2401 mHasControlOverDaemon = true; 2402 currentPowerPolicyId = mCurrentPowerPolicyId; 2403 currentPolicyGroupId = mCurrentPowerPolicyGroupId; 2404 } 2405 // If the current power policy or the policy group has been modified by CPMS, we ignore 2406 // the power policy or the policy group passed from car power policy daemon, and 2407 // notifies the current power policy to the daemon. 2408 if (currentPowerPolicyId == null || currentPowerPolicyId.isEmpty()) { 2409 Slogf.i(TAG, "Attempting to apply the power policy(%s) from the daemon", 2410 state.policyId); 2411 int status = applyPowerPolicy(state.policyId, /* delayNotification= */ false, 2412 /* upToDaemon= */ false, /* force= */ false); 2413 if (status != PolicyOperationStatus.OK) { 2414 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(status)); 2415 } 2416 } else { 2417 Slogf.i(TAG, 2418 "CPMS applied power policy(%s) before connecting to the daemon. Notifying " 2419 + "to the daemon...", currentPowerPolicyId); 2420 notifyPowerPolicyChangeToDaemon(currentPowerPolicyId, /* force= */ true); 2421 } 2422 if (currentPolicyGroupId == null || currentPolicyGroupId.isEmpty()) { 2423 int status = setCurrentPowerPolicyGroup(state.policyGroupId); 2424 if (status != PolicyOperationStatus.OK) { 2425 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(status)); 2426 } 2427 } 2428 } 2429 mSilentModeHandler.init(); 2430 } 2431 2432 @PolicyOperationStatus.ErrorCode setCurrentPowerPolicyGroup(String policyGroupId)2433 private int setCurrentPowerPolicyGroup(String policyGroupId) { 2434 if (!mPolicyReader.isPowerPolicyGroupAvailable(policyGroupId)) { 2435 int error = PolicyOperationStatus.ERROR_SET_POWER_POLICY_GROUP; 2436 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error, 2437 policyGroupId + " is not registered")); 2438 return error; 2439 } 2440 synchronized (mLock) { 2441 mCurrentPowerPolicyGroupId = policyGroupId; 2442 } 2443 return PolicyOperationStatus.OK; 2444 } 2445 2446 private static final class AsyncPolicyRequest { 2447 private final Object mLock = new Object(); 2448 private final int mRequestId; 2449 private final long mTimeoutMs; 2450 private final CountDownLatch mPolicyRequestLatch = new CountDownLatch(1); 2451 @GuardedBy("mLock") 2452 private boolean mPolicyRequestSucceeded; 2453 @GuardedBy("mLock") 2454 @Nullable 2455 private CarPowerPolicy mAccumulatedPolicy; 2456 @GuardedBy("mLock") 2457 @PowerPolicyFailureReason 2458 private int mFailureReason; 2459 @GuardedBy("mLock") 2460 private boolean mIsDeferred; 2461 AsyncPolicyRequest(int requestId, long timeoutMs)2462 AsyncPolicyRequest(int requestId, long timeoutMs) { 2463 mRequestId = requestId; 2464 mTimeoutMs = timeoutMs; 2465 } 2466 getRequestId()2467 public int getRequestId() { 2468 return mRequestId; 2469 } 2470 isSuccessful()2471 public boolean isSuccessful() { 2472 synchronized (mLock) { 2473 return mPolicyRequestSucceeded; 2474 } 2475 } 2476 2477 @Nullable getAccumulatedPolicy()2478 public CarPowerPolicy getAccumulatedPolicy() { 2479 synchronized (mLock) { 2480 return mAccumulatedPolicy; 2481 } 2482 } 2483 2484 @PowerPolicyFailureReason getFailureReason()2485 public int getFailureReason() { 2486 synchronized (mLock) { 2487 return mFailureReason; 2488 } 2489 } 2490 isDeferred()2491 public boolean isDeferred() { 2492 synchronized (mLock) { 2493 return mIsDeferred; 2494 } 2495 } 2496 await()2497 public boolean await() throws InterruptedException { 2498 return mPolicyRequestLatch.await(mTimeoutMs, TimeUnit.MILLISECONDS); 2499 } 2500 onPolicyRequestSucceeded(CarPowerPolicy accumulatedPolicy, boolean deferred)2501 public void onPolicyRequestSucceeded(CarPowerPolicy accumulatedPolicy, boolean deferred) { 2502 synchronized (mLock) { 2503 mPolicyRequestSucceeded = true; 2504 if (!deferred) { 2505 mAccumulatedPolicy = accumulatedPolicy; 2506 } 2507 mIsDeferred = deferred; 2508 } 2509 mPolicyRequestLatch.countDown(); 2510 } 2511 onPolicyRequestFailed(@owerPolicyFailureReason int reason)2512 public void onPolicyRequestFailed(@PowerPolicyFailureReason int reason) { 2513 synchronized (mLock) { 2514 mFailureReason = reason; 2515 } 2516 mPolicyRequestLatch.countDown(); 2517 } 2518 } 2519 generateAsyncPolicyRequest(long timeoutMs)2520 private AsyncPolicyRequest generateAsyncPolicyRequest(long timeoutMs) { 2521 int requestId = mPolicyRequestIdCounter.getAndIncrement(); 2522 return new AsyncPolicyRequest(requestId, timeoutMs); 2523 } 2524 2525 @PolicyOperationStatus.ErrorCode getPolicyRequestError(int requestId, @PowerPolicyFailureReason int reason)2526 private int getPolicyRequestError(int requestId, @PowerPolicyFailureReason int reason) { 2527 switch(reason) { 2528 case PowerPolicyFailureReason.POWER_POLICY_FAILURE_UNKNOWN: 2529 Slogf.w(TAG, "Power policy request %d failed for unknown reason", 2530 requestId); 2531 return PolicyOperationStatus.ERROR_APPLY_POWER_POLICY; 2532 case PowerPolicyFailureReason.POWER_POLICY_FAILURE_NOT_REGISTERED_ID: 2533 Slogf.w(TAG, "Power policy request %d failed due to unregistered" 2534 + "power policy ID", requestId); 2535 return PolicyOperationStatus.ERROR_NOT_REGISTERED_POWER_POLICY_ID; 2536 case PowerPolicyFailureReason.POWER_POLICY_FAILURE_CANNOT_OVERRIDE: 2537 Slogf.w(TAG, "Power policy request %d failed because current non-" 2538 + "preemptive power policy cannot be overridden", requestId); 2539 return PolicyOperationStatus.ERROR_APPLY_POWER_POLICY; 2540 default: 2541 Slogf.w(TAG, "Reason for power policy request %d failing is " 2542 + "undefined", requestId); 2543 return PolicyOperationStatus.ERROR_APPLY_POWER_POLICY; 2544 } 2545 } 2546 2547 @PolicyOperationStatus.ErrorCode applyPowerPolicy(@ullable String policyId, boolean delayNotification, boolean upToDaemon, boolean force)2548 private int applyPowerPolicy(@Nullable String policyId, boolean delayNotification, 2549 boolean upToDaemon, boolean force) { 2550 if (mFeatureFlags.carPowerPolicyRefactoring()) { 2551 AsyncPolicyRequest request = generateAsyncPolicyRequest( 2552 DEFAULT_POWER_POLICY_REQUEST_TIMEOUT_MS); 2553 int requestId = request.getRequestId(); 2554 ICarPowerPolicyDelegate daemon; 2555 synchronized (mLock) { 2556 daemon = mRefactoredCarPowerPolicyDaemon; 2557 mRequestIdToPolicyRequest.put(requestId, request); 2558 } 2559 if (daemon == null) { 2560 Slogf.w(TAG, "Cannot call applyPowerPolicyAsync(requestId=%d, policyId=%s) to CPPD:" 2561 + " CPPD is not available", requestId, policyId); 2562 return PolicyOperationStatus.ERROR_APPLY_POWER_POLICY; 2563 } 2564 if (!mReadyForCallback.get()) { 2565 Slogf.w(TAG, "Cannot call applyPowerPolicyAsync(requestId=%d, policyId=%s) to CPPD:" 2566 + " not ready for calling to CPPD", requestId, policyId); 2567 return PolicyOperationStatus.ERROR_APPLY_POWER_POLICY; 2568 } 2569 try { 2570 Slogf.i(TAG, "Request(%d) of applying power policy(%s) to CPPD in async", requestId, 2571 policyId); 2572 daemon.applyPowerPolicyAsync(requestId, policyId, force); 2573 boolean policyRequestServed = request.await(); 2574 if (!policyRequestServed) { 2575 Slogf.w(TAG, "Power policy request (ID: %d) successful application timed out" 2576 + " after %d ms", requestId, DEFAULT_POWER_POLICY_REQUEST_TIMEOUT_MS); 2577 return PolicyOperationStatus.ERROR_APPLY_POWER_POLICY; 2578 } 2579 } catch (IllegalArgumentException e) { 2580 int error = PolicyOperationStatus.ERROR_INVALID_POWER_POLICY_ID; 2581 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error, policyId)); 2582 return error; 2583 } catch (IllegalStateException e) { 2584 int error = PolicyOperationStatus.ERROR_APPLY_POWER_POLICY; 2585 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error, policyId)); 2586 return error; 2587 } catch (SecurityException e) { 2588 Slogf.w(TAG, e, "Failed to apply power policy, insufficient permissions"); 2589 return PolicyOperationStatus.ERROR_APPLY_POWER_POLICY; 2590 } catch (InterruptedException e) { 2591 Slogf.w(TAG, e, "Wait for power policy change request interrupted"); 2592 Thread.currentThread().interrupt(); 2593 return PolicyOperationStatus.ERROR_APPLY_POWER_POLICY; 2594 } catch (RemoteException e) { 2595 Slogf.w(TAG, e, "Failed to apply power policy, connection issue"); 2596 return PolicyOperationStatus.ERROR_APPLY_POWER_POLICY; 2597 } finally { 2598 synchronized (mLock) { 2599 mRequestIdToPolicyRequest.remove(requestId); 2600 } 2601 } 2602 if (!request.isSuccessful()) { 2603 Slogf.w(TAG, "Failed to apply power policy, failure reason = %d", 2604 request.getFailureReason()); 2605 return getPolicyRequestError(requestId, request.getFailureReason()); 2606 } 2607 if (request.isDeferred()) { 2608 Slogf.i(TAG, "Applying power policy(%s) is deferred", policyId); 2609 return PolicyOperationStatus.OK; 2610 } 2611 CarPowerPolicy accumulatedPolicy = request.getAccumulatedPolicy(); 2612 updateCurrentPowerPolicy(accumulatedPolicy); 2613 if (delayNotification) { 2614 Slogf.d(TAG, 2615 "Queueing power policy notification (id: %s) in the handler", policyId); 2616 mHandler.handlePowerPolicyNotification(accumulatedPolicy); 2617 } else { 2618 notifyPowerPolicyChange(accumulatedPolicy); 2619 } 2620 } else { 2621 CarPowerPolicy policy = mPolicyReader.getPowerPolicy(policyId); 2622 if (policy == null) { 2623 int error = PolicyOperationStatus.ERROR_NOT_REGISTERED_POWER_POLICY_ID; 2624 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error, policyId)); 2625 return error; 2626 } 2627 synchronized (mLock) { 2628 if (mIsPowerPolicyLocked) { 2629 Slogf.i(TAG, "Power policy is locked. The request policy(%s) will be applied " 2630 + "when power policy becomes unlocked", policyId); 2631 mPendingPowerPolicyId = policyId; 2632 return PolicyOperationStatus.OK; 2633 } 2634 mCurrentPowerPolicyId = policyId; 2635 } 2636 mPowerComponentHandler.applyPowerPolicy(policy); 2637 if (delayNotification) { 2638 Slogf.d(TAG, 2639 "Queueing power policy notification (id: %s) in the handler", policyId); 2640 mHandler.handlePowerPolicyNotification(policyId); 2641 } else { 2642 notifyPowerPolicyChange(policyId, upToDaemon, force); 2643 } 2644 } 2645 Slogf.i(TAG, "The current power policy is %s", policyId); 2646 return PolicyOperationStatus.OK; 2647 } 2648 2649 @PolicyOperationStatus.ErrorCode applyPreemptivePowerPolicy(String policyId)2650 private int applyPreemptivePowerPolicy(String policyId) { 2651 CarPowerPolicy policy = mPolicyReader.getPreemptivePowerPolicy(policyId); 2652 if (policy == null) { 2653 int error = PolicyOperationStatus.ERROR_NOT_REGISTERED_POWER_POLICY_ID; 2654 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(error, policyId)); 2655 return error; 2656 } 2657 synchronized (mLock) { 2658 mIsPowerPolicyLocked = true; 2659 if (!mPolicyReader.isPreemptivePowerPolicy(mCurrentPowerPolicyId)) { 2660 mPendingPowerPolicyId = mCurrentPowerPolicyId; 2661 } 2662 mCurrentPowerPolicyId = policyId; 2663 } 2664 mPowerComponentHandler.applyPowerPolicy(policy); 2665 notifyPowerPolicyChange(policyId, /* upToDaemon= */ true, /* force= */ true); 2666 Slogf.i(TAG, "The current power policy is %s", policyId); 2667 return PolicyOperationStatus.OK; 2668 } 2669 cancelPreemptivePowerPolicy()2670 private void cancelPreemptivePowerPolicy() { 2671 Slogf.i(TAG, "Canceling preemptive power policy"); 2672 String policyId; 2673 synchronized (mLock) { 2674 if (!mIsPowerPolicyLocked) { 2675 Slogf.w(TAG, "Failed to cancel system power policy: the current policy is not the " 2676 + "system power policy"); 2677 return; 2678 } 2679 mIsPowerPolicyLocked = false; 2680 policyId = mPendingPowerPolicyId; 2681 mPendingPowerPolicyId = null; 2682 } 2683 if (policyId != null) { // Pending policy exist 2684 int status = applyPowerPolicy(policyId, /* delayNotification= */ false, 2685 /* upToDaemon= */ true, /* force= */ true); 2686 if (status != PolicyOperationStatus.OK) { 2687 Slogf.w(TAG, "Failed to cancel system power policy: %s", 2688 PolicyOperationStatus.errorCodeToString(status)); 2689 } 2690 } else { 2691 Slogf.w(TAG, "cancelPreemptivePowerPolicy(), no pending power policy"); 2692 } 2693 } 2694 notifyPowerPolicyChangeToDaemon(String policyId, boolean force)2695 private void notifyPowerPolicyChangeToDaemon(String policyId, boolean force) { 2696 ICarPowerPolicySystemNotification daemon; 2697 synchronized (mLock) { 2698 daemon = mCarPowerPolicyDaemon; 2699 if (daemon == null) { 2700 Slogf.e(TAG, "Failed to notify car power policy daemon: the daemon is not ready"); 2701 return; 2702 } 2703 if (!mHasControlOverDaemon) { 2704 Slogf.w(TAG, "Notifying policy change is deferred: CPMS has not yet taken control"); 2705 return; 2706 } 2707 } 2708 try { 2709 daemon.notifyPowerPolicyChange(policyId, force); 2710 } catch (RemoteException | IllegalStateException e) { 2711 Slogf.e(TAG, e, "Failed to notify car power policy daemon of a new power policy(%s)", 2712 policyId); 2713 } 2714 } 2715 2716 // TODO(b/286303350): remove after power policy refactor is complete - will only use version 2717 // that takes 'accumulatedPowerPolicy' as input notifyPowerPolicyChange(String policyId, boolean upToDaemon, boolean force)2718 private void notifyPowerPolicyChange(String policyId, boolean upToDaemon, boolean force) { 2719 // Notify system clients 2720 if (upToDaemon) { 2721 notifyPowerPolicyChangeToDaemon(policyId, force); 2722 } 2723 // Notify Java clients 2724 CarPowerPolicy appliedPolicy = mPolicyReader.isPreemptivePowerPolicy(policyId) 2725 ? mPolicyReader.getPreemptivePowerPolicy(policyId) 2726 : mPolicyReader.getPowerPolicy(policyId); 2727 CarPowerPolicy accumulatedPolicy = mPowerComponentHandler.getAccumulatedPolicy(); 2728 notifyPowerPolicyChange(policyId, appliedPolicy, accumulatedPolicy); 2729 } 2730 2731 @Nullable getPowerPolicyDefinition(String policyId, long timeoutMs)2732 private CarPowerPolicy getPowerPolicyDefinition(String policyId, long timeoutMs) 2733 throws InterruptedException { 2734 if (!mPowerPoliciesInitialized) { 2735 boolean result = 2736 mPowerPolicyInitializationLatch.await(timeoutMs, TimeUnit.MILLISECONDS); 2737 if (!result) { 2738 Slogf.e(TAG, "Failed to get power policy initialization after waiting %d ms", 2739 timeoutMs); 2740 return null; 2741 } 2742 } 2743 return mPolicyReader.getPowerPolicy(policyId); 2744 } 2745 notifyPowerPolicyChange(CarPowerPolicy accumulatedPowerPolicy)2746 private void notifyPowerPolicyChange(CarPowerPolicy accumulatedPowerPolicy) { 2747 String policyId = accumulatedPowerPolicy.getPolicyId(); 2748 try { 2749 CarPowerPolicy appliedPolicy = 2750 getPowerPolicyDefinition(policyId, CAR_POWER_POLICY_DEFINITION_TIMEOUT_MS); 2751 if (appliedPolicy == null) { 2752 Slogf.wtf(TAG, "The new power policy(%s) should exist", policyId); 2753 return; 2754 } 2755 notifyPowerPolicyChange(policyId, appliedPolicy, accumulatedPowerPolicy); 2756 } catch (InterruptedException e) { 2757 Slogf.e(TAG, e, "Failed to get power policy definition for policy ID %s", policyId); 2758 } 2759 } 2760 2761 // TODO(b/286303350): after power policy refactor is complete, remove this function and replace 2762 // the inner call to it by notifyPowerPolicyChange(accumulatedPowerPolicy) 2763 // with this function's code contents notifyPowerPolicyChange(String policyId, CarPowerPolicy appliedPolicy, CarPowerPolicy accumulatedPolicy)2764 private void notifyPowerPolicyChange(String policyId, CarPowerPolicy appliedPolicy, 2765 CarPowerPolicy accumulatedPolicy) { 2766 EventLogHelper.writePowerPolicyChange(policyId); 2767 if (appliedPolicy == null) { 2768 Slogf.wtf(TAG, "The new power policy(%s) should exist", policyId); 2769 } 2770 Slogf.i(TAG, "Power policy change to %s is notified to apps", policyId); 2771 mBroadcastHandler.post(() -> { 2772 int idx = mPowerPolicyListeners.beginBroadcast(); 2773 2774 while (idx-- > 0) { 2775 ICarPowerPolicyListener listener = mPowerPolicyListeners.getBroadcastItem(idx); 2776 CarPowerPolicyFilter filter = 2777 (CarPowerPolicyFilter) mPowerPolicyListeners.getBroadcastCookie(idx); 2778 if (!mPowerComponentHandler.isComponentChanged(filter)) { 2779 continue; 2780 } 2781 try { 2782 listener.onPolicyChanged(appliedPolicy, accumulatedPolicy); 2783 } catch (RemoteException e) { 2784 // It's likely the connection snapped. Let binder death handle the situation. 2785 Slogf.e(TAG, e, "onPolicyChanged() call failed: policyId = %s", policyId); 2786 } 2787 } 2788 mPowerPolicyListeners.finishBroadcast(); 2789 }); 2790 } 2791 makeSureNoUserInteraction()2792 private void makeSureNoUserInteraction() { 2793 mSilentModeHandler.updateKernelSilentMode(true); 2794 int status; 2795 if (mFeatureFlags.carPowerPolicyRefactoring()) { 2796 status = applyPowerPolicy(PolicyReader.POWER_POLICY_ID_NO_USER_INTERACTION, 2797 /* delayNotification= */ false, /* upToDaemon= */ false, /* force= */ true); 2798 } else { 2799 status = applyPreemptivePowerPolicy( 2800 PolicyReader.POWER_POLICY_ID_NO_USER_INTERACTION); 2801 } 2802 if (status != PolicyOperationStatus.OK) { 2803 Slogf.w(TAG, PolicyOperationStatus.errorCodeToString(status)); 2804 } 2805 } 2806 2807 @GuardedBy("mLock") getPowerPolicyDaemonLocked()2808 private android.os.IInterface getPowerPolicyDaemonLocked() { 2809 if (mFeatureFlags.carPowerPolicyRefactoring()) { 2810 return mRefactoredCarPowerPolicyDaemon; 2811 } else { 2812 return mCarPowerPolicyDaemon; 2813 } 2814 } 2815 connectToPowerPolicyDaemon()2816 private void connectToPowerPolicyDaemon() { 2817 synchronized (mLock) { 2818 android.os.IInterface powerPolicyDaemon = getPowerPolicyDaemonLocked(); 2819 if (powerPolicyDaemon != null || mConnectionInProgress) { 2820 return; 2821 } 2822 mConnectionInProgress = true; 2823 } 2824 connectToDaemonHelper(CAR_POWER_POLICY_DAEMON_BIND_MAX_RETRY); 2825 } 2826 connectToDaemonHelper(int retryCount)2827 private void connectToDaemonHelper(int retryCount) { 2828 if (retryCount <= 0) { 2829 synchronized (mLock) { 2830 mConnectionInProgress = false; 2831 } 2832 Slogf.e(TAG, "Cannot reconnect to car power policyd daemon after retrying %d times", 2833 CAR_POWER_POLICY_DAEMON_BIND_MAX_RETRY); 2834 return; 2835 } 2836 if (makeBinderConnection()) { 2837 Slogf.i(TAG, "Connected to car power policy daemon"); 2838 initializePowerPolicy(); 2839 return; 2840 } 2841 final int numRetry = retryCount - 1; 2842 mHandler.postDelayed(() -> connectToDaemonHelper(numRetry), 2843 CAR_POWER_POLICY_DAEMON_BIND_RETRY_INTERVAL_MS); 2844 } 2845 makeBinderConnection()2846 private boolean makeBinderConnection() { 2847 long currentTimeMs = SystemClock.uptimeMillis(); 2848 IBinder binder; 2849 if (mFeatureFlags.carPowerPolicyRefactoring()) { 2850 binder = ServiceManagerHelper.getService(REFACTORED_CAR_POWER_POLICY_DAEMON_INTERFACE); 2851 } else { 2852 binder = ServiceManagerHelper.getService(CAR_POWER_POLICY_DAEMON_INTERFACE); 2853 } 2854 if (binder == null) { 2855 Slogf.w(TAG, "Finding car power policy daemon failed. Power policy management is not " 2856 + "supported"); 2857 return false; 2858 } 2859 long elapsedTimeMs = SystemClock.uptimeMillis() - currentTimeMs; 2860 if (elapsedTimeMs > CAR_POWER_POLICY_DAEMON_FIND_MARGINAL_TIME_MS) { 2861 Slogf.wtf(TAG, "Finding car power policy daemon took too long(%dms)", elapsedTimeMs); 2862 } 2863 2864 if (mFeatureFlags.carPowerPolicyRefactoring()) { 2865 ICarPowerPolicyDelegate daemon = ICarPowerPolicyDelegate.Stub.asInterface(binder); 2866 if (daemon == null) { 2867 Slogf.w(TAG, "Getting car power policy daemon interface failed. Power policy " 2868 + "management is not supported"); 2869 return false; 2870 } 2871 synchronized (mLock) { 2872 mRefactoredCarPowerPolicyDaemon = daemon; 2873 mConnectionInProgress = false; 2874 } 2875 mBinderHandler = new BinderHandler(daemon); 2876 } else { 2877 ICarPowerPolicySystemNotification daemon = 2878 ICarPowerPolicySystemNotification.Stub.asInterface(binder); 2879 if (daemon == null) { 2880 Slogf.w(TAG, "Getting car power policy daemon interface failed. Power policy " 2881 + "management is not supported"); 2882 return false; 2883 } 2884 synchronized (mLock) { 2885 mCarPowerPolicyDaemon = daemon; 2886 mConnectionInProgress = false; 2887 } 2888 mBinderHandler = new BinderHandler(daemon); 2889 } 2890 mBinderHandler.linkToDeath(); 2891 return true; 2892 } 2893 updateCurrentPowerPolicy(CarPowerPolicy accumulatedPolicy)2894 private void updateCurrentPowerPolicy(CarPowerPolicy accumulatedPolicy) { 2895 synchronized (mLock) { 2896 mCurrentPowerPolicyId = accumulatedPolicy.getPolicyId(); 2897 mCurrentAccumulatedPowerPolicy = accumulatedPolicy; 2898 } 2899 } 2900 2901 private final class BinderHandler implements IBinder.DeathRecipient { 2902 // TODO(b/286303350): replace with refactored daemon once power policy refactor is complete 2903 private ICarPowerPolicySystemNotification mDaemon; 2904 private ICarPowerPolicyDelegate mRefactoredDaemon; 2905 BinderHandler(ICarPowerPolicySystemNotification daemon)2906 private BinderHandler(ICarPowerPolicySystemNotification daemon) { 2907 mDaemon = daemon; 2908 } 2909 BinderHandler(ICarPowerPolicyDelegate daemon)2910 private BinderHandler(ICarPowerPolicyDelegate daemon) { 2911 mRefactoredDaemon = daemon; 2912 } 2913 2914 @Override binderDied()2915 public void binderDied() { 2916 Slogf.w(TAG, "Car power policy daemon died: reconnecting"); 2917 unlinkToDeath(); 2918 if (mFeatureFlags.carPowerPolicyRefactoring()) { 2919 mRefactoredDaemon = null; 2920 } else { 2921 mDaemon = null; 2922 } 2923 mReadyForCallback.set(false); 2924 synchronized (mLock) { 2925 if (mFeatureFlags.carPowerPolicyRefactoring()) { 2926 mRefactoredCarPowerPolicyDaemon = null; 2927 } else { 2928 mCarPowerPolicyDaemon = null; 2929 mHasControlOverDaemon = false; 2930 } 2931 } 2932 mHandler.postDelayed( 2933 () -> connectToDaemonHelper(CAR_POWER_POLICY_DAEMON_BIND_MAX_RETRY), 2934 CAR_POWER_POLICY_DAEMON_BIND_RETRY_INTERVAL_MS); 2935 } 2936 linkToDeath()2937 private void linkToDeath() { 2938 if (mFeatureFlags.carPowerPolicyRefactoring()) { 2939 if (mRefactoredDaemon == null) { 2940 return; 2941 } 2942 } else { 2943 if (mDaemon == null) { 2944 return; 2945 } 2946 } 2947 IBinder binder; 2948 if (mFeatureFlags.carPowerPolicyRefactoring()) { 2949 binder = mRefactoredDaemon.asBinder(); 2950 } else { 2951 binder = mDaemon.asBinder(); 2952 } 2953 if (binder == null) { 2954 Slogf.w(TAG, "Linking to binder death recipient skipped"); 2955 return; 2956 } 2957 try { 2958 binder.linkToDeath(this, 0); 2959 } catch (RemoteException e) { 2960 if (mFeatureFlags.carPowerPolicyRefactoring()) { 2961 mRefactoredDaemon = null; 2962 } else { 2963 mDaemon = null; 2964 } 2965 Slogf.w(TAG, e, "Linking to binder death recipient failed: %s"); 2966 } 2967 } 2968 unlinkToDeath()2969 private void unlinkToDeath() { 2970 if (mFeatureFlags.carPowerPolicyRefactoring()) { 2971 if (mRefactoredDaemon == null) { 2972 return; 2973 } 2974 } else { 2975 if (mDaemon == null) { 2976 return; 2977 } 2978 } 2979 IBinder binder; 2980 if (mFeatureFlags.carPowerPolicyRefactoring()) { 2981 binder = mRefactoredDaemon.asBinder(); 2982 } else { 2983 binder = mDaemon.asBinder(); 2984 } 2985 if (binder == null) { 2986 Slogf.w(TAG, "Unlinking from binder death recipient skipped"); 2987 return; 2988 } 2989 binder.unlinkToDeath(this, 0); 2990 } 2991 } 2992 2993 private final class PowerHandler extends Handler { 2994 private static final String TAG = PowerHandler.class.getSimpleName(); 2995 private static final int MSG_POWER_STATE_CHANGE = 0; 2996 private static final int MSG_DISPLAY_BRIGHTNESS_CHANGE = 1; 2997 private static final int MSG_DISPLAY_STATE_CHANGE = 2; 2998 private static final int MSG_PROCESSING_COMPLETE = 3; 2999 private static final int MSG_POWER_POLICY_NOTIFICATION = 4; 3000 3001 // Do not handle this immediately but with some delay as there can be a race between 3002 // display off due to rear view camera and delivery to here. 3003 private static final long MAIN_DISPLAY_EVENT_DELAY_MS = 500; 3004 3005 private final WeakReference<CarPowerManagementService> mService; 3006 PowerHandler(Looper looper, CarPowerManagementService service)3007 private PowerHandler(Looper looper, CarPowerManagementService service) { 3008 super(looper); 3009 mService = new WeakReference<CarPowerManagementService>(service); 3010 } 3011 handlePowerStateChange()3012 private void handlePowerStateChange() { 3013 Message msg = obtainMessage(MSG_POWER_STATE_CHANGE); 3014 sendMessage(msg); 3015 } 3016 handleDisplayBrightnessChange(int displayId, int brightness)3017 private void handleDisplayBrightnessChange(int displayId, int brightness) { 3018 Message msg = obtainMessage(MSG_DISPLAY_BRIGHTNESS_CHANGE, displayId, brightness); 3019 sendMessage(msg); 3020 } 3021 handleDisplayStateChange(int displayId, boolean on)3022 private void handleDisplayStateChange(int displayId, boolean on) { 3023 HandlerHelper.removeEqualMessages(this, MSG_DISPLAY_STATE_CHANGE, displayId); 3024 Message msg = obtainMessage(MSG_DISPLAY_STATE_CHANGE, displayId); 3025 msg.arg1 = on ? Display.STATE_ON : Display.STATE_OFF; 3026 sendMessageDelayed(msg, MAIN_DISPLAY_EVENT_DELAY_MS); 3027 } 3028 handleProcessingComplete()3029 private void handleProcessingComplete() { 3030 removeMessages(MSG_PROCESSING_COMPLETE); 3031 Message msg = obtainMessage(MSG_PROCESSING_COMPLETE); 3032 sendMessage(msg); 3033 } 3034 cancelProcessingComplete()3035 private void cancelProcessingComplete() { 3036 removeMessages(MSG_PROCESSING_COMPLETE); 3037 } 3038 handlePowerPolicyNotification(String policyId)3039 private void handlePowerPolicyNotification(String policyId) { 3040 Message msg = obtainMessage(MSG_POWER_POLICY_NOTIFICATION, policyId); 3041 sendMessage(msg); 3042 } 3043 handlePowerPolicyNotification(CarPowerPolicy accumulatedPolicy)3044 private void handlePowerPolicyNotification(CarPowerPolicy accumulatedPolicy) { 3045 Message msg = obtainMessage(MSG_POWER_POLICY_NOTIFICATION, accumulatedPolicy); 3046 sendMessage(msg); 3047 } 3048 cancelAll()3049 private void cancelAll() { 3050 removeMessages(MSG_POWER_STATE_CHANGE); 3051 removeMessages(MSG_DISPLAY_BRIGHTNESS_CHANGE); 3052 removeMessages(MSG_DISPLAY_STATE_CHANGE); 3053 removeMessages(MSG_PROCESSING_COMPLETE); 3054 removeMessages(MSG_POWER_POLICY_NOTIFICATION); 3055 } 3056 3057 @Override handleMessage(Message msg)3058 public void handleMessage(Message msg) { 3059 CarPowerManagementService service = mService.get(); 3060 if (service == null) { 3061 Slogf.i(TAG, "handleMessage null service"); 3062 return; 3063 } 3064 switch (msg.what) { 3065 case MSG_POWER_STATE_CHANGE: 3066 service.doHandlePowerStateChange(); 3067 break; 3068 case MSG_DISPLAY_BRIGHTNESS_CHANGE: 3069 service.doHandleDisplayBrightnessChange( 3070 /* displayId= */ msg.arg1, /* brightness= */ msg.arg2); 3071 break; 3072 case MSG_DISPLAY_STATE_CHANGE: 3073 int displayId = (Integer) msg.obj; 3074 boolean on = msg.arg1 == Display.STATE_ON; 3075 service.doHandleDisplayStateChange(displayId, on); 3076 break; 3077 case MSG_PROCESSING_COMPLETE: 3078 service.doHandleProcessingComplete(); 3079 break; 3080 case MSG_POWER_POLICY_NOTIFICATION: 3081 if (mFeatureFlags.carPowerPolicyRefactoring()) { 3082 service.doHandlePowerPolicyNotification((CarPowerPolicy) msg.obj); 3083 } else { 3084 service.doHandlePowerPolicyNotification((String) msg.obj); 3085 } 3086 break; 3087 default: 3088 Slogf.w(TAG, "handleMessage invalid message type: %d", msg.what); 3089 break; 3090 } 3091 } 3092 } 3093 3094 // Send the command to enter Suspend to RAM. 3095 // If the command is not successful, try again with an exponential back-off. 3096 // If it fails repeatedly, send the command to shut down. 3097 // If we decide to go to a different power state, abort this retry mechanism. 3098 // Returns true if we successfully suspended. suspendWithRetries()3099 private boolean suspendWithRetries() { 3100 boolean isSuspendToDisk; 3101 synchronized (mLock) { 3102 isSuspendToDisk = mActionOnFinish == ACTION_ON_FINISH_HIBERNATION; 3103 } 3104 3105 String suspendTarget = isSuspendToDisk ? "Suspend-to-Disk" : "Suspend-to-RAM"; 3106 long retryIntervalMs = INITIAL_SUSPEND_RETRY_INTERVAL_MS; 3107 long totalWaitDurationMs = 0; 3108 while (true) { 3109 long suspendStartTime = SystemClock.elapsedRealtime(); 3110 Slogf.i(TAG, "Entering %s", suspendTarget); 3111 if (isSuspendToDisk) { 3112 freeMemory(); 3113 } 3114 boolean suspendSucceeded = isSuspendToDisk ? mSystemInterface.enterHibernation() 3115 : mSystemInterface.enterDeepSleep(); 3116 3117 if (suspendSucceeded) { 3118 return true; 3119 } 3120 if (totalWaitDurationMs >= mMaxSuspendWaitDurationMs) { 3121 break; 3122 } 3123 // We failed to suspend. Block the thread briefly and try again. 3124 synchronized (mLock) { 3125 if (!mPendingPowerStates.isEmpty()) { 3126 // Check for a new power state now, before going around the loop again. 3127 CpmsState state = mPendingPowerStates.peekFirst(); 3128 if (state != null && needPowerStateChangeLocked(state)) { 3129 Slogf.i(TAG, "Terminating the attempt to suspend target = %s," 3130 + " currentState = %s, pendingState = %s", suspendTarget, 3131 mCurrentState.stateToString(), state.stateToString()); 3132 return false; 3133 } 3134 } 3135 long suspendStopTime = SystemClock.elapsedRealtime(); 3136 Slogf.w(TAG, "Failed to Suspend; will retry after %dms", retryIntervalMs); 3137 try { 3138 mLock.wait(retryIntervalMs); 3139 } catch (InterruptedException ignored) { 3140 Thread.currentThread().interrupt(); 3141 } 3142 totalWaitDurationMs += retryIntervalMs; 3143 totalWaitDurationMs += (suspendStopTime - suspendStartTime); 3144 retryIntervalMs = Math.min(retryIntervalMs * 2, MAX_RETRY_INTERVAL_MS); 3145 } 3146 } 3147 // Too many failures trying to suspend. Shut down. 3148 Slogf.w(TAG, "Could not %s after %dms long trial. Shutting down.", suspendTarget, 3149 totalWaitDurationMs); 3150 mSystemInterface.shutdown(); 3151 return false; 3152 } 3153 3154 private static final class CpmsState { 3155 // NOTE: When modifying states below, make sure to update CarPowerStateChanged.State in 3156 // frameworks/proto_logging/stats/atoms.proto also. 3157 public static final int WAIT_FOR_VHAL = 0; 3158 public static final int ON = 1; 3159 public static final int SHUTDOWN_PREPARE = 2; 3160 public static final int WAIT_FOR_FINISH = 3; 3161 public static final int SUSPEND = 4; 3162 public static final int SIMULATE_SLEEP = 5; 3163 public static final int SIMULATE_HIBERNATION = 6; 3164 3165 /* Config values from AP_POWER_STATE_REQ */ 3166 public final boolean mCanPostpone; 3167 3168 @PowerState.ShutdownType 3169 public final int mShutdownType; 3170 3171 /* Message sent to CarPowerStateListener in response to this state */ 3172 @CarPowerManager.CarPowerState 3173 public final int mCarPowerStateListenerState; 3174 /* One of the above state variables */ 3175 public final int mState; 3176 3177 /** 3178 * This constructor takes a PowerHalService.PowerState object and creates the corresponding 3179 * CPMS state from it. 3180 */ CpmsState(PowerState halPowerState)3181 CpmsState(PowerState halPowerState) { 3182 switch (halPowerState.mState) { 3183 case VehicleApPowerStateReq.ON: 3184 this.mCanPostpone = false; 3185 this.mShutdownType = PowerState.SHUTDOWN_TYPE_UNDEFINED; 3186 this.mCarPowerStateListenerState = cpmsStateToPowerStateListenerState(ON); 3187 this.mState = ON; 3188 break; 3189 case VehicleApPowerStateReq.SHUTDOWN_PREPARE: 3190 this.mCanPostpone = halPowerState.canPostponeShutdown(); 3191 this.mShutdownType = halPowerState.getShutdownType(); 3192 this.mCarPowerStateListenerState = cpmsStateToPowerStateListenerState( 3193 SHUTDOWN_PREPARE); 3194 this.mState = SHUTDOWN_PREPARE; 3195 break; 3196 case VehicleApPowerStateReq.CANCEL_SHUTDOWN: 3197 this.mCanPostpone = false; 3198 this.mShutdownType = PowerState.SHUTDOWN_TYPE_UNDEFINED; 3199 this.mCarPowerStateListenerState = CarPowerManager.STATE_SHUTDOWN_CANCELLED; 3200 this.mState = WAIT_FOR_VHAL; 3201 break; 3202 case VehicleApPowerStateReq.FINISHED: 3203 this.mCanPostpone = false; 3204 this.mShutdownType = PowerState.SHUTDOWN_TYPE_UNDEFINED; 3205 this.mCarPowerStateListenerState = cpmsStateToPowerStateListenerState(SUSPEND); 3206 this.mState = SUSPEND; 3207 break; 3208 default: 3209 // Illegal state from PowerState. Throw an exception? 3210 // TODO(b/202414427): Add handling of illegal state 3211 this.mCanPostpone = false; 3212 this.mShutdownType = PowerState.SHUTDOWN_TYPE_UNDEFINED; 3213 this.mCarPowerStateListenerState = 0; 3214 this.mState = 0; 3215 break; 3216 } 3217 } 3218 CpmsState(int state, int carPowerStateListenerState, boolean canPostpone)3219 CpmsState(int state, int carPowerStateListenerState, boolean canPostpone) { 3220 this.mCanPostpone = canPostpone; 3221 this.mCarPowerStateListenerState = carPowerStateListenerState; 3222 this.mState = state; 3223 this.mShutdownType = state == SIMULATE_SLEEP ? PowerState.SHUTDOWN_TYPE_DEEP_SLEEP : 3224 (state == SIMULATE_HIBERNATION ? PowerState.SHUTDOWN_TYPE_HIBERNATION 3225 : PowerState.SHUTDOWN_TYPE_POWER_OFF); 3226 } 3227 CpmsState(int state, int carPowerStateListenerState, boolean canPostpone, int shutdownType)3228 CpmsState(int state, int carPowerStateListenerState, boolean canPostpone, 3229 int shutdownType) { 3230 this.mCanPostpone = canPostpone; 3231 this.mCarPowerStateListenerState = carPowerStateListenerState; 3232 this.mState = state; 3233 this.mShutdownType = shutdownType; 3234 } 3235 name()3236 public String name() { 3237 return new StringBuilder() 3238 .append(stateToString()) 3239 .append('(') 3240 .append(mState) 3241 .append(')') 3242 .toString(); 3243 } 3244 stateToString()3245 private String stateToString() { 3246 String baseName; 3247 switch(mState) { 3248 case WAIT_FOR_VHAL: baseName = "WAIT_FOR_VHAL"; break; 3249 case ON: baseName = "ON"; break; 3250 case SHUTDOWN_PREPARE: baseName = "SHUTDOWN_PREPARE"; break; 3251 case WAIT_FOR_FINISH: baseName = "WAIT_FOR_FINISH"; break; 3252 case SUSPEND: baseName = "SUSPEND"; break; 3253 case SIMULATE_SLEEP: baseName = "SIMULATE_SLEEP"; break; 3254 case SIMULATE_HIBERNATION: baseName = "SIMULATE_HIBERNATION"; break; 3255 default: baseName = "<unknown>"; break; 3256 } 3257 return baseName; 3258 } 3259 cpmsStateToPowerStateListenerState(int state)3260 private static int cpmsStateToPowerStateListenerState(int state) { 3261 int powerStateListenerState = 0; 3262 3263 // Set the CarPowerStateListenerState based on current state 3264 switch (state) { 3265 case ON: 3266 powerStateListenerState = CarPowerManager.STATE_ON; 3267 break; 3268 case SHUTDOWN_PREPARE: 3269 powerStateListenerState = CarPowerManager.STATE_PRE_SHUTDOWN_PREPARE; 3270 break; 3271 case SUSPEND: 3272 powerStateListenerState = CarPowerManager.STATE_SUSPEND_ENTER; 3273 break; 3274 case WAIT_FOR_VHAL: 3275 case WAIT_FOR_FINISH: 3276 default: 3277 // Illegal state for this constructor. Throw an exception? 3278 break; 3279 } 3280 return powerStateListenerState; 3281 } 3282 3283 @Override equals(Object o)3284 public boolean equals(Object o) { 3285 if (this == o) { 3286 return true; 3287 } 3288 if (!(o instanceof CpmsState)) { 3289 return false; 3290 } 3291 CpmsState that = (CpmsState) o; 3292 return this.mState == that.mState 3293 && this.mShutdownType == that.mShutdownType 3294 && this.mCanPostpone == that.mCanPostpone 3295 && this.mCarPowerStateListenerState == that.mCarPowerStateListenerState; 3296 } 3297 3298 @Override hashCode()3299 public int hashCode() { 3300 return Objects.hash(mCanPostpone, mShutdownType, mCarPowerStateListenerState, mState); 3301 } 3302 3303 // PowerPolicyHostTest uses the dump output of {@code CarPowerManagementService}. If the 3304 // {@code CpmsState.toString} is modifed, PowerPolicyHostTest should be updated accordingly. 3305 // TODO(b/184862429): Remove the above comment once dump in proto buffer is done. 3306 @Override toString()3307 public String toString() { 3308 return "CpmsState canPostpone=" + mCanPostpone 3309 + ", carPowerStateListenerState=" + mCarPowerStateListenerState 3310 + ", mShutdownType=" + mShutdownType 3311 + ", CpmsState=" + name(); 3312 } 3313 } 3314 3315 /** 3316 * Resume after a manually-invoked suspend. 3317 * Invoked using "adb shell dumpsys cmd car_service resume". 3318 */ forceSimulatedResume()3319 public void forceSimulatedResume() { 3320 synchronized (mLock) { 3321 // Cancel Garage Mode in case it's running 3322 boolean isSuspendToDisk = mActionOnFinish == ACTION_ON_FINISH_HIBERNATION; 3323 mPendingPowerStates.addFirst(new CpmsState(CpmsState.WAIT_FOR_VHAL, 3324 isSuspendToDisk ? CarPowerManager.STATE_HIBERNATION_EXIT 3325 : CarPowerManager.STATE_SUSPEND_EXIT, /* canPostpone= */ false)); 3326 mLock.notifyAll(); 3327 } 3328 mHandler.handlePowerStateChange(); 3329 3330 synchronized (mSimulationWaitObject) { 3331 mWakeFromSimulatedSleep = true; 3332 mSimulationWaitObject.notifyAll(); 3333 } 3334 } 3335 3336 /** 3337 * Manually enters simulated suspend (deep sleep or hibernation) mode, trigging Garage mode. 3338 * 3339 * <p>If {@code shouldReboot} is 'true', reboots the system when Garage Mode completes. 3340 * 3341 * Can be invoked using 3342 * {@code "adb shell cmd car_service suspend --simulate"} or 3343 * {@code "adb shell cmd car_service hibernate --simulate"} or 3344 * {@code "adb shell cmd car_service garage-mode reboot"}. 3345 * 3346 * This is similar to {@code 'onApPowerStateChange()'} except that it needs to create a 3347 * {@code CpmsState} that is not directly derived from a {@code VehicleApPowerStateReq}. 3348 */ simulateSuspendAndMaybeReboot(@owerState.ShutdownType int shutdownType, boolean shouldReboot, boolean skipGarageMode, int wakeupAfter, boolean freeMemory)3349 public void simulateSuspendAndMaybeReboot(@PowerState.ShutdownType int shutdownType, 3350 boolean shouldReboot, boolean skipGarageMode, int wakeupAfter, boolean freeMemory) { 3351 simulateSuspendAndMaybeReboot(shutdownType, shouldReboot, skipGarageMode, wakeupAfter, 3352 CarPowerManagementService.NO_WAKEUP_BY_TIMER, freeMemory); 3353 } 3354 3355 /** 3356 * Manually enters simulated suspend (deep sleep or hibernation) mode, trigging Garage mode. 3357 * 3358 * <p>If {@code shouldReboot} is 'true', reboots the system when Garage Mode completes. 3359 * 3360 * Can be invoked using 3361 * {@code "adb shell cmd car_service suspend --simulate"} or 3362 * {@code "adb shell cmd car_service hibernate --simulate"} or 3363 * {@code "adb shell cmd car_service garage-mode reboot"}. 3364 * 3365 * This is similar to {@code 'onApPowerStateChange()'} except that it needs to create a 3366 * {@code CpmsState} that is not directly derived from a {@code VehicleApPowerStateReq}. 3367 */ 3368 // TODO(b/274895468): Add tests simulateSuspendAndMaybeReboot(@owerState.ShutdownType int shutdownType, boolean shouldReboot, boolean skipGarageMode, int wakeupAfter, int cancelAfter, boolean freeMemory)3369 public void simulateSuspendAndMaybeReboot(@PowerState.ShutdownType int shutdownType, 3370 boolean shouldReboot, boolean skipGarageMode, int wakeupAfter, int cancelAfter, 3371 boolean freeMemory) { 3372 boolean isDeepSleep = shutdownType == PowerState.SHUTDOWN_TYPE_DEEP_SLEEP; 3373 if (cancelAfter >= 0) { 3374 Slogf.i(TAG, "Cancel after is: %d", cancelAfter); 3375 } 3376 if (wakeupAfter >= 0) { 3377 Slogf.i(TAG, "Wakeup after is: %d", wakeupAfter); 3378 } 3379 synchronized (mSimulationWaitObject) { 3380 mInSimulatedDeepSleepMode = true; 3381 mWakeFromSimulatedSleep = false; 3382 mBlockFromSimulatedCancelEvent = false; 3383 mResumeDelayFromSimulatedSuspendSec = wakeupAfter; 3384 mCancelDelayFromSimulatedSuspendSec = cancelAfter; 3385 mFreeMemoryBeforeSuspend = freeMemory; 3386 } 3387 synchronized (mLock) { 3388 mRebootAfterGarageMode = shouldReboot; 3389 mPendingPowerStates.addFirst(new CpmsState(isDeepSleep ? CpmsState.SIMULATE_SLEEP 3390 : CpmsState.SIMULATE_HIBERNATION, 3391 CarPowerManager.STATE_PRE_SHUTDOWN_PREPARE, !skipGarageMode)); 3392 } 3393 mHandler.handlePowerStateChange(); 3394 } 3395 3396 /** 3397 * Manually defines a power policy. 3398 * 3399 * <p>If the given ID already exists or specified power components are invalid, it fails. 3400 * 3401 * @return {@code true}, if successful. Otherwise, {@code false}. 3402 */ definePowerPolicyFromCommand(String[] args, IndentingPrintWriter writer)3403 public boolean definePowerPolicyFromCommand(String[] args, IndentingPrintWriter writer) { 3404 if (args.length < 2) { 3405 writer.println("Too few arguments"); 3406 return false; 3407 } 3408 String powerPolicyId = args[1]; 3409 int index = 2; 3410 String[] enabledComponents = new String[0]; 3411 String[] disabledComponents = new String[0]; 3412 while (index < args.length) { 3413 switch (args[index]) { 3414 case "--enable": 3415 if (index == args.length - 1) { 3416 writer.println("No components for --enable"); 3417 return false; 3418 } 3419 enabledComponents = args[index + 1].split(","); 3420 break; 3421 case "--disable": 3422 if (index == args.length - 1) { 3423 writer.println("No components for --disabled"); 3424 return false; 3425 } 3426 disabledComponents = args[index + 1].split(","); 3427 break; 3428 default: 3429 writer.printf("Unrecognized argument: %s\n", args[index]); 3430 return false; 3431 } 3432 index += 2; 3433 } 3434 int status = definePowerPolicy(powerPolicyId, enabledComponents, disabledComponents); 3435 if (status != PolicyOperationStatus.OK) { 3436 writer.println(PolicyOperationStatus.errorCodeToString(status)); 3437 return false; 3438 } 3439 writer.printf("Power policy(%s) is successfully defined.\n", powerPolicyId); 3440 return true; 3441 } 3442 3443 /** 3444 * Defines a power policy with the given id and components. 3445 * 3446 * <p> A policy defined with this method is valid until the system is rebooted/restarted. 3447 */ 3448 @VisibleForTesting 3449 @PolicyOperationStatus.ErrorCode definePowerPolicy(String powerPolicyId, String[] enabledComponents, String[] disabledComponents)3450 public int definePowerPolicy(String powerPolicyId, String[] enabledComponents, 3451 String[] disabledComponents) { 3452 Preconditions.checkArgument(!powerPolicyId.startsWith( 3453 PolicyReader.SYSTEM_POWER_POLICY_PREFIX), 3454 "System power policy cannot be defined by apps"); 3455 int status = mPolicyReader.definePowerPolicy(powerPolicyId, 3456 enabledComponents, disabledComponents); 3457 if (status != PolicyOperationStatus.OK) { 3458 return status; 3459 } 3460 // Get custom power components and update components list in PowerComponentHandler 3461 Collection<Integer> customComponents = mPolicyReader.getCustomComponents().values(); 3462 if (customComponents.size() > 0) { 3463 mPowerComponentHandler.registerCustomComponents( 3464 customComponents.toArray(new Integer[customComponents.size()])); 3465 } 3466 if (mFeatureFlags.carPowerPolicyRefactoring()) { 3467 ICarPowerPolicyDelegate daemon; 3468 synchronized (mLock) { 3469 daemon = mRefactoredCarPowerPolicyDaemon; 3470 } 3471 try { 3472 daemon.notifyPowerPolicyDefinition(powerPolicyId, enabledComponents, 3473 disabledComponents); 3474 } catch (IllegalArgumentException e) { 3475 int policyError = PolicyOperationStatus.ERROR_INVALID_POWER_POLICY_ID; 3476 int componentError = PolicyOperationStatus.ERROR_INVALID_POWER_COMPONENT; 3477 Slogf.w(TAG, e, "%s and/or %s", 3478 PolicyOperationStatus.errorCodeToString(policyError), 3479 PolicyOperationStatus.errorCodeToString(componentError)); 3480 return policyError; 3481 } catch (IllegalStateException | RemoteException e) { 3482 int error = PolicyOperationStatus.ERROR_DEFINE_POWER_POLICY; 3483 Slogf.w(TAG, e, PolicyOperationStatus.errorCodeToString(error)); 3484 return error; 3485 } catch (SecurityException e) { 3486 int error = PolicyOperationStatus.ERROR_DEFINE_POWER_POLICY; 3487 Slogf.w(TAG, e, "%s; insufficient permissions", 3488 PolicyOperationStatus.errorCodeToString(error)); 3489 return error; 3490 } 3491 } else { 3492 ICarPowerPolicySystemNotification daemon; 3493 synchronized (mLock) { 3494 daemon = mCarPowerPolicyDaemon; 3495 } 3496 try { 3497 daemon.notifyPowerPolicyDefinition(powerPolicyId, enabledComponents, 3498 disabledComponents); 3499 } catch (RemoteException e) { 3500 int error = PolicyOperationStatus.ERROR_DEFINE_POWER_POLICY; 3501 Slogf.w(TAG, e, PolicyOperationStatus.errorCodeToString(error)); 3502 return error; 3503 } 3504 } 3505 return PolicyOperationStatus.OK; 3506 } 3507 3508 /** 3509 * Manually applies a power policy. 3510 * 3511 * <p>If the given ID is not defined, it fails. 3512 * 3513 * @return {@code true}, if successful. Otherwise, {@code false}. 3514 */ applyPowerPolicyFromCommand(String[] args, IndentingPrintWriter writer)3515 public boolean applyPowerPolicyFromCommand(String[] args, IndentingPrintWriter writer) { 3516 if (args.length != 2) { 3517 writer.println("Power policy ID should be given"); 3518 return false; 3519 } 3520 String powerPolicyId = args[1]; 3521 if (powerPolicyId == null) { 3522 writer.println("Policy ID cannot be null"); 3523 return false; 3524 } 3525 int status; 3526 Slogf.i(TAG, "Applying power policy(%s) from shell command", powerPolicyId); 3527 if (mFeatureFlags.carPowerPolicyRefactoring()) { 3528 status = applyPowerPolicy(powerPolicyId, /* delayNotification= */ false, 3529 /* upToDaemon= */ false, /* force= */ false); 3530 } else { 3531 boolean isPreemptive = mPolicyReader.isPreemptivePowerPolicy(powerPolicyId); 3532 status = isPreemptive ? applyPreemptivePowerPolicy(powerPolicyId) 3533 : applyPowerPolicy(powerPolicyId, /* delayNotification= */ false, 3534 /* upToDaemon= */ true, /* force= */ false); 3535 } 3536 if (status != PolicyOperationStatus.OK) { 3537 writer.println(PolicyOperationStatus.errorCodeToString(status)); 3538 return false; 3539 } 3540 writer.printf("Power policy(%s) is successfully applied.\n", powerPolicyId); 3541 return true; 3542 } 3543 3544 /** 3545 * Manually defines a power policy group. 3546 * 3547 * <p>If the given ID already exists, a wrong power state is given, or specified power policy ID 3548 * doesn't exist, it fails. 3549 * 3550 * @return {@code true}, if successful. Otherwise, {@code false}. 3551 */ definePowerPolicyGroupFromCommand(String[] args, IndentingPrintWriter writer)3552 public boolean definePowerPolicyGroupFromCommand(String[] args, IndentingPrintWriter writer) { 3553 if (args.length < 3 || args.length > 4) { 3554 writer.println("Invalid syntax"); 3555 return false; 3556 } 3557 String policyGroupId = args[1]; 3558 int index = 2; 3559 SparseArray<String> defaultPolicyPerState = new SparseArray<>(); 3560 String[] powerPolicyPerState = {"", ""}; 3561 while (index < args.length) { 3562 String[] tokens = args[index].split(":"); 3563 if (tokens.length != 2) { 3564 writer.println("Invalid syntax"); 3565 return false; 3566 } 3567 int state = PolicyReader.toPowerState(tokens[0]); 3568 if (state == PolicyReader.INVALID_POWER_STATE) { 3569 writer.printf("Invalid power state: %s\n", tokens[0]); 3570 return false; 3571 } 3572 defaultPolicyPerState.put(state, tokens[1]); 3573 switch (state) { 3574 case VehicleApPowerStateReport.WAIT_FOR_VHAL: 3575 powerPolicyPerState[INDEX_WAIT_FOR_VHAL] = tokens[1]; 3576 break; 3577 case VehicleApPowerStateReport.ON: 3578 powerPolicyPerState[INDEX_ON] = tokens[1]; 3579 break; 3580 } 3581 index++; 3582 } 3583 if (mFeatureFlags.carPowerPolicyRefactoring()) { 3584 ICarPowerPolicyDelegate daemon; 3585 synchronized (mLock) { 3586 daemon = mRefactoredCarPowerPolicyDaemon; 3587 } 3588 try { 3589 daemon.notifyPowerPolicyGroupDefinition(policyGroupId, powerPolicyPerState); 3590 } catch (IllegalArgumentException e) { 3591 Slogf.w(TAG, e, "The given policy group ID(%s) or mapping between power state and" 3592 + " policy is invalid", policyGroupId); 3593 return false; 3594 } catch (RemoteException e) { 3595 Slogf.w(TAG, e, "Calling ICarPowerPolicyDelegate.notifyPowerPolicyGroupDefinition" 3596 + " failed"); 3597 return false; 3598 } 3599 } 3600 int status = mPolicyReader.definePowerPolicyGroup(policyGroupId, 3601 defaultPolicyPerState); 3602 if (status != PolicyOperationStatus.OK) { 3603 writer.println(PolicyOperationStatus.errorCodeToString(status)); 3604 return false; 3605 } 3606 writer.printf("Power policy group(%s) is successfully defined.\n", policyGroupId); 3607 return true; 3608 } 3609 3610 /** 3611 * Manually sets a power policy group. 3612 * 3613 * <p>If the given ID is not defined, it fails. 3614 * 3615 * @return {@code true}, if successful. Otherwise, {@code false}. 3616 */ setPowerPolicyGroupFromCommand(String[] args, IndentingPrintWriter writer)3617 public boolean setPowerPolicyGroupFromCommand(String[] args, IndentingPrintWriter writer) { 3618 if (args.length != 2) { 3619 writer.println("Power policy group ID should be given"); 3620 return false; 3621 } 3622 String policyGroupId = args[1]; 3623 if (mFeatureFlags.carPowerPolicyRefactoring()) { 3624 try { 3625 setPowerPolicyGroup(policyGroupId); 3626 } catch (RemoteException e) { 3627 writer.println("RemoteException encountered when setting power policy group"); 3628 return false; 3629 } 3630 } else { 3631 int status = setCurrentPowerPolicyGroup(policyGroupId); 3632 if (status != PolicyOperationStatus.OK) { 3633 writer.println(PolicyOperationStatus.errorCodeToString(status)); 3634 return false; 3635 } 3636 } 3637 writer.printf("Setting power policy group(%s) is successful.\n", policyGroupId); 3638 return true; 3639 } 3640 3641 /** 3642 * Suspends the device. 3643 * 3644 * <p>According to the argument, the device is suspended to RAM or disk. 3645 */ suspendFromCommand(boolean isHibernation, boolean skipGarageMode)3646 public void suspendFromCommand(boolean isHibernation, boolean skipGarageMode) { 3647 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 3648 int param = 0; 3649 if (isHibernation) { 3650 if (!isHibernationAvailable()) { 3651 throw new IllegalStateException("The device doesn't support hibernation"); 3652 } 3653 param = skipGarageMode ? VehicleApPowerStateShutdownParam.HIBERNATE_IMMEDIATELY 3654 : VehicleApPowerStateShutdownParam.CAN_HIBERNATE; 3655 } else { 3656 if (!isDeepSleepAvailable()) { 3657 throw new IllegalStateException("The device doesn't support deep sleep"); 3658 } 3659 param = skipGarageMode ? VehicleApPowerStateShutdownParam.SLEEP_IMMEDIATELY 3660 : VehicleApPowerStateShutdownParam.CAN_SLEEP; 3661 } 3662 PowerState state = new PowerState(VehicleApPowerStateReq.SHUTDOWN_PREPARE, param); 3663 synchronized (mLock) { 3664 mRebootAfterGarageMode = false; 3665 mPendingPowerStates.addFirst(new CpmsState(state)); 3666 mLock.notifyAll(); 3667 } 3668 mHandler.handlePowerStateChange(); 3669 } 3670 3671 /** 3672 * Powers off the device. 3673 */ powerOffFromCommand(boolean skipGarageMode, boolean reboot)3674 public void powerOffFromCommand(boolean skipGarageMode, boolean reboot) { 3675 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 3676 Slogf.i(TAG, "%s %s Garage Mode", reboot ? "Rebooting" : "Powering off", 3677 skipGarageMode ? "with" : "without"); 3678 int param = skipGarageMode ? VehicleApPowerStateShutdownParam.SHUTDOWN_IMMEDIATELY 3679 : VehicleApPowerStateShutdownParam.SHUTDOWN_ONLY; 3680 PowerState state = new PowerState(VehicleApPowerStateReq.SHUTDOWN_PREPARE, param); 3681 synchronized (mLock) { 3682 mRebootAfterGarageMode = reboot; 3683 mPendingPowerStates.addFirst(new CpmsState(state)); 3684 mLock.notifyAll(); 3685 } 3686 mHandler.handlePowerStateChange(); 3687 } 3688 3689 /** 3690 * Returns the last shutdown state. 3691 */ getLastShutdownState()3692 public int getLastShutdownState() { 3693 synchronized (mLock) { 3694 return mLastShutdownState; 3695 } 3696 } 3697 3698 /** 3699 * Changes Silent Mode to the given mode. 3700 */ setSilentMode(String silentMode)3701 public void setSilentMode(String silentMode) { 3702 CarServiceUtils.assertPermission(mContext, Car.PERMISSION_CAR_POWER); 3703 mSilentModeHandler.setSilentMode(silentMode); 3704 if (mFeatureFlags.carPowerPolicyRefactoring()) { 3705 ICarPowerPolicyDelegate daemon; 3706 synchronized (mLock) { 3707 daemon = mRefactoredCarPowerPolicyDaemon; 3708 } 3709 if (daemon != null) { 3710 try { 3711 daemon.setSilentMode(silentMode); 3712 } catch (RemoteException e) { 3713 Slogf.e(TAG, e, "Failed to notify car power policy daemon of the new silent " 3714 + "mode(%s)", silentMode); 3715 return; 3716 } 3717 } else { 3718 Slogf.w(TAG, "Failed to notify the new silent mode, car power policy daemon" 3719 + " is not available"); 3720 return; 3721 } 3722 Slogf.i(TAG, "Set the new silent mode(%s) to CPPD", silentMode); 3723 } 3724 } 3725 3726 /** 3727 * Dumps the current Silent Mode. 3728 */ 3729 @ExcludeFromCodeCoverageGeneratedReport(reason = DUMP_INFO) dumpSilentMode(IndentingPrintWriter writer)3730 public void dumpSilentMode(IndentingPrintWriter writer) { 3731 mSilentModeHandler.dump(writer); 3732 } 3733 3734 /** 3735 * Returns whether a listener completion is allowed for the given state. 3736 * 3737 * <p>This method is used internally and is different from 3738 * {@link CarPowerManager.isCompletionAllowed} in that listener completion is allowed for 3739 * SHUTDOWN_PREPARE. 3740 */ isCompletionAllowed(@arPowerManager.CarPowerState int state)3741 public static boolean isCompletionAllowed(@CarPowerManager.CarPowerState int state) { 3742 return CarPowerManager.isCompletionAllowed(state); 3743 } 3744 3745 /** 3746 * Returns a corresponding string of the given power state. 3747 */ powerStateToString(int state)3748 public static String powerStateToString(int state) { 3749 return DebugUtils.valueToString(CarPowerManager.class, "STATE_", state); 3750 } 3751 3752 /** 3753 * Requests VHAL to shutdown the head unit. 3754 * 3755 * @throws UnsupportedOperationException If the system doesn't not support 3756 * {@code nextPowerState}. 3757 */ requestShutdownAp(int nextPowerState, boolean runGarageMode)3758 public void requestShutdownAp(int nextPowerState, boolean runGarageMode) { 3759 int shutdownParam = PowerState.SHUTDOWN_TYPE_POWER_OFF; 3760 switch (nextPowerState) { 3761 case CarRemoteAccessManager.NEXT_POWER_STATE_ON: 3762 // Do nothing. 3763 return; 3764 case CarRemoteAccessManager.NEXT_POWER_STATE_OFF: 3765 shutdownParam = PowerState.SHUTDOWN_TYPE_POWER_OFF; 3766 break; 3767 case CarRemoteAccessManager.NEXT_POWER_STATE_SUSPEND_TO_RAM: 3768 if (!isDeepSleepAvailable()) { 3769 throw new UnsupportedOperationException("Suspend-to-RAM is not supported"); 3770 } 3771 shutdownParam = PowerState.SHUTDOWN_TYPE_DEEP_SLEEP; 3772 break; 3773 case CarRemoteAccessManager.NEXT_POWER_STATE_SUSPEND_TO_DISK: 3774 if (!isHibernationAvailable()) { 3775 throw new UnsupportedOperationException("Suspend-to-disk is not supported"); 3776 } 3777 shutdownParam = PowerState.SHUTDOWN_TYPE_HIBERNATION; 3778 break; 3779 default: 3780 Slogf.w(TAG, "Unknown power state(%d)", nextPowerState); 3781 return; 3782 } 3783 mHal.requestShutdownAp(shutdownParam, runGarageMode); 3784 } 3785 3786 /** 3787 * Returns whether suspend (deep sleep or hibernation) is available on the device. 3788 */ isSuspendAvailable(boolean isHibernation)3789 public boolean isSuspendAvailable(boolean isHibernation) { 3790 return isHibernation ? isHibernationAvailable() : isDeepSleepAvailable(); 3791 } 3792 3793 /** 3794 * Enters garage mode if the bootup reason is ENTER_GARAGE_MODE. 3795 */ 3796 @Override onInitComplete()3797 public void onInitComplete() { 3798 if (mFeatureFlags.serverlessRemoteAccess()) { 3799 maybeEnterGarageModeOnBoot(); 3800 } 3801 } 3802 3803 /** 3804 * Shutdown the device to run garage mode if the bootup reason is ENTER_GARAGE_MODE. 3805 */ maybeEnterGarageModeOnBoot()3806 private void maybeEnterGarageModeOnBoot() { 3807 @BootupReason int bootupReason = mHal.getVehicleApBootupReason(); 3808 Slogf.i(TAG, "Vehicle AP power bootup reason: " + bootupReason); 3809 if (bootupReason != BOOTUP_REASON_SYSTEM_ENTER_GARAGE_MODE) { 3810 return; 3811 } 3812 if (mHal.isVehicleInUse()) { 3813 Slogf.i(TAG, "Bootup reason is ENTER_GARAGE_MODE but vehicle is currently in use" 3814 + ", skip entering garage mode"); 3815 return; 3816 } 3817 try { 3818 requestShutdownAp(getLastShutdownState(), /* runGarageMode= */ true); 3819 } catch (Exception e) { 3820 Slogf.wtf(TAG, "Failed to call requestShutdownAp", e); 3821 } 3822 } 3823 isDeepSleepAvailable()3824 private boolean isDeepSleepAvailable() { 3825 return mHal.isDeepSleepAllowed() && mSystemInterface.isSystemSupportingDeepSleep(); 3826 } 3827 isHibernationAvailable()3828 private boolean isHibernationAvailable() { 3829 return mHal.isHibernationAllowed() && mSystemInterface.isSystemSupportingHibernation(); 3830 } 3831 3832 // In a real Deep Sleep, the hardware removes power from the CPU (but retains power 3833 // on the RAM). This puts the processor to sleep. Upon some external signal, power 3834 // is re-applied to the CPU, and processing resumes right where it left off. 3835 // We simulate this behavior by calling wait(). 3836 // We continue from wait() when forceSimulatedResume() is called. simulateSleepByWaiting()3837 private void simulateSleepByWaiting() { 3838 Slogf.i(TAG, "Starting to simulate Deep Sleep by waiting"); 3839 synchronized (mSimulationWaitObject) { 3840 if (mFreeMemoryBeforeSuspend) { 3841 freeMemory(); 3842 } 3843 if (mResumeDelayFromSimulatedSuspendSec >= 0) { 3844 Slogf.i(TAG, "Scheduling a wakeup after %d seconds", 3845 mResumeDelayFromSimulatedSuspendSec); 3846 Handler handler = new Handler(Looper.getMainLooper()); 3847 handler.postDelayed(() -> forceSimulatedResume(), 3848 mResumeDelayFromSimulatedSuspendSec * 1000L); 3849 } 3850 while (!mWakeFromSimulatedSleep) { 3851 try { 3852 mSimulationWaitObject.wait(); 3853 } catch (InterruptedException ignored) { 3854 Thread.currentThread().interrupt(); // Restore interrupted status 3855 } 3856 } 3857 mInSimulatedDeepSleepMode = false; 3858 } 3859 Slogf.i(TAG, "Exit Deep Sleep simulation"); 3860 } 3861 getMaxSuspendWaitDurationConfig()3862 private int getMaxSuspendWaitDurationConfig() { 3863 return mContext.getResources().getInteger(R.integer.config_maxSuspendWaitDuration); 3864 } 3865 isWifiAdjustmentForSuspendConfig()3866 private boolean isWifiAdjustmentForSuspendConfig() { 3867 return mContext.getResources().getBoolean(R.bool.config_wifiAdjustmentForSuspend); 3868 } 3869 getPreShutdownPrepareTimeoutConfig()3870 private int getPreShutdownPrepareTimeoutConfig() { 3871 return getCompletionWaitTimeoutConfig(R.integer.config_preShutdownPrepareTimeout); 3872 } 3873 getShutdownEnterTimeoutConfig()3874 private int getShutdownEnterTimeoutConfig() { 3875 return getCompletionWaitTimeoutConfig(R.integer.config_shutdownEnterTimeout); 3876 } 3877 getPostShutdownEnterTimeoutConfig()3878 private int getPostShutdownEnterTimeoutConfig() { 3879 return getCompletionWaitTimeoutConfig(R.integer.config_postShutdownEnterTimeout); 3880 } 3881 getS2dImportanceLevel()3882 private int getS2dImportanceLevel() { 3883 return convertMemorySuspendConfigToValue(mContext.getResources().getString( 3884 R.string.config_suspend_to_disk_memory_savings)); 3885 } 3886 getS2dAllowList()3887 private ArraySet<String> getS2dAllowList() { 3888 return new ArraySet<>(mContext.getResources().getStringArray( 3889 R.array.config_packages_not_to_stop_during_suspend)); 3890 } 3891 getCompletionWaitTimeoutConfig(int resourceId)3892 private int getCompletionWaitTimeoutConfig(int resourceId) { 3893 int timeout = mContext.getResources().getInteger(resourceId); 3894 return timeout >= 0 ? timeout : DEFAULT_COMPLETION_WAIT_TIMEOUT; 3895 } 3896 3897 @ExcludeFromCodeCoverageGeneratedReport(reason = DUMP_INFO) actionOnFinishToString(int actionOnFinish)3898 private static String actionOnFinishToString(int actionOnFinish) { 3899 switch (actionOnFinish) { 3900 case ACTION_ON_FINISH_SHUTDOWN: 3901 return "Shutdown"; 3902 case ACTION_ON_FINISH_DEEP_SLEEP: 3903 return "Deep sleep"; 3904 case ACTION_ON_FINISH_HIBERNATION: 3905 return "Hibernation"; 3906 default: 3907 return "Unknown"; 3908 } 3909 } 3910 waitForCompletionWithShutdownPostpone( @arPowerManager.CarPowerState int carPowerStateListenerState, long timeoutMs, Runnable taskAtCompletion, long intervalMs)3911 private void waitForCompletionWithShutdownPostpone( 3912 @CarPowerManager.CarPowerState int carPowerStateListenerState, long timeoutMs, 3913 Runnable taskAtCompletion, long intervalMs) { 3914 Runnable taskAtInterval = () -> { 3915 mHal.sendShutdownPostpone(SHUTDOWN_EXTEND_MAX_MS); 3916 }; 3917 3918 Slogf.i(TAG, "Start waiting for listener completion for %s", 3919 powerStateToString(carPowerStateListenerState)); 3920 3921 waitForCompletion(taskAtCompletion, taskAtInterval, timeoutMs, intervalMs); 3922 } 3923 3924 /** 3925 * Utility method to help with memory freeing before entering Suspend-To-Disk 3926 */ freeMemory()3927 private void freeMemory() { 3928 ActivityManagerHelper.killAllBackgroundProcesses(); 3929 if (!mFeatureFlags.stopProcessBeforeSuspendToDisk()) { 3930 return; 3931 } 3932 List<ActivityManager.RunningAppProcessInfo> allRunningAppProcesses = 3933 ActivityManagerHelper.getRunningAppProcesses(); 3934 ArraySet<Integer> safeUids = new ArraySet<>(); 3935 ArraySet<String> suspendToDiskAllowList = getS2dAllowList(); 3936 int suspendToDiskImportanceLevel = getS2dImportanceLevel(); 3937 for (int i = 0; i < allRunningAppProcesses.size(); i++) { 3938 ActivityManager.RunningAppProcessInfo info = allRunningAppProcesses.get(i); 3939 boolean isCarServiceOrMyPid = ICarImpl.class.getPackage().getName() 3940 .equals(info.processName) 3941 || info.pid == android.os.Process.myPid(); 3942 boolean isSystemOrShellUid = info.uid == Process.SYSTEM_UID 3943 || info.uid == Process.SHELL_UID; 3944 boolean isProcessPersistent = (ActivityManagerHelper 3945 .getFlagsForRunningAppProcessInfo(info) 3946 & ActivityManagerHelper.PROCESS_INFO_PERSISTENT_FLAG) != 0; 3947 boolean isWithinConfig = suspendToDiskImportanceLevel > info.importance; 3948 boolean isProcessAllowListed = suspendToDiskAllowList.contains(info.processName); 3949 if (isCarServiceOrMyPid || isSystemOrShellUid || isProcessPersistent 3950 || isWithinConfig || isProcessAllowListed) { 3951 safeUids.add(info.uid); 3952 } 3953 } 3954 3955 for (int i = 0; i < allRunningAppProcesses.size(); i++) { 3956 ActivityManager.RunningAppProcessInfo info = allRunningAppProcesses.get(i); 3957 if (!safeUids.contains(info.uid)) { 3958 for (int j = 0; j < info.pkgList.length; j++) { 3959 String pkgToStop = info.pkgList[j]; 3960 PackageManagerHelper.forceStopPackageAsUser(mContext, pkgToStop, 3961 UserManagerHelper.USER_ALL); 3962 } 3963 } 3964 } 3965 } 3966 3967 /** 3968 * Helper method to accept function with one displayId argument to run on all displays. 3969 */ forEachDisplay(@onNull Context context, @NonNull Consumer<Integer> consumer)3970 private static void forEachDisplay(@NonNull Context context, 3971 @NonNull Consumer<Integer> consumer) { 3972 DisplayManager displayManager = context.getSystemService(DisplayManager.class); 3973 for (Display display : displayManager.getDisplays()) { 3974 int displayId = display.getDisplayId(); 3975 consumer.accept(displayId); 3976 } 3977 } 3978 convertMemorySuspendConfigToValue(String configValue)3979 private int convertMemorySuspendConfigToValue(String configValue) { 3980 return switch (configValue) { 3981 case "low" -> ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED; 3982 case "medium" -> ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 3983 case "high" -> ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE; 3984 // none will fallthrough 3985 default -> ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE; 3986 }; 3987 } 3988 } 3989