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 com.android.server.display.DisplayDeviceInfo.TOUCH_NONE; 20 import static com.android.server.display.layout.Layout.Display.POSITION_REAR; 21 import static com.android.server.wm.utils.DisplayInfoOverrides.WM_OVERRIDE_FIELDS; 22 import static com.android.server.wm.utils.DisplayInfoOverrides.copyDisplayInfoFields; 23 24 import android.annotation.NonNull; 25 import android.annotation.Nullable; 26 import android.graphics.Point; 27 import android.graphics.Rect; 28 import android.hardware.display.DisplayManagerInternal; 29 import android.util.ArraySet; 30 import android.util.SparseArray; 31 import android.view.Display; 32 import android.view.DisplayEventReceiver; 33 import android.view.DisplayInfo; 34 import android.view.Surface; 35 import android.view.SurfaceControl; 36 37 import com.android.server.display.layout.Layout; 38 import com.android.server.display.mode.DisplayModeDirector; 39 import com.android.server.display.mode.SyntheticModeManager; 40 import com.android.server.wm.utils.InsetUtils; 41 42 import java.io.PrintWriter; 43 import java.io.StringWriter; 44 import java.util.Arrays; 45 import java.util.Objects; 46 47 /** 48 * Describes how a logical display is configured. 49 * <p> 50 * At this time, we only support logical displays that are coupled to a particular 51 * primary display device from which the logical display derives its basic properties 52 * such as its size, density and refresh rate. 53 * </p><p> 54 * A logical display may be mirrored onto multiple display devices in addition to its 55 * primary display device. Note that the contents of a logical display may not 56 * always be visible, even on its primary display device, such as in the case where 57 * the primary display device is currently mirroring content from a different 58 * logical display. 59 * </p><p> 60 * This object is designed to encapsulate as much of the policy of logical 61 * displays as possible. The idea is to make it easy to implement new kinds of 62 * logical displays mostly by making local changes to this class. 63 * </p><p> 64 * Note: The display manager architecture does not actually require logical displays 65 * to be associated with any individual display device. Logical displays and 66 * display devices are orthogonal concepts. Some mapping will exist between 67 * logical displays and display devices but it can be many-to-many and 68 * and some might have no relation at all. 69 * </p><p> 70 * Logical displays are guarded by the {@link DisplayManagerService.SyncRoot} lock. 71 * </p> 72 */ 73 final class LogicalDisplay { 74 private static final String TAG = "LogicalDisplay"; 75 // The layer stack we use when the display has been blanked to prevent any 76 // of its content from appearing. 77 private static final int BLANK_LAYER_STACK = -1; 78 79 private static final DisplayInfo EMPTY_DISPLAY_INFO = new DisplayInfo(); 80 81 private final DisplayInfo mBaseDisplayInfo = new DisplayInfo(); 82 private final int mDisplayId; 83 private final int mLayerStack; 84 85 // Indicates which display leads this logical display, in terms of brightness or other 86 // properties. 87 // {@link Layout.NO_LEAD_DISPLAY} means that this display is not lead by any others, and could 88 // be a leader itself. 89 private int mLeadDisplayId = Layout.NO_LEAD_DISPLAY; 90 91 private int mDisplayGroupId = Display.INVALID_DISPLAY_GROUP; 92 93 /** 94 * Override information set by the window manager. Will be reported instead of {@link #mInfo} 95 * if not null. 96 * @see #setDisplayInfoOverrideFromWindowManagerLocked(DisplayInfo) 97 * @see #getDisplayInfoLocked() 98 */ 99 private DisplayInfo mOverrideDisplayInfo; 100 /** 101 * Current display info. Initialized with {@link #mBaseDisplayInfo}. Set to {@code null} if 102 * needs to be updated. 103 * @see #getDisplayInfoLocked() 104 */ 105 private final DisplayInfoProxy mInfo = new DisplayInfoProxy(null); 106 107 // The display device that this logical display is based on and which 108 // determines the base metrics that it uses. 109 private DisplayDevice mPrimaryDisplayDevice; 110 private DisplayDeviceInfo mPrimaryDisplayDeviceInfo; 111 112 // True if the logical display has unique content. 113 private boolean mHasContent; 114 115 private int mRequestedColorMode; 116 private boolean mRequestedMinimalPostProcessing; 117 118 private int[] mUserDisabledHdrTypes = {}; 119 120 private DisplayModeDirector.DesiredDisplayModeSpecs mDesiredDisplayModeSpecs = 121 new DisplayModeDirector.DesiredDisplayModeSpecs(); 122 123 // The display offsets to apply to the display projection. 124 private int mDisplayOffsetX; 125 private int mDisplayOffsetY; 126 127 /** 128 * The position of the display projection sent to SurfaceFlinger 129 */ 130 private final Point mDisplayPosition = new Point(); 131 132 /** 133 * {@code true} if display scaling is disabled, or {@code false} if the default scaling mode 134 * is used. 135 * @see #isDisplayScalingDisabled() 136 * @see #setDisplayScalingDisabledLocked(boolean) 137 */ 138 private boolean mDisplayScalingDisabled; 139 140 // Temporary rectangle used when needed. 141 private final Rect mTempLayerStackRect = new Rect(); 142 private final Rect mTempDisplayRect = new Rect(); 143 144 /** A session token that controls the offloading operations of this logical display. */ 145 private DisplayOffloadSessionImpl mDisplayOffloadSession; 146 147 /** 148 * Name of a display group to which the display is assigned. 149 */ 150 private String mDisplayGroupName; 151 152 /** 153 * The UID mappings for refresh rate override 154 */ 155 private DisplayEventReceiver.FrameRateOverride[] mFrameRateOverrides; 156 157 /** 158 * Holds a set of UIDs that their frame rate override changed and needs to be notified 159 */ 160 private ArraySet<Integer> mPendingFrameRateOverrideUids; 161 162 /** 163 * Temporary frame rate override list, used when needed. 164 */ 165 private final SparseArray<Float> mTempFrameRateOverride; 166 167 // Indicates the display is enabled (allowed to be ON). 168 private boolean mIsEnabled; 169 170 // Indicates the display is part of a transition from one device-state ({@link 171 // DeviceStateManager}) to another. Being a "part" of a transition means that either 172 // the {@link mIsEnabled} is changing, or the underlying mPrimaryDisplayDevice is changing. 173 private boolean mIsInTransition; 174 175 // Indicates the position of the display, POSITION_UNKNOWN could mean it hasn't been specified, 176 // or this is a virtual display etc. 177 private int mDevicePosition = Layout.Display.POSITION_UNKNOWN; 178 179 // Indicates that something other than the primary display device info has changed and needs to 180 // be handled in the next update. 181 private boolean mDirty = false; 182 183 /** 184 * The ID of the thermal brightness throttling data that should be used. This can change e.g. 185 * in concurrent displays mode in which a stricter brightness throttling policy might need to 186 * be used. 187 */ 188 private String mThermalBrightnessThrottlingDataId; 189 190 /** 191 * Refresh rate range limitation based on the current device layout 192 */ 193 @Nullable 194 private SurfaceControl.RefreshRateRange mLayoutLimitedRefreshRate; 195 196 /** 197 * The ID of the power throttling data that should be used. 198 */ 199 private String mPowerThrottlingDataId; 200 201 /** 202 * RefreshRateRange limitation for @Temperature.ThrottlingStatus 203 */ 204 @NonNull 205 private SparseArray<SurfaceControl.RefreshRateRange> mThermalRefreshRateThrottling = 206 new SparseArray<>(); 207 208 /** 209 * If enabled, will not check for {@link Display#FLAG_ROTATES_WITH_CONTENT} in LogicalDisplay 210 * and simply use the {@link DisplayInfo#rotation} supplied by WindowManager via 211 * {@link #setDisplayInfoOverrideFromWindowManagerLocked} 212 */ 213 private boolean mAlwaysRotateDisplayDeviceEnabled; 214 215 /** 216 * If the aspect ratio of the resolution of the display does not match the physical aspect 217 * ratio of the display, then without this feature enabled, picture would appear stretched to 218 * the user. This is because applications assume that they are rendered on square pixels 219 * (meaning density of pixels in x and y directions are equal). This would result into circles 220 * appearing as ellipses to the user. 221 * To compensate for non-square (anisotropic) pixels, if this feature is enabled: 222 * 1. LogicalDisplay will add more pixels for the applications to render on, as if the pixels 223 * were square and occupied the full display. 224 * 2. SurfaceFlinger will squeeze this taller/wider surface into the available number of 225 * physical pixels in the current display resolution. 226 * 3. If a setting on the display itself is set to "fill the entire display panel" then the 227 * display will stretch the pixels to fill the display fully. 228 */ 229 private final boolean mIsAnisotropyCorrectionEnabled; 230 231 private final boolean mSyncedResolutionSwitchEnabled; 232 233 private boolean mCanHostTasks; 234 LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice)235 LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice) { 236 this(displayId, layerStack, primaryDisplayDevice, false, false, false); 237 } 238 LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice, boolean isAnisotropyCorrectionEnabled, boolean isAlwaysRotateDisplayDeviceEnabled, boolean isSyncedResolutionSwitchEnabled)239 LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice, 240 boolean isAnisotropyCorrectionEnabled, boolean isAlwaysRotateDisplayDeviceEnabled, 241 boolean isSyncedResolutionSwitchEnabled) { 242 mDisplayId = displayId; 243 mLayerStack = layerStack; 244 mPrimaryDisplayDevice = primaryDisplayDevice; 245 mPendingFrameRateOverrideUids = new ArraySet<>(); 246 mTempFrameRateOverride = new SparseArray<>(); 247 mIsEnabled = true; 248 mIsInTransition = false; 249 mThermalBrightnessThrottlingDataId = DisplayDeviceConfig.DEFAULT_ID; 250 mPowerThrottlingDataId = DisplayDeviceConfig.DEFAULT_ID; 251 mBaseDisplayInfo.thermalBrightnessThrottlingDataId = mThermalBrightnessThrottlingDataId; 252 mIsAnisotropyCorrectionEnabled = isAnisotropyCorrectionEnabled; 253 mAlwaysRotateDisplayDeviceEnabled = isAlwaysRotateDisplayDeviceEnabled; 254 mSyncedResolutionSwitchEnabled = isSyncedResolutionSwitchEnabled; 255 mCanHostTasks = (mDisplayId == Display.DEFAULT_DISPLAY); 256 } 257 setDevicePositionLocked(int position)258 public void setDevicePositionLocked(int position) { 259 if (mDevicePosition != position) { 260 mDevicePosition = position; 261 mDirty = true; 262 } 263 } getDevicePositionLocked()264 public int getDevicePositionLocked() { 265 return mDevicePosition; 266 } 267 268 /** 269 * Gets the logical display id of this logical display. 270 * 271 * @return The logical display id. 272 */ getDisplayIdLocked()273 public int getDisplayIdLocked() { 274 return mDisplayId; 275 } 276 277 /** 278 * Gets the primary display device associated with this logical display. 279 * 280 * @return The primary display device. 281 */ getPrimaryDisplayDeviceLocked()282 public DisplayDevice getPrimaryDisplayDeviceLocked() { 283 return mPrimaryDisplayDevice; 284 } 285 286 /** 287 * Gets information about the logical display. 288 * 289 * @return The device info, which should be treated as immutable by the caller. 290 * The logical display should allocate a new display info object whenever 291 * the data changes. 292 */ getDisplayInfoLocked()293 public DisplayInfo getDisplayInfoLocked() { 294 if (mInfo.get() == null) { 295 DisplayInfo info = new DisplayInfo(); 296 copyDisplayInfoFields(info, mBaseDisplayInfo, mOverrideDisplayInfo, 297 WM_OVERRIDE_FIELDS); 298 mInfo.set(info); 299 } 300 return mInfo.get(); 301 } 302 303 /** 304 * Returns the frame rate overrides list 305 */ getFrameRateOverrides()306 public DisplayEventReceiver.FrameRateOverride[] getFrameRateOverrides() { 307 return mFrameRateOverrides; 308 } 309 310 /** 311 * Returns the list of uids that needs to be updated about their frame rate override 312 */ getPendingFrameRateOverrideUids()313 public ArraySet<Integer> getPendingFrameRateOverrideUids() { 314 return mPendingFrameRateOverrideUids; 315 } 316 317 /** 318 * Clears the list of uids that needs to be updated about their frame rate override 319 */ clearPendingFrameRateOverrideUids()320 public void clearPendingFrameRateOverrideUids() { 321 mPendingFrameRateOverrideUids = new ArraySet<>(); 322 } 323 324 /** 325 * @see DisplayManagerInternal#getNonOverrideDisplayInfo(int, DisplayInfo) 326 */ getNonOverrideDisplayInfoLocked(DisplayInfo outInfo)327 void getNonOverrideDisplayInfoLocked(DisplayInfo outInfo) { 328 outInfo.copyFrom(mBaseDisplayInfo); 329 } 330 331 /** 332 * Sets overridden logical display information from the window manager. 333 * This method can be used to adjust application insets, rotation, and other 334 * properties that the window manager takes care of. 335 * 336 * @param info The logical display information, may be null. 337 */ setDisplayInfoOverrideFromWindowManagerLocked(DisplayInfo info)338 public boolean setDisplayInfoOverrideFromWindowManagerLocked(DisplayInfo info) { 339 if (info != null) { 340 if (mOverrideDisplayInfo == null) { 341 mOverrideDisplayInfo = new DisplayInfo(info); 342 mInfo.set(null); 343 return true; 344 } else if (!mOverrideDisplayInfo.equals(info)) { 345 mOverrideDisplayInfo.copyFrom(info); 346 mInfo.set(null); 347 return true; 348 } 349 } else if (mOverrideDisplayInfo != null) { 350 mOverrideDisplayInfo = null; 351 mInfo.set(null); 352 return true; 353 } 354 return false; 355 } 356 357 /** 358 * Returns true if the logical display is in a valid state. 359 * This method should be checked after calling {@link #updateLocked} to handle the 360 * case where a logical display should be removed because all of its associated 361 * display devices are gone or if it is otherwise no longer needed. 362 * 363 * @return True if the logical display is still valid. 364 */ isValidLocked()365 public boolean isValidLocked() { 366 return mPrimaryDisplayDevice != null; 367 } 368 isDirtyLocked()369 boolean isDirtyLocked() { 370 return mDirty; 371 } 372 373 /** 374 * Updates the {@link DisplayGroup} to which the logical display belongs. 375 * 376 * @param groupId Identifier for the {@link DisplayGroup}. 377 */ updateDisplayGroupIdLocked(int groupId)378 public void updateDisplayGroupIdLocked(int groupId) { 379 if (groupId != mDisplayGroupId) { 380 mDisplayGroupId = groupId; 381 mDirty = true; 382 } 383 } 384 385 /** 386 * Updates layoutLimitedRefreshRate 387 * 388 * @param layoutLimitedRefreshRate refresh rate limited by layout or null. 389 */ updateLayoutLimitedRefreshRateLocked( @ullable SurfaceControl.RefreshRateRange layoutLimitedRefreshRate)390 public void updateLayoutLimitedRefreshRateLocked( 391 @Nullable SurfaceControl.RefreshRateRange layoutLimitedRefreshRate) { 392 if (!Objects.equals(layoutLimitedRefreshRate, mLayoutLimitedRefreshRate)) { 393 mLayoutLimitedRefreshRate = layoutLimitedRefreshRate; 394 mDirty = true; 395 } 396 } 397 /** 398 * Updates thermalRefreshRateThrottling 399 * 400 * @param refreshRanges new thermalRefreshRateThrottling ranges limited by layout or default 401 */ updateThermalRefreshRateThrottling( @ullable SparseArray<SurfaceControl.RefreshRateRange> refreshRanges)402 public void updateThermalRefreshRateThrottling( 403 @Nullable SparseArray<SurfaceControl.RefreshRateRange> refreshRanges) { 404 if (refreshRanges == null) { 405 refreshRanges = new SparseArray<>(); 406 } 407 if (!mThermalRefreshRateThrottling.contentEquals(refreshRanges)) { 408 mThermalRefreshRateThrottling = refreshRanges; 409 mDirty = true; 410 } 411 } 412 413 /** 414 * Updates the state of the logical display based on the available display devices. 415 * The logical display might become invalid if it is attached to a display device 416 * that no longer exists. 417 * 418 * @param deviceRepo Repository of active {@link DisplayDevice}s. 419 */ updateLocked(DisplayDeviceRepository deviceRepo, SyntheticModeManager syntheticModeManager)420 public void updateLocked(DisplayDeviceRepository deviceRepo, 421 SyntheticModeManager syntheticModeManager) { 422 // Nothing to update if already invalid. 423 if (mPrimaryDisplayDevice == null) { 424 return; 425 } 426 427 // Check whether logical display has become invalid. 428 if (!deviceRepo.containsLocked(mPrimaryDisplayDevice)) { 429 setPrimaryDisplayDeviceLocked(null); 430 return; 431 } 432 433 // Bootstrap the logical display using its associated primary physical display. 434 // We might use more elaborate configurations later. It's possible that the 435 // configuration of several physical displays might be used to determine the 436 // logical display that they are sharing. (eg. Adjust size for pixel-perfect 437 // mirroring over HDMI.) 438 DisplayDeviceInfo deviceInfo = mPrimaryDisplayDevice.getDisplayDeviceInfoLocked(); 439 DisplayDeviceConfig config = mPrimaryDisplayDevice.getDisplayDeviceConfig(); 440 if (!Objects.equals(mPrimaryDisplayDeviceInfo, deviceInfo) || mDirty) { 441 mBaseDisplayInfo.layerStack = mLayerStack; 442 mBaseDisplayInfo.flags = 0; 443 // Displays default to moving content to the primary display when removed 444 mBaseDisplayInfo.removeMode = Display.REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY; 445 if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) { 446 mBaseDisplayInfo.flags |= Display.FLAG_SUPPORTS_PROTECTED_BUFFERS; 447 } 448 if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SECURE) != 0) { 449 mBaseDisplayInfo.flags |= Display.FLAG_SECURE; 450 } 451 if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_PRIVATE) != 0) { 452 mBaseDisplayInfo.flags |= Display.FLAG_PRIVATE; 453 // For private displays by default content is destroyed on removal. 454 mBaseDisplayInfo.removeMode = Display.REMOVE_MODE_DESTROY_CONTENT; 455 } 456 if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_DESTROY_CONTENT_ON_REMOVAL) != 0) { 457 mBaseDisplayInfo.removeMode = Display.REMOVE_MODE_DESTROY_CONTENT; 458 } 459 if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_PRESENTATION) != 0) { 460 mBaseDisplayInfo.flags |= Display.FLAG_PRESENTATION; 461 } 462 if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ROUND) != 0) { 463 mBaseDisplayInfo.flags |= Display.FLAG_ROUND; 464 } 465 if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) { 466 mBaseDisplayInfo.flags |= Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD; 467 } 468 if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) { 469 mBaseDisplayInfo.flags |= Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS; 470 } 471 if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_TRUSTED) != 0) { 472 mBaseDisplayInfo.flags |= Display.FLAG_TRUSTED; 473 } 474 if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP) != 0) { 475 mBaseDisplayInfo.flags |= Display.FLAG_OWN_DISPLAY_GROUP; 476 } 477 if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ALWAYS_UNLOCKED) != 0) { 478 mBaseDisplayInfo.flags |= Display.FLAG_ALWAYS_UNLOCKED; 479 } 480 if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0) { 481 mBaseDisplayInfo.flags |= Display.FLAG_ROTATES_WITH_CONTENT; 482 } 483 if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_TOUCH_FEEDBACK_DISABLED) != 0) { 484 mBaseDisplayInfo.flags |= Display.FLAG_TOUCH_FEEDBACK_DISABLED; 485 } 486 if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_OWN_FOCUS) != 0) { 487 mBaseDisplayInfo.flags |= Display.FLAG_OWN_FOCUS; 488 } 489 if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_STEAL_TOP_FOCUS_DISABLED) != 0) { 490 mBaseDisplayInfo.flags |= Display.FLAG_STEAL_TOP_FOCUS_DISABLED; 491 } 492 // Rear display should not be allowed to use the content mode switch. 493 if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ALLOWS_CONTENT_MODE_SWITCH) != 0 494 && mDevicePosition != Layout.Display.POSITION_REAR) { 495 mBaseDisplayInfo.flags |= Display.FLAG_ALLOWS_CONTENT_MODE_SWITCH; 496 } 497 Rect maskingInsets = getMaskingInsets(deviceInfo); 498 int maskedWidth = deviceInfo.width - maskingInsets.left - maskingInsets.right; 499 int maskedHeight = deviceInfo.height - maskingInsets.top - maskingInsets.bottom; 500 501 if (mIsAnisotropyCorrectionEnabled && deviceInfo.type == Display.TYPE_EXTERNAL 502 && deviceInfo.xDpi > 0 && deviceInfo.yDpi > 0) { 503 if (deviceInfo.xDpi > deviceInfo.yDpi * DisplayDevice.MAX_ANISOTROPY) { 504 maskedHeight = (int) (maskedHeight * deviceInfo.xDpi / deviceInfo.yDpi + 0.5); 505 } else if (deviceInfo.xDpi * DisplayDevice.MAX_ANISOTROPY < deviceInfo.yDpi) { 506 maskedWidth = (int) (maskedWidth * deviceInfo.yDpi / deviceInfo.xDpi + 0.5); 507 } 508 } 509 510 mBaseDisplayInfo.type = deviceInfo.type; 511 mBaseDisplayInfo.address = deviceInfo.address; 512 mBaseDisplayInfo.deviceProductInfo = deviceInfo.deviceProductInfo; 513 mBaseDisplayInfo.name = deviceInfo.name; 514 mBaseDisplayInfo.uniqueId = deviceInfo.uniqueId; 515 mBaseDisplayInfo.appWidth = maskedWidth; 516 mBaseDisplayInfo.appHeight = maskedHeight; 517 mBaseDisplayInfo.logicalWidth = maskedWidth; 518 mBaseDisplayInfo.logicalHeight = maskedHeight; 519 mBaseDisplayInfo.rotation = Surface.ROTATION_0; 520 mBaseDisplayInfo.modeId = deviceInfo.modeId; 521 mBaseDisplayInfo.renderFrameRate = deviceInfo.renderFrameRate; 522 mBaseDisplayInfo.hasArrSupport = deviceInfo.hasArrSupport; 523 mBaseDisplayInfo.frameRateCategoryRate = deviceInfo.frameRateCategoryRate; 524 mBaseDisplayInfo.supportedRefreshRates = Arrays.copyOf( 525 deviceInfo.supportedRefreshRates, deviceInfo.supportedRefreshRates.length); 526 mBaseDisplayInfo.defaultModeId = deviceInfo.defaultModeId; 527 mBaseDisplayInfo.userPreferredModeId = deviceInfo.userPreferredModeId; 528 mBaseDisplayInfo.supportedModes = Arrays.copyOf( 529 deviceInfo.supportedModes, deviceInfo.supportedModes.length); 530 mBaseDisplayInfo.appsSupportedModes = syntheticModeManager.createAppSupportedModes( 531 config, mBaseDisplayInfo.supportedModes, mBaseDisplayInfo.hasArrSupport 532 ); 533 mBaseDisplayInfo.colorMode = deviceInfo.colorMode; 534 mBaseDisplayInfo.supportedColorModes = Arrays.copyOf( 535 deviceInfo.supportedColorModes, 536 deviceInfo.supportedColorModes.length); 537 mBaseDisplayInfo.hdrCapabilities = deviceInfo.hdrCapabilities; 538 mBaseDisplayInfo.isForceSdr = deviceInfo.isForceSdr; 539 mBaseDisplayInfo.userDisabledHdrTypes = mUserDisabledHdrTypes; 540 mBaseDisplayInfo.minimalPostProcessingSupported = 541 deviceInfo.allmSupported || deviceInfo.gameContentTypeSupported; 542 mBaseDisplayInfo.logicalDensityDpi = deviceInfo.densityDpi; 543 mBaseDisplayInfo.physicalXDpi = deviceInfo.xDpi; 544 mBaseDisplayInfo.physicalYDpi = deviceInfo.yDpi; 545 mBaseDisplayInfo.appVsyncOffsetNanos = deviceInfo.appVsyncOffsetNanos; 546 mBaseDisplayInfo.presentationDeadlineNanos = deviceInfo.presentationDeadlineNanos; 547 mBaseDisplayInfo.state = deviceInfo.state; 548 mBaseDisplayInfo.committedState = deviceInfo.committedState; 549 mBaseDisplayInfo.smallestNominalAppWidth = maskedWidth; 550 mBaseDisplayInfo.smallestNominalAppHeight = maskedHeight; 551 mBaseDisplayInfo.largestNominalAppWidth = maskedWidth; 552 mBaseDisplayInfo.largestNominalAppHeight = maskedHeight; 553 mBaseDisplayInfo.ownerUid = deviceInfo.ownerUid; 554 mBaseDisplayInfo.ownerPackageName = deviceInfo.ownerPackageName; 555 boolean maskCutout = 556 (deviceInfo.flags & DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT) != 0; 557 mBaseDisplayInfo.displayCutout = maskCutout ? null : deviceInfo.displayCutout; 558 mBaseDisplayInfo.displayId = mDisplayId; 559 mBaseDisplayInfo.displayGroupId = mDisplayGroupId; 560 updateFrameRateOverrides(deviceInfo); 561 mBaseDisplayInfo.brightnessMinimum = deviceInfo.brightnessMinimum; 562 mBaseDisplayInfo.brightnessMaximum = deviceInfo.brightnessMaximum; 563 mBaseDisplayInfo.brightnessDefault = deviceInfo.brightnessDefault; 564 mBaseDisplayInfo.brightnessDim = deviceInfo.brightnessDim; 565 mBaseDisplayInfo.hdrSdrRatio = deviceInfo.hdrSdrRatio; 566 mBaseDisplayInfo.roundedCorners = deviceInfo.roundedCorners; 567 mBaseDisplayInfo.installOrientation = deviceInfo.installOrientation; 568 mBaseDisplayInfo.displayShape = deviceInfo.displayShape; 569 570 if (mDevicePosition == Layout.Display.POSITION_REAR) { 571 // A rear display is meant to host a specific experience that is essentially 572 // a presentation to another user or users other than the main user since they 573 // can't actually see that display. Given that, it's a suitable display for 574 // presentations but the content should be destroyed rather than moved to a non-rear 575 // display when the rear display is removed. 576 mBaseDisplayInfo.flags |= Display.FLAG_REAR; 577 mBaseDisplayInfo.flags |= Display.FLAG_PRESENTATION; 578 mBaseDisplayInfo.removeMode = Display.REMOVE_MODE_DESTROY_CONTENT; 579 } 580 581 mBaseDisplayInfo.layoutLimitedRefreshRate = mLayoutLimitedRefreshRate; 582 mBaseDisplayInfo.thermalRefreshRateThrottling = mThermalRefreshRateThrottling; 583 mBaseDisplayInfo.thermalBrightnessThrottlingDataId = mThermalBrightnessThrottlingDataId; 584 mBaseDisplayInfo.canHostTasks = mCanHostTasks; 585 586 mPrimaryDisplayDeviceInfo = deviceInfo; 587 mInfo.set(null); 588 mDirty = false; 589 } 590 } 591 updateFrameRateOverrides(DisplayDeviceInfo deviceInfo)592 private void updateFrameRateOverrides(DisplayDeviceInfo deviceInfo) { 593 mTempFrameRateOverride.clear(); 594 if (mFrameRateOverrides != null) { 595 for (DisplayEventReceiver.FrameRateOverride frameRateOverride 596 : mFrameRateOverrides) { 597 mTempFrameRateOverride.put(frameRateOverride.uid, 598 frameRateOverride.frameRateHz); 599 } 600 } 601 mFrameRateOverrides = deviceInfo.frameRateOverrides; 602 if (mFrameRateOverrides != null) { 603 for (DisplayEventReceiver.FrameRateOverride frameRateOverride 604 : mFrameRateOverrides) { 605 float refreshRate = mTempFrameRateOverride.get(frameRateOverride.uid, 0f); 606 if (refreshRate == 0 || frameRateOverride.frameRateHz != refreshRate) { 607 mTempFrameRateOverride.put(frameRateOverride.uid, 608 frameRateOverride.frameRateHz); 609 } else { 610 mTempFrameRateOverride.delete(frameRateOverride.uid); 611 } 612 } 613 } 614 for (int i = 0; i < mTempFrameRateOverride.size(); i++) { 615 mPendingFrameRateOverrideUids.add(mTempFrameRateOverride.keyAt(i)); 616 } 617 } 618 619 /** 620 * Return the insets currently applied to the display. 621 * 622 * Note that the base DisplayInfo already takes these insets into account, so if you want to 623 * find out the <b>true</b> size of the display, you need to add them back to the logical 624 * dimensions. 625 */ getInsets()626 public Rect getInsets() { 627 return getMaskingInsets(mPrimaryDisplayDeviceInfo); 628 } 629 630 /** 631 * Returns insets in ROTATION_0 for areas that are masked. 632 */ getMaskingInsets(DisplayDeviceInfo deviceInfo)633 private static Rect getMaskingInsets(DisplayDeviceInfo deviceInfo) { 634 boolean maskCutout = (deviceInfo.flags & DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT) != 0; 635 if (maskCutout && deviceInfo.displayCutout != null) { 636 // getSafeInsets is fixed at creation time and cannot change 637 return deviceInfo.displayCutout.getSafeInsets(); 638 } else { 639 return new Rect(); 640 } 641 } 642 643 /** 644 * Returns the position of the display's projection. 645 * 646 * @return The x, y coordinates of the display. The return object must be treated as immutable. 647 */ getDisplayPosition()648 Point getDisplayPosition() { 649 // Allocate a new object to avoid a data race. 650 return new Point(mDisplayPosition); 651 } 652 653 /** 654 * Applies the layer stack and transformation to the given display device 655 * so that it shows the contents of this logical display. 656 * 657 * We know that the given display device is only ever showing the contents of 658 * a single logical display, so this method is expected to blow away all of its 659 * transformation properties to make it happen regardless of what the 660 * display device was previously showing. 661 * 662 * The caller must have an open Surface transaction. 663 * 664 * The display device may not be the primary display device, in the case 665 * where the display is being mirrored. 666 * 667 * @param device The display device to modify. 668 * @param isBlanked True if the device is being blanked. 669 */ configureDisplayLocked(SurfaceControl.Transaction t, DisplayDevice device, boolean isBlanked)670 public void configureDisplayLocked(SurfaceControl.Transaction t, 671 DisplayDevice device, 672 boolean isBlanked) { 673 // Set the layer stack. 674 device.setLayerStackLocked(t, isBlanked ? BLANK_LAYER_STACK : mLayerStack, mDisplayId); 675 // Also inform whether the device is the same one sent to inputflinger for its layerstack. 676 // Prevent displays that are disabled from receiving input. 677 // TODO(b/188914255): Remove once input can dispatch against device vs layerstack. 678 device.setDisplayFlagsLocked(t, 679 (isEnabledLocked() && device.getDisplayDeviceInfoLocked().touch != TOUCH_NONE) 680 ? SurfaceControl.DISPLAY_RECEIVES_INPUT 681 : 0); 682 683 // Set the color mode and allowed display mode. 684 if (device == mPrimaryDisplayDevice) { 685 device.setDesiredDisplayModeSpecsLocked(mDesiredDisplayModeSpecs); 686 device.setRequestedColorModeLocked(mRequestedColorMode); 687 } else { 688 // Reset to default for non primary displays 689 device.setDesiredDisplayModeSpecsLocked( 690 new DisplayModeDirector.DesiredDisplayModeSpecs()); 691 device.setRequestedColorModeLocked(0); 692 } 693 694 device.setAutoLowLatencyModeLocked(mRequestedMinimalPostProcessing); 695 device.setGameContentTypeLocked(mRequestedMinimalPostProcessing); 696 697 // Only grab the display info now as it may have been changed based on the requests above. 698 final DisplayInfo displayInfo = getDisplayInfoLocked(); 699 final DisplayDeviceInfo displayDeviceInfo = device.getDisplayDeviceInfoLocked(); 700 701 // Set the viewport. 702 // This is the area of the logical display that we intend to show on the 703 // display device. For now, it is always the full size of the logical display. 704 mTempLayerStackRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight); 705 706 // Set the orientation. 707 // The orientation specifies how the physical coordinate system of the display 708 // is rotated when the contents of the logical display are rendered. 709 int orientation = Surface.ROTATION_0; 710 711 // FLAG_ROTATES_WITH_CONTENT is now handled in DisplayContent. When the flag 712 // mAlwaysRotateDisplayDeviceEnabled is removed, we should also remove this check for 713 // ROTATES_WITH_CONTENT here and always set the orientation. 714 if ((displayDeviceInfo.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0 715 || mAlwaysRotateDisplayDeviceEnabled) { 716 orientation = displayInfo.rotation; 717 } 718 719 // Apply the physical rotation of the display device itself. 720 orientation = (orientation + displayDeviceInfo.rotation) % 4; 721 722 // Set the frame. 723 // The frame specifies the rotated physical coordinates into which the viewport 724 // is mapped. We need to take care to preserve the aspect ratio of the viewport. 725 // Currently we maximize the area to fill the display, but we could try to be 726 // more clever and match resolutions. 727 boolean rotated = (orientation == Surface.ROTATION_90 728 || orientation == Surface.ROTATION_270); 729 int physWidth = rotated ? displayDeviceInfo.height : displayDeviceInfo.width; 730 int physHeight = rotated ? displayDeviceInfo.width : displayDeviceInfo.height; 731 732 Rect maskingInsets = getMaskingInsets(displayDeviceInfo); 733 InsetUtils.rotateInsets(maskingInsets, orientation); 734 // Don't consider the masked area as available when calculating the scaling below. 735 physWidth -= maskingInsets.left + maskingInsets.right; 736 physHeight -= maskingInsets.top + maskingInsets.bottom; 737 738 var displayLogicalWidth = displayInfo.logicalWidth; 739 var displayLogicalHeight = displayInfo.logicalHeight; 740 741 if (mIsAnisotropyCorrectionEnabled && displayDeviceInfo.type == Display.TYPE_EXTERNAL 742 && displayDeviceInfo.xDpi > 0 && displayDeviceInfo.yDpi > 0) { 743 if (displayDeviceInfo.xDpi > displayDeviceInfo.yDpi * DisplayDevice.MAX_ANISOTROPY) { 744 var scalingFactor = displayDeviceInfo.yDpi / displayDeviceInfo.xDpi; 745 if (rotated) { 746 displayLogicalWidth = (int) ((float) displayLogicalWidth * scalingFactor + 0.5); 747 } else { 748 displayLogicalHeight = (int) ((float) displayLogicalHeight * scalingFactor 749 + 0.5); 750 } 751 } else if (displayDeviceInfo.xDpi * DisplayDevice.MAX_ANISOTROPY 752 < displayDeviceInfo.yDpi) { 753 var scalingFactor = displayDeviceInfo.xDpi / displayDeviceInfo.yDpi; 754 if (rotated) { 755 displayLogicalHeight = (int) ((float) displayLogicalHeight * scalingFactor 756 + 0.5); 757 } else { 758 displayLogicalWidth = (int) ((float) displayLogicalWidth * scalingFactor + 0.5); 759 } 760 } 761 } 762 763 // Determine whether the width or height is more constrained to be scaled. 764 // physWidth / displayInfo.logicalWidth => letter box 765 // or physHeight / displayInfo.logicalHeight => pillar box 766 // 767 // We avoid a division (and possible floating point imprecision) here by 768 // multiplying the fractions by the product of their denominators before 769 // comparing them. 770 int displayRectWidth, displayRectHeight; 771 if ((displayInfo.flags & Display.FLAG_SCALING_DISABLED) != 0 || mDisplayScalingDisabled) { 772 displayRectWidth = displayLogicalWidth; 773 displayRectHeight = displayLogicalHeight; 774 } else if (physWidth * displayLogicalHeight 775 < physHeight * displayLogicalWidth) { 776 // Letter box. 777 displayRectWidth = physWidth; 778 displayRectHeight = displayLogicalHeight * physWidth / displayLogicalWidth; 779 } else { 780 // Pillar box. 781 displayRectWidth = displayLogicalWidth * physHeight / displayLogicalHeight; 782 displayRectHeight = physHeight; 783 } 784 int displayRectTop = (physHeight - displayRectHeight) / 2; 785 int displayRectLeft = (physWidth - displayRectWidth) / 2; 786 mTempDisplayRect.set(displayRectLeft, displayRectTop, 787 displayRectLeft + displayRectWidth, displayRectTop + displayRectHeight); 788 789 // Now add back the offset for the masked area. 790 mTempDisplayRect.offset(maskingInsets.left, maskingInsets.top); 791 792 if (orientation == Surface.ROTATION_0) { 793 mTempDisplayRect.offset(mDisplayOffsetX, mDisplayOffsetY); 794 } else if (orientation == Surface.ROTATION_90) { 795 mTempDisplayRect.offset(mDisplayOffsetY, -mDisplayOffsetX); 796 } else if (orientation == Surface.ROTATION_180) { 797 mTempDisplayRect.offset(-mDisplayOffsetX, -mDisplayOffsetY); 798 } else { // Surface.ROTATION_270 799 mTempDisplayRect.offset(-mDisplayOffsetY, mDisplayOffsetX); 800 } 801 802 mDisplayPosition.set(mTempDisplayRect.left, mTempDisplayRect.top); 803 804 if (mSyncedResolutionSwitchEnabled || displayDeviceInfo.type == Display.TYPE_VIRTUAL) { 805 device.configureDisplaySizeLocked(t); 806 } 807 device.setProjectionLocked(t, orientation, mTempLayerStackRect, mTempDisplayRect); 808 device.configureSurfaceLocked(t); 809 } 810 811 /** 812 * Returns true if the logical display has unique content. 813 * <p> 814 * If the display has unique content then we will try to ensure that it is 815 * visible on at least its primary display device. Otherwise we will ignore the 816 * logical display and perhaps show mirrored content on the primary display device. 817 * </p> 818 * 819 * @return True if the display has unique content. 820 */ hasContentLocked()821 public boolean hasContentLocked() { 822 return mHasContent; 823 } 824 825 /** 826 * Sets whether the logical display has unique content. 827 * 828 * @param hasContent True if the display has unique content. 829 */ setHasContentLocked(boolean hasContent)830 public void setHasContentLocked(boolean hasContent) { 831 mHasContent = hasContent; 832 } 833 834 /** 835 * Sets the display configs the system can use. 836 */ setDesiredDisplayModeSpecsLocked( DisplayModeDirector.DesiredDisplayModeSpecs specs)837 public void setDesiredDisplayModeSpecsLocked( 838 DisplayModeDirector.DesiredDisplayModeSpecs specs) { 839 mDesiredDisplayModeSpecs = specs; 840 } 841 842 /** 843 * Returns the display configs the system can choose. 844 */ getDesiredDisplayModeSpecsLocked()845 public DisplayModeDirector.DesiredDisplayModeSpecs getDesiredDisplayModeSpecsLocked() { 846 return mDesiredDisplayModeSpecs; 847 } 848 849 /** 850 * Requests the given color mode. 851 */ setRequestedColorModeLocked(int colorMode)852 public void setRequestedColorModeLocked(int colorMode) { 853 mRequestedColorMode = colorMode; 854 } 855 856 /** 857 * Returns the last requested minimal post processing setting. 858 */ getRequestedMinimalPostProcessingLocked()859 public boolean getRequestedMinimalPostProcessingLocked() { 860 return mRequestedMinimalPostProcessing; 861 } 862 863 /** 864 * Instructs the connected display to do minimal post processing. This is implemented either 865 * via HDMI 2.1 ALLM or HDMI 1.4 ContentType=Game. 866 * 867 * @param on Whether to set minimal post processing on/off on the connected display. 868 */ setRequestedMinimalPostProcessingLocked(boolean on)869 public void setRequestedMinimalPostProcessingLocked(boolean on) { 870 mRequestedMinimalPostProcessing = on; 871 } 872 873 /** Returns the pending requested color mode. */ getRequestedColorModeLocked()874 public int getRequestedColorModeLocked() { 875 return mRequestedColorMode; 876 } 877 878 /** 879 * Gets the burn-in offset in X. 880 */ getDisplayOffsetXLocked()881 public int getDisplayOffsetXLocked() { 882 return mDisplayOffsetX; 883 } 884 885 /** 886 * Gets the burn-in offset in Y. 887 */ getDisplayOffsetYLocked()888 public int getDisplayOffsetYLocked() { 889 return mDisplayOffsetY; 890 } 891 892 /** 893 * Sets the burn-in offsets. 894 */ setDisplayOffsetsLocked(int x, int y)895 public void setDisplayOffsetsLocked(int x, int y) { 896 mDisplayOffsetX = x; 897 mDisplayOffsetY = y; 898 } 899 900 /** 901 * @return {@code true} if display scaling is disabled, or {@code false} if the default scaling 902 * mode is used. 903 */ isDisplayScalingDisabled()904 public boolean isDisplayScalingDisabled() { 905 return mDisplayScalingDisabled; 906 } 907 908 /** 909 * Disables scaling for a display. 910 * 911 * @param disableScaling {@code true} to disable scaling, 912 * {@code false} to use the default scaling behavior of the logical display. 913 */ setDisplayScalingDisabledLocked(boolean disableScaling)914 public void setDisplayScalingDisabledLocked(boolean disableScaling) { 915 mDisplayScalingDisabled = disableScaling; 916 } 917 setUserDisabledHdrTypes(@onNull int[] userDisabledHdrTypes)918 public void setUserDisabledHdrTypes(@NonNull int[] userDisabledHdrTypes) { 919 if (mUserDisabledHdrTypes != userDisabledHdrTypes) { 920 mUserDisabledHdrTypes = userDisabledHdrTypes; 921 mBaseDisplayInfo.userDisabledHdrTypes = userDisabledHdrTypes; 922 mInfo.set(null); 923 } 924 } 925 926 /** 927 * Checks whether display is of the type where HDR settings are relevant, and then sets 928 * whether Force SDR conversion mode is active. isForceSdr is checked by the Display when 929 * returning HDR capabilities. 930 * 931 * @param isForceSdr Whether Force SDR conversion mode is active 932 * @return Whether Display Manager should call handleLogicalDisplayChangedLocked() 933 */ setIsForceSdr(boolean isForceSdr)934 public boolean setIsForceSdr(boolean isForceSdr) { 935 int displayType = getDisplayInfoLocked().type; 936 boolean isTargetDisplayType = displayType == Display.TYPE_INTERNAL 937 || displayType == Display.TYPE_EXTERNAL 938 || displayType == Display.TYPE_OVERLAY; 939 940 boolean handleLogicalDisplayChangedLocked = false; 941 if (isTargetDisplayType && mBaseDisplayInfo.isForceSdr != isForceSdr) { 942 mBaseDisplayInfo.isForceSdr = isForceSdr; 943 mInfo.set(null); 944 handleLogicalDisplayChangedLocked = true; 945 } 946 return handleLogicalDisplayChangedLocked; 947 } 948 canHostTasksLocked()949 boolean canHostTasksLocked() { 950 return mCanHostTasks; 951 } 952 953 /** 954 * Sets whether the display can host tasks. 955 * 956 * @param canHostTasks Whether the display can host tasks according to the user's setting. 957 * @return Whether Display Manager should call sendDisplayEventIfEnabledLocked(). 958 */ setCanHostTasksLocked(boolean canHostTasks)959 boolean setCanHostTasksLocked(boolean canHostTasks) { 960 canHostTasks = validateCanHostTasksLocked(canHostTasks); 961 if (mBaseDisplayInfo.canHostTasks == canHostTasks) { 962 return false; 963 } 964 965 mCanHostTasks = canHostTasks; 966 mBaseDisplayInfo.canHostTasks = canHostTasks; 967 mInfo.set(null); 968 return true; 969 } 970 971 /** 972 * Checks whether the display's ability to host tasks should be determined independently of the 973 * user's setting value. If so, returns the actual validated value based on the display's 974 * usage; otherwise, returns the user's setting value. 975 * 976 * @param canHostTasks Whether the display can host tasks according to the user's setting. 977 * @return Whether the display can actually host task after configuration. 978 */ validateCanHostTasksLocked(boolean canHostTasks)979 private boolean validateCanHostTasksLocked(boolean canHostTasks) { 980 // The default display can always host tasks. 981 if (getDisplayIdLocked() == Display.DEFAULT_DISPLAY) { 982 return true; 983 } 984 985 // The display that should only mirror can never host tasks. 986 if (mPrimaryDisplayDevice.shouldOnlyMirror()) { 987 return false; 988 } 989 990 // The display that has its own content can always host tasks. 991 final boolean isRearDisplay = getDevicePositionLocked() == POSITION_REAR; 992 final boolean ownContent = 993 ((mPrimaryDisplayDevice.getDisplayDeviceInfoLocked().flags 994 & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) 995 != 0) 996 || isRearDisplay; 997 if (ownContent) { 998 return true; 999 } 1000 1001 return canHostTasks; 1002 } 1003 1004 /** 1005 * Swap the underlying {@link DisplayDevice} with the specified LogicalDisplay. 1006 * 1007 * @param targetDisplay The display with which to swap display-devices. 1008 * @return {@code true} if the displays were swapped, {@code false} otherwise. 1009 */ swapDisplaysLocked(@onNull LogicalDisplay targetDisplay)1010 public void swapDisplaysLocked(@NonNull LogicalDisplay targetDisplay) { 1011 final DisplayDevice oldTargetDevice = 1012 targetDisplay.setPrimaryDisplayDeviceLocked(mPrimaryDisplayDevice); 1013 setPrimaryDisplayDeviceLocked(oldTargetDevice); 1014 } 1015 1016 /** 1017 * Sets the primary display device to the specified device. 1018 * 1019 * @param device The new device to set. 1020 * @return The previously set display device. 1021 */ setPrimaryDisplayDeviceLocked(@ullable DisplayDevice device)1022 public DisplayDevice setPrimaryDisplayDeviceLocked(@Nullable DisplayDevice device) { 1023 final DisplayDevice old = mPrimaryDisplayDevice; 1024 mPrimaryDisplayDevice = device; 1025 1026 // Reset all our display info data 1027 mPrimaryDisplayDeviceInfo = null; 1028 mBaseDisplayInfo.copyFrom(EMPTY_DISPLAY_INFO); 1029 mInfo.set(null); 1030 1031 return old; 1032 } 1033 1034 /** 1035 * @return {@code true} if the LogicalDisplay is enabled or {@code false} 1036 * if disabled indicating that the display should be hidden from the rest of the apps and 1037 * framework. 1038 */ isEnabledLocked()1039 public boolean isEnabledLocked() { 1040 return mIsEnabled; 1041 } 1042 1043 /** 1044 * Sets the display as enabled. 1045 * 1046 * @param enabled True if enabled, false otherwise. 1047 */ setEnabledLocked(boolean enabled)1048 public void setEnabledLocked(boolean enabled) { 1049 if (enabled != mIsEnabled) { 1050 mDirty = true; 1051 mIsEnabled = enabled; 1052 } 1053 } 1054 1055 /** 1056 * @return {@code true} if the LogicalDisplay is in a transition phase. This is used to indicate 1057 * that we are getting ready to swap the underlying display-device and the display should be 1058 * rendered appropriately to reduce jank. 1059 */ isInTransitionLocked()1060 public boolean isInTransitionLocked() { 1061 return mIsInTransition; 1062 } 1063 1064 /** 1065 * Sets the transition phase. 1066 * @param isInTransition True if it display is in transition. 1067 */ setIsInTransitionLocked(boolean isInTransition)1068 public void setIsInTransitionLocked(boolean isInTransition) { 1069 mIsInTransition = isInTransition; 1070 } 1071 1072 /** 1073 * @param brightnessThrottlingDataId The ID of the brightness throttling data that this 1074 * display should use. 1075 */ setThermalBrightnessThrottlingDataIdLocked(String brightnessThrottlingDataId)1076 public void setThermalBrightnessThrottlingDataIdLocked(String brightnessThrottlingDataId) { 1077 if (!Objects.equals(brightnessThrottlingDataId, mThermalBrightnessThrottlingDataId)) { 1078 mThermalBrightnessThrottlingDataId = brightnessThrottlingDataId; 1079 mDirty = true; 1080 } 1081 } 1082 1083 /** 1084 * @param powerThrottlingDataId The ID of the brightness throttling data that this 1085 * display should use. 1086 */ setPowerThrottlingDataIdLocked(String powerThrottlingDataId)1087 public void setPowerThrottlingDataIdLocked(String powerThrottlingDataId) { 1088 if (!Objects.equals(powerThrottlingDataId, mPowerThrottlingDataId)) { 1089 mPowerThrottlingDataId = powerThrottlingDataId; 1090 mDirty = true; 1091 } 1092 } 1093 1094 /** 1095 * Returns powerThrottlingDataId which is the ID of the brightness 1096 * throttling data that this display should use. 1097 */ getPowerThrottlingDataIdLocked()1098 public String getPowerThrottlingDataIdLocked() { 1099 return mPowerThrottlingDataId; 1100 } 1101 1102 /** 1103 * Sets the display of which this display is a follower, regarding brightness or other 1104 * properties. If set to {@link Layout#NO_LEAD_DISPLAY}, this display does not follow any 1105 * others, and has the potential to be a lead display to others. 1106 * 1107 * A display cannot be a leader or follower of itself, and there cannot be cycles. 1108 * A display cannot be both a leader and a follower, ie, there must not be any chains. 1109 * 1110 * @param displayId logical display id 1111 */ setLeadDisplayLocked(int displayId)1112 public void setLeadDisplayLocked(int displayId) { 1113 if (mDisplayId != mLeadDisplayId && mDisplayId != displayId) { 1114 mLeadDisplayId = displayId; 1115 } 1116 } 1117 getLeadDisplayIdLocked()1118 public int getLeadDisplayIdLocked() { 1119 return mLeadDisplayId; 1120 } 1121 1122 /** 1123 * Sets the name of display group to which the display is assigned. 1124 */ setDisplayGroupNameLocked(String displayGroupName)1125 public void setDisplayGroupNameLocked(String displayGroupName) { 1126 mDisplayGroupName = displayGroupName; 1127 } 1128 1129 /** 1130 * Gets the name of display group to which the display is assigned. 1131 */ getDisplayGroupNameLocked()1132 public String getDisplayGroupNameLocked() { 1133 return mDisplayGroupName; 1134 } 1135 setDisplayOffloadSessionLocked(DisplayOffloadSessionImpl session)1136 public void setDisplayOffloadSessionLocked(DisplayOffloadSessionImpl session) { 1137 mDisplayOffloadSession = session; 1138 } 1139 getDisplayOffloadSessionLocked()1140 public DisplayOffloadSessionImpl getDisplayOffloadSessionLocked() { 1141 return mDisplayOffloadSession; 1142 } 1143 dumpLocked(PrintWriter pw)1144 public void dumpLocked(PrintWriter pw) { 1145 pw.println("mDisplayId=" + mDisplayId); 1146 pw.println("mPrimaryDisplayDevice=" + (mPrimaryDisplayDevice != null 1147 ? mPrimaryDisplayDevice.getNameLocked() + "(" + mPrimaryDisplayDevice.getUniqueId() 1148 + ")" : "null")); 1149 pw.println("mIsEnabled=" + mIsEnabled); 1150 pw.println("mIsInTransition=" + mIsInTransition); 1151 pw.println("mLayerStack=" + mLayerStack); 1152 pw.println("mPosition=" + mDevicePosition); 1153 pw.println("mHasContent=" + mHasContent); 1154 pw.println("mDesiredDisplayModeSpecs={" + mDesiredDisplayModeSpecs + "}"); 1155 pw.println("mRequestedColorMode=" + mRequestedColorMode); 1156 pw.println("mDisplayOffset=(" + mDisplayOffsetX + ", " + mDisplayOffsetY + ")"); 1157 pw.println("mDisplayScalingDisabled=" + mDisplayScalingDisabled); 1158 pw.println("mBaseDisplayInfo=" + mBaseDisplayInfo); 1159 pw.println("mOverrideDisplayInfo=" + mOverrideDisplayInfo); 1160 pw.println("mRequestedMinimalPostProcessing=" + mRequestedMinimalPostProcessing); 1161 pw.println("mFrameRateOverrides=" + Arrays.toString(mFrameRateOverrides)); 1162 pw.println("mPendingFrameRateOverrideUids=" + mPendingFrameRateOverrideUids); 1163 pw.println("mDisplayGroupId=" + mDisplayGroupId); 1164 pw.println("mDisplayGroupName=" + mDisplayGroupName); 1165 pw.println("mThermalBrightnessThrottlingDataId=" + mThermalBrightnessThrottlingDataId); 1166 pw.println("mLeadDisplayId=" + mLeadDisplayId); 1167 pw.println("mLayoutLimitedRefreshRate=" + mLayoutLimitedRefreshRate); 1168 pw.println("mThermalRefreshRateThrottling=" + mThermalRefreshRateThrottling); 1169 pw.println("mPowerThrottlingDataId=" + mPowerThrottlingDataId); 1170 } 1171 1172 @Override toString()1173 public String toString() { 1174 StringWriter sw = new StringWriter(); 1175 dumpLocked(new PrintWriter(sw)); 1176 return sw.toString(); 1177 } 1178 } 1179