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