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