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