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