DisplayManagerService.java revision 037c33eae74bee2774897d969d48947f9abe254f
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 releaseVirtualDisplayInternal(IBinder appToken) { 521 synchronized (mSyncRoot) { 522 if (mVirtualDisplayAdapter == null) { 523 return; 524 } 525 526 DisplayDevice device = 527 mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken); 528 if (device != null) { 529 handleDisplayDeviceRemovedLocked(device); 530 } 531 } 532 } 533 534 private void registerDefaultDisplayAdapter() { 535 // Register default display adapter. 536 synchronized (mSyncRoot) { 537 registerDisplayAdapterLocked(new LocalDisplayAdapter( 538 mSyncRoot, mContext, mHandler, mDisplayAdapterListener)); 539 } 540 } 541 542 private void registerAdditionalDisplayAdapters() { 543 synchronized (mSyncRoot) { 544 if (shouldRegisterNonEssentialDisplayAdaptersLocked()) { 545 registerOverlayDisplayAdapterLocked(); 546 registerWifiDisplayAdapterLocked(); 547 registerVirtualDisplayAdapterLocked(); 548 } 549 } 550 } 551 552 private void registerOverlayDisplayAdapterLocked() { 553 registerDisplayAdapterLocked(new OverlayDisplayAdapter( 554 mSyncRoot, mContext, mHandler, mDisplayAdapterListener, mUiHandler)); 555 } 556 557 private void registerWifiDisplayAdapterLocked() { 558 if (mContext.getResources().getBoolean( 559 com.android.internal.R.bool.config_enableWifiDisplay) 560 || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) { 561 mWifiDisplayAdapter = new WifiDisplayAdapter( 562 mSyncRoot, mContext, mHandler, mDisplayAdapterListener, 563 mPersistentDataStore); 564 registerDisplayAdapterLocked(mWifiDisplayAdapter); 565 } 566 } 567 568 private void registerVirtualDisplayAdapterLocked() { 569 mVirtualDisplayAdapter = new VirtualDisplayAdapter( 570 mSyncRoot, mContext, mHandler, mDisplayAdapterListener); 571 registerDisplayAdapterLocked(mVirtualDisplayAdapter); 572 } 573 574 private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() { 575 // In safe mode, we disable non-essential display adapters to give the user 576 // an opportunity to fix broken settings or other problems that might affect 577 // system stability. 578 // In only-core mode, we disable non-essential display adapters to minimize 579 // the number of dependencies that are started while in this mode and to 580 // prevent problems that might occur due to the device being encrypted. 581 return !mSafeMode && !mOnlyCore; 582 } 583 584 private void registerDisplayAdapterLocked(DisplayAdapter adapter) { 585 mDisplayAdapters.add(adapter); 586 adapter.registerLocked(); 587 } 588 589 private void handleDisplayDeviceAdded(DisplayDevice device) { 590 synchronized (mSyncRoot) { 591 handleDisplayDeviceAddedLocked(device); 592 } 593 } 594 595 private void handleDisplayDeviceAddedLocked(DisplayDevice device) { 596 if (mDisplayDevices.contains(device)) { 597 Slog.w(TAG, "Attempted to add already added display device: " 598 + device.getDisplayDeviceInfoLocked()); 599 return; 600 } 601 602 Slog.i(TAG, "Display device added: " + device.getDisplayDeviceInfoLocked()); 603 604 mDisplayDevices.add(device); 605 addLogicalDisplayLocked(device); 606 updateDisplayStateLocked(device); 607 scheduleTraversalLocked(false); 608 } 609 610 private void handleDisplayDeviceChanged(DisplayDevice device) { 611 synchronized (mSyncRoot) { 612 if (!mDisplayDevices.contains(device)) { 613 Slog.w(TAG, "Attempted to change non-existent display device: " 614 + device.getDisplayDeviceInfoLocked()); 615 return; 616 } 617 618 Slog.i(TAG, "Display device changed: " + device.getDisplayDeviceInfoLocked()); 619 620 device.applyPendingDisplayDeviceInfoChangesLocked(); 621 if (updateLogicalDisplaysLocked()) { 622 scheduleTraversalLocked(false); 623 } 624 } 625 } 626 627 private void handleDisplayDeviceRemoved(DisplayDevice device) { 628 synchronized (mSyncRoot) { 629 handleDisplayDeviceRemovedLocked(device); 630 } 631 } 632 private void handleDisplayDeviceRemovedLocked(DisplayDevice device) { 633 if (!mDisplayDevices.remove(device)) { 634 Slog.w(TAG, "Attempted to remove non-existent display device: " 635 + device.getDisplayDeviceInfoLocked()); 636 return; 637 } 638 639 Slog.i(TAG, "Display device removed: " + device.getDisplayDeviceInfoLocked()); 640 641 updateLogicalDisplaysLocked(); 642 scheduleTraversalLocked(false); 643 } 644 645 private void updateGlobalDisplayStateLocked() { 646 final int count = mDisplayDevices.size(); 647 for (int i = 0; i < count; i++) { 648 DisplayDevice device = mDisplayDevices.get(i); 649 updateDisplayStateLocked(device); 650 } 651 } 652 653 private void updateDisplayStateLocked(DisplayDevice device) { 654 // Blank or unblank the display immediately to match the state requested 655 // by the display power controller (if known). 656 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 657 if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) { 658 device.requestDisplayStateLocked(mGlobalDisplayState); 659 } 660 } 661 662 // Adds a new logical display based on the given display device. 663 // Sends notifications if needed. 664 private void addLogicalDisplayLocked(DisplayDevice device) { 665 DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked(); 666 boolean isDefault = (deviceInfo.flags 667 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0; 668 if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) { 669 Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo); 670 isDefault = false; 671 } 672 673 if (!isDefault && mSingleDisplayDemoMode) { 674 Slog.i(TAG, "Not creating a logical display for a secondary display " 675 + " because single display demo mode is enabled: " + deviceInfo); 676 return; 677 } 678 679 final int displayId = assignDisplayIdLocked(isDefault); 680 final int layerStack = assignLayerStackLocked(displayId); 681 682 LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device); 683 display.updateLocked(mDisplayDevices); 684 if (!display.isValidLocked()) { 685 // This should never happen currently. 686 Slog.w(TAG, "Ignoring display device because the logical display " 687 + "created from it was not considered valid: " + deviceInfo); 688 return; 689 } 690 691 mLogicalDisplays.put(displayId, display); 692 693 // Wake up waitForDefaultDisplay. 694 if (isDefault) { 695 mSyncRoot.notifyAll(); 696 } 697 698 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED); 699 } 700 701 private int assignDisplayIdLocked(boolean isDefault) { 702 return isDefault ? Display.DEFAULT_DISPLAY : mNextNonDefaultDisplayId++; 703 } 704 705 private int assignLayerStackLocked(int displayId) { 706 // Currently layer stacks and display ids are the same. 707 // This need not be the case. 708 return displayId; 709 } 710 711 // Updates all existing logical displays given the current set of display devices. 712 // Removes invalid logical displays. 713 // Sends notifications if needed. 714 private boolean updateLogicalDisplaysLocked() { 715 boolean changed = false; 716 for (int i = mLogicalDisplays.size(); i-- > 0; ) { 717 final int displayId = mLogicalDisplays.keyAt(i); 718 LogicalDisplay display = mLogicalDisplays.valueAt(i); 719 720 mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked()); 721 display.updateLocked(mDisplayDevices); 722 if (!display.isValidLocked()) { 723 mLogicalDisplays.removeAt(i); 724 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED); 725 changed = true; 726 } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) { 727 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED); 728 changed = true; 729 } 730 } 731 return changed; 732 } 733 734 private void performTraversalInTransactionLocked() { 735 // Clear all viewports before configuring displays so that we can keep 736 // track of which ones we have configured. 737 clearViewportsLocked(); 738 739 // Configure each display device. 740 final int count = mDisplayDevices.size(); 741 for (int i = 0; i < count; i++) { 742 DisplayDevice device = mDisplayDevices.get(i); 743 configureDisplayInTransactionLocked(device); 744 device.performTraversalInTransactionLocked(); 745 } 746 747 // Tell the input system about these new viewports. 748 if (mInputManagerInternal != null) { 749 mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT); 750 } 751 } 752 753 private void setDisplayHasContentInternal(int displayId, boolean hasContent, 754 boolean inTraversal) { 755 synchronized (mSyncRoot) { 756 LogicalDisplay display = mLogicalDisplays.get(displayId); 757 if (display != null && display.hasContentLocked() != hasContent) { 758 if (DEBUG) { 759 Slog.d(TAG, "Display " + displayId + " hasContent flag changed: " 760 + "hasContent=" + hasContent + ", inTraversal=" + inTraversal); 761 } 762 763 display.setHasContentLocked(hasContent); 764 scheduleTraversalLocked(inTraversal); 765 } 766 } 767 } 768 769 private void clearViewportsLocked() { 770 mDefaultViewport.valid = false; 771 mExternalTouchViewport.valid = false; 772 } 773 774 private void configureDisplayInTransactionLocked(DisplayDevice device) { 775 final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 776 final boolean ownContent = (info.flags & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0; 777 778 // Find the logical display that the display device is showing. 779 // Certain displays only ever show their own content. 780 LogicalDisplay display = findLogicalDisplayForDeviceLocked(device); 781 if (!ownContent) { 782 if (display != null && !display.hasContentLocked()) { 783 // If the display does not have any content of its own, then 784 // automatically mirror the default logical display contents. 785 display = null; 786 } 787 if (display == null) { 788 display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY); 789 } 790 } 791 792 // Apply the logical display configuration to the display device. 793 if (display == null) { 794 // TODO: no logical display for the device, blank it 795 Slog.w(TAG, "Missing logical display to use for physical display device: " 796 + device.getDisplayDeviceInfoLocked()); 797 return; 798 } 799 display.configureDisplayInTransactionLocked(device, info.state == Display.STATE_OFF); 800 801 // Update the viewports if needed. 802 if (!mDefaultViewport.valid 803 && (info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) { 804 setViewportLocked(mDefaultViewport, display, device); 805 } 806 if (!mExternalTouchViewport.valid 807 && info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) { 808 setViewportLocked(mExternalTouchViewport, display, device); 809 } 810 } 811 812 private static void setViewportLocked(DisplayViewport viewport, 813 LogicalDisplay display, DisplayDevice device) { 814 viewport.valid = true; 815 viewport.displayId = display.getDisplayIdLocked(); 816 device.populateViewportLocked(viewport); 817 } 818 819 private LogicalDisplay findLogicalDisplayForDeviceLocked(DisplayDevice device) { 820 final int count = mLogicalDisplays.size(); 821 for (int i = 0; i < count; i++) { 822 LogicalDisplay display = mLogicalDisplays.valueAt(i); 823 if (display.getPrimaryDisplayDeviceLocked() == device) { 824 return display; 825 } 826 } 827 return null; 828 } 829 830 private void sendDisplayEventLocked(int displayId, int event) { 831 Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT, displayId, event); 832 mHandler.sendMessage(msg); 833 } 834 835 // Requests that performTraversalsInTransactionFromWindowManager be called at a 836 // later time to apply changes to surfaces and displays. 837 private void scheduleTraversalLocked(boolean inTraversal) { 838 if (!mPendingTraversal && mWindowManagerInternal != null) { 839 mPendingTraversal = true; 840 if (!inTraversal) { 841 mHandler.sendEmptyMessage(MSG_REQUEST_TRAVERSAL); 842 } 843 } 844 } 845 846 // Runs on Handler thread. 847 // Delivers display event notifications to callbacks. 848 private void deliverDisplayEvent(int displayId, int event) { 849 if (DEBUG) { 850 Slog.d(TAG, "Delivering display event: displayId=" 851 + displayId + ", event=" + event); 852 } 853 854 // Grab the lock and copy the callbacks. 855 final int count; 856 synchronized (mSyncRoot) { 857 count = mCallbacks.size(); 858 mTempCallbacks.clear(); 859 for (int i = 0; i < count; i++) { 860 mTempCallbacks.add(mCallbacks.valueAt(i)); 861 } 862 } 863 864 // After releasing the lock, send the notifications out. 865 for (int i = 0; i < count; i++) { 866 mTempCallbacks.get(i).notifyDisplayEventAsync(displayId, event); 867 } 868 mTempCallbacks.clear(); 869 } 870 871 private void dumpInternal(PrintWriter pw) { 872 pw.println("DISPLAY MANAGER (dumpsys display)"); 873 874 synchronized (mSyncRoot) { 875 pw.println(" mOnlyCode=" + mOnlyCore); 876 pw.println(" mSafeMode=" + mSafeMode); 877 pw.println(" mPendingTraversal=" + mPendingTraversal); 878 pw.println(" mGlobalDisplayState=" + Display.stateToString(mGlobalDisplayState)); 879 pw.println(" mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId); 880 pw.println(" mDefaultViewport=" + mDefaultViewport); 881 pw.println(" mExternalTouchViewport=" + mExternalTouchViewport); 882 pw.println(" mSingleDisplayDemoMode=" + mSingleDisplayDemoMode); 883 pw.println(" mWifiDisplayScanRequestCount=" + mWifiDisplayScanRequestCount); 884 885 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 886 ipw.increaseIndent(); 887 888 pw.println(); 889 pw.println("Display Adapters: size=" + mDisplayAdapters.size()); 890 for (DisplayAdapter adapter : mDisplayAdapters) { 891 pw.println(" " + adapter.getName()); 892 adapter.dumpLocked(ipw); 893 } 894 895 pw.println(); 896 pw.println("Display Devices: size=" + mDisplayDevices.size()); 897 for (DisplayDevice device : mDisplayDevices) { 898 pw.println(" " + device.getDisplayDeviceInfoLocked()); 899 device.dumpLocked(ipw); 900 } 901 902 final int logicalDisplayCount = mLogicalDisplays.size(); 903 pw.println(); 904 pw.println("Logical Displays: size=" + logicalDisplayCount); 905 for (int i = 0; i < logicalDisplayCount; i++) { 906 int displayId = mLogicalDisplays.keyAt(i); 907 LogicalDisplay display = mLogicalDisplays.valueAt(i); 908 pw.println(" Display " + displayId + ":"); 909 display.dumpLocked(ipw); 910 } 911 912 final int callbackCount = mCallbacks.size(); 913 pw.println(); 914 pw.println("Callbacks: size=" + callbackCount); 915 for (int i = 0; i < callbackCount; i++) { 916 CallbackRecord callback = mCallbacks.valueAt(i); 917 pw.println(" " + i + ": mPid=" + callback.mPid 918 + ", mWifiDisplayScanRequested=" + callback.mWifiDisplayScanRequested); 919 } 920 921 if (mDisplayPowerController != null) { 922 mDisplayPowerController.dump(pw); 923 } 924 } 925 } 926 927 /** 928 * This is the object that everything in the display manager locks on. 929 * We make it an inner class within the {@link DisplayManagerService} to so that it is 930 * clear that the object belongs to the display manager service and that it is 931 * a unique object with a special purpose. 932 */ 933 public static final class SyncRoot { 934 } 935 936 private final class DisplayManagerHandler extends Handler { 937 public DisplayManagerHandler(Looper looper) { 938 super(looper, null, true /*async*/); 939 } 940 941 @Override 942 public void handleMessage(Message msg) { 943 switch (msg.what) { 944 case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTER: 945 registerDefaultDisplayAdapter(); 946 break; 947 948 case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS: 949 registerAdditionalDisplayAdapters(); 950 break; 951 952 case MSG_DELIVER_DISPLAY_EVENT: 953 deliverDisplayEvent(msg.arg1, msg.arg2); 954 break; 955 956 case MSG_REQUEST_TRAVERSAL: 957 mWindowManagerInternal.requestTraversalFromDisplayManager(); 958 break; 959 960 case MSG_UPDATE_VIEWPORT: { 961 synchronized (mSyncRoot) { 962 mTempDefaultViewport.copyFrom(mDefaultViewport); 963 mTempExternalTouchViewport.copyFrom(mExternalTouchViewport); 964 } 965 mInputManagerInternal.setDisplayViewports( 966 mTempDefaultViewport, mTempExternalTouchViewport); 967 break; 968 } 969 } 970 } 971 } 972 973 private final class DisplayAdapterListener implements DisplayAdapter.Listener { 974 @Override 975 public void onDisplayDeviceEvent(DisplayDevice device, int event) { 976 switch (event) { 977 case DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED: 978 handleDisplayDeviceAdded(device); 979 break; 980 981 case DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED: 982 handleDisplayDeviceChanged(device); 983 break; 984 985 case DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED: 986 handleDisplayDeviceRemoved(device); 987 break; 988 } 989 } 990 991 @Override 992 public void onTraversalRequested() { 993 synchronized (mSyncRoot) { 994 scheduleTraversalLocked(false); 995 } 996 } 997 } 998 999 private final class CallbackRecord implements DeathRecipient { 1000 public final int mPid; 1001 private final IDisplayManagerCallback mCallback; 1002 1003 public boolean mWifiDisplayScanRequested; 1004 1005 public CallbackRecord(int pid, IDisplayManagerCallback callback) { 1006 mPid = pid; 1007 mCallback = callback; 1008 } 1009 1010 @Override 1011 public void binderDied() { 1012 if (DEBUG) { 1013 Slog.d(TAG, "Display listener for pid " + mPid + " died."); 1014 } 1015 onCallbackDied(this); 1016 } 1017 1018 public void notifyDisplayEventAsync(int displayId, int event) { 1019 try { 1020 mCallback.onDisplayEvent(displayId, event); 1021 } catch (RemoteException ex) { 1022 Slog.w(TAG, "Failed to notify process " 1023 + mPid + " that displays changed, assuming it died.", ex); 1024 binderDied(); 1025 } 1026 } 1027 } 1028 1029 private final class BinderService extends IDisplayManager.Stub { 1030 /** 1031 * Returns information about the specified logical display. 1032 * 1033 * @param displayId The logical display id. 1034 * @return The logical display info, or null if the display does not exist. The 1035 * returned object must be treated as immutable. 1036 */ 1037 @Override // Binder call 1038 public DisplayInfo getDisplayInfo(int displayId) { 1039 final int callingUid = Binder.getCallingUid(); 1040 final long token = Binder.clearCallingIdentity(); 1041 try { 1042 return getDisplayInfoInternal(displayId, callingUid); 1043 } finally { 1044 Binder.restoreCallingIdentity(token); 1045 } 1046 } 1047 1048 /** 1049 * Returns the list of all display ids. 1050 */ 1051 @Override // Binder call 1052 public int[] getDisplayIds() { 1053 final int callingUid = Binder.getCallingUid(); 1054 final long token = Binder.clearCallingIdentity(); 1055 try { 1056 return getDisplayIdsInternal(callingUid); 1057 } finally { 1058 Binder.restoreCallingIdentity(token); 1059 } 1060 } 1061 1062 @Override // Binder call 1063 public void registerCallback(IDisplayManagerCallback callback) { 1064 if (callback == null) { 1065 throw new IllegalArgumentException("listener must not be null"); 1066 } 1067 1068 final int callingPid = Binder.getCallingPid(); 1069 final long token = Binder.clearCallingIdentity(); 1070 try { 1071 registerCallbackInternal(callback, callingPid); 1072 } finally { 1073 Binder.restoreCallingIdentity(token); 1074 } 1075 } 1076 1077 @Override // Binder call 1078 public void startWifiDisplayScan() { 1079 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1080 "Permission required to start wifi display scans"); 1081 1082 final int callingPid = Binder.getCallingPid(); 1083 final long token = Binder.clearCallingIdentity(); 1084 try { 1085 startWifiDisplayScanInternal(callingPid); 1086 } finally { 1087 Binder.restoreCallingIdentity(token); 1088 } 1089 } 1090 1091 @Override // Binder call 1092 public void stopWifiDisplayScan() { 1093 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1094 "Permission required to stop wifi display scans"); 1095 1096 final int callingPid = Binder.getCallingPid(); 1097 final long token = Binder.clearCallingIdentity(); 1098 try { 1099 stopWifiDisplayScanInternal(callingPid); 1100 } finally { 1101 Binder.restoreCallingIdentity(token); 1102 } 1103 } 1104 1105 @Override // Binder call 1106 public void connectWifiDisplay(String address) { 1107 if (address == null) { 1108 throw new IllegalArgumentException("address must not be null"); 1109 } 1110 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1111 "Permission required to connect to a wifi display"); 1112 1113 final long token = Binder.clearCallingIdentity(); 1114 try { 1115 connectWifiDisplayInternal(address); 1116 } finally { 1117 Binder.restoreCallingIdentity(token); 1118 } 1119 } 1120 1121 @Override // Binder call 1122 public void disconnectWifiDisplay() { 1123 // This request does not require special permissions. 1124 // Any app can request disconnection from the currently active wifi display. 1125 // This exception should no longer be needed once wifi display control moves 1126 // to the media router service. 1127 1128 final long token = Binder.clearCallingIdentity(); 1129 try { 1130 disconnectWifiDisplayInternal(); 1131 } finally { 1132 Binder.restoreCallingIdentity(token); 1133 } 1134 } 1135 1136 @Override // Binder call 1137 public void renameWifiDisplay(String address, String alias) { 1138 if (address == null) { 1139 throw new IllegalArgumentException("address must not be null"); 1140 } 1141 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1142 "Permission required to rename to a wifi display"); 1143 1144 final long token = Binder.clearCallingIdentity(); 1145 try { 1146 renameWifiDisplayInternal(address, alias); 1147 } finally { 1148 Binder.restoreCallingIdentity(token); 1149 } 1150 } 1151 1152 @Override // Binder call 1153 public void forgetWifiDisplay(String address) { 1154 if (address == null) { 1155 throw new IllegalArgumentException("address must not be null"); 1156 } 1157 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1158 "Permission required to forget to a wifi display"); 1159 1160 final long token = Binder.clearCallingIdentity(); 1161 try { 1162 forgetWifiDisplayInternal(address); 1163 } finally { 1164 Binder.restoreCallingIdentity(token); 1165 } 1166 } 1167 1168 @Override // Binder call 1169 public void pauseWifiDisplay() { 1170 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1171 "Permission required to pause a wifi display session"); 1172 1173 final long token = Binder.clearCallingIdentity(); 1174 try { 1175 pauseWifiDisplayInternal(); 1176 } finally { 1177 Binder.restoreCallingIdentity(token); 1178 } 1179 } 1180 1181 @Override // Binder call 1182 public void resumeWifiDisplay() { 1183 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1184 "Permission required to resume a wifi display session"); 1185 1186 final long token = Binder.clearCallingIdentity(); 1187 try { 1188 resumeWifiDisplayInternal(); 1189 } finally { 1190 Binder.restoreCallingIdentity(token); 1191 } 1192 } 1193 1194 @Override // Binder call 1195 public WifiDisplayStatus getWifiDisplayStatus() { 1196 // This request does not require special permissions. 1197 // Any app can get information about available wifi displays. 1198 1199 final long token = Binder.clearCallingIdentity(); 1200 try { 1201 return getWifiDisplayStatusInternal(); 1202 } finally { 1203 Binder.restoreCallingIdentity(token); 1204 } 1205 } 1206 1207 @Override // Binder call 1208 public int createVirtualDisplay(IBinder appToken, String packageName, 1209 String name, int width, int height, int densityDpi, Surface surface, int flags) { 1210 final int callingUid = Binder.getCallingUid(); 1211 if (!validatePackageName(callingUid, packageName)) { 1212 throw new SecurityException("packageName must match the calling uid"); 1213 } 1214 if (appToken == null) { 1215 throw new IllegalArgumentException("appToken must not be null"); 1216 } 1217 if (TextUtils.isEmpty(name)) { 1218 throw new IllegalArgumentException("name must be non-null and non-empty"); 1219 } 1220 if (width <= 0 || height <= 0 || densityDpi <= 0) { 1221 throw new IllegalArgumentException("width, height, and densityDpi must be " 1222 + "greater than 0"); 1223 } 1224 if (surface == null) { 1225 throw new IllegalArgumentException("surface must not be null"); 1226 } 1227 if (callingUid != Process.SYSTEM_UID && 1228 (flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) { 1229 if (mContext.checkCallingPermission(android.Manifest.permission.CAPTURE_VIDEO_OUTPUT) 1230 != PackageManager.PERMISSION_GRANTED 1231 && mContext.checkCallingPermission( 1232 android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT) 1233 != PackageManager.PERMISSION_GRANTED) { 1234 throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or " 1235 + "CAPTURE_SECURE_VIDEO_OUTPUT permission to create a " 1236 + "public virtual display."); 1237 } 1238 } 1239 if ((flags & DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE) != 0) { 1240 if (mContext.checkCallingPermission( 1241 android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT) 1242 != PackageManager.PERMISSION_GRANTED) { 1243 throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT " 1244 + "to create a secure virtual display."); 1245 } 1246 } 1247 1248 final long token = Binder.clearCallingIdentity(); 1249 try { 1250 return createVirtualDisplayInternal(appToken, callingUid, packageName, 1251 name, width, height, densityDpi, surface, flags); 1252 } finally { 1253 Binder.restoreCallingIdentity(token); 1254 } 1255 } 1256 1257 @Override // Binder call 1258 public void releaseVirtualDisplay(IBinder appToken) { 1259 final long token = Binder.clearCallingIdentity(); 1260 try { 1261 releaseVirtualDisplayInternal(appToken); 1262 } finally { 1263 Binder.restoreCallingIdentity(token); 1264 } 1265 } 1266 1267 @Override // Binder call 1268 public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) { 1269 if (mContext == null 1270 || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP) 1271 != PackageManager.PERMISSION_GRANTED) { 1272 pw.println("Permission Denial: can't dump DisplayManager from from pid=" 1273 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()); 1274 return; 1275 } 1276 1277 final long token = Binder.clearCallingIdentity(); 1278 try { 1279 dumpInternal(pw); 1280 } finally { 1281 Binder.restoreCallingIdentity(token); 1282 } 1283 } 1284 1285 private boolean validatePackageName(int uid, String packageName) { 1286 if (packageName != null) { 1287 String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid); 1288 if (packageNames != null) { 1289 for (String n : packageNames) { 1290 if (n.equals(packageName)) { 1291 return true; 1292 } 1293 } 1294 } 1295 } 1296 return false; 1297 } 1298 } 1299 1300 private final class LocalService extends DisplayManagerInternal { 1301 @Override 1302 public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler, 1303 SensorManager sensorManager) { 1304 synchronized (mSyncRoot) { 1305 DisplayBlanker blanker = new DisplayBlanker() { 1306 @Override 1307 public void requestDisplayState(int state) { 1308 // The order of operations is important for legacy reasons. 1309 if (state == Display.STATE_OFF) { 1310 requestGlobalDisplayStateInternal(state); 1311 } 1312 1313 callbacks.onDisplayStateChange(state); 1314 1315 if (state != Display.STATE_OFF) { 1316 requestGlobalDisplayStateInternal(state); 1317 } 1318 } 1319 }; 1320 mDisplayPowerController = new DisplayPowerController( 1321 mContext, callbacks, handler, sensorManager, blanker); 1322 } 1323 } 1324 1325 @Override 1326 public boolean requestPowerState(DisplayPowerRequest request, 1327 boolean waitForNegativeProximity) { 1328 return mDisplayPowerController.requestPowerState(request, 1329 waitForNegativeProximity); 1330 } 1331 1332 @Override 1333 public boolean isProximitySensorAvailable() { 1334 return mDisplayPowerController.isProximitySensorAvailable(); 1335 } 1336 1337 @Override 1338 public DisplayInfo getDisplayInfo(int displayId) { 1339 return getDisplayInfoInternal(displayId, Process.myUid()); 1340 } 1341 1342 @Override 1343 public void registerDisplayTransactionListener(DisplayTransactionListener listener) { 1344 if (listener == null) { 1345 throw new IllegalArgumentException("listener must not be null"); 1346 } 1347 1348 registerDisplayTransactionListenerInternal(listener); 1349 } 1350 1351 @Override 1352 public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) { 1353 if (listener == null) { 1354 throw new IllegalArgumentException("listener must not be null"); 1355 } 1356 1357 unregisterDisplayTransactionListenerInternal(listener); 1358 } 1359 1360 @Override 1361 public void setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info) { 1362 setDisplayInfoOverrideFromWindowManagerInternal(displayId, info); 1363 } 1364 1365 @Override 1366 public void performTraversalInTransactionFromWindowManager() { 1367 performTraversalInTransactionFromWindowManagerInternal(); 1368 } 1369 1370 @Override 1371 public void setDisplayHasContent(int displayId, boolean hasContent, boolean inTraversal) { 1372 setDisplayHasContentInternal(displayId, hasContent, inTraversal); 1373 } 1374 } 1375} 1376