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