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