1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.display; 18 19 import static android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT; 20 import static android.Manifest.permission.CAPTURE_VIDEO_OUTPUT; 21 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; 22 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; 23 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD; 24 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY; 25 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; 26 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE; 27 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; 28 import static android.hardware.display.DisplayViewport.VIEWPORT_EXTERNAL; 29 import static android.hardware.display.DisplayViewport.VIEWPORT_INTERNAL; 30 import static android.hardware.display.DisplayViewport.VIEWPORT_VIRTUAL; 31 32 import android.Manifest; 33 import android.annotation.NonNull; 34 import android.annotation.Nullable; 35 import android.annotation.UserIdInt; 36 import android.app.AppOpsManager; 37 import android.content.Context; 38 import android.content.pm.PackageManager; 39 import android.content.pm.ParceledListSlice; 40 import android.content.res.Resources; 41 import android.content.res.TypedArray; 42 import android.graphics.ColorSpace; 43 import android.graphics.Point; 44 import android.graphics.Rect; 45 import android.hardware.SensorManager; 46 import android.hardware.display.AmbientBrightnessDayStats; 47 import android.hardware.display.BrightnessChangeEvent; 48 import android.hardware.display.BrightnessConfiguration; 49 import android.hardware.display.Curve; 50 import android.hardware.display.DisplayManagerGlobal; 51 import android.hardware.display.DisplayManagerInternal; 52 import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener; 53 import android.hardware.display.DisplayViewport; 54 import android.hardware.display.DisplayedContentSample; 55 import android.hardware.display.DisplayedContentSamplingAttributes; 56 import android.hardware.display.IDisplayManager; 57 import android.hardware.display.IDisplayManagerCallback; 58 import android.hardware.display.IVirtualDisplayCallback; 59 import android.hardware.display.WifiDisplayStatus; 60 import android.hardware.input.InputManagerInternal; 61 import android.media.projection.IMediaProjection; 62 import android.media.projection.IMediaProjectionManager; 63 import android.os.Binder; 64 import android.os.Handler; 65 import android.os.IBinder; 66 import android.os.IBinder.DeathRecipient; 67 import android.os.Looper; 68 import android.os.Message; 69 import android.os.PowerManager; 70 import android.os.Process; 71 import android.os.RemoteException; 72 import android.os.ResultReceiver; 73 import android.os.ServiceManager; 74 import android.os.ShellCallback; 75 import android.os.SystemClock; 76 import android.os.SystemProperties; 77 import android.os.Trace; 78 import android.os.UserHandle; 79 import android.os.UserManager; 80 import android.provider.Settings; 81 import android.text.TextUtils; 82 import android.util.IntArray; 83 import android.util.Pair; 84 import android.util.Slog; 85 import android.util.SparseArray; 86 import android.util.Spline; 87 import android.view.Display; 88 import android.view.DisplayInfo; 89 import android.view.Surface; 90 import android.view.SurfaceControl; 91 92 import com.android.internal.annotations.GuardedBy; 93 import com.android.internal.annotations.VisibleForTesting; 94 import com.android.internal.util.DumpUtils; 95 import com.android.internal.util.IndentingPrintWriter; 96 import com.android.server.AnimationThread; 97 import com.android.server.DisplayThread; 98 import com.android.server.LocalServices; 99 import com.android.server.SystemService; 100 import com.android.server.UiThread; 101 import com.android.server.wm.SurfaceAnimationThread; 102 import com.android.server.wm.WindowManagerInternal; 103 104 import java.io.FileDescriptor; 105 import java.io.PrintWriter; 106 import java.util.ArrayList; 107 import java.util.Arrays; 108 import java.util.List; 109 import java.util.concurrent.CopyOnWriteArrayList; 110 111 /** 112 * Manages attached displays. 113 * <p> 114 * The {@link DisplayManagerService} manages the global lifecycle of displays, 115 * decides how to configure logical displays based on the physical display devices currently 116 * attached, sends notifications to the system and to applications when the state 117 * changes, and so on. 118 * </p><p> 119 * The display manager service relies on a collection of {@link DisplayAdapter} components, 120 * for discovering and configuring physical display devices attached to the system. 121 * There are separate display adapters for each manner that devices are attached: 122 * one display adapter for built-in local displays, one for simulated non-functional 123 * displays when the system is headless, one for simulated overlay displays used for 124 * development, one for wifi displays, etc. 125 * </p><p> 126 * Display adapters are only weakly coupled to the display manager service. 127 * Display adapters communicate changes in display device state to the display manager 128 * service asynchronously via a {@link DisplayAdapter.Listener} registered 129 * by the display manager service. This separation of concerns is important for 130 * two main reasons. First, it neatly encapsulates the responsibilities of these 131 * two classes: display adapters handle individual display devices whereas 132 * the display manager service handles the global state. Second, it eliminates 133 * the potential for deadlocks resulting from asynchronous display device discovery. 134 * </p> 135 * 136 * <h3>Synchronization</h3> 137 * <p> 138 * Because the display manager may be accessed by multiple threads, the synchronization 139 * story gets a little complicated. In particular, the window manager may call into 140 * the display manager while holding a surface transaction with the expectation that 141 * it can apply changes immediately. Unfortunately, that means we can't just do 142 * everything asynchronously (*grump*). 143 * </p><p> 144 * To make this work, all of the objects that belong to the display manager must 145 * use the same lock. We call this lock the synchronization root and it has a unique 146 * type {@link DisplayManagerService.SyncRoot}. Methods that require this lock are 147 * named with the "Locked" suffix. 148 * </p><p> 149 * Where things get tricky is that the display manager is not allowed to make 150 * any potentially reentrant calls, especially into the window manager. We generally 151 * avoid this by making all potentially reentrant out-calls asynchronous. 152 * </p> 153 */ 154 public final class DisplayManagerService extends SystemService { 155 private static final String TAG = "DisplayManagerService"; 156 private static final boolean DEBUG = false; 157 158 // When this system property is set to 0, WFD is forcibly disabled on boot. 159 // When this system property is set to 1, WFD is forcibly enabled on boot. 160 // Otherwise WFD is enabled according to the value of config_enableWifiDisplay. 161 private static final String FORCE_WIFI_DISPLAY_ENABLE = "persist.debug.wfd.enable"; 162 163 private static final String PROP_DEFAULT_DISPLAY_TOP_INSET = "persist.sys.displayinset.top"; 164 165 private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000; 166 167 private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1; 168 private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2; 169 private static final int MSG_DELIVER_DISPLAY_EVENT = 3; 170 private static final int MSG_REQUEST_TRAVERSAL = 4; 171 private static final int MSG_UPDATE_VIEWPORT = 5; 172 private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATION = 6; 173 174 private final Context mContext; 175 private final DisplayManagerHandler mHandler; 176 private final Handler mUiHandler; 177 private final DisplayAdapterListener mDisplayAdapterListener; 178 private final DisplayModeDirector mDisplayModeDirector; 179 private WindowManagerInternal mWindowManagerInternal; 180 private InputManagerInternal mInputManagerInternal; 181 private IMediaProjectionManager mProjectionService; 182 183 // The synchronization root for the display manager. 184 // This lock guards most of the display manager's state. 185 // NOTE: This is synchronized on while holding WindowManagerService.mWindowMap so never call 186 // into WindowManagerService methods that require mWindowMap while holding this unless you are 187 // very very sure that no deadlock can occur. 188 private final SyncRoot mSyncRoot = new SyncRoot(); 189 190 // True if in safe mode. 191 // This option may disable certain display adapters. 192 public boolean mSafeMode; 193 194 // True if we are in a special boot mode where only core applications and 195 // services should be started. This option may disable certain display adapters. 196 public boolean mOnlyCore; 197 198 // True if the display manager service should pretend there is only one display 199 // and only tell applications about the existence of the default logical display. 200 // The display manager can still mirror content to secondary displays but applications 201 // cannot present unique content on those displays. 202 // Used for demonstration purposes only. 203 private final boolean mSingleDisplayDemoMode; 204 205 // All callback records indexed by calling process id. 206 public final SparseArray<CallbackRecord> mCallbacks = 207 new SparseArray<CallbackRecord>(); 208 209 // List of all currently registered display adapters. 210 private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>(); 211 212 // List of all currently connected display devices. 213 private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>(); 214 215 // List of all logical displays indexed by logical display id. 216 private final SparseArray<LogicalDisplay> mLogicalDisplays = 217 new SparseArray<LogicalDisplay>(); 218 private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1; 219 220 // List of all display transaction listeners. 221 private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners = 222 new CopyOnWriteArrayList<DisplayTransactionListener>(); 223 224 // Display power controller. 225 private DisplayPowerController mDisplayPowerController; 226 227 // The overall display state, independent of changes that might influence one 228 // display or another in particular. 229 private int mGlobalDisplayState = Display.STATE_ON; 230 231 // The overall display brightness. 232 // For now, this only applies to the built-in display but we may split it up eventually. 233 private int mGlobalDisplayBrightness = PowerManager.BRIGHTNESS_DEFAULT; 234 235 // Set to true when there are pending display changes that have yet to be applied 236 // to the surface flinger state. 237 private boolean mPendingTraversal; 238 239 // The Wifi display adapter, or null if not registered. 240 private WifiDisplayAdapter mWifiDisplayAdapter; 241 242 // The number of active wifi display scan requests. 243 private int mWifiDisplayScanRequestCount; 244 245 // The virtual display adapter, or null if not registered. 246 private VirtualDisplayAdapter mVirtualDisplayAdapter; 247 248 // The User ID of the current user 249 private @UserIdInt int mCurrentUserId; 250 251 // The stable device screen height and width. These are not tied to a specific display, even 252 // the default display, because they need to be stable over the course of the device's entire 253 // life, even if the default display changes (e.g. a new monitor is plugged into a PC-like 254 // device). 255 private Point mStableDisplaySize = new Point(); 256 257 // Whether the system has finished booting or not. 258 private boolean mSystemReady; 259 260 // The top inset of the default display. 261 // This gets persisted so that the boot animation knows how to transition from the display's 262 // full size to the size configured by the user. Right now we only persist and animate the top 263 // inset, but theoretically we could do it for all of them. 264 private int mDefaultDisplayTopInset; 265 266 // Viewports of the default display and the display that should receive touch 267 // input from an external source. Used by the input system. 268 @GuardedBy("mSyncRoot") 269 private final ArrayList<DisplayViewport> mViewports = new ArrayList<>(); 270 271 // Persistent data store for all internal settings maintained by the display manager service. 272 private final PersistentDataStore mPersistentDataStore = new PersistentDataStore(); 273 274 // Temporary callback list, used when sending display events to applications. 275 // May be used outside of the lock but only on the handler thread. 276 private final ArrayList<CallbackRecord> mTempCallbacks = new ArrayList<CallbackRecord>(); 277 278 // Temporary display info, used for comparing display configurations. 279 private final DisplayInfo mTempDisplayInfo = new DisplayInfo(); 280 281 // Temporary viewports, used when sending new viewport information to the 282 // input system. May be used outside of the lock but only on the handler thread. 283 private final ArrayList<DisplayViewport> mTempViewports = new ArrayList<>(); 284 285 // The default color mode for default displays. Overrides the usual 286 // Display.Display.COLOR_MODE_DEFAULT for displays with the 287 // DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY flag set. 288 private final int mDefaultDisplayDefaultColorMode; 289 290 // Temporary list of deferred work to perform when setting the display state. 291 // Only used by requestDisplayState. The field is self-synchronized and only 292 // intended for use inside of the requestGlobalDisplayStateInternal function. 293 private final ArrayList<Runnable> mTempDisplayStateWorkQueue = new ArrayList<Runnable>(); 294 295 // Lists of UIDs that are present on the displays. Maps displayId -> array of UIDs. 296 private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>(); 297 298 private final Injector mInjector; 299 300 // The minimum brightness curve, which guarantess that any brightness curve that dips below it 301 // is rejected by the system. 302 private final Curve mMinimumBrightnessCurve; 303 private final Spline mMinimumBrightnessSpline; 304 private final ColorSpace mWideColorSpace; 305 306 private SensorManager mSensorManager; 307 DisplayManagerService(Context context)308 public DisplayManagerService(Context context) { 309 this(context, new Injector()); 310 } 311 312 @VisibleForTesting DisplayManagerService(Context context, Injector injector)313 DisplayManagerService(Context context, Injector injector) { 314 super(context); 315 mInjector = injector; 316 mContext = context; 317 mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper()); 318 mUiHandler = UiThread.getHandler(); 319 mDisplayAdapterListener = new DisplayAdapterListener(); 320 mDisplayModeDirector = new DisplayModeDirector(context, mHandler); 321 mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false); 322 Resources resources = mContext.getResources(); 323 mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger( 324 com.android.internal.R.integer.config_defaultDisplayDefaultColorMode); 325 mDefaultDisplayTopInset = SystemProperties.getInt(PROP_DEFAULT_DISPLAY_TOP_INSET, -1); 326 float[] lux = getFloatArray(resources.obtainTypedArray( 327 com.android.internal.R.array.config_minimumBrightnessCurveLux)); 328 float[] nits = getFloatArray(resources.obtainTypedArray( 329 com.android.internal.R.array.config_minimumBrightnessCurveNits)); 330 mMinimumBrightnessCurve = new Curve(lux, nits); 331 mMinimumBrightnessSpline = Spline.createSpline(lux, nits); 332 333 PowerManager pm = mContext.getSystemService(PowerManager.class); 334 mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting(); 335 mCurrentUserId = UserHandle.USER_SYSTEM; 336 ColorSpace[] colorSpaces = SurfaceControl.getCompositionColorSpaces(); 337 mWideColorSpace = colorSpaces[1]; 338 339 mSystemReady = false; 340 } 341 setupSchedulerPolicies()342 public void setupSchedulerPolicies() { 343 // android.display and android.anim is critical to user experience and we should make sure 344 // it is not in the default foregroup groups, add it to top-app to make sure it uses all 345 // the cores and scheduling settings for top-app when it runs. 346 Process.setThreadGroupAndCpuset(DisplayThread.get().getThreadId(), 347 Process.THREAD_GROUP_TOP_APP); 348 Process.setThreadGroupAndCpuset(AnimationThread.get().getThreadId(), 349 Process.THREAD_GROUP_TOP_APP); 350 Process.setThreadGroupAndCpuset(SurfaceAnimationThread.get().getThreadId(), 351 Process.THREAD_GROUP_TOP_APP); 352 } 353 354 @Override onStart()355 public void onStart() { 356 // We need to pre-load the persistent data store so it's ready before the default display 357 // adapter is up so that we have it's configuration. We could load it lazily, but since 358 // we're going to have to read it in eventually we may as well do it here rather than after 359 // we've waited for the display to register itself with us. 360 synchronized (mSyncRoot) { 361 mPersistentDataStore.loadIfNeeded(); 362 loadStableDisplayValuesLocked(); 363 } 364 mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS); 365 366 publishBinderService(Context.DISPLAY_SERVICE, new BinderService(), 367 true /*allowIsolated*/); 368 publishLocalService(DisplayManagerInternal.class, new LocalService()); 369 } 370 371 @Override onBootPhase(int phase)372 public void onBootPhase(int phase) { 373 if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) { 374 synchronized (mSyncRoot) { 375 long timeout = SystemClock.uptimeMillis() 376 + mInjector.getDefaultDisplayDelayTimeout(); 377 while (mLogicalDisplays.get(Display.DEFAULT_DISPLAY) == null || 378 mVirtualDisplayAdapter == null) { 379 long delay = timeout - SystemClock.uptimeMillis(); 380 if (delay <= 0) { 381 throw new RuntimeException("Timeout waiting for default display " 382 + "to be initialized. DefaultDisplay=" 383 + mLogicalDisplays.get(Display.DEFAULT_DISPLAY) 384 + ", mVirtualDisplayAdapter=" + mVirtualDisplayAdapter); 385 } 386 if (DEBUG) { 387 Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay); 388 } 389 try { 390 mSyncRoot.wait(delay); 391 } catch (InterruptedException ex) { 392 } 393 } 394 } 395 } 396 } 397 398 @Override onSwitchUser(@serIdInt int newUserId)399 public void onSwitchUser(@UserIdInt int newUserId) { 400 final int userSerial = getUserManager().getUserSerialNumber(newUserId); 401 synchronized (mSyncRoot) { 402 if (mCurrentUserId != newUserId) { 403 mCurrentUserId = newUserId; 404 BrightnessConfiguration config = 405 mPersistentDataStore.getBrightnessConfiguration(userSerial); 406 mDisplayPowerController.setBrightnessConfiguration(config); 407 } 408 mDisplayPowerController.onSwitchUser(newUserId); 409 } 410 } 411 412 // TODO: Use dependencies or a boot phase windowManagerAndInputReady()413 public void windowManagerAndInputReady() { 414 synchronized (mSyncRoot) { 415 mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class); 416 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); 417 scheduleTraversalLocked(false); 418 } 419 } 420 421 /** 422 * Called when the system is ready to go. 423 */ systemReady(boolean safeMode, boolean onlyCore)424 public void systemReady(boolean safeMode, boolean onlyCore) { 425 synchronized (mSyncRoot) { 426 mSafeMode = safeMode; 427 mOnlyCore = onlyCore; 428 mSystemReady = true; 429 // Just in case the top inset changed before the system was ready. At this point, any 430 // relevant configuration should be in place. 431 recordTopInsetLocked(mLogicalDisplays.get(Display.DEFAULT_DISPLAY)); 432 } 433 434 mDisplayModeDirector.setListener(new AllowedDisplayModeObserver()); 435 mDisplayModeDirector.start(mSensorManager); 436 437 mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS); 438 } 439 440 @VisibleForTesting getDisplayHandler()441 Handler getDisplayHandler() { 442 return mHandler; 443 } 444 loadStableDisplayValuesLocked()445 private void loadStableDisplayValuesLocked() { 446 final Point size = mPersistentDataStore.getStableDisplaySize(); 447 if (size.x > 0 && size.y > 0) { 448 // Just set these values directly so we don't write the display persistent data again 449 // unnecessarily 450 mStableDisplaySize.set(size.x, size.y); 451 } else { 452 final Resources res = mContext.getResources(); 453 final int width = res.getInteger( 454 com.android.internal.R.integer.config_stableDeviceDisplayWidth); 455 final int height = res.getInteger( 456 com.android.internal.R.integer.config_stableDeviceDisplayHeight); 457 if (width > 0 && height > 0) { 458 setStableDisplaySizeLocked(width, height); 459 } 460 } 461 } 462 getStableDisplaySizeInternal()463 private Point getStableDisplaySizeInternal() { 464 Point r = new Point(); 465 synchronized (mSyncRoot) { 466 if (mStableDisplaySize.x > 0 && mStableDisplaySize.y > 0) { 467 r.set(mStableDisplaySize.x, mStableDisplaySize.y); 468 } 469 } 470 return r; 471 } 472 registerDisplayTransactionListenerInternal( DisplayTransactionListener listener)473 private void registerDisplayTransactionListenerInternal( 474 DisplayTransactionListener listener) { 475 // List is self-synchronized copy-on-write. 476 mDisplayTransactionListeners.add(listener); 477 } 478 unregisterDisplayTransactionListenerInternal( DisplayTransactionListener listener)479 private void unregisterDisplayTransactionListenerInternal( 480 DisplayTransactionListener listener) { 481 // List is self-synchronized copy-on-write. 482 mDisplayTransactionListeners.remove(listener); 483 } 484 setDisplayInfoOverrideFromWindowManagerInternal( int displayId, DisplayInfo info)485 private void setDisplayInfoOverrideFromWindowManagerInternal( 486 int displayId, DisplayInfo info) { 487 synchronized (mSyncRoot) { 488 LogicalDisplay display = mLogicalDisplays.get(displayId); 489 if (display != null) { 490 if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) { 491 handleLogicalDisplayChanged(displayId, display); 492 scheduleTraversalLocked(false); 493 } 494 } 495 } 496 } 497 498 /** 499 * @see DisplayManagerInternal#getNonOverrideDisplayInfo(int, DisplayInfo) 500 */ getNonOverrideDisplayInfoInternal(int displayId, DisplayInfo outInfo)501 private void getNonOverrideDisplayInfoInternal(int displayId, DisplayInfo outInfo) { 502 synchronized (mSyncRoot) { 503 final LogicalDisplay display = mLogicalDisplays.get(displayId); 504 if (display != null) { 505 display.getNonOverrideDisplayInfoLocked(outInfo); 506 } 507 } 508 } 509 510 @VisibleForTesting performTraversalInternal(SurfaceControl.Transaction t)511 void performTraversalInternal(SurfaceControl.Transaction t) { 512 synchronized (mSyncRoot) { 513 if (!mPendingTraversal) { 514 return; 515 } 516 mPendingTraversal = false; 517 518 performTraversalLocked(t); 519 } 520 521 // List is self-synchronized copy-on-write. 522 for (DisplayTransactionListener listener : mDisplayTransactionListeners) { 523 listener.onDisplayTransaction(t); 524 } 525 } 526 requestGlobalDisplayStateInternal(int state, int brightness)527 private void requestGlobalDisplayStateInternal(int state, int brightness) { 528 if (state == Display.STATE_UNKNOWN) { 529 state = Display.STATE_ON; 530 } 531 if (state == Display.STATE_OFF) { 532 brightness = PowerManager.BRIGHTNESS_OFF; 533 } else if (brightness < 0) { 534 brightness = PowerManager.BRIGHTNESS_DEFAULT; 535 } else if (brightness > PowerManager.BRIGHTNESS_ON) { 536 brightness = PowerManager.BRIGHTNESS_ON; 537 } 538 539 synchronized (mTempDisplayStateWorkQueue) { 540 try { 541 // Update the display state within the lock. 542 // Note that we do not need to schedule traversals here although it 543 // may happen as a side-effect of displays changing state. 544 synchronized (mSyncRoot) { 545 if (mGlobalDisplayState == state 546 && mGlobalDisplayBrightness == brightness) { 547 return; // no change 548 } 549 550 Trace.traceBegin(Trace.TRACE_TAG_POWER, "requestGlobalDisplayState(" 551 + Display.stateToString(state) 552 + ", brightness=" + brightness + ")"); 553 mGlobalDisplayState = state; 554 mGlobalDisplayBrightness = brightness; 555 applyGlobalDisplayStateLocked(mTempDisplayStateWorkQueue); 556 } 557 558 // Setting the display power state can take hundreds of milliseconds 559 // to complete so we defer the most expensive part of the work until 560 // after we have exited the critical section to avoid blocking other 561 // threads for a long time. 562 for (int i = 0; i < mTempDisplayStateWorkQueue.size(); i++) { 563 mTempDisplayStateWorkQueue.get(i).run(); 564 } 565 Trace.traceEnd(Trace.TRACE_TAG_POWER); 566 } finally { 567 mTempDisplayStateWorkQueue.clear(); 568 } 569 } 570 } 571 getDisplayInfoInternal(int displayId, int callingUid)572 private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) { 573 synchronized (mSyncRoot) { 574 LogicalDisplay display = mLogicalDisplays.get(displayId); 575 if (display != null) { 576 DisplayInfo info = display.getDisplayInfoLocked(); 577 if (info.hasAccess(callingUid) 578 || isUidPresentOnDisplayInternal(callingUid, displayId)) { 579 return info; 580 } 581 } 582 return null; 583 } 584 } 585 getDisplayIdsInternal(int callingUid)586 private int[] getDisplayIdsInternal(int callingUid) { 587 synchronized (mSyncRoot) { 588 final int count = mLogicalDisplays.size(); 589 int[] displayIds = new int[count]; 590 int n = 0; 591 for (int i = 0; i < count; i++) { 592 LogicalDisplay display = mLogicalDisplays.valueAt(i); 593 DisplayInfo info = display.getDisplayInfoLocked(); 594 if (info.hasAccess(callingUid)) { 595 displayIds[n++] = mLogicalDisplays.keyAt(i); 596 } 597 } 598 if (n != count) { 599 displayIds = Arrays.copyOfRange(displayIds, 0, n); 600 } 601 return displayIds; 602 } 603 } 604 registerCallbackInternal(IDisplayManagerCallback callback, int callingPid)605 private void registerCallbackInternal(IDisplayManagerCallback callback, int callingPid) { 606 synchronized (mSyncRoot) { 607 if (mCallbacks.get(callingPid) != null) { 608 throw new SecurityException("The calling process has already " 609 + "registered an IDisplayManagerCallback."); 610 } 611 612 CallbackRecord record = new CallbackRecord(callingPid, callback); 613 try { 614 IBinder binder = callback.asBinder(); 615 binder.linkToDeath(record, 0); 616 } catch (RemoteException ex) { 617 // give up 618 throw new RuntimeException(ex); 619 } 620 621 mCallbacks.put(callingPid, record); 622 } 623 } 624 onCallbackDied(CallbackRecord record)625 private void onCallbackDied(CallbackRecord record) { 626 synchronized (mSyncRoot) { 627 mCallbacks.remove(record.mPid); 628 stopWifiDisplayScanLocked(record); 629 } 630 } 631 startWifiDisplayScanInternal(int callingPid)632 private void startWifiDisplayScanInternal(int callingPid) { 633 synchronized (mSyncRoot) { 634 CallbackRecord record = mCallbacks.get(callingPid); 635 if (record == null) { 636 throw new IllegalStateException("The calling process has not " 637 + "registered an IDisplayManagerCallback."); 638 } 639 startWifiDisplayScanLocked(record); 640 } 641 } 642 startWifiDisplayScanLocked(CallbackRecord record)643 private void startWifiDisplayScanLocked(CallbackRecord record) { 644 if (!record.mWifiDisplayScanRequested) { 645 record.mWifiDisplayScanRequested = true; 646 if (mWifiDisplayScanRequestCount++ == 0) { 647 if (mWifiDisplayAdapter != null) { 648 mWifiDisplayAdapter.requestStartScanLocked(); 649 } 650 } 651 } 652 } 653 stopWifiDisplayScanInternal(int callingPid)654 private void stopWifiDisplayScanInternal(int callingPid) { 655 synchronized (mSyncRoot) { 656 CallbackRecord record = mCallbacks.get(callingPid); 657 if (record == null) { 658 throw new IllegalStateException("The calling process has not " 659 + "registered an IDisplayManagerCallback."); 660 } 661 stopWifiDisplayScanLocked(record); 662 } 663 } 664 stopWifiDisplayScanLocked(CallbackRecord record)665 private void stopWifiDisplayScanLocked(CallbackRecord record) { 666 if (record.mWifiDisplayScanRequested) { 667 record.mWifiDisplayScanRequested = false; 668 if (--mWifiDisplayScanRequestCount == 0) { 669 if (mWifiDisplayAdapter != null) { 670 mWifiDisplayAdapter.requestStopScanLocked(); 671 } 672 } else if (mWifiDisplayScanRequestCount < 0) { 673 Slog.wtf(TAG, "mWifiDisplayScanRequestCount became negative: " 674 + mWifiDisplayScanRequestCount); 675 mWifiDisplayScanRequestCount = 0; 676 } 677 } 678 } 679 connectWifiDisplayInternal(String address)680 private void connectWifiDisplayInternal(String address) { 681 synchronized (mSyncRoot) { 682 if (mWifiDisplayAdapter != null) { 683 mWifiDisplayAdapter.requestConnectLocked(address); 684 } 685 } 686 } 687 pauseWifiDisplayInternal()688 private void pauseWifiDisplayInternal() { 689 synchronized (mSyncRoot) { 690 if (mWifiDisplayAdapter != null) { 691 mWifiDisplayAdapter.requestPauseLocked(); 692 } 693 } 694 } 695 resumeWifiDisplayInternal()696 private void resumeWifiDisplayInternal() { 697 synchronized (mSyncRoot) { 698 if (mWifiDisplayAdapter != null) { 699 mWifiDisplayAdapter.requestResumeLocked(); 700 } 701 } 702 } 703 disconnectWifiDisplayInternal()704 private void disconnectWifiDisplayInternal() { 705 synchronized (mSyncRoot) { 706 if (mWifiDisplayAdapter != null) { 707 mWifiDisplayAdapter.requestDisconnectLocked(); 708 } 709 } 710 } 711 renameWifiDisplayInternal(String address, String alias)712 private void renameWifiDisplayInternal(String address, String alias) { 713 synchronized (mSyncRoot) { 714 if (mWifiDisplayAdapter != null) { 715 mWifiDisplayAdapter.requestRenameLocked(address, alias); 716 } 717 } 718 } 719 forgetWifiDisplayInternal(String address)720 private void forgetWifiDisplayInternal(String address) { 721 synchronized (mSyncRoot) { 722 if (mWifiDisplayAdapter != null) { 723 mWifiDisplayAdapter.requestForgetLocked(address); 724 } 725 } 726 } 727 getWifiDisplayStatusInternal()728 private WifiDisplayStatus getWifiDisplayStatusInternal() { 729 synchronized (mSyncRoot) { 730 if (mWifiDisplayAdapter != null) { 731 return mWifiDisplayAdapter.getWifiDisplayStatusLocked(); 732 } 733 return new WifiDisplayStatus(); 734 } 735 } 736 requestColorModeInternal(int displayId, int colorMode)737 private void requestColorModeInternal(int displayId, int colorMode) { 738 synchronized (mSyncRoot) { 739 LogicalDisplay display = mLogicalDisplays.get(displayId); 740 if (display != null && 741 display.getRequestedColorModeLocked() != colorMode) { 742 display.setRequestedColorModeLocked(colorMode); 743 scheduleTraversalLocked(false); 744 } 745 } 746 } 747 createVirtualDisplayInternal(IVirtualDisplayCallback callback, IMediaProjection projection, int callingUid, String packageName, String name, int width, int height, int densityDpi, Surface surface, int flags, String uniqueId)748 private int createVirtualDisplayInternal(IVirtualDisplayCallback callback, 749 IMediaProjection projection, int callingUid, String packageName, String name, int width, 750 int height, int densityDpi, Surface surface, int flags, String uniqueId) { 751 synchronized (mSyncRoot) { 752 if (mVirtualDisplayAdapter == null) { 753 Slog.w(TAG, "Rejecting request to create private virtual display " 754 + "because the virtual display adapter is not available."); 755 return -1; 756 } 757 758 DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked( 759 callback, projection, callingUid, packageName, name, width, height, densityDpi, 760 surface, flags, uniqueId); 761 if (device == null) { 762 return -1; 763 } 764 765 handleDisplayDeviceAddedLocked(device); 766 LogicalDisplay display = findLogicalDisplayForDeviceLocked(device); 767 if (display != null) { 768 return display.getDisplayIdLocked(); 769 } 770 771 // Something weird happened and the logical display was not created. 772 Slog.w(TAG, "Rejecting request to create virtual display " 773 + "because the logical display was not created."); 774 mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callback.asBinder()); 775 handleDisplayDeviceRemovedLocked(device); 776 } 777 return -1; 778 } 779 resizeVirtualDisplayInternal(IBinder appToken, int width, int height, int densityDpi)780 private void resizeVirtualDisplayInternal(IBinder appToken, 781 int width, int height, int densityDpi) { 782 synchronized (mSyncRoot) { 783 if (mVirtualDisplayAdapter == null) { 784 return; 785 } 786 787 mVirtualDisplayAdapter.resizeVirtualDisplayLocked(appToken, width, height, densityDpi); 788 } 789 } 790 setVirtualDisplaySurfaceInternal(IBinder appToken, Surface surface)791 private void setVirtualDisplaySurfaceInternal(IBinder appToken, Surface surface) { 792 synchronized (mSyncRoot) { 793 if (mVirtualDisplayAdapter == null) { 794 return; 795 } 796 797 mVirtualDisplayAdapter.setVirtualDisplaySurfaceLocked(appToken, surface); 798 } 799 } 800 releaseVirtualDisplayInternal(IBinder appToken)801 private void releaseVirtualDisplayInternal(IBinder appToken) { 802 synchronized (mSyncRoot) { 803 if (mVirtualDisplayAdapter == null) { 804 return; 805 } 806 807 DisplayDevice device = 808 mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken); 809 if (device != null) { 810 handleDisplayDeviceRemovedLocked(device); 811 } 812 } 813 } 814 setVirtualDisplayStateInternal(IBinder appToken, boolean isOn)815 private void setVirtualDisplayStateInternal(IBinder appToken, boolean isOn) { 816 synchronized (mSyncRoot) { 817 if (mVirtualDisplayAdapter == null) { 818 return; 819 } 820 821 mVirtualDisplayAdapter.setVirtualDisplayStateLocked(appToken, isOn); 822 } 823 } 824 registerDefaultDisplayAdapters()825 private void registerDefaultDisplayAdapters() { 826 // Register default display adapters. 827 synchronized (mSyncRoot) { 828 // main display adapter 829 registerDisplayAdapterLocked(new LocalDisplayAdapter( 830 mSyncRoot, mContext, mHandler, mDisplayAdapterListener)); 831 832 // Standalone VR devices rely on a virtual display as their primary display for 833 // 2D UI. We register virtual display adapter along side the main display adapter 834 // here so that it is ready by the time the system sends the home Intent for 835 // early apps like SetupWizard/Launcher. In particular, SUW is displayed using 836 // the virtual display inside VR before any VR-specific apps even run. 837 mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext, 838 mHandler, mDisplayAdapterListener); 839 if (mVirtualDisplayAdapter != null) { 840 registerDisplayAdapterLocked(mVirtualDisplayAdapter); 841 } 842 } 843 } 844 registerAdditionalDisplayAdapters()845 private void registerAdditionalDisplayAdapters() { 846 synchronized (mSyncRoot) { 847 if (shouldRegisterNonEssentialDisplayAdaptersLocked()) { 848 registerOverlayDisplayAdapterLocked(); 849 registerWifiDisplayAdapterLocked(); 850 } 851 } 852 } 853 registerOverlayDisplayAdapterLocked()854 private void registerOverlayDisplayAdapterLocked() { 855 registerDisplayAdapterLocked(new OverlayDisplayAdapter( 856 mSyncRoot, mContext, mHandler, mDisplayAdapterListener, mUiHandler)); 857 } 858 registerWifiDisplayAdapterLocked()859 private void registerWifiDisplayAdapterLocked() { 860 if (mContext.getResources().getBoolean( 861 com.android.internal.R.bool.config_enableWifiDisplay) 862 || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) { 863 mWifiDisplayAdapter = new WifiDisplayAdapter( 864 mSyncRoot, mContext, mHandler, mDisplayAdapterListener, 865 mPersistentDataStore); 866 registerDisplayAdapterLocked(mWifiDisplayAdapter); 867 } 868 } 869 shouldRegisterNonEssentialDisplayAdaptersLocked()870 private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() { 871 // In safe mode, we disable non-essential display adapters to give the user 872 // an opportunity to fix broken settings or other problems that might affect 873 // system stability. 874 // In only-core mode, we disable non-essential display adapters to minimize 875 // the number of dependencies that are started while in this mode and to 876 // prevent problems that might occur due to the device being encrypted. 877 return !mSafeMode && !mOnlyCore; 878 } 879 registerDisplayAdapterLocked(DisplayAdapter adapter)880 private void registerDisplayAdapterLocked(DisplayAdapter adapter) { 881 mDisplayAdapters.add(adapter); 882 adapter.registerLocked(); 883 } 884 handleDisplayDeviceAdded(DisplayDevice device)885 private void handleDisplayDeviceAdded(DisplayDevice device) { 886 synchronized (mSyncRoot) { 887 handleDisplayDeviceAddedLocked(device); 888 } 889 } 890 handleDisplayDeviceAddedLocked(DisplayDevice device)891 private void handleDisplayDeviceAddedLocked(DisplayDevice device) { 892 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 893 if (mDisplayDevices.contains(device)) { 894 Slog.w(TAG, "Attempted to add already added display device: " + info); 895 return; 896 } 897 898 Slog.i(TAG, "Display device added: " + info); 899 device.mDebugLastLoggedDeviceInfo = info; 900 901 mDisplayDevices.add(device); 902 LogicalDisplay display = addLogicalDisplayLocked(device); 903 Runnable work = updateDisplayStateLocked(device); 904 if (work != null) { 905 work.run(); 906 } 907 scheduleTraversalLocked(false); 908 } 909 handleDisplayDeviceChanged(DisplayDevice device)910 private void handleDisplayDeviceChanged(DisplayDevice device) { 911 synchronized (mSyncRoot) { 912 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 913 if (!mDisplayDevices.contains(device)) { 914 Slog.w(TAG, "Attempted to change non-existent display device: " + info); 915 return; 916 } 917 918 int diff = device.mDebugLastLoggedDeviceInfo.diff(info); 919 if (diff == DisplayDeviceInfo.DIFF_STATE) { 920 Slog.i(TAG, "Display device changed state: \"" + info.name 921 + "\", " + Display.stateToString(info.state)); 922 } else if (diff != 0) { 923 Slog.i(TAG, "Display device changed: " + info); 924 } 925 if ((diff & DisplayDeviceInfo.DIFF_COLOR_MODE) != 0) { 926 try { 927 mPersistentDataStore.setColorMode(device, info.colorMode); 928 } finally { 929 mPersistentDataStore.saveIfNeeded(); 930 } 931 } 932 device.mDebugLastLoggedDeviceInfo = info; 933 934 device.applyPendingDisplayDeviceInfoChangesLocked(); 935 if (updateLogicalDisplaysLocked()) { 936 scheduleTraversalLocked(false); 937 } 938 } 939 } 940 handleDisplayDeviceRemoved(DisplayDevice device)941 private void handleDisplayDeviceRemoved(DisplayDevice device) { 942 synchronized (mSyncRoot) { 943 handleDisplayDeviceRemovedLocked(device); 944 } 945 } 946 handleDisplayDeviceRemovedLocked(DisplayDevice device)947 private void handleDisplayDeviceRemovedLocked(DisplayDevice device) { 948 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 949 if (!mDisplayDevices.remove(device)) { 950 Slog.w(TAG, "Attempted to remove non-existent display device: " + info); 951 return; 952 } 953 954 Slog.i(TAG, "Display device removed: " + info); 955 device.mDebugLastLoggedDeviceInfo = info; 956 957 updateLogicalDisplaysLocked(); 958 scheduleTraversalLocked(false); 959 } 960 handleLogicalDisplayChanged(int displayId, @NonNull LogicalDisplay display)961 private void handleLogicalDisplayChanged(int displayId, @NonNull LogicalDisplay display) { 962 if (displayId == Display.DEFAULT_DISPLAY) { 963 recordTopInsetLocked(display); 964 } 965 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED); 966 } 967 applyGlobalDisplayStateLocked(List<Runnable> workQueue)968 private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) { 969 final int count = mDisplayDevices.size(); 970 for (int i = 0; i < count; i++) { 971 DisplayDevice device = mDisplayDevices.get(i); 972 Runnable runnable = updateDisplayStateLocked(device); 973 if (runnable != null) { 974 workQueue.add(runnable); 975 } 976 } 977 } 978 updateDisplayStateLocked(DisplayDevice device)979 private Runnable updateDisplayStateLocked(DisplayDevice device) { 980 // Blank or unblank the display immediately to match the state requested 981 // by the display power controller (if known). 982 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 983 if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) { 984 return device.requestDisplayStateLocked(mGlobalDisplayState, mGlobalDisplayBrightness); 985 } 986 return null; 987 } 988 989 // Adds a new logical display based on the given display device. 990 // Sends notifications if needed. addLogicalDisplayLocked(DisplayDevice device)991 private LogicalDisplay addLogicalDisplayLocked(DisplayDevice device) { 992 DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked(); 993 boolean isDefault = (deviceInfo.flags 994 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0; 995 if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) { 996 Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo); 997 isDefault = false; 998 } 999 1000 if (!isDefault && mSingleDisplayDemoMode) { 1001 Slog.i(TAG, "Not creating a logical display for a secondary display " 1002 + " because single display demo mode is enabled: " + deviceInfo); 1003 return null; 1004 } 1005 1006 final int displayId = assignDisplayIdLocked(isDefault); 1007 final int layerStack = assignLayerStackLocked(displayId); 1008 1009 LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device); 1010 display.updateLocked(mDisplayDevices); 1011 if (!display.isValidLocked()) { 1012 // This should never happen currently. 1013 Slog.w(TAG, "Ignoring display device because the logical display " 1014 + "created from it was not considered valid: " + deviceInfo); 1015 return null; 1016 } 1017 1018 configureColorModeLocked(display, device); 1019 if (isDefault) { 1020 recordStableDisplayStatsIfNeededLocked(display); 1021 recordTopInsetLocked(display); 1022 } 1023 1024 mLogicalDisplays.put(displayId, display); 1025 1026 // Wake up waitForDefaultDisplay. 1027 if (isDefault) { 1028 mSyncRoot.notifyAll(); 1029 } 1030 1031 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED); 1032 return display; 1033 } 1034 assignDisplayIdLocked(boolean isDefault)1035 private int assignDisplayIdLocked(boolean isDefault) { 1036 return isDefault ? Display.DEFAULT_DISPLAY : mNextNonDefaultDisplayId++; 1037 } 1038 assignLayerStackLocked(int displayId)1039 private int assignLayerStackLocked(int displayId) { 1040 // Currently layer stacks and display ids are the same. 1041 // This need not be the case. 1042 return displayId; 1043 } 1044 configureColorModeLocked(LogicalDisplay display, DisplayDevice device)1045 private void configureColorModeLocked(LogicalDisplay display, DisplayDevice device) { 1046 if (display.getPrimaryDisplayDeviceLocked() == device) { 1047 int colorMode = mPersistentDataStore.getColorMode(device); 1048 if (colorMode == Display.COLOR_MODE_INVALID) { 1049 if ((device.getDisplayDeviceInfoLocked().flags 1050 & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) { 1051 colorMode = mDefaultDisplayDefaultColorMode; 1052 } else { 1053 colorMode = Display.COLOR_MODE_DEFAULT; 1054 } 1055 } 1056 display.setRequestedColorModeLocked(colorMode); 1057 } 1058 } 1059 1060 // If we've never recorded stable device stats for this device before and they aren't 1061 // explicitly configured, go ahead and record the stable device stats now based on the status 1062 // of the default display at first boot. recordStableDisplayStatsIfNeededLocked(LogicalDisplay d)1063 private void recordStableDisplayStatsIfNeededLocked(LogicalDisplay d) { 1064 if (mStableDisplaySize.x <= 0 && mStableDisplaySize.y <= 0) { 1065 DisplayInfo info = d.getDisplayInfoLocked(); 1066 setStableDisplaySizeLocked(info.getNaturalWidth(), info.getNaturalHeight()); 1067 } 1068 } 1069 recordTopInsetLocked(@ullable LogicalDisplay d)1070 private void recordTopInsetLocked(@Nullable LogicalDisplay d) { 1071 // We must only persist the inset after boot has completed, otherwise we will end up 1072 // overwriting the persisted value before the masking flag has been loaded from the 1073 // resource overlay. 1074 if (!mSystemReady || d == null) { 1075 return; 1076 } 1077 int topInset = d.getInsets().top; 1078 if (topInset == mDefaultDisplayTopInset) { 1079 return; 1080 } 1081 mDefaultDisplayTopInset = topInset; 1082 SystemProperties.set(PROP_DEFAULT_DISPLAY_TOP_INSET, Integer.toString(topInset)); 1083 } 1084 setStableDisplaySizeLocked(int width, int height)1085 private void setStableDisplaySizeLocked(int width, int height) { 1086 mStableDisplaySize = new Point(width, height); 1087 try { 1088 mPersistentDataStore.setStableDisplaySize(mStableDisplaySize); 1089 } finally { 1090 mPersistentDataStore.saveIfNeeded(); 1091 } 1092 } 1093 1094 @VisibleForTesting getMinimumBrightnessCurveInternal()1095 Curve getMinimumBrightnessCurveInternal() { 1096 return mMinimumBrightnessCurve; 1097 } 1098 getPreferredWideGamutColorSpaceIdInternal()1099 int getPreferredWideGamutColorSpaceIdInternal() { 1100 return mWideColorSpace.getId(); 1101 } 1102 setBrightnessConfigurationForUserInternal( @ullable BrightnessConfiguration c, @UserIdInt int userId, @Nullable String packageName)1103 private void setBrightnessConfigurationForUserInternal( 1104 @Nullable BrightnessConfiguration c, @UserIdInt int userId, 1105 @Nullable String packageName) { 1106 validateBrightnessConfiguration(c); 1107 final int userSerial = getUserManager().getUserSerialNumber(userId); 1108 synchronized (mSyncRoot) { 1109 try { 1110 mPersistentDataStore.setBrightnessConfigurationForUser(c, userSerial, 1111 packageName); 1112 } finally { 1113 mPersistentDataStore.saveIfNeeded(); 1114 } 1115 if (userId == mCurrentUserId) { 1116 mDisplayPowerController.setBrightnessConfiguration(c); 1117 } 1118 } 1119 } 1120 1121 @VisibleForTesting validateBrightnessConfiguration(BrightnessConfiguration config)1122 void validateBrightnessConfiguration(BrightnessConfiguration config) { 1123 if (config == null) { 1124 return; 1125 } 1126 if (isBrightnessConfigurationTooDark(config)) { 1127 throw new IllegalArgumentException("brightness curve is too dark"); 1128 } 1129 } 1130 isBrightnessConfigurationTooDark(BrightnessConfiguration config)1131 private boolean isBrightnessConfigurationTooDark(BrightnessConfiguration config) { 1132 Pair<float[], float[]> curve = config.getCurve(); 1133 float[] lux = curve.first; 1134 float[] nits = curve.second; 1135 for (int i = 0; i < lux.length; i++) { 1136 if (nits[i] < mMinimumBrightnessSpline.interpolate(lux[i])) { 1137 return true; 1138 } 1139 } 1140 return false; 1141 } 1142 loadBrightnessConfiguration()1143 private void loadBrightnessConfiguration() { 1144 synchronized (mSyncRoot) { 1145 final int userSerial = getUserManager().getUserSerialNumber(mCurrentUserId); 1146 BrightnessConfiguration config = 1147 mPersistentDataStore.getBrightnessConfiguration(userSerial); 1148 mDisplayPowerController.setBrightnessConfiguration(config); 1149 } 1150 } 1151 1152 // Updates all existing logical displays given the current set of display devices. 1153 // Removes invalid logical displays. 1154 // Sends notifications if needed. updateLogicalDisplaysLocked()1155 private boolean updateLogicalDisplaysLocked() { 1156 boolean changed = false; 1157 for (int i = mLogicalDisplays.size(); i-- > 0; ) { 1158 final int displayId = mLogicalDisplays.keyAt(i); 1159 LogicalDisplay display = mLogicalDisplays.valueAt(i); 1160 1161 mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked()); 1162 display.updateLocked(mDisplayDevices); 1163 if (!display.isValidLocked()) { 1164 mLogicalDisplays.removeAt(i); 1165 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED); 1166 changed = true; 1167 } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) { 1168 handleLogicalDisplayChanged(displayId, display); 1169 changed = true; 1170 } 1171 } 1172 return changed; 1173 } 1174 performTraversalLocked(SurfaceControl.Transaction t)1175 private void performTraversalLocked(SurfaceControl.Transaction t) { 1176 // Clear all viewports before configuring displays so that we can keep 1177 // track of which ones we have configured. 1178 clearViewportsLocked(); 1179 1180 // Configure each display device. 1181 final int count = mDisplayDevices.size(); 1182 for (int i = 0; i < count; i++) { 1183 DisplayDevice device = mDisplayDevices.get(i); 1184 configureDisplayLocked(t, device); 1185 device.performTraversalLocked(t); 1186 } 1187 1188 // Tell the input system about these new viewports. 1189 if (mInputManagerInternal != null) { 1190 mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT); 1191 } 1192 } 1193 setDisplayPropertiesInternal(int displayId, boolean hasContent, float requestedRefreshRate, int requestedModeId, boolean inTraversal)1194 private void setDisplayPropertiesInternal(int displayId, boolean hasContent, 1195 float requestedRefreshRate, int requestedModeId, boolean inTraversal) { 1196 synchronized (mSyncRoot) { 1197 LogicalDisplay display = mLogicalDisplays.get(displayId); 1198 if (display == null) { 1199 return; 1200 } 1201 if (display.hasContentLocked() != hasContent) { 1202 if (DEBUG) { 1203 Slog.d(TAG, "Display " + displayId + " hasContent flag changed: " 1204 + "hasContent=" + hasContent + ", inTraversal=" + inTraversal); 1205 } 1206 1207 display.setHasContentLocked(hasContent); 1208 scheduleTraversalLocked(inTraversal); 1209 } 1210 if (requestedModeId == 0 && requestedRefreshRate != 0) { 1211 // Scan supported modes returned by display.getInfo() to find a mode with the same 1212 // size as the default display mode but with the specified refresh rate instead. 1213 requestedModeId = display.getDisplayInfoLocked().findDefaultModeByRefreshRate( 1214 requestedRefreshRate); 1215 } 1216 mDisplayModeDirector.getAppRequestObserver().setAppRequestedMode( 1217 displayId, requestedModeId); 1218 } 1219 } 1220 setDisplayOffsetsInternal(int displayId, int x, int y)1221 private void setDisplayOffsetsInternal(int displayId, int x, int y) { 1222 synchronized (mSyncRoot) { 1223 LogicalDisplay display = mLogicalDisplays.get(displayId); 1224 if (display == null) { 1225 return; 1226 } 1227 if (display.getDisplayOffsetXLocked() != x 1228 || display.getDisplayOffsetYLocked() != y) { 1229 if (DEBUG) { 1230 Slog.d(TAG, "Display " + displayId + " burn-in offset set to (" 1231 + x + ", " + y + ")"); 1232 } 1233 display.setDisplayOffsetsLocked(x, y); 1234 scheduleTraversalLocked(false); 1235 } 1236 } 1237 } 1238 setDisplayScalingDisabledInternal(int displayId, boolean disable)1239 private void setDisplayScalingDisabledInternal(int displayId, boolean disable) { 1240 synchronized (mSyncRoot) { 1241 final LogicalDisplay display = mLogicalDisplays.get(displayId); 1242 if (display == null) { 1243 return; 1244 } 1245 if (display.isDisplayScalingDisabled() != disable) { 1246 if (DEBUG) { 1247 Slog.d(TAG, "Display " + displayId + " content scaling disabled = " + disable); 1248 } 1249 display.setDisplayScalingDisabledLocked(disable); 1250 scheduleTraversalLocked(false); 1251 } 1252 } 1253 } 1254 1255 // Updates the lists of UIDs that are present on displays. setDisplayAccessUIDsInternal(SparseArray<IntArray> newDisplayAccessUIDs)1256 private void setDisplayAccessUIDsInternal(SparseArray<IntArray> newDisplayAccessUIDs) { 1257 synchronized (mSyncRoot) { 1258 mDisplayAccessUIDs.clear(); 1259 for (int i = newDisplayAccessUIDs.size() - 1; i >= 0; i--) { 1260 mDisplayAccessUIDs.append(newDisplayAccessUIDs.keyAt(i), 1261 newDisplayAccessUIDs.valueAt(i)); 1262 } 1263 } 1264 } 1265 1266 // Checks if provided UID's content is present on the display and UID has access to it. isUidPresentOnDisplayInternal(int uid, int displayId)1267 private boolean isUidPresentOnDisplayInternal(int uid, int displayId) { 1268 synchronized (mSyncRoot) { 1269 final IntArray displayUIDs = mDisplayAccessUIDs.get(displayId); 1270 return displayUIDs != null && displayUIDs.indexOf(uid) != -1; 1271 } 1272 } 1273 1274 @Nullable getDisplayToken(int displayId)1275 private IBinder getDisplayToken(int displayId) { 1276 synchronized (mSyncRoot) { 1277 final LogicalDisplay display = mLogicalDisplays.get(displayId); 1278 if (display != null) { 1279 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); 1280 if (device != null) { 1281 return device.getDisplayTokenLocked(); 1282 } 1283 } 1284 } 1285 1286 return null; 1287 } 1288 screenshotInternal(int displayId)1289 private SurfaceControl.ScreenshotGraphicBuffer screenshotInternal(int displayId) { 1290 final IBinder token = getDisplayToken(displayId); 1291 if (token == null) { 1292 return null; 1293 } 1294 return SurfaceControl.screenshotToBufferWithSecureLayersUnsafe( 1295 token, new Rect(), 0 /* width */, 0 /* height */, 1296 false /* useIdentityTransform */, 0 /* rotation */); 1297 } 1298 1299 @VisibleForTesting getDisplayedContentSamplingAttributesInternal( int displayId)1300 DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributesInternal( 1301 int displayId) { 1302 final IBinder token = getDisplayToken(displayId); 1303 if (token == null) { 1304 return null; 1305 } 1306 return SurfaceControl.getDisplayedContentSamplingAttributes(token); 1307 } 1308 1309 @VisibleForTesting setDisplayedContentSamplingEnabledInternal( int displayId, boolean enable, int componentMask, int maxFrames)1310 boolean setDisplayedContentSamplingEnabledInternal( 1311 int displayId, boolean enable, int componentMask, int maxFrames) { 1312 final IBinder token = getDisplayToken(displayId); 1313 if (token == null) { 1314 return false; 1315 } 1316 return SurfaceControl.setDisplayedContentSamplingEnabled( 1317 token, enable, componentMask, maxFrames); 1318 } 1319 1320 @VisibleForTesting getDisplayedContentSampleInternal(int displayId, long maxFrames, long timestamp)1321 DisplayedContentSample getDisplayedContentSampleInternal(int displayId, 1322 long maxFrames, long timestamp) { 1323 final IBinder token = getDisplayToken(displayId); 1324 if (token == null) { 1325 return null; 1326 } 1327 return SurfaceControl.getDisplayedContentSample(token, maxFrames, timestamp); 1328 } 1329 onAllowedDisplayModesChangedInternal()1330 private void onAllowedDisplayModesChangedInternal() { 1331 boolean changed = false; 1332 synchronized (mSyncRoot) { 1333 final int count = mLogicalDisplays.size(); 1334 for (int i = 0; i < count; i++) { 1335 LogicalDisplay display = mLogicalDisplays.valueAt(i); 1336 int displayId = mLogicalDisplays.keyAt(i); 1337 int[] allowedModes = mDisplayModeDirector.getAllowedModes(displayId); 1338 // Note that order is important here since not all display devices are capable of 1339 // automatically switching, so we do actually want to check for equality and not 1340 // just equivalent contents (regardless of order). 1341 if (!Arrays.equals(allowedModes, display.getAllowedDisplayModesLocked())) { 1342 display.setAllowedDisplayModesLocked(allowedModes); 1343 changed = true; 1344 } 1345 } 1346 if (changed) { 1347 scheduleTraversalLocked(false); 1348 } 1349 } 1350 } 1351 clearViewportsLocked()1352 private void clearViewportsLocked() { 1353 mViewports.clear(); 1354 } 1355 configureDisplayLocked(SurfaceControl.Transaction t, DisplayDevice device)1356 private void configureDisplayLocked(SurfaceControl.Transaction t, DisplayDevice device) { 1357 final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 1358 final boolean ownContent = (info.flags & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0; 1359 1360 // Find the logical display that the display device is showing. 1361 // Certain displays only ever show their own content. 1362 LogicalDisplay display = findLogicalDisplayForDeviceLocked(device); 1363 if (!ownContent) { 1364 if (display != null && !display.hasContentLocked()) { 1365 // If the display does not have any content of its own, then 1366 // automatically mirror the default logical display contents. 1367 display = null; 1368 } 1369 if (display == null) { 1370 display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY); 1371 } 1372 } 1373 1374 // Apply the logical display configuration to the display device. 1375 if (display == null) { 1376 // TODO: no logical display for the device, blank it 1377 Slog.w(TAG, "Missing logical display to use for physical display device: " 1378 + device.getDisplayDeviceInfoLocked()); 1379 return; 1380 } 1381 display.configureDisplayLocked(t, device, info.state == Display.STATE_OFF); 1382 final int viewportType; 1383 // Update the corresponding viewport. 1384 if ((info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) { 1385 viewportType = VIEWPORT_INTERNAL; 1386 } else if (info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) { 1387 viewportType = VIEWPORT_EXTERNAL; 1388 } else if (info.touch == DisplayDeviceInfo.TOUCH_VIRTUAL 1389 && !TextUtils.isEmpty(info.uniqueId)) { 1390 viewportType = VIEWPORT_VIRTUAL; 1391 } else { 1392 Slog.i(TAG, "Display " + info + " does not support input device matching."); 1393 return; 1394 } 1395 1396 populateViewportLocked(viewportType, display.getDisplayIdLocked(), device, info.uniqueId); 1397 } 1398 1399 /** 1400 * Get internal or external viewport. Create it if does not currently exist. 1401 * @param viewportType - either INTERNAL or EXTERNAL 1402 * @return the viewport with the requested type 1403 */ getViewportLocked(int viewportType, String uniqueId)1404 private DisplayViewport getViewportLocked(int viewportType, String uniqueId) { 1405 if (viewportType != VIEWPORT_INTERNAL && viewportType != VIEWPORT_EXTERNAL 1406 && viewportType != VIEWPORT_VIRTUAL) { 1407 Slog.wtf(TAG, "Cannot call getViewportByTypeLocked for type " 1408 + DisplayViewport.typeToString(viewportType)); 1409 return null; 1410 } 1411 1412 // Only allow a single INTERNAL or EXTERNAL viewport by forcing their uniqueIds 1413 // to be identical (in particular, empty). 1414 // TODO (b/116824030) allow multiple EXTERNAL viewports and remove this function. 1415 if (viewportType != VIEWPORT_VIRTUAL) { 1416 uniqueId = ""; 1417 } 1418 1419 DisplayViewport viewport; 1420 final int count = mViewports.size(); 1421 for (int i = 0; i < count; i++) { 1422 viewport = mViewports.get(i); 1423 if (viewport.type == viewportType && uniqueId.equals(viewport.uniqueId)) { 1424 return viewport; 1425 } 1426 } 1427 1428 // Creates the viewport if none exists. 1429 viewport = new DisplayViewport(); 1430 viewport.type = viewportType; 1431 viewport.uniqueId = uniqueId; 1432 mViewports.add(viewport); 1433 return viewport; 1434 } 1435 populateViewportLocked(int viewportType, int displayId, DisplayDevice device, String uniqueId)1436 private void populateViewportLocked(int viewportType, 1437 int displayId, DisplayDevice device, String uniqueId) { 1438 final DisplayViewport viewport = getViewportLocked(viewportType, uniqueId); 1439 device.populateViewportLocked(viewport); 1440 viewport.valid = true; 1441 viewport.displayId = displayId; 1442 } 1443 findLogicalDisplayForDeviceLocked(DisplayDevice device)1444 private LogicalDisplay findLogicalDisplayForDeviceLocked(DisplayDevice device) { 1445 final int count = mLogicalDisplays.size(); 1446 for (int i = 0; i < count; i++) { 1447 LogicalDisplay display = mLogicalDisplays.valueAt(i); 1448 if (display.getPrimaryDisplayDeviceLocked() == device) { 1449 return display; 1450 } 1451 } 1452 return null; 1453 } 1454 sendDisplayEventLocked(int displayId, int event)1455 private void sendDisplayEventLocked(int displayId, int event) { 1456 Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT, displayId, event); 1457 mHandler.sendMessage(msg); 1458 } 1459 1460 // Requests that performTraversals be called at a 1461 // later time to apply changes to surfaces and displays. scheduleTraversalLocked(boolean inTraversal)1462 private void scheduleTraversalLocked(boolean inTraversal) { 1463 if (!mPendingTraversal && mWindowManagerInternal != null) { 1464 mPendingTraversal = true; 1465 if (!inTraversal) { 1466 mHandler.sendEmptyMessage(MSG_REQUEST_TRAVERSAL); 1467 } 1468 } 1469 } 1470 1471 // Runs on Handler thread. 1472 // Delivers display event notifications to callbacks. deliverDisplayEvent(int displayId, int event)1473 private void deliverDisplayEvent(int displayId, int event) { 1474 if (DEBUG) { 1475 Slog.d(TAG, "Delivering display event: displayId=" 1476 + displayId + ", event=" + event); 1477 } 1478 1479 // Grab the lock and copy the callbacks. 1480 final int count; 1481 synchronized (mSyncRoot) { 1482 count = mCallbacks.size(); 1483 mTempCallbacks.clear(); 1484 for (int i = 0; i < count; i++) { 1485 mTempCallbacks.add(mCallbacks.valueAt(i)); 1486 } 1487 } 1488 1489 // After releasing the lock, send the notifications out. 1490 for (int i = 0; i < count; i++) { 1491 mTempCallbacks.get(i).notifyDisplayEventAsync(displayId, event); 1492 } 1493 mTempCallbacks.clear(); 1494 } 1495 getProjectionService()1496 private IMediaProjectionManager getProjectionService() { 1497 if (mProjectionService == null) { 1498 IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE); 1499 mProjectionService = IMediaProjectionManager.Stub.asInterface(b); 1500 } 1501 return mProjectionService; 1502 } 1503 getUserManager()1504 private UserManager getUserManager() { 1505 return mContext.getSystemService(UserManager.class); 1506 } 1507 dumpInternal(PrintWriter pw)1508 private void dumpInternal(PrintWriter pw) { 1509 pw.println("DISPLAY MANAGER (dumpsys display)"); 1510 1511 synchronized (mSyncRoot) { 1512 pw.println(" mOnlyCode=" + mOnlyCore); 1513 pw.println(" mSafeMode=" + mSafeMode); 1514 pw.println(" mPendingTraversal=" + mPendingTraversal); 1515 pw.println(" mGlobalDisplayState=" + Display.stateToString(mGlobalDisplayState)); 1516 pw.println(" mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId); 1517 pw.println(" mViewports=" + mViewports); 1518 pw.println(" mDefaultDisplayDefaultColorMode=" + mDefaultDisplayDefaultColorMode); 1519 pw.println(" mSingleDisplayDemoMode=" + mSingleDisplayDemoMode); 1520 pw.println(" mWifiDisplayScanRequestCount=" + mWifiDisplayScanRequestCount); 1521 pw.println(" mStableDisplaySize=" + mStableDisplaySize); 1522 pw.println(" mMinimumBrightnessCurve=" + mMinimumBrightnessCurve); 1523 1524 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 1525 ipw.increaseIndent(); 1526 1527 pw.println(); 1528 pw.println("Display Adapters: size=" + mDisplayAdapters.size()); 1529 for (DisplayAdapter adapter : mDisplayAdapters) { 1530 pw.println(" " + adapter.getName()); 1531 adapter.dumpLocked(ipw); 1532 } 1533 1534 pw.println(); 1535 pw.println("Display Devices: size=" + mDisplayDevices.size()); 1536 for (DisplayDevice device : mDisplayDevices) { 1537 pw.println(" " + device.getDisplayDeviceInfoLocked()); 1538 device.dumpLocked(ipw); 1539 } 1540 1541 final int logicalDisplayCount = mLogicalDisplays.size(); 1542 pw.println(); 1543 pw.println("Logical Displays: size=" + logicalDisplayCount); 1544 for (int i = 0; i < logicalDisplayCount; i++) { 1545 int displayId = mLogicalDisplays.keyAt(i); 1546 LogicalDisplay display = mLogicalDisplays.valueAt(i); 1547 pw.println(" Display " + displayId + ":"); 1548 display.dumpLocked(ipw); 1549 } 1550 1551 pw.println(); 1552 mDisplayModeDirector.dump(pw); 1553 1554 final int callbackCount = mCallbacks.size(); 1555 pw.println(); 1556 pw.println("Callbacks: size=" + callbackCount); 1557 for (int i = 0; i < callbackCount; i++) { 1558 CallbackRecord callback = mCallbacks.valueAt(i); 1559 pw.println(" " + i + ": mPid=" + callback.mPid 1560 + ", mWifiDisplayScanRequested=" + callback.mWifiDisplayScanRequested); 1561 } 1562 1563 if (mDisplayPowerController != null) { 1564 mDisplayPowerController.dump(pw); 1565 } 1566 1567 pw.println(); 1568 mPersistentDataStore.dump(pw); 1569 } 1570 } 1571 getFloatArray(TypedArray array)1572 private static float[] getFloatArray(TypedArray array) { 1573 int length = array.length(); 1574 float[] floatArray = new float[length]; 1575 for (int i = 0; i < length; i++) { 1576 floatArray[i] = array.getFloat(i, Float.NaN); 1577 } 1578 array.recycle(); 1579 return floatArray; 1580 } 1581 1582 /** 1583 * This is the object that everything in the display manager locks on. 1584 * We make it an inner class within the {@link DisplayManagerService} to so that it is 1585 * clear that the object belongs to the display manager service and that it is 1586 * a unique object with a special purpose. 1587 */ 1588 public static final class SyncRoot { 1589 } 1590 1591 @VisibleForTesting 1592 static class Injector { getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, Handler handler, DisplayAdapter.Listener displayAdapterListener)1593 VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, 1594 Handler handler, DisplayAdapter.Listener displayAdapterListener) { 1595 return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener); 1596 } 1597 getDefaultDisplayDelayTimeout()1598 long getDefaultDisplayDelayTimeout() { 1599 return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT; 1600 } 1601 } 1602 1603 @VisibleForTesting getDisplayDeviceInfoInternal(int displayId)1604 DisplayDeviceInfo getDisplayDeviceInfoInternal(int displayId) { 1605 synchronized (mSyncRoot) { 1606 LogicalDisplay display = mLogicalDisplays.get(displayId); 1607 if (display != null) { 1608 DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked(); 1609 return displayDevice.getDisplayDeviceInfoLocked(); 1610 } 1611 return null; 1612 } 1613 } 1614 1615 private final class DisplayManagerHandler extends Handler { DisplayManagerHandler(Looper looper)1616 public DisplayManagerHandler(Looper looper) { 1617 super(looper, null, true /*async*/); 1618 } 1619 1620 @Override handleMessage(Message msg)1621 public void handleMessage(Message msg) { 1622 switch (msg.what) { 1623 case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS: 1624 registerDefaultDisplayAdapters(); 1625 break; 1626 1627 case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS: 1628 registerAdditionalDisplayAdapters(); 1629 break; 1630 1631 case MSG_DELIVER_DISPLAY_EVENT: 1632 deliverDisplayEvent(msg.arg1, msg.arg2); 1633 break; 1634 1635 case MSG_REQUEST_TRAVERSAL: 1636 mWindowManagerInternal.requestTraversalFromDisplayManager(); 1637 break; 1638 1639 case MSG_UPDATE_VIEWPORT: { 1640 final boolean changed; 1641 synchronized (mSyncRoot) { 1642 changed = !mTempViewports.equals(mViewports); 1643 if (changed) { 1644 mTempViewports.clear(); 1645 for (DisplayViewport d : mViewports) { 1646 mTempViewports.add(d.makeCopy()); 1647 } 1648 } 1649 } 1650 if (changed) { 1651 mInputManagerInternal.setDisplayViewports(mTempViewports); 1652 } 1653 break; 1654 } 1655 1656 case MSG_LOAD_BRIGHTNESS_CONFIGURATION: 1657 loadBrightnessConfiguration(); 1658 break; 1659 } 1660 } 1661 } 1662 1663 private final class DisplayAdapterListener implements DisplayAdapter.Listener { 1664 @Override onDisplayDeviceEvent(DisplayDevice device, int event)1665 public void onDisplayDeviceEvent(DisplayDevice device, int event) { 1666 switch (event) { 1667 case DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED: 1668 handleDisplayDeviceAdded(device); 1669 break; 1670 1671 case DisplayAdapter.DISPLAY_DEVICE_EVENT_CHANGED: 1672 handleDisplayDeviceChanged(device); 1673 break; 1674 1675 case DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED: 1676 handleDisplayDeviceRemoved(device); 1677 break; 1678 } 1679 } 1680 1681 @Override onTraversalRequested()1682 public void onTraversalRequested() { 1683 synchronized (mSyncRoot) { 1684 scheduleTraversalLocked(false); 1685 } 1686 } 1687 } 1688 1689 private final class CallbackRecord implements DeathRecipient { 1690 public final int mPid; 1691 private final IDisplayManagerCallback mCallback; 1692 1693 public boolean mWifiDisplayScanRequested; 1694 CallbackRecord(int pid, IDisplayManagerCallback callback)1695 public CallbackRecord(int pid, IDisplayManagerCallback callback) { 1696 mPid = pid; 1697 mCallback = callback; 1698 } 1699 1700 @Override binderDied()1701 public void binderDied() { 1702 if (DEBUG) { 1703 Slog.d(TAG, "Display listener for pid " + mPid + " died."); 1704 } 1705 onCallbackDied(this); 1706 } 1707 notifyDisplayEventAsync(int displayId, int event)1708 public void notifyDisplayEventAsync(int displayId, int event) { 1709 try { 1710 mCallback.onDisplayEvent(displayId, event); 1711 } catch (RemoteException ex) { 1712 Slog.w(TAG, "Failed to notify process " 1713 + mPid + " that displays changed, assuming it died.", ex); 1714 binderDied(); 1715 } 1716 } 1717 } 1718 1719 @VisibleForTesting 1720 final class BinderService extends IDisplayManager.Stub { 1721 /** 1722 * Returns information about the specified logical display. 1723 * 1724 * @param displayId The logical display id. 1725 * @return The logical display info, return {@code null} if the display does not exist or 1726 * the calling UID isn't present on the display. The returned object must be treated as 1727 * immutable. 1728 */ 1729 @Override // Binder call getDisplayInfo(int displayId)1730 public DisplayInfo getDisplayInfo(int displayId) { 1731 final int callingUid = Binder.getCallingUid(); 1732 final long token = Binder.clearCallingIdentity(); 1733 try { 1734 return getDisplayInfoInternal(displayId, callingUid); 1735 } finally { 1736 Binder.restoreCallingIdentity(token); 1737 } 1738 } 1739 1740 /** 1741 * Returns the list of all display ids. 1742 */ 1743 @Override // Binder call getDisplayIds()1744 public int[] getDisplayIds() { 1745 final int callingUid = Binder.getCallingUid(); 1746 final long token = Binder.clearCallingIdentity(); 1747 try { 1748 return getDisplayIdsInternal(callingUid); 1749 } finally { 1750 Binder.restoreCallingIdentity(token); 1751 } 1752 } 1753 1754 @Override // Binder call isUidPresentOnDisplay(int uid, int displayId)1755 public boolean isUidPresentOnDisplay(int uid, int displayId) { 1756 final long token = Binder.clearCallingIdentity(); 1757 try { 1758 return isUidPresentOnDisplayInternal(uid, displayId); 1759 } finally { 1760 Binder.restoreCallingIdentity(token); 1761 } 1762 } 1763 1764 /** 1765 * Returns the stable device display size, in pixels. 1766 */ 1767 @Override // Binder call getStableDisplaySize()1768 public Point getStableDisplaySize() { 1769 final long token = Binder.clearCallingIdentity(); 1770 try { 1771 return getStableDisplaySizeInternal(); 1772 } finally { 1773 Binder.restoreCallingIdentity(token); 1774 } 1775 } 1776 1777 @Override // Binder call registerCallback(IDisplayManagerCallback callback)1778 public void registerCallback(IDisplayManagerCallback callback) { 1779 if (callback == null) { 1780 throw new IllegalArgumentException("listener must not be null"); 1781 } 1782 1783 final int callingPid = Binder.getCallingPid(); 1784 final long token = Binder.clearCallingIdentity(); 1785 try { 1786 registerCallbackInternal(callback, callingPid); 1787 } finally { 1788 Binder.restoreCallingIdentity(token); 1789 } 1790 } 1791 1792 @Override // Binder call startWifiDisplayScan()1793 public void startWifiDisplayScan() { 1794 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1795 "Permission required to start wifi display scans"); 1796 1797 final int callingPid = Binder.getCallingPid(); 1798 final long token = Binder.clearCallingIdentity(); 1799 try { 1800 startWifiDisplayScanInternal(callingPid); 1801 } finally { 1802 Binder.restoreCallingIdentity(token); 1803 } 1804 } 1805 1806 @Override // Binder call stopWifiDisplayScan()1807 public void stopWifiDisplayScan() { 1808 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1809 "Permission required to stop wifi display scans"); 1810 1811 final int callingPid = Binder.getCallingPid(); 1812 final long token = Binder.clearCallingIdentity(); 1813 try { 1814 stopWifiDisplayScanInternal(callingPid); 1815 } finally { 1816 Binder.restoreCallingIdentity(token); 1817 } 1818 } 1819 1820 @Override // Binder call connectWifiDisplay(String address)1821 public void connectWifiDisplay(String address) { 1822 if (address == null) { 1823 throw new IllegalArgumentException("address must not be null"); 1824 } 1825 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1826 "Permission required to connect to a wifi display"); 1827 1828 final long token = Binder.clearCallingIdentity(); 1829 try { 1830 connectWifiDisplayInternal(address); 1831 } finally { 1832 Binder.restoreCallingIdentity(token); 1833 } 1834 } 1835 1836 @Override // Binder call disconnectWifiDisplay()1837 public void disconnectWifiDisplay() { 1838 // This request does not require special permissions. 1839 // Any app can request disconnection from the currently active wifi display. 1840 // This exception should no longer be needed once wifi display control moves 1841 // to the media router service. 1842 1843 final long token = Binder.clearCallingIdentity(); 1844 try { 1845 disconnectWifiDisplayInternal(); 1846 } finally { 1847 Binder.restoreCallingIdentity(token); 1848 } 1849 } 1850 1851 @Override // Binder call renameWifiDisplay(String address, String alias)1852 public void renameWifiDisplay(String address, String alias) { 1853 if (address == null) { 1854 throw new IllegalArgumentException("address must not be null"); 1855 } 1856 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1857 "Permission required to rename to a wifi display"); 1858 1859 final long token = Binder.clearCallingIdentity(); 1860 try { 1861 renameWifiDisplayInternal(address, alias); 1862 } finally { 1863 Binder.restoreCallingIdentity(token); 1864 } 1865 } 1866 1867 @Override // Binder call forgetWifiDisplay(String address)1868 public void forgetWifiDisplay(String address) { 1869 if (address == null) { 1870 throw new IllegalArgumentException("address must not be null"); 1871 } 1872 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1873 "Permission required to forget to a wifi display"); 1874 1875 final long token = Binder.clearCallingIdentity(); 1876 try { 1877 forgetWifiDisplayInternal(address); 1878 } finally { 1879 Binder.restoreCallingIdentity(token); 1880 } 1881 } 1882 1883 @Override // Binder call pauseWifiDisplay()1884 public void pauseWifiDisplay() { 1885 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1886 "Permission required to pause a wifi display session"); 1887 1888 final long token = Binder.clearCallingIdentity(); 1889 try { 1890 pauseWifiDisplayInternal(); 1891 } finally { 1892 Binder.restoreCallingIdentity(token); 1893 } 1894 } 1895 1896 @Override // Binder call resumeWifiDisplay()1897 public void resumeWifiDisplay() { 1898 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 1899 "Permission required to resume a wifi display session"); 1900 1901 final long token = Binder.clearCallingIdentity(); 1902 try { 1903 resumeWifiDisplayInternal(); 1904 } finally { 1905 Binder.restoreCallingIdentity(token); 1906 } 1907 } 1908 1909 @Override // Binder call getWifiDisplayStatus()1910 public WifiDisplayStatus getWifiDisplayStatus() { 1911 // This request does not require special permissions. 1912 // Any app can get information about available wifi displays. 1913 1914 final long token = Binder.clearCallingIdentity(); 1915 try { 1916 return getWifiDisplayStatusInternal(); 1917 } finally { 1918 Binder.restoreCallingIdentity(token); 1919 } 1920 } 1921 1922 @Override // Binder call requestColorMode(int displayId, int colorMode)1923 public void requestColorMode(int displayId, int colorMode) { 1924 mContext.enforceCallingOrSelfPermission( 1925 Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE, 1926 "Permission required to change the display color mode"); 1927 final long token = Binder.clearCallingIdentity(); 1928 try { 1929 requestColorModeInternal(displayId, colorMode); 1930 } finally { 1931 Binder.restoreCallingIdentity(token); 1932 } 1933 } 1934 1935 @Override // Binder call createVirtualDisplay(IVirtualDisplayCallback callback, IMediaProjection projection, String packageName, String name, int width, int height, int densityDpi, Surface surface, int flags, String uniqueId)1936 public int createVirtualDisplay(IVirtualDisplayCallback callback, 1937 IMediaProjection projection, String packageName, String name, 1938 int width, int height, int densityDpi, Surface surface, int flags, 1939 String uniqueId) { 1940 final int callingUid = Binder.getCallingUid(); 1941 if (!validatePackageName(callingUid, packageName)) { 1942 throw new SecurityException("packageName must match the calling uid"); 1943 } 1944 if (callback == null) { 1945 throw new IllegalArgumentException("appToken must not be null"); 1946 } 1947 if (TextUtils.isEmpty(name)) { 1948 throw new IllegalArgumentException("name must be non-null and non-empty"); 1949 } 1950 if (width <= 0 || height <= 0 || densityDpi <= 0) { 1951 throw new IllegalArgumentException("width, height, and densityDpi must be " 1952 + "greater than 0"); 1953 } 1954 if (surface != null && surface.isSingleBuffered()) { 1955 throw new IllegalArgumentException("Surface can't be single-buffered"); 1956 } 1957 1958 if ((flags & VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) { 1959 flags |= VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; 1960 1961 // Public displays can't be allowed to show content when locked. 1962 if ((flags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) { 1963 throw new IllegalArgumentException( 1964 "Public display must not be marked as SHOW_WHEN_LOCKED_INSECURE"); 1965 } 1966 } 1967 if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) { 1968 flags &= ~VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; 1969 } 1970 1971 if (projection != null) { 1972 try { 1973 if (!getProjectionService().isValidMediaProjection(projection)) { 1974 throw new SecurityException("Invalid media projection"); 1975 } 1976 flags = projection.applyVirtualDisplayFlags(flags); 1977 } catch (RemoteException e) { 1978 throw new SecurityException("unable to validate media projection or flags"); 1979 } 1980 } 1981 1982 if (callingUid != Process.SYSTEM_UID && 1983 (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) { 1984 if (!canProjectVideo(projection)) { 1985 throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or " 1986 + "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate " 1987 + "MediaProjection token in order to create a screen sharing virtual " 1988 + "display."); 1989 } 1990 } 1991 if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0) { 1992 if (!canProjectSecureVideo(projection)) { 1993 throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT " 1994 + "or an appropriate MediaProjection token to create a " 1995 + "secure virtual display."); 1996 } 1997 } 1998 1999 // Sometimes users can have sensitive information in system decoration windows. An app 2000 // could create a virtual display with system decorations support and read the user info 2001 // from the surface. 2002 // We should only allow adding flag VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS 2003 // to virtual displays that are owned by the system. 2004 if (callingUid != Process.SYSTEM_UID 2005 && (flags & VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) { 2006 if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "createVirtualDisplay()")) { 2007 throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); 2008 } 2009 } 2010 2011 final long token = Binder.clearCallingIdentity(); 2012 try { 2013 return createVirtualDisplayInternal(callback, projection, callingUid, packageName, 2014 name, width, height, densityDpi, surface, flags, uniqueId); 2015 } finally { 2016 Binder.restoreCallingIdentity(token); 2017 } 2018 } 2019 2020 @Override // Binder call resizeVirtualDisplay(IVirtualDisplayCallback callback, int width, int height, int densityDpi)2021 public void resizeVirtualDisplay(IVirtualDisplayCallback callback, 2022 int width, int height, int densityDpi) { 2023 final long token = Binder.clearCallingIdentity(); 2024 try { 2025 resizeVirtualDisplayInternal(callback.asBinder(), width, height, densityDpi); 2026 } finally { 2027 Binder.restoreCallingIdentity(token); 2028 } 2029 } 2030 2031 @Override // Binder call setVirtualDisplaySurface(IVirtualDisplayCallback callback, Surface surface)2032 public void setVirtualDisplaySurface(IVirtualDisplayCallback callback, Surface surface) { 2033 if (surface != null && surface.isSingleBuffered()) { 2034 throw new IllegalArgumentException("Surface can't be single-buffered"); 2035 } 2036 final long token = Binder.clearCallingIdentity(); 2037 try { 2038 setVirtualDisplaySurfaceInternal(callback.asBinder(), surface); 2039 } finally { 2040 Binder.restoreCallingIdentity(token); 2041 } 2042 } 2043 2044 @Override // Binder call releaseVirtualDisplay(IVirtualDisplayCallback callback)2045 public void releaseVirtualDisplay(IVirtualDisplayCallback callback) { 2046 final long token = Binder.clearCallingIdentity(); 2047 try { 2048 releaseVirtualDisplayInternal(callback.asBinder()); 2049 } finally { 2050 Binder.restoreCallingIdentity(token); 2051 } 2052 } 2053 2054 @Override // Binder call setVirtualDisplayState(IVirtualDisplayCallback callback, boolean isOn)2055 public void setVirtualDisplayState(IVirtualDisplayCallback callback, boolean isOn) { 2056 final long token = Binder.clearCallingIdentity(); 2057 try { 2058 setVirtualDisplayStateInternal(callback.asBinder(), isOn); 2059 } finally { 2060 Binder.restoreCallingIdentity(token); 2061 } 2062 } 2063 2064 @Override // Binder call dump(FileDescriptor fd, final PrintWriter pw, String[] args)2065 public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) { 2066 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 2067 2068 final long token = Binder.clearCallingIdentity(); 2069 try { 2070 dumpInternal(pw); 2071 } finally { 2072 Binder.restoreCallingIdentity(token); 2073 } 2074 } 2075 2076 @Override // Binder call getBrightnessEvents(String callingPackage)2077 public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents(String callingPackage) { 2078 mContext.enforceCallingOrSelfPermission( 2079 Manifest.permission.BRIGHTNESS_SLIDER_USAGE, 2080 "Permission to read brightness events."); 2081 2082 final int callingUid = Binder.getCallingUid(); 2083 AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class); 2084 final int mode = appOpsManager.noteOp(AppOpsManager.OP_GET_USAGE_STATS, 2085 callingUid, callingPackage); 2086 final boolean hasUsageStats; 2087 if (mode == AppOpsManager.MODE_DEFAULT) { 2088 // The default behavior here is to check if PackageManager has given the app 2089 // permission. 2090 hasUsageStats = mContext.checkCallingPermission( 2091 Manifest.permission.PACKAGE_USAGE_STATS) 2092 == PackageManager.PERMISSION_GRANTED; 2093 } else { 2094 hasUsageStats = mode == AppOpsManager.MODE_ALLOWED; 2095 } 2096 2097 final int userId = UserHandle.getUserId(callingUid); 2098 final long token = Binder.clearCallingIdentity(); 2099 try { 2100 synchronized (mSyncRoot) { 2101 return mDisplayPowerController.getBrightnessEvents(userId, hasUsageStats); 2102 } 2103 } finally { 2104 Binder.restoreCallingIdentity(token); 2105 } 2106 } 2107 2108 @Override // Binder call getAmbientBrightnessStats()2109 public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats() { 2110 mContext.enforceCallingOrSelfPermission( 2111 Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS, 2112 "Permission required to to access ambient light stats."); 2113 final int callingUid = Binder.getCallingUid(); 2114 final int userId = UserHandle.getUserId(callingUid); 2115 final long token = Binder.clearCallingIdentity(); 2116 try { 2117 synchronized (mSyncRoot) { 2118 return mDisplayPowerController.getAmbientBrightnessStats(userId); 2119 } 2120 } finally { 2121 Binder.restoreCallingIdentity(token); 2122 } 2123 } 2124 2125 @Override // Binder call setBrightnessConfigurationForUser( BrightnessConfiguration c, @UserIdInt int userId, String packageName)2126 public void setBrightnessConfigurationForUser( 2127 BrightnessConfiguration c, @UserIdInt int userId, String packageName) { 2128 mContext.enforceCallingOrSelfPermission( 2129 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS, 2130 "Permission required to change the display's brightness configuration"); 2131 if (userId != UserHandle.getCallingUserId()) { 2132 mContext.enforceCallingOrSelfPermission( 2133 Manifest.permission.INTERACT_ACROSS_USERS, 2134 "Permission required to change the display brightness" 2135 + " configuration of another user"); 2136 } 2137 if (packageName != null && !validatePackageName(getCallingUid(), packageName)) { 2138 packageName = null; 2139 } 2140 final long token = Binder.clearCallingIdentity(); 2141 try { 2142 setBrightnessConfigurationForUserInternal(c, userId, packageName); 2143 } finally { 2144 Binder.restoreCallingIdentity(token); 2145 } 2146 } 2147 2148 @Override // Binder call getBrightnessConfigurationForUser(int userId)2149 public BrightnessConfiguration getBrightnessConfigurationForUser(int userId) { 2150 mContext.enforceCallingOrSelfPermission( 2151 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS, 2152 "Permission required to read the display's brightness configuration"); 2153 if (userId != UserHandle.getCallingUserId()) { 2154 mContext.enforceCallingOrSelfPermission( 2155 Manifest.permission.INTERACT_ACROSS_USERS, 2156 "Permission required to read the display brightness" 2157 + " configuration of another user"); 2158 } 2159 final long token = Binder.clearCallingIdentity(); 2160 try { 2161 final int userSerial = getUserManager().getUserSerialNumber(userId); 2162 synchronized (mSyncRoot) { 2163 BrightnessConfiguration config = 2164 mPersistentDataStore.getBrightnessConfiguration(userSerial); 2165 if (config == null) { 2166 config = mDisplayPowerController.getDefaultBrightnessConfiguration(); 2167 } 2168 return config; 2169 } 2170 } finally { 2171 Binder.restoreCallingIdentity(token); 2172 } 2173 } 2174 2175 @Override // Binder call getDefaultBrightnessConfiguration()2176 public BrightnessConfiguration getDefaultBrightnessConfiguration() { 2177 mContext.enforceCallingOrSelfPermission( 2178 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS, 2179 "Permission required to read the display's default brightness configuration"); 2180 final long token = Binder.clearCallingIdentity(); 2181 try { 2182 synchronized (mSyncRoot) { 2183 return mDisplayPowerController.getDefaultBrightnessConfiguration(); 2184 } 2185 } finally { 2186 Binder.restoreCallingIdentity(token); 2187 } 2188 } 2189 2190 @Override // Binder call setTemporaryBrightness(int brightness)2191 public void setTemporaryBrightness(int brightness) { 2192 mContext.enforceCallingOrSelfPermission( 2193 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS, 2194 "Permission required to set the display's brightness"); 2195 final long token = Binder.clearCallingIdentity(); 2196 try { 2197 synchronized (mSyncRoot) { 2198 mDisplayPowerController.setTemporaryBrightness(brightness); 2199 } 2200 } finally { 2201 Binder.restoreCallingIdentity(token); 2202 } 2203 } 2204 2205 @Override // Binder call setTemporaryAutoBrightnessAdjustment(float adjustment)2206 public void setTemporaryAutoBrightnessAdjustment(float adjustment) { 2207 mContext.enforceCallingOrSelfPermission( 2208 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS, 2209 "Permission required to set the display's auto brightness adjustment"); 2210 final long token = Binder.clearCallingIdentity(); 2211 try { 2212 synchronized (mSyncRoot) { 2213 mDisplayPowerController.setTemporaryAutoBrightnessAdjustment(adjustment); 2214 } 2215 } finally { 2216 Binder.restoreCallingIdentity(token); 2217 } 2218 } 2219 2220 @Override // Binder call onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)2221 public void onShellCommand(FileDescriptor in, FileDescriptor out, 2222 FileDescriptor err, String[] args, ShellCallback callback, 2223 ResultReceiver resultReceiver) { 2224 final long token = Binder.clearCallingIdentity(); 2225 try { 2226 DisplayManagerShellCommand command = new DisplayManagerShellCommand(this); 2227 command.exec(this, in, out, err, args, callback, resultReceiver); 2228 } finally { 2229 Binder.restoreCallingIdentity(token); 2230 } 2231 } 2232 2233 @Override // Binder call getMinimumBrightnessCurve()2234 public Curve getMinimumBrightnessCurve() { 2235 final long token = Binder.clearCallingIdentity(); 2236 try { 2237 return getMinimumBrightnessCurveInternal(); 2238 } finally { 2239 Binder.restoreCallingIdentity(token); 2240 } 2241 } 2242 2243 @Override // Binder call getPreferredWideGamutColorSpaceId()2244 public int getPreferredWideGamutColorSpaceId() { 2245 final long token = Binder.clearCallingIdentity(); 2246 try { 2247 return getPreferredWideGamutColorSpaceIdInternal(); 2248 } finally { 2249 Binder.restoreCallingIdentity(token); 2250 } 2251 } 2252 setBrightness(int brightness)2253 void setBrightness(int brightness) { 2254 Settings.System.putIntForUser(mContext.getContentResolver(), 2255 Settings.System.SCREEN_BRIGHTNESS, brightness, UserHandle.USER_CURRENT); 2256 } 2257 resetBrightnessConfiguration()2258 void resetBrightnessConfiguration() { 2259 setBrightnessConfigurationForUserInternal(null, mContext.getUserId(), 2260 mContext.getPackageName()); 2261 } 2262 setAutoBrightnessLoggingEnabled(boolean enabled)2263 void setAutoBrightnessLoggingEnabled(boolean enabled) { 2264 if (mDisplayPowerController != null) { 2265 synchronized (mSyncRoot) { 2266 mDisplayPowerController.setAutoBrightnessLoggingEnabled(enabled); 2267 } 2268 } 2269 } 2270 setDisplayWhiteBalanceLoggingEnabled(boolean enabled)2271 void setDisplayWhiteBalanceLoggingEnabled(boolean enabled) { 2272 if (mDisplayPowerController != null) { 2273 synchronized (mSyncRoot) { 2274 mDisplayPowerController.setDisplayWhiteBalanceLoggingEnabled(enabled); 2275 } 2276 } 2277 } 2278 setAmbientColorTemperatureOverride(float cct)2279 void setAmbientColorTemperatureOverride(float cct) { 2280 if (mDisplayPowerController != null) { 2281 synchronized (mSyncRoot) { 2282 mDisplayPowerController.setAmbientColorTemperatureOverride(cct); 2283 } 2284 } 2285 } 2286 validatePackageName(int uid, String packageName)2287 private boolean validatePackageName(int uid, String packageName) { 2288 if (packageName != null) { 2289 String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid); 2290 if (packageNames != null) { 2291 for (String n : packageNames) { 2292 if (n.equals(packageName)) { 2293 return true; 2294 } 2295 } 2296 } 2297 } 2298 return false; 2299 } 2300 canProjectVideo(IMediaProjection projection)2301 private boolean canProjectVideo(IMediaProjection projection) { 2302 if (projection != null) { 2303 try { 2304 if (projection.canProjectVideo()) { 2305 return true; 2306 } 2307 } catch (RemoteException e) { 2308 Slog.e(TAG, "Unable to query projection service for permissions", e); 2309 } 2310 } 2311 if (checkCallingPermission(CAPTURE_VIDEO_OUTPUT, "canProjectVideo()")) { 2312 return true; 2313 } 2314 return canProjectSecureVideo(projection); 2315 } 2316 canProjectSecureVideo(IMediaProjection projection)2317 private boolean canProjectSecureVideo(IMediaProjection projection) { 2318 if (projection != null) { 2319 try { 2320 if (projection.canProjectSecureVideo()){ 2321 return true; 2322 } 2323 } catch (RemoteException e) { 2324 Slog.e(TAG, "Unable to query projection service for permissions", e); 2325 } 2326 } 2327 return checkCallingPermission(CAPTURE_SECURE_VIDEO_OUTPUT, "canProjectSecureVideo()"); 2328 } 2329 checkCallingPermission(String permission, String func)2330 private boolean checkCallingPermission(String permission, String func) { 2331 if (mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) { 2332 return true; 2333 } 2334 final String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid() 2335 + ", uid=" + Binder.getCallingUid() + " requires " + permission; 2336 Slog.w(TAG, msg); 2337 return false; 2338 } 2339 } 2340 2341 private final class LocalService extends DisplayManagerInternal { 2342 @Override initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler, SensorManager sensorManager)2343 public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler, 2344 SensorManager sensorManager) { 2345 synchronized (mSyncRoot) { 2346 DisplayBlanker blanker = new DisplayBlanker() { 2347 @Override 2348 public void requestDisplayState(int state, int brightness) { 2349 // The order of operations is important for legacy reasons. 2350 if (state == Display.STATE_OFF) { 2351 requestGlobalDisplayStateInternal(state, brightness); 2352 } 2353 2354 callbacks.onDisplayStateChange(state); 2355 2356 if (state != Display.STATE_OFF) { 2357 requestGlobalDisplayStateInternal(state, brightness); 2358 } 2359 } 2360 }; 2361 mDisplayPowerController = new DisplayPowerController( 2362 mContext, callbacks, handler, sensorManager, blanker); 2363 mSensorManager = sensorManager; 2364 } 2365 2366 mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATION); 2367 } 2368 2369 @Override requestPowerState(DisplayPowerRequest request, boolean waitForNegativeProximity)2370 public boolean requestPowerState(DisplayPowerRequest request, 2371 boolean waitForNegativeProximity) { 2372 synchronized (mSyncRoot) { 2373 return mDisplayPowerController.requestPowerState(request, 2374 waitForNegativeProximity); 2375 } 2376 } 2377 2378 @Override isProximitySensorAvailable()2379 public boolean isProximitySensorAvailable() { 2380 synchronized (mSyncRoot) { 2381 return mDisplayPowerController.isProximitySensorAvailable(); 2382 } 2383 } 2384 2385 @Override screenshot(int displayId)2386 public SurfaceControl.ScreenshotGraphicBuffer screenshot(int displayId) { 2387 return screenshotInternal(displayId); 2388 } 2389 2390 @Override getDisplayInfo(int displayId)2391 public DisplayInfo getDisplayInfo(int displayId) { 2392 return getDisplayInfoInternal(displayId, Process.myUid()); 2393 } 2394 2395 @Override registerDisplayTransactionListener(DisplayTransactionListener listener)2396 public void registerDisplayTransactionListener(DisplayTransactionListener listener) { 2397 if (listener == null) { 2398 throw new IllegalArgumentException("listener must not be null"); 2399 } 2400 2401 registerDisplayTransactionListenerInternal(listener); 2402 } 2403 2404 @Override unregisterDisplayTransactionListener(DisplayTransactionListener listener)2405 public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) { 2406 if (listener == null) { 2407 throw new IllegalArgumentException("listener must not be null"); 2408 } 2409 2410 unregisterDisplayTransactionListenerInternal(listener); 2411 } 2412 2413 @Override setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info)2414 public void setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info) { 2415 setDisplayInfoOverrideFromWindowManagerInternal(displayId, info); 2416 } 2417 2418 @Override getNonOverrideDisplayInfo(int displayId, DisplayInfo outInfo)2419 public void getNonOverrideDisplayInfo(int displayId, DisplayInfo outInfo) { 2420 getNonOverrideDisplayInfoInternal(displayId, outInfo); 2421 } 2422 2423 @Override performTraversal(SurfaceControl.Transaction t)2424 public void performTraversal(SurfaceControl.Transaction t) { 2425 performTraversalInternal(t); 2426 } 2427 2428 @Override setDisplayProperties(int displayId, boolean hasContent, float requestedRefreshRate, int requestedMode, boolean inTraversal)2429 public void setDisplayProperties(int displayId, boolean hasContent, 2430 float requestedRefreshRate, int requestedMode, boolean inTraversal) { 2431 setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate, 2432 requestedMode, inTraversal); 2433 } 2434 2435 @Override setDisplayOffsets(int displayId, int x, int y)2436 public void setDisplayOffsets(int displayId, int x, int y) { 2437 setDisplayOffsetsInternal(displayId, x, y); 2438 } 2439 2440 @Override setDisplayScalingDisabled(int displayId, boolean disableScaling)2441 public void setDisplayScalingDisabled(int displayId, boolean disableScaling) { 2442 setDisplayScalingDisabledInternal(displayId, disableScaling); 2443 } 2444 2445 @Override setDisplayAccessUIDs(SparseArray<IntArray> newDisplayAccessUIDs)2446 public void setDisplayAccessUIDs(SparseArray<IntArray> newDisplayAccessUIDs) { 2447 setDisplayAccessUIDsInternal(newDisplayAccessUIDs); 2448 } 2449 2450 @Override persistBrightnessTrackerState()2451 public void persistBrightnessTrackerState() { 2452 synchronized (mSyncRoot) { 2453 mDisplayPowerController.persistBrightnessTrackerState(); 2454 } 2455 } 2456 2457 @Override onOverlayChanged()2458 public void onOverlayChanged() { 2459 synchronized (mSyncRoot) { 2460 for (int i = 0; i < mDisplayDevices.size(); i++) { 2461 mDisplayDevices.get(i).onOverlayChangedLocked(); 2462 } 2463 } 2464 } 2465 2466 @Override getDisplayedContentSamplingAttributes( int displayId)2467 public DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributes( 2468 int displayId) { 2469 return getDisplayedContentSamplingAttributesInternal(displayId); 2470 } 2471 2472 @Override setDisplayedContentSamplingEnabled( int displayId, boolean enable, int componentMask, int maxFrames)2473 public boolean setDisplayedContentSamplingEnabled( 2474 int displayId, boolean enable, int componentMask, int maxFrames) { 2475 return setDisplayedContentSamplingEnabledInternal( 2476 displayId, enable, componentMask, maxFrames); 2477 } 2478 2479 @Override getDisplayedContentSample(int displayId, long maxFrames, long timestamp)2480 public DisplayedContentSample getDisplayedContentSample(int displayId, 2481 long maxFrames, long timestamp) { 2482 return getDisplayedContentSampleInternal(displayId, maxFrames, timestamp); 2483 } 2484 2485 } 2486 2487 class AllowedDisplayModeObserver implements DisplayModeDirector.Listener { onAllowedDisplayModesChanged()2488 public void onAllowedDisplayModesChanged() { 2489 onAllowedDisplayModesChangedInternal(); 2490 } 2491 } 2492 } 2493