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