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