1 /* 2 * Copyright (C) 2012 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.display; 18 19 import static android.Manifest.permission.ADD_TRUSTED_DISPLAY; 20 import static android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT; 21 import static android.Manifest.permission.CAPTURE_VIDEO_OUTPUT; 22 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; 23 import static android.hardware.display.DisplayManager.EventsMask; 24 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; 25 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD; 26 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY; 27 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP; 28 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; 29 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE; 30 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; 31 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED; 32 import static android.hardware.display.DisplayManagerGlobal.DisplayEvent; 33 import static android.hardware.display.DisplayViewport.VIEWPORT_EXTERNAL; 34 import static android.hardware.display.DisplayViewport.VIEWPORT_INTERNAL; 35 import static android.hardware.display.DisplayViewport.VIEWPORT_VIRTUAL; 36 37 import android.Manifest; 38 import android.annotation.NonNull; 39 import android.annotation.Nullable; 40 import android.annotation.UserIdInt; 41 import android.app.AppOpsManager; 42 import android.app.compat.CompatChanges; 43 import android.compat.annotation.ChangeId; 44 import android.compat.annotation.EnabledSince; 45 import android.content.Context; 46 import android.content.pm.PackageManager; 47 import android.content.pm.ParceledListSlice; 48 import android.content.res.Resources; 49 import android.content.res.TypedArray; 50 import android.database.ContentObserver; 51 import android.graphics.ColorSpace; 52 import android.graphics.Point; 53 import android.hardware.Sensor; 54 import android.hardware.SensorManager; 55 import android.hardware.devicestate.DeviceStateManager; 56 import android.hardware.display.AmbientBrightnessDayStats; 57 import android.hardware.display.BrightnessChangeEvent; 58 import android.hardware.display.BrightnessConfiguration; 59 import android.hardware.display.BrightnessInfo; 60 import android.hardware.display.Curve; 61 import android.hardware.display.DisplayManager; 62 import android.hardware.display.DisplayManagerGlobal; 63 import android.hardware.display.DisplayManagerInternal; 64 import android.hardware.display.DisplayManagerInternal.DisplayGroupListener; 65 import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener; 66 import android.hardware.display.DisplayManagerInternal.RefreshRateLimitation; 67 import android.hardware.display.DisplayManagerInternal.RefreshRateRange; 68 import android.hardware.display.DisplayViewport; 69 import android.hardware.display.DisplayedContentSample; 70 import android.hardware.display.DisplayedContentSamplingAttributes; 71 import android.hardware.display.IDisplayManager; 72 import android.hardware.display.IDisplayManagerCallback; 73 import android.hardware.display.IVirtualDisplayCallback; 74 import android.hardware.display.VirtualDisplayConfig; 75 import android.hardware.display.WifiDisplayStatus; 76 import android.hardware.input.InputManagerInternal; 77 import android.media.projection.IMediaProjection; 78 import android.media.projection.IMediaProjectionManager; 79 import android.net.Uri; 80 import android.os.Binder; 81 import android.os.Handler; 82 import android.os.HandlerExecutor; 83 import android.os.IBinder; 84 import android.os.IBinder.DeathRecipient; 85 import android.os.Looper; 86 import android.os.Message; 87 import android.os.PowerManager; 88 import android.os.Process; 89 import android.os.RemoteException; 90 import android.os.ResultReceiver; 91 import android.os.ServiceManager; 92 import android.os.ShellCallback; 93 import android.os.SystemClock; 94 import android.os.SystemProperties; 95 import android.os.Trace; 96 import android.os.UserHandle; 97 import android.os.UserManager; 98 import android.provider.Settings; 99 import android.sysprop.DisplayProperties; 100 import android.text.TextUtils; 101 import android.util.ArraySet; 102 import android.util.EventLog; 103 import android.util.IntArray; 104 import android.util.Pair; 105 import android.util.Slog; 106 import android.util.SparseArray; 107 import android.util.SparseIntArray; 108 import android.util.Spline; 109 import android.view.Display; 110 import android.view.DisplayEventReceiver; 111 import android.view.DisplayInfo; 112 import android.view.Surface; 113 import android.view.SurfaceControl; 114 115 import com.android.internal.annotations.GuardedBy; 116 import com.android.internal.annotations.VisibleForTesting; 117 import com.android.internal.display.BrightnessSynchronizer; 118 import com.android.internal.util.DumpUtils; 119 import com.android.internal.util.IndentingPrintWriter; 120 import com.android.server.AnimationThread; 121 import com.android.server.DisplayThread; 122 import com.android.server.LocalServices; 123 import com.android.server.SystemService; 124 import com.android.server.UiThread; 125 import com.android.server.display.DisplayDeviceConfig.SensorData; 126 import com.android.server.display.utils.SensorUtils; 127 import com.android.server.wm.SurfaceAnimationThread; 128 import com.android.server.wm.WindowManagerInternal; 129 130 import java.io.FileDescriptor; 131 import java.io.PrintWriter; 132 import java.util.ArrayList; 133 import java.util.Arrays; 134 import java.util.List; 135 import java.util.Optional; 136 import java.util.concurrent.CopyOnWriteArrayList; 137 import java.util.concurrent.atomic.AtomicLong; 138 import java.util.function.Consumer; 139 140 /** 141 * Manages attached displays. 142 * <p> 143 * The {@link DisplayManagerService} manages the global lifecycle of displays, 144 * decides how to configure logical displays based on the physical display devices currently 145 * attached, sends notifications to the system and to applications when the state 146 * changes, and so on. 147 * </p><p> 148 * The display manager service relies on a collection of {@link DisplayAdapter} components, 149 * for discovering and configuring physical display devices attached to the system. 150 * There are separate display adapters for each manner that devices are attached: 151 * one display adapter for physical displays, one for simulated non-functional 152 * displays when the system is headless, one for simulated overlay displays used for 153 * development, one for wifi displays, etc. 154 * </p><p> 155 * Display adapters are only weakly coupled to the display manager service. 156 * Display adapters communicate changes in display device state to the display manager 157 * service asynchronously via a {@link DisplayAdapter.Listener}, and through 158 * the {@link DisplayDeviceRepository.Listener}, which is ultimately registered 159 * by the display manager service. This separation of concerns is important for 160 * two main reasons. First, it neatly encapsulates the responsibilities of these 161 * two classes: display adapters handle individual display devices whereas 162 * the display manager service handles the global state. Second, it eliminates 163 * the potential for deadlocks resulting from asynchronous display device discovery. 164 * </p> 165 * 166 * <h3>Synchronization</h3> 167 * <p> 168 * Because the display manager may be accessed by multiple threads, the synchronization 169 * story gets a little complicated. In particular, the window manager may call into 170 * the display manager while holding a surface transaction with the expectation that 171 * it can apply changes immediately. Unfortunately, that means we can't just do 172 * everything asynchronously (*grump*). 173 * </p><p> 174 * To make this work, all of the objects that belong to the display manager must 175 * use the same lock. We call this lock the synchronization root and it has a unique 176 * type {@link DisplayManagerService.SyncRoot}. Methods that require this lock are 177 * named with the "Locked" suffix. 178 * </p><p> 179 * Where things get tricky is that the display manager is not allowed to make 180 * any potentially reentrant calls, especially into the window manager. We generally 181 * avoid this by making all potentially reentrant out-calls asynchronous. 182 * </p> 183 */ 184 public final class DisplayManagerService extends SystemService { 185 private static final String TAG = "DisplayManagerService"; 186 private static final boolean DEBUG = false; 187 188 // When this system property is set to 0, WFD is forcibly disabled on boot. 189 // When this system property is set to 1, WFD is forcibly enabled on boot. 190 // Otherwise WFD is enabled according to the value of config_enableWifiDisplay. 191 private static final String FORCE_WIFI_DISPLAY_ENABLE = "persist.debug.wfd.enable"; 192 193 private static final String PROP_DEFAULT_DISPLAY_TOP_INSET = "persist.sys.displayinset.top"; 194 private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000; 195 private static final float THRESHOLD_FOR_REFRESH_RATES_DIVIDERS = 0.1f; 196 197 private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1; 198 private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2; 199 private static final int MSG_DELIVER_DISPLAY_EVENT = 3; 200 private static final int MSG_REQUEST_TRAVERSAL = 4; 201 private static final int MSG_UPDATE_VIEWPORT = 5; 202 private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATION = 6; 203 private static final int MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE = 7; 204 private static final int MSG_DELIVER_DISPLAY_GROUP_EVENT = 8; 205 206 private final Context mContext; 207 private final DisplayManagerHandler mHandler; 208 private final Handler mUiHandler; 209 private final DisplayModeDirector mDisplayModeDirector; 210 private WindowManagerInternal mWindowManagerInternal; 211 private InputManagerInternal mInputManagerInternal; 212 private IMediaProjectionManager mProjectionService; 213 private int[] mUserDisabledHdrTypes = {}; 214 private boolean mAreUserDisabledHdrTypesAllowed = true; 215 216 // The synchronization root for the display manager. 217 // This lock guards most of the display manager's state. 218 // NOTE: This is synchronized on while holding WindowManagerService.mWindowMap so never call 219 // into WindowManagerService methods that require mWindowMap while holding this unless you are 220 // very very sure that no deadlock can occur. 221 private final SyncRoot mSyncRoot = new SyncRoot(); 222 223 // True if in safe mode. 224 // This option may disable certain display adapters. 225 public boolean mSafeMode; 226 227 // True if we are in a special boot mode where only core applications and 228 // services should be started. This option may disable certain display adapters. 229 public boolean mOnlyCore; 230 231 // All callback records indexed by calling process id. 232 public final SparseArray<CallbackRecord> mCallbacks = 233 new SparseArray<CallbackRecord>(); 234 235 // List of all currently registered display adapters. 236 private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>(); 237 238 /** 239 * Repository of all active {@link DisplayDevice}s. 240 */ 241 private final DisplayDeviceRepository mDisplayDeviceRepo; 242 243 /** 244 * Contains all the {@link LogicalDisplay} instances and is responsible for mapping 245 * {@link DisplayDevice}s to {@link LogicalDisplay}s. DisplayManagerService listens to display 246 * event on this object. 247 */ 248 private final LogicalDisplayMapper mLogicalDisplayMapper; 249 250 // List of all display transaction listeners. 251 private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners = 252 new CopyOnWriteArrayList<DisplayTransactionListener>(); 253 254 /** List of all display group listeners. */ 255 private final CopyOnWriteArrayList<DisplayGroupListener> mDisplayGroupListeners = 256 new CopyOnWriteArrayList<>(); 257 258 /** All {@link DisplayPowerController}s indexed by {@link LogicalDisplay} ID. */ 259 private final SparseArray<DisplayPowerController> mDisplayPowerControllers = 260 new SparseArray<>(); 261 262 /** {@link DisplayBlanker} used by all {@link DisplayPowerController}s. */ 263 private final DisplayBlanker mDisplayBlanker = new DisplayBlanker() { 264 // Synchronized to avoid race conditions when updating multiple display states. 265 @Override 266 public synchronized void requestDisplayState(int displayId, int state, float brightness, 267 float sdrBrightness) { 268 boolean allInactive = true; 269 boolean allOff = true; 270 final boolean stateChanged; 271 synchronized (mSyncRoot) { 272 final int index = mDisplayStates.indexOfKey(displayId); 273 if (index > -1) { 274 final int currentState = mDisplayStates.valueAt(index); 275 stateChanged = state != currentState; 276 if (stateChanged) { 277 final int size = mDisplayStates.size(); 278 for (int i = 0; i < size; i++) { 279 final int displayState = i == index ? state : mDisplayStates.valueAt(i); 280 if (displayState != Display.STATE_OFF) { 281 allOff = false; 282 } 283 if (Display.isActiveState(displayState)) { 284 allInactive = false; 285 } 286 if (!allOff && !allInactive) { 287 break; 288 } 289 } 290 } 291 } else { 292 stateChanged = false; 293 } 294 } 295 296 // The order of operations is important for legacy reasons. 297 if (state == Display.STATE_OFF) { 298 requestDisplayStateInternal(displayId, state, brightness, sdrBrightness); 299 } 300 301 if (stateChanged) { 302 mDisplayPowerCallbacks.onDisplayStateChange(allInactive, allOff); 303 } 304 305 if (state != Display.STATE_OFF) { 306 requestDisplayStateInternal(displayId, state, brightness, sdrBrightness); 307 } 308 } 309 }; 310 311 /** 312 * Used to inform {@link com.android.server.power.PowerManagerService} of changes to display 313 * state. 314 */ 315 private DisplayManagerInternal.DisplayPowerCallbacks mDisplayPowerCallbacks; 316 317 /** The {@link Handler} used by all {@link DisplayPowerController}s. */ 318 private Handler mPowerHandler; 319 320 // A map from LogicalDisplay ID to display power state. 321 @GuardedBy("mSyncRoot") 322 private final SparseIntArray mDisplayStates = new SparseIntArray(); 323 324 // A map from LogicalDisplay ID to display brightness. 325 @GuardedBy("mSyncRoot") 326 private final SparseArray<BrightnessPair> mDisplayBrightnesses = new SparseArray<>(); 327 328 // Set to true when there are pending display changes that have yet to be applied 329 // to the surface flinger state. 330 private boolean mPendingTraversal; 331 332 // The Wifi display adapter, or null if not registered. 333 private WifiDisplayAdapter mWifiDisplayAdapter; 334 335 // The number of active wifi display scan requests. 336 private int mWifiDisplayScanRequestCount; 337 338 // The virtual display adapter, or null if not registered. 339 private VirtualDisplayAdapter mVirtualDisplayAdapter; 340 341 // The User ID of the current user 342 private @UserIdInt int mCurrentUserId; 343 344 // The stable device screen height and width. These are not tied to a specific display, even 345 // the default display, because they need to be stable over the course of the device's entire 346 // life, even if the default display changes (e.g. a new monitor is plugged into a PC-like 347 // device). 348 private Point mStableDisplaySize = new Point(); 349 350 // Whether the system has finished booting or not. 351 private boolean mSystemReady; 352 353 // The top inset of the default display. 354 // This gets persisted so that the boot animation knows how to transition from the display's 355 // full size to the size configured by the user. Right now we only persist and animate the top 356 // inset, but theoretically we could do it for all of them. 357 private int mDefaultDisplayTopInset; 358 359 // Viewports of the default display and the display that should receive touch 360 // input from an external source. Used by the input system. 361 @GuardedBy("mSyncRoot") 362 private final ArrayList<DisplayViewport> mViewports = new ArrayList<>(); 363 364 // Persistent data store for all internal settings maintained by the display manager service. 365 private final PersistentDataStore mPersistentDataStore = new PersistentDataStore(); 366 367 // Temporary callback list, used when sending display events to applications. 368 // May be used outside of the lock but only on the handler thread. 369 private final ArrayList<CallbackRecord> mTempCallbacks = new ArrayList<CallbackRecord>(); 370 371 // Temporary viewports, used when sending new viewport information to the 372 // input system. May be used outside of the lock but only on the handler thread. 373 private final ArrayList<DisplayViewport> mTempViewports = new ArrayList<>(); 374 375 // The default color mode for default displays. Overrides the usual 376 // Display.Display.COLOR_MODE_DEFAULT for displays with the 377 // DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY flag set. 378 private final int mDefaultDisplayDefaultColorMode; 379 380 // Lists of UIDs that are present on the displays. Maps displayId -> array of UIDs. 381 private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>(); 382 383 private final Injector mInjector; 384 385 // The minimum brightness curve, which guarantess that any brightness curve that dips below it 386 // is rejected by the system. 387 private final Curve mMinimumBrightnessCurve; 388 private final Spline mMinimumBrightnessSpline; 389 private final ColorSpace mWideColorSpace; 390 391 private SensorManager mSensorManager; 392 private BrightnessTracker mBrightnessTracker; 393 394 395 // Whether minimal post processing is allowed by the user. 396 @GuardedBy("mSyncRoot") 397 private boolean mMinimalPostProcessingAllowed; 398 399 // Receives notifications about changes to Settings. 400 private SettingsObserver mSettingsObserver; 401 402 private final boolean mAllowNonNativeRefreshRateOverride; 403 404 private final BrightnessSynchronizer mBrightnessSynchronizer; 405 406 /** 407 * Applications use {@link android.view.Display#getRefreshRate} and 408 * {@link android.view.Display.Mode#getRefreshRate} to know what is the display refresh rate. 409 * Starting with Android S, the platform might throttle down applications frame rate to a 410 * divisor of the refresh rate if it is more preferable (for example if the application called 411 * to {@link android.view.Surface#setFrameRate}). 412 * Applications will experience {@link android.view.Choreographer#postFrameCallback} callbacks 413 * and backpressure at the throttled frame rate. 414 * 415 * {@link android.view.Display#getRefreshRate} will always return the application frame rate 416 * and not the physical display refresh rate to allow applications to do frame pacing correctly. 417 * 418 * {@link android.view.Display.Mode#getRefreshRate} will return the application frame rate if 419 * compiled to a previous release and starting with Android S it will return the physical 420 * display refresh rate. 421 */ 422 @ChangeId 423 @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.S) 424 static final long DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE = 170503758L; 425 DisplayManagerService(Context context)426 public DisplayManagerService(Context context) { 427 this(context, new Injector()); 428 } 429 430 @VisibleForTesting DisplayManagerService(Context context, Injector injector)431 DisplayManagerService(Context context, Injector injector) { 432 super(context); 433 mInjector = injector; 434 mContext = context; 435 mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper()); 436 mUiHandler = UiThread.getHandler(); 437 mDisplayDeviceRepo = new DisplayDeviceRepository(mSyncRoot, mPersistentDataStore); 438 mLogicalDisplayMapper = new LogicalDisplayMapper(mContext, mDisplayDeviceRepo, 439 new LogicalDisplayListener(), mSyncRoot, mHandler); 440 mDisplayModeDirector = new DisplayModeDirector(context, mHandler); 441 mBrightnessSynchronizer = new BrightnessSynchronizer(mContext); 442 Resources resources = mContext.getResources(); 443 mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger( 444 com.android.internal.R.integer.config_defaultDisplayDefaultColorMode); 445 mDefaultDisplayTopInset = SystemProperties.getInt(PROP_DEFAULT_DISPLAY_TOP_INSET, -1); 446 float[] lux = getFloatArray(resources.obtainTypedArray( 447 com.android.internal.R.array.config_minimumBrightnessCurveLux)); 448 float[] nits = getFloatArray(resources.obtainTypedArray( 449 com.android.internal.R.array.config_minimumBrightnessCurveNits)); 450 mMinimumBrightnessCurve = new Curve(lux, nits); 451 mMinimumBrightnessSpline = Spline.createSpline(lux, nits); 452 453 mCurrentUserId = UserHandle.USER_SYSTEM; 454 ColorSpace[] colorSpaces = SurfaceControl.getCompositionColorSpaces(); 455 mWideColorSpace = colorSpaces[1]; 456 mAllowNonNativeRefreshRateOverride = mInjector.getAllowNonNativeRefreshRateOverride(); 457 458 mSystemReady = false; 459 } 460 setupSchedulerPolicies()461 public void setupSchedulerPolicies() { 462 // android.display and android.anim is critical to user experience and we should make sure 463 // it is not in the default foregroup groups, add it to top-app to make sure it uses all 464 // the cores and scheduling settings for top-app when it runs. 465 Process.setThreadGroupAndCpuset(DisplayThread.get().getThreadId(), 466 Process.THREAD_GROUP_TOP_APP); 467 Process.setThreadGroupAndCpuset(AnimationThread.get().getThreadId(), 468 Process.THREAD_GROUP_TOP_APP); 469 Process.setThreadGroupAndCpuset(SurfaceAnimationThread.get().getThreadId(), 470 Process.THREAD_GROUP_TOP_APP); 471 } 472 473 @Override onStart()474 public void onStart() { 475 // We need to pre-load the persistent data store so it's ready before the default display 476 // adapter is up so that we have it's configuration. We could load it lazily, but since 477 // we're going to have to read it in eventually we may as well do it here rather than after 478 // we've waited for the display to register itself with us. 479 synchronized (mSyncRoot) { 480 mPersistentDataStore.loadIfNeeded(); 481 loadStableDisplayValuesLocked(); 482 } 483 mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS); 484 485 // If there was a runtime restart then we may have stale caches left around, so we need to 486 // make sure to invalidate them upon every start. 487 DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); 488 489 publishBinderService(Context.DISPLAY_SERVICE, new BinderService(), 490 true /*allowIsolated*/); 491 publishLocalService(DisplayManagerInternal.class, new LocalService()); 492 } 493 494 @Override onBootPhase(int phase)495 public void onBootPhase(int phase) { 496 if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) { 497 synchronized (mSyncRoot) { 498 long timeout = SystemClock.uptimeMillis() 499 + mInjector.getDefaultDisplayDelayTimeout(); 500 while (mLogicalDisplayMapper.getDisplayLocked(Display.DEFAULT_DISPLAY) == null 501 || mVirtualDisplayAdapter == null) { 502 long delay = timeout - SystemClock.uptimeMillis(); 503 if (delay <= 0) { 504 throw new RuntimeException("Timeout waiting for default display " 505 + "to be initialized. DefaultDisplay=" 506 + mLogicalDisplayMapper.getDisplayLocked(Display.DEFAULT_DISPLAY) 507 + ", mVirtualDisplayAdapter=" + mVirtualDisplayAdapter); 508 } 509 if (DEBUG) { 510 Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay); 511 } 512 try { 513 mSyncRoot.wait(delay); 514 } catch (InterruptedException ex) { 515 } 516 } 517 } 518 } else if (phase == PHASE_BOOT_COMPLETED) { 519 mDisplayModeDirector.onBootCompleted(); 520 } 521 } 522 523 @Override onUserSwitching(@ullable TargetUser from, @NonNull TargetUser to)524 public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) { 525 final int newUserId = to.getUserIdentifier(); 526 final int userSerial = getUserManager().getUserSerialNumber(newUserId); 527 synchronized (mSyncRoot) { 528 final DisplayPowerController displayPowerController = mDisplayPowerControllers.get( 529 Display.DEFAULT_DISPLAY); 530 if (mCurrentUserId != newUserId) { 531 mCurrentUserId = newUserId; 532 BrightnessConfiguration config = 533 mPersistentDataStore.getBrightnessConfiguration(userSerial); 534 displayPowerController.setBrightnessConfiguration(config); 535 handleSettingsChange(); 536 } 537 displayPowerController.onSwitchUser(newUserId); 538 } 539 } 540 541 // TODO: Use dependencies or a boot phase windowManagerAndInputReady()542 public void windowManagerAndInputReady() { 543 synchronized (mSyncRoot) { 544 mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class); 545 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); 546 547 DeviceStateManager deviceStateManager = 548 mContext.getSystemService(DeviceStateManager.class); 549 deviceStateManager.registerCallback(new HandlerExecutor(mHandler), 550 new DeviceStateListener()); 551 552 scheduleTraversalLocked(false); 553 } 554 } 555 556 /** 557 * Called when the system is ready to go. 558 */ systemReady(boolean safeMode, boolean onlyCore)559 public void systemReady(boolean safeMode, boolean onlyCore) { 560 synchronized (mSyncRoot) { 561 mSafeMode = safeMode; 562 mOnlyCore = onlyCore; 563 mSystemReady = true; 564 // Just in case the top inset changed before the system was ready. At this point, any 565 // relevant configuration should be in place. 566 recordTopInsetLocked(mLogicalDisplayMapper.getDisplayLocked(Display.DEFAULT_DISPLAY)); 567 568 updateSettingsLocked(); 569 570 updateUserDisabledHdrTypesFromSettingsLocked(); 571 } 572 573 mDisplayModeDirector.setDesiredDisplayModeSpecsListener( 574 new DesiredDisplayModeSpecsObserver()); 575 mDisplayModeDirector.start(mSensorManager); 576 577 mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS); 578 579 mSettingsObserver = new SettingsObserver(); 580 581 mBrightnessSynchronizer.startSynchronizing(); 582 } 583 584 @VisibleForTesting getDisplayHandler()585 Handler getDisplayHandler() { 586 return mHandler; 587 } 588 589 @VisibleForTesting getDisplayDeviceRepository()590 DisplayDeviceRepository getDisplayDeviceRepository() { 591 return mDisplayDeviceRepo; 592 } 593 loadStableDisplayValuesLocked()594 private void loadStableDisplayValuesLocked() { 595 final Point size = mPersistentDataStore.getStableDisplaySize(); 596 if (size.x > 0 && size.y > 0) { 597 // Just set these values directly so we don't write the display persistent data again 598 // unnecessarily 599 mStableDisplaySize.set(size.x, size.y); 600 } else { 601 final Resources res = mContext.getResources(); 602 final int width = res.getInteger( 603 com.android.internal.R.integer.config_stableDeviceDisplayWidth); 604 final int height = res.getInteger( 605 com.android.internal.R.integer.config_stableDeviceDisplayHeight); 606 if (width > 0 && height > 0) { 607 setStableDisplaySizeLocked(width, height); 608 } 609 } 610 } 611 getStableDisplaySizeInternal()612 private Point getStableDisplaySizeInternal() { 613 Point r = new Point(); 614 synchronized (mSyncRoot) { 615 if (mStableDisplaySize.x > 0 && mStableDisplaySize.y > 0) { 616 r.set(mStableDisplaySize.x, mStableDisplaySize.y); 617 } 618 } 619 return r; 620 } 621 registerDisplayTransactionListenerInternal( DisplayTransactionListener listener)622 private void registerDisplayTransactionListenerInternal( 623 DisplayTransactionListener listener) { 624 // List is self-synchronized copy-on-write. 625 mDisplayTransactionListeners.add(listener); 626 } 627 unregisterDisplayTransactionListenerInternal( DisplayTransactionListener listener)628 private void unregisterDisplayTransactionListenerInternal( 629 DisplayTransactionListener listener) { 630 // List is self-synchronized copy-on-write. 631 mDisplayTransactionListeners.remove(listener); 632 } 633 634 @VisibleForTesting setDisplayInfoOverrideFromWindowManagerInternal(int displayId, DisplayInfo info)635 void setDisplayInfoOverrideFromWindowManagerInternal(int displayId, DisplayInfo info) { 636 synchronized (mSyncRoot) { 637 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 638 if (display != null) { 639 if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) { 640 handleLogicalDisplayChangedLocked(display); 641 scheduleTraversalLocked(false); 642 } 643 } 644 } 645 } 646 647 /** 648 * @see DisplayManagerInternal#getNonOverrideDisplayInfo(int, DisplayInfo) 649 */ getNonOverrideDisplayInfoInternal(int displayId, DisplayInfo outInfo)650 private void getNonOverrideDisplayInfoInternal(int displayId, DisplayInfo outInfo) { 651 synchronized (mSyncRoot) { 652 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 653 if (display != null) { 654 display.getNonOverrideDisplayInfoLocked(outInfo); 655 } 656 } 657 } 658 659 @VisibleForTesting performTraversalInternal(SurfaceControl.Transaction t)660 void performTraversalInternal(SurfaceControl.Transaction t) { 661 synchronized (mSyncRoot) { 662 if (!mPendingTraversal) { 663 return; 664 } 665 mPendingTraversal = false; 666 667 performTraversalLocked(t); 668 } 669 670 // List is self-synchronized copy-on-write. 671 for (DisplayTransactionListener listener : mDisplayTransactionListeners) { 672 listener.onDisplayTransaction(t); 673 } 674 } 675 clampBrightness(int displayState, float brightnessState)676 private float clampBrightness(int displayState, float brightnessState) { 677 if (displayState == Display.STATE_OFF) { 678 brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT; 679 } else if (brightnessState != PowerManager.BRIGHTNESS_OFF_FLOAT 680 && brightnessState < PowerManager.BRIGHTNESS_MIN) { 681 brightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT; 682 } else if (brightnessState > PowerManager.BRIGHTNESS_MAX) { 683 brightnessState = PowerManager.BRIGHTNESS_MAX; 684 } 685 return brightnessState; 686 } 687 requestDisplayStateInternal(int displayId, int state, float brightnessState, float sdrBrightnessState)688 private void requestDisplayStateInternal(int displayId, int state, float brightnessState, 689 float sdrBrightnessState) { 690 if (state == Display.STATE_UNKNOWN) { 691 state = Display.STATE_ON; 692 } 693 694 brightnessState = clampBrightness(state, brightnessState); 695 sdrBrightnessState = clampBrightness(state, sdrBrightnessState); 696 697 // Update the display state within the lock. 698 // Note that we do not need to schedule traversals here although it 699 // may happen as a side-effect of displays changing state. 700 final Runnable runnable; 701 final String traceMessage; 702 synchronized (mSyncRoot) { 703 final int index = mDisplayStates.indexOfKey(displayId); 704 705 final BrightnessPair brightnessPair = 706 index < 0 ? null : mDisplayBrightnesses.valueAt(index); 707 if (index < 0 || (mDisplayStates.valueAt(index) == state 708 && brightnessPair.brightness == brightnessState 709 && brightnessPair.sdrBrightness == sdrBrightnessState)) { 710 return; // Display no longer exists or no change. 711 } 712 713 traceMessage = "requestDisplayStateInternal(" 714 + displayId + ", " 715 + Display.stateToString(state) 716 + ", brightness=" + brightnessState 717 + ", sdrBrightness=" + sdrBrightnessState + ")"; 718 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, traceMessage, displayId); 719 720 mDisplayStates.setValueAt(index, state); 721 brightnessPair.brightness = brightnessState; 722 brightnessPair.sdrBrightness = sdrBrightnessState; 723 runnable = updateDisplayStateLocked(mLogicalDisplayMapper.getDisplayLocked(displayId) 724 .getPrimaryDisplayDeviceLocked()); 725 } 726 727 // Setting the display power state can take hundreds of milliseconds 728 // to complete so we defer the most expensive part of the work until 729 // after we have exited the critical section to avoid blocking other 730 // threads for a long time. 731 if (runnable != null) { 732 runnable.run(); 733 } 734 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, traceMessage, displayId); 735 } 736 737 private class SettingsObserver extends ContentObserver { 738 SettingsObserver() { 739 super(mHandler); 740 741 mContext.getContentResolver().registerContentObserver( 742 Settings.Secure.getUriFor( 743 Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED), false, this); 744 } 745 746 @Override 747 public void onChange(boolean selfChange, Uri uri) { 748 handleSettingsChange(); 749 } 750 } 751 752 private void handleSettingsChange() { 753 synchronized (mSyncRoot) { 754 updateSettingsLocked(); 755 scheduleTraversalLocked(false); 756 } 757 } 758 759 private void updateSettingsLocked() { 760 mMinimalPostProcessingAllowed = Settings.Secure.getIntForUser(mContext.getContentResolver(), 761 Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED, 1, UserHandle.USER_CURRENT) != 0; 762 } 763 764 private void updateUserDisabledHdrTypesFromSettingsLocked() { 765 mAreUserDisabledHdrTypesAllowed = (Settings.Global.getInt( 766 mContext.getContentResolver(), 767 Settings.Global.ARE_USER_DISABLED_HDR_FORMATS_ALLOWED, 768 1) != 0); 769 770 String userDisabledHdrTypes = Settings.Global.getString(mContext.getContentResolver(), 771 Settings.Global.USER_DISABLED_HDR_FORMATS); 772 773 if (userDisabledHdrTypes != null) { 774 try { 775 String[] userDisabledHdrTypeStrings = 776 TextUtils.split(userDisabledHdrTypes, ","); 777 mUserDisabledHdrTypes = new int[userDisabledHdrTypeStrings.length]; 778 for (int i = 0; i < userDisabledHdrTypeStrings.length; i++) { 779 mUserDisabledHdrTypes[i] = Integer.parseInt(userDisabledHdrTypeStrings[i]); 780 } 781 } catch (NumberFormatException e) { 782 Slog.e(TAG, 783 "Failed to parse USER_DISABLED_HDR_FORMATS. " 784 + "Clearing the setting.", e); 785 clearUserDisabledHdrTypesLocked(); 786 } 787 } else { 788 clearUserDisabledHdrTypesLocked(); 789 } 790 } 791 792 private void clearUserDisabledHdrTypesLocked() { 793 mUserDisabledHdrTypes = new int[]{}; 794 synchronized (mSyncRoot) { 795 Settings.Global.putString(mContext.getContentResolver(), 796 Settings.Global.USER_DISABLED_HDR_FORMATS, ""); 797 } 798 } 799 800 private DisplayInfo getDisplayInfoForFrameRateOverride(DisplayEventReceiver.FrameRateOverride[] 801 frameRateOverrides, DisplayInfo info, int callingUid) { 802 float frameRateHz = 0; 803 for (DisplayEventReceiver.FrameRateOverride frameRateOverride : frameRateOverrides) { 804 if (frameRateOverride.uid == callingUid) { 805 frameRateHz = frameRateOverride.frameRateHz; 806 break; 807 } 808 } 809 if (frameRateHz == 0) { 810 return info; 811 } 812 813 // Override the refresh rate only if it is a divider of the current 814 // refresh rate. This calculation needs to be in sync with the native code 815 // in RefreshRateConfigs::getRefreshRateDividerForUid 816 Display.Mode currentMode = info.getMode(); 817 float numPeriods = currentMode.getRefreshRate() / frameRateHz; 818 float numPeriodsRound = Math.round(numPeriods); 819 if (Math.abs(numPeriods - numPeriodsRound) > THRESHOLD_FOR_REFRESH_RATES_DIVIDERS) { 820 return info; 821 } 822 frameRateHz = currentMode.getRefreshRate() / numPeriodsRound; 823 824 DisplayInfo overriddenInfo = new DisplayInfo(); 825 overriddenInfo.copyFrom(info); 826 for (Display.Mode mode : info.supportedModes) { 827 if (!mode.equalsExceptRefreshRate(currentMode)) { 828 continue; 829 } 830 831 if (mode.getRefreshRate() >= frameRateHz - THRESHOLD_FOR_REFRESH_RATES_DIVIDERS 832 && mode.getRefreshRate() 833 <= frameRateHz + THRESHOLD_FOR_REFRESH_RATES_DIVIDERS) { 834 if (DEBUG) { 835 Slog.d(TAG, "found matching modeId " + mode.getModeId()); 836 } 837 overriddenInfo.refreshRateOverride = mode.getRefreshRate(); 838 839 if (!CompatChanges.isChangeEnabled(DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE, 840 callingUid)) { 841 overriddenInfo.modeId = mode.getModeId(); 842 } 843 return overriddenInfo; 844 } 845 } 846 847 if (mAllowNonNativeRefreshRateOverride) { 848 overriddenInfo.refreshRateOverride = frameRateHz; 849 if (!CompatChanges.isChangeEnabled(DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE, 850 callingUid)) { 851 overriddenInfo.supportedModes = Arrays.copyOf(info.supportedModes, 852 info.supportedModes.length + 1); 853 overriddenInfo.supportedModes[overriddenInfo.supportedModes.length - 1] = 854 new Display.Mode(Display.DISPLAY_MODE_ID_FOR_FRAME_RATE_OVERRIDE, 855 currentMode.getPhysicalWidth(), currentMode.getPhysicalHeight(), 856 overriddenInfo.refreshRateOverride); 857 overriddenInfo.modeId = 858 overriddenInfo.supportedModes[overriddenInfo.supportedModes.length - 1] 859 .getModeId(); 860 } 861 return overriddenInfo; 862 } 863 864 return info; 865 } 866 867 private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) { 868 synchronized (mSyncRoot) { 869 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 870 if (display != null) { 871 final DisplayInfo info = 872 getDisplayInfoForFrameRateOverride(display.getFrameRateOverrides(), 873 display.getDisplayInfoLocked(), callingUid); 874 if (info.hasAccess(callingUid) 875 || isUidPresentOnDisplayInternal(callingUid, displayId)) { 876 return info; 877 } 878 } 879 return null; 880 } 881 } 882 883 private void registerCallbackInternal(IDisplayManagerCallback callback, int callingPid, 884 int callingUid, @EventsMask long eventsMask) { 885 synchronized (mSyncRoot) { 886 CallbackRecord record = mCallbacks.get(callingPid); 887 888 if (record != null) { 889 record.updateEventsMask(eventsMask); 890 return; 891 } 892 893 record = new CallbackRecord(callingPid, callingUid, callback, eventsMask); 894 try { 895 IBinder binder = callback.asBinder(); 896 binder.linkToDeath(record, 0); 897 } catch (RemoteException ex) { 898 // give up 899 throw new RuntimeException(ex); 900 } 901 902 mCallbacks.put(callingPid, record); 903 } 904 } 905 906 private void onCallbackDied(CallbackRecord record) { 907 synchronized (mSyncRoot) { 908 mCallbacks.remove(record.mPid); 909 stopWifiDisplayScanLocked(record); 910 } 911 } 912 913 private void startWifiDisplayScanInternal(int callingPid) { 914 synchronized (mSyncRoot) { 915 CallbackRecord record = mCallbacks.get(callingPid); 916 if (record == null) { 917 throw new IllegalStateException("The calling process has not " 918 + "registered an IDisplayManagerCallback."); 919 } 920 startWifiDisplayScanLocked(record); 921 } 922 } 923 924 private void startWifiDisplayScanLocked(CallbackRecord record) { 925 if (!record.mWifiDisplayScanRequested) { 926 record.mWifiDisplayScanRequested = true; 927 if (mWifiDisplayScanRequestCount++ == 0) { 928 if (mWifiDisplayAdapter != null) { 929 mWifiDisplayAdapter.requestStartScanLocked(); 930 } 931 } 932 } 933 } 934 935 private void stopWifiDisplayScanInternal(int callingPid) { 936 synchronized (mSyncRoot) { 937 CallbackRecord record = mCallbacks.get(callingPid); 938 if (record == null) { 939 throw new IllegalStateException("The calling process has not " 940 + "registered an IDisplayManagerCallback."); 941 } 942 stopWifiDisplayScanLocked(record); 943 } 944 } 945 946 private void stopWifiDisplayScanLocked(CallbackRecord record) { 947 if (record.mWifiDisplayScanRequested) { 948 record.mWifiDisplayScanRequested = false; 949 if (--mWifiDisplayScanRequestCount == 0) { 950 if (mWifiDisplayAdapter != null) { 951 mWifiDisplayAdapter.requestStopScanLocked(); 952 } 953 } else if (mWifiDisplayScanRequestCount < 0) { 954 Slog.wtf(TAG, "mWifiDisplayScanRequestCount became negative: " 955 + mWifiDisplayScanRequestCount); 956 mWifiDisplayScanRequestCount = 0; 957 } 958 } 959 } 960 961 private void connectWifiDisplayInternal(String address) { 962 synchronized (mSyncRoot) { 963 if (mWifiDisplayAdapter != null) { 964 mWifiDisplayAdapter.requestConnectLocked(address); 965 } 966 } 967 } 968 969 private void pauseWifiDisplayInternal() { 970 synchronized (mSyncRoot) { 971 if (mWifiDisplayAdapter != null) { 972 mWifiDisplayAdapter.requestPauseLocked(); 973 } 974 } 975 } 976 977 private void resumeWifiDisplayInternal() { 978 synchronized (mSyncRoot) { 979 if (mWifiDisplayAdapter != null) { 980 mWifiDisplayAdapter.requestResumeLocked(); 981 } 982 } 983 } 984 985 private void disconnectWifiDisplayInternal() { 986 synchronized (mSyncRoot) { 987 if (mWifiDisplayAdapter != null) { 988 mWifiDisplayAdapter.requestDisconnectLocked(); 989 } 990 } 991 } 992 993 private void renameWifiDisplayInternal(String address, String alias) { 994 synchronized (mSyncRoot) { 995 if (mWifiDisplayAdapter != null) { 996 mWifiDisplayAdapter.requestRenameLocked(address, alias); 997 } 998 } 999 } 1000 1001 private void forgetWifiDisplayInternal(String address) { 1002 synchronized (mSyncRoot) { 1003 if (mWifiDisplayAdapter != null) { 1004 mWifiDisplayAdapter.requestForgetLocked(address); 1005 } 1006 } 1007 } 1008 1009 private WifiDisplayStatus getWifiDisplayStatusInternal() { 1010 synchronized (mSyncRoot) { 1011 if (mWifiDisplayAdapter != null) { 1012 return mWifiDisplayAdapter.getWifiDisplayStatusLocked(); 1013 } 1014 return new WifiDisplayStatus(); 1015 } 1016 } 1017 1018 private void setUserDisabledHdrTypesInternal(int[] userDisabledHdrTypes) { 1019 synchronized (mSyncRoot) { 1020 if (userDisabledHdrTypes == null) { 1021 Slog.e(TAG, "Null is not an expected argument to " 1022 + "setUserDisabledHdrTypesInternal"); 1023 return; 1024 } 1025 Arrays.sort(userDisabledHdrTypes); 1026 if (Arrays.equals(mUserDisabledHdrTypes, userDisabledHdrTypes)) { 1027 return; 1028 } 1029 String userDisabledFormatsString = ""; 1030 if (userDisabledHdrTypes.length != 0) { 1031 userDisabledFormatsString = TextUtils.join(",", 1032 Arrays.stream(userDisabledHdrTypes).boxed().toArray()); 1033 } 1034 Settings.Global.putString(mContext.getContentResolver(), 1035 Settings.Global.USER_DISABLED_HDR_FORMATS, userDisabledFormatsString); 1036 mUserDisabledHdrTypes = userDisabledHdrTypes; 1037 if (!mAreUserDisabledHdrTypesAllowed) { 1038 mLogicalDisplayMapper.forEachLocked( 1039 display -> { 1040 display.setUserDisabledHdrTypes(userDisabledHdrTypes); 1041 handleLogicalDisplayChangedLocked(display); 1042 }); 1043 } 1044 } 1045 } 1046 1047 private void setAreUserDisabledHdrTypesAllowedInternal( 1048 boolean areUserDisabledHdrTypesAllowed) { 1049 synchronized (mSyncRoot) { 1050 if (mAreUserDisabledHdrTypesAllowed == areUserDisabledHdrTypesAllowed) { 1051 return; 1052 } 1053 mAreUserDisabledHdrTypesAllowed = areUserDisabledHdrTypesAllowed; 1054 if (mUserDisabledHdrTypes.length == 0) { 1055 return; 1056 } 1057 Settings.Global.putInt(mContext.getContentResolver(), 1058 Settings.Global.ARE_USER_DISABLED_HDR_FORMATS_ALLOWED, 1059 areUserDisabledHdrTypesAllowed ? 1 : 0); 1060 int userDisabledHdrTypes[] = {}; 1061 if (!mAreUserDisabledHdrTypesAllowed) { 1062 userDisabledHdrTypes = mUserDisabledHdrTypes; 1063 } 1064 int[] finalUserDisabledHdrTypes = userDisabledHdrTypes; 1065 mLogicalDisplayMapper.forEachLocked( 1066 display -> { 1067 display.setUserDisabledHdrTypes(finalUserDisabledHdrTypes); 1068 handleLogicalDisplayChangedLocked(display); 1069 }); 1070 } 1071 } 1072 1073 private void requestColorModeInternal(int displayId, int colorMode) { 1074 synchronized (mSyncRoot) { 1075 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 1076 if (display != null && 1077 display.getRequestedColorModeLocked() != colorMode) { 1078 display.setRequestedColorModeLocked(colorMode); 1079 scheduleTraversalLocked(false); 1080 } 1081 } 1082 } 1083 1084 private int createVirtualDisplayInternal(IVirtualDisplayCallback callback, 1085 IMediaProjection projection, int callingUid, String packageName, Surface surface, 1086 int flags, VirtualDisplayConfig virtualDisplayConfig) { 1087 synchronized (mSyncRoot) { 1088 if (mVirtualDisplayAdapter == null) { 1089 Slog.w(TAG, "Rejecting request to create private virtual display " 1090 + "because the virtual display adapter is not available."); 1091 return -1; 1092 } 1093 1094 DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked( 1095 callback, projection, callingUid, packageName, surface, flags, 1096 virtualDisplayConfig); 1097 if (device == null) { 1098 return -1; 1099 } 1100 1101 // DisplayDevice events are handled manually for Virtual Displays. 1102 // TODO: multi-display Fix this so that generic add/remove events are not handled in a 1103 // different code path for virtual displays. Currently this happens so that we can 1104 // return a valid display ID synchronously upon successful Virtual Display creation. 1105 // This code can run on any binder thread, while onDisplayDeviceAdded() callbacks are 1106 // called on the DisplayThread (which we don't want to wait for?). 1107 // One option would be to actually wait here on the binder thread 1108 // to be notified when the virtual display is created (or failed). 1109 mDisplayDeviceRepo.onDisplayDeviceEvent(device, 1110 DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED); 1111 1112 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device); 1113 if (display != null) { 1114 return display.getDisplayIdLocked(); 1115 } 1116 1117 // Something weird happened and the logical display was not created. 1118 Slog.w(TAG, "Rejecting request to create virtual display " 1119 + "because the logical display was not created."); 1120 mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callback.asBinder()); 1121 mDisplayDeviceRepo.onDisplayDeviceEvent(device, 1122 DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED); 1123 } 1124 return -1; 1125 } 1126 1127 private void resizeVirtualDisplayInternal(IBinder appToken, 1128 int width, int height, int densityDpi) { 1129 synchronized (mSyncRoot) { 1130 if (mVirtualDisplayAdapter == null) { 1131 return; 1132 } 1133 1134 mVirtualDisplayAdapter.resizeVirtualDisplayLocked(appToken, width, height, densityDpi); 1135 } 1136 } 1137 1138 private void setVirtualDisplaySurfaceInternal(IBinder appToken, Surface surface) { 1139 synchronized (mSyncRoot) { 1140 if (mVirtualDisplayAdapter == null) { 1141 return; 1142 } 1143 1144 mVirtualDisplayAdapter.setVirtualDisplaySurfaceLocked(appToken, surface); 1145 } 1146 } 1147 1148 private void releaseVirtualDisplayInternal(IBinder appToken) { 1149 synchronized (mSyncRoot) { 1150 if (mVirtualDisplayAdapter == null) { 1151 return; 1152 } 1153 1154 DisplayDevice device = 1155 mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken); 1156 if (device != null) { 1157 // TODO: multi-display - handle virtual displays the same as other display adapters. 1158 mDisplayDeviceRepo.onDisplayDeviceEvent(device, 1159 DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED); 1160 } 1161 } 1162 } 1163 1164 private void setVirtualDisplayStateInternal(IBinder appToken, boolean isOn) { 1165 synchronized (mSyncRoot) { 1166 if (mVirtualDisplayAdapter == null) { 1167 return; 1168 } 1169 1170 mVirtualDisplayAdapter.setVirtualDisplayStateLocked(appToken, isOn); 1171 } 1172 } 1173 1174 private void registerDefaultDisplayAdapters() { 1175 // Register default display adapters. 1176 synchronized (mSyncRoot) { 1177 // main display adapter 1178 registerDisplayAdapterLocked(new LocalDisplayAdapter( 1179 mSyncRoot, mContext, mHandler, mDisplayDeviceRepo)); 1180 1181 // Standalone VR devices rely on a virtual display as their primary display for 1182 // 2D UI. We register virtual display adapter along side the main display adapter 1183 // here so that it is ready by the time the system sends the home Intent for 1184 // early apps like SetupWizard/Launcher. In particular, SUW is displayed using 1185 // the virtual display inside VR before any VR-specific apps even run. 1186 mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext, 1187 mHandler, mDisplayDeviceRepo); 1188 if (mVirtualDisplayAdapter != null) { 1189 registerDisplayAdapterLocked(mVirtualDisplayAdapter); 1190 } 1191 } 1192 } 1193 1194 private void registerAdditionalDisplayAdapters() { 1195 synchronized (mSyncRoot) { 1196 if (shouldRegisterNonEssentialDisplayAdaptersLocked()) { 1197 registerOverlayDisplayAdapterLocked(); 1198 registerWifiDisplayAdapterLocked(); 1199 } 1200 } 1201 } 1202 1203 private void registerOverlayDisplayAdapterLocked() { 1204 registerDisplayAdapterLocked(new OverlayDisplayAdapter( 1205 mSyncRoot, mContext, mHandler, mDisplayDeviceRepo, mUiHandler)); 1206 } 1207 1208 private void registerWifiDisplayAdapterLocked() { 1209 if (mContext.getResources().getBoolean( 1210 com.android.internal.R.bool.config_enableWifiDisplay) 1211 || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) { 1212 mWifiDisplayAdapter = new WifiDisplayAdapter( 1213 mSyncRoot, mContext, mHandler, mDisplayDeviceRepo, 1214 mPersistentDataStore); 1215 registerDisplayAdapterLocked(mWifiDisplayAdapter); 1216 } 1217 } 1218 1219 private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() { 1220 // In safe mode, we disable non-essential display adapters to give the user 1221 // an opportunity to fix broken settings or other problems that might affect 1222 // system stability. 1223 // In only-core mode, we disable non-essential display adapters to minimize 1224 // the number of dependencies that are started while in this mode and to 1225 // prevent problems that might occur due to the device being encrypted. 1226 return !mSafeMode && !mOnlyCore; 1227 } 1228 1229 private void registerDisplayAdapterLocked(DisplayAdapter adapter) { 1230 mDisplayAdapters.add(adapter); 1231 adapter.registerLocked(); 1232 } 1233 1234 private void handleLogicalDisplayAddedLocked(LogicalDisplay display) { 1235 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); 1236 final int displayId = display.getDisplayIdLocked(); 1237 final boolean isDefault = displayId == Display.DEFAULT_DISPLAY; 1238 configureColorModeLocked(display, device); 1239 if (!mAreUserDisabledHdrTypesAllowed) { 1240 display.setUserDisabledHdrTypes(mUserDisabledHdrTypes); 1241 } 1242 if (isDefault) { 1243 recordStableDisplayStatsIfNeededLocked(display); 1244 recordTopInsetLocked(display); 1245 } 1246 addDisplayPowerControllerLocked(display); 1247 mDisplayStates.append(displayId, Display.STATE_UNKNOWN); 1248 1249 final float brightnessDefault = display.getDisplayInfoLocked().brightnessDefault; 1250 mDisplayBrightnesses.append(displayId, 1251 new BrightnessPair(brightnessDefault, brightnessDefault)); 1252 1253 DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); 1254 1255 // Wake up waitForDefaultDisplay. 1256 if (isDefault) { 1257 mSyncRoot.notifyAll(); 1258 } 1259 1260 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED); 1261 1262 Runnable work = updateDisplayStateLocked(device); 1263 if (work != null) { 1264 work.run(); 1265 } 1266 scheduleTraversalLocked(false); 1267 } 1268 1269 private void handleLogicalDisplayChangedLocked(@NonNull LogicalDisplay display) { 1270 updateViewportPowerStateLocked(display); 1271 1272 final int displayId = display.getDisplayIdLocked(); 1273 if (displayId == Display.DEFAULT_DISPLAY) { 1274 recordTopInsetLocked(display); 1275 } 1276 // We don't bother invalidating the display info caches here because any changes to the 1277 // display info will trigger a cache invalidation inside of LogicalDisplay before we hit 1278 // this point. 1279 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED); 1280 scheduleTraversalLocked(false); 1281 mPersistentDataStore.saveIfNeeded(); 1282 1283 DisplayPowerController dpc = mDisplayPowerControllers.get(displayId); 1284 if (dpc != null) { 1285 dpc.onDisplayChanged(); 1286 } 1287 } 1288 1289 private void handleLogicalDisplayFrameRateOverridesChangedLocked( 1290 @NonNull LogicalDisplay display) { 1291 final int displayId = display.getDisplayIdLocked(); 1292 // We don't bother invalidating the display info caches here because any changes to the 1293 // display info will trigger a cache invalidation inside of LogicalDisplay before we hit 1294 // this point. 1295 sendDisplayEventFrameRateOverrideLocked(displayId); 1296 scheduleTraversalLocked(false); 1297 } 1298 1299 private void handleLogicalDisplayRemovedLocked(@NonNull LogicalDisplay display) { 1300 final int displayId = display.getDisplayIdLocked(); 1301 final DisplayPowerController dpc = mDisplayPowerControllers.removeReturnOld(displayId); 1302 if (dpc != null) { 1303 dpc.stop(); 1304 } 1305 mDisplayStates.delete(displayId); 1306 mDisplayBrightnesses.delete(displayId); 1307 DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); 1308 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED); 1309 scheduleTraversalLocked(false); 1310 } 1311 1312 private void handleLogicalDisplaySwappedLocked(@NonNull LogicalDisplay display) { 1313 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); 1314 final Runnable work = updateDisplayStateLocked(device); 1315 if (work != null) { 1316 mHandler.post(work); 1317 } 1318 handleLogicalDisplayChangedLocked(display); 1319 } 1320 1321 private void handleLogicalDisplayDeviceStateTransitionLocked(@NonNull LogicalDisplay display) { 1322 final int displayId = display.getDisplayIdLocked(); 1323 final DisplayPowerController dpc = mDisplayPowerControllers.get(displayId); 1324 if (dpc != null) { 1325 dpc.onDeviceStateTransition(); 1326 } 1327 } 1328 1329 private Runnable updateDisplayStateLocked(DisplayDevice device) { 1330 // Blank or unblank the display immediately to match the state requested 1331 // by the display power controller (if known). 1332 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 1333 if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) { 1334 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device); 1335 if (display == null) { 1336 return null; 1337 } 1338 final int displayId = display.getDisplayIdLocked(); 1339 final int state = mDisplayStates.get(displayId); 1340 1341 // Only send a request for display state if display state has already been initialized. 1342 if (state != Display.STATE_UNKNOWN) { 1343 final BrightnessPair brightnessPair = mDisplayBrightnesses.get(displayId); 1344 return device.requestDisplayStateLocked(state, brightnessPair.brightness, 1345 brightnessPair.sdrBrightness); 1346 } 1347 } 1348 return null; 1349 } 1350 1351 private void configureColorModeLocked(LogicalDisplay display, DisplayDevice device) { 1352 if (display.getPrimaryDisplayDeviceLocked() == device) { 1353 int colorMode = mPersistentDataStore.getColorMode(device); 1354 if (colorMode == Display.COLOR_MODE_INVALID) { 1355 if ((device.getDisplayDeviceInfoLocked().flags 1356 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) { 1357 colorMode = mDefaultDisplayDefaultColorMode; 1358 } else { 1359 colorMode = Display.COLOR_MODE_DEFAULT; 1360 } 1361 } 1362 display.setRequestedColorModeLocked(colorMode); 1363 } 1364 } 1365 1366 // If we've never recorded stable device stats for this device before and they aren't 1367 // explicitly configured, go ahead and record the stable device stats now based on the status 1368 // of the default display at first boot. 1369 private void recordStableDisplayStatsIfNeededLocked(LogicalDisplay d) { 1370 if (mStableDisplaySize.x <= 0 && mStableDisplaySize.y <= 0) { 1371 DisplayInfo info = d.getDisplayInfoLocked(); 1372 setStableDisplaySizeLocked(info.getNaturalWidth(), info.getNaturalHeight()); 1373 } 1374 } 1375 1376 private void recordTopInsetLocked(@Nullable LogicalDisplay d) { 1377 // We must only persist the inset after boot has completed, otherwise we will end up 1378 // overwriting the persisted value before the masking flag has been loaded from the 1379 // resource overlay. 1380 if (!mSystemReady || d == null) { 1381 return; 1382 } 1383 int topInset = d.getInsets().top; 1384 if (topInset == mDefaultDisplayTopInset) { 1385 return; 1386 } 1387 mDefaultDisplayTopInset = topInset; 1388 SystemProperties.set(PROP_DEFAULT_DISPLAY_TOP_INSET, Integer.toString(topInset)); 1389 } 1390 1391 private void setStableDisplaySizeLocked(int width, int height) { 1392 mStableDisplaySize = new Point(width, height); 1393 try { 1394 mPersistentDataStore.setStableDisplaySize(mStableDisplaySize); 1395 } finally { 1396 mPersistentDataStore.saveIfNeeded(); 1397 } 1398 } 1399 1400 @VisibleForTesting 1401 Curve getMinimumBrightnessCurveInternal() { 1402 return mMinimumBrightnessCurve; 1403 } 1404 1405 int getPreferredWideGamutColorSpaceIdInternal() { 1406 return mWideColorSpace.getId(); 1407 } 1408 1409 void setShouldAlwaysRespectAppRequestedModeInternal(boolean enabled) { 1410 mDisplayModeDirector.setShouldAlwaysRespectAppRequestedMode(enabled); 1411 } 1412 1413 boolean shouldAlwaysRespectAppRequestedModeInternal() { 1414 return mDisplayModeDirector.shouldAlwaysRespectAppRequestedMode(); 1415 } 1416 1417 void setRefreshRateSwitchingTypeInternal(@DisplayManager.SwitchingType int newValue) { 1418 mDisplayModeDirector.setModeSwitchingType(newValue); 1419 } 1420 1421 @DisplayManager.SwitchingType 1422 int getRefreshRateSwitchingTypeInternal() { 1423 return mDisplayModeDirector.getModeSwitchingType(); 1424 } 1425 1426 private void setBrightnessConfigurationForUserInternal( 1427 @Nullable BrightnessConfiguration c, @UserIdInt int userId, 1428 @Nullable String packageName) { 1429 validateBrightnessConfiguration(c); 1430 final int userSerial = getUserManager().getUserSerialNumber(userId); 1431 synchronized (mSyncRoot) { 1432 try { 1433 mPersistentDataStore.setBrightnessConfigurationForUser(c, userSerial, 1434 packageName); 1435 } finally { 1436 mPersistentDataStore.saveIfNeeded(); 1437 } 1438 if (userId == mCurrentUserId) { 1439 mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY).setBrightnessConfiguration(c); 1440 } 1441 } 1442 } 1443 1444 @VisibleForTesting 1445 void validateBrightnessConfiguration(BrightnessConfiguration config) { 1446 if (config == null) { 1447 return; 1448 } 1449 if (isBrightnessConfigurationTooDark(config)) { 1450 throw new IllegalArgumentException("brightness curve is too dark"); 1451 } 1452 } 1453 1454 private boolean isBrightnessConfigurationTooDark(BrightnessConfiguration config) { 1455 Pair<float[], float[]> curve = config.getCurve(); 1456 float[] lux = curve.first; 1457 float[] nits = curve.second; 1458 for (int i = 0; i < lux.length; i++) { 1459 if (nits[i] < mMinimumBrightnessSpline.interpolate(lux[i])) { 1460 return true; 1461 } 1462 } 1463 return false; 1464 } 1465 1466 private void loadBrightnessConfiguration() { 1467 synchronized (mSyncRoot) { 1468 final int userSerial = getUserManager().getUserSerialNumber(mCurrentUserId); 1469 BrightnessConfiguration config = 1470 mPersistentDataStore.getBrightnessConfiguration(userSerial); 1471 mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY).setBrightnessConfiguration( 1472 config); 1473 } 1474 } 1475 1476 private void performTraversalLocked(SurfaceControl.Transaction t) { 1477 // Clear all viewports before configuring displays so that we can keep 1478 // track of which ones we have configured. 1479 clearViewportsLocked(); 1480 1481 // Configure each display device. 1482 mLogicalDisplayMapper.forEachLocked((LogicalDisplay display) -> { 1483 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); 1484 if (device != null) { 1485 configureDisplayLocked(t, device); 1486 device.performTraversalLocked(t); 1487 } 1488 }); 1489 1490 // Tell the input system about these new viewports. 1491 if (mInputManagerInternal != null) { 1492 mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT); 1493 } 1494 } 1495 1496 private void setDisplayPropertiesInternal(int displayId, boolean hasContent, 1497 float requestedRefreshRate, int requestedModeId, float requestedMinRefreshRate, 1498 float requestedMaxRefreshRate, boolean preferMinimalPostProcessing, 1499 boolean inTraversal) { 1500 synchronized (mSyncRoot) { 1501 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 1502 if (display == null) { 1503 return; 1504 } 1505 1506 boolean shouldScheduleTraversal = false; 1507 1508 if (display.hasContentLocked() != hasContent) { 1509 if (DEBUG) { 1510 Slog.d(TAG, "Display " + displayId + " hasContent flag changed: " 1511 + "hasContent=" + hasContent + ", inTraversal=" + inTraversal); 1512 } 1513 1514 display.setHasContentLocked(hasContent); 1515 shouldScheduleTraversal = true; 1516 } 1517 if (requestedModeId == 0 && requestedRefreshRate != 0) { 1518 // Scan supported modes returned by display.getInfo() to find a mode with the same 1519 // size as the default display mode but with the specified refresh rate instead. 1520 Display.Mode mode = display.getDisplayInfoLocked().findDefaultModeByRefreshRate( 1521 requestedRefreshRate); 1522 if (mode != null) { 1523 requestedModeId = mode.getModeId(); 1524 } else { 1525 Slog.e(TAG, "Couldn't find a mode for the requestedRefreshRate: " 1526 + requestedRefreshRate + " on Display: " + displayId); 1527 } 1528 } 1529 mDisplayModeDirector.getAppRequestObserver().setAppRequest( 1530 displayId, requestedModeId, requestedMinRefreshRate, requestedMaxRefreshRate); 1531 1532 if (display.getDisplayInfoLocked().minimalPostProcessingSupported) { 1533 boolean mppRequest = mMinimalPostProcessingAllowed && preferMinimalPostProcessing; 1534 1535 if (display.getRequestedMinimalPostProcessingLocked() != mppRequest) { 1536 display.setRequestedMinimalPostProcessingLocked(mppRequest); 1537 shouldScheduleTraversal = true; 1538 } 1539 } 1540 1541 if (shouldScheduleTraversal) { 1542 scheduleTraversalLocked(inTraversal); 1543 } 1544 } 1545 } 1546 1547 private void setDisplayOffsetsInternal(int displayId, int x, int y) { 1548 synchronized (mSyncRoot) { 1549 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 1550 if (display == null) { 1551 return; 1552 } 1553 if (display.getDisplayOffsetXLocked() != x 1554 || display.getDisplayOffsetYLocked() != y) { 1555 if (DEBUG) { 1556 Slog.d(TAG, "Display " + displayId + " burn-in offset set to (" 1557 + x + ", " + y + ")"); 1558 } 1559 display.setDisplayOffsetsLocked(x, y); 1560 scheduleTraversalLocked(false); 1561 } 1562 } 1563 } 1564 1565 private void setDisplayScalingDisabledInternal(int displayId, boolean disable) { 1566 synchronized (mSyncRoot) { 1567 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 1568 if (display == null) { 1569 return; 1570 } 1571 if (display.isDisplayScalingDisabled() != disable) { 1572 if (DEBUG) { 1573 Slog.d(TAG, "Display " + displayId + " content scaling disabled = " + disable); 1574 } 1575 display.setDisplayScalingDisabledLocked(disable); 1576 scheduleTraversalLocked(false); 1577 } 1578 } 1579 } 1580 1581 // Updates the lists of UIDs that are present on displays. 1582 private void setDisplayAccessUIDsInternal(SparseArray<IntArray> newDisplayAccessUIDs) { 1583 synchronized (mSyncRoot) { 1584 mDisplayAccessUIDs.clear(); 1585 for (int i = newDisplayAccessUIDs.size() - 1; i >= 0; i--) { 1586 mDisplayAccessUIDs.append(newDisplayAccessUIDs.keyAt(i), 1587 newDisplayAccessUIDs.valueAt(i)); 1588 } 1589 } 1590 } 1591 1592 // Checks if provided UID's content is present on the display and UID has access to it. 1593 private boolean isUidPresentOnDisplayInternal(int uid, int displayId) { 1594 synchronized (mSyncRoot) { 1595 final IntArray displayUIDs = mDisplayAccessUIDs.get(displayId); 1596 return displayUIDs != null && displayUIDs.indexOf(uid) != -1; 1597 } 1598 } 1599 1600 @Nullable 1601 private IBinder getDisplayToken(int displayId) { 1602 synchronized (mSyncRoot) { 1603 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 1604 if (display != null) { 1605 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); 1606 if (device != null) { 1607 return device.getDisplayTokenLocked(); 1608 } 1609 } 1610 } 1611 1612 return null; 1613 } 1614 1615 private SurfaceControl.ScreenshotHardwareBuffer systemScreenshotInternal(int displayId) { 1616 synchronized (mSyncRoot) { 1617 final IBinder token = getDisplayToken(displayId); 1618 if (token == null) { 1619 return null; 1620 } 1621 final LogicalDisplay logicalDisplay = mLogicalDisplayMapper.getDisplayLocked(displayId); 1622 if (logicalDisplay == null) { 1623 return null; 1624 } 1625 1626 final DisplayInfo displayInfo = logicalDisplay.getDisplayInfoLocked(); 1627 final SurfaceControl.DisplayCaptureArgs captureArgs = 1628 new SurfaceControl.DisplayCaptureArgs.Builder(token) 1629 .setSize(displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight()) 1630 .setUseIdentityTransform(true) 1631 .setCaptureSecureLayers(true) 1632 .setAllowProtected(true) 1633 .build(); 1634 return SurfaceControl.captureDisplay(captureArgs); 1635 } 1636 } 1637 1638 private SurfaceControl.ScreenshotHardwareBuffer userScreenshotInternal(int displayId) { 1639 synchronized (mSyncRoot) { 1640 final IBinder token = getDisplayToken(displayId); 1641 if (token == null) { 1642 return null; 1643 } 1644 1645 final SurfaceControl.DisplayCaptureArgs captureArgs = 1646 new SurfaceControl.DisplayCaptureArgs.Builder(token) 1647 .build(); 1648 return SurfaceControl.captureDisplay(captureArgs); 1649 } 1650 } 1651 1652 @VisibleForTesting 1653 DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributesInternal( 1654 int displayId) { 1655 final IBinder token = getDisplayToken(displayId); 1656 if (token == null) { 1657 return null; 1658 } 1659 return SurfaceControl.getDisplayedContentSamplingAttributes(token); 1660 } 1661 1662 @VisibleForTesting 1663 boolean setDisplayedContentSamplingEnabledInternal( 1664 int displayId, boolean enable, int componentMask, int maxFrames) { 1665 final IBinder token = getDisplayToken(displayId); 1666 if (token == null) { 1667 return false; 1668 } 1669 return SurfaceControl.setDisplayedContentSamplingEnabled( 1670 token, enable, componentMask, maxFrames); 1671 } 1672 1673 @VisibleForTesting 1674 DisplayedContentSample getDisplayedContentSampleInternal(int displayId, 1675 long maxFrames, long timestamp) { 1676 final IBinder token = getDisplayToken(displayId); 1677 if (token == null) { 1678 return null; 1679 } 1680 return SurfaceControl.getDisplayedContentSample(token, maxFrames, timestamp); 1681 } 1682 1683 void resetBrightnessConfiguration() { 1684 setBrightnessConfigurationForUserInternal(null, mContext.getUserId(), 1685 mContext.getPackageName()); 1686 } 1687 1688 void setAutoBrightnessLoggingEnabled(boolean enabled) { 1689 synchronized (mSyncRoot) { 1690 final DisplayPowerController displayPowerController = mDisplayPowerControllers.get( 1691 Display.DEFAULT_DISPLAY); 1692 if (displayPowerController != null) { 1693 displayPowerController.setAutoBrightnessLoggingEnabled(enabled); 1694 } 1695 } 1696 } 1697 1698 void setDisplayWhiteBalanceLoggingEnabled(boolean enabled) { 1699 synchronized (mSyncRoot) { 1700 final DisplayPowerController displayPowerController = mDisplayPowerControllers.get( 1701 Display.DEFAULT_DISPLAY); 1702 if (displayPowerController != null) { 1703 displayPowerController.setDisplayWhiteBalanceLoggingEnabled(enabled); 1704 } 1705 } 1706 } 1707 1708 void setDisplayModeDirectorLoggingEnabled(boolean enabled) { 1709 synchronized (mSyncRoot) { 1710 if (mDisplayModeDirector != null) { 1711 mDisplayModeDirector.setLoggingEnabled(enabled); 1712 } 1713 } 1714 } 1715 1716 void setAmbientColorTemperatureOverride(float cct) { 1717 synchronized (mSyncRoot) { 1718 final DisplayPowerController displayPowerController = mDisplayPowerControllers.get( 1719 Display.DEFAULT_DISPLAY); 1720 if (displayPowerController != null) { 1721 displayPowerController.setAmbientColorTemperatureOverride(cct); 1722 } 1723 } 1724 } 1725 1726 private void clearViewportsLocked() { 1727 mViewports.clear(); 1728 } 1729 1730 private Optional<Integer> getViewportType(DisplayDeviceInfo info) { 1731 // Get the corresponding viewport type. 1732 switch (info.touch) { 1733 case DisplayDeviceInfo.TOUCH_INTERNAL: 1734 return Optional.of(VIEWPORT_INTERNAL); 1735 case DisplayDeviceInfo.TOUCH_EXTERNAL: 1736 return Optional.of(VIEWPORT_EXTERNAL); 1737 case DisplayDeviceInfo.TOUCH_VIRTUAL: 1738 if (!TextUtils.isEmpty(info.uniqueId)) { 1739 return Optional.of(VIEWPORT_VIRTUAL); 1740 } 1741 // fallthrough 1742 default: 1743 Slog.w(TAG, "Display " + info + " does not support input device matching."); 1744 } 1745 return Optional.empty(); 1746 } 1747 1748 private void configureDisplayLocked(SurfaceControl.Transaction t, DisplayDevice device) { 1749 final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 1750 final boolean ownContent = (info.flags & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0; 1751 1752 // Find the logical display that the display device is showing. 1753 // Certain displays only ever show their own content. 1754 LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device); 1755 if (!ownContent) { 1756 if (display != null && !display.hasContentLocked()) { 1757 // If the display does not have any content of its own, then 1758 // automatically mirror the requested logical display contents if possible. 1759 display = mLogicalDisplayMapper.getDisplayLocked( 1760 device.getDisplayIdToMirrorLocked()); 1761 } 1762 if (display == null) { 1763 display = mLogicalDisplayMapper.getDisplayLocked(Display.DEFAULT_DISPLAY); 1764 } 1765 } 1766 1767 // Apply the logical display configuration to the display device. 1768 if (display == null) { 1769 // TODO: no logical display for the device, blank it 1770 Slog.w(TAG, "Missing logical display to use for physical display device: " 1771 + device.getDisplayDeviceInfoLocked()); 1772 return; 1773 } 1774 display.configureDisplayLocked(t, device, info.state == Display.STATE_OFF); 1775 final Optional<Integer> viewportType = getViewportType(info); 1776 if (viewportType.isPresent()) { 1777 populateViewportLocked(viewportType.get(), display.getDisplayIdLocked(), device, info); 1778 } 1779 } 1780 1781 /** 1782 * Get internal or external viewport. Create it if does not currently exist. 1783 * @param viewportType - either INTERNAL or EXTERNAL 1784 * @return the viewport with the requested type 1785 */ 1786 private DisplayViewport getViewportLocked(int viewportType, String uniqueId) { 1787 if (viewportType != VIEWPORT_INTERNAL && viewportType != VIEWPORT_EXTERNAL 1788 && viewportType != VIEWPORT_VIRTUAL) { 1789 Slog.wtf(TAG, "Cannot call getViewportByTypeLocked for type " 1790 + DisplayViewport.typeToString(viewportType)); 1791 return null; 1792 } 1793 1794 DisplayViewport viewport; 1795 final int count = mViewports.size(); 1796 for (int i = 0; i < count; i++) { 1797 viewport = mViewports.get(i); 1798 if (viewport.type == viewportType && uniqueId.equals(viewport.uniqueId)) { 1799 return viewport; 1800 } 1801 } 1802 1803 // Creates the viewport if none exists. 1804 viewport = new DisplayViewport(); 1805 viewport.type = viewportType; 1806 viewport.uniqueId = uniqueId; 1807 mViewports.add(viewport); 1808 return viewport; 1809 } 1810 1811 private void populateViewportLocked(int viewportType, int displayId, DisplayDevice device, 1812 DisplayDeviceInfo info) { 1813 final DisplayViewport viewport = getViewportLocked(viewportType, info.uniqueId); 1814 device.populateViewportLocked(viewport); 1815 viewport.valid = true; 1816 viewport.displayId = displayId; 1817 viewport.isActive = Display.isActiveState(info.state); 1818 } 1819 1820 private void updateViewportPowerStateLocked(LogicalDisplay display) { 1821 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); 1822 final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 1823 final Optional<Integer> viewportType = getViewportType(info); 1824 if (viewportType.isPresent()) { 1825 for (DisplayViewport d : mViewports) { 1826 if (d.type == viewportType.get() && info.uniqueId.equals(d.uniqueId)) { 1827 // Update display view port power state 1828 d.isActive = Display.isActiveState(info.state); 1829 } 1830 } 1831 if (mInputManagerInternal != null) { 1832 mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT); 1833 } 1834 } 1835 } 1836 1837 private void sendDisplayEventLocked(int displayId, @DisplayEvent int event) { 1838 Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT, displayId, event); 1839 mHandler.sendMessage(msg); 1840 } 1841 1842 private void sendDisplayGroupEvent(int groupId, int event) { 1843 Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_GROUP_EVENT, groupId, event); 1844 mHandler.sendMessage(msg); 1845 } 1846 1847 private void sendDisplayEventFrameRateOverrideLocked(int displayId) { 1848 Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE, 1849 displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED); 1850 mHandler.sendMessage(msg); 1851 } 1852 1853 // Requests that performTraversals be called at a 1854 // later time to apply changes to surfaces and displays. 1855 private void scheduleTraversalLocked(boolean inTraversal) { 1856 if (!mPendingTraversal && mWindowManagerInternal != null) { 1857 mPendingTraversal = true; 1858 if (!inTraversal) { 1859 mHandler.sendEmptyMessage(MSG_REQUEST_TRAVERSAL); 1860 } 1861 } 1862 } 1863 1864 // Runs on Handler thread. 1865 // Delivers display event notifications to callbacks. 1866 private void deliverDisplayEvent(int displayId, ArraySet<Integer> uids, 1867 @DisplayEvent int event) { 1868 if (DEBUG) { 1869 Slog.d(TAG, "Delivering display event: displayId=" 1870 + displayId + ", event=" + event); 1871 } 1872 1873 // Grab the lock and copy the callbacks. 1874 final int count; 1875 synchronized (mSyncRoot) { 1876 count = mCallbacks.size(); 1877 mTempCallbacks.clear(); 1878 for (int i = 0; i < count; i++) { 1879 if (uids == null || uids.contains(mCallbacks.valueAt(i).mUid)) { 1880 mTempCallbacks.add(mCallbacks.valueAt(i)); 1881 } 1882 } 1883 } 1884 1885 // After releasing the lock, send the notifications out. 1886 for (int i = 0; i < mTempCallbacks.size(); i++) { 1887 mTempCallbacks.get(i).notifyDisplayEventAsync(displayId, event); 1888 } 1889 mTempCallbacks.clear(); 1890 } 1891 1892 // Runs on Handler thread. 1893 // Delivers display group event notifications to callbacks. 1894 private void deliverDisplayGroupEvent(int groupId, int event) { 1895 if (DEBUG) { 1896 Slog.d(TAG, "Delivering display group event: groupId=" + groupId + ", event=" 1897 + event); 1898 } 1899 1900 switch (event) { 1901 case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_ADDED: 1902 for (DisplayGroupListener listener : mDisplayGroupListeners) { 1903 listener.onDisplayGroupAdded(groupId); 1904 } 1905 break; 1906 1907 case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_CHANGED: 1908 for (DisplayGroupListener listener : mDisplayGroupListeners) { 1909 listener.onDisplayGroupChanged(groupId); 1910 } 1911 break; 1912 1913 case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_REMOVED: 1914 for (DisplayGroupListener listener : mDisplayGroupListeners) { 1915 listener.onDisplayGroupRemoved(groupId); 1916 } 1917 break; 1918 } 1919 } 1920 1921 private IMediaProjectionManager getProjectionService() { 1922 if (mProjectionService == null) { 1923 IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE); 1924 mProjectionService = IMediaProjectionManager.Stub.asInterface(b); 1925 } 1926 return mProjectionService; 1927 } 1928 1929 private UserManager getUserManager() { 1930 return mContext.getSystemService(UserManager.class); 1931 } 1932 1933 private void dumpInternal(PrintWriter pw) { 1934 pw.println("DISPLAY MANAGER (dumpsys display)"); 1935 1936 synchronized (mSyncRoot) { 1937 pw.println(" mOnlyCode=" + mOnlyCore); 1938 pw.println(" mSafeMode=" + mSafeMode); 1939 pw.println(" mPendingTraversal=" + mPendingTraversal); 1940 pw.println(" mViewports=" + mViewports); 1941 pw.println(" mDefaultDisplayDefaultColorMode=" + mDefaultDisplayDefaultColorMode); 1942 pw.println(" mWifiDisplayScanRequestCount=" + mWifiDisplayScanRequestCount); 1943 pw.println(" mStableDisplaySize=" + mStableDisplaySize); 1944 pw.println(" mMinimumBrightnessCurve=" + mMinimumBrightnessCurve); 1945 1946 pw.println(); 1947 if (!mAreUserDisabledHdrTypesAllowed) { 1948 pw.println(" mUserDisabledHdrTypes: size=" + mUserDisabledHdrTypes.length); 1949 for (int type : mUserDisabledHdrTypes) { 1950 pw.println(" " + type); 1951 } 1952 } 1953 1954 pw.println(); 1955 final int displayStateCount = mDisplayStates.size(); 1956 pw.println("Display States: size=" + displayStateCount); 1957 for (int i = 0; i < displayStateCount; i++) { 1958 final int displayId = mDisplayStates.keyAt(i); 1959 final int displayState = mDisplayStates.valueAt(i); 1960 final BrightnessPair brightnessPair = mDisplayBrightnesses.valueAt(i); 1961 pw.println(" Display Id=" + displayId); 1962 pw.println(" Display State=" + Display.stateToString(displayState)); 1963 pw.println(" Display Brightness=" + brightnessPair.brightness); 1964 pw.println(" Display SdrBrightness=" + brightnessPair.sdrBrightness); 1965 } 1966 1967 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 1968 ipw.increaseIndent(); 1969 1970 pw.println(); 1971 pw.println("Display Adapters: size=" + mDisplayAdapters.size()); 1972 for (DisplayAdapter adapter : mDisplayAdapters) { 1973 pw.println(" " + adapter.getName()); 1974 adapter.dumpLocked(ipw); 1975 } 1976 1977 pw.println(); 1978 pw.println("Display Devices: size=" + mDisplayDeviceRepo.sizeLocked()); 1979 mDisplayDeviceRepo.forEachLocked(device -> { 1980 pw.println(" " + device.getDisplayDeviceInfoLocked()); 1981 device.dumpLocked(ipw); 1982 }); 1983 1984 pw.println(); 1985 mLogicalDisplayMapper.dumpLocked(pw); 1986 1987 pw.println(); 1988 mDisplayModeDirector.dump(pw); 1989 1990 final int callbackCount = mCallbacks.size(); 1991 pw.println(); 1992 pw.println("Callbacks: size=" + callbackCount); 1993 for (int i = 0; i < callbackCount; i++) { 1994 CallbackRecord callback = mCallbacks.valueAt(i); 1995 pw.println(" " + i + ": mPid=" + callback.mPid 1996 + ", mWifiDisplayScanRequested=" + callback.mWifiDisplayScanRequested); 1997 } 1998 1999 final int displayPowerControllerCount = mDisplayPowerControllers.size(); 2000 pw.println(); 2001 pw.println("Display Power Controllers: size=" + displayPowerControllerCount); 2002 for (int i = 0; i < displayPowerControllerCount; i++) { 2003 mDisplayPowerControllers.valueAt(i).dump(pw); 2004 } 2005 if (mBrightnessTracker != null) { 2006 pw.println(); 2007 mBrightnessTracker.dump(pw); 2008 } 2009 pw.println(); 2010 mPersistentDataStore.dump(pw); 2011 } 2012 } 2013 2014 private static float[] getFloatArray(TypedArray array) { 2015 int length = array.length(); 2016 float[] floatArray = new float[length]; 2017 for (int i = 0; i < length; i++) { 2018 floatArray[i] = array.getFloat(i, Float.NaN); 2019 } 2020 array.recycle(); 2021 return floatArray; 2022 } 2023 2024 /** 2025 * This is the object that everything in the display manager locks on. 2026 * We make it an inner class within the {@link DisplayManagerService} to so that it is 2027 * clear that the object belongs to the display manager service and that it is 2028 * a unique object with a special purpose. 2029 */ 2030 public static final class SyncRoot { 2031 } 2032 2033 @VisibleForTesting 2034 static class Injector { 2035 VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, 2036 Handler handler, DisplayAdapter.Listener displayAdapterListener) { 2037 return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener); 2038 } 2039 2040 long getDefaultDisplayDelayTimeout() { 2041 return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT; 2042 } 2043 2044 boolean getAllowNonNativeRefreshRateOverride() { 2045 return DisplayProperties 2046 .debug_allow_non_native_refresh_rate_override().orElse(false); 2047 } 2048 } 2049 2050 @VisibleForTesting 2051 DisplayDeviceInfo getDisplayDeviceInfoInternal(int displayId) { 2052 synchronized (mSyncRoot) { 2053 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 2054 if (display != null) { 2055 final DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked(); 2056 return displayDevice.getDisplayDeviceInfoLocked(); 2057 } 2058 return null; 2059 } 2060 } 2061 2062 @VisibleForTesting 2063 int getDisplayIdToMirrorInternal(int displayId) { 2064 synchronized (mSyncRoot) { 2065 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 2066 if (display != null) { 2067 final DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked(); 2068 return displayDevice.getDisplayIdToMirrorLocked(); 2069 } 2070 return Display.INVALID_DISPLAY; 2071 } 2072 } 2073 2074 @VisibleForTesting 2075 Surface getVirtualDisplaySurfaceInternal(IBinder appToken) { 2076 synchronized (mSyncRoot) { 2077 if (mVirtualDisplayAdapter == null) { 2078 return null; 2079 } 2080 return mVirtualDisplayAdapter.getVirtualDisplaySurfaceLocked(appToken); 2081 } 2082 } 2083 2084 private void initializeDisplayPowerControllersLocked() { 2085 mLogicalDisplayMapper.forEachLocked(this::addDisplayPowerControllerLocked); 2086 } 2087 2088 private void addDisplayPowerControllerLocked(LogicalDisplay display) { 2089 if (mPowerHandler == null) { 2090 // initPowerManagement has not yet been called. 2091 return; 2092 } 2093 if (mBrightnessTracker == null) { 2094 mBrightnessTracker = new BrightnessTracker(mContext, null); 2095 } 2096 2097 final BrightnessSetting brightnessSetting = new BrightnessSetting(mPersistentDataStore, 2098 display, mSyncRoot); 2099 final DisplayPowerController displayPowerController = new DisplayPowerController( 2100 mContext, mDisplayPowerCallbacks, mPowerHandler, mSensorManager, 2101 mDisplayBlanker, display, mBrightnessTracker, brightnessSetting, 2102 () -> handleBrightnessChange(display)); 2103 mDisplayPowerControllers.append(display.getDisplayIdLocked(), displayPowerController); 2104 } 2105 2106 private void handleBrightnessChange(LogicalDisplay display) { 2107 sendDisplayEventLocked(display.getDisplayIdLocked(), 2108 DisplayManagerGlobal.EVENT_DISPLAY_BRIGHTNESS_CHANGED); 2109 } 2110 2111 private DisplayDevice getDeviceForDisplayLocked(int displayId) { 2112 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 2113 return display == null ? null : display.getPrimaryDisplayDeviceLocked(); 2114 } 2115 2116 private final class DisplayManagerHandler extends Handler { 2117 public DisplayManagerHandler(Looper looper) { 2118 super(looper, null, true /*async*/); 2119 } 2120 2121 @Override 2122 public void handleMessage(Message msg) { 2123 switch (msg.what) { 2124 case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS: 2125 registerDefaultDisplayAdapters(); 2126 break; 2127 2128 case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS: 2129 registerAdditionalDisplayAdapters(); 2130 break; 2131 2132 case MSG_DELIVER_DISPLAY_EVENT: 2133 deliverDisplayEvent(msg.arg1, null, msg.arg2); 2134 break; 2135 2136 case MSG_REQUEST_TRAVERSAL: 2137 mWindowManagerInternal.requestTraversalFromDisplayManager(); 2138 break; 2139 2140 case MSG_UPDATE_VIEWPORT: { 2141 final boolean changed; 2142 synchronized (mSyncRoot) { 2143 changed = !mTempViewports.equals(mViewports); 2144 if (changed) { 2145 mTempViewports.clear(); 2146 for (DisplayViewport d : mViewports) { 2147 mTempViewports.add(d.makeCopy()); 2148 } 2149 } 2150 } 2151 if (changed) { 2152 mInputManagerInternal.setDisplayViewports(mTempViewports); 2153 } 2154 break; 2155 } 2156 2157 case MSG_LOAD_BRIGHTNESS_CONFIGURATION: 2158 loadBrightnessConfiguration(); 2159 break; 2160 2161 case MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE: 2162 ArraySet<Integer> uids; 2163 synchronized (mSyncRoot) { 2164 int displayId = msg.arg1; 2165 final LogicalDisplay display = 2166 mLogicalDisplayMapper.getDisplayLocked(displayId); 2167 uids = display.getPendingFrameRateOverrideUids(); 2168 display.clearPendingFrameRateOverrideUids(); 2169 } 2170 deliverDisplayEvent(msg.arg1, uids, msg.arg2); 2171 break; 2172 2173 case MSG_DELIVER_DISPLAY_GROUP_EVENT: 2174 deliverDisplayGroupEvent(msg.arg1, msg.arg2); 2175 break; 2176 2177 } 2178 } 2179 } 2180 2181 private final class LogicalDisplayListener implements LogicalDisplayMapper.Listener { 2182 @Override 2183 public void onLogicalDisplayEventLocked(LogicalDisplay display, int event) { 2184 switch (event) { 2185 case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_ADDED: 2186 handleLogicalDisplayAddedLocked(display); 2187 break; 2188 2189 case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_CHANGED: 2190 handleLogicalDisplayChangedLocked(display); 2191 break; 2192 2193 case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REMOVED: 2194 handleLogicalDisplayRemovedLocked(display); 2195 break; 2196 2197 case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_SWAPPED: 2198 handleLogicalDisplaySwappedLocked(display); 2199 break; 2200 2201 case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED: 2202 handleLogicalDisplayFrameRateOverridesChangedLocked(display); 2203 break; 2204 2205 case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_DEVICE_STATE_TRANSITION: 2206 handleLogicalDisplayDeviceStateTransitionLocked(display); 2207 break; 2208 } 2209 } 2210 2211 @Override 2212 public void onDisplayGroupEventLocked(int groupId, int event) { 2213 sendDisplayGroupEvent(groupId, event); 2214 } 2215 2216 @Override 2217 public void onTraversalRequested() { 2218 synchronized (mSyncRoot) { 2219 scheduleTraversalLocked(false); 2220 } 2221 } 2222 } 2223 2224 private final class CallbackRecord implements DeathRecipient { 2225 public final int mPid; 2226 public final int mUid; 2227 private final IDisplayManagerCallback mCallback; 2228 private @EventsMask AtomicLong mEventsMask; 2229 2230 public boolean mWifiDisplayScanRequested; 2231 2232 CallbackRecord(int pid, int uid, IDisplayManagerCallback callback, 2233 @EventsMask long eventsMask) { 2234 mPid = pid; 2235 mUid = uid; 2236 mCallback = callback; 2237 mEventsMask = new AtomicLong(eventsMask); 2238 } 2239 2240 public void updateEventsMask(@EventsMask long eventsMask) { 2241 mEventsMask.set(eventsMask); 2242 } 2243 2244 @Override 2245 public void binderDied() { 2246 if (DEBUG) { 2247 Slog.d(TAG, "Display listener for pid " + mPid + " died."); 2248 } 2249 onCallbackDied(this); 2250 } 2251 2252 public void notifyDisplayEventAsync(int displayId, @DisplayEvent int event) { 2253 if (!shouldSendEvent(event)) { 2254 return; 2255 } 2256 2257 try { 2258 mCallback.onDisplayEvent(displayId, event); 2259 } catch (RemoteException ex) { 2260 Slog.w(TAG, "Failed to notify process " 2261 + mPid + " that displays changed, assuming it died.", ex); 2262 binderDied(); 2263 } 2264 } 2265 2266 private boolean shouldSendEvent(@DisplayEvent int event) { 2267 final long mask = mEventsMask.get(); 2268 switch (event) { 2269 case DisplayManagerGlobal.EVENT_DISPLAY_ADDED: 2270 return (mask & DisplayManager.EVENT_FLAG_DISPLAY_ADDED) != 0; 2271 case DisplayManagerGlobal.EVENT_DISPLAY_CHANGED: 2272 return (mask & DisplayManager.EVENT_FLAG_DISPLAY_CHANGED) != 0; 2273 case DisplayManagerGlobal.EVENT_DISPLAY_BRIGHTNESS_CHANGED: 2274 return (mask & DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS) != 0; 2275 case DisplayManagerGlobal.EVENT_DISPLAY_REMOVED: 2276 return (mask & DisplayManager.EVENT_FLAG_DISPLAY_REMOVED) != 0; 2277 default: 2278 // This should never happen. 2279 Slog.e(TAG, "Unknown display event " + event); 2280 return true; 2281 } 2282 } 2283 } 2284 2285 @VisibleForTesting 2286 final class BinderService extends IDisplayManager.Stub { 2287 /** 2288 * Returns information about the specified logical display. 2289 * 2290 * @param displayId The logical display id. 2291 * @return The logical display info, return {@code null} if the display does not exist or 2292 * the calling UID isn't present on the display. The returned object must be treated as 2293 * immutable. 2294 */ 2295 @Override // Binder call 2296 public DisplayInfo getDisplayInfo(int displayId) { 2297 final int callingUid = Binder.getCallingUid(); 2298 final long token = Binder.clearCallingIdentity(); 2299 try { 2300 return getDisplayInfoInternal(displayId, callingUid); 2301 } finally { 2302 Binder.restoreCallingIdentity(token); 2303 } 2304 } 2305 2306 /** 2307 * Returns the list of all display ids. 2308 */ 2309 @Override // Binder call 2310 public int[] getDisplayIds() { 2311 final int callingUid = Binder.getCallingUid(); 2312 final long token = Binder.clearCallingIdentity(); 2313 try { 2314 synchronized (mSyncRoot) { 2315 return mLogicalDisplayMapper.getDisplayIdsLocked(callingUid); 2316 } 2317 } finally { 2318 Binder.restoreCallingIdentity(token); 2319 } 2320 } 2321 2322 @Override // Binder call 2323 public boolean isUidPresentOnDisplay(int uid, int displayId) { 2324 final long token = Binder.clearCallingIdentity(); 2325 try { 2326 return isUidPresentOnDisplayInternal(uid, displayId); 2327 } finally { 2328 Binder.restoreCallingIdentity(token); 2329 } 2330 } 2331 2332 /** 2333 * Returns the stable device display size, in pixels. 2334 */ 2335 @Override // Binder call 2336 public Point getStableDisplaySize() { 2337 final long token = Binder.clearCallingIdentity(); 2338 try { 2339 return getStableDisplaySizeInternal(); 2340 } finally { 2341 Binder.restoreCallingIdentity(token); 2342 } 2343 } 2344 2345 @Override // Binder call 2346 public void registerCallback(IDisplayManagerCallback callback) { 2347 registerCallbackWithEventMask(callback, DisplayManager.EVENT_FLAG_DISPLAY_ADDED 2348 | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED 2349 | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED); 2350 } 2351 2352 @Override // Binder call 2353 public void registerCallbackWithEventMask(IDisplayManagerCallback callback, 2354 @EventsMask long eventsMask) { 2355 if (callback == null) { 2356 throw new IllegalArgumentException("listener must not be null"); 2357 } 2358 2359 final int callingPid = Binder.getCallingPid(); 2360 final int callingUid = Binder.getCallingUid(); 2361 final long token = Binder.clearCallingIdentity(); 2362 try { 2363 registerCallbackInternal(callback, callingPid, callingUid, eventsMask); 2364 } finally { 2365 Binder.restoreCallingIdentity(token); 2366 } 2367 } 2368 2369 @Override // Binder call 2370 public void startWifiDisplayScan() { 2371 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 2372 "Permission required to start wifi display scans"); 2373 2374 final int callingPid = Binder.getCallingPid(); 2375 final long token = Binder.clearCallingIdentity(); 2376 try { 2377 startWifiDisplayScanInternal(callingPid); 2378 } finally { 2379 Binder.restoreCallingIdentity(token); 2380 } 2381 } 2382 2383 @Override // Binder call 2384 public void stopWifiDisplayScan() { 2385 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 2386 "Permission required to stop wifi display scans"); 2387 2388 final int callingPid = Binder.getCallingPid(); 2389 final long token = Binder.clearCallingIdentity(); 2390 try { 2391 stopWifiDisplayScanInternal(callingPid); 2392 } finally { 2393 Binder.restoreCallingIdentity(token); 2394 } 2395 } 2396 2397 @Override // Binder call 2398 public void connectWifiDisplay(String address) { 2399 if (address == null) { 2400 throw new IllegalArgumentException("address must not be null"); 2401 } 2402 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 2403 "Permission required to connect to a wifi display"); 2404 2405 final long token = Binder.clearCallingIdentity(); 2406 try { 2407 connectWifiDisplayInternal(address); 2408 } finally { 2409 Binder.restoreCallingIdentity(token); 2410 } 2411 } 2412 2413 @Override // Binder call 2414 public void disconnectWifiDisplay() { 2415 // This request does not require special permissions. 2416 // Any app can request disconnection from the currently active wifi display. 2417 // This exception should no longer be needed once wifi display control moves 2418 // to the media router service. 2419 2420 final long token = Binder.clearCallingIdentity(); 2421 try { 2422 disconnectWifiDisplayInternal(); 2423 } finally { 2424 Binder.restoreCallingIdentity(token); 2425 } 2426 } 2427 2428 @Override // Binder call 2429 public void renameWifiDisplay(String address, String alias) { 2430 if (address == null) { 2431 throw new IllegalArgumentException("address must not be null"); 2432 } 2433 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 2434 "Permission required to rename to a wifi display"); 2435 2436 final long token = Binder.clearCallingIdentity(); 2437 try { 2438 renameWifiDisplayInternal(address, alias); 2439 } finally { 2440 Binder.restoreCallingIdentity(token); 2441 } 2442 } 2443 2444 @Override // Binder call 2445 public void forgetWifiDisplay(String address) { 2446 if (address == null) { 2447 throw new IllegalArgumentException("address must not be null"); 2448 } 2449 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 2450 "Permission required to forget to a wifi display"); 2451 2452 final long token = Binder.clearCallingIdentity(); 2453 try { 2454 forgetWifiDisplayInternal(address); 2455 } finally { 2456 Binder.restoreCallingIdentity(token); 2457 } 2458 } 2459 2460 @Override // Binder call 2461 public void pauseWifiDisplay() { 2462 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 2463 "Permission required to pause a wifi display session"); 2464 2465 final long token = Binder.clearCallingIdentity(); 2466 try { 2467 pauseWifiDisplayInternal(); 2468 } finally { 2469 Binder.restoreCallingIdentity(token); 2470 } 2471 } 2472 2473 @Override // Binder call 2474 public void resumeWifiDisplay() { 2475 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 2476 "Permission required to resume a wifi display session"); 2477 2478 final long token = Binder.clearCallingIdentity(); 2479 try { 2480 resumeWifiDisplayInternal(); 2481 } finally { 2482 Binder.restoreCallingIdentity(token); 2483 } 2484 } 2485 2486 @Override // Binder call 2487 public WifiDisplayStatus getWifiDisplayStatus() { 2488 // This request does not require special permissions. 2489 // Any app can get information about available wifi displays. 2490 2491 final long token = Binder.clearCallingIdentity(); 2492 try { 2493 return getWifiDisplayStatusInternal(); 2494 } finally { 2495 Binder.restoreCallingIdentity(token); 2496 } 2497 } 2498 2499 @Override // Binder call 2500 public void setUserDisabledHdrTypes(int[] userDisabledFormats) { 2501 mContext.enforceCallingOrSelfPermission( 2502 Manifest.permission.WRITE_SECURE_SETTINGS, 2503 "Permission required to write the user settings."); 2504 2505 final long token = Binder.clearCallingIdentity(); 2506 try { 2507 setUserDisabledHdrTypesInternal(userDisabledFormats); 2508 } finally { 2509 Binder.restoreCallingIdentity(token); 2510 } 2511 } 2512 2513 @Override // Binder call 2514 public void setAreUserDisabledHdrTypesAllowed(boolean areUserDisabledHdrTypesAllowed) { 2515 mContext.enforceCallingOrSelfPermission( 2516 Manifest.permission.WRITE_SECURE_SETTINGS, 2517 "Permission required to write the user settings."); 2518 final long token = Binder.clearCallingIdentity(); 2519 try { 2520 setAreUserDisabledHdrTypesAllowedInternal(areUserDisabledHdrTypesAllowed); 2521 } finally { 2522 Binder.restoreCallingIdentity(token); 2523 } 2524 } 2525 2526 @Override // Binder call 2527 public boolean areUserDisabledHdrTypesAllowed() { 2528 synchronized (mSyncRoot) { 2529 return mAreUserDisabledHdrTypesAllowed; 2530 } 2531 } 2532 2533 @Override // Binder call 2534 public int[] getUserDisabledHdrTypes() { 2535 return mUserDisabledHdrTypes; 2536 } 2537 2538 @Override // Binder call 2539 public void requestColorMode(int displayId, int colorMode) { 2540 mContext.enforceCallingOrSelfPermission( 2541 Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE, 2542 "Permission required to change the display color mode"); 2543 final long token = Binder.clearCallingIdentity(); 2544 try { 2545 requestColorModeInternal(displayId, colorMode); 2546 } finally { 2547 Binder.restoreCallingIdentity(token); 2548 } 2549 } 2550 2551 @Override // Binder call 2552 public int createVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig, 2553 IVirtualDisplayCallback callback, IMediaProjection projection, String packageName) { 2554 final int callingUid = Binder.getCallingUid(); 2555 if (!validatePackageName(callingUid, packageName)) { 2556 throw new SecurityException("packageName must match the calling uid"); 2557 } 2558 if (callback == null) { 2559 throw new IllegalArgumentException("appToken must not be null"); 2560 } 2561 if (virtualDisplayConfig == null) { 2562 throw new IllegalArgumentException("virtualDisplayConfig must not be null"); 2563 } 2564 final Surface surface = virtualDisplayConfig.getSurface(); 2565 int flags = virtualDisplayConfig.getFlags(); 2566 2567 if (surface != null && surface.isSingleBuffered()) { 2568 throw new IllegalArgumentException("Surface can't be single-buffered"); 2569 } 2570 2571 if ((flags & VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) { 2572 flags |= VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; 2573 2574 // Public displays can't be allowed to show content when locked. 2575 if ((flags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) { 2576 throw new IllegalArgumentException( 2577 "Public display must not be marked as SHOW_WHEN_LOCKED_INSECURE"); 2578 } 2579 } 2580 if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) { 2581 flags &= ~VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; 2582 } 2583 if ((flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) { 2584 flags &= ~VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP; 2585 } 2586 2587 if (projection != null) { 2588 try { 2589 if (!getProjectionService().isValidMediaProjection(projection)) { 2590 throw new SecurityException("Invalid media projection"); 2591 } 2592 flags = projection.applyVirtualDisplayFlags(flags); 2593 } catch (RemoteException e) { 2594 throw new SecurityException("unable to validate media projection or flags"); 2595 } 2596 } 2597 2598 if (callingUid != Process.SYSTEM_UID && 2599 (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) { 2600 if (!canProjectVideo(projection)) { 2601 throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or " 2602 + "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate " 2603 + "MediaProjection token in order to create a screen sharing virtual " 2604 + "display."); 2605 } 2606 } 2607 if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0) { 2608 if (!canProjectSecureVideo(projection)) { 2609 throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT " 2610 + "or an appropriate MediaProjection token to create a " 2611 + "secure virtual display."); 2612 } 2613 } 2614 2615 if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) != 0) { 2616 if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { 2617 EventLog.writeEvent(0x534e4554, "162627132", callingUid, 2618 "Attempt to create a trusted display without holding permission!"); 2619 throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to " 2620 + "create a trusted virtual display."); 2621 } 2622 } 2623 2624 if (callingUid != Process.SYSTEM_UID 2625 && (flags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) { 2626 if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { 2627 throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to " 2628 + "create a virtual display which is not in the default DisplayGroup."); 2629 } 2630 } 2631 2632 if ((flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == 0) { 2633 flags &= ~VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; 2634 } 2635 2636 // Sometimes users can have sensitive information in system decoration windows. An app 2637 // could create a virtual display with system decorations support and read the user info 2638 // from the surface. 2639 // We should only allow adding flag VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS 2640 // to trusted virtual displays. 2641 final int trustedDisplayWithSysDecorFlag = 2642 (VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS 2643 | VIRTUAL_DISPLAY_FLAG_TRUSTED); 2644 if ((flags & trustedDisplayWithSysDecorFlag) 2645 == VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS 2646 && !checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "createVirtualDisplay()")) { 2647 throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); 2648 } 2649 2650 final long token = Binder.clearCallingIdentity(); 2651 try { 2652 return createVirtualDisplayInternal(callback, projection, callingUid, packageName, 2653 surface, flags, virtualDisplayConfig); 2654 } finally { 2655 Binder.restoreCallingIdentity(token); 2656 } 2657 } 2658 2659 @Override // Binder call 2660 public void resizeVirtualDisplay(IVirtualDisplayCallback callback, 2661 int width, int height, int densityDpi) { 2662 if (width <= 0 || height <= 0 || densityDpi <= 0) { 2663 throw new IllegalArgumentException("width, height, and densityDpi must be " 2664 + "greater than 0"); 2665 } 2666 final long token = Binder.clearCallingIdentity(); 2667 try { 2668 resizeVirtualDisplayInternal(callback.asBinder(), width, height, densityDpi); 2669 } finally { 2670 Binder.restoreCallingIdentity(token); 2671 } 2672 } 2673 2674 @Override // Binder call 2675 public void setVirtualDisplaySurface(IVirtualDisplayCallback callback, Surface surface) { 2676 if (surface != null && surface.isSingleBuffered()) { 2677 throw new IllegalArgumentException("Surface can't be single-buffered"); 2678 } 2679 final long token = Binder.clearCallingIdentity(); 2680 try { 2681 setVirtualDisplaySurfaceInternal(callback.asBinder(), surface); 2682 } finally { 2683 Binder.restoreCallingIdentity(token); 2684 } 2685 } 2686 2687 @Override // Binder call 2688 public void releaseVirtualDisplay(IVirtualDisplayCallback callback) { 2689 final long token = Binder.clearCallingIdentity(); 2690 try { 2691 releaseVirtualDisplayInternal(callback.asBinder()); 2692 } finally { 2693 Binder.restoreCallingIdentity(token); 2694 } 2695 } 2696 2697 @Override // Binder call 2698 public void setVirtualDisplayState(IVirtualDisplayCallback callback, boolean isOn) { 2699 final long token = Binder.clearCallingIdentity(); 2700 try { 2701 setVirtualDisplayStateInternal(callback.asBinder(), isOn); 2702 } finally { 2703 Binder.restoreCallingIdentity(token); 2704 } 2705 } 2706 2707 @Override // Binder call 2708 public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) { 2709 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 2710 2711 final long token = Binder.clearCallingIdentity(); 2712 try { 2713 dumpInternal(pw); 2714 } finally { 2715 Binder.restoreCallingIdentity(token); 2716 } 2717 } 2718 2719 @Override // Binder call 2720 public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents(String callingPackage) { 2721 mContext.enforceCallingOrSelfPermission( 2722 Manifest.permission.BRIGHTNESS_SLIDER_USAGE, 2723 "Permission to read brightness events."); 2724 2725 final int callingUid = Binder.getCallingUid(); 2726 AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class); 2727 final int mode = appOpsManager.noteOp(AppOpsManager.OP_GET_USAGE_STATS, 2728 callingUid, callingPackage); 2729 final boolean hasUsageStats; 2730 if (mode == AppOpsManager.MODE_DEFAULT) { 2731 // The default behavior here is to check if PackageManager has given the app 2732 // permission. 2733 hasUsageStats = mContext.checkCallingPermission( 2734 Manifest.permission.PACKAGE_USAGE_STATS) 2735 == PackageManager.PERMISSION_GRANTED; 2736 } else { 2737 hasUsageStats = mode == AppOpsManager.MODE_ALLOWED; 2738 } 2739 2740 final int userId = UserHandle.getUserId(callingUid); 2741 final long token = Binder.clearCallingIdentity(); 2742 try { 2743 synchronized (mSyncRoot) { 2744 return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) 2745 .getBrightnessEvents(userId, hasUsageStats); 2746 } 2747 } finally { 2748 Binder.restoreCallingIdentity(token); 2749 } 2750 } 2751 2752 @Override // Binder call 2753 public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats() { 2754 mContext.enforceCallingOrSelfPermission( 2755 Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS, 2756 "Permission required to to access ambient light stats."); 2757 final int callingUid = Binder.getCallingUid(); 2758 final int userId = UserHandle.getUserId(callingUid); 2759 final long token = Binder.clearCallingIdentity(); 2760 try { 2761 synchronized (mSyncRoot) { 2762 return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) 2763 .getAmbientBrightnessStats(userId); 2764 } 2765 } finally { 2766 Binder.restoreCallingIdentity(token); 2767 } 2768 } 2769 2770 @Override // Binder call 2771 public void setBrightnessConfigurationForUser( 2772 BrightnessConfiguration c, @UserIdInt int userId, String packageName) { 2773 mContext.enforceCallingOrSelfPermission( 2774 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS, 2775 "Permission required to change the display's brightness configuration"); 2776 if (userId != UserHandle.getCallingUserId()) { 2777 mContext.enforceCallingOrSelfPermission( 2778 Manifest.permission.INTERACT_ACROSS_USERS, 2779 "Permission required to change the display brightness" 2780 + " configuration of another user"); 2781 } 2782 if (packageName != null && !validatePackageName(getCallingUid(), packageName)) { 2783 packageName = null; 2784 } 2785 final long token = Binder.clearCallingIdentity(); 2786 try { 2787 setBrightnessConfigurationForUserInternal(c, userId, packageName); 2788 } finally { 2789 Binder.restoreCallingIdentity(token); 2790 } 2791 } 2792 2793 @Override // Binder call 2794 public BrightnessConfiguration getBrightnessConfigurationForUser(int userId) { 2795 mContext.enforceCallingOrSelfPermission( 2796 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS, 2797 "Permission required to read the display's brightness configuration"); 2798 if (userId != UserHandle.getCallingUserId()) { 2799 mContext.enforceCallingOrSelfPermission( 2800 Manifest.permission.INTERACT_ACROSS_USERS, 2801 "Permission required to read the display brightness" 2802 + " configuration of another user"); 2803 } 2804 final long token = Binder.clearCallingIdentity(); 2805 try { 2806 final int userSerial = getUserManager().getUserSerialNumber(userId); 2807 synchronized (mSyncRoot) { 2808 BrightnessConfiguration config = 2809 mPersistentDataStore.getBrightnessConfiguration(userSerial); 2810 if (config == null) { 2811 config = mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) 2812 .getDefaultBrightnessConfiguration(); 2813 } 2814 return config; 2815 } 2816 } finally { 2817 Binder.restoreCallingIdentity(token); 2818 } 2819 } 2820 2821 @Override // Binder call 2822 public BrightnessConfiguration getDefaultBrightnessConfiguration() { 2823 mContext.enforceCallingOrSelfPermission( 2824 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS, 2825 "Permission required to read the display's default brightness configuration"); 2826 final long token = Binder.clearCallingIdentity(); 2827 try { 2828 synchronized (mSyncRoot) { 2829 return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) 2830 .getDefaultBrightnessConfiguration(); 2831 } 2832 } finally { 2833 Binder.restoreCallingIdentity(token); 2834 } 2835 } 2836 2837 @Override 2838 public BrightnessInfo getBrightnessInfo(int displayId) { 2839 mContext.enforceCallingOrSelfPermission( 2840 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS, 2841 "Permission required to read the display's brightness info."); 2842 final long token = Binder.clearCallingIdentity(); 2843 try { 2844 synchronized (mSyncRoot) { 2845 DisplayPowerController dpc = mDisplayPowerControllers.get(displayId); 2846 if (dpc != null) { 2847 return dpc.getBrightnessInfo(); 2848 } 2849 } 2850 } finally { 2851 Binder.restoreCallingIdentity(token); 2852 } 2853 return null; 2854 } 2855 2856 @Override // Binder call 2857 public boolean isMinimalPostProcessingRequested(int displayId) { 2858 synchronized (mSyncRoot) { 2859 return mLogicalDisplayMapper.getDisplayLocked(displayId) 2860 .getRequestedMinimalPostProcessingLocked(); 2861 } 2862 } 2863 2864 @Override // Binder call 2865 public void setTemporaryBrightness(int displayId, float brightness) { 2866 mContext.enforceCallingOrSelfPermission( 2867 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS, 2868 "Permission required to set the display's brightness"); 2869 final long token = Binder.clearCallingIdentity(); 2870 try { 2871 synchronized (mSyncRoot) { 2872 mDisplayPowerControllers.get(displayId) 2873 .setTemporaryBrightness(brightness); 2874 } 2875 } finally { 2876 Binder.restoreCallingIdentity(token); 2877 } 2878 } 2879 2880 @Override // Binder call 2881 public void setBrightness(int displayId, float brightness) { 2882 mContext.enforceCallingOrSelfPermission( 2883 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS, 2884 "Permission required to set the display's brightness"); 2885 if (!isValidBrightness(brightness)) { 2886 Slog.w(TAG, "Attempted to set invalid brightness" + brightness); 2887 return; 2888 } 2889 final long token = Binder.clearCallingIdentity(); 2890 try { 2891 synchronized (mSyncRoot) { 2892 DisplayPowerController dpc = mDisplayPowerControllers.get(displayId); 2893 if (dpc != null) { 2894 dpc.putScreenBrightnessSetting(brightness); 2895 } 2896 mPersistentDataStore.saveIfNeeded(); 2897 } 2898 } finally { 2899 Binder.restoreCallingIdentity(token); 2900 } 2901 } 2902 2903 @Override // Binder call 2904 public float getBrightness(int displayId) { 2905 float brightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; 2906 mContext.enforceCallingOrSelfPermission( 2907 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS, 2908 "Permission required to set the display's brightness"); 2909 final long token = Binder.clearCallingIdentity(); 2910 try { 2911 synchronized (mSyncRoot) { 2912 DisplayPowerController dpc = mDisplayPowerControllers.get(displayId); 2913 if (dpc != null) { 2914 brightness = dpc.getScreenBrightnessSetting(); 2915 } 2916 } 2917 } finally { 2918 Binder.restoreCallingIdentity(token); 2919 } 2920 return brightness; 2921 } 2922 2923 @Override // Binder call 2924 public void setTemporaryAutoBrightnessAdjustment(float adjustment) { 2925 mContext.enforceCallingOrSelfPermission( 2926 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS, 2927 "Permission required to set the display's auto brightness adjustment"); 2928 final long token = Binder.clearCallingIdentity(); 2929 try { 2930 synchronized (mSyncRoot) { 2931 mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) 2932 .setTemporaryAutoBrightnessAdjustment(adjustment); 2933 } 2934 } finally { 2935 Binder.restoreCallingIdentity(token); 2936 } 2937 } 2938 2939 @Override // Binder call 2940 public void onShellCommand(FileDescriptor in, FileDescriptor out, 2941 FileDescriptor err, String[] args, ShellCallback callback, 2942 ResultReceiver resultReceiver) { 2943 new DisplayManagerShellCommand(DisplayManagerService.this).exec(this, in, out, err, 2944 args, callback, resultReceiver); 2945 } 2946 2947 @Override // Binder call 2948 public Curve getMinimumBrightnessCurve() { 2949 final long token = Binder.clearCallingIdentity(); 2950 try { 2951 return getMinimumBrightnessCurveInternal(); 2952 } finally { 2953 Binder.restoreCallingIdentity(token); 2954 } 2955 } 2956 2957 @Override // Binder call 2958 public int getPreferredWideGamutColorSpaceId() { 2959 final long token = Binder.clearCallingIdentity(); 2960 try { 2961 return getPreferredWideGamutColorSpaceIdInternal(); 2962 } finally { 2963 Binder.restoreCallingIdentity(token); 2964 } 2965 } 2966 2967 @Override // Binder call 2968 public void setShouldAlwaysRespectAppRequestedMode(boolean enabled) { 2969 mContext.enforceCallingOrSelfPermission( 2970 Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS, 2971 "Permission required to override display mode requests."); 2972 final long token = Binder.clearCallingIdentity(); 2973 try { 2974 setShouldAlwaysRespectAppRequestedModeInternal(enabled); 2975 } finally { 2976 Binder.restoreCallingIdentity(token); 2977 } 2978 } 2979 2980 @Override // Binder call 2981 public boolean shouldAlwaysRespectAppRequestedMode() { 2982 mContext.enforceCallingOrSelfPermission( 2983 Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS, 2984 "Permission required to override display mode requests."); 2985 final long token = Binder.clearCallingIdentity(); 2986 try { 2987 return shouldAlwaysRespectAppRequestedModeInternal(); 2988 } finally { 2989 Binder.restoreCallingIdentity(token); 2990 } 2991 } 2992 2993 @Override // Binder call 2994 public void setRefreshRateSwitchingType(int newValue) { 2995 mContext.enforceCallingOrSelfPermission( 2996 Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE, 2997 "Permission required to modify refresh rate switching type."); 2998 final long token = Binder.clearCallingIdentity(); 2999 try { 3000 setRefreshRateSwitchingTypeInternal(newValue); 3001 } finally { 3002 Binder.restoreCallingIdentity(token); 3003 } 3004 } 3005 3006 @Override // Binder call 3007 public int getRefreshRateSwitchingType() { 3008 final long token = Binder.clearCallingIdentity(); 3009 try { 3010 return getRefreshRateSwitchingTypeInternal(); 3011 } finally { 3012 Binder.restoreCallingIdentity(token); 3013 } 3014 } 3015 3016 private boolean validatePackageName(int uid, String packageName) { 3017 if (packageName != null) { 3018 String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid); 3019 if (packageNames != null) { 3020 for (String n : packageNames) { 3021 if (n.equals(packageName)) { 3022 return true; 3023 } 3024 } 3025 } 3026 } 3027 return false; 3028 } 3029 3030 private boolean canProjectVideo(IMediaProjection projection) { 3031 if (projection != null) { 3032 try { 3033 if (projection.canProjectVideo()) { 3034 return true; 3035 } 3036 } catch (RemoteException e) { 3037 Slog.e(TAG, "Unable to query projection service for permissions", e); 3038 } 3039 } 3040 if (checkCallingPermission(CAPTURE_VIDEO_OUTPUT, "canProjectVideo()")) { 3041 return true; 3042 } 3043 return canProjectSecureVideo(projection); 3044 } 3045 3046 private boolean canProjectSecureVideo(IMediaProjection projection) { 3047 if (projection != null) { 3048 try { 3049 if (projection.canProjectSecureVideo()){ 3050 return true; 3051 } 3052 } catch (RemoteException e) { 3053 Slog.e(TAG, "Unable to query projection service for permissions", e); 3054 } 3055 } 3056 return checkCallingPermission(CAPTURE_SECURE_VIDEO_OUTPUT, "canProjectSecureVideo()"); 3057 } 3058 3059 private boolean checkCallingPermission(String permission, String func) { 3060 if (mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) { 3061 return true; 3062 } 3063 final String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid() 3064 + ", uid=" + Binder.getCallingUid() + " requires " + permission; 3065 Slog.w(TAG, msg); 3066 return false; 3067 } 3068 3069 } 3070 3071 private static boolean isValidBrightness(float brightness) { 3072 return !Float.isNaN(brightness) 3073 && (brightness >= PowerManager.BRIGHTNESS_MIN) 3074 && (brightness <= PowerManager.BRIGHTNESS_MAX); 3075 } 3076 3077 private final class LocalService extends DisplayManagerInternal { 3078 3079 @Override 3080 public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler, 3081 SensorManager sensorManager) { 3082 synchronized (mSyncRoot) { 3083 mDisplayPowerCallbacks = callbacks; 3084 mSensorManager = sensorManager; 3085 mPowerHandler = handler; 3086 initializeDisplayPowerControllersLocked(); 3087 } 3088 3089 mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATION); 3090 } 3091 3092 @Override 3093 public boolean requestPowerState(int groupId, DisplayPowerRequest request, 3094 boolean waitForNegativeProximity) { 3095 synchronized (mSyncRoot) { 3096 final DisplayGroup displayGroup = mLogicalDisplayMapper.getDisplayGroupLocked( 3097 groupId); 3098 if (displayGroup == null) { 3099 return true; 3100 } 3101 3102 final int size = displayGroup.getSizeLocked(); 3103 boolean ready = true; 3104 for (int i = 0; i < size; i++) { 3105 final int id = displayGroup.getIdLocked(i); 3106 final DisplayDevice displayDevice = mLogicalDisplayMapper.getDisplayLocked( 3107 id).getPrimaryDisplayDeviceLocked(); 3108 final int flags = displayDevice.getDisplayDeviceInfoLocked().flags; 3109 if ((flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) { 3110 final DisplayPowerController displayPowerController = 3111 mDisplayPowerControllers.get(id); 3112 ready &= displayPowerController.requestPowerState(request, 3113 waitForNegativeProximity); 3114 } 3115 } 3116 3117 return ready; 3118 } 3119 } 3120 3121 @Override 3122 public boolean isProximitySensorAvailable() { 3123 synchronized (mSyncRoot) { 3124 return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) 3125 .isProximitySensorAvailable(); 3126 } 3127 } 3128 3129 @Override 3130 public void registerDisplayGroupListener(DisplayGroupListener listener) { 3131 mDisplayGroupListeners.add(listener); 3132 } 3133 3134 @Override 3135 public void unregisterDisplayGroupListener(DisplayGroupListener listener) { 3136 mDisplayGroupListeners.remove(listener); 3137 } 3138 3139 @Override 3140 public SurfaceControl.ScreenshotHardwareBuffer systemScreenshot(int displayId) { 3141 return systemScreenshotInternal(displayId); 3142 } 3143 3144 @Override 3145 public SurfaceControl.ScreenshotHardwareBuffer userScreenshot(int displayId) { 3146 return userScreenshotInternal(displayId); 3147 } 3148 3149 @Override 3150 public DisplayInfo getDisplayInfo(int displayId) { 3151 return getDisplayInfoInternal(displayId, Process.myUid()); 3152 } 3153 3154 @Override 3155 public Point getDisplayPosition(int displayId) { 3156 synchronized (mSyncRoot) { 3157 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 3158 if (display != null) { 3159 return display.getDisplayPosition(); 3160 } 3161 return null; 3162 } 3163 } 3164 3165 @Override 3166 public void registerDisplayTransactionListener(DisplayTransactionListener listener) { 3167 if (listener == null) { 3168 throw new IllegalArgumentException("listener must not be null"); 3169 } 3170 3171 registerDisplayTransactionListenerInternal(listener); 3172 } 3173 3174 @Override 3175 public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) { 3176 if (listener == null) { 3177 throw new IllegalArgumentException("listener must not be null"); 3178 } 3179 3180 unregisterDisplayTransactionListenerInternal(listener); 3181 } 3182 3183 @Override 3184 public void setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info) { 3185 setDisplayInfoOverrideFromWindowManagerInternal(displayId, info); 3186 } 3187 3188 @Override 3189 public void getNonOverrideDisplayInfo(int displayId, DisplayInfo outInfo) { 3190 getNonOverrideDisplayInfoInternal(displayId, outInfo); 3191 } 3192 3193 @Override 3194 public void performTraversal(SurfaceControl.Transaction t) { 3195 performTraversalInternal(t); 3196 } 3197 3198 @Override 3199 public void setDisplayProperties(int displayId, boolean hasContent, 3200 float requestedRefreshRate, int requestedMode, float requestedMinRefreshRate, 3201 float requestedMaxRefreshRate, boolean requestedMinimalPostProcessing, 3202 boolean inTraversal) { 3203 setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate, 3204 requestedMode, requestedMinRefreshRate, requestedMaxRefreshRate, 3205 requestedMinimalPostProcessing, inTraversal); 3206 } 3207 3208 @Override 3209 public void setDisplayOffsets(int displayId, int x, int y) { 3210 setDisplayOffsetsInternal(displayId, x, y); 3211 } 3212 3213 @Override 3214 public void setDisplayScalingDisabled(int displayId, boolean disableScaling) { 3215 setDisplayScalingDisabledInternal(displayId, disableScaling); 3216 } 3217 3218 @Override 3219 public void setDisplayAccessUIDs(SparseArray<IntArray> newDisplayAccessUIDs) { 3220 setDisplayAccessUIDsInternal(newDisplayAccessUIDs); 3221 } 3222 3223 @Override 3224 public void persistBrightnessTrackerState() { 3225 synchronized (mSyncRoot) { 3226 mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) 3227 .persistBrightnessTrackerState(); 3228 } 3229 } 3230 3231 @Override 3232 public void onOverlayChanged() { 3233 synchronized (mSyncRoot) { 3234 mDisplayDeviceRepo.forEachLocked(DisplayDevice::onOverlayChangedLocked); 3235 } 3236 } 3237 3238 @Override 3239 public DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributes( 3240 int displayId) { 3241 return getDisplayedContentSamplingAttributesInternal(displayId); 3242 } 3243 3244 @Override 3245 public boolean setDisplayedContentSamplingEnabled( 3246 int displayId, boolean enable, int componentMask, int maxFrames) { 3247 return setDisplayedContentSamplingEnabledInternal( 3248 displayId, enable, componentMask, maxFrames); 3249 } 3250 3251 @Override 3252 public DisplayedContentSample getDisplayedContentSample(int displayId, 3253 long maxFrames, long timestamp) { 3254 return getDisplayedContentSampleInternal(displayId, maxFrames, timestamp); 3255 } 3256 3257 @Override 3258 public void ignoreProximitySensorUntilChanged() { 3259 mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) 3260 .ignoreProximitySensorUntilChanged(); 3261 } 3262 3263 @Override 3264 public int getRefreshRateSwitchingType() { 3265 return getRefreshRateSwitchingTypeInternal(); 3266 } 3267 3268 @Override 3269 public RefreshRateRange getRefreshRateForDisplayAndSensor(int displayId, String sensorName, 3270 String sensorType) { 3271 final SensorManager sensorManager; 3272 synchronized (mSyncRoot) { 3273 sensorManager = mSensorManager; 3274 } 3275 if (sensorManager == null) { 3276 return null; 3277 } 3278 3279 // Verify that the specified sensor exists. 3280 final Sensor sensor = SensorUtils.findSensor(sensorManager, sensorType, sensorName, 3281 SensorUtils.NO_FALLBACK); 3282 if (sensor == null) { 3283 return null; 3284 } 3285 3286 synchronized (mSyncRoot) { 3287 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 3288 if (display == null) { 3289 return null; 3290 } 3291 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); 3292 if (device == null) { 3293 return null; 3294 } 3295 final DisplayDeviceConfig config = device.getDisplayDeviceConfig(); 3296 SensorData sensorData = config.getProximitySensor(); 3297 if (sensorData.matches(sensorName, sensorType)) { 3298 return new RefreshRateRange(sensorData.minRefreshRate, 3299 sensorData.maxRefreshRate); 3300 } 3301 } 3302 return null; 3303 } 3304 3305 @Override 3306 public List<RefreshRateLimitation> getRefreshRateLimitations(int displayId) { 3307 final DisplayDeviceConfig config; 3308 synchronized (mSyncRoot) { 3309 final DisplayDevice device = getDeviceForDisplayLocked(displayId); 3310 if (device == null) { 3311 return null; 3312 } 3313 config = device.getDisplayDeviceConfig(); 3314 } 3315 return config.getRefreshRateLimitations(); 3316 } 3317 } 3318 3319 class DesiredDisplayModeSpecsObserver 3320 implements DisplayModeDirector.DesiredDisplayModeSpecsListener { 3321 3322 private final Consumer<LogicalDisplay> mSpecsChangedConsumer = display -> { 3323 int displayId = display.getDisplayIdLocked(); 3324 DisplayModeDirector.DesiredDisplayModeSpecs desiredDisplayModeSpecs = 3325 mDisplayModeDirector.getDesiredDisplayModeSpecs(displayId); 3326 DisplayModeDirector.DesiredDisplayModeSpecs existingDesiredDisplayModeSpecs = 3327 display.getDesiredDisplayModeSpecsLocked(); 3328 if (DEBUG) { 3329 Slog.i(TAG, 3330 "Comparing display specs: " + desiredDisplayModeSpecs 3331 + ", existing: " + existingDesiredDisplayModeSpecs); 3332 } 3333 if (!desiredDisplayModeSpecs.equals(existingDesiredDisplayModeSpecs)) { 3334 display.setDesiredDisplayModeSpecsLocked(desiredDisplayModeSpecs); 3335 mChanged = true; 3336 } 3337 }; 3338 3339 @GuardedBy("mSyncRoot") 3340 private boolean mChanged = false; 3341 3342 public void onDesiredDisplayModeSpecsChanged() { 3343 synchronized (mSyncRoot) { 3344 mChanged = false; 3345 mLogicalDisplayMapper.forEachLocked(mSpecsChangedConsumer); 3346 if (mChanged) { 3347 scheduleTraversalLocked(false); 3348 mChanged = false; 3349 } 3350 } 3351 } 3352 } 3353 3354 /** 3355 * Listens to changes in device state and reports the state to LogicalDisplayMapper. 3356 */ 3357 class DeviceStateListener implements DeviceStateManager.DeviceStateCallback { 3358 @Override 3359 public void onStateChanged(int deviceState) { 3360 synchronized (mSyncRoot) { 3361 mLogicalDisplayMapper.setDeviceStateLocked(deviceState); 3362 } 3363 } 3364 }; 3365 3366 private class BrightnessPair { 3367 public float brightness; 3368 public float sdrBrightness; 3369 3370 BrightnessPair(float brightness, float sdrBrightness) { 3371 this.brightness = brightness; 3372 this.sdrBrightness = sdrBrightness; 3373 } 3374 } 3375 3376 /** 3377 * Functional interface for providing time. 3378 * TODO(b/184781936): merge with PowerManagerService.Clock 3379 */ 3380 @VisibleForTesting 3381 public interface Clock { 3382 /** 3383 * Returns current time in milliseconds since boot, not counting time spent in deep sleep. 3384 */ 3385 long uptimeMillis(); 3386 } 3387 } 3388