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.CAPTURE_SECURE_VIDEO_OUTPUT; 20 import static android.Manifest.permission.CAPTURE_VIDEO_OUTPUT; 21 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; 22 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; 23 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD; 24 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY; 25 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; 26 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE; 27 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; 28 import static android.hardware.display.DisplayViewport.VIEWPORT_EXTERNAL; 29 import static android.hardware.display.DisplayViewport.VIEWPORT_INTERNAL; 30 import static android.hardware.display.DisplayViewport.VIEWPORT_VIRTUAL; 31 32 import android.Manifest; 33 import android.annotation.NonNull; 34 import android.annotation.Nullable; 35 import android.annotation.UserIdInt; 36 import android.app.AppOpsManager; 37 import android.content.Context; 38 import android.content.pm.PackageManager; 39 import android.content.pm.ParceledListSlice; 40 import android.content.res.Resources; 41 import android.content.res.TypedArray; 42 import android.graphics.ColorSpace; 43 import android.graphics.Point; 44 import android.graphics.Rect; 45 import android.hardware.SensorManager; 46 import android.hardware.display.AmbientBrightnessDayStats; 47 import android.hardware.display.BrightnessChangeEvent; 48 import android.hardware.display.BrightnessConfiguration; 49 import android.hardware.display.Curve; 50 import android.hardware.display.DisplayManagerGlobal; 51 import android.hardware.display.DisplayManagerInternal; 52 import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener; 53 import android.hardware.display.DisplayViewport; 54 import android.hardware.display.DisplayedContentSample; 55 import android.hardware.display.DisplayedContentSamplingAttributes; 56 import android.hardware.display.IDisplayManager; 57 import android.hardware.display.IDisplayManagerCallback; 58 import android.hardware.display.IVirtualDisplayCallback; 59 import android.hardware.display.WifiDisplayStatus; 60 import android.hardware.input.InputManagerInternal; 61 import android.media.projection.IMediaProjection; 62 import android.media.projection.IMediaProjectionManager; 63 import android.os.Binder; 64 import android.os.Handler; 65 import android.os.IBinder; 66 import android.os.IBinder.DeathRecipient; 67 import android.os.Looper; 68 import android.os.Message; 69 import android.os.PowerManager; 70 import android.os.Process; 71 import android.os.RemoteException; 72 import android.os.ResultReceiver; 73 import android.os.ServiceManager; 74 import android.os.ShellCallback; 75 import android.os.SystemClock; 76 import android.os.SystemProperties; 77 import android.os.Trace; 78 import android.os.UserHandle; 79 import android.os.UserManager; 80 import android.provider.Settings; 81 import android.text.TextUtils; 82 import android.util.IntArray; 83 import android.util.Pair; 84 import android.util.Slog; 85 import android.util.SparseArray; 86 import android.util.Spline; 87 import android.view.Display; 88 import android.view.DisplayInfo; 89 import android.view.Surface; 90 import android.view.SurfaceControl; 91 92 import com.android.internal.annotations.GuardedBy; 93 import com.android.internal.annotations.VisibleForTesting; 94 import com.android.internal.util.DumpUtils; 95 import com.android.internal.util.IndentingPrintWriter; 96 import com.android.server.AnimationThread; 97 import com.android.server.DisplayThread; 98 import com.android.server.LocalServices; 99 import com.android.server.SystemService; 100 import com.android.server.UiThread; 101 import com.android.server.wm.SurfaceAnimationThread; 102 import com.android.server.wm.WindowManagerInternal; 103 104 import java.io.FileDescriptor; 105 import java.io.PrintWriter; 106 import java.util.ArrayList; 107 import java.util.Arrays; 108 import java.util.List; 109 import java.util.concurrent.CopyOnWriteArrayList; 110 111 /** 112 * Manages attached displays. 113 * <p> 114 * The {@link DisplayManagerService} manages the global lifecycle of displays, 115 * decides how to configure logical displays based on the physical display devices currently 116 * attached, sends notifications to the system and to applications when the state 117 * changes, and so on. 118 * </p><p> 119 * The display manager service relies on a collection of {@link DisplayAdapter} components, 120 * for discovering and configuring physical display devices attached to the system. 121 * There are separate display adapters for each manner that devices are attached: 122 * one display adapter for built-in local displays, one for simulated non-functional 123 * displays when the system is headless, one for simulated overlay displays used for 124 * development, one for wifi displays, etc. 125 * </p><p> 126 * Display adapters are only weakly coupled to the display manager service. 127 * Display adapters communicate changes in display device state to the display manager 128 * service asynchronously via a {@link DisplayAdapter.Listener} registered 129 * by the display manager service. This separation of concerns is important for 130 * two main reasons. First, it neatly encapsulates the responsibilities of these 131 * two classes: display adapters handle individual display devices whereas 132 * the display manager service handles the global state. Second, it eliminates 133 * the potential for deadlocks resulting from asynchronous display device discovery. 134 * </p> 135 * 136 * <h3>Synchronization</h3> 137 * <p> 138 * Because the display manager may be accessed by multiple threads, the synchronization 139 * story gets a little complicated. In particular, the window manager may call into 140 * the display manager while holding a surface transaction with the expectation that 141 * it can apply changes immediately. Unfortunately, that means we can't just do 142 * everything asynchronously (*grump*). 143 * </p><p> 144 * To make this work, all of the objects that belong to the display manager must 145 * use the same lock. We call this lock the synchronization root and it has a unique 146 * type {@link DisplayManagerService.SyncRoot}. Methods that require this lock are 147 * named with the "Locked" suffix. 148 * </p><p> 149 * Where things get tricky is that the display manager is not allowed to make 150 * any potentially reentrant calls, especially into the window manager. We generally 151 * avoid this by making all potentially reentrant out-calls asynchronous. 152 * </p> 153 */ 154 public final class DisplayManagerService extends SystemService { 155 private static final String TAG = "DisplayManagerService"; 156 private static final boolean DEBUG = false; 157 158 // When this system property is set to 0, WFD is forcibly disabled on boot. 159 // When this system property is set to 1, WFD is forcibly enabled on boot. 160 // Otherwise WFD is enabled according to the value of config_enableWifiDisplay. 161 private static final String FORCE_WIFI_DISPLAY_ENABLE = "persist.debug.wfd.enable"; 162 163 private static final String PROP_DEFAULT_DISPLAY_TOP_INSET = "persist.sys.displayinset.top"; 164 165 private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000; 166 167 private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1; 168 private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2; 169 private static final int MSG_DELIVER_DISPLAY_EVENT = 3; 170 private static final int MSG_REQUEST_TRAVERSAL = 4; 171 private static final int MSG_UPDATE_VIEWPORT = 5; 172 private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATION = 6; 173 174 private final Context mContext; 175 private final DisplayManagerHandler mHandler; 176 private final Handler mUiHandler; 177 private final DisplayAdapterListener mDisplayAdapterListener; 178 private final DisplayModeDirector mDisplayModeDirector; 179 private WindowManagerInternal mWindowManagerInternal; 180 private InputManagerInternal mInputManagerInternal; 181 private IMediaProjectionManager mProjectionService; 182 183 // The synchronization root for the display manager. 184 // This lock guards most of the display manager's state. 185 // NOTE: This is synchronized on while holding WindowManagerService.mWindowMap so never call 186 // into WindowManagerService methods that require mWindowMap while holding this unless you are 187 // very very sure that no deadlock can occur. 188 private final SyncRoot mSyncRoot = new SyncRoot(); 189 190 // True if in safe mode. 191 // This option may disable certain display adapters. 192 public boolean mSafeMode; 193 194 // True if we are in a special boot mode where only core applications and 195 // services should be started. This option may disable certain display adapters. 196 public boolean mOnlyCore; 197 198 // True if the display manager service should pretend there is only one display 199 // and only tell applications about the existence of the default logical display. 200 // The display manager can still mirror content to secondary displays but applications 201 // cannot present unique content on those displays. 202 // Used for demonstration purposes only. 203 private final boolean mSingleDisplayDemoMode; 204 205 // All callback records indexed by calling process id. 206 public final SparseArray<CallbackRecord> mCallbacks = 207 new SparseArray<CallbackRecord>(); 208 209 // List of all currently registered display adapters. 210 private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>(); 211 212 // List of all currently connected display devices. 213 private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>(); 214 215 // List of all logical displays indexed by logical display id. 216 private final SparseArray<LogicalDisplay> mLogicalDisplays = 217 new SparseArray<LogicalDisplay>(); 218 private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1; 219 220 // List of all display transaction listeners. 221 private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners = 222 new CopyOnWriteArrayList<DisplayTransactionListener>(); 223 224 // Display power controller. 225 private DisplayPowerController mDisplayPowerController; 226 227 // The overall display state, independent of changes that might influence one 228 // display or another in particular. 229 private int mGlobalDisplayState = Display.STATE_ON; 230 231 // The overall display brightness. 232 // For now, this only applies to the built-in display but we may split it up eventually. 233 private int mGlobalDisplayBrightness = PowerManager.BRIGHTNESS_DEFAULT; 234 235 // Set to true when there are pending display changes that have yet to be applied 236 // to the surface flinger state. 237 private boolean mPendingTraversal; 238 239 // The Wifi display adapter, or null if not registered. 240 private WifiDisplayAdapter mWifiDisplayAdapter; 241 242 // The number of active wifi display scan requests. 243 private int mWifiDisplayScanRequestCount; 244 245 // The virtual display adapter, or null if not registered. 246 private VirtualDisplayAdapter mVirtualDisplayAdapter; 247 248 // The User ID of the current user 249 private @UserIdInt int mCurrentUserId; 250 251 // The stable device screen height and width. These are not tied to a specific display, even 252 // the default display, because they need to be stable over the course of the device's entire 253 // life, even if the default display changes (e.g. a new monitor is plugged into a PC-like 254 // device). 255 private Point mStableDisplaySize = new Point(); 256 257 // Whether the system has finished booting or not. 258 private boolean mSystemReady; 259 260 // The top inset of the default display. 261 // This gets persisted so that the boot animation knows how to transition from the display's 262 // full size to the size configured by the user. Right now we only persist and animate the top 263 // inset, but theoretically we could do it for all of them. 264 private int mDefaultDisplayTopInset; 265 266 // Viewports of the default display and the display that should receive touch 267 // input from an external source. Used by the input system. 268 @GuardedBy("mSyncRoot") 269 private final ArrayList<DisplayViewport> mViewports = new ArrayList<>(); 270 271 // Persistent data store for all internal settings maintained by the display manager service. 272 private final PersistentDataStore mPersistentDataStore = new PersistentDataStore(); 273 274 // Temporary callback list, used when sending display events to applications. 275 // May be used outside of the lock but only on the handler thread. 276 private final ArrayList<CallbackRecord> mTempCallbacks = new ArrayList<CallbackRecord>(); 277 278 // Temporary display info, used for comparing display configurations. 279 private final DisplayInfo mTempDisplayInfo = new DisplayInfo(); 280 281 // Temporary viewports, used when sending new viewport information to the 282 // input system. May be used outside of the lock but only on the handler thread. 283 private final ArrayList<DisplayViewport> mTempViewports = new ArrayList<>(); 284 285 // The default color mode for default displays. Overrides the usual 286 // Display.Display.COLOR_MODE_DEFAULT for displays with the 287 // DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY flag set. 288 private final int mDefaultDisplayDefaultColorMode; 289 290 // Temporary list of deferred work to perform when setting the display state. 291 // Only used by requestDisplayState. The field is self-synchronized and only 292 // intended for use inside of the requestGlobalDisplayStateInternal function. 293 private final ArrayList<Runnable> mTempDisplayStateWorkQueue = new ArrayList<Runnable>(); 294 295 // Lists of UIDs that are present on the displays. Maps displayId -> array of UIDs. 296 private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>(); 297 298 private final Injector mInjector; 299 300 // The minimum brightness curve, which guarantess that any brightness curve that dips below it 301 // is rejected by the system. 302 private final Curve mMinimumBrightnessCurve; 303 private final Spline mMinimumBrightnessSpline; 304 private final ColorSpace mWideColorSpace; 305 DisplayManagerService(Context context)306 public DisplayManagerService(Context context) { 307 this(context, new Injector()); 308 } 309 310 @VisibleForTesting DisplayManagerService(Context context, Injector injector)311 DisplayManagerService(Context context, Injector injector) { 312 super(context); 313 mInjector = injector; 314 mContext = context; 315 mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper()); 316 mUiHandler = UiThread.getHandler(); 317 mDisplayAdapterListener = new DisplayAdapterListener(); 318 mDisplayModeDirector = new DisplayModeDirector(context, mHandler); 319 mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false); 320 Resources resources = mContext.getResources(); 321 mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger( 322 com.android.internal.R.integer.config_defaultDisplayDefaultColorMode); 323 mDefaultDisplayTopInset = SystemProperties.getInt(PROP_DEFAULT_DISPLAY_TOP_INSET, -1); 324 float[] lux = getFloatArray(resources.obtainTypedArray( 325 com.android.internal.R.array.config_minimumBrightnessCurveLux)); 326 float[] nits = getFloatArray(resources.obtainTypedArray( 327 com.android.internal.R.array.config_minimumBrightnessCurveNits)); 328 mMinimumBrightnessCurve = new Curve(lux, nits); 329 mMinimumBrightnessSpline = Spline.createSpline(lux, nits); 330 331 PowerManager pm = mContext.getSystemService(PowerManager.class); 332 mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting(); 333 mCurrentUserId = UserHandle.USER_SYSTEM; 334 ColorSpace[] colorSpaces = SurfaceControl.getCompositionColorSpaces(); 335 mWideColorSpace = colorSpaces[1]; 336 337 mSystemReady = false; 338 } 339 setupSchedulerPolicies()340 public void setupSchedulerPolicies() { 341 // android.display and android.anim is critical to user experience and we should make sure 342 // it is not in the default foregroup groups, add it to top-app to make sure it uses all 343 // the cores and scheduling settings for top-app when it runs. 344 Process.setThreadGroupAndCpuset(DisplayThread.get().getThreadId(), 345 Process.THREAD_GROUP_TOP_APP); 346 Process.setThreadGroupAndCpuset(AnimationThread.get().getThreadId(), 347 Process.THREAD_GROUP_TOP_APP); 348 Process.setThreadGroupAndCpuset(SurfaceAnimationThread.get().getThreadId(), 349 Process.THREAD_GROUP_TOP_APP); 350 } 351 352 @Override onStart()353 public void onStart() { 354 // We need to pre-load the persistent data store so it's ready before the default display 355 // adapter is up so that we have it's configuration. We could load it lazily, but since 356 // we're going to have to read it in eventually we may as well do it here rather than after 357 // we've waited for the display to register itself with us. 358 synchronized (mSyncRoot) { 359 mPersistentDataStore.loadIfNeeded(); 360 loadStableDisplayValuesLocked(); 361 } 362 mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS); 363 364 publishBinderService(Context.DISPLAY_SERVICE, new BinderService(), 365 true /*allowIsolated*/); 366 publishLocalService(DisplayManagerInternal.class, new LocalService()); 367 } 368 369 @Override onBootPhase(int phase)370 public void onBootPhase(int phase) { 371 if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) { 372 synchronized (mSyncRoot) { 373 long timeout = SystemClock.uptimeMillis() 374 + mInjector.getDefaultDisplayDelayTimeout(); 375 while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null || 376 mVirtualDisplayAdapter == null) { 377 long delay = timeout - SystemClock.uptimeMillis(); 378 if (delay <= 0) { 379 throw new RuntimeException("Timeout waiting for default display " 380 + "to be initialized. DefaultDisplay=" 381 + mLogicalDisplays.get(Display.DEFAULT_DISPLAY) 382 + ", mVirtualDisplayAdapter=" + mVirtualDisplayAdapter); 383 } 384 if (DEBUG) { 385 Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay); 386 } 387 try { 388 mSyncRoot.wait(delay); 389 } catch (InterruptedException ex) { 390 } 391 } 392 } 393 } 394 } 395 396 @Override onSwitchUser(@serIdInt int newUserId)397 public void onSwitchUser(@UserIdInt int newUserId) { 398 final int userSerial = getUserManager().getUserSerialNumber(newUserId); 399 synchronized (mSyncRoot) { 400 if (mCurrentUserId != newUserId) { 401 mCurrentUserId = newUserId; 402 BrightnessConfiguration config = 403 mPersistentDataStore.getBrightnessConfiguration(userSerial); 404 mDisplayPowerController.setBrightnessConfiguration(config); 405 } 406 mDisplayPowerController.onSwitchUser(newUserId); 407 } 408 } 409 410 // TODO: Use dependencies or a boot phase windowManagerAndInputReady()411 public void windowManagerAndInputReady() { 412 synchronized (mSyncRoot) { 413 mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class); 414 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); 415 scheduleTraversalLocked(false); 416 } 417 } 418 419 /** 420 * Called when the system is ready to go. 421 */ systemReady(boolean safeMode, boolean onlyCore)422 public void systemReady(boolean safeMode, boolean onlyCore) { 423 synchronized (mSyncRoot) { 424 mSafeMode = safeMode; 425 mOnlyCore = onlyCore; 426 mSystemReady = true; 427 // Just in case the top inset changed before the system was ready. At this point, any 428 // relevant configuration should be in place. 429 recordTopInsetLocked(mLogicalDisplays.get(Display.DEFAULT_DISPLAY)); 430 } 431 432 mDisplayModeDirector.setListener(new AllowedDisplayModeObserver()); 433 mDisplayModeDirector.start(); 434 435 mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS); 436 } 437 438 @VisibleForTesting getDisplayHandler()439 Handler getDisplayHandler() { 440 return mHandler; 441 } 442 loadStableDisplayValuesLocked()443 private void loadStableDisplayValuesLocked() { 444 final Point size = mPersistentDataStore.getStableDisplaySize(); 445 if (size.x > 0 && size.y > 0) { 446 // Just set these values directly so we don't write the display persistent data again 447 // unnecessarily 448 mStableDisplaySize.set(size.x, size.y); 449 } else { 450 final Resources res = mContext.getResources(); 451 final int width = res.getInteger( 452 com.android.internal.R.integer.config_stableDeviceDisplayWidth); 453 final int height = res.getInteger( 454 com.android.internal.R.integer.config_stableDeviceDisplayHeight); 455 if (width > 0 && height > 0) { 456 setStableDisplaySizeLocked(width, height); 457 } 458 } 459 } 460 getStableDisplaySizeInternal()461 private Point getStableDisplaySizeInternal() { 462 Point r = new Point(); 463 synchronized (mSyncRoot) { 464 if (mStableDisplaySize.x > 0 && mStableDisplaySize.y > 0) { 465 r.set(mStableDisplaySize.x, mStableDisplaySize.y); 466 } 467 } 468 return r; 469 } 470 registerDisplayTransactionListenerInternal( DisplayTransactionListener listener)471 private void registerDisplayTransactionListenerInternal( 472 DisplayTransactionListener listener) { 473 // List is self-synchronized copy-on-write. 474 mDisplayTransactionListeners.add(listener); 475 } 476 unregisterDisplayTransactionListenerInternal( DisplayTransactionListener listener)477 private void unregisterDisplayTransactionListenerInternal( 478 DisplayTransactionListener listener) { 479 // List is self-synchronized copy-on-write. 480 mDisplayTransactionListeners.remove(listener); 481 } 482 setDisplayInfoOverrideFromWindowManagerInternal( int displayId, DisplayInfo info)483 private void setDisplayInfoOverrideFromWindowManagerInternal( 484 int displayId, DisplayInfo info) { 485 synchronized (mSyncRoot) { 486 LogicalDisplay display = mLogicalDisplays.get(displayId); 487 if (display != null) { 488 if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) { 489 handleLogicalDisplayChanged(displayId, display); 490 scheduleTraversalLocked(false); 491 } 492 } 493 } 494 } 495 496 /** 497 * @see DisplayManagerInternal#getNonOverrideDisplayInfo(int, DisplayInfo) 498 */ getNonOverrideDisplayInfoInternal(int displayId, DisplayInfo outInfo)499 private void getNonOverrideDisplayInfoInternal(int displayId, DisplayInfo outInfo) { 500 synchronized (mSyncRoot) { 501 final LogicalDisplay display = mLogicalDisplays.get(displayId); 502 if (display != null) { 503 display.getNonOverrideDisplayInfoLocked(outInfo); 504 } 505 } 506 } 507 508 @VisibleForTesting performTraversalInternal(SurfaceControl.Transaction t)509 void performTraversalInternal(SurfaceControl.Transaction t) { 510 synchronized (mSyncRoot) { 511 if (!mPendingTraversal) { 512 return; 513 } 514 mPendingTraversal = false; 515 516 performTraversalLocked(t); 517 } 518 519 // List is self-synchronized copy-on-write. 520 for (DisplayTransactionListener listener : mDisplayTransactionListeners) { 521 listener.onDisplayTransaction(t); 522 } 523 } 524 requestGlobalDisplayStateInternal(int state, int brightness)525 private void requestGlobalDisplayStateInternal(int state, int brightness) { 526 if (state == Display.STATE_UNKNOWN) { 527 state = Display.STATE_ON; 528 } 529 if (state == Display.STATE_OFF) { 530 brightness = PowerManager.BRIGHTNESS_OFF; 531 } else if (brightness < 0) { 532 brightness = PowerManager.BRIGHTNESS_DEFAULT; 533 } else if (brightness > PowerManager.BRIGHTNESS_ON) { 534 brightness = PowerManager.BRIGHTNESS_ON; 535 } 536 537 synchronized (mTempDisplayStateWorkQueue) { 538 try { 539 // Update the display state within the lock. 540 // Note that we do not need to schedule traversals here although it 541 // may happen as a side-effect of displays changing state. 542 synchronized (mSyncRoot) { 543 if (mGlobalDisplayState == state 544 && mGlobalDisplayBrightness == brightness) { 545 return; // no change 546 } 547 548 Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState(" 549 + Display.stateToString(state) 550 + ", brightness=" + brightness + ")"); 551 mGlobalDisplayState = state; 552 mGlobalDisplayBrightness = brightness; 553 applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue); 554 } 555 556 // Setting the display power state can take hundreds of milliseconds 557 // to complete so we defer the most expensive part of the work until 558 // after we have exited the critical section to avoid blocking other 559 // threads for a long time. 560 for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) { 561 mTempDisplayStateWorkQueue.get(i).run(); 562 } 563 Trace.traceEnd(Trace.TRACE_TAG_POWER); 564 } finally { 565 mTempDisplayStateWorkQueue.clear(); 566 } 567 } 568 } 569 getDisplayInfoInternal(int displayId, int callingUid)570 private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) { 571 synchronized (mSyncRoot) { 572 LogicalDisplay display = mLogicalDisplays.get(displayId); 573 if (display != null) { 574 DisplayInfo info = display.getDisplayInfoLocked(); 575 if (info.hasAccess(callingUid) 576 || isUidPresentOnDisplayInternal(callingUid, displayId)) { 577 return info; 578 } 579 } 580 return null; 581 } 582 } 583 getDisplayIdsInternal(int callingUid)584 private int[] getDisplayIdsInternal(int callingUid) { 585 synchronized (mSyncRoot) { 586 final int count = mLogicalDisplays.size(); 587 int[] displayIds = new int[count]; 588 int n = 0; 589 for (int i = 0; i < count; i++) { 590 LogicalDisplay display = mLogicalDisplays.valueAt(i); 591 DisplayInfo info = display.getDisplayInfoLocked(); 592 if (info.hasAccess(callingUid)) { 593 displayIds[n++] = mLogicalDisplays.keyAt(i); 594 } 595 } 596 if (n != count) { 597 displayIds = Arrays.copyOfRange(displayIds, 0, n); 598 } 599 return displayIds; 600 } 601 } 602 registerCallbackInternal(IDisplayManagerCallback callback, int callingPid)603 private void registerCallbackInternal(IDisplayManagerCallback callback, int callingPid) { 604 synchronized (mSyncRoot) { 605 if (mCallbacks.get(callingPid) != null) { 606 throw new SecurityException("The calling process has already " 607 + "registered an IDisplayManagerCallback."); 608 } 609 610 CallbackRecord record = new CallbackRecord(callingPid, callback); 611 try { 612 IBinder binder = callback.asBinder(); 613 binder.linkToDeath(record, 0); 614 } catch (RemoteException ex) { 615 // give up 616 throw new RuntimeException(ex); 617 } 618 619 mCallbacks.put(callingPid, record); 620 } 621 } 622 onCallbackDied(CallbackRecord record)623 private void onCallbackDied(CallbackRecord record) { 624 synchronized (mSyncRoot) { 625 mCallbacks.remove(record.mPid); 626 stopWifiDisplayScanLocked(record); 627 } 628 } 629 startWifiDisplayScanInternal(int callingPid)630 private void startWifiDisplayScanInternal(int callingPid) { 631 synchronized (mSyncRoot) { 632 CallbackRecord record = mCallbacks.get(callingPid); 633 if (record == null) { 634 throw new IllegalStateException("The calling process has not " 635 + "registered an IDisplayManagerCallback."); 636 } 637 startWifiDisplayScanLocked(record); 638 } 639 } 640 startWifiDisplayScanLocked(CallbackRecord record)641 private void startWifiDisplayScanLocked(CallbackRecord record) { 642 if (!record.mWifiDisplayScanRequested) { 643 record.mWifiDisplayScanRequested = true; 644 if (mWifiDisplayScanRequestCount++ == 0) { 645 if (mWifiDisplayAdapter != null) { 646 mWifiDisplayAdapter.requestStartScanLocked(); 647 } 648 } 649 } 650 } 651 stopWifiDisplayScanInternal(int callingPid)652 private void stopWifiDisplayScanInternal(int callingPid) { 653 synchronized (mSyncRoot) { 654 CallbackRecord record = mCallbacks.get(callingPid); 655 if (record == null) { 656 throw new IllegalStateException("The calling process has not " 657 + "registered an IDisplayManagerCallback."); 658 } 659 stopWifiDisplayScanLocked(record); 660 } 661 } 662 stopWifiDisplayScanLocked(CallbackRecord record)663 private void stopWifiDisplayScanLocked(CallbackRecord record) { 664 if (record.mWifiDisplayScanRequested) { 665 record.mWifiDisplayScanRequested = false; 666 if (--mWifiDisplayScanRequestCount == 0) { 667 if (mWifiDisplayAdapter != null) { 668 mWifiDisplayAdapter.requestStopScanLocked(); 669 } 670 } else if (mWifiDisplayScanRequestCount < 0) { 671 Slog.wtf(TAG, "mWifiDisplayScanRequestCount became negative: " 672 + mWifiDisplayScanRequestCount); 673 mWifiDisplayScanRequestCount = 0; 674 } 675 } 676 } 677 connectWifiDisplayInternal(String address)678 private void connectWifiDisplayInternal(String address) { 679 synchronized (mSyncRoot) { 680 if (mWifiDisplayAdapter != null) { 681 mWifiDisplayAdapter.requestConnectLocked(address); 682 } 683 } 684 } 685 pauseWifiDisplayInternal()686 private void pauseWifiDisplayInternal() { 687 synchronized (mSyncRoot) { 688 if (mWifiDisplayAdapter != null) { 689 mWifiDisplayAdapter.requestPauseLocked(); 690 } 691 } 692 } 693 resumeWifiDisplayInternal()694 private void resumeWifiDisplayInternal() { 695 synchronized (mSyncRoot) { 696 if (mWifiDisplayAdapter != null) { 697 mWifiDisplayAdapter.requestResumeLocked(); 698 } 699 } 700 } 701 disconnectWifiDisplayInternal()702 private void disconnectWifiDisplayInternal() { 703 synchronized (mSyncRoot) { 704 if (mWifiDisplayAdapter != null) { 705 mWifiDisplayAdapter.requestDisconnectLocked(); 706 } 707 } 708 } 709 renameWifiDisplayInternal(String address, String alias)710 private void renameWifiDisplayInternal(String address, String alias) { 711 synchronized (mSyncRoot) { 712 if (mWifiDisplayAdapter != null) { 713 mWifiDisplayAdapter.requestRenameLocked(address, alias); 714 } 715 } 716 } 717 forgetWifiDisplayInternal(String address)718 private void forgetWifiDisplayInternal(String address) { 719 synchronized (mSyncRoot) { 720 if (mWifiDisplayAdapter != null) { 721 mWifiDisplayAdapter.requestForgetLocked(address); 722 } 723 } 724 } 725 getWifiDisplayStatusInternal()726 private WifiDisplayStatus getWifiDisplayStatusInternal() { 727 synchronized (mSyncRoot) { 728 if (mWifiDisplayAdapter != null) { 729 return mWifiDisplayAdapter.getWifiDisplayStatusLocked(); 730 } 731 return new WifiDisplayStatus(); 732 } 733 } 734 requestColorModeInternal(int displayId, int colorMode)735 private void requestColorModeInternal(int displayId, int colorMode) { 736 synchronized (mSyncRoot) { 737 LogicalDisplay display = mLogicalDisplays.get(displayId); 738 if (display != null && 739 display.getRequestedColorModeLocked() != colorMode) { 740 display.setRequestedColorModeLocked(colorMode); 741 scheduleTraversalLocked(false); 742 } 743 } 744 } 745 createVirtualDisplayInternal(IVirtualDisplayCallback callback, IMediaProjection projection, int callingUid, String packageName, String name, int width, int height, int densityDpi, Surface surface, int flags, String uniqueId)746 private int createVirtualDisplayInternal(IVirtualDisplayCallback callback, 747 IMediaProjection projection, int callingUid, String packageName, String name, int width, 748 int height, int densityDpi, Surface surface, int flags, String uniqueId) { 749 synchronized (mSyncRoot) { 750 if (mVirtualDisplayAdapter == null) { 751 Slog.w(TAG, "Rejecting request to create private virtual display " 752 + "because the virtual display adapter is not available."); 753 return -1; 754 } 755 756 DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked( 757 callback, projection, callingUid, packageName, name, width, height, densityDpi, 758 surface, flags, uniqueId); 759 if (device == null) { 760 return -1; 761 } 762 763 handleDisplayDeviceAddedLocked(device); 764 LogicalDisplay display = findLogicalDisplayForDeviceLocked(device); 765 if (display != null) { 766 return display.getDisplayIdLocked(); 767 } 768 769 // Something weird happened and the logical display was not created. 770 Slog.w(TAG, "Rejecting request to create virtual display " 771 + "because the logical display was not created."); 772 mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callback.asBinder()); 773 handleDisplayDeviceRemovedLocked(device); 774 } 775 return -1; 776 } 777 resizeVirtualDisplayInternal(IBinder appToken, int width, int height, int densityDpi)778 private void resizeVirtualDisplayInternal(IBinder appToken, 779 int width, int height, int densityDpi) { 780 synchronized (mSyncRoot) { 781 if (mVirtualDisplayAdapter == null) { 782 return; 783 } 784 785 mVirtualDisplayAdapter.resizeVirtualDisplayLocked(appToken, width, height, densityDpi); 786 } 787 } 788 setVirtualDisplaySurfaceInternal(IBinder appToken, Surface surface)789 private void setVirtualDisplaySurfaceInternal(IBinder appToken, Surface surface) { 790 synchronized (mSyncRoot) { 791 if (mVirtualDisplayAdapter == null) { 792 return; 793 } 794 795 mVirtualDisplayAdapter.setVirtualDisplaySurfaceLocked(appToken, surface); 796 } 797 } 798 releaseVirtualDisplayInternal(IBinder appToken)799 private void releaseVirtualDisplayInternal(IBinder appToken) { 800 synchronized (mSyncRoot) { 801 if (mVirtualDisplayAdapter == null) { 802 return; 803 } 804 805 DisplayDevice device = 806 mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken); 807 if (device != null) { 808 handleDisplayDeviceRemovedLocked(device); 809 } 810 } 811 } 812 setVirtualDisplayStateInternal(IBinder appToken, boolean isOn)813 private void setVirtualDisplayStateInternal(IBinder appToken, boolean isOn) { 814 synchronized (mSyncRoot) { 815 if (mVirtualDisplayAdapter == null) { 816 return; 817 } 818 819 mVirtualDisplayAdapter.setVirtualDisplayStateLocked(appToken, isOn); 820 } 821 } 822 registerDefaultDisplayAdapters()823 private void registerDefaultDisplayAdapters() { 824 // Register default display adapters. 825 synchronized (mSyncRoot) { 826 // main display adapter 827 registerDisplayAdapterLocked(new LocalDisplayAdapter( 828 mSyncRoot, mContext, mHandler, mDisplayAdapterListener)); 829 830 // Standalone VR devices rely on a virtual display as their primary display for 831 // 2D UI. We register virtual display adapter along side the main display adapter 832 // here so that it is ready by the time the system sends the home Intent for 833 // early apps like SetupWizard/Launcher. In particular, SUW is displayed using 834 // the virtual display inside VR before any VR-specific apps even run. 835 mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext, 836 mHandler, mDisplayAdapterListener); 837 if (mVirtualDisplayAdapter != null) { 838 registerDisplayAdapterLocked(mVirtualDisplayAdapter); 839 } 840 } 841 } 842 registerAdditionalDisplayAdapters()843 private void registerAdditionalDisplayAdapters() { 844 synchronized (mSyncRoot) { 845 if (shouldRegisterNonEssentialDisplayAdaptersLocked()) { 846 registerOverlayDisplayAdapterLocked(); 847 registerWifiDisplayAdapterLocked(); 848 } 849 } 850 } 851 registerOverlayDisplayAdapterLocked()852 private void registerOverlayDisplayAdapterLocked() { 853 registerDisplayAdapterLocked(new OverlayDisplayAdapter( 854 mSyncRoot, mContext, mHandler, mDisplayAdapterListener, mUiHandler)); 855 } 856 registerWifiDisplayAdapterLocked()857 private void registerWifiDisplayAdapterLocked() { 858 if (mContext.getResources().getBoolean( 859 com.android.internal.R.bool.config_enableWifiDisplay) 860 || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) { 861 mWifiDisplayAdapter = new WifiDisplayAdapter( 862 mSyncRoot, mContext, mHandler, mDisplayAdapterListener, 863 mPersistentDataStore); 864 registerDisplayAdapterLocked(mWifiDisplayAdapter); 865 } 866 } 867 shouldRegisterNonEssentialDisplayAdaptersLocked()868 private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() { 869 // In safe mode, we disable non-essential display adapters to give the user 870 // an opportunity to fix broken settings or other problems that might affect 871 // system stability. 872 // In only-core mode, we disable non-essential display adapters to minimize 873 // the number of dependencies that are started while in this mode and to 874 // prevent problems that might occur due to the device being encrypted. 875 return !mSafeMode && !mOnlyCore; 876 } 877 registerDisplayAdapterLocked(DisplayAdapter adapter)878 private void registerDisplayAdapterLocked(DisplayAdapter adapter) { 879 mDisplayAdapters.add(adapter); 880 adapter.registerLocked(); 881 } 882 handleDisplayDeviceAdded(DisplayDevice device)883 private void handleDisplayDeviceAdded(DisplayDevice device) { 884 synchronized (mSyncRoot) { 885 handleDisplayDeviceAddedLocked(device); 886 } 887 } 888 handleDisplayDeviceAddedLocked(DisplayDevice device)889 private void handleDisplayDeviceAddedLocked(DisplayDevice device) { 890 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 891 if (mDisplayDevices.contains(device)) { 892 Slog.w(TAG, "Attempted to add already added display device: " + info); 893 return; 894 } 895 896 Slog.i(TAG, "Display device added: " + info); 897 device.mDebugLastLoggedDeviceInfo = info; 898 899 mDisplayDevices.add(device); 900 LogicalDisplay display = addLogicalDisplayLocked(device); 901 Runnable work = updateDisplayStateLocked(device); 902 if (work != null) { 903 work.run(); 904 } 905 scheduleTraversalLocked(false); 906 } 907 handleDisplayDeviceChanged(DisplayDevice device)908 private void handleDisplayDeviceChanged(DisplayDevice device) { 909 synchronized (mSyncRoot) { 910 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 911 if (!mDisplayDevices.contains(device)) { 912 Slog.w(TAG, "Attempted to change non-existent display device: " + info); 913 return; 914 } 915 916 int diff = device.mDebugLastLoggedDeviceInfo.diff(info); 917 if (diff == DisplayDeviceInfo.DIFF_STATE) { 918 Slog.i(TAG, "Display device changed state: \"" + info.name 919 + "\", " + Display.stateToString(info.state)); 920 } else if (diff != 0) { 921 Slog.i(TAG, "Display device changed: " + info); 922 } 923 if ((diff & DisplayDeviceInfo.DIFF_COLOR_MODE) != 0) { 924 try { 925 mPersistentDataStore.setColorMode(device, info.colorMode); 926 } finally { 927 mPersistentDataStore.saveIfNeeded(); 928 } 929 } 930 device.mDebugLastLoggedDeviceInfo = info; 931 932 device.applyPendingDisplayDeviceInfoChangesLocked(); 933 if (updateLogicalDisplaysLocked()) { 934 scheduleTraversalLocked(false); 935 } 936 } 937 } 938 handleDisplayDeviceRemoved(DisplayDevice device)939 private void handleDisplayDeviceRemoved(DisplayDevice device) { 940 synchronized (mSyncRoot) { 941 handleDisplayDeviceRemovedLocked(device); 942 } 943 } 944 handleDisplayDeviceRemovedLocked(DisplayDevice device)945 private void handleDisplayDeviceRemovedLocked(DisplayDevice device) { 946 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 947 if (!mDisplayDevices.remove(device)) { 948 Slog.w(TAG, "Attempted to remove non-existent display device: " + info); 949 return; 950 } 951 952 Slog.i(TAG, "Display device removed: " + info); 953 device.mDebugLastLoggedDeviceInfo = info; 954 955 updateLogicalDisplaysLocked(); 956 scheduleTraversalLocked(false); 957 } 958 handleLogicalDisplayChanged(int displayId, @NonNull LogicalDisplay display)959 private void handleLogicalDisplayChanged(int displayId, @NonNull LogicalDisplay display) { 960 if (displayId == Display.DEFAULT_DISPLAY) { 961 recordTopInsetLocked(display); 962 } 963 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED); 964 } 965 applyGlobalDisplayStateLocked(List<Runnable> workQueue)966 private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) { 967 final int count = mDisplayDevices.size(); 968 for (int i = 0; i < count; i++) { 969 DisplayDevice device = mDisplayDevices.get(i); 970 Runnable runnable = updateDisplayStateLocked(device); 971 if (runnable != null) { 972 workQueue.add(runnable); 973 } 974 } 975 } 976 updateDisplayStateLocked(DisplayDevice device)977 private Runnable updateDisplayStateLocked(DisplayDevice device) { 978 // Blank or unblank the display immediately to match the state requested 979 // by the display power controller (if known). 980 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 981 if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) { 982 return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness); 983 } 984 return null; 985 } 986 987 // Adds a new logical display based on the given display device. 988 // Sends notifications if needed. addLogicalDisplayLocked(DisplayDevice device)989 private LogicalDisplay addLogicalDisplayLocked(DisplayDevice device) { 990 DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked(); 991 boolean isDefault = (deviceInfo.flags 992 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0; 993 if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) { 994 Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo); 995 isDefault = false; 996 } 997 998 if (!isDefault && mSingleDisplayDemoMode) { 999 Slog.i(TAG, "Not creating a logical display for a secondary display " 1000 + " because single display demo mode is enabled: " + deviceInfo); 1001 return null; 1002 } 1003 1004 final int displayId = assignDisplayIdLocked(isDefault); 1005 final int layerStack = assignLayerStackLocked(displayId); 1006 1007 LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device); 1008 display.updateLocked(mDisplayDevices); 1009 if (!display.isValidLocked()) { 1010 // This should never happen currently. 1011 Slog.w(TAG, "Ignoring display device because the logical display " 1012 + "created from it was not considered valid: " + deviceInfo); 1013 return null; 1014 } 1015 1016 configureColorModeLocked(display, device); 1017 if (isDefault) { 1018 recordStableDisplayStatsIfNeededLocked(display); 1019 recordTopInsetLocked(display); 1020 } 1021 1022 mLogicalDisplays.put(displayId, display); 1023 1024 // Wake up waitForDefaultDisplay. 1025 if (isDefault) { 1026 mSyncRoot.notifyAll(); 1027 } 1028 1029 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED); 1030 return display; 1031 } 1032 assignDisplayIdLocked(boolean isDefault)1033 private int assignDisplayIdLocked(boolean isDefault) { 1034 return isDefault ? Display.DEFAULT_DISPLAY : mNextNonDefaultDisplayId++; 1035 } 1036 assignLayerStackLocked(int displayId)1037 private int assignLayerStackLocked(int displayId) { 1038 // Currently layer stacks and display ids are the same. 1039 // This need not be the case. 1040 return displayId; 1041 } 1042 configureColorModeLocked(LogicalDisplay display, DisplayDevice device)1043 private void configureColorModeLocked(LogicalDisplay display, DisplayDevice device) { 1044 if (display.getPrimaryDisplayDeviceLocked() == device) { 1045 int colorMode = mPersistentDataStore.getColorMode(device); 1046 if (colorMode == Display.COLOR_MODE_INVALID) { 1047 if ((device.getDisplayDeviceInfoLocked().flags 1048 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) { 1049 colorMode = mDefaultDisplayDefaultColorMode; 1050 } else { 1051 colorMode = Display.COLOR_MODE_DEFAULT; 1052 } 1053 } 1054 display.setRequestedColorModeLocked(colorMode); 1055 } 1056 } 1057 1058 // If we've never recorded stable device stats for this device before and they aren't 1059 // explicitly configured, go ahead and record the stable device stats now based on the status 1060 // of the default display at first boot. recordStableDisplayStatsIfNeededLocked(LogicalDisplay d)1061 private void recordStableDisplayStatsIfNeededLocked(LogicalDisplay d) { 1062 if (mStableDisplaySize.x <= 0 && mStableDisplaySize.y <= 0) { 1063 DisplayInfo info = d.getDisplayInfoLocked(); 1064 setStableDisplaySizeLocked(info.getNaturalWidth(), info.getNaturalHeight()); 1065 } 1066 } 1067 recordTopInsetLocked(@ullable LogicalDisplay d)1068 private void recordTopInsetLocked(@Nullable LogicalDisplay d) { 1069 // We must only persist the inset after boot has completed, otherwise we will end up 1070 // overwriting the persisted value before the masking flag has been loaded from the 1071 // resource overlay. 1072 if (!mSystemReady || d == null) { 1073 return; 1074 } 1075 int topInset = d.getInsets().top; 1076 if (topInset == mDefaultDisplayTopInset) { 1077 return; 1078 } 1079 mDefaultDisplayTopInset = topInset; 1080 SystemProperties.set(PROP_DEFAULT_DISPLAY_TOP_INSET, Integer.toString(topInset)); 1081 } 1082 setStableDisplaySizeLocked(int width, int height)1083 private void setStableDisplaySizeLocked(int width, int height) { 1084 mStableDisplaySize = new Point(width, height); 1085 try { 1086 mPersistentDataStore.setStableDisplaySize(mStableDisplaySize); 1087 } finally { 1088 mPersistentDataStore.saveIfNeeded(); 1089 } 1090 } 1091 1092 @VisibleForTesting getMinimumBrightnessCurveInternal()1093 Curve getMinimumBrightnessCurveInternal() { 1094 return mMinimumBrightnessCurve; 1095 } 1096 getPreferredWideGamutColorSpaceIdInternal()1097 int getPreferredWideGamutColorSpaceIdInternal() { 1098 return mWideColorSpace.getId(); 1099 } 1100 setBrightnessConfigurationForUserInternal( @ullable BrightnessConfiguration c, @UserIdInt int userId, @Nullable String packageName)1101 private void setBrightnessConfigurationForUserInternal( 1102 @Nullable BrightnessConfiguration c, @UserIdInt int userId, 1103 @Nullable String packageName) { 1104 validateBrightnessConfiguration(c); 1105 final int userSerial = getUserManager().getUserSerialNumber(userId); 1106 synchronized (mSyncRoot) { 1107 try { 1108 mPersistentDataStore.setBrightnessConfigurationForUser(c, userSerial, 1109 packageName); 1110 } finally { 1111 mPersistentDataStore.saveIfNeeded(); 1112 } 1113 if (userId == mCurrentUserId) { 1114 mDisplayPowerController.setBrightnessConfiguration(c); 1115 } 1116 } 1117 } 1118 1119 @VisibleForTesting validateBrightnessConfiguration(BrightnessConfiguration config)1120 void validateBrightnessConfiguration(BrightnessConfiguration config) { 1121 if (config == null) { 1122 return; 1123 } 1124 if (isBrightnessConfigurationTooDark(config)) { 1125 throw new IllegalArgumentException("brightness curve is too dark"); 1126 } 1127 } 1128 isBrightnessConfigurationTooDark(BrightnessConfiguration config)1129 private boolean isBrightnessConfigurationTooDark(BrightnessConfiguration config) { 1130 Pair<float[], float[]> curve = config.getCurve(); 1131 float[] lux = curve.first; 1132 float[] nits = curve.second; 1133 for (int i = 0; i < lux.length; i++) { 1134 if (nits[i] < mMinimumBrightnessSpline.interpolate(lux[i])) { 1135 return true; 1136 } 1137 } 1138 return false; 1139 } 1140 loadBrightnessConfiguration()1141 private void loadBrightnessConfiguration() { 1142 synchronized (mSyncRoot) { 1143 final int userSerial = getUserManager().getUserSerialNumber(mCurrentUserId); 1144 BrightnessConfiguration config = 1145 mPersistentDataStore.getBrightnessConfiguration(userSerial); 1146 mDisplayPowerController.setBrightnessConfiguration(config); 1147 } 1148 } 1149 1150 // Updates all existing logical displays given the current set of display devices. 1151 // Removes invalid logical displays. 1152 // Sends notifications if needed. updateLogicalDisplaysLocked()1153 private boolean updateLogicalDisplaysLocked() { 1154 boolean changed = false; 1155 for (int i = mLogicalDisplays.size(); i-- > 0; ) { 1156 final int displayId = mLogicalDisplays.keyAt(i); 1157 LogicalDisplay display = mLogicalDisplays.valueAt(i); 1158 1159 mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked()); 1160 display.updateLocked(mDisplayDevices); 1161 if (!display.isValidLocked()) { 1162 mLogicalDisplays.removeAt(i); 1163 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED); 1164 changed = true; 1165 } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) { 1166 handleLogicalDisplayChanged(displayId, display); 1167 changed = true; 1168 } 1169 } 1170 return changed; 1171 } 1172 performTraversalLocked(SurfaceControl.Transaction t)1173 private void performTraversalLocked(SurfaceControl.Transaction t) { 1174 // Clear all viewports before configuring displays so that we can keep 1175 // track of which ones we have configured. 1176 clearViewportsLocked(); 1177 1178 // Configure each display device. 1179 final int count = mDisplayDevices.size(); 1180 for (int i = 0; i < count; i++) { 1181 DisplayDevice device = mDisplayDevices.get(i); 1182 configureDisplayLocked(t, device); 1183 device.performTraversalLocked(t); 1184 } 1185 1186 // Tell the input system about these new viewports. 1187 if (mInputManagerInternal != null) { 1188 mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT); 1189 } 1190 } 1191 setDisplayPropertiesInternal(int displayId, boolean hasContent, float requestedRefreshRate, int requestedModeId, boolean inTraversal)1192 private void setDisplayPropertiesInternal(int displayId, boolean hasContent, 1193 float requestedRefreshRate, int requestedModeId, boolean inTraversal) { 1194 synchronized (mSyncRoot) { 1195 LogicalDisplay display = mLogicalDisplays.get(displayId); 1196 if (display == null) { 1197 return; 1198 } 1199 if (display.hasContentLocked() != hasContent) { 1200 if (DEBUG) { 1201 Slog.d(TAG, "Display " + displayId + " hasContent flag changed: " 1202 + "hasContent=" + hasContent + ", inTraversal=" + inTraversal); 1203 } 1204 1205 display.setHasContentLocked(hasContent); 1206 scheduleTraversalLocked(inTraversal); 1207 } 1208 if (requestedModeId == 0 && requestedRefreshRate != 0) { 1209 // Scan supported modes returned by display.getInfo() to find a mode with the same 1210 // size as the default display mode but with the specified refresh rate instead. 1211 requestedModeId = display.getDisplayInfoLocked().findDefaultModeByRefreshRate( 1212 requestedRefreshRate); 1213 } 1214 mDisplayModeDirector.getAppRequestObserver().setAppRequestedMode( 1215 displayId, requestedModeId); 1216 } 1217 } 1218 setDisplayOffsetsInternal(int displayId, int x, int y)1219 private void setDisplayOffsetsInternal(int displayId, int x, int y) { 1220 synchronized (mSyncRoot) { 1221 LogicalDisplay display = mLogicalDisplays.get(displayId); 1222 if (display == null) { 1223 return; 1224 } 1225 if (display.getDisplayOffsetXLocked() != x 1226 || display.getDisplayOffsetYLocked() != y) { 1227 if (DEBUG) { 1228 Slog.d(TAG, "Display " + displayId + " burn-in offset set to (" 1229 + x + ", " + y + ")"); 1230 } 1231 display.setDisplayOffsetsLocked(x, y); 1232 scheduleTraversalLocked(false); 1233 } 1234 } 1235 } 1236 setDisplayScalingDisabledInternal(int displayId, boolean disable)1237 private void setDisplayScalingDisabledInternal(int displayId, boolean disable) { 1238 synchronized (mSyncRoot) { 1239 final LogicalDisplay display = mLogicalDisplays.get(displayId); 1240 if (display == null) { 1241 return; 1242 } 1243 if (display.isDisplayScalingDisabled() != disable) { 1244 if (DEBUG) { 1245 Slog.d(TAG, "Display " + displayId + " content scaling disabled = " + disable); 1246 } 1247 display.setDisplayScalingDisabledLocked(disable); 1248 scheduleTraversalLocked(false); 1249 } 1250 } 1251 } 1252 1253 // Updates the lists of UIDs that are present on displays. setDisplayAccessUIDsInternal(SparseArray<IntArray> newDisplayAccessUIDs)1254 private void setDisplayAccessUIDsInternal(SparseArray<IntArray> newDisplayAccessUIDs) { 1255 synchronized (mSyncRoot) { 1256 mDisplayAccessUIDs.clear(); 1257 for (int i = newDisplayAccessUIDs.size() - 1; i >= 0; i--) { 1258 mDisplayAccessUIDs.append(newDisplayAccessUIDs.keyAt(i), 1259 newDisplayAccessUIDs.valueAt(i)); 1260 } 1261 } 1262 } 1263 1264 // Checks if provided UID's content is present on the display and UID has access to it. isUidPresentOnDisplayInternal(int uid, int displayId)1265 private boolean isUidPresentOnDisplayInternal(int uid, int displayId) { 1266 synchronized (mSyncRoot) { 1267 final IntArray displayUIDs = mDisplayAccessUIDs.get(displayId); 1268 return displayUIDs != null && displayUIDs.indexOf(uid) != -1; 1269 } 1270 } 1271 1272 @Nullable getDisplayToken(int displayId)1273 private IBinder getDisplayToken(int displayId) { 1274 synchronized (mSyncRoot) { 1275 final LogicalDisplay display = mLogicalDisplays.get(displayId); 1276 if (display != null) { 1277 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); 1278 if (device != null) { 1279 return device.getDisplayTokenLocked(); 1280 } 1281 } 1282 } 1283 1284 return null; 1285 } 1286 screenshotInternal(int displayId)1287 private SurfaceControl.ScreenshotGraphicBuffer screenshotInternal(int displayId) { 1288 final IBinder token = getDisplayToken(displayId); 1289 if (token == null) { 1290 return null; 1291 } 1292 return SurfaceControl.screenshotToBufferWithSecureLayersUnsafe( 1293 token, new Rect(), 0 /* width */, 0 /* height */, 1294 false /* useIdentityTransform */, 0 /* rotation */); 1295 } 1296 1297 @VisibleForTesting getDisplayedContentSamplingAttributesInternal( int displayId)1298 DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributesInternal( 1299 int displayId) { 1300 final IBinder token = getDisplayToken(displayId); 1301 if (token == null) { 1302 return null; 1303 } 1304 return SurfaceControl.getDisplayedContentSamplingAttributes(token); 1305 } 1306 1307 @VisibleForTesting setDisplayedContentSamplingEnabledInternal( int displayId, boolean enable, int componentMask, int maxFrames)1308 boolean setDisplayedContentSamplingEnabledInternal( 1309 int displayId, boolean enable, int componentMask, int maxFrames) { 1310 final IBinder token = getDisplayToken(displayId); 1311 if (token == null) { 1312 return false; 1313 } 1314 return SurfaceControl.setDisplayedContentSamplingEnabled( 1315 token, enable, componentMask, maxFrames); 1316 } 1317 1318 @VisibleForTesting getDisplayedContentSampleInternal(int displayId, long maxFrames, long timestamp)1319 DisplayedContentSample getDisplayedContentSampleInternal(int displayId, 1320 long maxFrames, long timestamp) { 1321 final IBinder token = getDisplayToken(displayId); 1322 if (token == null) { 1323 return null; 1324 } 1325 return SurfaceControl.getDisplayedContentSample(token, maxFrames, timestamp); 1326 } 1327 onAllowedDisplayModesChangedInternal()1328 private void onAllowedDisplayModesChangedInternal() { 1329 boolean changed = false; 1330 synchronized (mSyncRoot) { 1331 final int count = mLogicalDisplays.size(); 1332 for (int i = 0; i < count; i++) { 1333 LogicalDisplay display = mLogicalDisplays.valueAt(i); 1334 int displayId = mLogicalDisplays.keyAt(i); 1335 int[] allowedModes = mDisplayModeDirector.getAllowedModes(displayId); 1336 // Note that order is important here since not all display devices are capable of 1337 // automatically switching, so we do actually want to check for equality and not 1338 // just equivalent contents (regardless of order). 1339 if (!Arrays.equals(allowedModes, display.getAllowedDisplayModesLocked())) { 1340 display.setAllowedDisplayModesLocked(allowedModes); 1341 changed = true; 1342 } 1343 } 1344 if (changed) { 1345 scheduleTraversalLocked(false); 1346 } 1347 } 1348 } 1349 clearViewportsLocked()1350 private void clearViewportsLocked() { 1351 mViewports.clear(); 1352 } 1353 configureDisplayLocked(SurfaceControl.Transaction t, DisplayDevice device)1354 private void configureDisplayLocked(SurfaceControl.Transaction t, DisplayDevice device) { 1355 final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 1356 final boolean ownContent = (info.flags & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0; 1357 1358 // Find the logical display that the display device is showing. 1359 // Certain displays only ever show their own content. 1360 LogicalDisplay display = findLogicalDisplayForDeviceLocked(device); 1361 if (!ownContent) { 1362 if (display != null && !display.hasContentLocked()) { 1363 // If the display does not have any content of its own, then 1364 // automatically mirror the default logical display contents. 1365 display = null; 1366 } 1367 if (display == null) { 1368 display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY); 1369 } 1370 } 1371 1372 // Apply the logical display configuration to the display device. 1373 if (display == null) { 1374 // TODO: no logical display for the device, blank it 1375 Slog.w(TAG, "Missing logical display to use for physical display device: " 1376 + device.getDisplayDeviceInfoLocked()); 1377 return; 1378 } 1379 display.configureDisplayLocked(t, device, info.state == Display.STATE_OFF); 1380 final int viewportType; 1381 // Update the corresponding viewport. 1382 if ((info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) { 1383 viewportType = VIEWPORT_INTERNAL; 1384 } else if (info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) { 1385 viewportType = VIEWPORT_EXTERNAL; 1386 } else if (info.touch == DisplayDeviceInfo.TOUCH_VIRTUAL 1387 && !TextUtils.isEmpty(info.uniqueId)) { 1388 viewportType = VIEWPORT_VIRTUAL; 1389 } else { 1390 Slog.i(TAG, "Display " + info + " does not support input device matching."); 1391 return; 1392 } 1393 1394 populateViewportLocked(viewportType, display.getDisplayIdLocked(), device, info.uniqueId); 1395 } 1396 1397 /** 1398 * Get internal or external viewport. Create it if does not currently exist. 1399 * @param viewportType - either INTERNAL or EXTERNAL 1400 * @return the viewport with the requested type 1401 */ getViewportLocked(int viewportType, String uniqueId)1402 private DisplayViewport getViewportLocked(int viewportType, String uniqueId) { 1403 if (viewportType != VIEWPORT_INTERNAL && viewportType != VIEWPORT_EXTERNAL 1404 && viewportType != VIEWPORT_VIRTUAL) { 1405 Slog.wtf(TAG, "Cannot call getViewportByTypeLocked for type " 1406 + DisplayViewport.typeToString(viewportType)); 1407 return null; 1408 } 1409 1410 // Only allow a single INTERNAL or EXTERNAL viewport by forcing their uniqueIds 1411 // to be identical (in particular, empty). 1412 // TODO (b/116824030) allow multiple EXTERNAL viewports and remove this function. 1413 if (viewportType != VIEWPORT_VIRTUAL) { 1414 uniqueId = ""; 1415 } 1416 1417 DisplayViewport viewport; 1418 final int count = mViewports.size(); 1419 for (int i = 0; i < count; i++) { 1420 viewport = mViewports.get(i); 1421 if (viewport.type == viewportType && uniqueId.equals(viewport.uniqueId)) { 1422 return viewport; 1423 } 1424 } 1425 1426 // Creates the viewport if none exists. 1427 viewport = new DisplayViewport(); 1428 viewport.type = viewportType; 1429 viewport.uniqueId = uniqueId; 1430 mViewports.add(viewport); 1431 return viewport; 1432 } 1433 populateViewportLocked(int viewportType, int displayId, DisplayDevice device, String uniqueId)1434 private void populateViewportLocked(int viewportType, 1435 int displayId, DisplayDevice device, String uniqueId) { 1436 final DisplayViewport viewport = getViewportLocked(viewportType, uniqueId); 1437 device.populateViewportLocked(viewport); 1438 viewport.valid = true; 1439 viewport.displayId = displayId; 1440 } 1441 findLogicalDisplayForDeviceLocked(DisplayDevice device)1442 private LogicalDisplay findLogicalDisplayForDeviceLocked(DisplayDevice device) { 1443 final int count = mLogicalDisplays.size(); 1444 for (int i = 0; i < count; i++) { 1445 LogicalDisplay display = mLogicalDisplays.valueAt(i); 1446 if (display.getPrimaryDisplayDeviceLocked() == device) { 1447 return display; 1448 } 1449 } 1450 return null; 1451 } 1452 sendDisplayEventLocked(int displayId, int event)1453 private void sendDisplayEventLocked(int displayId, int event) { 1454 Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT, displayId, event); 1455 mHandler.sendMessage(msg); 1456 } 1457 1458 // Requests that performTraversals be called at a 1459 // later time to apply changes to surfaces and displays. scheduleTraversalLocked(boolean inTraversal)1460 private void scheduleTraversalLocked(boolean inTraversal) { 1461 if (!mPendingTraversal && mWindowManagerInternal != null) { 1462 mPendingTraversal = true; 1463 if (!inTraversal) { 1464 mHandler.sendEmptyMessage(MSG_REQUEST_TRAVERSAL); 1465 } 1466 } 1467 } 1468 1469 // Runs on Handler thread. 1470 // Delivers display event notifications to callbacks. deliverDisplayEvent(int displayId, int event)1471 private void deliverDisplayEvent(int displayId, int event) { 1472 if (DEBUG) { 1473 Slog.d(TAG, "Delivering display event: displayId=" 1474 + displayId + ", event=" + event); 1475 } 1476 1477 // Grab the lock and copy the callbacks. 1478 final int count; 1479 synchronized (mSyncRoot) { 1480 count = mCallbacks.size(); 1481 mTempCallbacks.clear(); 1482 for (int i = 0; i < count; i++) { 1483 mTempCallbacks.add(mCallbacks.valueAt(i)); 1484 } 1485 } 1486 1487 // After releasing the lock, send the notifications out. 1488 for (int i = 0; i < count; i++) { 1489 mTempCallbacks.get(i).notifyDisplayEventAsync(displayId, event); 1490 } 1491 mTempCallbacks.clear(); 1492 } 1493 getProjectionService()1494 private IMediaProjectionManager getProjectionService() { 1495 if (mProjectionService == null) { 1496 IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE); 1497 mProjectionService = IMediaProjectionManager.Stub.asInterface(b); 1498 } 1499 return mProjectionService; 1500 } 1501 getUserManager()1502 private UserManager getUserManager() { 1503 return mContext.getSystemService(UserManager.class); 1504 } 1505 dumpInternal(PrintWriter pw)1506 private void dumpInternal(PrintWriter pw) { 1507 pw.println("DISPLAY MANAGER (dumpsys display)"); 1508 1509 synchronized (mSyncRoot) { 1510 pw.println(" mOnlyCode=" + mOnlyCore); 1511 pw.println(" mSafeMode=" + mSafeMode); 1512 pw.println(" mPendingTraversal=" + mPendingTraversal); 1513 pw.println(" mGlobalDisplayState=" + Display.stateToString(mGlobalDisplayState)); 1514 pw.println(" mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId); 1515 pw.println(" mViewports=" + mViewports); 1516 pw.println(" mDefaultDisplayDefaultColorMode=" + mDefaultDisplayDefaultColorMode); 1517 pw.println(" mSingleDisplayDemoMode=" + mSingleDisplayDemoMode); 1518 pw.println(" mWifiDisplayScanRequestCount=" + mWifiDisplayScanRequestCount); 1519 pw.println(" mStableDisplaySize=" + mStableDisplaySize); 1520 pw.println(" mMinimumBrightnessCurve=" + mMinimumBrightnessCurve); 1521 1522 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 1523 ipw.increaseIndent(); 1524 1525 pw.println(); 1526 pw.println("Display Adapters: size=" + mDisplayAdapters.size()); 1527 for (DisplayAdapter adapter : mDisplayAdapters) { 1528 pw.println(" " + adapter.getName()); 1529 adapter.dumpLocked(ipw); 1530 } 1531 1532 pw.println(); 1533 pw.println("Display Devices: size=" + mDisplayDevices.size()); 1534 for (DisplayDevice device : mDisplayDevices) { 1535 pw.println(" " + device.getDisplayDeviceInfoLocked()); 1536 device.dumpLocked(ipw); 1537 } 1538 1539 final int logicalDisplayCount = mLogicalDisplays.size(); 1540 pw.println(); 1541 pw.println("Logical Displays: size=" + logicalDisplayCount); 1542 for (int i = 0; i < logicalDisplayCount; i++) { 1543 int displayId = mLogicalDisplays.keyAt(i); 1544 LogicalDisplay display = mLogicalDisplays.valueAt(i); 1545 pw.println(" Display " + displayId + ":"); 1546 display.dumpLocked(ipw); 1547 } 1548 1549 pw.println(); 1550 mDisplayModeDirector.dump(pw); 1551 1552 final int callbackCount = mCallbacks.size(); 1553 pw.println(); 1554 pw.println("Callbacks: size=" + callbackCount); 1555 for (int i = 0; i < callbackCount; i++) { 1556 CallbackRecord callback = mCallbacks.valueAt(i); 1557 pw.println(" " + i + ": mPid=" + callback.mPid 1558 + ", mWifiDisplayScanRequested=" + callback.mWifiDisplayScanRequested); 1559 } 1560 1561 if (mDisplayPowerController != null) { 1562 mDisplayPowerController.dump(pw); 1563 } 1564 1565 pw.println(); 1566 mPersistentDataStore.dump(pw); 1567 } 1568 } 1569 getFloatArray(TypedArray array)1570 private static float[] getFloatArray(TypedArray array) { 1571 int length = array.length(); 1572 float[] floatArray = new float[length]; 1573 for (int i = 0; i < length; i++) { 1574 floatArray[i] = array.getFloat(i, Float.NaN); 1575 } 1576 array.recycle(); 1577 return floatArray; 1578 } 1579 1580 /** 1581 * This is the object that everything in the display manager locks on. 1582 * We make it an inner class within the {@link DisplayManagerService} to so that it is 1583 * clear that the object belongs to the display manager service and that it is 1584 * a unique object with a special purpose. 1585 */ 1586 public static final class SyncRoot { 1587 } 1588 1589 @VisibleForTesting 1590 static class Injector { getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, Handler handler, DisplayAdapter.Listener displayAdapterListener)1591 VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, 1592 Handler handler, DisplayAdapter.Listener displayAdapterListener) { 1593 return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener); 1594 } 1595 getDefaultDisplayDelayTimeout()1596 long getDefaultDisplayDelayTimeout() { 1597 return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT; 1598 } 1599 } 1600 1601 @VisibleForTesting getDisplayDeviceInfoInternal(int displayId)1602 DisplayDeviceInfo getDisplayDeviceInfoInternal(int displayId) { 1603 synchronized (mSyncRoot) { 1604 LogicalDisplay display = mLogicalDisplays.get(displayId); 1605 if (display != null) { 1606 DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked(); 1607 return displayDevice.getDisplayDeviceInfoLocked(); 1608 } 1609 return null; 1610 } 1611 } 1612 1613 private final class DisplayManagerHandler extends Handler { DisplayManagerHandler(Looper looper)1614 public DisplayManagerHandler(Looper looper) { 1615 super(looper, null, true /*async*/); 1616 } 1617 1618 @Override handleMessage(Message msg)1619 public void handleMessage(Message msg) { 1620 switch (msg.what) { 1621 case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS: 1622 registerDefaultDisplayAdapters(); 1623 break; 1624 1625 case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS: 1626 registerAdditionalDisplayAdapters(); 1627 break; 1628 1629 case MSG_DELIVER_DISPLAY_EVENT: 1630 deliverDisplayEvent(msg.arg1, msg.arg2); 1631 break; 1632 1633 case MSG_REQUEST_TRAVERSAL: 1634 mWindowManagerInternal.requestTraversalFromDisplayManager(); 1635 break; 1636 1637 case MSG_UPDATE_VIEWPORT: { 1638 final boolean changed; 1639 synchronized (mSyncRoot) { 1640 changed = !mTempViewports.equals(mViewports); 1641 if (changed) { 1642 mTempViewports.clear(); 1643 for (DisplayViewport d : mViewports) { 1644 mTempViewports.add(d.makeCopy()); 1645 } 1646 } 1647 } 1648 if (changed) { 1649 mInputManagerInternal.setDisplayViewports(mTempViewports); 1650 } 1651 break; 1652 } 1653 1654 case MSG_LOAD_BRIGHTNESS_CONFIGURATION: 1655 loadBrightnessConfiguration(); 1656 break; 1657 } 1658 } 1659 } 1660 1661 private final class DisplayAdapterListener implements DisplayAdapter.Listener { 1662 @Override onDisplayDeviceEvent(DisplayDevice device, int event)1663 public void onDisplayDeviceEvent(DisplayDevice device, int event) { 1664 switch (event) { 1665 case DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED: 1666 handleDisplayDeviceAdded(device); 1667 break; 1668 1669 case DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED: 1670 handleDisplayDeviceChanged(device); 1671 break; 1672 1673 case DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED: 1674 handleDisplayDeviceRemoved(device); 1675 break; 1676 } 1677 } 1678 1679 @Override onTraversalRequested()1680 public void onTraversalRequested() { 1681 synchronized (mSyncRoot) { 1682 scheduleTraversalLocked(false); 1683 } 1684 } 1685 } 1686 1687 private final class CallbackRecord implements DeathRecipient { 1688 public final int mPid; 1689 private final IDisplayManagerCallback mCallback; 1690 1691 public boolean mWifiDisplayScanRequested; 1692 CallbackRecord(int pid, IDisplayManagerCallback callback)1693 public CallbackRecord(int pid, IDisplayManagerCallback callback) { 1694 mPid = pid; 1695 mCallback = callback; 1696 } 1697 1698 @Override binderDied()1699 public void binderDied() { 1700 if (DEBUG) { 1701 Slog.d(TAG, "Display listener for pid " + mPid + " died."); 1702 } 1703 onCallbackDied(this); 1704 } 1705 notifyDisplayEventAsync(int displayId, int event)1706 public void notifyDisplayEventAsync(int displayId, int event) { 1707 try { 1708 mCallback.onDisplayEvent(displayId, event); 1709 } catch (RemoteException ex) { 1710 Slog.w(TAG, "Failed to notify process " 1711 + mPid + " that displays changed, assuming it died.", ex); 1712 binderDied(); 1713 } 1714 } 1715 } 1716 1717 @VisibleForTesting 1718 final class BinderService extends IDisplayManager.Stub { 1719 /** 1720 * Returns information about the specified logical display. 1721 * 1722 * @param displayId The logical display id. 1723 * @return The logical display info, return {@code null} if the display does not exist or 1724 * the calling UID isn't present on the display. The returned object must be treated as 1725 * immutable. 1726 */ 1727 @Override // Binder call getDisplayInfo(int displayId)1728 public DisplayInfo getDisplayInfo(int displayId) { 1729 final int callingUid = Binder.getCallingUid(); 1730 final long token = Binder.clearCallingIdentity(); 1731 try { 1732 return getDisplayInfoInternal(displayId, callingUid); 1733 } finally { 1734 Binder.restoreCallingIdentity(token); 1735 } 1736 } 1737 1738 /** 1739 * Returns the list of all display ids. 1740 */ 1741 @Override // Binder call getDisplayIds()1742 public int[] getDisplayIds() { 1743 final int callingUid = Binder.getCallingUid(); 1744 final long token = Binder.clearCallingIdentity(); 1745 try { 1746 return getDisplayIdsInternal(callingUid); 1747 } finally { 1748 Binder.restoreCallingIdentity(token); 1749 } 1750 } 1751 1752 @Override // Binder call isUidPresentOnDisplay(int uid, int displayId)1753 public boolean isUidPresentOnDisplay(int uid, int displayId) { 1754 final long token = Binder.clearCallingIdentity(); 1755 try { 1756 return isUidPresentOnDisplayInternal(uid, displayId); 1757 } finally { 1758 Binder.restoreCallingIdentity(token); 1759 } 1760 } 1761 1762 /** 1763 * Returns the stable device display size, in pixels. 1764 */ 1765 @Override // Binder call getStableDisplaySize()1766 public Point getStableDisplaySize() { 1767 final long token = Binder.clearCallingIdentity(); 1768 try { 1769 return getStableDisplaySizeInternal(); 1770 } finally { 1771 Binder.restoreCallingIdentity(token); 1772 } 1773 } 1774 1775 @Override // Binder call registerCallback(IDisplayManagerCallback callback)1776 public void registerCallback(IDisplayManagerCallback callback) { 1777 if (callback == null) { 1778 throw new IllegalArgumentException("listener must not be null"); 1779 } 1780 1781 final int callingPid = Binder.getCallingPid(); 1782 final long token = Binder.clearCallingIdentity(); 1783 try { 1784 registerCallbackInternal(callback, callingPid); 1785 } finally { 1786 Binder.restoreCallingIdentity(token); 1787 } 1788 } 1789 1790 @Override // Binder call startWifiDisplayScan()1791 public void startWifiDisplayScan() { 1792 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1793 "Permission required to start wifi display scans"); 1794 1795 final int callingPid = Binder.getCallingPid(); 1796 final long token = Binder.clearCallingIdentity(); 1797 try { 1798 startWifiDisplayScanInternal(callingPid); 1799 } finally { 1800 Binder.restoreCallingIdentity(token); 1801 } 1802 } 1803 1804 @Override // Binder call stopWifiDisplayScan()1805 public void stopWifiDisplayScan() { 1806 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1807 "Permission required to stop wifi display scans"); 1808 1809 final int callingPid = Binder.getCallingPid(); 1810 final long token = Binder.clearCallingIdentity(); 1811 try { 1812 stopWifiDisplayScanInternal(callingPid); 1813 } finally { 1814 Binder.restoreCallingIdentity(token); 1815 } 1816 } 1817 1818 @Override // Binder call connectWifiDisplay(String address)1819 public void connectWifiDisplay(String address) { 1820 if (address == null) { 1821 throw new IllegalArgumentException("address must not be null"); 1822 } 1823 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1824 "Permission required to connect to a wifi display"); 1825 1826 final long token = Binder.clearCallingIdentity(); 1827 try { 1828 connectWifiDisplayInternal(address); 1829 } finally { 1830 Binder.restoreCallingIdentity(token); 1831 } 1832 } 1833 1834 @Override // Binder call disconnectWifiDisplay()1835 public void disconnectWifiDisplay() { 1836 // This request does not require special permissions. 1837 // Any app can request disconnection from the currently active wifi display. 1838 // This exception should no longer be needed once wifi display control moves 1839 // to the media router service. 1840 1841 final long token = Binder.clearCallingIdentity(); 1842 try { 1843 disconnectWifiDisplayInternal(); 1844 } finally { 1845 Binder.restoreCallingIdentity(token); 1846 } 1847 } 1848 1849 @Override // Binder call renameWifiDisplay(String address, String alias)1850 public void renameWifiDisplay(String address, String alias) { 1851 if (address == null) { 1852 throw new IllegalArgumentException("address must not be null"); 1853 } 1854 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1855 "Permission required to rename to a wifi display"); 1856 1857 final long token = Binder.clearCallingIdentity(); 1858 try { 1859 renameWifiDisplayInternal(address, alias); 1860 } finally { 1861 Binder.restoreCallingIdentity(token); 1862 } 1863 } 1864 1865 @Override // Binder call forgetWifiDisplay(String address)1866 public void forgetWifiDisplay(String address) { 1867 if (address == null) { 1868 throw new IllegalArgumentException("address must not be null"); 1869 } 1870 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1871 "Permission required to forget to a wifi display"); 1872 1873 final long token = Binder.clearCallingIdentity(); 1874 try { 1875 forgetWifiDisplayInternal(address); 1876 } finally { 1877 Binder.restoreCallingIdentity(token); 1878 } 1879 } 1880 1881 @Override // Binder call pauseWifiDisplay()1882 public void pauseWifiDisplay() { 1883 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1884 "Permission required to pause a wifi display session"); 1885 1886 final long token = Binder.clearCallingIdentity(); 1887 try { 1888 pauseWifiDisplayInternal(); 1889 } finally { 1890 Binder.restoreCallingIdentity(token); 1891 } 1892 } 1893 1894 @Override // Binder call resumeWifiDisplay()1895 public void resumeWifiDisplay() { 1896 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1897 "Permission required to resume a wifi display session"); 1898 1899 final long token = Binder.clearCallingIdentity(); 1900 try { 1901 resumeWifiDisplayInternal(); 1902 } finally { 1903 Binder.restoreCallingIdentity(token); 1904 } 1905 } 1906 1907 @Override // Binder call getWifiDisplayStatus()1908 public WifiDisplayStatus getWifiDisplayStatus() { 1909 // This request does not require special permissions. 1910 // Any app can get information about available wifi displays. 1911 1912 final long token = Binder.clearCallingIdentity(); 1913 try { 1914 return getWifiDisplayStatusInternal(); 1915 } finally { 1916 Binder.restoreCallingIdentity(token); 1917 } 1918 } 1919 1920 @Override // Binder call requestColorMode(int displayId, int colorMode)1921 public void requestColorMode(int displayId, int colorMode) { 1922 mContext.enforceCallingOrSelfPermission( 1923 Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE, 1924 "Permission required to change the display color mode"); 1925 final long token = Binder.clearCallingIdentity(); 1926 try { 1927 requestColorModeInternal(displayId, colorMode); 1928 } finally { 1929 Binder.restoreCallingIdentity(token); 1930 } 1931 } 1932 1933 @Override // Binder call createVirtualDisplay(IVirtualDisplayCallback callback, IMediaProjection projection, String packageName, String name, int width, int height, int densityDpi, Surface surface, int flags, String uniqueId)1934 public int createVirtualDisplay(IVirtualDisplayCallback callback, 1935 IMediaProjection projection, String packageName, String name, 1936 int width, int height, int densityDpi, Surface surface, int flags, 1937 String uniqueId) { 1938 final int callingUid = Binder.getCallingUid(); 1939 if (!validatePackageName(callingUid, packageName)) { 1940 throw new SecurityException("packageName must match the calling uid"); 1941 } 1942 if (callback == null) { 1943 throw new IllegalArgumentException("appToken must not be null"); 1944 } 1945 if (TextUtils.isEmpty(name)) { 1946 throw new IllegalArgumentException("name must be non-null and non-empty"); 1947 } 1948 if (width <= 0 || height <= 0 || densityDpi <= 0) { 1949 throw new IllegalArgumentException("width, height, and densityDpi must be " 1950 + "greater than 0"); 1951 } 1952 if (surface != null && surface.isSingleBuffered()) { 1953 throw new IllegalArgumentException("Surface can't be single-buffered"); 1954 } 1955 1956 if ((flags & VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) { 1957 flags |= VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; 1958 1959 // Public displays can't be allowed to show content when locked. 1960 if ((flags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) { 1961 throw new IllegalArgumentException( 1962 "Public display must not be marked as SHOW_WHEN_LOCKED_INSECURE"); 1963 } 1964 } 1965 if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) { 1966 flags &= ~VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; 1967 } 1968 1969 if (projection != null) { 1970 try { 1971 if (!getProjectionService().isValidMediaProjection(projection)) { 1972 throw new SecurityException("Invalid media projection"); 1973 } 1974 flags = projection.applyVirtualDisplayFlags(flags); 1975 } catch (RemoteException e) { 1976 throw new SecurityException("unable to validate media projection or flags"); 1977 } 1978 } 1979 1980 if (callingUid != Process.SYSTEM_UID && 1981 (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) { 1982 if (!canProjectVideo(projection)) { 1983 throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or " 1984 + "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate " 1985 + "MediaProjection token in order to create a screen sharing virtual " 1986 + "display."); 1987 } 1988 } 1989 if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0) { 1990 if (!canProjectSecureVideo(projection)) { 1991 throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT " 1992 + "or an appropriate MediaProjection token to create a " 1993 + "secure virtual display."); 1994 } 1995 } 1996 1997 // Sometimes users can have sensitive information in system decoration windows. An app 1998 // could create a virtual display with system decorations support and read the user info 1999 // from the surface. 2000 // We should only allow adding flag VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS 2001 // to virtual displays that are owned by the system. 2002 if (callingUid != Process.SYSTEM_UID 2003 && (flags & VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) { 2004 if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "createVirtualDisplay()")) { 2005 throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); 2006 } 2007 } 2008 2009 final long token = Binder.clearCallingIdentity(); 2010 try { 2011 return createVirtualDisplayInternal(callback, projection, callingUid, packageName, 2012 name, width, height, densityDpi, surface, flags, uniqueId); 2013 } finally { 2014 Binder.restoreCallingIdentity(token); 2015 } 2016 } 2017 2018 @Override // Binder call resizeVirtualDisplay(IVirtualDisplayCallback callback, int width, int height, int densityDpi)2019 public void resizeVirtualDisplay(IVirtualDisplayCallback callback, 2020 int width, int height, int densityDpi) { 2021 final long token = Binder.clearCallingIdentity(); 2022 try { 2023 resizeVirtualDisplayInternal(callback.asBinder(), width, height, densityDpi); 2024 } finally { 2025 Binder.restoreCallingIdentity(token); 2026 } 2027 } 2028 2029 @Override // Binder call setVirtualDisplaySurface(IVirtualDisplayCallback callback, Surface surface)2030 public void setVirtualDisplaySurface(IVirtualDisplayCallback callback, Surface surface) { 2031 if (surface != null && surface.isSingleBuffered()) { 2032 throw new IllegalArgumentException("Surface can't be single-buffered"); 2033 } 2034 final long token = Binder.clearCallingIdentity(); 2035 try { 2036 setVirtualDisplaySurfaceInternal(callback.asBinder(), surface); 2037 } finally { 2038 Binder.restoreCallingIdentity(token); 2039 } 2040 } 2041 2042 @Override // Binder call releaseVirtualDisplay(IVirtualDisplayCallback callback)2043 public void releaseVirtualDisplay(IVirtualDisplayCallback callback) { 2044 final long token = Binder.clearCallingIdentity(); 2045 try { 2046 releaseVirtualDisplayInternal(callback.asBinder()); 2047 } finally { 2048 Binder.restoreCallingIdentity(token); 2049 } 2050 } 2051 2052 @Override // Binder call setVirtualDisplayState(IVirtualDisplayCallback callback, boolean isOn)2053 public void setVirtualDisplayState(IVirtualDisplayCallback callback, boolean isOn) { 2054 final long token = Binder.clearCallingIdentity(); 2055 try { 2056 setVirtualDisplayStateInternal(callback.asBinder(), isOn); 2057 } finally { 2058 Binder.restoreCallingIdentity(token); 2059 } 2060 } 2061 2062 @Override // Binder call dump(FileDescriptor fd, final PrintWriter pw, String[] args)2063 public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) { 2064 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 2065 2066 final long token = Binder.clearCallingIdentity(); 2067 try { 2068 dumpInternal(pw); 2069 } finally { 2070 Binder.restoreCallingIdentity(token); 2071 } 2072 } 2073 2074 @Override // Binder call getBrightnessEvents(String callingPackage)2075 public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents(String callingPackage) { 2076 mContext.enforceCallingOrSelfPermission( 2077 Manifest.permission.BRIGHTNESS_SLIDER_USAGE, 2078 "Permission to read brightness events."); 2079 2080 final int callingUid = Binder.getCallingUid(); 2081 AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class); 2082 final int mode = appOpsManager.noteOp(AppOpsManager.OP_GET_USAGE_STATS, 2083 callingUid, callingPackage); 2084 final boolean hasUsageStats; 2085 if (mode == AppOpsManager.MODE_DEFAULT) { 2086 // The default behavior here is to check if PackageManager has given the app 2087 // permission. 2088 hasUsageStats = mContext.checkCallingPermission( 2089 Manifest.permission.PACKAGE_USAGE_STATS) 2090 == PackageManager.PERMISSION_GRANTED; 2091 } else { 2092 hasUsageStats = mode == AppOpsManager.MODE_ALLOWED; 2093 } 2094 2095 final int userId = UserHandle.getUserId(callingUid); 2096 final long token = Binder.clearCallingIdentity(); 2097 try { 2098 synchronized (mSyncRoot) { 2099 return mDisplayPowerController.getBrightnessEvents(userId, hasUsageStats); 2100 } 2101 } finally { 2102 Binder.restoreCallingIdentity(token); 2103 } 2104 } 2105 2106 @Override // Binder call getAmbientBrightnessStats()2107 public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats() { 2108 mContext.enforceCallingOrSelfPermission( 2109 Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS, 2110 "Permission required to to access ambient light stats."); 2111 final int callingUid = Binder.getCallingUid(); 2112 final int userId = UserHandle.getUserId(callingUid); 2113 final long token = Binder.clearCallingIdentity(); 2114 try { 2115 synchronized (mSyncRoot) { 2116 return mDisplayPowerController.getAmbientBrightnessStats(userId); 2117 } 2118 } finally { 2119 Binder.restoreCallingIdentity(token); 2120 } 2121 } 2122 2123 @Override // Binder call setBrightnessConfigurationForUser( BrightnessConfiguration c, @UserIdInt int userId, String packageName)2124 public void setBrightnessConfigurationForUser( 2125 BrightnessConfiguration c, @UserIdInt int userId, String packageName) { 2126 mContext.enforceCallingOrSelfPermission( 2127 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS, 2128 "Permission required to change the display's brightness configuration"); 2129 if (userId != UserHandle.getCallingUserId()) { 2130 mContext.enforceCallingOrSelfPermission( 2131 Manifest.permission.INTERACT_ACROSS_USERS, 2132 "Permission required to change the display brightness" 2133 + " configuration of another user"); 2134 } 2135 if (packageName != null && !validatePackageName(getCallingUid(), packageName)) { 2136 packageName = null; 2137 } 2138 final long token = Binder.clearCallingIdentity(); 2139 try { 2140 setBrightnessConfigurationForUserInternal(c, userId, packageName); 2141 } finally { 2142 Binder.restoreCallingIdentity(token); 2143 } 2144 } 2145 2146 @Override // Binder call getBrightnessConfigurationForUser(int userId)2147 public BrightnessConfiguration getBrightnessConfigurationForUser(int userId) { 2148 mContext.enforceCallingOrSelfPermission( 2149 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS, 2150 "Permission required to read the display's brightness configuration"); 2151 if (userId != UserHandle.getCallingUserId()) { 2152 mContext.enforceCallingOrSelfPermission( 2153 Manifest.permission.INTERACT_ACROSS_USERS, 2154 "Permission required to read the display brightness" 2155 + " configuration of another user"); 2156 } 2157 final long token = Binder.clearCallingIdentity(); 2158 try { 2159 final int userSerial = getUserManager().getUserSerialNumber(userId); 2160 synchronized (mSyncRoot) { 2161 BrightnessConfiguration config = 2162 mPersistentDataStore.getBrightnessConfiguration(userSerial); 2163 if (config == null) { 2164 config = mDisplayPowerController.getDefaultBrightnessConfiguration(); 2165 } 2166 return config; 2167 } 2168 } finally { 2169 Binder.restoreCallingIdentity(token); 2170 } 2171 } 2172 2173 @Override // Binder call getDefaultBrightnessConfiguration()2174 public BrightnessConfiguration getDefaultBrightnessConfiguration() { 2175 mContext.enforceCallingOrSelfPermission( 2176 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS, 2177 "Permission required to read the display's default brightness configuration"); 2178 final long token = Binder.clearCallingIdentity(); 2179 try { 2180 synchronized (mSyncRoot) { 2181 return mDisplayPowerController.getDefaultBrightnessConfiguration(); 2182 } 2183 } finally { 2184 Binder.restoreCallingIdentity(token); 2185 } 2186 } 2187 2188 @Override // Binder call setTemporaryBrightness(int brightness)2189 public void setTemporaryBrightness(int brightness) { 2190 mContext.enforceCallingOrSelfPermission( 2191 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS, 2192 "Permission required to set the display's brightness"); 2193 final long token = Binder.clearCallingIdentity(); 2194 try { 2195 synchronized (mSyncRoot) { 2196 mDisplayPowerController.setTemporaryBrightness(brightness); 2197 } 2198 } finally { 2199 Binder.restoreCallingIdentity(token); 2200 } 2201 } 2202 2203 @Override // Binder call setTemporaryAutoBrightnessAdjustment(float adjustment)2204 public void setTemporaryAutoBrightnessAdjustment(float adjustment) { 2205 mContext.enforceCallingOrSelfPermission( 2206 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS, 2207 "Permission required to set the display's auto brightness adjustment"); 2208 final long token = Binder.clearCallingIdentity(); 2209 try { 2210 synchronized (mSyncRoot) { 2211 mDisplayPowerController.setTemporaryAutoBrightnessAdjustment(adjustment); 2212 } 2213 } finally { 2214 Binder.restoreCallingIdentity(token); 2215 } 2216 } 2217 2218 @Override // Binder call onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)2219 public void onShellCommand(FileDescriptor in, FileDescriptor out, 2220 FileDescriptor err, String[] args, ShellCallback callback, 2221 ResultReceiver resultReceiver) { 2222 final long token = Binder.clearCallingIdentity(); 2223 try { 2224 DisplayManagerShellCommand command = new DisplayManagerShellCommand(this); 2225 command.exec(this, in, out, err, args, callback, resultReceiver); 2226 } finally { 2227 Binder.restoreCallingIdentity(token); 2228 } 2229 } 2230 2231 @Override // Binder call getMinimumBrightnessCurve()2232 public Curve getMinimumBrightnessCurve() { 2233 final long token = Binder.clearCallingIdentity(); 2234 try { 2235 return getMinimumBrightnessCurveInternal(); 2236 } finally { 2237 Binder.restoreCallingIdentity(token); 2238 } 2239 } 2240 2241 @Override // Binder call getPreferredWideGamutColorSpaceId()2242 public int getPreferredWideGamutColorSpaceId() { 2243 final long token = Binder.clearCallingIdentity(); 2244 try { 2245 return getPreferredWideGamutColorSpaceIdInternal(); 2246 } finally { 2247 Binder.restoreCallingIdentity(token); 2248 } 2249 } 2250 setBrightness(int brightness)2251 void setBrightness(int brightness) { 2252 Settings.System.putIntForUser(mContext.getContentResolver(), 2253 Settings.System.SCREEN_BRIGHTNESS, brightness, UserHandle.USER_CURRENT); 2254 } 2255 resetBrightnessConfiguration()2256 void resetBrightnessConfiguration() { 2257 setBrightnessConfigurationForUserInternal(null, mContext.getUserId(), 2258 mContext.getPackageName()); 2259 } 2260 setAutoBrightnessLoggingEnabled(boolean enabled)2261 void setAutoBrightnessLoggingEnabled(boolean enabled) { 2262 if (mDisplayPowerController != null) { 2263 synchronized (mSyncRoot) { 2264 mDisplayPowerController.setAutoBrightnessLoggingEnabled(enabled); 2265 } 2266 } 2267 } 2268 setDisplayWhiteBalanceLoggingEnabled(boolean enabled)2269 void setDisplayWhiteBalanceLoggingEnabled(boolean enabled) { 2270 if (mDisplayPowerController != null) { 2271 synchronized (mSyncRoot) { 2272 mDisplayPowerController.setDisplayWhiteBalanceLoggingEnabled(enabled); 2273 } 2274 } 2275 } 2276 setAmbientColorTemperatureOverride(float cct)2277 void setAmbientColorTemperatureOverride(float cct) { 2278 if (mDisplayPowerController != null) { 2279 synchronized (mSyncRoot) { 2280 mDisplayPowerController.setAmbientColorTemperatureOverride(cct); 2281 } 2282 } 2283 } 2284 validatePackageName(int uid, String packageName)2285 private boolean validatePackageName(int uid, String packageName) { 2286 if (packageName != null) { 2287 String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid); 2288 if (packageNames != null) { 2289 for (String n : packageNames) { 2290 if (n.equals(packageName)) { 2291 return true; 2292 } 2293 } 2294 } 2295 } 2296 return false; 2297 } 2298 canProjectVideo(IMediaProjection projection)2299 private boolean canProjectVideo(IMediaProjection projection) { 2300 if (projection != null) { 2301 try { 2302 if (projection.canProjectVideo()) { 2303 return true; 2304 } 2305 } catch (RemoteException e) { 2306 Slog.e(TAG, "Unable to query projection service for permissions", e); 2307 } 2308 } 2309 if (checkCallingPermission(CAPTURE_VIDEO_OUTPUT, "canProjectVideo()")) { 2310 return true; 2311 } 2312 return canProjectSecureVideo(projection); 2313 } 2314 canProjectSecureVideo(IMediaProjection projection)2315 private boolean canProjectSecureVideo(IMediaProjection projection) { 2316 if (projection != null) { 2317 try { 2318 if (projection.canProjectSecureVideo()){ 2319 return true; 2320 } 2321 } catch (RemoteException e) { 2322 Slog.e(TAG, "Unable to query projection service for permissions", e); 2323 } 2324 } 2325 return checkCallingPermission(CAPTURE_SECURE_VIDEO_OUTPUT, "canProjectSecureVideo()"); 2326 } 2327 checkCallingPermission(String permission, String func)2328 private boolean checkCallingPermission(String permission, String func) { 2329 if (mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) { 2330 return true; 2331 } 2332 final String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid() 2333 + ", uid=" + Binder.getCallingUid() + " requires " + permission; 2334 Slog.w(TAG, msg); 2335 return false; 2336 } 2337 } 2338 2339 private final class LocalService extends DisplayManagerInternal { 2340 @Override initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler, SensorManager sensorManager)2341 public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler, 2342 SensorManager sensorManager) { 2343 synchronized (mSyncRoot) { 2344 DisplayBlanker blanker = new DisplayBlanker() { 2345 @Override 2346 public void requestDisplayState(int state, int brightness) { 2347 // The order of operations is important for legacy reasons. 2348 if (state == Display.STATE_OFF) { 2349 requestGlobalDisplayStateInternal(state, brightness); 2350 } 2351 2352 callbacks.onDisplayStateChange(state); 2353 2354 if (state != Display.STATE_OFF) { 2355 requestGlobalDisplayStateInternal(state, brightness); 2356 } 2357 } 2358 }; 2359 mDisplayPowerController = new DisplayPowerController( 2360 mContext, callbacks, handler, sensorManager, blanker); 2361 } 2362 2363 mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATION); 2364 } 2365 2366 @Override requestPowerState(DisplayPowerRequest request, boolean waitForNegativeProximity)2367 public boolean requestPowerState(DisplayPowerRequest request, 2368 boolean waitForNegativeProximity) { 2369 synchronized (mSyncRoot) { 2370 return mDisplayPowerController.requestPowerState(request, 2371 waitForNegativeProximity); 2372 } 2373 } 2374 2375 @Override isProximitySensorAvailable()2376 public boolean isProximitySensorAvailable() { 2377 synchronized (mSyncRoot) { 2378 return mDisplayPowerController.isProximitySensorAvailable(); 2379 } 2380 } 2381 2382 @Override screenshot(int displayId)2383 public SurfaceControl.ScreenshotGraphicBuffer screenshot(int displayId) { 2384 return screenshotInternal(displayId); 2385 } 2386 2387 @Override getDisplayInfo(int displayId)2388 public DisplayInfo getDisplayInfo(int displayId) { 2389 return getDisplayInfoInternal(displayId, Process.myUid()); 2390 } 2391 2392 @Override registerDisplayTransactionListener(DisplayTransactionListener listener)2393 public void registerDisplayTransactionListener(DisplayTransactionListener listener) { 2394 if (listener == null) { 2395 throw new IllegalArgumentException("listener must not be null"); 2396 } 2397 2398 registerDisplayTransactionListenerInternal(listener); 2399 } 2400 2401 @Override unregisterDisplayTransactionListener(DisplayTransactionListener listener)2402 public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) { 2403 if (listener == null) { 2404 throw new IllegalArgumentException("listener must not be null"); 2405 } 2406 2407 unregisterDisplayTransactionListenerInternal(listener); 2408 } 2409 2410 @Override setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info)2411 public void setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info) { 2412 setDisplayInfoOverrideFromWindowManagerInternal(displayId, info); 2413 } 2414 2415 @Override getNonOverrideDisplayInfo(int displayId, DisplayInfo outInfo)2416 public void getNonOverrideDisplayInfo(int displayId, DisplayInfo outInfo) { 2417 getNonOverrideDisplayInfoInternal(displayId, outInfo); 2418 } 2419 2420 @Override performTraversal(SurfaceControl.Transaction t)2421 public void performTraversal(SurfaceControl.Transaction t) { 2422 performTraversalInternal(t); 2423 } 2424 2425 @Override setDisplayProperties(int displayId, boolean hasContent, float requestedRefreshRate, int requestedMode, boolean inTraversal)2426 public void setDisplayProperties(int displayId, boolean hasContent, 2427 float requestedRefreshRate, int requestedMode, boolean inTraversal) { 2428 setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate, 2429 requestedMode, inTraversal); 2430 } 2431 2432 @Override setDisplayOffsets(int displayId, int x, int y)2433 public void setDisplayOffsets(int displayId, int x, int y) { 2434 setDisplayOffsetsInternal(displayId, x, y); 2435 } 2436 2437 @Override setDisplayScalingDisabled(int displayId, boolean disableScaling)2438 public void setDisplayScalingDisabled(int displayId, boolean disableScaling) { 2439 setDisplayScalingDisabledInternal(displayId, disableScaling); 2440 } 2441 2442 @Override setDisplayAccessUIDs(SparseArray<IntArray> newDisplayAccessUIDs)2443 public void setDisplayAccessUIDs(SparseArray<IntArray> newDisplayAccessUIDs) { 2444 setDisplayAccessUIDsInternal(newDisplayAccessUIDs); 2445 } 2446 2447 @Override persistBrightnessTrackerState()2448 public void persistBrightnessTrackerState() { 2449 synchronized (mSyncRoot) { 2450 mDisplayPowerController.persistBrightnessTrackerState(); 2451 } 2452 } 2453 2454 @Override onOverlayChanged()2455 public void onOverlayChanged() { 2456 synchronized (mSyncRoot) { 2457 for (int i = 0; i < mDisplayDevices.size(); i++) { 2458 mDisplayDevices.get(i).onOverlayChangedLocked(); 2459 } 2460 } 2461 } 2462 2463 @Override getDisplayedContentSamplingAttributes( int displayId)2464 public DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributes( 2465 int displayId) { 2466 return getDisplayedContentSamplingAttributesInternal(displayId); 2467 } 2468 2469 @Override setDisplayedContentSamplingEnabled( int displayId, boolean enable, int componentMask, int maxFrames)2470 public boolean setDisplayedContentSamplingEnabled( 2471 int displayId, boolean enable, int componentMask, int maxFrames) { 2472 return setDisplayedContentSamplingEnabledInternal( 2473 displayId, enable, componentMask, maxFrames); 2474 } 2475 2476 @Override getDisplayedContentSample(int displayId, long maxFrames, long timestamp)2477 public DisplayedContentSample getDisplayedContentSample(int displayId, 2478 long maxFrames, long timestamp) { 2479 return getDisplayedContentSampleInternal(displayId, maxFrames, timestamp); 2480 } 2481 2482 } 2483 2484 class AllowedDisplayModeObserver implements DisplayModeDirector.Listener { onAllowedDisplayModesChanged()2485 public void onAllowedDisplayModesChanged() { 2486 onAllowedDisplayModesChangedInternal(); 2487 } 2488 } 2489 } 2490