1 /* 2 * Copyright (C) 2020 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.server.devicestate; 18 19 import static android.Manifest.permission.CONTROL_DEVICE_STATE; 20 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 21 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 22 import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS; 23 import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP; 24 import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE_IDENTIFIER; 25 import static android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE_IDENTIFIER; 26 import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE_IDENTIFIER; 27 28 import static com.android.server.devicestate.OverrideRequest.OVERRIDE_REQUEST_TYPE_BASE_STATE; 29 import static com.android.server.devicestate.OverrideRequest.OVERRIDE_REQUEST_TYPE_EMULATED_STATE; 30 import static com.android.server.devicestate.OverrideRequestController.FLAG_POWER_SAVE_ENABLED; 31 import static com.android.server.devicestate.OverrideRequestController.FLAG_THERMAL_CRITICAL; 32 import static com.android.server.devicestate.OverrideRequestController.STATUS_ACTIVE; 33 import static com.android.server.devicestate.OverrideRequestController.STATUS_CANCELED; 34 import static com.android.server.devicestate.OverrideRequestController.STATUS_UNKNOWN; 35 36 import android.annotation.IntDef; 37 import android.annotation.IntRange; 38 import android.annotation.NonNull; 39 import android.annotation.Nullable; 40 import android.app.ActivityManager; 41 import android.app.ActivityManagerInternal; 42 import android.app.IProcessObserver; 43 import android.content.Context; 44 import android.hardware.devicestate.DeviceState; 45 import android.hardware.devicestate.DeviceStateInfo; 46 import android.hardware.devicestate.DeviceStateManager; 47 import android.hardware.devicestate.DeviceStateManagerInternal; 48 import android.hardware.devicestate.IDeviceStateManager; 49 import android.hardware.devicestate.IDeviceStateManagerCallback; 50 import android.os.Binder; 51 import android.os.Handler; 52 import android.os.IBinder; 53 import android.os.RemoteException; 54 import android.os.ResultReceiver; 55 import android.os.ShellCallback; 56 import android.os.SystemProperties; 57 import android.os.Trace; 58 import android.util.Slog; 59 import android.util.SparseArray; 60 61 import com.android.internal.R; 62 import com.android.internal.annotations.GuardedBy; 63 import com.android.internal.annotations.VisibleForTesting; 64 import com.android.internal.util.DumpUtils; 65 import com.android.internal.util.FrameworkStatsLog; 66 import com.android.server.DisplayThread; 67 import com.android.server.LocalServices; 68 import com.android.server.SystemService; 69 import com.android.server.statusbar.StatusBarManagerInternal; 70 import com.android.server.wm.ActivityTaskManagerInternal; 71 import com.android.server.wm.WindowProcessController; 72 73 import java.io.FileDescriptor; 74 import java.io.PrintWriter; 75 import java.lang.annotation.Retention; 76 import java.lang.annotation.RetentionPolicy; 77 import java.util.ArrayList; 78 import java.util.Arrays; 79 import java.util.HashSet; 80 import java.util.List; 81 import java.util.Optional; 82 import java.util.Set; 83 import java.util.WeakHashMap; 84 85 /** 86 * A system service that manages the state of a device with user-configurable hardware like a 87 * foldable phone. 88 * <p> 89 * Device state is an abstract concept that allows mapping the current state of the device to the 90 * state of the system. For example, system services (like 91 * {@link com.android.server.display.DisplayManagerService display manager} and 92 * {@link com.android.server.wm.WindowManagerService window manager}) and system UI may have 93 * different behaviors depending on the physical state of the device. This is useful for 94 * variable-state devices, like foldable or rollable devices, that can be configured by users into 95 * differing hardware states, which each may have a different expected use case. 96 * </p> 97 * <p> 98 * The {@link DeviceStateManagerService} is responsible for receiving state change requests from 99 * the {@link DeviceStateProvider} to modify the current device state and communicating with the 100 * {@link DeviceStatePolicy policy} to ensure the system is configured to match the requested state. 101 * </p> 102 * The service also provides the {@link DeviceStateManager} API allowing clients to listen for 103 * changes in device state and submit requests to override the device state provided by the 104 * {@link DeviceStateProvider}. 105 * 106 * @see DeviceStatePolicy 107 * @see DeviceStateManager 108 */ 109 public final class DeviceStateManagerService extends SystemService { 110 private static final String TAG = "DeviceStateManagerService"; 111 private static final boolean DEBUG = false; 112 113 /** {@link DeviceState} to model an invalid device state */ 114 // TODO(b/328314031): Investigate how we can remove this constant 115 private static final DeviceState INVALID_DEVICE_STATE = new DeviceState( 116 new DeviceState.Configuration.Builder(INVALID_DEVICE_STATE_IDENTIFIER, 117 "INVALID").build()); 118 119 private final Object mLock = new Object(); 120 // Handler on the {@link DisplayThread} used to dispatch calls to the policy and to registered 121 // callbacks though its handler (mHandler). Provides a guarantee of callback order when 122 // leveraging mHandler and also enables posting messages with the service lock held. 123 private final Handler mHandler; 124 @NonNull 125 private final DeviceStatePolicy mDeviceStatePolicy; 126 @NonNull 127 private final BinderService mBinderService; 128 @NonNull 129 private final OverrideRequestController mOverrideRequestController; 130 @NonNull 131 private final DeviceStateProviderListener mDeviceStateProviderListener; 132 @VisibleForTesting 133 @NonNull 134 public ActivityTaskManagerInternal mActivityTaskManagerInternal; 135 136 // All supported device states keyed by identifier. 137 @GuardedBy("mLock") 138 private SparseArray<DeviceState> mDeviceStates = new SparseArray<>(); 139 140 // The current committed device state. Will be empty until the first device state provided by 141 // the DeviceStateProvider is committed. 142 @GuardedBy("mLock") 143 @NonNull 144 private Optional<DeviceState> mCommittedState = Optional.empty(); 145 // The device state that is currently awaiting callback from the policy to be committed. 146 @GuardedBy("mLock") 147 @NonNull 148 private Optional<DeviceState> mPendingState = Optional.empty(); 149 // Whether or not the policy is currently waiting to be notified of the current pending state. 150 @GuardedBy("mLock") 151 private boolean mIsPolicyWaitingForState = false; 152 153 // The device state that is set by the DeviceStateProvider. Will be empty until the first 154 // callback from the provider and then will always contain the most recent value. 155 @GuardedBy("mLock") 156 @NonNull 157 private Optional<DeviceState> mBaseState = Optional.empty(); 158 159 // The current active override request. When set the device state specified here will take 160 // precedence over mBaseState. 161 @GuardedBy("mLock") 162 @NonNull 163 private Optional<OverrideRequest> mActiveOverride = Optional.empty(); 164 165 // The current active base state override request. When set the device state specified here will 166 // replace the value in mBaseState. 167 @GuardedBy("mLock") 168 @NonNull 169 private Optional<OverrideRequest> mActiveBaseStateOverride = Optional.empty(); 170 171 // List of processes registered to receive notifications about changes to device state and 172 // request status indexed by process id. 173 @GuardedBy("mLock") 174 private final SparseArray<ProcessRecord> mProcessRecords = new SparseArray<>(); 175 176 private Set<Integer> mDeviceStatesAvailableForAppRequests = new HashSet<>(); 177 178 private Set<Integer> mFoldedDeviceStates; 179 180 @Nullable 181 private DeviceState mRearDisplayState; 182 183 // TODO(259328837) Generalize for all pending feature requests in the future 184 @GuardedBy("mLock") 185 @Nullable 186 private OverrideRequest mRearDisplayPendingOverrideRequest; 187 188 @VisibleForTesting 189 interface SystemPropertySetter { setDebugTracingDeviceStateProperty(String value)190 void setDebugTracingDeviceStateProperty(String value); 191 } 192 @NonNull 193 private final SystemPropertySetter mSystemPropertySetter; 194 195 @VisibleForTesting 196 final IProcessObserver mProcessObserver = new IProcessObserver.Stub() { 197 @Override 198 public void onForegroundActivitiesChanged(int pid, int uid, boolean fg) { 199 synchronized (mLock) { 200 if (!shouldCancelOverrideRequestWhenRequesterNotOnTop()) { 201 return; 202 } 203 204 OverrideRequest request = mActiveOverride.get(); 205 if (pid != request.getPid() || uid != request.getUid()) { 206 return; 207 } 208 if (!fg) { 209 mOverrideRequestController.cancelRequest(request); 210 } 211 } 212 } 213 214 @Override 215 public void onProcessStarted(int pid, int processUid, int packageUid, String packageName, 216 String processName) {} 217 218 @Override 219 public void onProcessDied(int pid, int uid) {} 220 221 @Override 222 public void onForegroundServicesChanged(int pid, int uid, int serviceTypes) {} 223 }; 224 @VisibleForTesting 225 ActivityTaskManagerInternal.ScreenObserver mOverrideRequestScreenObserver = 226 new OverrideRequestScreenObserver(); 227 228 @NonNull 229 private final DeviceStateNotificationController mDeviceStateNotificationController; 230 DeviceStateManagerService(@onNull Context context)231 public DeviceStateManagerService(@NonNull Context context) { 232 this(context, DeviceStatePolicy.Provider 233 .fromResources(context.getResources()) 234 .instantiate(context)); 235 } 236 DeviceStateManagerService(@onNull Context context, @NonNull DeviceStatePolicy policy)237 private DeviceStateManagerService(@NonNull Context context, @NonNull DeviceStatePolicy policy) { 238 this(context, policy, (value) -> { 239 SystemProperties.set("debug.tracing.device_state", value); 240 }); 241 } 242 243 @VisibleForTesting DeviceStateManagerService(@onNull Context context, @NonNull DeviceStatePolicy policy, @NonNull SystemPropertySetter systemPropertySetter)244 DeviceStateManagerService(@NonNull Context context, @NonNull DeviceStatePolicy policy, 245 @NonNull SystemPropertySetter systemPropertySetter) { 246 super(context); 247 mSystemPropertySetter = systemPropertySetter; 248 // We use the DisplayThread because this service indirectly drives 249 // display (on/off) and window (position) events through its callbacks. 250 DisplayThread displayThread = DisplayThread.get(); 251 mHandler = new Handler(displayThread.getLooper()); 252 mOverrideRequestController = new OverrideRequestController( 253 this::onOverrideRequestStatusChangedLocked); 254 mDeviceStatePolicy = policy; 255 mDeviceStateProviderListener = new DeviceStateProviderListener(); 256 mDeviceStatePolicy.getDeviceStateProvider().setListener(mDeviceStateProviderListener); 257 mBinderService = new BinderService(); 258 mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class); 259 mDeviceStateNotificationController = new DeviceStateNotificationController( 260 context, mHandler, 261 () -> { 262 synchronized (mLock) { 263 mActiveOverride.ifPresent(mOverrideRequestController::cancelRequest); 264 } 265 }); 266 } 267 268 @Override onStart()269 public void onStart() { 270 publishBinderService(Context.DEVICE_STATE_SERVICE, mBinderService); 271 publishLocalService(DeviceStateManagerInternal.class, new LocalService()); 272 273 synchronized (mLock) { 274 readStatesAvailableForRequestFromApps(); 275 mFoldedDeviceStates = readFoldedStates(); 276 } 277 278 mActivityTaskManagerInternal.registerScreenObserver(mOverrideRequestScreenObserver); 279 LocalServices.getService(ActivityManagerInternal.class).registerProcessObserver( 280 mProcessObserver); 281 } 282 283 @VisibleForTesting getHandler()284 Handler getHandler() { 285 return mHandler; 286 } 287 288 /** 289 * Returns the current state the system is in. Note that the system may be in the process of 290 * configuring a different state. 291 * <p> 292 * Note: This method will return {@link Optional#empty()} if called before the first state has 293 * been committed, otherwise it will return the last committed state. 294 * 295 * @see #getPendingState() 296 */ 297 @NonNull getCommittedState()298 Optional<DeviceState> getCommittedState() { 299 synchronized (mLock) { 300 return mCommittedState; 301 } 302 } 303 304 /** 305 * Returns the state the system is currently configuring, or {@link Optional#empty()} if the 306 * system is not in the process of configuring a state. 307 */ 308 @VisibleForTesting 309 @NonNull getPendingState()310 Optional<DeviceState> getPendingState() { 311 synchronized (mLock) { 312 return mPendingState; 313 } 314 } 315 316 /** 317 * Returns the base state. The service will configure the device to match the base state when 318 * there is no active request to override the base state. 319 * <p> 320 * Note: This method will return {@link Optional#empty()} if called before a base state is 321 * provided to the service by the {@link DeviceStateProvider}, otherwise it will return the 322 * most recent provided value. 323 * 324 * @see #getOverrideState() 325 */ 326 @NonNull getBaseState()327 Optional<DeviceState> getBaseState() { 328 synchronized (mLock) { 329 return mBaseState; 330 } 331 } 332 333 /** 334 * Returns the current override state, or {@link Optional#empty()} if no override state is 335 * requested. If an override states is present, the returned state will take precedence over 336 * the base state returned from {@link #getBaseState()}. 337 */ 338 @NonNull getOverrideState()339 Optional<DeviceState> getOverrideState() { 340 synchronized (mLock) { 341 if (mActiveOverride.isPresent()) { 342 return getStateLocked(mActiveOverride.get().getRequestedStateIdentifier()); 343 } 344 return Optional.empty(); 345 } 346 } 347 348 /** 349 * Returns the current override base state, or {@link Optional#empty()} if no override state is 350 * requested. If an override base state is present, the returned state will be the same as 351 * the base state returned from {@link #getBaseState()}. 352 */ 353 @NonNull getOverrideBaseState()354 Optional<DeviceState> getOverrideBaseState() { 355 synchronized (mLock) { 356 if (mActiveBaseStateOverride.isPresent()) { 357 return getStateLocked(mActiveBaseStateOverride.get().getRequestedStateIdentifier()); 358 } 359 return Optional.empty(); 360 } 361 } 362 363 /** Returns the list of currently supported device states. */ getSupportedStates()364 List<DeviceState> getSupportedStates() { 365 synchronized (mLock) { 366 return getSupportedStatesLocked(); 367 } 368 } 369 370 /** Returns the list of currently supported device states */ 371 @GuardedBy("mLock") getSupportedStatesLocked()372 private List<DeviceState> getSupportedStatesLocked() { 373 List<DeviceState> supportedStates = new ArrayList<>(mDeviceStates.size()); 374 for (int i = 0; i < mDeviceStates.size(); i++) { 375 supportedStates.add(i, mDeviceStates.valueAt(i)); 376 } 377 return supportedStates; 378 } 379 380 /** Returns the list of currently supported device state identifiers. */ getSupportedStateIdentifiersLocked()381 private int[] getSupportedStateIdentifiersLocked() { 382 int[] supportedStates = new int[mDeviceStates.size()]; 383 for (int i = 0; i < supportedStates.length; i++) { 384 supportedStates[i] = mDeviceStates.valueAt(i).getIdentifier(); 385 } 386 return supportedStates; 387 } 388 389 /** 390 * Returns the current {@link DeviceStateInfo} of the device. If there has been no base state 391 * or committed state provided, {@link #INVALID_DEVICE_STATE} will be returned 392 * respectively. The supported states will always be included. 393 * 394 */ 395 @GuardedBy("mLock") 396 @NonNull getDeviceStateInfoLocked()397 private DeviceStateInfo getDeviceStateInfoLocked() { 398 final List<DeviceState> supportedStates = getSupportedStatesLocked(); 399 final DeviceState baseState = mBaseState.orElse(INVALID_DEVICE_STATE); 400 final DeviceState currentState = mCommittedState.orElse(INVALID_DEVICE_STATE); 401 402 return new DeviceStateInfo(new ArrayList<>(supportedStates), baseState, 403 createMergedDeviceState(currentState, baseState)); 404 } 405 406 /** 407 * Returns a {@link DeviceState} with the combined properties of the current system state, as 408 * well as the physical property that corresponds to the base state (physical hardware state) of 409 * the device. 410 */ createMergedDeviceState(@ullable DeviceState committedState, @Nullable DeviceState baseState)411 private DeviceState createMergedDeviceState(@Nullable DeviceState committedState, 412 @Nullable DeviceState baseState) { 413 if (committedState.equals(INVALID_DEVICE_STATE)) { 414 return INVALID_DEVICE_STATE; 415 } 416 417 Set<@DeviceState.DeviceStateProperties Integer> systemProperties = 418 committedState.getConfiguration().getSystemProperties(); 419 420 Set<@DeviceState.DeviceStateProperties Integer> physicalProperties = 421 baseState.getConfiguration().getPhysicalProperties(); 422 423 DeviceState.Configuration deviceStateConfiguration = new DeviceState.Configuration.Builder( 424 committedState.getIdentifier(), committedState.getName()) 425 .setSystemProperties(systemProperties) 426 .setPhysicalProperties(physicalProperties) 427 .build(); 428 return new DeviceState(deviceStateConfiguration); 429 } 430 431 @VisibleForTesting getBinderService()432 IDeviceStateManager getBinderService() { 433 return mBinderService; 434 } 435 updateSupportedStates(DeviceState[] supportedDeviceStates, @DeviceStateProvider.SupportedStatesUpdatedReason int reason)436 private void updateSupportedStates(DeviceState[] supportedDeviceStates, 437 @DeviceStateProvider.SupportedStatesUpdatedReason int reason) { 438 synchronized (mLock) { 439 final int[] oldStateIdentifiers = getSupportedStateIdentifiersLocked(); 440 441 // Whether or not at least one device state has the flag FLAG_CANCEL_OVERRIDE_REQUESTS 442 // set. If set to true, the OverrideRequestController will be configured to allow sticky 443 // requests. 444 boolean hasTerminalDeviceState = false; 445 mDeviceStates.clear(); 446 for (int i = 0; i < supportedDeviceStates.length; i++) { 447 DeviceState state = supportedDeviceStates[i]; 448 if (state.hasProperty(PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS)) { 449 hasTerminalDeviceState = true; 450 } 451 mDeviceStates.put(state.getIdentifier(), state); 452 } 453 454 mOverrideRequestController.setStickyRequestsAllowed(hasTerminalDeviceState); 455 456 final int[] newStateIdentifiers = getSupportedStateIdentifiersLocked(); 457 if (Arrays.equals(oldStateIdentifiers, newStateIdentifiers)) { 458 return; 459 } 460 461 mOverrideRequestController.handleNewSupportedStates(newStateIdentifiers, reason); 462 updatePendingStateLocked(); 463 464 setRearDisplayStateLocked(); 465 466 notifyDeviceStateInfoChangedAsync(); 467 468 mHandler.post(this::notifyPolicyIfNeeded); 469 } 470 } 471 472 @GuardedBy("mLock") setRearDisplayStateLocked()473 private void setRearDisplayStateLocked() { 474 int rearDisplayIdentifier = getContext().getResources().getInteger( 475 R.integer.config_deviceStateRearDisplay); 476 if (rearDisplayIdentifier != INVALID_DEVICE_STATE_IDENTIFIER) { 477 mRearDisplayState = mDeviceStates.get(rearDisplayIdentifier); 478 } 479 } 480 481 /** 482 * Returns {@code true} if the provided state is supported. Requires that 483 * {@link #mDeviceStates} is sorted prior to calling. 484 */ isSupportedStateLocked(int identifier)485 private boolean isSupportedStateLocked(int identifier) { 486 return mDeviceStates.contains(identifier); 487 } 488 489 /** 490 * Returns the {@link DeviceState} with the supplied {@code identifier}, or {@code null} if 491 * there is no device state with the identifier. 492 */ 493 @NonNull getStateLocked(int identifier)494 private Optional<DeviceState> getStateLocked(int identifier) { 495 return Optional.ofNullable(mDeviceStates.get(identifier)); 496 } 497 498 /** 499 * Sets the base state. 500 * 501 * @throws IllegalArgumentException if the {@code identifier} is not a supported state. 502 * 503 * @see #isSupportedStateLocked(int) 504 */ setBaseState(int identifier)505 private void setBaseState(int identifier) { 506 synchronized (mLock) { 507 final Optional<DeviceState> baseStateOptional = getStateLocked(identifier); 508 if (baseStateOptional.isEmpty()) { 509 throw new IllegalArgumentException("Base state is not supported"); 510 } 511 512 final DeviceState baseState = baseStateOptional.get(); 513 514 if (mBaseState.isPresent() && mBaseState.get().equals(baseState)) { 515 // Base state hasn't changed. Nothing to do. 516 return; 517 } 518 // There is a pending rear display request, so we check if the overlay should be closed 519 if (mRearDisplayPendingOverrideRequest != null) { 520 handleRearDisplayBaseStateChangedLocked(identifier); 521 } 522 mBaseState = Optional.of(baseState); 523 524 if (baseState.hasProperty(PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS)) { 525 mOverrideRequestController.cancelOverrideRequest(); 526 } 527 mOverrideRequestController.handleBaseStateChanged(identifier); 528 updatePendingStateLocked(); 529 530 notifyDeviceStateInfoChangedAsync(); 531 532 mHandler.post(this::notifyPolicyIfNeeded); 533 } 534 } 535 536 /** 537 * Tries to update the current pending state with the current requested state. Must call 538 * {@link #notifyPolicyIfNeeded()} to actually notify the policy that the state is being 539 * changed. 540 * 541 * @return {@code true} if the pending state has changed as a result of this call, {@code false} 542 * otherwise. 543 */ 544 @GuardedBy("mLock") updatePendingStateLocked()545 private boolean updatePendingStateLocked() { 546 if (mPendingState.isPresent()) { 547 // Have pending state, can not configure a new state until the state is committed. 548 return false; 549 } 550 551 final DeviceState stateToConfigure; 552 if (mActiveOverride.isPresent()) { 553 stateToConfigure = getStateLocked( 554 mActiveOverride.get().getRequestedStateIdentifier()).get(); 555 } else if (mBaseState.isPresent() 556 && isSupportedStateLocked(mBaseState.get().getIdentifier())) { 557 // Base state could have recently become unsupported after a change in supported states. 558 stateToConfigure = mBaseState.get(); 559 } else { 560 stateToConfigure = null; 561 } 562 563 if (stateToConfigure == null) { 564 // No currently requested state. 565 return false; 566 } 567 568 if (mCommittedState.isPresent() && stateToConfigure.equals(mCommittedState.get())) { 569 // The state requesting to be committed already matches the current committed state. 570 return false; 571 } 572 573 mPendingState = Optional.of(stateToConfigure); 574 mIsPolicyWaitingForState = true; 575 return true; 576 } 577 578 /** 579 * Notifies the policy to configure the supplied state. Should not be called with {@link #mLock} 580 * held. 581 */ notifyPolicyIfNeeded()582 private void notifyPolicyIfNeeded() { 583 if (Thread.holdsLock(mLock)) { 584 Throwable error = new Throwable("Attempting to notify DeviceStatePolicy with service" 585 + " lock held"); 586 error.fillInStackTrace(); 587 Slog.w(TAG, error); 588 } 589 int state; 590 synchronized (mLock) { 591 if (!mIsPolicyWaitingForState) { 592 return; 593 } 594 mIsPolicyWaitingForState = false; 595 state = mPendingState.get().getIdentifier(); 596 } 597 598 if (DEBUG) { 599 Slog.d(TAG, "Notifying policy to configure state: " + state); 600 } 601 mDeviceStatePolicy.configureDeviceForState(state, this::commitPendingState); 602 } 603 604 /** 605 * Commits the current pending state after a callback from the {@link DeviceStatePolicy}. 606 * 607 * <pre> 608 * ------------- ----------- ------------- 609 * Provider -> | Requested | -> | Pending | -> Policy -> | Committed | 610 * ------------- ----------- ------------- 611 * </pre> 612 * <p> 613 * When a new state is requested it immediately enters the requested state. Once the policy is 614 * available to accept a new state, which could also be immediately if there is no current 615 * pending state at the point of request, the policy is notified and a callback is provided to 616 * trigger the state to be committed. 617 * </p> 618 */ commitPendingState()619 private void commitPendingState() { 620 synchronized (mLock) { 621 final DeviceState newState = mPendingState.get(); 622 if (DEBUG) { 623 Slog.d(TAG, "Committing state: " + newState); 624 } 625 626 FrameworkStatsLog.write(FrameworkStatsLog.DEVICE_STATE_CHANGED, 627 newState.getIdentifier(), !mCommittedState.isPresent()); 628 String traceString = newState.getIdentifier() + ":" + newState.getName(); 629 Trace.instantForTrack( 630 Trace.TRACE_TAG_SYSTEM_SERVER, "DeviceStateChanged", traceString); 631 mSystemPropertySetter.setDebugTracingDeviceStateProperty(traceString); 632 633 mCommittedState = Optional.of(newState); 634 mPendingState = Optional.empty(); 635 updatePendingStateLocked(); 636 637 // Notify callbacks of a change. 638 notifyDeviceStateInfoChangedAsync(); 639 640 // The top request could have come in while the service was awaiting callback 641 // from the policy. In that case we only set it to active if it matches the 642 // current committed state, otherwise it will be set to active when its 643 // requested state is committed. 644 OverrideRequest activeRequest = mActiveOverride.orElse(null); 645 if (activeRequest != null 646 && activeRequest.getRequestedStateIdentifier() == newState.getIdentifier()) { 647 ProcessRecord processRecord = mProcessRecords.get(activeRequest.getPid()); 648 if (processRecord != null) { 649 processRecord.notifyRequestActiveAsync(activeRequest.getToken()); 650 } 651 } 652 653 // Try to configure the next state if needed. 654 mHandler.post(this::notifyPolicyIfNeeded); 655 } 656 } 657 notifyDeviceStateInfoChangedAsync()658 private void notifyDeviceStateInfoChangedAsync() { 659 synchronized (mLock) { 660 if (mPendingState.isPresent()) { 661 Slog.i(TAG, 662 "Cannot notify device state info change when pending state is present."); 663 return; 664 } 665 666 if (!mBaseState.isPresent() || !mCommittedState.isPresent()) { 667 Slog.e(TAG, "Cannot notify device state info change before the initial state has" 668 + " been committed."); 669 return; 670 } 671 672 if (mProcessRecords.size() == 0) { 673 return; 674 } 675 676 ArrayList<ProcessRecord> registeredProcesses = new ArrayList<>(); 677 for (int i = 0; i < mProcessRecords.size(); i++) { 678 registeredProcesses.add(mProcessRecords.valueAt(i)); 679 } 680 681 DeviceStateInfo info = getDeviceStateInfoLocked(); 682 683 for (int i = 0; i < registeredProcesses.size(); i++) { 684 registeredProcesses.get(i).notifyDeviceStateInfoAsync(info); 685 } 686 } 687 } 688 689 @GuardedBy("mLock") onOverrideRequestStatusChangedLocked(@onNull OverrideRequest request, @OverrideRequestController.RequestStatus int status, @OverrideRequestController.StatusChangedFlag int flags)690 private void onOverrideRequestStatusChangedLocked(@NonNull OverrideRequest request, 691 @OverrideRequestController.RequestStatus int status, 692 @OverrideRequestController.StatusChangedFlag int flags) { 693 if (request.getRequestType() == OVERRIDE_REQUEST_TYPE_BASE_STATE) { 694 switch (status) { 695 case STATUS_ACTIVE: 696 enableBaseStateRequestLocked(request); 697 return; 698 case STATUS_CANCELED: 699 if (mActiveBaseStateOverride.isPresent() 700 && mActiveBaseStateOverride.get() == request) { 701 mActiveBaseStateOverride = Optional.empty(); 702 } 703 break; 704 case STATUS_UNKNOWN: // same as default 705 default: 706 throw new IllegalArgumentException("Unknown request status: " + status); 707 } 708 } else if (request.getRequestType() == OVERRIDE_REQUEST_TYPE_EMULATED_STATE) { 709 switch (status) { 710 case STATUS_ACTIVE: 711 mActiveOverride = Optional.of(request); 712 mDeviceStateNotificationController.showStateActiveNotificationIfNeeded( 713 request.getRequestedStateIdentifier(), request.getUid()); 714 break; 715 case STATUS_CANCELED: 716 if (mActiveOverride.isPresent() && mActiveOverride.get() == request) { 717 mActiveOverride = Optional.empty(); 718 mDeviceStateNotificationController.cancelNotification( 719 request.getRequestedStateIdentifier()); 720 if ((flags & FLAG_THERMAL_CRITICAL) == FLAG_THERMAL_CRITICAL) { 721 mDeviceStateNotificationController 722 .showThermalCriticalNotificationIfNeeded( 723 request.getRequestedStateIdentifier()); 724 } else if ((flags & FLAG_POWER_SAVE_ENABLED) == FLAG_POWER_SAVE_ENABLED) { 725 mDeviceStateNotificationController 726 .showPowerSaveNotificationIfNeeded( 727 request.getRequestedStateIdentifier()); 728 } 729 } 730 break; 731 case STATUS_UNKNOWN: // same as default 732 default: 733 throw new IllegalArgumentException("Unknown request status: " + status); 734 } 735 } else { 736 throw new IllegalArgumentException( 737 "Unknown OverrideRest type: " + request.getRequestType()); 738 } 739 740 boolean updatedPendingState = updatePendingStateLocked(); 741 742 ProcessRecord processRecord = mProcessRecords.get(request.getPid()); 743 if (processRecord == null) { 744 // If the process is no longer registered with the service, for example if it has died, 745 // there is no need to notify it of a change in request status. 746 mHandler.post(this::notifyPolicyIfNeeded); 747 return; 748 } 749 750 if (status == STATUS_ACTIVE) { 751 if (!updatedPendingState && !mPendingState.isPresent()) { 752 // If the pending state was not updated and there is not currently a pending state 753 // then this newly active request will never be notified of a change in state. 754 // Schedule the notification now. 755 processRecord.notifyRequestActiveAsync(request.getToken()); 756 } 757 } else { 758 processRecord.notifyRequestCanceledAsync(request.getToken()); 759 } 760 761 mHandler.post(this::notifyPolicyIfNeeded); 762 } 763 764 /** 765 * Sets the new base state of the device and notifies the process that made the base state 766 * override request that the request is now active. 767 */ 768 @GuardedBy("mLock") enableBaseStateRequestLocked(OverrideRequest request)769 private void enableBaseStateRequestLocked(OverrideRequest request) { 770 setBaseState(request.getRequestedStateIdentifier()); 771 mActiveBaseStateOverride = Optional.of(request); 772 ProcessRecord processRecord = mProcessRecords.get(request.getPid()); 773 processRecord.notifyRequestActiveAsync(request.getToken()); 774 } 775 registerProcess(int pid, IDeviceStateManagerCallback callback)776 private void registerProcess(int pid, IDeviceStateManagerCallback callback) { 777 synchronized (mLock) { 778 if (mProcessRecords.contains(pid)) { 779 throw new SecurityException("The calling process has already registered an" 780 + " IDeviceStateManagerCallback."); 781 } 782 783 ProcessRecord record = new ProcessRecord(callback, pid, this::handleProcessDied, 784 mHandler); 785 try { 786 callback.asBinder().linkToDeath(record, 0); 787 } catch (RemoteException ex) { 788 throw new RuntimeException(ex); 789 } 790 mProcessRecords.put(pid, record); 791 792 // Callback clients should not be notified of invalid device states, so calls to 793 // #getDeviceStateInfoLocked should be gated on checks if a committed state is present 794 // before getting the device state info. 795 DeviceStateInfo currentInfo = mCommittedState.isPresent() 796 ? getDeviceStateInfoLocked() : null; 797 if (currentInfo != null) { 798 // If there is not a committed state we'll wait to notify the process of the initial 799 // value. 800 record.notifyDeviceStateInfoAsync(currentInfo); 801 } 802 } 803 } 804 handleProcessDied(ProcessRecord processRecord)805 private void handleProcessDied(ProcessRecord processRecord) { 806 synchronized (mLock) { 807 mProcessRecords.remove(processRecord.mPid); 808 mOverrideRequestController.handleProcessDied(processRecord.mPid); 809 810 if (shouldCancelOverrideRequestWhenRequesterNotOnTop()) { 811 OverrideRequest request = mActiveOverride.get(); 812 mOverrideRequestController.cancelRequest(request); 813 } 814 } 815 } 816 requestStateInternal(int state, int flags, int callingPid, int callingUid, @NonNull IBinder token, boolean hasControlDeviceStatePermission)817 private void requestStateInternal(int state, int flags, int callingPid, int callingUid, 818 @NonNull IBinder token, boolean hasControlDeviceStatePermission) { 819 synchronized (mLock) { 820 final ProcessRecord processRecord = mProcessRecords.get(callingPid); 821 if (processRecord == null) { 822 throw new IllegalStateException("Process " + callingPid 823 + " has no registered callback."); 824 } 825 826 if (mOverrideRequestController.hasRequest(token, 827 OVERRIDE_REQUEST_TYPE_EMULATED_STATE)) { 828 throw new IllegalStateException("Request has already been made for the supplied" 829 + " token: " + token); 830 } 831 832 final Optional<DeviceState> deviceState = getStateLocked(state); 833 if (!deviceState.isPresent()) { 834 throw new IllegalArgumentException("Requested state: " + state 835 + " is not supported."); 836 } 837 838 OverrideRequest request = new OverrideRequest(token, callingPid, callingUid, 839 deviceState.get(), flags, OVERRIDE_REQUEST_TYPE_EMULATED_STATE); 840 841 // If we don't have the CONTROL_DEVICE_STATE permission, we want to show the overlay 842 if (!hasControlDeviceStatePermission && mRearDisplayState != null 843 && state == mRearDisplayState.getIdentifier()) { 844 showRearDisplayEducationalOverlayLocked(request); 845 } else { 846 mOverrideRequestController.addRequest(request); 847 } 848 } 849 } 850 851 /** 852 * If we get a request to enter rear display mode, we need to display an educational 853 * overlay to let the user know what will happen. This calls into the 854 * {@link StatusBarManagerInternal} to notify SystemUI to display the educational dialog. 855 */ 856 @GuardedBy("mLock") showRearDisplayEducationalOverlayLocked(@onNull OverrideRequest request)857 private void showRearDisplayEducationalOverlayLocked(@NonNull OverrideRequest request) { 858 mRearDisplayPendingOverrideRequest = request; 859 860 StatusBarManagerInternal statusBar = 861 LocalServices.getService(StatusBarManagerInternal.class); 862 if (statusBar != null) { 863 statusBar.showRearDisplayDialog(mBaseState.get().getIdentifier()); 864 } 865 } 866 cancelStateRequestInternal(int callingPid)867 private void cancelStateRequestInternal(int callingPid) { 868 synchronized (mLock) { 869 final ProcessRecord processRecord = mProcessRecords.get(callingPid); 870 if (processRecord == null) { 871 throw new IllegalStateException("Process " + callingPid 872 + " has no registered callback."); 873 } 874 mActiveOverride.ifPresent(mOverrideRequestController::cancelRequest); 875 } 876 } 877 requestBaseStateOverrideInternal(int state, int flags, int callingPid, int callingUid, @NonNull IBinder token)878 private void requestBaseStateOverrideInternal(int state, int flags, int callingPid, 879 int callingUid, @NonNull IBinder token) { 880 synchronized (mLock) { 881 final Optional<DeviceState> deviceState = getStateLocked(state); 882 if (!deviceState.isPresent()) { 883 throw new IllegalArgumentException("Requested state: " + state 884 + " is not supported."); 885 } 886 887 final ProcessRecord processRecord = mProcessRecords.get(callingPid); 888 if (processRecord == null) { 889 throw new IllegalStateException("Process " + callingPid 890 + " has no registered callback."); 891 } 892 893 if (mOverrideRequestController.hasRequest(token, 894 OVERRIDE_REQUEST_TYPE_BASE_STATE)) { 895 throw new IllegalStateException("Request has already been made for the supplied" 896 + " token: " + token); 897 } 898 899 OverrideRequest request = new OverrideRequest(token, callingPid, callingUid, 900 deviceState.get(), flags, OVERRIDE_REQUEST_TYPE_BASE_STATE); 901 mOverrideRequestController.addBaseStateRequest(request); 902 } 903 } 904 cancelBaseStateOverrideInternal(int callingPid)905 private void cancelBaseStateOverrideInternal(int callingPid) { 906 synchronized (mLock) { 907 final ProcessRecord processRecord = mProcessRecords.get(callingPid); 908 if (processRecord == null) { 909 throw new IllegalStateException("Process " + callingPid 910 + " has no registered callback."); 911 } 912 setBaseState(mDeviceStateProviderListener.mCurrentBaseState); 913 } 914 } 915 916 /** 917 * Adds the rear display state request to the {@link OverrideRequestController} if the 918 * educational overlay was closed in a way that should enable the feature, and cancels the 919 * request if it was dismissed in a way that should cancel the feature. 920 */ onStateRequestOverlayDismissedInternal(boolean shouldCancelRequest)921 private void onStateRequestOverlayDismissedInternal(boolean shouldCancelRequest) { 922 synchronized (mLock) { 923 if (mRearDisplayPendingOverrideRequest != null) { 924 if (shouldCancelRequest) { 925 ProcessRecord processRecord = mProcessRecords.get( 926 mRearDisplayPendingOverrideRequest.getPid()); 927 processRecord.notifyRequestCanceledAsync( 928 mRearDisplayPendingOverrideRequest.getToken()); 929 } else { 930 mOverrideRequestController.addRequest(mRearDisplayPendingOverrideRequest); 931 } 932 mRearDisplayPendingOverrideRequest = null; 933 } 934 } 935 } 936 dumpInternal(PrintWriter pw)937 private void dumpInternal(PrintWriter pw) { 938 pw.println("DEVICE STATE MANAGER (dumpsys device_state)"); 939 940 synchronized (mLock) { 941 pw.println(" mCommittedState=" + mCommittedState); 942 pw.println(" mPendingState=" + mPendingState); 943 pw.println(" mBaseState=" + mBaseState); 944 pw.println(" mOverrideState=" + getOverrideState()); 945 946 final int processCount = mProcessRecords.size(); 947 pw.println(); 948 pw.println("Registered processes: size=" + processCount); 949 for (int i = 0; i < processCount; i++) { 950 ProcessRecord processRecord = mProcessRecords.valueAt(i); 951 pw.println(" " + i + ": mPid=" + processRecord.mPid); 952 } 953 954 mOverrideRequestController.dumpInternal(pw); 955 pw.println(); 956 957 mDeviceStatePolicy.dump(pw, /* args= */ null); 958 } 959 } 960 961 /** 962 * Allow top processes to request or cancel a device state change. If the calling process ID is 963 * not the top app, then check if this process holds the 964 * {@link android.Manifest.permission.CONTROL_DEVICE_STATE} permission. If the calling process 965 * is the top app, check to verify they are requesting a state we've deemed to be able to be 966 * available for an app process to request. States that can be requested are based around 967 * features that we've created that require specific device state overrides. 968 * @param callingPid Process ID that is requesting this state change 969 * @param state state that is being requested. 970 */ assertCanRequestDeviceState(int callingPid, int callingUid, int state)971 private void assertCanRequestDeviceState(int callingPid, int callingUid, int state) { 972 final boolean isTopApp = isTopApp(callingPid); 973 final boolean isForegroundApp = isForegroundApp(callingPid, callingUid); 974 final boolean isStateAvailableForAppRequests = isStateAvailableForAppRequests(state); 975 976 final boolean canRequestState = isTopApp 977 && isForegroundApp 978 && isStateAvailableForAppRequests; 979 980 if (!canRequestState) { 981 getContext().enforceCallingOrSelfPermission(CONTROL_DEVICE_STATE, 982 "Permission required to request device state, " 983 + "or the call must come from the top app " 984 + "and be a device state that is available for apps to request."); 985 } 986 } 987 988 /** 989 * Checks if the process can control the device state. If the calling process ID is 990 * not the top app, then check if this process holds the CONTROL_DEVICE_STATE permission. 991 * 992 * @param callingPid Process ID that is requesting this state change 993 * @param callingUid UID that is requesting this state change 994 */ assertCanControlDeviceState(int callingPid, int callingUid)995 private void assertCanControlDeviceState(int callingPid, int callingUid) { 996 final boolean isTopApp = isTopApp(callingPid); 997 final boolean isForegroundApp = isForegroundApp(callingPid, callingUid); 998 999 final boolean canControlState = isTopApp && isForegroundApp; 1000 1001 if (!canControlState) { 1002 getContext().enforceCallingOrSelfPermission(CONTROL_DEVICE_STATE, 1003 "Permission required to request device state, " 1004 + "or the call must come from the top app."); 1005 } 1006 } 1007 1008 /** 1009 * Checks if the caller is in the foreground. Note that callers may be the top app as returned 1010 * from {@link #isTopApp(int)}, but not be in the foreground. For example, keyguard may be on 1011 * top of the top app. 1012 */ isForegroundApp(int callingPid, int callingUid)1013 private boolean isForegroundApp(int callingPid, int callingUid) { 1014 try { 1015 final List<ActivityManager.RunningAppProcessInfo> procs = 1016 ActivityManager.getService().getRunningAppProcesses(); 1017 for (int i = 0; i < procs.size(); i++) { 1018 ActivityManager.RunningAppProcessInfo proc = procs.get(i); 1019 if (proc.pid == callingPid && proc.uid == callingUid 1020 && proc.importance <= IMPORTANCE_FOREGROUND) { 1021 return true; 1022 } 1023 } 1024 } catch (RemoteException e) { 1025 Slog.w(TAG, "am.getRunningAppProcesses() failed", e); 1026 } 1027 return false; 1028 } 1029 isTopApp(int callingPid)1030 private boolean isTopApp(int callingPid) { 1031 final WindowProcessController topApp = mActivityTaskManagerInternal.getTopApp(); 1032 return topApp != null && topApp.getPid() == callingPid; 1033 } 1034 isStateAvailableForAppRequests(int state)1035 private boolean isStateAvailableForAppRequests(int state) { 1036 synchronized (mLock) { 1037 return mDeviceStatesAvailableForAppRequests.contains(state); 1038 } 1039 } 1040 1041 /** 1042 * Adds device state values that are available to be requested by the top level app. 1043 */ 1044 @GuardedBy("mLock") readStatesAvailableForRequestFromApps()1045 private void readStatesAvailableForRequestFromApps() { 1046 String[] availableAppStatesConfigIdentifiers = getContext().getResources() 1047 .getStringArray(R.array.config_deviceStatesAvailableForAppRequests); 1048 for (int i = 0; i < availableAppStatesConfigIdentifiers.length; i++) { 1049 String identifierToFetch = availableAppStatesConfigIdentifiers[i]; 1050 int configValueIdentifier = getContext().getResources() 1051 .getIdentifier(identifierToFetch, "integer", "android"); 1052 int state = getContext().getResources().getInteger(configValueIdentifier); 1053 if (isValidState(state)) { 1054 mDeviceStatesAvailableForAppRequests.add(state); 1055 } else { 1056 Slog.e(TAG, "Invalid device state was found in the configuration file. State id: " 1057 + state); 1058 } 1059 } 1060 } 1061 readFoldedStates()1062 private Set<Integer> readFoldedStates() { 1063 Set<Integer> foldedStates = new HashSet<>(); 1064 int[] mFoldedStatesArray = getContext().getResources().getIntArray( 1065 com.android.internal.R.array.config_foldedDeviceStates); 1066 for (int i = 0; i < mFoldedStatesArray.length; i++) { 1067 foldedStates.add(mFoldedStatesArray[i]); 1068 } 1069 return foldedStates; 1070 } 1071 1072 @GuardedBy("mLock") isValidState(int state)1073 private boolean isValidState(int state) { 1074 for (int i = 0; i < mDeviceStates.size(); i++) { 1075 if (state == mDeviceStates.valueAt(i).getIdentifier()) { 1076 return true; 1077 } 1078 } 1079 return false; 1080 } 1081 1082 /** 1083 * If the device is being opened, in response to the rear display educational overlay, we should 1084 * dismiss the overlay and enter the mode. 1085 */ 1086 @GuardedBy("mLock") handleRearDisplayBaseStateChangedLocked(int newBaseState)1087 private void handleRearDisplayBaseStateChangedLocked(int newBaseState) { 1088 if (isDeviceOpeningLocked(newBaseState)) { 1089 onStateRequestOverlayDismissedInternal(false); 1090 } 1091 } 1092 1093 /** 1094 * Determines if the device is being opened and if we are going from a folded state to a 1095 * non-folded state. 1096 */ 1097 @GuardedBy("mLock") isDeviceOpeningLocked(int newBaseState)1098 private boolean isDeviceOpeningLocked(int newBaseState) { 1099 return mBaseState.filter( 1100 deviceState -> mFoldedDeviceStates.contains(deviceState.getIdentifier()) 1101 && !mFoldedDeviceStates.contains(newBaseState)).isPresent(); 1102 } 1103 1104 private final class DeviceStateProviderListener implements DeviceStateProvider.Listener { 1105 @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = MAXIMUM_DEVICE_STATE_IDENTIFIER) 1106 int mCurrentBaseState; 1107 1108 @Override onSupportedDeviceStatesChanged(DeviceState[] newDeviceStates, @DeviceStateProvider.SupportedStatesUpdatedReason int reason)1109 public void onSupportedDeviceStatesChanged(DeviceState[] newDeviceStates, 1110 @DeviceStateProvider.SupportedStatesUpdatedReason int reason) { 1111 if (newDeviceStates.length == 0) { 1112 throw new IllegalArgumentException("Supported device states must not be empty"); 1113 } 1114 updateSupportedStates(newDeviceStates, reason); 1115 } 1116 1117 @Override onStateChanged( @ntRangefrom = MINIMUM_DEVICE_STATE_IDENTIFIER, to = MAXIMUM_DEVICE_STATE_IDENTIFIER) int identifier)1118 public void onStateChanged( 1119 @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = 1120 MAXIMUM_DEVICE_STATE_IDENTIFIER) int identifier) { 1121 if (identifier < MINIMUM_DEVICE_STATE_IDENTIFIER 1122 || identifier > MAXIMUM_DEVICE_STATE_IDENTIFIER) { 1123 throw new IllegalArgumentException("Invalid identifier: " + identifier); 1124 } 1125 1126 mCurrentBaseState = identifier; 1127 setBaseState(identifier); 1128 } 1129 } 1130 1131 private static final class ProcessRecord implements IBinder.DeathRecipient { 1132 public interface DeathListener { onProcessDied(ProcessRecord record)1133 void onProcessDied(ProcessRecord record); 1134 } 1135 1136 private static final int STATUS_ACTIVE = 0; 1137 1138 private static final int STATUS_SUSPENDED = 1; 1139 1140 private static final int STATUS_CANCELED = 2; 1141 1142 @IntDef(prefix = {"STATUS_"}, value = { 1143 STATUS_ACTIVE, 1144 STATUS_SUSPENDED, 1145 STATUS_CANCELED 1146 }) 1147 @Retention(RetentionPolicy.SOURCE) 1148 private @interface RequestStatus {} 1149 1150 private final IDeviceStateManagerCallback mCallback; 1151 private final int mPid; 1152 private final DeathListener mDeathListener; 1153 private final Handler mHandler; 1154 1155 private final WeakHashMap<IBinder, Integer> mLastNotifiedStatus = new WeakHashMap<>(); 1156 ProcessRecord(IDeviceStateManagerCallback callback, int pid, DeathListener deathListener, Handler handler)1157 ProcessRecord(IDeviceStateManagerCallback callback, int pid, DeathListener deathListener, 1158 Handler handler) { 1159 mCallback = callback; 1160 mPid = pid; 1161 mDeathListener = deathListener; 1162 mHandler = handler; 1163 } 1164 1165 @Override binderDied()1166 public void binderDied() { 1167 mDeathListener.onProcessDied(this); 1168 } 1169 notifyDeviceStateInfoAsync(@onNull DeviceStateInfo info)1170 public void notifyDeviceStateInfoAsync(@NonNull DeviceStateInfo info) { 1171 mHandler.post(() -> { 1172 boolean tracingEnabled = Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER); 1173 if (tracingEnabled) { // To avoid creating the string when not needed. 1174 Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, 1175 "notifyDeviceStateInfoAsync(pid=" + mPid + ")"); 1176 } 1177 try { 1178 mCallback.onDeviceStateInfoChanged(info); 1179 } catch (RemoteException ex) { 1180 Slog.w(TAG, "Failed to notify process " + mPid + " that device state changed.", 1181 ex); 1182 } 1183 finally { 1184 if (tracingEnabled) { 1185 Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); 1186 } 1187 } 1188 }); 1189 } 1190 notifyRequestActiveAsync(IBinder token)1191 public void notifyRequestActiveAsync(IBinder token) { 1192 @RequestStatus Integer lastStatus = mLastNotifiedStatus.get(token); 1193 if (lastStatus != null 1194 && (lastStatus == STATUS_ACTIVE || lastStatus == STATUS_CANCELED)) { 1195 return; 1196 } 1197 1198 mLastNotifiedStatus.put(token, STATUS_ACTIVE); 1199 mHandler.post(() -> { 1200 try { 1201 mCallback.onRequestActive(token); 1202 } catch (RemoteException ex) { 1203 Slog.w(TAG, "Failed to notify process " + mPid + " that request state changed.", 1204 ex); 1205 } 1206 }); 1207 } 1208 notifyRequestCanceledAsync(IBinder token)1209 public void notifyRequestCanceledAsync(IBinder token) { 1210 @RequestStatus Integer lastStatus = mLastNotifiedStatus.get(token); 1211 if (lastStatus != null && lastStatus == STATUS_CANCELED) { 1212 return; 1213 } 1214 1215 mLastNotifiedStatus.put(token, STATUS_CANCELED); 1216 mHandler.post(() -> { 1217 try { 1218 mCallback.onRequestCanceled(token); 1219 } catch (RemoteException ex) { 1220 Slog.w(TAG, "Failed to notify process " + mPid + " that request state changed.", 1221 ex); 1222 } 1223 }); 1224 } 1225 } 1226 1227 /** Implementation of {@link IDeviceStateManager} published as a binder service. */ 1228 private final class BinderService extends IDeviceStateManager.Stub { 1229 1230 @Override // Binder call getDeviceStateInfo()1231 public DeviceStateInfo getDeviceStateInfo() { 1232 synchronized (mLock) { 1233 return getDeviceStateInfoLocked(); 1234 } 1235 } 1236 1237 @Override // Binder call registerCallback(IDeviceStateManagerCallback callback)1238 public void registerCallback(IDeviceStateManagerCallback callback) { 1239 if (callback == null) { 1240 throw new IllegalArgumentException("Device state callback must not be null."); 1241 } 1242 1243 final int callingPid = Binder.getCallingPid(); 1244 final long token = Binder.clearCallingIdentity(); 1245 try { 1246 registerProcess(callingPid, callback); 1247 } finally { 1248 Binder.restoreCallingIdentity(token); 1249 } 1250 } 1251 1252 @Override // Binder call requestState(IBinder token, int state, int flags)1253 public void requestState(IBinder token, int state, int flags) { 1254 final int callingPid = Binder.getCallingPid(); 1255 final int callingUid = Binder.getCallingUid(); 1256 // Allow top processes to request a device state change 1257 // If the calling process ID is not the top app, then we check if this process 1258 // holds a permission to CONTROL_DEVICE_STATE 1259 assertCanRequestDeviceState(callingPid, callingUid, state); 1260 1261 if (token == null) { 1262 throw new IllegalArgumentException("Request token must not be null."); 1263 } 1264 1265 boolean hasControlStatePermission = getContext().checkCallingOrSelfPermission( 1266 CONTROL_DEVICE_STATE) == PERMISSION_GRANTED; 1267 1268 final long callingIdentity = Binder.clearCallingIdentity(); 1269 try { 1270 requestStateInternal(state, flags, callingPid, callingUid, token, 1271 hasControlStatePermission); 1272 } finally { 1273 Binder.restoreCallingIdentity(callingIdentity); 1274 } 1275 } 1276 1277 @Override // Binder call cancelStateRequest()1278 public void cancelStateRequest() { 1279 final int callingPid = Binder.getCallingPid(); 1280 final int callingUid = Binder.getCallingUid(); 1281 // Allow top processes to cancel a device state change 1282 // If the calling process ID is not the top app, then we check if this process 1283 // holds a permission to CONTROL_DEVICE_STATE 1284 assertCanControlDeviceState(callingPid, callingUid); 1285 1286 final long callingIdentity = Binder.clearCallingIdentity(); 1287 try { 1288 cancelStateRequestInternal(callingPid); 1289 } finally { 1290 Binder.restoreCallingIdentity(callingIdentity); 1291 } 1292 } 1293 1294 @Override // Binder call requestBaseStateOverride(IBinder token, int state, int flags)1295 public void requestBaseStateOverride(IBinder token, int state, int flags) { 1296 final int callingPid = Binder.getCallingPid(); 1297 final int callingUid = Binder.getCallingUid(); 1298 getContext().enforceCallingOrSelfPermission(CONTROL_DEVICE_STATE, 1299 "Permission required to control base state of device."); 1300 1301 if (token == null) { 1302 throw new IllegalArgumentException("Request token must not be null."); 1303 } 1304 1305 final long callingIdentity = Binder.clearCallingIdentity(); 1306 try { 1307 requestBaseStateOverrideInternal(state, flags, callingPid, callingUid, token); 1308 } finally { 1309 Binder.restoreCallingIdentity(callingIdentity); 1310 } 1311 } 1312 1313 @Override // Binder call cancelBaseStateOverride()1314 public void cancelBaseStateOverride() { 1315 final int callingPid = Binder.getCallingPid(); 1316 getContext().enforceCallingOrSelfPermission(CONTROL_DEVICE_STATE, 1317 "Permission required to control base state of device."); 1318 1319 final long callingIdentity = Binder.clearCallingIdentity(); 1320 try { 1321 cancelBaseStateOverrideInternal(callingPid); 1322 } finally { 1323 Binder.restoreCallingIdentity(callingIdentity); 1324 } 1325 } 1326 1327 @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DEVICE_STATE) 1328 @Override // Binder call onStateRequestOverlayDismissed(boolean shouldCancelRequest)1329 public void onStateRequestOverlayDismissed(boolean shouldCancelRequest) { 1330 1331 onStateRequestOverlayDismissed_enforcePermission(); 1332 1333 final long callingIdentity = Binder.clearCallingIdentity(); 1334 try { 1335 onStateRequestOverlayDismissedInternal(shouldCancelRequest); 1336 } finally { 1337 Binder.restoreCallingIdentity(callingIdentity); 1338 } 1339 } 1340 1341 @Override // Binder call onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver result)1342 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, 1343 String[] args, ShellCallback callback, ResultReceiver result) { 1344 new DeviceStateManagerShellCommand(DeviceStateManagerService.this) 1345 .exec(this, in, out, err, args, callback, result); 1346 } 1347 1348 @Override // Binder call dump(FileDescriptor fd, final PrintWriter pw, String[] args)1349 public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) { 1350 if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return; 1351 1352 final long token = Binder.clearCallingIdentity(); 1353 try { 1354 dumpInternal(pw); 1355 } finally { 1356 Binder.restoreCallingIdentity(token); 1357 } 1358 } 1359 } 1360 1361 /** Implementation of {@link DeviceStateManagerInternal} published as a local service. */ 1362 private final class LocalService extends DeviceStateManagerInternal { 1363 @Override getSupportedStateIdentifiers()1364 public int[] getSupportedStateIdentifiers() { 1365 synchronized (mLock) { 1366 return getSupportedStateIdentifiersLocked(); 1367 } 1368 } 1369 } 1370 1371 @GuardedBy("mLock") shouldCancelOverrideRequestWhenRequesterNotOnTop()1372 private boolean shouldCancelOverrideRequestWhenRequesterNotOnTop() { 1373 if (mActiveOverride.isEmpty()) { 1374 return false; 1375 } 1376 int identifier = mActiveOverride.get().getRequestedStateIdentifier(); 1377 DeviceState deviceState = mDeviceStates.get(identifier); 1378 return deviceState.hasProperty(PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP); 1379 } 1380 1381 private class OverrideRequestScreenObserver implements 1382 ActivityTaskManagerInternal.ScreenObserver { 1383 1384 @Override onAwakeStateChanged(boolean isAwake)1385 public void onAwakeStateChanged(boolean isAwake) { 1386 synchronized (mLock) { 1387 if (!isAwake && shouldCancelOverrideRequestWhenRequesterNotOnTop()) { 1388 mOverrideRequestController.cancelRequest(mActiveOverride.get()); 1389 } 1390 } 1391 } 1392 1393 @Override onKeyguardStateChanged(boolean isShowing)1394 public void onKeyguardStateChanged(boolean isShowing) { 1395 synchronized (mLock) { 1396 if (isShowing && shouldCancelOverrideRequestWhenRequesterNotOnTop()) { 1397 mOverrideRequestController.cancelRequest(mActiveOverride.get()); 1398 } 1399 } 1400 } 1401 } 1402 } 1403