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