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