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_ALWAYS_UNLOCKED_DISPLAY; 20 import static android.Manifest.permission.ADD_TRUSTED_DISPLAY; 21 import static android.Manifest.permission.CAPTURE_SECURE_VIDEO_OUTPUT; 22 import static android.Manifest.permission.CAPTURE_VIDEO_OUTPUT; 23 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; 24 import static android.hardware.display.DisplayManager.EventsMask; 25 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED; 26 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; 27 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD; 28 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY; 29 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP; 30 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC; 31 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE; 32 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; 33 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED; 34 import static android.hardware.display.DisplayManagerGlobal.DisplayEvent; 35 import static android.hardware.display.DisplayViewport.VIEWPORT_EXTERNAL; 36 import static android.hardware.display.DisplayViewport.VIEWPORT_INTERNAL; 37 import static android.hardware.display.DisplayViewport.VIEWPORT_VIRTUAL; 38 39 import android.Manifest; 40 import android.annotation.NonNull; 41 import android.annotation.Nullable; 42 import android.annotation.UserIdInt; 43 import android.app.AppOpsManager; 44 import android.app.compat.CompatChanges; 45 import android.companion.virtual.IVirtualDevice; 46 import android.compat.annotation.ChangeId; 47 import android.compat.annotation.EnabledSince; 48 import android.content.BroadcastReceiver; 49 import android.content.Context; 50 import android.content.Intent; 51 import android.content.IntentFilter; 52 import android.content.pm.PackageManager; 53 import android.content.pm.ParceledListSlice; 54 import android.content.res.Resources; 55 import android.content.res.TypedArray; 56 import android.database.ContentObserver; 57 import android.graphics.ColorSpace; 58 import android.graphics.Point; 59 import android.hardware.Sensor; 60 import android.hardware.SensorManager; 61 import android.hardware.devicestate.DeviceStateManager; 62 import android.hardware.devicestate.DeviceStateManagerInternal; 63 import android.hardware.display.AmbientBrightnessDayStats; 64 import android.hardware.display.BrightnessChangeEvent; 65 import android.hardware.display.BrightnessConfiguration; 66 import android.hardware.display.BrightnessInfo; 67 import android.hardware.display.Curve; 68 import android.hardware.display.DisplayManager; 69 import android.hardware.display.DisplayManagerGlobal; 70 import android.hardware.display.DisplayManagerInternal; 71 import android.hardware.display.DisplayManagerInternal.DisplayGroupListener; 72 import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener; 73 import android.hardware.display.DisplayViewport; 74 import android.hardware.display.DisplayedContentSample; 75 import android.hardware.display.DisplayedContentSamplingAttributes; 76 import android.hardware.display.IDisplayManager; 77 import android.hardware.display.IDisplayManagerCallback; 78 import android.hardware.display.IVirtualDisplayCallback; 79 import android.hardware.display.VirtualDisplayConfig; 80 import android.hardware.display.WifiDisplayStatus; 81 import android.hardware.graphics.common.DisplayDecorationSupport; 82 import android.hardware.input.InputManagerInternal; 83 import android.media.projection.IMediaProjection; 84 import android.media.projection.IMediaProjectionManager; 85 import android.net.Uri; 86 import android.os.Binder; 87 import android.os.Handler; 88 import android.os.HandlerExecutor; 89 import android.os.IBinder; 90 import android.os.IBinder.DeathRecipient; 91 import android.os.Looper; 92 import android.os.Message; 93 import android.os.PowerManager; 94 import android.os.Process; 95 import android.os.RemoteException; 96 import android.os.ResultReceiver; 97 import android.os.ServiceManager; 98 import android.os.ShellCallback; 99 import android.os.SystemClock; 100 import android.os.SystemProperties; 101 import android.os.Trace; 102 import android.os.UserHandle; 103 import android.os.UserManager; 104 import android.provider.Settings; 105 import android.sysprop.DisplayProperties; 106 import android.text.TextUtils; 107 import android.util.ArrayMap; 108 import android.util.ArraySet; 109 import android.util.EventLog; 110 import android.util.IntArray; 111 import android.util.Pair; 112 import android.util.Slog; 113 import android.util.SparseArray; 114 import android.util.SparseIntArray; 115 import android.util.Spline; 116 import android.view.Display; 117 import android.view.DisplayEventReceiver; 118 import android.view.DisplayInfo; 119 import android.view.Surface; 120 import android.view.SurfaceControl; 121 import android.window.DisplayWindowPolicyController; 122 123 import com.android.internal.annotations.GuardedBy; 124 import com.android.internal.annotations.VisibleForTesting; 125 import com.android.internal.display.BrightnessSynchronizer; 126 import com.android.internal.util.DumpUtils; 127 import com.android.internal.util.FrameworkStatsLog; 128 import com.android.internal.util.IndentingPrintWriter; 129 import com.android.server.AnimationThread; 130 import com.android.server.DisplayThread; 131 import com.android.server.LocalServices; 132 import com.android.server.SystemService; 133 import com.android.server.UiThread; 134 import com.android.server.companion.virtual.VirtualDeviceManagerInternal; 135 import com.android.server.display.DisplayDeviceConfig.SensorData; 136 import com.android.server.display.utils.SensorUtils; 137 import com.android.server.wm.SurfaceAnimationThread; 138 import com.android.server.wm.WindowManagerInternal; 139 140 import java.io.FileDescriptor; 141 import java.io.PrintWriter; 142 import java.util.ArrayList; 143 import java.util.Arrays; 144 import java.util.List; 145 import java.util.Optional; 146 import java.util.Set; 147 import java.util.concurrent.CopyOnWriteArrayList; 148 import java.util.concurrent.atomic.AtomicLong; 149 import java.util.function.Consumer; 150 151 152 /** 153 * Manages attached displays. 154 * <p> 155 * The {@link DisplayManagerService} manages the global lifecycle of displays, 156 * decides how to configure logical displays based on the physical display devices currently 157 * attached, sends notifications to the system and to applications when the state 158 * changes, and so on. 159 * </p><p> 160 * The display manager service relies on a collection of {@link DisplayAdapter} components, 161 * for discovering and configuring physical display devices attached to the system. 162 * There are separate display adapters for each manner that devices are attached: 163 * one display adapter for physical displays, one for simulated non-functional 164 * displays when the system is headless, one for simulated overlay displays used for 165 * development, one for wifi displays, etc. 166 * </p><p> 167 * Display adapters are only weakly coupled to the display manager service. 168 * Display adapters communicate changes in display device state to the display manager 169 * service asynchronously via a {@link DisplayAdapter.Listener}, and through 170 * the {@link DisplayDeviceRepository.Listener}, which is ultimately registered 171 * by the display manager service. This separation of concerns is important for 172 * two main reasons. First, it neatly encapsulates the responsibilities of these 173 * two classes: display adapters handle individual display devices whereas 174 * the display manager service handles the global state. Second, it eliminates 175 * the potential for deadlocks resulting from asynchronous display device discovery. 176 * </p> 177 * 178 * <h3>Synchronization</h3> 179 * <p> 180 * Because the display manager may be accessed by multiple threads, the synchronization 181 * story gets a little complicated. In particular, the window manager may call into 182 * the display manager while holding a surface transaction with the expectation that 183 * it can apply changes immediately. Unfortunately, that means we can't just do 184 * everything asynchronously (*grump*). 185 * </p><p> 186 * To make this work, all of the objects that belong to the display manager must 187 * use the same lock. We call this lock the synchronization root and it has a unique 188 * type {@link DisplayManagerService.SyncRoot}. Methods that require this lock are 189 * named with the "Locked" suffix. 190 * </p><p> 191 * Where things get tricky is that the display manager is not allowed to make 192 * any potentially reentrant calls, especially into the window manager. We generally 193 * avoid this by making all potentially reentrant out-calls asynchronous. 194 * </p> 195 */ 196 public final class DisplayManagerService extends SystemService { 197 private static final String TAG = "DisplayManagerService"; 198 private static final boolean DEBUG = false; 199 200 // When this system property is set to 0, WFD is forcibly disabled on boot. 201 // When this system property is set to 1, WFD is forcibly enabled on boot. 202 // Otherwise WFD is enabled according to the value of config_enableWifiDisplay. 203 private static final String FORCE_WIFI_DISPLAY_ENABLE = "persist.debug.wfd.enable"; 204 205 private static final String PROP_DEFAULT_DISPLAY_TOP_INSET = "persist.sys.displayinset.top"; 206 private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000; 207 // This value needs to be in sync with the threshold 208 // in RefreshRateConfigs::getFrameRateDivisor. 209 private static final float THRESHOLD_FOR_REFRESH_RATES_DIVISORS = 0.0009f; 210 211 private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1; 212 private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2; 213 private static final int MSG_DELIVER_DISPLAY_EVENT = 3; 214 private static final int MSG_REQUEST_TRAVERSAL = 4; 215 private static final int MSG_UPDATE_VIEWPORT = 5; 216 private static final int MSG_LOAD_BRIGHTNESS_CONFIGURATIONS = 6; 217 private static final int MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE = 7; 218 private static final int MSG_DELIVER_DISPLAY_GROUP_EVENT = 8; 219 220 private final Context mContext; 221 private final DisplayManagerHandler mHandler; 222 private final Handler mUiHandler; 223 private final DisplayModeDirector mDisplayModeDirector; 224 private WindowManagerInternal mWindowManagerInternal; 225 private InputManagerInternal mInputManagerInternal; 226 private IMediaProjectionManager mProjectionService; 227 private DeviceStateManagerInternal mDeviceStateManager; 228 private int[] mUserDisabledHdrTypes = {}; 229 private boolean mAreUserDisabledHdrTypesAllowed = true; 230 231 // Display mode chosen by user. 232 private Display.Mode mUserPreferredMode; 233 234 // The synchronization root for the display manager. 235 // This lock guards most of the display manager's state. 236 // NOTE: This is synchronized on while holding WindowManagerService.mWindowMap so never call 237 // into WindowManagerService methods that require mWindowMap while holding this unless you are 238 // very very sure that no deadlock can occur. 239 private final SyncRoot mSyncRoot = new SyncRoot(); 240 241 // True if in safe mode. 242 // This option may disable certain display adapters. 243 public boolean mSafeMode; 244 245 // True if we are in a special boot mode where only core applications and 246 // services should be started. This option may disable certain display adapters. 247 public boolean mOnlyCore; 248 249 // All callback records indexed by calling process id. 250 public final SparseArray<CallbackRecord> mCallbacks = 251 new SparseArray<CallbackRecord>(); 252 253 /** 254 * All {@link IVirtualDevice} and {@link DisplayWindowPolicyController}s indexed by 255 * {@link DisplayInfo#displayId}. 256 */ 257 final SparseArray<Pair<IVirtualDevice, DisplayWindowPolicyController>> 258 mDisplayWindowPolicyControllers = new SparseArray<>(); 259 260 /** 261 * Map of every display device {@link HighBrightnessModeMetadata}s indexed by 262 * {@link DisplayDevice#mUniqueId}. 263 */ 264 public final ArrayMap<String, HighBrightnessModeMetadata> mHighBrightnessModeMetadataMap = 265 new ArrayMap<>(); 266 267 // List of all currently registered display adapters. 268 private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>(); 269 270 /** 271 * Repository of all active {@link DisplayDevice}s. 272 */ 273 private final DisplayDeviceRepository mDisplayDeviceRepo; 274 275 /** 276 * Contains all the {@link LogicalDisplay} instances and is responsible for mapping 277 * {@link DisplayDevice}s to {@link LogicalDisplay}s. DisplayManagerService listens to display 278 * event on this object. 279 */ 280 private final LogicalDisplayMapper mLogicalDisplayMapper; 281 282 // List of all display transaction listeners. 283 private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners = 284 new CopyOnWriteArrayList<DisplayTransactionListener>(); 285 286 /** List of all display group listeners. */ 287 private final CopyOnWriteArrayList<DisplayGroupListener> mDisplayGroupListeners = 288 new CopyOnWriteArrayList<>(); 289 290 /** All {@link DisplayPowerController}s indexed by {@link LogicalDisplay} ID. */ 291 private final SparseArray<DisplayPowerController> mDisplayPowerControllers = 292 new SparseArray<>(); 293 294 /** {@link DisplayBlanker} used by all {@link DisplayPowerController}s. */ 295 private final DisplayBlanker mDisplayBlanker = new DisplayBlanker() { 296 // Synchronized to avoid race conditions when updating multiple display states. 297 @Override 298 public synchronized void requestDisplayState(int displayId, int state, float brightness, 299 float sdrBrightness) { 300 boolean allInactive = true; 301 boolean allOff = true; 302 final boolean stateChanged; 303 synchronized (mSyncRoot) { 304 final int index = mDisplayStates.indexOfKey(displayId); 305 if (index > -1) { 306 final int currentState = mDisplayStates.valueAt(index); 307 stateChanged = state != currentState; 308 if (stateChanged) { 309 final int size = mDisplayStates.size(); 310 for (int i = 0; i < size; i++) { 311 final int displayState = i == index ? state : mDisplayStates.valueAt(i); 312 if (displayState != Display.STATE_OFF) { 313 allOff = false; 314 } 315 if (Display.isActiveState(displayState)) { 316 allInactive = false; 317 } 318 if (!allOff && !allInactive) { 319 break; 320 } 321 } 322 } 323 } else { 324 stateChanged = false; 325 } 326 } 327 328 // The order of operations is important for legacy reasons. 329 if (state == Display.STATE_OFF) { 330 requestDisplayStateInternal(displayId, state, brightness, sdrBrightness); 331 } 332 333 if (stateChanged) { 334 mDisplayPowerCallbacks.onDisplayStateChange(allInactive, allOff); 335 } 336 337 if (state != Display.STATE_OFF) { 338 requestDisplayStateInternal(displayId, state, brightness, sdrBrightness); 339 } 340 } 341 }; 342 343 /** 344 * Used to inform {@link com.android.server.power.PowerManagerService} of changes to display 345 * state. 346 */ 347 private DisplayManagerInternal.DisplayPowerCallbacks mDisplayPowerCallbacks; 348 349 /** The {@link Handler} used by all {@link DisplayPowerController}s. */ 350 private Handler mPowerHandler; 351 352 // A map from LogicalDisplay ID to display power state. 353 @GuardedBy("mSyncRoot") 354 private final SparseIntArray mDisplayStates = new SparseIntArray(); 355 356 // A map from LogicalDisplay ID to display brightness. 357 @GuardedBy("mSyncRoot") 358 private final SparseArray<BrightnessPair> mDisplayBrightnesses = new SparseArray<>(); 359 360 // Set to true when there are pending display changes that have yet to be applied 361 // to the surface flinger state. 362 private boolean mPendingTraversal; 363 364 // The Wifi display adapter, or null if not registered. 365 private WifiDisplayAdapter mWifiDisplayAdapter; 366 367 // The number of active wifi display scan requests. 368 private int mWifiDisplayScanRequestCount; 369 370 // The virtual display adapter, or null if not registered. 371 private VirtualDisplayAdapter mVirtualDisplayAdapter; 372 373 // The User ID of the current user 374 private @UserIdInt int mCurrentUserId; 375 376 // The stable device screen height and width. These are not tied to a specific display, even 377 // the default display, because they need to be stable over the course of the device's entire 378 // life, even if the default display changes (e.g. a new monitor is plugged into a PC-like 379 // device). 380 private Point mStableDisplaySize = new Point(); 381 382 // Whether the system has finished booting or not. 383 private boolean mSystemReady; 384 385 // The top inset of the default display. 386 // This gets persisted so that the boot animation knows how to transition from the display's 387 // full size to the size configured by the user. Right now we only persist and animate the top 388 // inset, but theoretically we could do it for all of them. 389 private int mDefaultDisplayTopInset; 390 391 // Viewports of the default display and the display that should receive touch 392 // input from an external source. Used by the input system. 393 @GuardedBy("mSyncRoot") 394 private final ArrayList<DisplayViewport> mViewports = new ArrayList<>(); 395 396 // Persistent data store for all internal settings maintained by the display manager service. 397 private final PersistentDataStore mPersistentDataStore = new PersistentDataStore(); 398 399 // Temporary callback list, used when sending display events to applications. 400 // May be used outside of the lock but only on the handler thread. 401 private final ArrayList<CallbackRecord> mTempCallbacks = new ArrayList<CallbackRecord>(); 402 403 // Temporary viewports, used when sending new viewport information to the 404 // input system. May be used outside of the lock but only on the handler thread. 405 private final ArrayList<DisplayViewport> mTempViewports = new ArrayList<>(); 406 407 // The default color mode for default displays. Overrides the usual 408 // Display.Display.COLOR_MODE_DEFAULT for local displays. 409 private final int mDefaultDisplayDefaultColorMode; 410 411 // Lists of UIDs that are present on the displays. Maps displayId -> array of UIDs. 412 private final SparseArray<IntArray> mDisplayAccessUIDs = new SparseArray<>(); 413 414 private final Injector mInjector; 415 416 // The minimum brightness curve, which guarantess that any brightness curve that dips below it 417 // is rejected by the system. 418 private final Curve mMinimumBrightnessCurve; 419 private final Spline mMinimumBrightnessSpline; 420 private final ColorSpace mWideColorSpace; 421 422 private SensorManager mSensorManager; 423 private BrightnessTracker mBrightnessTracker; 424 425 426 // Whether minimal post processing is allowed by the user. 427 @GuardedBy("mSyncRoot") 428 private boolean mMinimalPostProcessingAllowed; 429 430 // Receives notifications about changes to Settings. 431 private SettingsObserver mSettingsObserver; 432 433 // Keeps note of what state the device is in, used for idle screen brightness mode. 434 private boolean mIsDocked; 435 private boolean mIsDreaming; 436 437 private boolean mBootCompleted = false; 438 439 private final BroadcastReceiver mIdleModeReceiver = new BroadcastReceiver() { 440 @Override 441 public void onReceive(Context context, Intent intent) { 442 final DisplayManagerInternal dmi = 443 LocalServices.getService(DisplayManagerInternal.class); 444 if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) { 445 int dockState = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, 446 Intent.EXTRA_DOCK_STATE_UNDOCKED); 447 mIsDocked = dockState == Intent.EXTRA_DOCK_STATE_DESK 448 || dockState == Intent.EXTRA_DOCK_STATE_LE_DESK 449 || dockState == Intent.EXTRA_DOCK_STATE_HE_DESK; 450 } 451 if (Intent.ACTION_DREAMING_STARTED.equals(intent.getAction())) { 452 mIsDreaming = true; 453 } else if (Intent.ACTION_DREAMING_STOPPED.equals(intent.getAction())) { 454 mIsDreaming = false; 455 } 456 setDockedAndIdleEnabled(/* enabled= */(mIsDocked && mIsDreaming), 457 Display.DEFAULT_DISPLAY); 458 } 459 }; 460 461 private final boolean mAllowNonNativeRefreshRateOverride; 462 463 private final BrightnessSynchronizer mBrightnessSynchronizer; 464 465 /** 466 * Applications use {@link android.view.Display#getRefreshRate} and 467 * {@link android.view.Display.Mode#getRefreshRate} to know what is the display refresh rate. 468 * Starting with Android S, the platform might throttle down applications frame rate to a 469 * divisor of the refresh rate if it is more preferable (for example if the application called 470 * to {@link android.view.Surface#setFrameRate}). 471 * Applications will experience {@link android.view.Choreographer#postFrameCallback} callbacks 472 * and backpressure at the throttled frame rate. 473 * 474 * {@link android.view.Display#getRefreshRate} will always return the application frame rate 475 * and not the physical display refresh rate to allow applications to do frame pacing correctly. 476 * 477 * {@link android.view.Display.Mode#getRefreshRate} will return the application frame rate if 478 * compiled to a previous release and starting with Android S it will return the physical 479 * display refresh rate. 480 */ 481 @ChangeId 482 @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.S) 483 static final long DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE = 170503758L; 484 DisplayManagerService(Context context)485 public DisplayManagerService(Context context) { 486 this(context, new Injector()); 487 } 488 489 @VisibleForTesting DisplayManagerService(Context context, Injector injector)490 DisplayManagerService(Context context, Injector injector) { 491 super(context); 492 mInjector = injector; 493 mContext = context; 494 mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper()); 495 mUiHandler = UiThread.getHandler(); 496 mDisplayDeviceRepo = new DisplayDeviceRepository(mSyncRoot, mPersistentDataStore); 497 mLogicalDisplayMapper = new LogicalDisplayMapper(mContext, mDisplayDeviceRepo, 498 new LogicalDisplayListener(), mSyncRoot, mHandler); 499 mDisplayModeDirector = new DisplayModeDirector(context, mHandler); 500 mBrightnessSynchronizer = new BrightnessSynchronizer(mContext); 501 Resources resources = mContext.getResources(); 502 mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger( 503 com.android.internal.R.integer.config_defaultDisplayDefaultColorMode); 504 mDefaultDisplayTopInset = SystemProperties.getInt(PROP_DEFAULT_DISPLAY_TOP_INSET, -1); 505 float[] lux = getFloatArray(resources.obtainTypedArray( 506 com.android.internal.R.array.config_minimumBrightnessCurveLux)); 507 float[] nits = getFloatArray(resources.obtainTypedArray( 508 com.android.internal.R.array.config_minimumBrightnessCurveNits)); 509 mMinimumBrightnessCurve = new Curve(lux, nits); 510 mMinimumBrightnessSpline = Spline.createSpline(lux, nits); 511 512 mCurrentUserId = UserHandle.USER_SYSTEM; 513 ColorSpace[] colorSpaces = SurfaceControl.getCompositionColorSpaces(); 514 mWideColorSpace = colorSpaces[1]; 515 mAllowNonNativeRefreshRateOverride = mInjector.getAllowNonNativeRefreshRateOverride(); 516 517 mSystemReady = false; 518 } 519 setupSchedulerPolicies()520 public void setupSchedulerPolicies() { 521 // android.display and android.anim is critical to user experience and we should make sure 522 // it is not in the default foregroup groups, add it to top-app to make sure it uses all 523 // the cores and scheduling settings for top-app when it runs. 524 Process.setThreadGroupAndCpuset(DisplayThread.get().getThreadId(), 525 Process.THREAD_GROUP_TOP_APP); 526 Process.setThreadGroupAndCpuset(AnimationThread.get().getThreadId(), 527 Process.THREAD_GROUP_TOP_APP); 528 Process.setThreadGroupAndCpuset(SurfaceAnimationThread.get().getThreadId(), 529 Process.THREAD_GROUP_TOP_APP); 530 } 531 532 @Override onStart()533 public void onStart() { 534 // We need to pre-load the persistent data store so it's ready before the default display 535 // adapter is up so that we have it's configuration. We could load it lazily, but since 536 // we're going to have to read it in eventually we may as well do it here rather than after 537 // we've waited for the display to register itself with us. 538 synchronized (mSyncRoot) { 539 mPersistentDataStore.loadIfNeeded(); 540 loadStableDisplayValuesLocked(); 541 } 542 mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS); 543 544 // If there was a runtime restart then we may have stale caches left around, so we need to 545 // make sure to invalidate them upon every start. 546 DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); 547 548 publishBinderService(Context.DISPLAY_SERVICE, new BinderService(), 549 true /*allowIsolated*/); 550 publishLocalService(DisplayManagerInternal.class, new LocalService()); 551 } 552 553 @Override onBootPhase(int phase)554 public void onBootPhase(int phase) { 555 if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) { 556 synchronized (mSyncRoot) { 557 long timeout = SystemClock.uptimeMillis() 558 + mInjector.getDefaultDisplayDelayTimeout(); 559 while (mLogicalDisplayMapper.getDisplayLocked(Display.DEFAULT_DISPLAY) == null 560 || mVirtualDisplayAdapter == null) { 561 long delay = timeout - SystemClock.uptimeMillis(); 562 if (delay <= 0) { 563 throw new RuntimeException("Timeout waiting for default display " 564 + "to be initialized. DefaultDisplay=" 565 + mLogicalDisplayMapper.getDisplayLocked(Display.DEFAULT_DISPLAY) 566 + ", mVirtualDisplayAdapter=" + mVirtualDisplayAdapter); 567 } 568 if (DEBUG) { 569 Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay); 570 } 571 try { 572 mSyncRoot.wait(delay); 573 } catch (InterruptedException ex) { 574 } 575 } 576 } 577 } else if (phase == PHASE_BOOT_COMPLETED) { 578 synchronized (mSyncRoot) { 579 mBootCompleted = true; 580 for (int i = 0; i < mDisplayPowerControllers.size(); i++) { 581 mDisplayPowerControllers.valueAt(i).onBootCompleted(); 582 } 583 } 584 mDisplayModeDirector.onBootCompleted(); 585 mLogicalDisplayMapper.onBootCompleted(); 586 } 587 } 588 589 @Override onUserSwitching(@ullable TargetUser from, @NonNull TargetUser to)590 public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) { 591 final int newUserId = to.getUserIdentifier(); 592 final int userSerial = getUserManager().getUserSerialNumber(newUserId); 593 synchronized (mSyncRoot) { 594 boolean userSwitching = mCurrentUserId != newUserId; 595 if (userSwitching) { 596 mCurrentUserId = newUserId; 597 } 598 mLogicalDisplayMapper.forEachLocked(logicalDisplay -> { 599 if (logicalDisplay.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) { 600 return; 601 } 602 final DisplayPowerController dpc = mDisplayPowerControllers.get( 603 logicalDisplay.getDisplayIdLocked()); 604 if (dpc == null) { 605 return; 606 } 607 if (userSwitching) { 608 BrightnessConfiguration config = 609 getBrightnessConfigForDisplayWithPdsFallbackLocked( 610 logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(), 611 userSerial); 612 dpc.setBrightnessConfiguration(config, /* shouldResetShortTermModel= */ true); 613 } 614 dpc.onSwitchUser(newUserId); 615 }); 616 handleSettingsChange(); 617 } 618 } 619 620 // TODO: Use dependencies or a boot phase windowManagerAndInputReady()621 public void windowManagerAndInputReady() { 622 synchronized (mSyncRoot) { 623 mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class); 624 mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); 625 626 mDeviceStateManager = LocalServices.getService(DeviceStateManagerInternal.class); 627 mContext.getSystemService(DeviceStateManager.class).registerCallback( 628 new HandlerExecutor(mHandler), new DeviceStateListener()); 629 630 scheduleTraversalLocked(false); 631 } 632 } 633 634 /** 635 * Called when the system is ready to go. 636 */ systemReady(boolean safeMode, boolean onlyCore)637 public void systemReady(boolean safeMode, boolean onlyCore) { 638 synchronized (mSyncRoot) { 639 mSafeMode = safeMode; 640 mOnlyCore = onlyCore; 641 mSystemReady = true; 642 // Just in case the top inset changed before the system was ready. At this point, any 643 // relevant configuration should be in place. 644 recordTopInsetLocked(mLogicalDisplayMapper.getDisplayLocked(Display.DEFAULT_DISPLAY)); 645 646 updateSettingsLocked(); 647 648 updateUserDisabledHdrTypesFromSettingsLocked(); 649 updateUserPreferredDisplayModeSettingsLocked(); 650 } 651 652 mDisplayModeDirector.setDesiredDisplayModeSpecsListener( 653 new DesiredDisplayModeSpecsObserver()); 654 mDisplayModeDirector.start(mSensorManager); 655 656 mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS); 657 658 mSettingsObserver = new SettingsObserver(); 659 660 mBrightnessSynchronizer.startSynchronizing(); 661 662 final IntentFilter filter = new IntentFilter(); 663 filter.addAction(Intent.ACTION_DREAMING_STARTED); 664 filter.addAction(Intent.ACTION_DREAMING_STOPPED); 665 filter.addAction(Intent.ACTION_DOCK_EVENT); 666 667 mContext.registerReceiver(mIdleModeReceiver, filter); 668 } 669 670 @VisibleForTesting getDisplayHandler()671 Handler getDisplayHandler() { 672 return mHandler; 673 } 674 675 @VisibleForTesting getDisplayDeviceRepository()676 DisplayDeviceRepository getDisplayDeviceRepository() { 677 return mDisplayDeviceRepo; 678 } 679 loadStableDisplayValuesLocked()680 private void loadStableDisplayValuesLocked() { 681 final Point size = mPersistentDataStore.getStableDisplaySize(); 682 if (size.x > 0 && size.y > 0) { 683 // Just set these values directly so we don't write the display persistent data again 684 // unnecessarily 685 mStableDisplaySize.set(size.x, size.y); 686 } else { 687 final Resources res = mContext.getResources(); 688 final int width = res.getInteger( 689 com.android.internal.R.integer.config_stableDeviceDisplayWidth); 690 final int height = res.getInteger( 691 com.android.internal.R.integer.config_stableDeviceDisplayHeight); 692 if (width > 0 && height > 0) { 693 setStableDisplaySizeLocked(width, height); 694 } 695 } 696 } 697 getStableDisplaySizeInternal()698 private Point getStableDisplaySizeInternal() { 699 Point r = new Point(); 700 synchronized (mSyncRoot) { 701 if (mStableDisplaySize.x > 0 && mStableDisplaySize.y > 0) { 702 r.set(mStableDisplaySize.x, mStableDisplaySize.y); 703 } 704 } 705 return r; 706 } 707 registerDisplayTransactionListenerInternal( DisplayTransactionListener listener)708 private void registerDisplayTransactionListenerInternal( 709 DisplayTransactionListener listener) { 710 // List is self-synchronized copy-on-write. 711 mDisplayTransactionListeners.add(listener); 712 } 713 unregisterDisplayTransactionListenerInternal( DisplayTransactionListener listener)714 private void unregisterDisplayTransactionListenerInternal( 715 DisplayTransactionListener listener) { 716 // List is self-synchronized copy-on-write. 717 mDisplayTransactionListeners.remove(listener); 718 } 719 720 @VisibleForTesting setDisplayInfoOverrideFromWindowManagerInternal(int displayId, DisplayInfo info)721 void setDisplayInfoOverrideFromWindowManagerInternal(int displayId, DisplayInfo info) { 722 synchronized (mSyncRoot) { 723 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 724 if (display != null) { 725 if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) { 726 handleLogicalDisplayChangedLocked(display); 727 } 728 } 729 } 730 } 731 732 /** 733 * @see DisplayManagerInternal#getNonOverrideDisplayInfo(int, DisplayInfo) 734 */ getNonOverrideDisplayInfoInternal(int displayId, DisplayInfo outInfo)735 private void getNonOverrideDisplayInfoInternal(int displayId, DisplayInfo outInfo) { 736 synchronized (mSyncRoot) { 737 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 738 if (display != null) { 739 display.getNonOverrideDisplayInfoLocked(outInfo); 740 } 741 } 742 } 743 744 @VisibleForTesting performTraversalInternal(SurfaceControl.Transaction t)745 void performTraversalInternal(SurfaceControl.Transaction t) { 746 synchronized (mSyncRoot) { 747 if (!mPendingTraversal) { 748 return; 749 } 750 mPendingTraversal = false; 751 752 performTraversalLocked(t); 753 } 754 755 // List is self-synchronized copy-on-write. 756 for (DisplayTransactionListener listener : mDisplayTransactionListeners) { 757 listener.onDisplayTransaction(t); 758 } 759 } 760 clampBrightness(int displayState, float brightnessState)761 private float clampBrightness(int displayState, float brightnessState) { 762 if (displayState == Display.STATE_OFF) { 763 brightnessState = PowerManager.BRIGHTNESS_OFF_FLOAT; 764 } else if (brightnessState != PowerManager.BRIGHTNESS_OFF_FLOAT 765 && brightnessState < PowerManager.BRIGHTNESS_MIN) { 766 brightnessState = PowerManager.BRIGHTNESS_INVALID_FLOAT; 767 } else if (brightnessState > PowerManager.BRIGHTNESS_MAX) { 768 brightnessState = PowerManager.BRIGHTNESS_MAX; 769 } 770 return brightnessState; 771 } 772 requestDisplayStateInternal(int displayId, int state, float brightnessState, float sdrBrightnessState)773 private void requestDisplayStateInternal(int displayId, int state, float brightnessState, 774 float sdrBrightnessState) { 775 if (state == Display.STATE_UNKNOWN) { 776 state = Display.STATE_ON; 777 } 778 779 brightnessState = clampBrightness(state, brightnessState); 780 sdrBrightnessState = clampBrightness(state, sdrBrightnessState); 781 782 // Update the display state within the lock. 783 // Note that we do not need to schedule traversals here although it 784 // may happen as a side-effect of displays changing state. 785 final Runnable runnable; 786 final String traceMessage; 787 synchronized (mSyncRoot) { 788 final int index = mDisplayStates.indexOfKey(displayId); 789 790 final BrightnessPair brightnessPair = 791 index < 0 ? null : mDisplayBrightnesses.valueAt(index); 792 if (index < 0 || (mDisplayStates.valueAt(index) == state 793 && brightnessPair.brightness == brightnessState 794 && brightnessPair.sdrBrightness == sdrBrightnessState)) { 795 return; // Display no longer exists or no change. 796 } 797 798 traceMessage = "requestDisplayStateInternal(" 799 + displayId + ", " 800 + Display.stateToString(state) 801 + ", brightness=" + brightnessState 802 + ", sdrBrightness=" + sdrBrightnessState + ")"; 803 Trace.asyncTraceBegin(Trace.TRACE_TAG_POWER, traceMessage, displayId); 804 805 mDisplayStates.setValueAt(index, state); 806 brightnessPair.brightness = brightnessState; 807 brightnessPair.sdrBrightness = sdrBrightnessState; 808 runnable = updateDisplayStateLocked(mLogicalDisplayMapper.getDisplayLocked(displayId) 809 .getPrimaryDisplayDeviceLocked()); 810 } 811 812 // Setting the display power state can take hundreds of milliseconds 813 // to complete so we defer the most expensive part of the work until 814 // after we have exited the critical section to avoid blocking other 815 // threads for a long time. 816 if (runnable != null) { 817 runnable.run(); 818 } 819 Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, traceMessage, displayId); 820 } 821 822 private class SettingsObserver extends ContentObserver { 823 SettingsObserver() { 824 super(mHandler); 825 826 mContext.getContentResolver().registerContentObserver( 827 Settings.Secure.getUriFor( 828 Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED), false, this); 829 } 830 831 @Override 832 public void onChange(boolean selfChange, Uri uri) { 833 handleSettingsChange(); 834 } 835 } 836 837 private void handleSettingsChange() { 838 synchronized (mSyncRoot) { 839 updateSettingsLocked(); 840 scheduleTraversalLocked(false); 841 } 842 } 843 844 private void updateSettingsLocked() { 845 mMinimalPostProcessingAllowed = Settings.Secure.getIntForUser(mContext.getContentResolver(), 846 Settings.Secure.MINIMAL_POST_PROCESSING_ALLOWED, 1, UserHandle.USER_CURRENT) != 0; 847 } 848 849 private void updateUserDisabledHdrTypesFromSettingsLocked() { 850 mAreUserDisabledHdrTypesAllowed = (Settings.Global.getInt( 851 mContext.getContentResolver(), 852 Settings.Global.ARE_USER_DISABLED_HDR_FORMATS_ALLOWED, 853 1) != 0); 854 855 String userDisabledHdrTypes = Settings.Global.getString(mContext.getContentResolver(), 856 Settings.Global.USER_DISABLED_HDR_FORMATS); 857 858 if (userDisabledHdrTypes != null) { 859 try { 860 String[] userDisabledHdrTypeStrings = 861 TextUtils.split(userDisabledHdrTypes, ","); 862 mUserDisabledHdrTypes = new int[userDisabledHdrTypeStrings.length]; 863 for (int i = 0; i < userDisabledHdrTypeStrings.length; i++) { 864 mUserDisabledHdrTypes[i] = Integer.parseInt(userDisabledHdrTypeStrings[i]); 865 } 866 } catch (NumberFormatException e) { 867 Slog.e(TAG, "Failed to parse USER_DISABLED_HDR_FORMATS. " 868 + "Clearing the setting.", e); 869 clearUserDisabledHdrTypesLocked(); 870 } 871 } else { 872 clearUserDisabledHdrTypesLocked(); 873 } 874 } 875 876 private void clearUserDisabledHdrTypesLocked() { 877 mUserDisabledHdrTypes = new int[]{}; 878 synchronized (mSyncRoot) { 879 Settings.Global.putString(mContext.getContentResolver(), 880 Settings.Global.USER_DISABLED_HDR_FORMATS, ""); 881 } 882 } 883 884 private void updateUserPreferredDisplayModeSettingsLocked() { 885 final float refreshRate = Settings.Global.getFloat(mContext.getContentResolver(), 886 Settings.Global.USER_PREFERRED_REFRESH_RATE, Display.INVALID_DISPLAY_REFRESH_RATE); 887 final int height = Settings.Global.getInt(mContext.getContentResolver(), 888 Settings.Global.USER_PREFERRED_RESOLUTION_HEIGHT, Display.INVALID_DISPLAY_HEIGHT); 889 final int width = Settings.Global.getInt(mContext.getContentResolver(), 890 Settings.Global.USER_PREFERRED_RESOLUTION_WIDTH, Display.INVALID_DISPLAY_WIDTH); 891 Display.Mode mode = new Display.Mode(width, height, refreshRate); 892 mUserPreferredMode = isResolutionAndRefreshRateValid(mode) ? mode : null; 893 } 894 895 private DisplayInfo getDisplayInfoForFrameRateOverride(DisplayEventReceiver.FrameRateOverride[] 896 frameRateOverrides, DisplayInfo info, int callingUid) { 897 float frameRateHz = 0; 898 for (DisplayEventReceiver.FrameRateOverride frameRateOverride : frameRateOverrides) { 899 if (frameRateOverride.uid == callingUid) { 900 frameRateHz = frameRateOverride.frameRateHz; 901 break; 902 } 903 } 904 if (frameRateHz == 0) { 905 return info; 906 } 907 908 // Override the refresh rate only if it is a divisor of the current 909 // refresh rate. This calculation needs to be in sync with the native code 910 // in RefreshRateConfigs::getFrameRateDivisor 911 Display.Mode currentMode = info.getMode(); 912 float numPeriods = currentMode.getRefreshRate() / frameRateHz; 913 float numPeriodsRound = Math.round(numPeriods); 914 if (Math.abs(numPeriods - numPeriodsRound) > THRESHOLD_FOR_REFRESH_RATES_DIVISORS) { 915 return info; 916 } 917 frameRateHz = currentMode.getRefreshRate() / numPeriodsRound; 918 919 DisplayInfo overriddenInfo = new DisplayInfo(); 920 overriddenInfo.copyFrom(info); 921 for (Display.Mode mode : info.supportedModes) { 922 if (!mode.equalsExceptRefreshRate(currentMode)) { 923 continue; 924 } 925 926 if (mode.getRefreshRate() >= frameRateHz - THRESHOLD_FOR_REFRESH_RATES_DIVISORS 927 && mode.getRefreshRate() 928 <= frameRateHz + THRESHOLD_FOR_REFRESH_RATES_DIVISORS) { 929 if (DEBUG) { 930 Slog.d(TAG, "found matching modeId " + mode.getModeId()); 931 } 932 overriddenInfo.refreshRateOverride = mode.getRefreshRate(); 933 934 if (!CompatChanges.isChangeEnabled(DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE, 935 callingUid)) { 936 overriddenInfo.modeId = mode.getModeId(); 937 } 938 return overriddenInfo; 939 } 940 } 941 942 if (mAllowNonNativeRefreshRateOverride) { 943 overriddenInfo.refreshRateOverride = frameRateHz; 944 if (!CompatChanges.isChangeEnabled(DISPLAY_MODE_RETURNS_PHYSICAL_REFRESH_RATE, 945 callingUid)) { 946 overriddenInfo.supportedModes = Arrays.copyOf(info.supportedModes, 947 info.supportedModes.length + 1); 948 overriddenInfo.supportedModes[overriddenInfo.supportedModes.length - 1] = 949 new Display.Mode(Display.DISPLAY_MODE_ID_FOR_FRAME_RATE_OVERRIDE, 950 currentMode.getPhysicalWidth(), currentMode.getPhysicalHeight(), 951 overriddenInfo.refreshRateOverride); 952 overriddenInfo.modeId = 953 overriddenInfo.supportedModes[overriddenInfo.supportedModes.length - 1] 954 .getModeId(); 955 } 956 return overriddenInfo; 957 } 958 959 return info; 960 } 961 962 private DisplayInfo getDisplayInfoInternal(int displayId, int callingUid) { 963 synchronized (mSyncRoot) { 964 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 965 if (display != null) { 966 final DisplayInfo info = 967 getDisplayInfoForFrameRateOverride(display.getFrameRateOverrides(), 968 display.getDisplayInfoLocked(), callingUid); 969 if (info.hasAccess(callingUid) 970 || isUidPresentOnDisplayInternal(callingUid, displayId)) { 971 return info; 972 } 973 } 974 return null; 975 } 976 } 977 978 private void registerCallbackInternal(IDisplayManagerCallback callback, int callingPid, 979 int callingUid, @EventsMask long eventsMask) { 980 synchronized (mSyncRoot) { 981 CallbackRecord record = mCallbacks.get(callingPid); 982 983 if (record != null) { 984 record.updateEventsMask(eventsMask); 985 return; 986 } 987 988 record = new CallbackRecord(callingPid, callingUid, callback, eventsMask); 989 try { 990 IBinder binder = callback.asBinder(); 991 binder.linkToDeath(record, 0); 992 } catch (RemoteException ex) { 993 // give up 994 throw new RuntimeException(ex); 995 } 996 997 mCallbacks.put(callingPid, record); 998 } 999 } 1000 1001 private void onCallbackDied(CallbackRecord record) { 1002 synchronized (mSyncRoot) { 1003 mCallbacks.remove(record.mPid); 1004 stopWifiDisplayScanLocked(record); 1005 } 1006 } 1007 1008 private void startWifiDisplayScanInternal(int callingPid) { 1009 synchronized (mSyncRoot) { 1010 CallbackRecord record = mCallbacks.get(callingPid); 1011 if (record == null) { 1012 throw new IllegalStateException("The calling process has not " 1013 + "registered an IDisplayManagerCallback."); 1014 } 1015 startWifiDisplayScanLocked(record); 1016 } 1017 } 1018 1019 private void startWifiDisplayScanLocked(CallbackRecord record) { 1020 if (!record.mWifiDisplayScanRequested) { 1021 record.mWifiDisplayScanRequested = true; 1022 if (mWifiDisplayScanRequestCount++ == 0) { 1023 if (mWifiDisplayAdapter != null) { 1024 mWifiDisplayAdapter.requestStartScanLocked(); 1025 } 1026 } 1027 } 1028 } 1029 1030 private void stopWifiDisplayScanInternal(int callingPid) { 1031 synchronized (mSyncRoot) { 1032 CallbackRecord record = mCallbacks.get(callingPid); 1033 if (record == null) { 1034 throw new IllegalStateException("The calling process has not " 1035 + "registered an IDisplayManagerCallback."); 1036 } 1037 stopWifiDisplayScanLocked(record); 1038 } 1039 } 1040 1041 private void stopWifiDisplayScanLocked(CallbackRecord record) { 1042 if (record.mWifiDisplayScanRequested) { 1043 record.mWifiDisplayScanRequested = false; 1044 if (--mWifiDisplayScanRequestCount == 0) { 1045 if (mWifiDisplayAdapter != null) { 1046 mWifiDisplayAdapter.requestStopScanLocked(); 1047 } 1048 } else if (mWifiDisplayScanRequestCount < 0) { 1049 Slog.wtf(TAG, "mWifiDisplayScanRequestCount became negative: " 1050 + mWifiDisplayScanRequestCount); 1051 mWifiDisplayScanRequestCount = 0; 1052 } 1053 } 1054 } 1055 1056 private void connectWifiDisplayInternal(String address) { 1057 synchronized (mSyncRoot) { 1058 if (mWifiDisplayAdapter != null) { 1059 mWifiDisplayAdapter.requestConnectLocked(address); 1060 } 1061 } 1062 } 1063 1064 private void pauseWifiDisplayInternal() { 1065 synchronized (mSyncRoot) { 1066 if (mWifiDisplayAdapter != null) { 1067 mWifiDisplayAdapter.requestPauseLocked(); 1068 } 1069 } 1070 } 1071 1072 private void resumeWifiDisplayInternal() { 1073 synchronized (mSyncRoot) { 1074 if (mWifiDisplayAdapter != null) { 1075 mWifiDisplayAdapter.requestResumeLocked(); 1076 } 1077 } 1078 } 1079 1080 private void disconnectWifiDisplayInternal() { 1081 synchronized (mSyncRoot) { 1082 if (mWifiDisplayAdapter != null) { 1083 mWifiDisplayAdapter.requestDisconnectLocked(); 1084 } 1085 } 1086 } 1087 1088 private void renameWifiDisplayInternal(String address, String alias) { 1089 synchronized (mSyncRoot) { 1090 if (mWifiDisplayAdapter != null) { 1091 mWifiDisplayAdapter.requestRenameLocked(address, alias); 1092 } 1093 } 1094 } 1095 1096 private void forgetWifiDisplayInternal(String address) { 1097 synchronized (mSyncRoot) { 1098 if (mWifiDisplayAdapter != null) { 1099 mWifiDisplayAdapter.requestForgetLocked(address); 1100 } 1101 } 1102 } 1103 1104 private WifiDisplayStatus getWifiDisplayStatusInternal() { 1105 synchronized (mSyncRoot) { 1106 if (mWifiDisplayAdapter != null) { 1107 return mWifiDisplayAdapter.getWifiDisplayStatusLocked(); 1108 } 1109 return new WifiDisplayStatus(); 1110 } 1111 } 1112 1113 private void setUserDisabledHdrTypesInternal(int[] userDisabledHdrTypes) { 1114 synchronized (mSyncRoot) { 1115 if (userDisabledHdrTypes == null) { 1116 Slog.e(TAG, "Null is not an expected argument to " 1117 + "setUserDisabledHdrTypesInternal"); 1118 return; 1119 } 1120 1121 // Verify if userDisabledHdrTypes contains expected HDR types 1122 if (!isSubsetOf(Display.HdrCapabilities.HDR_TYPES, userDisabledHdrTypes)) { 1123 Slog.e(TAG, "userDisabledHdrTypes contains unexpected types"); 1124 return; 1125 } 1126 1127 Arrays.sort(userDisabledHdrTypes); 1128 if (Arrays.equals(mUserDisabledHdrTypes, userDisabledHdrTypes)) { 1129 return; 1130 } 1131 String userDisabledFormatsString = ""; 1132 if (userDisabledHdrTypes.length != 0) { 1133 userDisabledFormatsString = TextUtils.join(",", 1134 Arrays.stream(userDisabledHdrTypes).boxed().toArray()); 1135 } 1136 Settings.Global.putString(mContext.getContentResolver(), 1137 Settings.Global.USER_DISABLED_HDR_FORMATS, userDisabledFormatsString); 1138 mUserDisabledHdrTypes = userDisabledHdrTypes; 1139 if (!mAreUserDisabledHdrTypesAllowed) { 1140 mLogicalDisplayMapper.forEachLocked( 1141 display -> { 1142 display.setUserDisabledHdrTypes(userDisabledHdrTypes); 1143 handleLogicalDisplayChangedLocked(display); 1144 }); 1145 } 1146 } 1147 } 1148 1149 private boolean isSubsetOf(int[] sortedSuperset, int[] subset) { 1150 for (int i : subset) { 1151 if (Arrays.binarySearch(sortedSuperset, i) < 0) { 1152 return false; 1153 } 1154 } 1155 return true; 1156 } 1157 1158 private void setAreUserDisabledHdrTypesAllowedInternal( 1159 boolean areUserDisabledHdrTypesAllowed) { 1160 synchronized (mSyncRoot) { 1161 if (mAreUserDisabledHdrTypesAllowed == areUserDisabledHdrTypesAllowed) { 1162 return; 1163 } 1164 mAreUserDisabledHdrTypesAllowed = areUserDisabledHdrTypesAllowed; 1165 if (mUserDisabledHdrTypes.length == 0) { 1166 return; 1167 } 1168 Settings.Global.putInt(mContext.getContentResolver(), 1169 Settings.Global.ARE_USER_DISABLED_HDR_FORMATS_ALLOWED, 1170 areUserDisabledHdrTypesAllowed ? 1 : 0); 1171 int userDisabledHdrTypes[] = {}; 1172 if (!mAreUserDisabledHdrTypesAllowed) { 1173 userDisabledHdrTypes = mUserDisabledHdrTypes; 1174 } 1175 int[] finalUserDisabledHdrTypes = userDisabledHdrTypes; 1176 mLogicalDisplayMapper.forEachLocked( 1177 display -> { 1178 display.setUserDisabledHdrTypes(finalUserDisabledHdrTypes); 1179 handleLogicalDisplayChangedLocked(display); 1180 }); 1181 } 1182 } 1183 1184 private void requestColorModeInternal(int displayId, int colorMode) { 1185 synchronized (mSyncRoot) { 1186 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 1187 if (display != null && 1188 display.getRequestedColorModeLocked() != colorMode) { 1189 display.setRequestedColorModeLocked(colorMode); 1190 scheduleTraversalLocked(false); 1191 } 1192 } 1193 } 1194 1195 private boolean validatePackageName(int uid, String packageName) { 1196 if (packageName != null) { 1197 String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid); 1198 if (packageNames != null) { 1199 for (String n : packageNames) { 1200 if (n.equals(packageName)) { 1201 return true; 1202 } 1203 } 1204 } 1205 } 1206 return false; 1207 } 1208 1209 private boolean canProjectVideo(IMediaProjection projection) { 1210 if (projection != null) { 1211 try { 1212 if (projection.canProjectVideo()) { 1213 return true; 1214 } 1215 } catch (RemoteException e) { 1216 Slog.e(TAG, "Unable to query projection service for permissions", e); 1217 } 1218 } 1219 if (checkCallingPermission(CAPTURE_VIDEO_OUTPUT, "canProjectVideo()")) { 1220 return true; 1221 } 1222 return canProjectSecureVideo(projection); 1223 } 1224 1225 private boolean canProjectSecureVideo(IMediaProjection projection) { 1226 if (projection != null) { 1227 try { 1228 if (projection.canProjectSecureVideo()) { 1229 return true; 1230 } 1231 } catch (RemoteException e) { 1232 Slog.e(TAG, "Unable to query projection service for permissions", e); 1233 } 1234 } 1235 return checkCallingPermission(CAPTURE_SECURE_VIDEO_OUTPUT, "canProjectSecureVideo()"); 1236 } 1237 1238 private boolean checkCallingPermission(String permission, String func) { 1239 if (mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) { 1240 return true; 1241 } 1242 final String msg = "Permission Denial: " + func + " from pid=" + Binder.getCallingPid() 1243 + ", uid=" + Binder.getCallingUid() + " requires " + permission; 1244 Slog.w(TAG, msg); 1245 return false; 1246 } 1247 1248 private int createVirtualDisplayInternal(VirtualDisplayConfig virtualDisplayConfig, 1249 IVirtualDisplayCallback callback, IMediaProjection projection, 1250 IVirtualDevice virtualDevice, DisplayWindowPolicyController dwpc, String packageName) { 1251 final int callingUid = Binder.getCallingUid(); 1252 if (!validatePackageName(callingUid, packageName)) { 1253 throw new SecurityException("packageName must match the calling uid"); 1254 } 1255 if (callback == null) { 1256 throw new IllegalArgumentException("appToken must not be null"); 1257 } 1258 if (virtualDisplayConfig == null) { 1259 throw new IllegalArgumentException("virtualDisplayConfig must not be null"); 1260 } 1261 final Surface surface = virtualDisplayConfig.getSurface(); 1262 int flags = virtualDisplayConfig.getFlags(); 1263 if (virtualDevice != null) { 1264 final VirtualDeviceManagerInternal vdm = 1265 getLocalService(VirtualDeviceManagerInternal.class); 1266 if (!vdm.isValidVirtualDevice(virtualDevice)) { 1267 throw new SecurityException("Invalid virtual device"); 1268 } 1269 flags |= vdm.getBaseVirtualDisplayFlags(virtualDevice); 1270 } 1271 1272 if (surface != null && surface.isSingleBuffered()) { 1273 throw new IllegalArgumentException("Surface can't be single-buffered"); 1274 } 1275 1276 if ((flags & VIRTUAL_DISPLAY_FLAG_PUBLIC) != 0) { 1277 flags |= VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; 1278 1279 // Public displays can't be allowed to show content when locked. 1280 if ((flags & VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) { 1281 throw new IllegalArgumentException( 1282 "Public display must not be marked as SHOW_WHEN_LOCKED_INSECURE"); 1283 } 1284 } 1285 if ((flags & VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY) != 0) { 1286 flags &= ~VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR; 1287 } 1288 if ((flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) { 1289 flags &= ~VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP; 1290 } 1291 1292 if (projection != null) { 1293 try { 1294 if (!getProjectionService().isValidMediaProjection(projection)) { 1295 throw new SecurityException("Invalid media projection"); 1296 } 1297 flags = projection.applyVirtualDisplayFlags(flags); 1298 } catch (RemoteException e) { 1299 throw new SecurityException("unable to validate media projection or flags"); 1300 } 1301 } 1302 1303 if (callingUid != Process.SYSTEM_UID 1304 && (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0) { 1305 if (!canProjectVideo(projection)) { 1306 throw new SecurityException("Requires CAPTURE_VIDEO_OUTPUT or " 1307 + "CAPTURE_SECURE_VIDEO_OUTPUT permission, or an appropriate " 1308 + "MediaProjection token in order to create a screen sharing virtual " 1309 + "display."); 1310 } 1311 } 1312 if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_SECURE) != 0) { 1313 if (!canProjectSecureVideo(projection)) { 1314 throw new SecurityException("Requires CAPTURE_SECURE_VIDEO_OUTPUT " 1315 + "or an appropriate MediaProjection token to create a " 1316 + "secure virtual display."); 1317 } 1318 } 1319 1320 if (callingUid != Process.SYSTEM_UID && (flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) != 0) { 1321 if (!checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { 1322 EventLog.writeEvent(0x534e4554, "162627132", callingUid, 1323 "Attempt to create a trusted display without holding permission!"); 1324 throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to " 1325 + "create a trusted virtual display."); 1326 } 1327 } 1328 1329 if (callingUid != Process.SYSTEM_UID 1330 && (flags & VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP) != 0) { 1331 // The virtualDevice instance has been validated above using isValidVirtualDevice 1332 if (virtualDevice == null 1333 && !checkCallingPermission(ADD_TRUSTED_DISPLAY, "createVirtualDisplay()")) { 1334 throw new SecurityException("Requires ADD_TRUSTED_DISPLAY permission to " 1335 + "create a virtual display which is not in the default DisplayGroup."); 1336 } 1337 } 1338 1339 if ((flags & VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED) != 0) { 1340 if (callingUid != Process.SYSTEM_UID 1341 && !checkCallingPermission(ADD_ALWAYS_UNLOCKED_DISPLAY, 1342 "createVirtualDisplay()")) { 1343 throw new SecurityException( 1344 "Requires ADD_ALWAYS_UNLOCKED_DISPLAY permission to " 1345 + "create an always unlocked virtual display."); 1346 } 1347 } 1348 1349 if ((flags & VIRTUAL_DISPLAY_FLAG_TRUSTED) == 0) { 1350 flags &= ~VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; 1351 } 1352 1353 // Sometimes users can have sensitive information in system decoration windows. An app 1354 // could create a virtual display with system decorations support and read the user info 1355 // from the surface. 1356 // We should only allow adding flag VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS 1357 // to trusted virtual displays. 1358 final int trustedDisplayWithSysDecorFlag = 1359 (VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS 1360 | VIRTUAL_DISPLAY_FLAG_TRUSTED); 1361 if ((flags & trustedDisplayWithSysDecorFlag) 1362 == VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS 1363 && !checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "createVirtualDisplay()")) { 1364 throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission"); 1365 } 1366 1367 final long token = Binder.clearCallingIdentity(); 1368 try { 1369 synchronized (mSyncRoot) { 1370 final int displayId = createVirtualDisplayLocked(callback, projection, callingUid, 1371 packageName, surface, flags, virtualDisplayConfig); 1372 if (displayId != Display.INVALID_DISPLAY && virtualDevice != null && dwpc != null) { 1373 mDisplayWindowPolicyControllers.put(displayId, 1374 Pair.create(virtualDevice, dwpc)); 1375 } 1376 return displayId; 1377 } 1378 } finally { 1379 Binder.restoreCallingIdentity(token); 1380 } 1381 } 1382 1383 private int createVirtualDisplayLocked(IVirtualDisplayCallback callback, 1384 IMediaProjection projection, int callingUid, String packageName, Surface surface, 1385 int flags, VirtualDisplayConfig virtualDisplayConfig) { 1386 if (mVirtualDisplayAdapter == null) { 1387 Slog.w(TAG, "Rejecting request to create private virtual display " 1388 + "because the virtual display adapter is not available."); 1389 return -1; 1390 } 1391 1392 DisplayDevice device = mVirtualDisplayAdapter.createVirtualDisplayLocked( 1393 callback, projection, callingUid, packageName, surface, flags, 1394 virtualDisplayConfig); 1395 if (device == null) { 1396 return -1; 1397 } 1398 1399 // DisplayDevice events are handled manually for Virtual Displays. 1400 // TODO: multi-display Fix this so that generic add/remove events are not handled in a 1401 // different code path for virtual displays. Currently this happens so that we can 1402 // return a valid display ID synchronously upon successful Virtual Display creation. 1403 // This code can run on any binder thread, while onDisplayDeviceAdded() callbacks are 1404 // called on the DisplayThread (which we don't want to wait for?). 1405 // One option would be to actually wait here on the binder thread 1406 // to be notified when the virtual display is created (or failed). 1407 mDisplayDeviceRepo.onDisplayDeviceEvent(device, 1408 DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED); 1409 1410 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device); 1411 if (display != null) { 1412 return display.getDisplayIdLocked(); 1413 } 1414 1415 // Something weird happened and the logical display was not created. 1416 Slog.w(TAG, "Rejecting request to create virtual display " 1417 + "because the logical display was not created."); 1418 mVirtualDisplayAdapter.releaseVirtualDisplayLocked(callback.asBinder()); 1419 mDisplayDeviceRepo.onDisplayDeviceEvent(device, 1420 DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED); 1421 return -1; 1422 } 1423 1424 private void resizeVirtualDisplayInternal(IBinder appToken, 1425 int width, int height, int densityDpi) { 1426 synchronized (mSyncRoot) { 1427 if (mVirtualDisplayAdapter == null) { 1428 return; 1429 } 1430 1431 mVirtualDisplayAdapter.resizeVirtualDisplayLocked(appToken, width, height, densityDpi); 1432 } 1433 } 1434 1435 private void setVirtualDisplaySurfaceInternal(IBinder appToken, Surface surface) { 1436 synchronized (mSyncRoot) { 1437 if (mVirtualDisplayAdapter == null) { 1438 return; 1439 } 1440 1441 mVirtualDisplayAdapter.setVirtualDisplaySurfaceLocked(appToken, surface); 1442 } 1443 } 1444 1445 private void releaseVirtualDisplayInternal(IBinder appToken) { 1446 synchronized (mSyncRoot) { 1447 if (mVirtualDisplayAdapter == null) { 1448 return; 1449 } 1450 1451 DisplayDevice device = 1452 mVirtualDisplayAdapter.releaseVirtualDisplayLocked(appToken); 1453 if (device != null) { 1454 // TODO: multi-display - handle virtual displays the same as other display adapters. 1455 mDisplayDeviceRepo.onDisplayDeviceEvent(device, 1456 DisplayAdapter.DISPLAY_DEVICE_EVENT_REMOVED); 1457 } 1458 } 1459 } 1460 1461 private void setVirtualDisplayStateInternal(IBinder appToken, boolean isOn) { 1462 synchronized (mSyncRoot) { 1463 if (mVirtualDisplayAdapter == null) { 1464 return; 1465 } 1466 1467 mVirtualDisplayAdapter.setVirtualDisplayStateLocked(appToken, isOn); 1468 } 1469 } 1470 1471 private void registerDefaultDisplayAdapters() { 1472 // Register default display adapters. 1473 synchronized (mSyncRoot) { 1474 // main display adapter 1475 registerDisplayAdapterLocked(new LocalDisplayAdapter( 1476 mSyncRoot, mContext, mHandler, mDisplayDeviceRepo)); 1477 1478 // Standalone VR devices rely on a virtual display as their primary display for 1479 // 2D UI. We register virtual display adapter along side the main display adapter 1480 // here so that it is ready by the time the system sends the home Intent for 1481 // early apps like SetupWizard/Launcher. In particular, SUW is displayed using 1482 // the virtual display inside VR before any VR-specific apps even run. 1483 mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext, 1484 mHandler, mDisplayDeviceRepo); 1485 if (mVirtualDisplayAdapter != null) { 1486 registerDisplayAdapterLocked(mVirtualDisplayAdapter); 1487 } 1488 } 1489 } 1490 1491 private void registerAdditionalDisplayAdapters() { 1492 synchronized (mSyncRoot) { 1493 if (shouldRegisterNonEssentialDisplayAdaptersLocked()) { 1494 registerOverlayDisplayAdapterLocked(); 1495 registerWifiDisplayAdapterLocked(); 1496 } 1497 } 1498 } 1499 1500 private void registerOverlayDisplayAdapterLocked() { 1501 registerDisplayAdapterLocked(new OverlayDisplayAdapter( 1502 mSyncRoot, mContext, mHandler, mDisplayDeviceRepo, mUiHandler)); 1503 } 1504 1505 private void registerWifiDisplayAdapterLocked() { 1506 if (mContext.getResources().getBoolean( 1507 com.android.internal.R.bool.config_enableWifiDisplay) 1508 || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) { 1509 mWifiDisplayAdapter = new WifiDisplayAdapter( 1510 mSyncRoot, mContext, mHandler, mDisplayDeviceRepo, 1511 mPersistentDataStore); 1512 registerDisplayAdapterLocked(mWifiDisplayAdapter); 1513 } 1514 } 1515 1516 private boolean shouldRegisterNonEssentialDisplayAdaptersLocked() { 1517 // In safe mode, we disable non-essential display adapters to give the user 1518 // an opportunity to fix broken settings or other problems that might affect 1519 // system stability. 1520 // In only-core mode, we disable non-essential display adapters to minimize 1521 // the number of dependencies that are started while in this mode and to 1522 // prevent problems that might occur due to the device being encrypted. 1523 return !mSafeMode && !mOnlyCore; 1524 } 1525 1526 private void registerDisplayAdapterLocked(DisplayAdapter adapter) { 1527 mDisplayAdapters.add(adapter); 1528 adapter.registerLocked(); 1529 } 1530 1531 private void handleLogicalDisplayAddedLocked(LogicalDisplay display) { 1532 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); 1533 final int displayId = display.getDisplayIdLocked(); 1534 final boolean isDefault = displayId == Display.DEFAULT_DISPLAY; 1535 configureColorModeLocked(display, device); 1536 1537 if (!mAreUserDisabledHdrTypesAllowed) { 1538 display.setUserDisabledHdrTypes(mUserDisabledHdrTypes); 1539 } 1540 if (isDefault) { 1541 notifyDefaultDisplayDeviceUpdated(display); 1542 recordStableDisplayStatsIfNeededLocked(display); 1543 recordTopInsetLocked(display); 1544 } 1545 if (mUserPreferredMode != null) { 1546 device.setUserPreferredDisplayModeLocked(mUserPreferredMode); 1547 } else { 1548 configurePreferredDisplayModeLocked(display); 1549 } 1550 addDisplayPowerControllerLocked(display); 1551 1552 mDisplayStates.append(displayId, Display.STATE_UNKNOWN); 1553 1554 final float brightnessDefault = display.getDisplayInfoLocked().brightnessDefault; 1555 mDisplayBrightnesses.append(displayId, 1556 new BrightnessPair(brightnessDefault, brightnessDefault)); 1557 1558 DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); 1559 1560 // Wake up waitForDefaultDisplay. 1561 if (isDefault) { 1562 mSyncRoot.notifyAll(); 1563 } 1564 1565 sendDisplayEventLocked(display, DisplayManagerGlobal.EVENT_DISPLAY_ADDED); 1566 1567 Runnable work = updateDisplayStateLocked(device); 1568 if (work != null) { 1569 work.run(); 1570 } 1571 scheduleTraversalLocked(false); 1572 } 1573 1574 private void handleLogicalDisplayChangedLocked(@NonNull LogicalDisplay display) { 1575 updateViewportPowerStateLocked(display); 1576 1577 final int displayId = display.getDisplayIdLocked(); 1578 if (displayId == Display.DEFAULT_DISPLAY) { 1579 recordTopInsetLocked(display); 1580 } 1581 // We don't bother invalidating the display info caches here because any changes to the 1582 // display info will trigger a cache invalidation inside of LogicalDisplay before we hit 1583 // this point. 1584 sendDisplayEventLocked(display, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED); 1585 scheduleTraversalLocked(false); 1586 mPersistentDataStore.saveIfNeeded(); 1587 1588 DisplayPowerController dpc = mDisplayPowerControllers.get(displayId); 1589 if (dpc != null) { 1590 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); 1591 if (device == null) { 1592 Slog.wtf(TAG, "Display Device is null in DisplayManagerService for display: " 1593 + display.getDisplayIdLocked()); 1594 return; 1595 } 1596 1597 final String uniqueId = device.getUniqueId(); 1598 HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId); 1599 dpc.onDisplayChanged(hbmMetadata); 1600 } 1601 } 1602 1603 private void handleLogicalDisplayFrameRateOverridesChangedLocked( 1604 @NonNull LogicalDisplay display) { 1605 final int displayId = display.getDisplayIdLocked(); 1606 // We don't bother invalidating the display info caches here because any changes to the 1607 // display info will trigger a cache invalidation inside of LogicalDisplay before we hit 1608 // this point. 1609 sendDisplayEventFrameRateOverrideLocked(displayId); 1610 scheduleTraversalLocked(false); 1611 } 1612 1613 private void handleLogicalDisplayRemovedLocked(@NonNull LogicalDisplay display) { 1614 final int displayId = display.getDisplayIdLocked(); 1615 final DisplayPowerController dpc = mDisplayPowerControllers.removeReturnOld(displayId); 1616 if (dpc != null) { 1617 dpc.stop(); 1618 } 1619 mDisplayStates.delete(displayId); 1620 mDisplayBrightnesses.delete(displayId); 1621 DisplayManagerGlobal.invalidateLocalDisplayInfoCaches(); 1622 sendDisplayEventLocked(display, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED); 1623 scheduleTraversalLocked(false); 1624 1625 if (mDisplayWindowPolicyControllers.contains(displayId)) { 1626 final IVirtualDevice virtualDevice = mDisplayWindowPolicyControllers.removeReturnOld( 1627 displayId).first; 1628 if (virtualDevice != null) { 1629 mHandler.post(() -> { 1630 getLocalService(VirtualDeviceManagerInternal.class) 1631 .onVirtualDisplayRemoved(virtualDevice, displayId); 1632 }); 1633 } 1634 } 1635 } 1636 1637 private void handleLogicalDisplaySwappedLocked(@NonNull LogicalDisplay display) { 1638 handleLogicalDisplayChangedLocked(display); 1639 1640 final int displayId = display.getDisplayIdLocked(); 1641 if (displayId == Display.DEFAULT_DISPLAY) { 1642 notifyDefaultDisplayDeviceUpdated(display); 1643 } 1644 mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATIONS); 1645 } 1646 1647 private void notifyDefaultDisplayDeviceUpdated(LogicalDisplay display) { 1648 mDisplayModeDirector.defaultDisplayDeviceUpdated(display.getPrimaryDisplayDeviceLocked() 1649 .mDisplayDeviceConfig); 1650 } 1651 1652 private void handleLogicalDisplayDeviceStateTransitionLocked(@NonNull LogicalDisplay display) { 1653 final int displayId = display.getDisplayIdLocked(); 1654 final DisplayPowerController dpc = mDisplayPowerControllers.get(displayId); 1655 if (dpc != null) { 1656 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); 1657 if (device == null) { 1658 Slog.wtf(TAG, "Display Device is null in DisplayManagerService for display: " 1659 + display.getDisplayIdLocked()); 1660 return; 1661 } 1662 final String uniqueId = device.getUniqueId(); 1663 HighBrightnessModeMetadata hbmMetadata = mHighBrightnessModeMetadataMap.get(uniqueId); 1664 dpc.onDisplayChanged(hbmMetadata); 1665 } 1666 } 1667 1668 private Runnable updateDisplayStateLocked(DisplayDevice device) { 1669 // Blank or unblank the display immediately to match the state requested 1670 // by the display power controller (if known). 1671 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 1672 if ((info.flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) { 1673 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device); 1674 if (display == null) { 1675 return null; 1676 } 1677 final int displayId = display.getDisplayIdLocked(); 1678 final int state = mDisplayStates.get(displayId); 1679 1680 // Only send a request for display state if display state has already been initialized. 1681 if (state != Display.STATE_UNKNOWN) { 1682 final BrightnessPair brightnessPair = mDisplayBrightnesses.get(displayId); 1683 return device.requestDisplayStateLocked(state, brightnessPair.brightness, 1684 brightnessPair.sdrBrightness); 1685 } 1686 } 1687 return null; 1688 } 1689 1690 private void configureColorModeLocked(LogicalDisplay display, DisplayDevice device) { 1691 if (display.getPrimaryDisplayDeviceLocked() == device) { 1692 int colorMode = mPersistentDataStore.getColorMode(device); 1693 if (colorMode == Display.COLOR_MODE_INVALID) { 1694 if (display.getDisplayIdLocked() == Display.DEFAULT_DISPLAY) { 1695 colorMode = mDefaultDisplayDefaultColorMode; 1696 } else { 1697 colorMode = Display.COLOR_MODE_DEFAULT; 1698 } 1699 } 1700 display.setRequestedColorModeLocked(colorMode); 1701 } 1702 } 1703 1704 private void configurePreferredDisplayModeLocked(LogicalDisplay display) { 1705 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); 1706 final Point userPreferredResolution = 1707 mPersistentDataStore.getUserPreferredResolution(device); 1708 final float refreshRate = mPersistentDataStore.getUserPreferredRefreshRate(device); 1709 // If value in persistentDataStore is null, preserving the mode from systemPreferredMode. 1710 // This is required because in some devices, user-preferred mode was not stored in 1711 // persistentDataStore, but was stored in a config which is returned through 1712 // systemPreferredMode. 1713 if ((userPreferredResolution == null && Float.isNaN(refreshRate)) 1714 || (userPreferredResolution.equals(0, 0) && refreshRate == 0.0f)) { 1715 Display.Mode systemPreferredMode = device.getSystemPreferredDisplayModeLocked(); 1716 if (systemPreferredMode == null) { 1717 return; 1718 } 1719 storeModeInPersistentDataStoreLocked( 1720 display.getDisplayIdLocked(), systemPreferredMode.getPhysicalWidth(), 1721 systemPreferredMode.getPhysicalHeight(), systemPreferredMode.getRefreshRate()); 1722 device.setUserPreferredDisplayModeLocked(systemPreferredMode); 1723 return; 1724 } 1725 Display.Mode.Builder modeBuilder = new Display.Mode.Builder(); 1726 if (userPreferredResolution != null) { 1727 modeBuilder.setResolution(userPreferredResolution.x, userPreferredResolution.y); 1728 } 1729 if (!Float.isNaN(refreshRate)) { 1730 modeBuilder.setRefreshRate(refreshRate); 1731 } 1732 device.setUserPreferredDisplayModeLocked(modeBuilder.build()); 1733 } 1734 1735 // If we've never recorded stable device stats for this device before and they aren't 1736 // explicitly configured, go ahead and record the stable device stats now based on the status 1737 // of the default display at first boot. 1738 private void recordStableDisplayStatsIfNeededLocked(LogicalDisplay d) { 1739 if (mStableDisplaySize.x <= 0 && mStableDisplaySize.y <= 0) { 1740 DisplayInfo info = d.getDisplayInfoLocked(); 1741 setStableDisplaySizeLocked(info.getNaturalWidth(), info.getNaturalHeight()); 1742 } 1743 } 1744 1745 private void recordTopInsetLocked(@Nullable LogicalDisplay d) { 1746 // We must only persist the inset after boot has completed, otherwise we will end up 1747 // overwriting the persisted value before the masking flag has been loaded from the 1748 // resource overlay. 1749 if (!mSystemReady || d == null) { 1750 return; 1751 } 1752 int topInset = d.getInsets().top; 1753 if (topInset == mDefaultDisplayTopInset) { 1754 return; 1755 } 1756 mDefaultDisplayTopInset = topInset; 1757 SystemProperties.set(PROP_DEFAULT_DISPLAY_TOP_INSET, Integer.toString(topInset)); 1758 } 1759 1760 private void setStableDisplaySizeLocked(int width, int height) { 1761 mStableDisplaySize = new Point(width, height); 1762 try { 1763 mPersistentDataStore.setStableDisplaySize(mStableDisplaySize); 1764 } finally { 1765 mPersistentDataStore.saveIfNeeded(); 1766 } 1767 } 1768 1769 @VisibleForTesting 1770 Curve getMinimumBrightnessCurveInternal() { 1771 return mMinimumBrightnessCurve; 1772 } 1773 1774 int getPreferredWideGamutColorSpaceIdInternal() { 1775 return mWideColorSpace.getId(); 1776 } 1777 1778 void setUserPreferredDisplayModeInternal(int displayId, Display.Mode mode) { 1779 synchronized (mSyncRoot) { 1780 if (mode != null && !isResolutionAndRefreshRateValid(mode) 1781 && displayId == Display.INVALID_DISPLAY) { 1782 throw new IllegalArgumentException("width, height and refresh rate of mode should " 1783 + "be greater than 0 when setting the global user preferred display mode."); 1784 } 1785 1786 final int resolutionHeight = mode == null ? Display.INVALID_DISPLAY_HEIGHT 1787 : mode.getPhysicalHeight(); 1788 final int resolutionWidth = mode == null ? Display.INVALID_DISPLAY_WIDTH 1789 : mode.getPhysicalWidth(); 1790 final float refreshRate = mode == null ? Display.INVALID_DISPLAY_REFRESH_RATE 1791 : mode.getRefreshRate(); 1792 1793 storeModeInPersistentDataStoreLocked( 1794 displayId, resolutionWidth, resolutionHeight, refreshRate); 1795 if (displayId != Display.INVALID_DISPLAY) { 1796 setUserPreferredModeForDisplayLocked(displayId, mode); 1797 } else { 1798 mUserPreferredMode = mode; 1799 storeModeInGlobalSettingsLocked( 1800 resolutionWidth, resolutionHeight, refreshRate, mode); 1801 } 1802 } 1803 } 1804 1805 private void storeModeInPersistentDataStoreLocked(int displayId, int resolutionWidth, 1806 int resolutionHeight, float refreshRate) { 1807 DisplayDevice displayDevice = getDeviceForDisplayLocked(displayId); 1808 if (displayDevice == null) { 1809 return; 1810 } 1811 try { 1812 mPersistentDataStore.setUserPreferredResolution( 1813 displayDevice, resolutionWidth, resolutionHeight); 1814 mPersistentDataStore.setUserPreferredRefreshRate(displayDevice, refreshRate); 1815 } finally { 1816 mPersistentDataStore.saveIfNeeded(); 1817 } 1818 } 1819 1820 private void setUserPreferredModeForDisplayLocked(int displayId, Display.Mode mode) { 1821 DisplayDevice displayDevice = getDeviceForDisplayLocked(displayId); 1822 if (displayDevice == null) { 1823 return; 1824 } 1825 displayDevice.setUserPreferredDisplayModeLocked(mode); 1826 } 1827 1828 private void storeModeInGlobalSettingsLocked( 1829 int resolutionWidth, int resolutionHeight, float refreshRate, Display.Mode mode) { 1830 Settings.Global.putFloat(mContext.getContentResolver(), 1831 Settings.Global.USER_PREFERRED_REFRESH_RATE, refreshRate); 1832 Settings.Global.putInt(mContext.getContentResolver(), 1833 Settings.Global.USER_PREFERRED_RESOLUTION_HEIGHT, resolutionHeight); 1834 Settings.Global.putInt(mContext.getContentResolver(), 1835 Settings.Global.USER_PREFERRED_RESOLUTION_WIDTH, resolutionWidth); 1836 mDisplayDeviceRepo.forEachLocked((DisplayDevice device) -> { 1837 // If there is a display specific mode, don't override that 1838 final Point deviceUserPreferredResolution = 1839 mPersistentDataStore.getUserPreferredResolution(device); 1840 final float deviceRefreshRate = 1841 mPersistentDataStore.getUserPreferredRefreshRate(device); 1842 if (!isValidResolution(deviceUserPreferredResolution) 1843 && !isValidRefreshRate(deviceRefreshRate)) { 1844 device.setUserPreferredDisplayModeLocked(mode); 1845 } 1846 }); 1847 } 1848 1849 Display.Mode getUserPreferredDisplayModeInternal(int displayId) { 1850 synchronized (mSyncRoot) { 1851 if (displayId == Display.INVALID_DISPLAY) { 1852 return mUserPreferredMode; 1853 } 1854 DisplayDevice displayDevice = getDeviceForDisplayLocked(displayId); 1855 if (displayDevice == null) { 1856 return null; 1857 } 1858 return displayDevice.getUserPreferredDisplayModeLocked(); 1859 } 1860 } 1861 1862 Display.Mode getSystemPreferredDisplayModeInternal(int displayId) { 1863 synchronized (mSyncRoot) { 1864 final DisplayDevice device = getDeviceForDisplayLocked(displayId); 1865 if (device == null) { 1866 return null; 1867 } 1868 return device.getSystemPreferredDisplayModeLocked(); 1869 } 1870 } 1871 1872 void setShouldAlwaysRespectAppRequestedModeInternal(boolean enabled) { 1873 mDisplayModeDirector.setShouldAlwaysRespectAppRequestedMode(enabled); 1874 } 1875 1876 boolean shouldAlwaysRespectAppRequestedModeInternal() { 1877 return mDisplayModeDirector.shouldAlwaysRespectAppRequestedMode(); 1878 } 1879 1880 void setRefreshRateSwitchingTypeInternal(@DisplayManager.SwitchingType int newValue) { 1881 mDisplayModeDirector.setModeSwitchingType(newValue); 1882 } 1883 1884 @DisplayManager.SwitchingType 1885 int getRefreshRateSwitchingTypeInternal() { 1886 return mDisplayModeDirector.getModeSwitchingType(); 1887 } 1888 1889 private DisplayDecorationSupport getDisplayDecorationSupportInternal(int displayId) { 1890 final IBinder displayToken = getDisplayToken(displayId); 1891 if (null == displayToken) { 1892 return null; 1893 } 1894 return SurfaceControl.getDisplayDecorationSupport(displayToken); 1895 } 1896 1897 private void setBrightnessConfigurationForDisplayInternal( 1898 @Nullable BrightnessConfiguration c, String uniqueId, @UserIdInt int userId, 1899 String packageName) { 1900 validateBrightnessConfiguration(c); 1901 final int userSerial = getUserManager().getUserSerialNumber(userId); 1902 synchronized (mSyncRoot) { 1903 try { 1904 DisplayDevice displayDevice = mDisplayDeviceRepo.getByUniqueIdLocked(uniqueId); 1905 if (displayDevice == null) { 1906 return; 1907 } 1908 if (mLogicalDisplayMapper.getDisplayLocked(displayDevice) != null 1909 && mLogicalDisplayMapper.getDisplayLocked(displayDevice) 1910 .getDisplayInfoLocked().type == Display.TYPE_INTERNAL && c != null) { 1911 FrameworkStatsLog.write(FrameworkStatsLog.BRIGHTNESS_CONFIGURATION_UPDATED, 1912 c.getCurve().first, 1913 c.getCurve().second, 1914 // should not be logged for virtual displays 1915 uniqueId); 1916 } 1917 mPersistentDataStore.setBrightnessConfigurationForDisplayLocked(c, displayDevice, 1918 userSerial, packageName); 1919 } finally { 1920 mPersistentDataStore.saveIfNeeded(); 1921 } 1922 if (userId != mCurrentUserId) { 1923 return; 1924 } 1925 DisplayPowerController dpc = getDpcFromUniqueIdLocked(uniqueId); 1926 if (dpc != null) { 1927 dpc.setBrightnessConfiguration(c, /* shouldResetShortTermModel= */ true); 1928 } 1929 } 1930 } 1931 1932 private DisplayPowerController getDpcFromUniqueIdLocked(String uniqueId) { 1933 final DisplayDevice displayDevice = mDisplayDeviceRepo.getByUniqueIdLocked(uniqueId); 1934 final LogicalDisplay logicalDisplay = mLogicalDisplayMapper.getDisplayLocked(displayDevice); 1935 if (logicalDisplay != null) { 1936 final int displayId = logicalDisplay.getDisplayIdLocked(); 1937 return mDisplayPowerControllers.get(displayId); 1938 } 1939 return null; 1940 } 1941 1942 @VisibleForTesting 1943 void validateBrightnessConfiguration(BrightnessConfiguration config) { 1944 if (config == null) { 1945 return; 1946 } 1947 if (isBrightnessConfigurationTooDark(config)) { 1948 throw new IllegalArgumentException("brightness curve is too dark"); 1949 } 1950 } 1951 1952 private boolean isBrightnessConfigurationTooDark(BrightnessConfiguration config) { 1953 Pair<float[], float[]> curve = config.getCurve(); 1954 float[] lux = curve.first; 1955 float[] nits = curve.second; 1956 for (int i = 0; i < lux.length; i++) { 1957 if (nits[i] < mMinimumBrightnessSpline.interpolate(lux[i])) { 1958 return true; 1959 } 1960 } 1961 return false; 1962 } 1963 1964 private void loadBrightnessConfigurations() { 1965 int userSerial = getUserManager().getUserSerialNumber(mContext.getUserId()); 1966 synchronized (mSyncRoot) { 1967 mLogicalDisplayMapper.forEachLocked((logicalDisplay) -> { 1968 final String uniqueId = 1969 logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(); 1970 final BrightnessConfiguration config = 1971 getBrightnessConfigForDisplayWithPdsFallbackLocked(uniqueId, userSerial); 1972 if (config != null) { 1973 final DisplayPowerController dpc = mDisplayPowerControllers.get( 1974 logicalDisplay.getDisplayIdLocked()); 1975 if (dpc != null) { 1976 dpc.setBrightnessConfiguration(config, 1977 /* shouldResetShortTermModel= */ false); 1978 } 1979 } 1980 }); 1981 } 1982 } 1983 1984 private void performTraversalLocked(SurfaceControl.Transaction t) { 1985 // Clear all viewports before configuring displays so that we can keep 1986 // track of which ones we have configured. 1987 clearViewportsLocked(); 1988 1989 // Configure each display device. 1990 mLogicalDisplayMapper.forEachLocked((LogicalDisplay display) -> { 1991 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); 1992 if (device != null) { 1993 configureDisplayLocked(t, device); 1994 device.performTraversalLocked(t); 1995 } 1996 }); 1997 1998 // Tell the input system about these new viewports. 1999 if (mInputManagerInternal != null) { 2000 mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT); 2001 } 2002 } 2003 2004 private void setDisplayPropertiesInternal(int displayId, boolean hasContent, 2005 float requestedRefreshRate, int requestedModeId, float requestedMinRefreshRate, 2006 float requestedMaxRefreshRate, boolean preferMinimalPostProcessing, 2007 boolean inTraversal) { 2008 synchronized (mSyncRoot) { 2009 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 2010 if (display == null) { 2011 return; 2012 } 2013 2014 boolean shouldScheduleTraversal = false; 2015 2016 if (display.hasContentLocked() != hasContent) { 2017 if (DEBUG) { 2018 Slog.d(TAG, "Display " + displayId + " hasContent flag changed: " 2019 + "hasContent=" + hasContent + ", inTraversal=" + inTraversal); 2020 } 2021 2022 display.setHasContentLocked(hasContent); 2023 shouldScheduleTraversal = true; 2024 } 2025 if (requestedModeId == 0 && requestedRefreshRate != 0) { 2026 // Scan supported modes returned by display.getInfo() to find a mode with the same 2027 // size as the default display mode but with the specified refresh rate instead. 2028 Display.Mode mode = display.getDisplayInfoLocked().findDefaultModeByRefreshRate( 2029 requestedRefreshRate); 2030 if (mode != null) { 2031 requestedModeId = mode.getModeId(); 2032 } else { 2033 Slog.e(TAG, "Couldn't find a mode for the requestedRefreshRate: " 2034 + requestedRefreshRate + " on Display: " + displayId); 2035 } 2036 } 2037 mDisplayModeDirector.getAppRequestObserver().setAppRequest( 2038 displayId, requestedModeId, requestedMinRefreshRate, requestedMaxRefreshRate); 2039 2040 // TODO(b/202378408) set minimal post-processing only if it's supported once we have a 2041 // separate API for disabling on-device processing. 2042 boolean mppRequest = mMinimalPostProcessingAllowed && preferMinimalPostProcessing; 2043 2044 if (display.getRequestedMinimalPostProcessingLocked() != mppRequest) { 2045 display.setRequestedMinimalPostProcessingLocked(mppRequest); 2046 shouldScheduleTraversal = true; 2047 } 2048 2049 if (shouldScheduleTraversal) { 2050 scheduleTraversalLocked(inTraversal); 2051 } 2052 } 2053 } 2054 2055 private void setDisplayOffsetsInternal(int displayId, int x, int y) { 2056 synchronized (mSyncRoot) { 2057 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 2058 if (display == null) { 2059 return; 2060 } 2061 if (display.getDisplayOffsetXLocked() != x 2062 || display.getDisplayOffsetYLocked() != y) { 2063 if (DEBUG) { 2064 Slog.d(TAG, "Display " + displayId + " burn-in offset set to (" 2065 + x + ", " + y + ")"); 2066 } 2067 display.setDisplayOffsetsLocked(x, y); 2068 scheduleTraversalLocked(false); 2069 } 2070 } 2071 } 2072 2073 private void setDisplayScalingDisabledInternal(int displayId, boolean disable) { 2074 synchronized (mSyncRoot) { 2075 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 2076 if (display == null) { 2077 return; 2078 } 2079 if (display.isDisplayScalingDisabled() != disable) { 2080 if (DEBUG) { 2081 Slog.d(TAG, "Display " + displayId + " content scaling disabled = " + disable); 2082 } 2083 display.setDisplayScalingDisabledLocked(disable); 2084 scheduleTraversalLocked(false); 2085 } 2086 } 2087 } 2088 2089 // Updates the lists of UIDs that are present on displays. 2090 private void setDisplayAccessUIDsInternal(SparseArray<IntArray> newDisplayAccessUIDs) { 2091 synchronized (mSyncRoot) { 2092 mDisplayAccessUIDs.clear(); 2093 for (int i = newDisplayAccessUIDs.size() - 1; i >= 0; i--) { 2094 mDisplayAccessUIDs.append(newDisplayAccessUIDs.keyAt(i), 2095 newDisplayAccessUIDs.valueAt(i)); 2096 } 2097 } 2098 } 2099 2100 // Checks if provided UID's content is present on the display and UID has access to it. 2101 private boolean isUidPresentOnDisplayInternal(int uid, int displayId) { 2102 synchronized (mSyncRoot) { 2103 final IntArray displayUIDs = mDisplayAccessUIDs.get(displayId); 2104 return displayUIDs != null && displayUIDs.indexOf(uid) != -1; 2105 } 2106 } 2107 2108 @Nullable 2109 private IBinder getDisplayToken(int displayId) { 2110 synchronized (mSyncRoot) { 2111 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 2112 if (display != null) { 2113 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); 2114 if (device != null) { 2115 return device.getDisplayTokenLocked(); 2116 } 2117 } 2118 } 2119 2120 return null; 2121 } 2122 2123 private SurfaceControl.ScreenshotHardwareBuffer systemScreenshotInternal(int displayId) { 2124 final SurfaceControl.DisplayCaptureArgs captureArgs; 2125 synchronized (mSyncRoot) { 2126 final IBinder token = getDisplayToken(displayId); 2127 if (token == null) { 2128 return null; 2129 } 2130 final LogicalDisplay logicalDisplay = mLogicalDisplayMapper.getDisplayLocked(displayId); 2131 if (logicalDisplay == null) { 2132 return null; 2133 } 2134 2135 final DisplayInfo displayInfo = logicalDisplay.getDisplayInfoLocked(); 2136 captureArgs = new SurfaceControl.DisplayCaptureArgs.Builder(token) 2137 .setSize(displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight()) 2138 .setUseIdentityTransform(true) 2139 .setCaptureSecureLayers(true) 2140 .setAllowProtected(true) 2141 .build(); 2142 } 2143 return SurfaceControl.captureDisplay(captureArgs); 2144 } 2145 2146 private SurfaceControl.ScreenshotHardwareBuffer userScreenshotInternal(int displayId) { 2147 synchronized (mSyncRoot) { 2148 final IBinder token = getDisplayToken(displayId); 2149 if (token == null) { 2150 return null; 2151 } 2152 2153 final SurfaceControl.DisplayCaptureArgs captureArgs = 2154 new SurfaceControl.DisplayCaptureArgs.Builder(token) 2155 .build(); 2156 return SurfaceControl.captureDisplay(captureArgs); 2157 } 2158 } 2159 2160 @VisibleForTesting 2161 DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributesInternal( 2162 int displayId) { 2163 final IBinder token = getDisplayToken(displayId); 2164 if (token == null) { 2165 return null; 2166 } 2167 return SurfaceControl.getDisplayedContentSamplingAttributes(token); 2168 } 2169 2170 @VisibleForTesting 2171 boolean setDisplayedContentSamplingEnabledInternal( 2172 int displayId, boolean enable, int componentMask, int maxFrames) { 2173 final IBinder token = getDisplayToken(displayId); 2174 if (token == null) { 2175 return false; 2176 } 2177 return SurfaceControl.setDisplayedContentSamplingEnabled( 2178 token, enable, componentMask, maxFrames); 2179 } 2180 2181 @VisibleForTesting 2182 DisplayedContentSample getDisplayedContentSampleInternal(int displayId, 2183 long maxFrames, long timestamp) { 2184 final IBinder token = getDisplayToken(displayId); 2185 if (token == null) { 2186 return null; 2187 } 2188 return SurfaceControl.getDisplayedContentSample(token, maxFrames, timestamp); 2189 } 2190 2191 void resetBrightnessConfigurations() { 2192 mPersistentDataStore.setBrightnessConfigurationForUser(null, mContext.getUserId(), 2193 mContext.getPackageName()); 2194 mLogicalDisplayMapper.forEachLocked((logicalDisplay -> { 2195 if (logicalDisplay.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) { 2196 return; 2197 } 2198 final String uniqueId = logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(); 2199 setBrightnessConfigurationForDisplayInternal(null, uniqueId, mContext.getUserId(), 2200 mContext.getPackageName()); 2201 })); 2202 } 2203 setAutoBrightnessLoggingEnabled(boolean enabled)2204 void setAutoBrightnessLoggingEnabled(boolean enabled) { 2205 synchronized (mSyncRoot) { 2206 final DisplayPowerController displayPowerController = mDisplayPowerControllers.get( 2207 Display.DEFAULT_DISPLAY); 2208 if (displayPowerController != null) { 2209 displayPowerController.setAutoBrightnessLoggingEnabled(enabled); 2210 } 2211 } 2212 } 2213 setDisplayWhiteBalanceLoggingEnabled(boolean enabled)2214 void setDisplayWhiteBalanceLoggingEnabled(boolean enabled) { 2215 synchronized (mSyncRoot) { 2216 final DisplayPowerController displayPowerController = mDisplayPowerControllers.get( 2217 Display.DEFAULT_DISPLAY); 2218 if (displayPowerController != null) { 2219 displayPowerController.setDisplayWhiteBalanceLoggingEnabled(enabled); 2220 } 2221 } 2222 } 2223 setDisplayModeDirectorLoggingEnabled(boolean enabled)2224 void setDisplayModeDirectorLoggingEnabled(boolean enabled) { 2225 synchronized (mSyncRoot) { 2226 if (mDisplayModeDirector != null) { 2227 mDisplayModeDirector.setLoggingEnabled(enabled); 2228 } 2229 } 2230 } 2231 getActiveDisplayModeAtStart(int displayId)2232 Display.Mode getActiveDisplayModeAtStart(int displayId) { 2233 synchronized (mSyncRoot) { 2234 final DisplayDevice device = getDeviceForDisplayLocked(displayId); 2235 if (device == null) { 2236 return null; 2237 } 2238 return device.getActiveDisplayModeAtStartLocked(); 2239 } 2240 } 2241 setAmbientColorTemperatureOverride(float cct)2242 void setAmbientColorTemperatureOverride(float cct) { 2243 synchronized (mSyncRoot) { 2244 final DisplayPowerController displayPowerController = mDisplayPowerControllers.get( 2245 Display.DEFAULT_DISPLAY); 2246 if (displayPowerController != null) { 2247 displayPowerController.setAmbientColorTemperatureOverride(cct); 2248 } 2249 } 2250 } 2251 setDockedAndIdleEnabled(boolean enabled, int displayId)2252 void setDockedAndIdleEnabled(boolean enabled, int displayId) { 2253 synchronized (mSyncRoot) { 2254 final DisplayPowerController displayPowerController = mDisplayPowerControllers.get( 2255 displayId); 2256 if (displayPowerController != null) { 2257 displayPowerController.setAutomaticScreenBrightnessMode(enabled); 2258 } 2259 } 2260 } 2261 clearViewportsLocked()2262 private void clearViewportsLocked() { 2263 mViewports.clear(); 2264 } 2265 getViewportType(DisplayDeviceInfo info)2266 private Optional<Integer> getViewportType(DisplayDeviceInfo info) { 2267 // Get the corresponding viewport type. 2268 switch (info.touch) { 2269 case DisplayDeviceInfo.TOUCH_INTERNAL: 2270 return Optional.of(VIEWPORT_INTERNAL); 2271 case DisplayDeviceInfo.TOUCH_EXTERNAL: 2272 return Optional.of(VIEWPORT_EXTERNAL); 2273 case DisplayDeviceInfo.TOUCH_VIRTUAL: 2274 if (!TextUtils.isEmpty(info.uniqueId)) { 2275 return Optional.of(VIEWPORT_VIRTUAL); 2276 } 2277 // fallthrough 2278 default: 2279 Slog.w(TAG, "Display " + info + " does not support input device matching."); 2280 } 2281 return Optional.empty(); 2282 } 2283 configureDisplayLocked(SurfaceControl.Transaction t, DisplayDevice device)2284 private void configureDisplayLocked(SurfaceControl.Transaction t, DisplayDevice device) { 2285 final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 2286 final boolean ownContent = (info.flags & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0; 2287 2288 // Find the logical display that the display device is showing. 2289 // Certain displays only ever show their own content. 2290 LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device); 2291 // Proceed with display-managed mirroring only if window manager will not be handling it. 2292 if (!ownContent && !device.isWindowManagerMirroringLocked()) { 2293 // Only mirror the display if content recording is not taking place in WM. 2294 if (display != null && !display.hasContentLocked()) { 2295 // If the display does not have any content of its own, then 2296 // automatically mirror the requested logical display contents if possible. 2297 display = mLogicalDisplayMapper.getDisplayLocked( 2298 device.getDisplayIdToMirrorLocked()); 2299 } 2300 if (display == null) { 2301 display = mLogicalDisplayMapper.getDisplayLocked(Display.DEFAULT_DISPLAY); 2302 } 2303 } 2304 2305 // Apply the logical display configuration to the display device. 2306 if (display == null) { 2307 // TODO: no logical display for the device, blank it 2308 Slog.w(TAG, "Missing logical display to use for physical display device: " 2309 + device.getDisplayDeviceInfoLocked()); 2310 return; 2311 } 2312 display.configureDisplayLocked(t, device, info.state == Display.STATE_OFF); 2313 final Optional<Integer> viewportType = getViewportType(info); 2314 if (viewportType.isPresent()) { 2315 populateViewportLocked(viewportType.get(), display.getDisplayIdLocked(), device, info); 2316 } 2317 } 2318 2319 /** 2320 * Get internal or external viewport. Create it if does not currently exist. 2321 * @param viewportType - either INTERNAL or EXTERNAL 2322 * @return the viewport with the requested type 2323 */ getViewportLocked(int viewportType, String uniqueId)2324 private DisplayViewport getViewportLocked(int viewportType, String uniqueId) { 2325 if (viewportType != VIEWPORT_INTERNAL && viewportType != VIEWPORT_EXTERNAL 2326 && viewportType != VIEWPORT_VIRTUAL) { 2327 Slog.wtf(TAG, "Cannot call getViewportByTypeLocked for type " 2328 + DisplayViewport.typeToString(viewportType)); 2329 return null; 2330 } 2331 2332 DisplayViewport viewport; 2333 final int count = mViewports.size(); 2334 for (int i = 0; i < count; i++) { 2335 viewport = mViewports.get(i); 2336 if (viewport.type == viewportType && uniqueId.equals(viewport.uniqueId)) { 2337 return viewport; 2338 } 2339 } 2340 2341 // Creates the viewport if none exists. 2342 viewport = new DisplayViewport(); 2343 viewport.type = viewportType; 2344 viewport.uniqueId = uniqueId; 2345 mViewports.add(viewport); 2346 return viewport; 2347 } 2348 populateViewportLocked(int viewportType, int displayId, DisplayDevice device, DisplayDeviceInfo info)2349 private void populateViewportLocked(int viewportType, int displayId, DisplayDevice device, 2350 DisplayDeviceInfo info) { 2351 final DisplayViewport viewport = getViewportLocked(viewportType, info.uniqueId); 2352 device.populateViewportLocked(viewport); 2353 viewport.valid = true; 2354 viewport.displayId = displayId; 2355 viewport.isActive = Display.isActiveState(info.state); 2356 } 2357 updateViewportPowerStateLocked(LogicalDisplay display)2358 private void updateViewportPowerStateLocked(LogicalDisplay display) { 2359 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); 2360 final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); 2361 final Optional<Integer> viewportType = getViewportType(info); 2362 if (viewportType.isPresent()) { 2363 for (DisplayViewport d : mViewports) { 2364 if (d.type == viewportType.get() && info.uniqueId.equals(d.uniqueId)) { 2365 // Update display view port power state 2366 d.isActive = Display.isActiveState(info.state); 2367 } 2368 } 2369 if (mInputManagerInternal != null) { 2370 mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT); 2371 } 2372 } 2373 } 2374 sendDisplayEventLocked(@onNull LogicalDisplay display, @DisplayEvent int event)2375 private void sendDisplayEventLocked(@NonNull LogicalDisplay display, @DisplayEvent int event) { 2376 // Only send updates outside of DisplayManagerService for enabled displays 2377 if (display.isEnabledLocked()) { 2378 int displayId = display.getDisplayIdLocked(); 2379 Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT, displayId, event); 2380 mHandler.sendMessage(msg); 2381 } 2382 } 2383 sendDisplayGroupEvent(int groupId, int event)2384 private void sendDisplayGroupEvent(int groupId, int event) { 2385 Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_GROUP_EVENT, groupId, event); 2386 mHandler.sendMessage(msg); 2387 } 2388 sendDisplayEventFrameRateOverrideLocked(int displayId)2389 private void sendDisplayEventFrameRateOverrideLocked(int displayId) { 2390 Message msg = mHandler.obtainMessage(MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE, 2391 displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED); 2392 mHandler.sendMessage(msg); 2393 } 2394 2395 // Requests that performTraversals be called at a 2396 // later time to apply changes to surfaces and displays. scheduleTraversalLocked(boolean inTraversal)2397 private void scheduleTraversalLocked(boolean inTraversal) { 2398 if (!mPendingTraversal && mWindowManagerInternal != null) { 2399 mPendingTraversal = true; 2400 if (!inTraversal) { 2401 mHandler.sendEmptyMessage(MSG_REQUEST_TRAVERSAL); 2402 } 2403 } 2404 } 2405 2406 // Runs on Handler thread. 2407 // Delivers display event notifications to callbacks. deliverDisplayEvent(int displayId, ArraySet<Integer> uids, @DisplayEvent int event)2408 private void deliverDisplayEvent(int displayId, ArraySet<Integer> uids, 2409 @DisplayEvent int event) { 2410 if (DEBUG) { 2411 Slog.d(TAG, "Delivering display event: displayId=" 2412 + displayId + ", event=" + event); 2413 } 2414 2415 // Grab the lock and copy the callbacks. 2416 final int count; 2417 synchronized (mSyncRoot) { 2418 count = mCallbacks.size(); 2419 mTempCallbacks.clear(); 2420 for (int i = 0; i < count; i++) { 2421 if (uids == null || uids.contains(mCallbacks.valueAt(i).mUid)) { 2422 mTempCallbacks.add(mCallbacks.valueAt(i)); 2423 } 2424 } 2425 } 2426 2427 // After releasing the lock, send the notifications out. 2428 for (int i = 0; i < mTempCallbacks.size(); i++) { 2429 mTempCallbacks.get(i).notifyDisplayEventAsync(displayId, event); 2430 } 2431 mTempCallbacks.clear(); 2432 } 2433 2434 // Runs on Handler thread. 2435 // Delivers display group event notifications to callbacks. deliverDisplayGroupEvent(int groupId, int event)2436 private void deliverDisplayGroupEvent(int groupId, int event) { 2437 if (DEBUG) { 2438 Slog.d(TAG, "Delivering display group event: groupId=" + groupId + ", event=" 2439 + event); 2440 } 2441 2442 switch (event) { 2443 case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_ADDED: 2444 for (DisplayGroupListener listener : mDisplayGroupListeners) { 2445 listener.onDisplayGroupAdded(groupId); 2446 } 2447 break; 2448 2449 case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_CHANGED: 2450 for (DisplayGroupListener listener : mDisplayGroupListeners) { 2451 listener.onDisplayGroupChanged(groupId); 2452 } 2453 break; 2454 2455 case LogicalDisplayMapper.DISPLAY_GROUP_EVENT_REMOVED: 2456 for (DisplayGroupListener listener : mDisplayGroupListeners) { 2457 listener.onDisplayGroupRemoved(groupId); 2458 } 2459 break; 2460 } 2461 } 2462 getProjectionService()2463 private IMediaProjectionManager getProjectionService() { 2464 if (mProjectionService == null) { 2465 IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE); 2466 mProjectionService = IMediaProjectionManager.Stub.asInterface(b); 2467 } 2468 return mProjectionService; 2469 } 2470 getUserManager()2471 private UserManager getUserManager() { 2472 return mContext.getSystemService(UserManager.class); 2473 } 2474 dumpInternal(PrintWriter pw)2475 private void dumpInternal(PrintWriter pw) { 2476 pw.println("DISPLAY MANAGER (dumpsys display)"); 2477 2478 synchronized (mSyncRoot) { 2479 pw.println(" mOnlyCode=" + mOnlyCore); 2480 pw.println(" mSafeMode=" + mSafeMode); 2481 pw.println(" mPendingTraversal=" + mPendingTraversal); 2482 pw.println(" mViewports=" + mViewports); 2483 pw.println(" mDefaultDisplayDefaultColorMode=" + mDefaultDisplayDefaultColorMode); 2484 pw.println(" mWifiDisplayScanRequestCount=" + mWifiDisplayScanRequestCount); 2485 pw.println(" mStableDisplaySize=" + mStableDisplaySize); 2486 pw.println(" mMinimumBrightnessCurve=" + mMinimumBrightnessCurve); 2487 2488 if (mUserPreferredMode != null) { 2489 pw.println(" mUserPreferredMode=" + mUserPreferredMode); 2490 } 2491 2492 pw.println(); 2493 if (!mAreUserDisabledHdrTypesAllowed) { 2494 pw.println(" mUserDisabledHdrTypes: size=" + mUserDisabledHdrTypes.length); 2495 for (int type : mUserDisabledHdrTypes) { 2496 pw.println(" " + type); 2497 } 2498 } 2499 2500 pw.println(); 2501 final int displayStateCount = mDisplayStates.size(); 2502 pw.println("Display States: size=" + displayStateCount); 2503 for (int i = 0; i < displayStateCount; i++) { 2504 final int displayId = mDisplayStates.keyAt(i); 2505 final int displayState = mDisplayStates.valueAt(i); 2506 final BrightnessPair brightnessPair = mDisplayBrightnesses.valueAt(i); 2507 pw.println(" Display Id=" + displayId); 2508 pw.println(" Display State=" + Display.stateToString(displayState)); 2509 pw.println(" Display Brightness=" + brightnessPair.brightness); 2510 pw.println(" Display SdrBrightness=" + brightnessPair.sdrBrightness); 2511 } 2512 2513 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 2514 ipw.increaseIndent(); 2515 2516 pw.println(); 2517 pw.println("Display Adapters: size=" + mDisplayAdapters.size()); 2518 for (DisplayAdapter adapter : mDisplayAdapters) { 2519 pw.println(" " + adapter.getName()); 2520 adapter.dumpLocked(ipw); 2521 } 2522 2523 pw.println(); 2524 pw.println("Display Devices: size=" + mDisplayDeviceRepo.sizeLocked()); 2525 mDisplayDeviceRepo.forEachLocked(device -> { 2526 pw.println(" " + device.getDisplayDeviceInfoLocked()); 2527 device.dumpLocked(ipw); 2528 }); 2529 2530 pw.println(); 2531 mLogicalDisplayMapper.dumpLocked(pw); 2532 2533 final int callbackCount = mCallbacks.size(); 2534 pw.println(); 2535 pw.println("Callbacks: size=" + callbackCount); 2536 for (int i = 0; i < callbackCount; i++) { 2537 CallbackRecord callback = mCallbacks.valueAt(i); 2538 pw.println(" " + i + ": mPid=" + callback.mPid 2539 + ", mWifiDisplayScanRequested=" + callback.mWifiDisplayScanRequested); 2540 } 2541 2542 final int displayPowerControllerCount = mDisplayPowerControllers.size(); 2543 pw.println(); 2544 pw.println("Display Power Controllers: size=" + displayPowerControllerCount); 2545 for (int i = 0; i < displayPowerControllerCount; i++) { 2546 mDisplayPowerControllers.valueAt(i).dump(pw); 2547 } 2548 if (mBrightnessTracker != null) { 2549 pw.println(); 2550 mBrightnessTracker.dump(pw); 2551 } 2552 pw.println(); 2553 mPersistentDataStore.dump(pw); 2554 2555 final int displayWindowPolicyControllerCount = mDisplayWindowPolicyControllers.size(); 2556 pw.println(); 2557 pw.println("Display Window Policy Controllers: size=" 2558 + displayWindowPolicyControllerCount); 2559 for (int i = 0; i < displayWindowPolicyControllerCount; i++) { 2560 pw.print("Display " + mDisplayWindowPolicyControllers.keyAt(i) + ":"); 2561 mDisplayWindowPolicyControllers.valueAt(i).second.dump(" ", pw); 2562 } 2563 } 2564 pw.println(); 2565 mDisplayModeDirector.dump(pw); 2566 mBrightnessSynchronizer.dump(pw); 2567 } 2568 getFloatArray(TypedArray array)2569 private static float[] getFloatArray(TypedArray array) { 2570 int length = array.length(); 2571 float[] floatArray = new float[length]; 2572 for (int i = 0; i < length; i++) { 2573 floatArray[i] = array.getFloat(i, Float.NaN); 2574 } 2575 array.recycle(); 2576 return floatArray; 2577 } 2578 isResolutionAndRefreshRateValid(Display.Mode mode)2579 private static boolean isResolutionAndRefreshRateValid(Display.Mode mode) { 2580 return mode.getPhysicalWidth() > 0 && mode.getPhysicalHeight() > 0 2581 && mode.getRefreshRate() > 0.0f; 2582 } 2583 2584 /** 2585 * This is the object that everything in the display manager locks on. 2586 * We make it an inner class within the {@link DisplayManagerService} to so that it is 2587 * clear that the object belongs to the display manager service and that it is 2588 * a unique object with a special purpose. 2589 */ 2590 public static final class SyncRoot { 2591 } 2592 2593 @VisibleForTesting 2594 static class Injector { getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, Handler handler, DisplayAdapter.Listener displayAdapterListener)2595 VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context, 2596 Handler handler, DisplayAdapter.Listener displayAdapterListener) { 2597 return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener); 2598 } 2599 getDefaultDisplayDelayTimeout()2600 long getDefaultDisplayDelayTimeout() { 2601 return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT; 2602 } 2603 getAllowNonNativeRefreshRateOverride()2604 boolean getAllowNonNativeRefreshRateOverride() { 2605 return DisplayProperties 2606 .debug_allow_non_native_refresh_rate_override().orElse(true); 2607 } 2608 } 2609 2610 @VisibleForTesting getDisplayDeviceInfoInternal(int displayId)2611 DisplayDeviceInfo getDisplayDeviceInfoInternal(int displayId) { 2612 synchronized (mSyncRoot) { 2613 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 2614 if (display != null) { 2615 final DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked(); 2616 return displayDevice.getDisplayDeviceInfoLocked(); 2617 } 2618 return null; 2619 } 2620 } 2621 2622 @VisibleForTesting getDisplayIdToMirrorInternal(int displayId)2623 int getDisplayIdToMirrorInternal(int displayId) { 2624 synchronized (mSyncRoot) { 2625 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 2626 if (display != null) { 2627 final DisplayDevice displayDevice = display.getPrimaryDisplayDeviceLocked(); 2628 return displayDevice.getDisplayIdToMirrorLocked(); 2629 } 2630 return Display.INVALID_DISPLAY; 2631 } 2632 } 2633 2634 @VisibleForTesting getVirtualDisplaySurfaceInternal(IBinder appToken)2635 Surface getVirtualDisplaySurfaceInternal(IBinder appToken) { 2636 synchronized (mSyncRoot) { 2637 if (mVirtualDisplayAdapter == null) { 2638 return null; 2639 } 2640 return mVirtualDisplayAdapter.getVirtualDisplaySurfaceLocked(appToken); 2641 } 2642 } 2643 initializeDisplayPowerControllersLocked()2644 private void initializeDisplayPowerControllersLocked() { 2645 mLogicalDisplayMapper.forEachLocked(this::addDisplayPowerControllerLocked); 2646 } 2647 2648 @VisibleForTesting getHighBrightnessModeMetadata(LogicalDisplay display)2649 HighBrightnessModeMetadata getHighBrightnessModeMetadata(LogicalDisplay display) { 2650 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); 2651 if (device == null) { 2652 Slog.wtf(TAG, "Display Device is null in DisplayPowerController for display: " 2653 + display.getDisplayIdLocked()); 2654 return null; 2655 } 2656 2657 final String uniqueId = device.getUniqueId(); 2658 2659 if (mHighBrightnessModeMetadataMap.containsKey(uniqueId)) { 2660 return mHighBrightnessModeMetadataMap.get(uniqueId); 2661 } 2662 2663 // HBM Time info not present. Create a new one for this physical display. 2664 HighBrightnessModeMetadata hbmInfo = new HighBrightnessModeMetadata(); 2665 mHighBrightnessModeMetadataMap.put(uniqueId, hbmInfo); 2666 return hbmInfo; 2667 } 2668 addDisplayPowerControllerLocked(LogicalDisplay display)2669 private void addDisplayPowerControllerLocked(LogicalDisplay display) { 2670 if (mPowerHandler == null) { 2671 // initPowerManagement has not yet been called. 2672 return; 2673 } 2674 if (mBrightnessTracker == null && display.getDisplayIdLocked() == Display.DEFAULT_DISPLAY) { 2675 mBrightnessTracker = new BrightnessTracker(mContext, null); 2676 } 2677 2678 final BrightnessSetting brightnessSetting = new BrightnessSetting(mPersistentDataStore, 2679 display, mSyncRoot); 2680 2681 // If display already has a HighBrightnessModeMetadata mapping, use that. 2682 // Or create a new one and use that. 2683 // We also need to pass a mapping of the HighBrightnessModeTimeInfoMap to 2684 // displayPowerController, so the hbm info can be correctly associated 2685 // with the corresponding displaydevice. 2686 HighBrightnessModeMetadata hbmMetadata = getHighBrightnessModeMetadata(display); 2687 2688 final DisplayPowerController displayPowerController = new DisplayPowerController( 2689 mContext, mDisplayPowerCallbacks, mPowerHandler, mSensorManager, 2690 mDisplayBlanker, display, mBrightnessTracker, brightnessSetting, 2691 () -> handleBrightnessChange(display), hbmMetadata, mBootCompleted); 2692 mDisplayPowerControllers.append(display.getDisplayIdLocked(), displayPowerController); 2693 } 2694 handleBrightnessChange(LogicalDisplay display)2695 private void handleBrightnessChange(LogicalDisplay display) { 2696 sendDisplayEventLocked(display, DisplayManagerGlobal.EVENT_DISPLAY_BRIGHTNESS_CHANGED); 2697 } 2698 getDeviceForDisplayLocked(int displayId)2699 private DisplayDevice getDeviceForDisplayLocked(int displayId) { 2700 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 2701 return display == null ? null : display.getPrimaryDisplayDeviceLocked(); 2702 } 2703 getBrightnessConfigForDisplayWithPdsFallbackLocked( String uniqueId, int userSerial)2704 private BrightnessConfiguration getBrightnessConfigForDisplayWithPdsFallbackLocked( 2705 String uniqueId, int userSerial) { 2706 BrightnessConfiguration config = 2707 mPersistentDataStore.getBrightnessConfigurationForDisplayLocked( 2708 uniqueId, userSerial); 2709 if (config == null) { 2710 // Get from global configurations 2711 config = mPersistentDataStore.getBrightnessConfiguration(userSerial); 2712 } 2713 return config; 2714 } 2715 2716 private final class DisplayManagerHandler extends Handler { DisplayManagerHandler(Looper looper)2717 public DisplayManagerHandler(Looper looper) { 2718 super(looper, null, true /*async*/); 2719 } 2720 2721 @Override handleMessage(Message msg)2722 public void handleMessage(Message msg) { 2723 switch (msg.what) { 2724 case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS: 2725 registerDefaultDisplayAdapters(); 2726 break; 2727 2728 case MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS: 2729 registerAdditionalDisplayAdapters(); 2730 break; 2731 2732 case MSG_DELIVER_DISPLAY_EVENT: 2733 deliverDisplayEvent(msg.arg1, null, msg.arg2); 2734 break; 2735 2736 case MSG_REQUEST_TRAVERSAL: 2737 mWindowManagerInternal.requestTraversalFromDisplayManager(); 2738 break; 2739 2740 case MSG_UPDATE_VIEWPORT: { 2741 final boolean changed; 2742 synchronized (mSyncRoot) { 2743 changed = !mTempViewports.equals(mViewports); 2744 if (changed) { 2745 mTempViewports.clear(); 2746 for (DisplayViewport d : mViewports) { 2747 mTempViewports.add(d.makeCopy()); 2748 } 2749 } 2750 } 2751 if (changed) { 2752 mInputManagerInternal.setDisplayViewports(mTempViewports); 2753 } 2754 break; 2755 } 2756 2757 case MSG_LOAD_BRIGHTNESS_CONFIGURATIONS: 2758 loadBrightnessConfigurations(); 2759 break; 2760 2761 case MSG_DELIVER_DISPLAY_EVENT_FRAME_RATE_OVERRIDE: 2762 ArraySet<Integer> uids; 2763 synchronized (mSyncRoot) { 2764 int displayId = msg.arg1; 2765 final LogicalDisplay display = 2766 mLogicalDisplayMapper.getDisplayLocked(displayId); 2767 if (display == null) { 2768 break; 2769 } 2770 uids = display.getPendingFrameRateOverrideUids(); 2771 display.clearPendingFrameRateOverrideUids(); 2772 } 2773 deliverDisplayEvent(msg.arg1, uids, msg.arg2); 2774 break; 2775 2776 case MSG_DELIVER_DISPLAY_GROUP_EVENT: 2777 deliverDisplayGroupEvent(msg.arg1, msg.arg2); 2778 break; 2779 2780 } 2781 } 2782 } 2783 2784 private final class LogicalDisplayListener implements LogicalDisplayMapper.Listener { 2785 @Override onLogicalDisplayEventLocked(LogicalDisplay display, int event)2786 public void onLogicalDisplayEventLocked(LogicalDisplay display, int event) { 2787 switch (event) { 2788 case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_ADDED: 2789 handleLogicalDisplayAddedLocked(display); 2790 break; 2791 2792 case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_CHANGED: 2793 handleLogicalDisplayChangedLocked(display); 2794 break; 2795 2796 case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REMOVED: 2797 handleLogicalDisplayRemovedLocked(display); 2798 break; 2799 2800 case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_SWAPPED: 2801 handleLogicalDisplaySwappedLocked(display); 2802 break; 2803 2804 case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED: 2805 handleLogicalDisplayFrameRateOverridesChangedLocked(display); 2806 break; 2807 2808 case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_DEVICE_STATE_TRANSITION: 2809 handleLogicalDisplayDeviceStateTransitionLocked(display); 2810 break; 2811 } 2812 } 2813 2814 @Override onDisplayGroupEventLocked(int groupId, int event)2815 public void onDisplayGroupEventLocked(int groupId, int event) { 2816 sendDisplayGroupEvent(groupId, event); 2817 } 2818 2819 @Override onTraversalRequested()2820 public void onTraversalRequested() { 2821 synchronized (mSyncRoot) { 2822 scheduleTraversalLocked(false); 2823 } 2824 } 2825 } 2826 2827 private final class CallbackRecord implements DeathRecipient { 2828 public final int mPid; 2829 public final int mUid; 2830 private final IDisplayManagerCallback mCallback; 2831 private @EventsMask AtomicLong mEventsMask; 2832 2833 public boolean mWifiDisplayScanRequested; 2834 CallbackRecord(int pid, int uid, IDisplayManagerCallback callback, @EventsMask long eventsMask)2835 CallbackRecord(int pid, int uid, IDisplayManagerCallback callback, 2836 @EventsMask long eventsMask) { 2837 mPid = pid; 2838 mUid = uid; 2839 mCallback = callback; 2840 mEventsMask = new AtomicLong(eventsMask); 2841 } 2842 updateEventsMask(@ventsMask long eventsMask)2843 public void updateEventsMask(@EventsMask long eventsMask) { 2844 mEventsMask.set(eventsMask); 2845 } 2846 2847 @Override binderDied()2848 public void binderDied() { 2849 if (DEBUG) { 2850 Slog.d(TAG, "Display listener for pid " + mPid + " died."); 2851 } 2852 onCallbackDied(this); 2853 } 2854 notifyDisplayEventAsync(int displayId, @DisplayEvent int event)2855 public void notifyDisplayEventAsync(int displayId, @DisplayEvent int event) { 2856 if (!shouldSendEvent(event)) { 2857 return; 2858 } 2859 2860 try { 2861 mCallback.onDisplayEvent(displayId, event); 2862 } catch (RemoteException ex) { 2863 Slog.w(TAG, "Failed to notify process " 2864 + mPid + " that displays changed, assuming it died.", ex); 2865 binderDied(); 2866 } 2867 } 2868 shouldSendEvent(@isplayEvent int event)2869 private boolean shouldSendEvent(@DisplayEvent int event) { 2870 final long mask = mEventsMask.get(); 2871 switch (event) { 2872 case DisplayManagerGlobal.EVENT_DISPLAY_ADDED: 2873 return (mask & DisplayManager.EVENT_FLAG_DISPLAY_ADDED) != 0; 2874 case DisplayManagerGlobal.EVENT_DISPLAY_CHANGED: 2875 return (mask & DisplayManager.EVENT_FLAG_DISPLAY_CHANGED) != 0; 2876 case DisplayManagerGlobal.EVENT_DISPLAY_BRIGHTNESS_CHANGED: 2877 return (mask & DisplayManager.EVENT_FLAG_DISPLAY_BRIGHTNESS) != 0; 2878 case DisplayManagerGlobal.EVENT_DISPLAY_REMOVED: 2879 return (mask & DisplayManager.EVENT_FLAG_DISPLAY_REMOVED) != 0; 2880 default: 2881 // This should never happen. 2882 Slog.e(TAG, "Unknown display event " + event); 2883 return true; 2884 } 2885 } 2886 } 2887 2888 @VisibleForTesting 2889 final class BinderService extends IDisplayManager.Stub { 2890 /** 2891 * Returns information about the specified logical display. 2892 * 2893 * @param displayId The logical display id. 2894 * @return The logical display info, return {@code null} if the display does not exist or 2895 * the calling UID isn't present on the display. The returned object must be treated as 2896 * immutable. 2897 */ 2898 @Override // Binder call getDisplayInfo(int displayId)2899 public DisplayInfo getDisplayInfo(int displayId) { 2900 final int callingUid = Binder.getCallingUid(); 2901 final long token = Binder.clearCallingIdentity(); 2902 try { 2903 return getDisplayInfoInternal(displayId, callingUid); 2904 } finally { 2905 Binder.restoreCallingIdentity(token); 2906 } 2907 } 2908 2909 /** 2910 * Returns the list of all display ids. 2911 */ 2912 @Override // Binder call getDisplayIds(boolean includeDisabled)2913 public int[] getDisplayIds(boolean includeDisabled) { 2914 final int callingUid = Binder.getCallingUid(); 2915 final long token = Binder.clearCallingIdentity(); 2916 try { 2917 synchronized (mSyncRoot) { 2918 return mLogicalDisplayMapper.getDisplayIdsLocked(callingUid, includeDisabled); 2919 } 2920 } finally { 2921 Binder.restoreCallingIdentity(token); 2922 } 2923 } 2924 2925 @Override // Binder call isUidPresentOnDisplay(int uid, int displayId)2926 public boolean isUidPresentOnDisplay(int uid, int displayId) { 2927 final long token = Binder.clearCallingIdentity(); 2928 try { 2929 return isUidPresentOnDisplayInternal(uid, displayId); 2930 } finally { 2931 Binder.restoreCallingIdentity(token); 2932 } 2933 } 2934 2935 /** 2936 * Returns the stable device display size, in pixels. 2937 */ 2938 @Override // Binder call getStableDisplaySize()2939 public Point getStableDisplaySize() { 2940 final long token = Binder.clearCallingIdentity(); 2941 try { 2942 return getStableDisplaySizeInternal(); 2943 } finally { 2944 Binder.restoreCallingIdentity(token); 2945 } 2946 } 2947 2948 @Override // Binder call registerCallback(IDisplayManagerCallback callback)2949 public void registerCallback(IDisplayManagerCallback callback) { 2950 registerCallbackWithEventMask(callback, DisplayManager.EVENT_FLAG_DISPLAY_ADDED 2951 | DisplayManager.EVENT_FLAG_DISPLAY_CHANGED 2952 | DisplayManager.EVENT_FLAG_DISPLAY_REMOVED); 2953 } 2954 2955 @Override // Binder call registerCallbackWithEventMask(IDisplayManagerCallback callback, @EventsMask long eventsMask)2956 public void registerCallbackWithEventMask(IDisplayManagerCallback callback, 2957 @EventsMask long eventsMask) { 2958 if (callback == null) { 2959 throw new IllegalArgumentException("listener must not be null"); 2960 } 2961 2962 final int callingPid = Binder.getCallingPid(); 2963 final int callingUid = Binder.getCallingUid(); 2964 final long token = Binder.clearCallingIdentity(); 2965 try { 2966 registerCallbackInternal(callback, callingPid, callingUid, eventsMask); 2967 } finally { 2968 Binder.restoreCallingIdentity(token); 2969 } 2970 } 2971 2972 @Override // Binder call startWifiDisplayScan()2973 public void startWifiDisplayScan() { 2974 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 2975 "Permission required to start wifi display scans"); 2976 2977 final int callingPid = Binder.getCallingPid(); 2978 final long token = Binder.clearCallingIdentity(); 2979 try { 2980 startWifiDisplayScanInternal(callingPid); 2981 } finally { 2982 Binder.restoreCallingIdentity(token); 2983 } 2984 } 2985 2986 @Override // Binder call stopWifiDisplayScan()2987 public void stopWifiDisplayScan() { 2988 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 2989 "Permission required to stop wifi display scans"); 2990 2991 final int callingPid = Binder.getCallingPid(); 2992 final long token = Binder.clearCallingIdentity(); 2993 try { 2994 stopWifiDisplayScanInternal(callingPid); 2995 } finally { 2996 Binder.restoreCallingIdentity(token); 2997 } 2998 } 2999 3000 @Override // Binder call connectWifiDisplay(String address)3001 public void connectWifiDisplay(String address) { 3002 if (address == null) { 3003 throw new IllegalArgumentException("address must not be null"); 3004 } 3005 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 3006 "Permission required to connect to a wifi display"); 3007 3008 final long token = Binder.clearCallingIdentity(); 3009 try { 3010 connectWifiDisplayInternal(address); 3011 } finally { 3012 Binder.restoreCallingIdentity(token); 3013 } 3014 } 3015 3016 @Override // Binder call disconnectWifiDisplay()3017 public void disconnectWifiDisplay() { 3018 // This request does not require special permissions. 3019 // Any app can request disconnection from the currently active wifi display. 3020 // This exception should no longer be needed once wifi display control moves 3021 // to the media router service. 3022 3023 final long token = Binder.clearCallingIdentity(); 3024 try { 3025 disconnectWifiDisplayInternal(); 3026 } finally { 3027 Binder.restoreCallingIdentity(token); 3028 } 3029 } 3030 3031 @Override // Binder call renameWifiDisplay(String address, String alias)3032 public void renameWifiDisplay(String address, String alias) { 3033 if (address == null) { 3034 throw new IllegalArgumentException("address must not be null"); 3035 } 3036 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 3037 "Permission required to rename to a wifi display"); 3038 3039 final long token = Binder.clearCallingIdentity(); 3040 try { 3041 renameWifiDisplayInternal(address, alias); 3042 } finally { 3043 Binder.restoreCallingIdentity(token); 3044 } 3045 } 3046 3047 @Override // Binder call forgetWifiDisplay(String address)3048 public void forgetWifiDisplay(String address) { 3049 if (address == null) { 3050 throw new IllegalArgumentException("address must not be null"); 3051 } 3052 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 3053 "Permission required to forget to a wifi display"); 3054 3055 final long token = Binder.clearCallingIdentity(); 3056 try { 3057 forgetWifiDisplayInternal(address); 3058 } finally { 3059 Binder.restoreCallingIdentity(token); 3060 } 3061 } 3062 3063 @Override // Binder call pauseWifiDisplay()3064 public void pauseWifiDisplay() { 3065 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 3066 "Permission required to pause a wifi display session"); 3067 3068 final long token = Binder.clearCallingIdentity(); 3069 try { 3070 pauseWifiDisplayInternal(); 3071 } finally { 3072 Binder.restoreCallingIdentity(token); 3073 } 3074 } 3075 3076 @Override // Binder call resumeWifiDisplay()3077 public void resumeWifiDisplay() { 3078 mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY, 3079 "Permission required to resume a wifi display session"); 3080 3081 final long token = Binder.clearCallingIdentity(); 3082 try { 3083 resumeWifiDisplayInternal(); 3084 } finally { 3085 Binder.restoreCallingIdentity(token); 3086 } 3087 } 3088 3089 @Override // Binder call getWifiDisplayStatus()3090 public WifiDisplayStatus getWifiDisplayStatus() { 3091 // This request does not require special permissions. 3092 // Any app can get information about available wifi displays. 3093 3094 final long token = Binder.clearCallingIdentity(); 3095 try { 3096 return getWifiDisplayStatusInternal(); 3097 } finally { 3098 Binder.restoreCallingIdentity(token); 3099 } 3100 } 3101 3102 @Override // Binder call setUserDisabledHdrTypes(int[] userDisabledFormats)3103 public void setUserDisabledHdrTypes(int[] userDisabledFormats) { 3104 mContext.enforceCallingOrSelfPermission( 3105 Manifest.permission.WRITE_SECURE_SETTINGS, 3106 "Permission required to write the user settings."); 3107 3108 final long token = Binder.clearCallingIdentity(); 3109 try { 3110 setUserDisabledHdrTypesInternal(userDisabledFormats); 3111 } finally { 3112 Binder.restoreCallingIdentity(token); 3113 } 3114 } 3115 3116 @Override // Binder call setAreUserDisabledHdrTypesAllowed(boolean areUserDisabledHdrTypesAllowed)3117 public void setAreUserDisabledHdrTypesAllowed(boolean areUserDisabledHdrTypesAllowed) { 3118 mContext.enforceCallingOrSelfPermission( 3119 Manifest.permission.WRITE_SECURE_SETTINGS, 3120 "Permission required to write the user settings."); 3121 final long token = Binder.clearCallingIdentity(); 3122 try { 3123 setAreUserDisabledHdrTypesAllowedInternal(areUserDisabledHdrTypesAllowed); 3124 } finally { 3125 Binder.restoreCallingIdentity(token); 3126 } 3127 } 3128 3129 @Override // Binder call areUserDisabledHdrTypesAllowed()3130 public boolean areUserDisabledHdrTypesAllowed() { 3131 synchronized (mSyncRoot) { 3132 return mAreUserDisabledHdrTypesAllowed; 3133 } 3134 } 3135 3136 @Override // Binder call getUserDisabledHdrTypes()3137 public int[] getUserDisabledHdrTypes() { 3138 return mUserDisabledHdrTypes; 3139 } 3140 3141 @Override // Binder call requestColorMode(int displayId, int colorMode)3142 public void requestColorMode(int displayId, int colorMode) { 3143 mContext.enforceCallingOrSelfPermission( 3144 Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE, 3145 "Permission required to change the display color mode"); 3146 final long token = Binder.clearCallingIdentity(); 3147 try { 3148 requestColorModeInternal(displayId, colorMode); 3149 } finally { 3150 Binder.restoreCallingIdentity(token); 3151 } 3152 } 3153 3154 @Override // Binder call createVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig, IVirtualDisplayCallback callback, IMediaProjection projection, String packageName)3155 public int createVirtualDisplay(VirtualDisplayConfig virtualDisplayConfig, 3156 IVirtualDisplayCallback callback, IMediaProjection projection, 3157 String packageName) { 3158 return createVirtualDisplayInternal(virtualDisplayConfig, callback, projection, 3159 null, null, packageName); 3160 } 3161 3162 @Override // Binder call resizeVirtualDisplay(IVirtualDisplayCallback callback, int width, int height, int densityDpi)3163 public void resizeVirtualDisplay(IVirtualDisplayCallback callback, 3164 int width, int height, int densityDpi) { 3165 if (width <= 0 || height <= 0 || densityDpi <= 0) { 3166 throw new IllegalArgumentException("width, height, and densityDpi must be " 3167 + "greater than 0"); 3168 } 3169 final long token = Binder.clearCallingIdentity(); 3170 try { 3171 resizeVirtualDisplayInternal(callback.asBinder(), width, height, densityDpi); 3172 } finally { 3173 Binder.restoreCallingIdentity(token); 3174 } 3175 } 3176 3177 @Override // Binder call setVirtualDisplaySurface(IVirtualDisplayCallback callback, Surface surface)3178 public void setVirtualDisplaySurface(IVirtualDisplayCallback callback, Surface surface) { 3179 if (surface != null && surface.isSingleBuffered()) { 3180 throw new IllegalArgumentException("Surface can't be single-buffered"); 3181 } 3182 final long token = Binder.clearCallingIdentity(); 3183 try { 3184 setVirtualDisplaySurfaceInternal(callback.asBinder(), surface); 3185 } finally { 3186 Binder.restoreCallingIdentity(token); 3187 } 3188 } 3189 3190 @Override // Binder call releaseVirtualDisplay(IVirtualDisplayCallback callback)3191 public void releaseVirtualDisplay(IVirtualDisplayCallback callback) { 3192 final long token = Binder.clearCallingIdentity(); 3193 try { 3194 releaseVirtualDisplayInternal(callback.asBinder()); 3195 } finally { 3196 Binder.restoreCallingIdentity(token); 3197 } 3198 } 3199 3200 @Override // Binder call setVirtualDisplayState(IVirtualDisplayCallback callback, boolean isOn)3201 public void setVirtualDisplayState(IVirtualDisplayCallback callback, boolean isOn) { 3202 final long token = Binder.clearCallingIdentity(); 3203 try { 3204 setVirtualDisplayStateInternal(callback.asBinder(), isOn); 3205 } finally { 3206 Binder.restoreCallingIdentity(token); 3207 } 3208 } 3209 3210 @Override // Binder call dump(FileDescriptor fd, final PrintWriter pw, String[] args)3211 public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) { 3212 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 3213 3214 final long token = Binder.clearCallingIdentity(); 3215 try { 3216 dumpInternal(pw); 3217 } finally { 3218 Binder.restoreCallingIdentity(token); 3219 } 3220 } 3221 3222 @Override // Binder call getBrightnessEvents(String callingPackage)3223 public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents(String callingPackage) { 3224 mContext.enforceCallingOrSelfPermission( 3225 Manifest.permission.BRIGHTNESS_SLIDER_USAGE, 3226 "Permission to read brightness events."); 3227 3228 final int callingUid = Binder.getCallingUid(); 3229 AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class); 3230 final int mode = appOpsManager.noteOp(AppOpsManager.OP_GET_USAGE_STATS, 3231 callingUid, callingPackage); 3232 final boolean hasUsageStats; 3233 if (mode == AppOpsManager.MODE_DEFAULT) { 3234 // The default behavior here is to check if PackageManager has given the app 3235 // permission. 3236 hasUsageStats = mContext.checkCallingPermission( 3237 Manifest.permission.PACKAGE_USAGE_STATS) 3238 == PackageManager.PERMISSION_GRANTED; 3239 } else { 3240 hasUsageStats = mode == AppOpsManager.MODE_ALLOWED; 3241 } 3242 3243 final int userId = UserHandle.getUserId(callingUid); 3244 final long token = Binder.clearCallingIdentity(); 3245 try { 3246 synchronized (mSyncRoot) { 3247 return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) 3248 .getBrightnessEvents(userId, hasUsageStats); 3249 } 3250 } finally { 3251 Binder.restoreCallingIdentity(token); 3252 } 3253 } 3254 3255 @Override // Binder call getAmbientBrightnessStats()3256 public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats() { 3257 mContext.enforceCallingOrSelfPermission( 3258 Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS, 3259 "Permission required to to access ambient light stats."); 3260 final int callingUid = Binder.getCallingUid(); 3261 final int userId = UserHandle.getUserId(callingUid); 3262 final long token = Binder.clearCallingIdentity(); 3263 try { 3264 synchronized (mSyncRoot) { 3265 return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) 3266 .getAmbientBrightnessStats(userId); 3267 } 3268 } finally { 3269 Binder.restoreCallingIdentity(token); 3270 } 3271 } 3272 3273 @Override // Binder call setBrightnessConfigurationForUser( BrightnessConfiguration c, @UserIdInt int userId, String packageName)3274 public void setBrightnessConfigurationForUser( 3275 BrightnessConfiguration c, @UserIdInt int userId, String packageName) { 3276 mContext.enforceCallingOrSelfPermission( 3277 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS, 3278 "Permission required to change the display's brightness configuration"); 3279 if (userId != UserHandle.getCallingUserId()) { 3280 mContext.enforceCallingOrSelfPermission( 3281 Manifest.permission.INTERACT_ACROSS_USERS, 3282 "Permission required to change the display brightness" 3283 + " configuration of another user"); 3284 } 3285 final long token = Binder.clearCallingIdentity(); 3286 try { 3287 synchronized (mSyncRoot) { 3288 mLogicalDisplayMapper.forEachLocked(logicalDisplay -> { 3289 if (logicalDisplay.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) { 3290 return; 3291 } 3292 final DisplayDevice displayDevice = 3293 logicalDisplay.getPrimaryDisplayDeviceLocked(); 3294 setBrightnessConfigurationForDisplayInternal(c, displayDevice.getUniqueId(), 3295 userId, packageName); 3296 }); 3297 } 3298 } finally { 3299 Binder.restoreCallingIdentity(token); 3300 } 3301 } 3302 3303 @Override // Binder call setBrightnessConfigurationForDisplay(BrightnessConfiguration c, String uniqueId, int userId, String packageName)3304 public void setBrightnessConfigurationForDisplay(BrightnessConfiguration c, 3305 String uniqueId, int userId, String packageName) { 3306 mContext.enforceCallingOrSelfPermission( 3307 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS, 3308 "Permission required to change the display's brightness configuration"); 3309 if (userId != UserHandle.getCallingUserId()) { 3310 mContext.enforceCallingOrSelfPermission( 3311 Manifest.permission.INTERACT_ACROSS_USERS, 3312 "Permission required to change the display brightness" 3313 + " configuration of another user"); 3314 } 3315 final long token = Binder.clearCallingIdentity(); 3316 try { 3317 setBrightnessConfigurationForDisplayInternal(c, uniqueId, userId, packageName); 3318 } finally { 3319 Binder.restoreCallingIdentity(token); 3320 } 3321 } 3322 3323 @Override // Binder call getBrightnessConfigurationForDisplay(String uniqueId, int userId)3324 public BrightnessConfiguration getBrightnessConfigurationForDisplay(String uniqueId, 3325 int userId) { 3326 mContext.enforceCallingOrSelfPermission( 3327 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS, 3328 "Permission required to read the display's brightness configuration"); 3329 if (userId != UserHandle.getCallingUserId()) { 3330 mContext.enforceCallingOrSelfPermission( 3331 Manifest.permission.INTERACT_ACROSS_USERS, 3332 "Permission required to read the display brightness" 3333 + " configuration of another user"); 3334 } 3335 final long token = Binder.clearCallingIdentity(); 3336 final int userSerial = getUserManager().getUserSerialNumber(userId); 3337 try { 3338 synchronized (mSyncRoot) { 3339 // Get from per-display configurations 3340 BrightnessConfiguration config = 3341 getBrightnessConfigForDisplayWithPdsFallbackLocked( 3342 uniqueId, userSerial); 3343 if (config == null) { 3344 // Get default configuration 3345 DisplayPowerController dpc = getDpcFromUniqueIdLocked(uniqueId); 3346 if (dpc != null) { 3347 config = dpc.getDefaultBrightnessConfiguration(); 3348 } 3349 } 3350 return config; 3351 } 3352 } finally { 3353 Binder.restoreCallingIdentity(token); 3354 } 3355 } 3356 3357 3358 3359 @Override // Binder call getBrightnessConfigurationForUser(int userId)3360 public BrightnessConfiguration getBrightnessConfigurationForUser(int userId) { 3361 final String uniqueId; 3362 synchronized (mSyncRoot) { 3363 DisplayDevice displayDevice = mLogicalDisplayMapper.getDisplayLocked( 3364 Display.DEFAULT_DISPLAY).getPrimaryDisplayDeviceLocked(); 3365 uniqueId = displayDevice.getUniqueId(); 3366 } 3367 return getBrightnessConfigurationForDisplay(uniqueId, userId); 3368 3369 3370 } 3371 3372 @Override // Binder call getDefaultBrightnessConfiguration()3373 public BrightnessConfiguration getDefaultBrightnessConfiguration() { 3374 mContext.enforceCallingOrSelfPermission( 3375 Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS, 3376 "Permission required to read the display's default brightness configuration"); 3377 final long token = Binder.clearCallingIdentity(); 3378 try { 3379 synchronized (mSyncRoot) { 3380 return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) 3381 .getDefaultBrightnessConfiguration(); 3382 } 3383 } finally { 3384 Binder.restoreCallingIdentity(token); 3385 } 3386 } 3387 3388 @Override getBrightnessInfo(int displayId)3389 public BrightnessInfo getBrightnessInfo(int displayId) { 3390 mContext.enforceCallingOrSelfPermission( 3391 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS, 3392 "Permission required to read the display's brightness info."); 3393 final long token = Binder.clearCallingIdentity(); 3394 try { 3395 synchronized (mSyncRoot) { 3396 LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked( 3397 displayId, /* includeDisabled= */ false); 3398 if (display == null || !display.isEnabledLocked()) { 3399 return null; 3400 } 3401 DisplayPowerController dpc = mDisplayPowerControllers.get(displayId); 3402 if (dpc != null) { 3403 return dpc.getBrightnessInfo(); 3404 } 3405 } 3406 } finally { 3407 Binder.restoreCallingIdentity(token); 3408 } 3409 return null; 3410 } 3411 3412 @Override // Binder call isMinimalPostProcessingRequested(int displayId)3413 public boolean isMinimalPostProcessingRequested(int displayId) { 3414 synchronized (mSyncRoot) { 3415 return mLogicalDisplayMapper.getDisplayLocked(displayId) 3416 .getRequestedMinimalPostProcessingLocked(); 3417 } 3418 } 3419 3420 @Override // Binder call setTemporaryBrightness(int displayId, float brightness)3421 public void setTemporaryBrightness(int displayId, float brightness) { 3422 mContext.enforceCallingOrSelfPermission( 3423 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS, 3424 "Permission required to set the display's brightness"); 3425 final long token = Binder.clearCallingIdentity(); 3426 try { 3427 synchronized (mSyncRoot) { 3428 mDisplayPowerControllers.get(displayId) 3429 .setTemporaryBrightness(brightness); 3430 } 3431 } finally { 3432 Binder.restoreCallingIdentity(token); 3433 } 3434 } 3435 3436 @Override // Binder call setBrightness(int displayId, float brightness)3437 public void setBrightness(int displayId, float brightness) { 3438 mContext.enforceCallingOrSelfPermission( 3439 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS, 3440 "Permission required to set the display's brightness"); 3441 if (!isValidBrightness(brightness)) { 3442 Slog.w(TAG, "Attempted to set invalid brightness" + brightness); 3443 return; 3444 } 3445 final long token = Binder.clearCallingIdentity(); 3446 try { 3447 synchronized (mSyncRoot) { 3448 DisplayPowerController dpc = mDisplayPowerControllers.get(displayId); 3449 if (dpc != null) { 3450 dpc.setBrightness(brightness); 3451 } 3452 mPersistentDataStore.saveIfNeeded(); 3453 } 3454 } finally { 3455 Binder.restoreCallingIdentity(token); 3456 } 3457 } 3458 3459 @Override // Binder call getBrightness(int displayId)3460 public float getBrightness(int displayId) { 3461 float brightness = PowerManager.BRIGHTNESS_INVALID_FLOAT; 3462 mContext.enforceCallingOrSelfPermission( 3463 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS, 3464 "Permission required to set the display's brightness"); 3465 final long token = Binder.clearCallingIdentity(); 3466 try { 3467 synchronized (mSyncRoot) { 3468 DisplayPowerController dpc = mDisplayPowerControllers.get(displayId); 3469 if (dpc != null) { 3470 brightness = dpc.getScreenBrightnessSetting(); 3471 } 3472 } 3473 } finally { 3474 Binder.restoreCallingIdentity(token); 3475 } 3476 return brightness; 3477 } 3478 3479 @Override // Binder call setTemporaryAutoBrightnessAdjustment(float adjustment)3480 public void setTemporaryAutoBrightnessAdjustment(float adjustment) { 3481 mContext.enforceCallingOrSelfPermission( 3482 Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS, 3483 "Permission required to set the display's auto brightness adjustment"); 3484 final long token = Binder.clearCallingIdentity(); 3485 try { 3486 synchronized (mSyncRoot) { 3487 mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) 3488 .setTemporaryAutoBrightnessAdjustment(adjustment); 3489 } 3490 } finally { 3491 Binder.restoreCallingIdentity(token); 3492 } 3493 } 3494 3495 @Override // Binder call onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)3496 public void onShellCommand(FileDescriptor in, FileDescriptor out, 3497 FileDescriptor err, String[] args, ShellCallback callback, 3498 ResultReceiver resultReceiver) { 3499 new DisplayManagerShellCommand(DisplayManagerService.this).exec(this, in, out, err, 3500 args, callback, resultReceiver); 3501 } 3502 3503 @Override // Binder call getMinimumBrightnessCurve()3504 public Curve getMinimumBrightnessCurve() { 3505 final long token = Binder.clearCallingIdentity(); 3506 try { 3507 return getMinimumBrightnessCurveInternal(); 3508 } finally { 3509 Binder.restoreCallingIdentity(token); 3510 } 3511 } 3512 3513 @Override // Binder call getPreferredWideGamutColorSpaceId()3514 public int getPreferredWideGamutColorSpaceId() { 3515 final long token = Binder.clearCallingIdentity(); 3516 try { 3517 return getPreferredWideGamutColorSpaceIdInternal(); 3518 } finally { 3519 Binder.restoreCallingIdentity(token); 3520 } 3521 } 3522 3523 @Override // Binder call setUserPreferredDisplayMode(int displayId, Display.Mode mode)3524 public void setUserPreferredDisplayMode(int displayId, Display.Mode mode) { 3525 mContext.enforceCallingOrSelfPermission( 3526 Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE, 3527 "Permission required to set the user preferred display mode."); 3528 final long token = Binder.clearCallingIdentity(); 3529 try { 3530 setUserPreferredDisplayModeInternal(displayId, mode); 3531 } finally { 3532 Binder.restoreCallingIdentity(token); 3533 } 3534 } 3535 3536 @Override // Binder call getUserPreferredDisplayMode(int displayId)3537 public Display.Mode getUserPreferredDisplayMode(int displayId) { 3538 final long token = Binder.clearCallingIdentity(); 3539 try { 3540 return getUserPreferredDisplayModeInternal(displayId); 3541 } finally { 3542 Binder.restoreCallingIdentity(token); 3543 } 3544 } 3545 3546 @Override // Binder call getSystemPreferredDisplayMode(int displayId)3547 public Display.Mode getSystemPreferredDisplayMode(int displayId) { 3548 final long token = Binder.clearCallingIdentity(); 3549 try { 3550 return getSystemPreferredDisplayModeInternal(displayId); 3551 } finally { 3552 Binder.restoreCallingIdentity(token); 3553 } 3554 } 3555 3556 @Override // Binder call setShouldAlwaysRespectAppRequestedMode(boolean enabled)3557 public void setShouldAlwaysRespectAppRequestedMode(boolean enabled) { 3558 mContext.enforceCallingOrSelfPermission( 3559 Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS, 3560 "Permission required to override display mode requests."); 3561 final long token = Binder.clearCallingIdentity(); 3562 try { 3563 setShouldAlwaysRespectAppRequestedModeInternal(enabled); 3564 } finally { 3565 Binder.restoreCallingIdentity(token); 3566 } 3567 } 3568 3569 @Override // Binder call shouldAlwaysRespectAppRequestedMode()3570 public boolean shouldAlwaysRespectAppRequestedMode() { 3571 mContext.enforceCallingOrSelfPermission( 3572 Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS, 3573 "Permission required to override display mode requests."); 3574 final long token = Binder.clearCallingIdentity(); 3575 try { 3576 return shouldAlwaysRespectAppRequestedModeInternal(); 3577 } finally { 3578 Binder.restoreCallingIdentity(token); 3579 } 3580 } 3581 3582 @Override // Binder call setRefreshRateSwitchingType(int newValue)3583 public void setRefreshRateSwitchingType(int newValue) { 3584 mContext.enforceCallingOrSelfPermission( 3585 Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE, 3586 "Permission required to modify refresh rate switching type."); 3587 final long token = Binder.clearCallingIdentity(); 3588 try { 3589 setRefreshRateSwitchingTypeInternal(newValue); 3590 } finally { 3591 Binder.restoreCallingIdentity(token); 3592 } 3593 } 3594 3595 @Override // Binder call getRefreshRateSwitchingType()3596 public int getRefreshRateSwitchingType() { 3597 final long token = Binder.clearCallingIdentity(); 3598 try { 3599 return getRefreshRateSwitchingTypeInternal(); 3600 } finally { 3601 Binder.restoreCallingIdentity(token); 3602 } 3603 } 3604 3605 @Override // Binder call getDisplayDecorationSupport(int displayId)3606 public DisplayDecorationSupport getDisplayDecorationSupport(int displayId) { 3607 final long token = Binder.clearCallingIdentity(); 3608 try { 3609 return getDisplayDecorationSupportInternal(displayId); 3610 } finally { 3611 Binder.restoreCallingIdentity(token); 3612 } 3613 } 3614 } 3615 isValidBrightness(float brightness)3616 private static boolean isValidBrightness(float brightness) { 3617 return !Float.isNaN(brightness) 3618 && (brightness >= PowerManager.BRIGHTNESS_MIN) 3619 && (brightness <= PowerManager.BRIGHTNESS_MAX); 3620 } 3621 isValidResolution(Point resolution)3622 private static boolean isValidResolution(Point resolution) { 3623 return (resolution != null) && (resolution.x > 0) && (resolution.y > 0); 3624 } 3625 isValidRefreshRate(float refreshRate)3626 private static boolean isValidRefreshRate(float refreshRate) { 3627 return !Float.isNaN(refreshRate) && (refreshRate > 0.0f); 3628 } 3629 3630 @VisibleForTesting 3631 final class LocalService extends DisplayManagerInternal { 3632 3633 @Override initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler, SensorManager sensorManager)3634 public void initPowerManagement(final DisplayPowerCallbacks callbacks, Handler handler, 3635 SensorManager sensorManager) { 3636 synchronized (mSyncRoot) { 3637 mDisplayPowerCallbacks = callbacks; 3638 mSensorManager = sensorManager; 3639 mPowerHandler = handler; 3640 initializeDisplayPowerControllersLocked(); 3641 } 3642 3643 mHandler.sendEmptyMessage(MSG_LOAD_BRIGHTNESS_CONFIGURATIONS); 3644 } 3645 3646 @Override createVirtualDisplay(VirtualDisplayConfig config, IVirtualDisplayCallback callback, IVirtualDevice virtualDevice, DisplayWindowPolicyController dwpc, String packageName)3647 public int createVirtualDisplay(VirtualDisplayConfig config, 3648 IVirtualDisplayCallback callback, IVirtualDevice virtualDevice, 3649 DisplayWindowPolicyController dwpc, String packageName) { 3650 return createVirtualDisplayInternal(config, callback, null, virtualDevice, dwpc, 3651 packageName); 3652 } 3653 3654 @Override requestPowerState(int groupId, DisplayPowerRequest request, boolean waitForNegativeProximity)3655 public boolean requestPowerState(int groupId, DisplayPowerRequest request, 3656 boolean waitForNegativeProximity) { 3657 synchronized (mSyncRoot) { 3658 final DisplayGroup displayGroup = mLogicalDisplayMapper.getDisplayGroupLocked( 3659 groupId); 3660 if (displayGroup == null) { 3661 return true; 3662 } 3663 3664 final int size = displayGroup.getSizeLocked(); 3665 boolean ready = true; 3666 for (int i = 0; i < size; i++) { 3667 final int id = displayGroup.getIdLocked(i); 3668 final DisplayDevice displayDevice = mLogicalDisplayMapper.getDisplayLocked( 3669 id).getPrimaryDisplayDeviceLocked(); 3670 final int flags = displayDevice.getDisplayDeviceInfoLocked().flags; 3671 if ((flags & DisplayDeviceInfo.FLAG_NEVER_BLANK) == 0) { 3672 final DisplayPowerController displayPowerController = 3673 mDisplayPowerControllers.get(id); 3674 ready &= displayPowerController.requestPowerState(request, 3675 waitForNegativeProximity); 3676 } 3677 } 3678 3679 return ready; 3680 } 3681 } 3682 3683 @Override isProximitySensorAvailable()3684 public boolean isProximitySensorAvailable() { 3685 synchronized (mSyncRoot) { 3686 return mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) 3687 .isProximitySensorAvailable(); 3688 } 3689 } 3690 3691 @Override registerDisplayGroupListener(DisplayGroupListener listener)3692 public void registerDisplayGroupListener(DisplayGroupListener listener) { 3693 mDisplayGroupListeners.add(listener); 3694 } 3695 3696 @Override unregisterDisplayGroupListener(DisplayGroupListener listener)3697 public void unregisterDisplayGroupListener(DisplayGroupListener listener) { 3698 mDisplayGroupListeners.remove(listener); 3699 } 3700 3701 @Override systemScreenshot(int displayId)3702 public SurfaceControl.ScreenshotHardwareBuffer systemScreenshot(int displayId) { 3703 return systemScreenshotInternal(displayId); 3704 } 3705 3706 @Override userScreenshot(int displayId)3707 public SurfaceControl.ScreenshotHardwareBuffer userScreenshot(int displayId) { 3708 return userScreenshotInternal(displayId); 3709 } 3710 3711 @Override getDisplayInfo(int displayId)3712 public DisplayInfo getDisplayInfo(int displayId) { 3713 return getDisplayInfoInternal(displayId, Process.myUid()); 3714 } 3715 3716 @Override getPossibleDisplayInfo(int displayId)3717 public Set<DisplayInfo> getPossibleDisplayInfo(int displayId) { 3718 synchronized (mSyncRoot) { 3719 Set<DisplayInfo> possibleInfo = new ArraySet<>(); 3720 // For each of supported device states, retrieve the display layout of that state, 3721 // and return all of the DisplayInfos (one per state) for the given display id. 3722 if (mDeviceStateManager == null) { 3723 Slog.w(TAG, "Can't get supported states since DeviceStateManager not ready"); 3724 return possibleInfo; 3725 } 3726 final int[] supportedStates = 3727 mDeviceStateManager.getSupportedStateIdentifiers(); 3728 DisplayInfo displayInfo; 3729 for (int state : supportedStates) { 3730 displayInfo = mLogicalDisplayMapper.getDisplayInfoForStateLocked(state, 3731 displayId); 3732 if (displayInfo != null) { 3733 possibleInfo.add(displayInfo); 3734 } 3735 } 3736 return possibleInfo; 3737 } 3738 } 3739 3740 @Override getDisplayPosition(int displayId)3741 public Point getDisplayPosition(int displayId) { 3742 synchronized (mSyncRoot) { 3743 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 3744 if (display != null) { 3745 return display.getDisplayPosition(); 3746 } 3747 return null; 3748 } 3749 } 3750 3751 @Override registerDisplayTransactionListener(DisplayTransactionListener listener)3752 public void registerDisplayTransactionListener(DisplayTransactionListener listener) { 3753 if (listener == null) { 3754 throw new IllegalArgumentException("listener must not be null"); 3755 } 3756 3757 registerDisplayTransactionListenerInternal(listener); 3758 } 3759 3760 @Override unregisterDisplayTransactionListener(DisplayTransactionListener listener)3761 public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) { 3762 if (listener == null) { 3763 throw new IllegalArgumentException("listener must not be null"); 3764 } 3765 3766 unregisterDisplayTransactionListenerInternal(listener); 3767 } 3768 3769 @Override setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info)3770 public void setDisplayInfoOverrideFromWindowManager(int displayId, DisplayInfo info) { 3771 setDisplayInfoOverrideFromWindowManagerInternal(displayId, info); 3772 } 3773 3774 @Override getNonOverrideDisplayInfo(int displayId, DisplayInfo outInfo)3775 public void getNonOverrideDisplayInfo(int displayId, DisplayInfo outInfo) { 3776 getNonOverrideDisplayInfoInternal(displayId, outInfo); 3777 } 3778 3779 @Override performTraversal(SurfaceControl.Transaction t)3780 public void performTraversal(SurfaceControl.Transaction t) { 3781 performTraversalInternal(t); 3782 } 3783 3784 @Override setDisplayProperties(int displayId, boolean hasContent, float requestedRefreshRate, int requestedMode, float requestedMinRefreshRate, float requestedMaxRefreshRate, boolean requestedMinimalPostProcessing, boolean inTraversal)3785 public void setDisplayProperties(int displayId, boolean hasContent, 3786 float requestedRefreshRate, int requestedMode, float requestedMinRefreshRate, 3787 float requestedMaxRefreshRate, boolean requestedMinimalPostProcessing, 3788 boolean inTraversal) { 3789 setDisplayPropertiesInternal(displayId, hasContent, requestedRefreshRate, 3790 requestedMode, requestedMinRefreshRate, requestedMaxRefreshRate, 3791 requestedMinimalPostProcessing, inTraversal); 3792 } 3793 3794 @Override setDisplayOffsets(int displayId, int x, int y)3795 public void setDisplayOffsets(int displayId, int x, int y) { 3796 setDisplayOffsetsInternal(displayId, x, y); 3797 } 3798 3799 @Override setDisplayScalingDisabled(int displayId, boolean disableScaling)3800 public void setDisplayScalingDisabled(int displayId, boolean disableScaling) { 3801 setDisplayScalingDisabledInternal(displayId, disableScaling); 3802 } 3803 3804 @Override setDisplayAccessUIDs(SparseArray<IntArray> newDisplayAccessUIDs)3805 public void setDisplayAccessUIDs(SparseArray<IntArray> newDisplayAccessUIDs) { 3806 setDisplayAccessUIDsInternal(newDisplayAccessUIDs); 3807 } 3808 3809 @Override persistBrightnessTrackerState()3810 public void persistBrightnessTrackerState() { 3811 synchronized (mSyncRoot) { 3812 mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) 3813 .persistBrightnessTrackerState(); 3814 } 3815 } 3816 3817 @Override onOverlayChanged()3818 public void onOverlayChanged() { 3819 synchronized (mSyncRoot) { 3820 mDisplayDeviceRepo.forEachLocked(DisplayDevice::onOverlayChangedLocked); 3821 } 3822 } 3823 3824 @Override getDisplayedContentSamplingAttributes( int displayId)3825 public DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributes( 3826 int displayId) { 3827 return getDisplayedContentSamplingAttributesInternal(displayId); 3828 } 3829 3830 @Override setDisplayedContentSamplingEnabled( int displayId, boolean enable, int componentMask, int maxFrames)3831 public boolean setDisplayedContentSamplingEnabled( 3832 int displayId, boolean enable, int componentMask, int maxFrames) { 3833 return setDisplayedContentSamplingEnabledInternal( 3834 displayId, enable, componentMask, maxFrames); 3835 } 3836 3837 @Override getDisplayedContentSample(int displayId, long maxFrames, long timestamp)3838 public DisplayedContentSample getDisplayedContentSample(int displayId, 3839 long maxFrames, long timestamp) { 3840 return getDisplayedContentSampleInternal(displayId, maxFrames, timestamp); 3841 } 3842 3843 @Override ignoreProximitySensorUntilChanged()3844 public void ignoreProximitySensorUntilChanged() { 3845 mDisplayPowerControllers.get(Display.DEFAULT_DISPLAY) 3846 .ignoreProximitySensorUntilChanged(); 3847 } 3848 3849 @Override getRefreshRateSwitchingType()3850 public int getRefreshRateSwitchingType() { 3851 return getRefreshRateSwitchingTypeInternal(); 3852 } 3853 3854 @Override getRefreshRateForDisplayAndSensor(int displayId, String sensorName, String sensorType)3855 public RefreshRateRange getRefreshRateForDisplayAndSensor(int displayId, String sensorName, 3856 String sensorType) { 3857 final SensorManager sensorManager; 3858 synchronized (mSyncRoot) { 3859 sensorManager = mSensorManager; 3860 } 3861 if (sensorManager == null) { 3862 return null; 3863 } 3864 3865 // Verify that the specified sensor exists. 3866 final Sensor sensor = SensorUtils.findSensor(sensorManager, sensorType, sensorName, 3867 SensorUtils.NO_FALLBACK); 3868 if (sensor == null) { 3869 return null; 3870 } 3871 3872 synchronized (mSyncRoot) { 3873 final LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(displayId); 3874 if (display == null) { 3875 return null; 3876 } 3877 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked(); 3878 if (device == null) { 3879 return null; 3880 } 3881 final DisplayDeviceConfig config = device.getDisplayDeviceConfig(); 3882 SensorData sensorData = config.getProximitySensor(); 3883 if (sensorData.matches(sensorName, sensorType)) { 3884 return new RefreshRateRange(sensorData.minRefreshRate, 3885 sensorData.maxRefreshRate); 3886 } 3887 } 3888 return null; 3889 } 3890 3891 @Override getRefreshRateLimitations(int displayId)3892 public List<RefreshRateLimitation> getRefreshRateLimitations(int displayId) { 3893 final DisplayDeviceConfig config; 3894 synchronized (mSyncRoot) { 3895 final DisplayDevice device = getDeviceForDisplayLocked(displayId); 3896 if (device == null) { 3897 return null; 3898 } 3899 config = device.getDisplayDeviceConfig(); 3900 } 3901 return config.getRefreshRateLimitations(); 3902 } 3903 3904 @Override setWindowManagerMirroring(int displayId, boolean isMirroring)3905 public void setWindowManagerMirroring(int displayId, boolean isMirroring) { 3906 synchronized (mSyncRoot) { 3907 final DisplayDevice device = getDeviceForDisplayLocked(displayId); 3908 if (device != null) { 3909 device.setWindowManagerMirroringLocked(isMirroring); 3910 } 3911 } 3912 } 3913 3914 @Override getDisplaySurfaceDefaultSize(int displayId)3915 public Point getDisplaySurfaceDefaultSize(int displayId) { 3916 final DisplayDevice device; 3917 synchronized (mSyncRoot) { 3918 device = getDeviceForDisplayLocked(displayId); 3919 if (device == null) { 3920 return null; 3921 } 3922 return device.getDisplaySurfaceDefaultSizeLocked(); 3923 } 3924 } 3925 3926 @Override onEarlyInteractivityChange(boolean interactive)3927 public void onEarlyInteractivityChange(boolean interactive) { 3928 mLogicalDisplayMapper.onEarlyInteractivityChange(interactive); 3929 } 3930 3931 @Override getDisplayWindowPolicyController(int displayId)3932 public DisplayWindowPolicyController getDisplayWindowPolicyController(int displayId) { 3933 synchronized (mSyncRoot) { 3934 if (mDisplayWindowPolicyControllers.contains(displayId)) { 3935 return mDisplayWindowPolicyControllers.get(displayId).second; 3936 } 3937 return null; 3938 } 3939 } 3940 } 3941 3942 class DesiredDisplayModeSpecsObserver 3943 implements DisplayModeDirector.DesiredDisplayModeSpecsListener { 3944 3945 private final Consumer<LogicalDisplay> mSpecsChangedConsumer = display -> { 3946 int displayId = display.getDisplayIdLocked(); 3947 DisplayModeDirector.DesiredDisplayModeSpecs desiredDisplayModeSpecs = 3948 mDisplayModeDirector.getDesiredDisplayModeSpecs(displayId); 3949 DisplayModeDirector.DesiredDisplayModeSpecs existingDesiredDisplayModeSpecs = 3950 display.getDesiredDisplayModeSpecsLocked(); 3951 if (DEBUG) { 3952 Slog.i(TAG, 3953 "Comparing display specs: " + desiredDisplayModeSpecs 3954 + ", existing: " + existingDesiredDisplayModeSpecs); 3955 } 3956 if (!desiredDisplayModeSpecs.equals(existingDesiredDisplayModeSpecs)) { 3957 display.setDesiredDisplayModeSpecsLocked(desiredDisplayModeSpecs); 3958 mChanged = true; 3959 } 3960 }; 3961 3962 @GuardedBy("mSyncRoot") 3963 private boolean mChanged = false; 3964 onDesiredDisplayModeSpecsChanged()3965 public void onDesiredDisplayModeSpecsChanged() { 3966 synchronized (mSyncRoot) { 3967 mChanged = false; 3968 mLogicalDisplayMapper.forEachLocked(mSpecsChangedConsumer); 3969 if (mChanged) { 3970 scheduleTraversalLocked(false); 3971 mChanged = false; 3972 } 3973 } 3974 } 3975 } 3976 3977 /** 3978 * Listens to changes in device state and reports the state to LogicalDisplayMapper. 3979 */ 3980 class DeviceStateListener implements DeviceStateManager.DeviceStateCallback { 3981 // Base state corresponds to the physical state of the device 3982 private int mBaseState = DeviceStateManager.INVALID_DEVICE_STATE; 3983 3984 @Override onStateChanged(int deviceState)3985 public void onStateChanged(int deviceState) { 3986 boolean isDeviceStateOverrideActive = deviceState != mBaseState; 3987 synchronized (mSyncRoot) { 3988 mLogicalDisplayMapper 3989 .setDeviceStateLocked(deviceState, isDeviceStateOverrideActive); 3990 } 3991 } 3992 3993 @Override onBaseStateChanged(int state)3994 public void onBaseStateChanged(int state) { 3995 mBaseState = state; 3996 } 3997 }; 3998 3999 private class BrightnessPair { 4000 public float brightness; 4001 public float sdrBrightness; 4002 BrightnessPair(float brightness, float sdrBrightness)4003 BrightnessPair(float brightness, float sdrBrightness) { 4004 this.brightness = brightness; 4005 this.sdrBrightness = sdrBrightness; 4006 } 4007 } 4008 4009 /** 4010 * Functional interface for providing time. 4011 * TODO(b/184781936): merge with PowerManagerService.Clock 4012 */ 4013 @VisibleForTesting 4014 public interface Clock { 4015 /** 4016 * Returns current time in milliseconds since boot, not counting time spent in deep sleep. 4017 */ 4018 long uptimeMillis(); 4019 } 4020 } 4021