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 android.view; 18 19 import static android.view.DisplayInfoProto.APP_HEIGHT; 20 import static android.view.DisplayInfoProto.APP_WIDTH; 21 import static android.view.DisplayInfoProto.LOGICAL_HEIGHT; 22 import static android.view.DisplayInfoProto.LOGICAL_WIDTH; 23 import static android.view.DisplayInfoProto.NAME; 24 25 import android.content.res.CompatibilityInfo; 26 import android.content.res.Configuration; 27 import android.graphics.Rect; 28 import android.os.Parcel; 29 import android.os.Parcelable; 30 import android.util.ArraySet; 31 import android.util.DisplayMetrics; 32 import android.util.proto.ProtoOutputStream; 33 34 import java.util.Arrays; 35 import java.util.Objects; 36 37 /** 38 * Describes the characteristics of a particular logical display. 39 * @hide 40 */ 41 public final class DisplayInfo implements Parcelable { 42 /** 43 * The surface flinger layer stack associated with this logical display. 44 */ 45 public int layerStack; 46 47 /** 48 * Display flags. 49 */ 50 public int flags; 51 52 /** 53 * Display type. 54 */ 55 public int type; 56 57 /** 58 * Display address, or null if none. 59 * Interpretation varies by display type. 60 */ 61 public String address; 62 63 /** 64 * The human-readable name of the display. 65 */ 66 public String name; 67 68 /** 69 * Unique identifier for the display. Shouldn't be displayed to the user. 70 */ 71 public String uniqueId; 72 73 /** 74 * The width of the portion of the display that is available to applications, in pixels. 75 * Represents the size of the display minus any system decorations. 76 */ 77 public int appWidth; 78 79 /** 80 * The height of the portion of the display that is available to applications, in pixels. 81 * Represents the size of the display minus any system decorations. 82 */ 83 public int appHeight; 84 85 /** 86 * The smallest value of {@link #appWidth} that an application is likely to encounter, 87 * in pixels, excepting cases where the width may be even smaller due to the presence 88 * of a soft keyboard, for example. 89 */ 90 public int smallestNominalAppWidth; 91 92 /** 93 * The smallest value of {@link #appHeight} that an application is likely to encounter, 94 * in pixels, excepting cases where the height may be even smaller due to the presence 95 * of a soft keyboard, for example. 96 */ 97 public int smallestNominalAppHeight; 98 99 /** 100 * The largest value of {@link #appWidth} that an application is likely to encounter, 101 * in pixels, excepting cases where the width may be even larger due to system decorations 102 * such as the status bar being hidden, for example. 103 */ 104 public int largestNominalAppWidth; 105 106 /** 107 * The largest value of {@link #appHeight} that an application is likely to encounter, 108 * in pixels, excepting cases where the height may be even larger due to system decorations 109 * such as the status bar being hidden, for example. 110 */ 111 public int largestNominalAppHeight; 112 113 /** 114 * The logical width of the display, in pixels. 115 * Represents the usable size of the display which may be smaller than the 116 * physical size when the system is emulating a smaller display. 117 */ 118 public int logicalWidth; 119 120 /** 121 * The logical height of the display, in pixels. 122 * Represents the usable size of the display which may be smaller than the 123 * physical size when the system is emulating a smaller display. 124 */ 125 public int logicalHeight; 126 127 /** 128 * @hide 129 * Number of overscan pixels on the left side of the display. 130 */ 131 public int overscanLeft; 132 133 /** 134 * @hide 135 * Number of overscan pixels on the top side of the display. 136 */ 137 public int overscanTop; 138 139 /** 140 * @hide 141 * Number of overscan pixels on the right side of the display. 142 */ 143 public int overscanRight; 144 145 /** 146 * @hide 147 * Number of overscan pixels on the bottom side of the display. 148 */ 149 public int overscanBottom; 150 151 /** 152 * The {@link DisplayCutout} if present, otherwise {@code null}. 153 * 154 * @hide 155 */ 156 public DisplayCutout displayCutout; 157 158 /** 159 * The rotation of the display relative to its natural orientation. 160 * May be one of {@link android.view.Surface#ROTATION_0}, 161 * {@link android.view.Surface#ROTATION_90}, {@link android.view.Surface#ROTATION_180}, 162 * {@link android.view.Surface#ROTATION_270}. 163 * <p> 164 * The value of this field is indeterminate if the logical display is presented on 165 * more than one physical display. 166 * </p> 167 */ 168 @Surface.Rotation 169 public int rotation; 170 171 /** 172 * The active display mode. 173 */ 174 public int modeId; 175 176 /** 177 * The default display mode. 178 */ 179 public int defaultModeId; 180 181 /** 182 * The supported modes of this display. 183 */ 184 public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY; 185 186 /** The active color mode. */ 187 public int colorMode; 188 189 /** The list of supported color modes */ 190 public int[] supportedColorModes = { Display.COLOR_MODE_DEFAULT }; 191 192 /** The display's HDR capabilities */ 193 public Display.HdrCapabilities hdrCapabilities; 194 195 /** 196 * The logical display density which is the basis for density-independent 197 * pixels. 198 */ 199 public int logicalDensityDpi; 200 201 /** 202 * The exact physical pixels per inch of the screen in the X dimension. 203 * <p> 204 * The value of this field is indeterminate if the logical display is presented on 205 * more than one physical display. 206 * </p> 207 */ 208 public float physicalXDpi; 209 210 /** 211 * The exact physical pixels per inch of the screen in the Y dimension. 212 * <p> 213 * The value of this field is indeterminate if the logical display is presented on 214 * more than one physical display. 215 * </p> 216 */ 217 public float physicalYDpi; 218 219 /** 220 * This is a positive value indicating the phase offset of the VSYNC events provided by 221 * Choreographer relative to the display refresh. For example, if Choreographer reports 222 * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos). 223 */ 224 public long appVsyncOffsetNanos; 225 226 /** 227 * This is how far in advance a buffer must be queued for presentation at 228 * a given time. If you want a buffer to appear on the screen at 229 * time N, you must submit the buffer before (N - bufferDeadlineNanos). 230 */ 231 public long presentationDeadlineNanos; 232 233 /** 234 * The state of the display, such as {@link android.view.Display#STATE_ON}. 235 */ 236 public int state; 237 238 /** 239 * The UID of the application that owns this display, or zero if it is owned by the system. 240 * <p> 241 * If the display is private, then only the owner can use it. 242 * </p> 243 */ 244 public int ownerUid; 245 246 /** 247 * The package name of the application that owns this display, or null if it is 248 * owned by the system. 249 * <p> 250 * If the display is private, then only the owner can use it. 251 * </p> 252 */ 253 public String ownerPackageName; 254 255 /** 256 * @hide 257 * Get current remove mode of the display - what actions should be performed with the display's 258 * content when it is removed. 259 * 260 * @see Display#getRemoveMode() 261 */ 262 public int removeMode = Display.REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY; 263 264 public static final Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() { 265 @Override 266 public DisplayInfo createFromParcel(Parcel source) { 267 return new DisplayInfo(source); 268 } 269 270 @Override 271 public DisplayInfo[] newArray(int size) { 272 return new DisplayInfo[size]; 273 } 274 }; 275 DisplayInfo()276 public DisplayInfo() { 277 } 278 DisplayInfo(DisplayInfo other)279 public DisplayInfo(DisplayInfo other) { 280 copyFrom(other); 281 } 282 DisplayInfo(Parcel source)283 private DisplayInfo(Parcel source) { 284 readFromParcel(source); 285 } 286 287 @Override equals(Object o)288 public boolean equals(Object o) { 289 return o instanceof DisplayInfo && equals((DisplayInfo)o); 290 } 291 equals(DisplayInfo other)292 public boolean equals(DisplayInfo other) { 293 return other != null 294 && layerStack == other.layerStack 295 && flags == other.flags 296 && type == other.type 297 && Objects.equals(address, other.address) 298 && Objects.equals(uniqueId, other.uniqueId) 299 && appWidth == other.appWidth 300 && appHeight == other.appHeight 301 && smallestNominalAppWidth == other.smallestNominalAppWidth 302 && smallestNominalAppHeight == other.smallestNominalAppHeight 303 && largestNominalAppWidth == other.largestNominalAppWidth 304 && largestNominalAppHeight == other.largestNominalAppHeight 305 && logicalWidth == other.logicalWidth 306 && logicalHeight == other.logicalHeight 307 && overscanLeft == other.overscanLeft 308 && overscanTop == other.overscanTop 309 && overscanRight == other.overscanRight 310 && overscanBottom == other.overscanBottom 311 && Objects.equals(displayCutout, other.displayCutout) 312 && rotation == other.rotation 313 && modeId == other.modeId 314 && defaultModeId == other.defaultModeId 315 && colorMode == other.colorMode 316 && Arrays.equals(supportedColorModes, other.supportedColorModes) 317 && Objects.equals(hdrCapabilities, other.hdrCapabilities) 318 && logicalDensityDpi == other.logicalDensityDpi 319 && physicalXDpi == other.physicalXDpi 320 && physicalYDpi == other.physicalYDpi 321 && appVsyncOffsetNanos == other.appVsyncOffsetNanos 322 && presentationDeadlineNanos == other.presentationDeadlineNanos 323 && state == other.state 324 && ownerUid == other.ownerUid 325 && Objects.equals(ownerPackageName, other.ownerPackageName) 326 && removeMode == other.removeMode; 327 } 328 329 @Override hashCode()330 public int hashCode() { 331 return 0; // don't care 332 } 333 copyFrom(DisplayInfo other)334 public void copyFrom(DisplayInfo other) { 335 layerStack = other.layerStack; 336 flags = other.flags; 337 type = other.type; 338 address = other.address; 339 name = other.name; 340 uniqueId = other.uniqueId; 341 appWidth = other.appWidth; 342 appHeight = other.appHeight; 343 smallestNominalAppWidth = other.smallestNominalAppWidth; 344 smallestNominalAppHeight = other.smallestNominalAppHeight; 345 largestNominalAppWidth = other.largestNominalAppWidth; 346 largestNominalAppHeight = other.largestNominalAppHeight; 347 logicalWidth = other.logicalWidth; 348 logicalHeight = other.logicalHeight; 349 overscanLeft = other.overscanLeft; 350 overscanTop = other.overscanTop; 351 overscanRight = other.overscanRight; 352 overscanBottom = other.overscanBottom; 353 displayCutout = other.displayCutout; 354 rotation = other.rotation; 355 modeId = other.modeId; 356 defaultModeId = other.defaultModeId; 357 supportedModes = Arrays.copyOf(other.supportedModes, other.supportedModes.length); 358 colorMode = other.colorMode; 359 supportedColorModes = Arrays.copyOf( 360 other.supportedColorModes, other.supportedColorModes.length); 361 hdrCapabilities = other.hdrCapabilities; 362 logicalDensityDpi = other.logicalDensityDpi; 363 physicalXDpi = other.physicalXDpi; 364 physicalYDpi = other.physicalYDpi; 365 appVsyncOffsetNanos = other.appVsyncOffsetNanos; 366 presentationDeadlineNanos = other.presentationDeadlineNanos; 367 state = other.state; 368 ownerUid = other.ownerUid; 369 ownerPackageName = other.ownerPackageName; 370 removeMode = other.removeMode; 371 } 372 readFromParcel(Parcel source)373 public void readFromParcel(Parcel source) { 374 layerStack = source.readInt(); 375 flags = source.readInt(); 376 type = source.readInt(); 377 address = source.readString(); 378 name = source.readString(); 379 appWidth = source.readInt(); 380 appHeight = source.readInt(); 381 smallestNominalAppWidth = source.readInt(); 382 smallestNominalAppHeight = source.readInt(); 383 largestNominalAppWidth = source.readInt(); 384 largestNominalAppHeight = source.readInt(); 385 logicalWidth = source.readInt(); 386 logicalHeight = source.readInt(); 387 overscanLeft = source.readInt(); 388 overscanTop = source.readInt(); 389 overscanRight = source.readInt(); 390 overscanBottom = source.readInt(); 391 displayCutout = DisplayCutout.ParcelableWrapper.readCutoutFromParcel(source); 392 rotation = source.readInt(); 393 modeId = source.readInt(); 394 defaultModeId = source.readInt(); 395 int nModes = source.readInt(); 396 supportedModes = new Display.Mode[nModes]; 397 for (int i = 0; i < nModes; i++) { 398 supportedModes[i] = Display.Mode.CREATOR.createFromParcel(source); 399 } 400 colorMode = source.readInt(); 401 int nColorModes = source.readInt(); 402 supportedColorModes = new int[nColorModes]; 403 for (int i = 0; i < nColorModes; i++) { 404 supportedColorModes[i] = source.readInt(); 405 } 406 hdrCapabilities = source.readParcelable(null); 407 logicalDensityDpi = source.readInt(); 408 physicalXDpi = source.readFloat(); 409 physicalYDpi = source.readFloat(); 410 appVsyncOffsetNanos = source.readLong(); 411 presentationDeadlineNanos = source.readLong(); 412 state = source.readInt(); 413 ownerUid = source.readInt(); 414 ownerPackageName = source.readString(); 415 uniqueId = source.readString(); 416 removeMode = source.readInt(); 417 } 418 419 @Override writeToParcel(Parcel dest, int flags)420 public void writeToParcel(Parcel dest, int flags) { 421 dest.writeInt(layerStack); 422 dest.writeInt(this.flags); 423 dest.writeInt(type); 424 dest.writeString(address); 425 dest.writeString(name); 426 dest.writeInt(appWidth); 427 dest.writeInt(appHeight); 428 dest.writeInt(smallestNominalAppWidth); 429 dest.writeInt(smallestNominalAppHeight); 430 dest.writeInt(largestNominalAppWidth); 431 dest.writeInt(largestNominalAppHeight); 432 dest.writeInt(logicalWidth); 433 dest.writeInt(logicalHeight); 434 dest.writeInt(overscanLeft); 435 dest.writeInt(overscanTop); 436 dest.writeInt(overscanRight); 437 dest.writeInt(overscanBottom); 438 DisplayCutout.ParcelableWrapper.writeCutoutToParcel(displayCutout, dest, flags); 439 dest.writeInt(rotation); 440 dest.writeInt(modeId); 441 dest.writeInt(defaultModeId); 442 dest.writeInt(supportedModes.length); 443 for (int i = 0; i < supportedModes.length; i++) { 444 supportedModes[i].writeToParcel(dest, flags); 445 } 446 dest.writeInt(colorMode); 447 dest.writeInt(supportedColorModes.length); 448 for (int i = 0; i < supportedColorModes.length; i++) { 449 dest.writeInt(supportedColorModes[i]); 450 } 451 dest.writeParcelable(hdrCapabilities, flags); 452 dest.writeInt(logicalDensityDpi); 453 dest.writeFloat(physicalXDpi); 454 dest.writeFloat(physicalYDpi); 455 dest.writeLong(appVsyncOffsetNanos); 456 dest.writeLong(presentationDeadlineNanos); 457 dest.writeInt(state); 458 dest.writeInt(ownerUid); 459 dest.writeString(ownerPackageName); 460 dest.writeString(uniqueId); 461 dest.writeInt(removeMode); 462 } 463 464 @Override describeContents()465 public int describeContents() { 466 return 0; 467 } 468 getMode()469 public Display.Mode getMode() { 470 return findMode(modeId); 471 } 472 getDefaultMode()473 public Display.Mode getDefaultMode() { 474 return findMode(defaultModeId); 475 } 476 findMode(int id)477 private Display.Mode findMode(int id) { 478 for (int i = 0; i < supportedModes.length; i++) { 479 if (supportedModes[i].getModeId() == id) { 480 return supportedModes[i]; 481 } 482 } 483 throw new IllegalStateException("Unable to locate mode " + id); 484 } 485 486 /** 487 * Returns the id of the "default" mode with the given refresh rate, or {@code 0} if no suitable 488 * mode could be found. 489 */ findDefaultModeByRefreshRate(float refreshRate)490 public int findDefaultModeByRefreshRate(float refreshRate) { 491 Display.Mode[] modes = supportedModes; 492 Display.Mode defaultMode = getDefaultMode(); 493 for (int i = 0; i < modes.length; i++) { 494 if (modes[i].matches( 495 defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), refreshRate)) { 496 return modes[i].getModeId(); 497 } 498 } 499 return 0; 500 } 501 502 /** 503 * Returns the list of supported refresh rates in the default mode. 504 */ getDefaultRefreshRates()505 public float[] getDefaultRefreshRates() { 506 Display.Mode[] modes = supportedModes; 507 ArraySet<Float> rates = new ArraySet<>(); 508 Display.Mode defaultMode = getDefaultMode(); 509 for (int i = 0; i < modes.length; i++) { 510 Display.Mode mode = modes[i]; 511 if (mode.getPhysicalWidth() == defaultMode.getPhysicalWidth() 512 && mode.getPhysicalHeight() == defaultMode.getPhysicalHeight()) { 513 rates.add(mode.getRefreshRate()); 514 } 515 } 516 float[] result = new float[rates.size()]; 517 int i = 0; 518 for (Float rate : rates) { 519 result[i++] = rate; 520 } 521 return result; 522 } 523 getAppMetrics(DisplayMetrics outMetrics)524 public void getAppMetrics(DisplayMetrics outMetrics) { 525 getAppMetrics(outMetrics, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); 526 } 527 getAppMetrics(DisplayMetrics outMetrics, DisplayAdjustments displayAdjustments)528 public void getAppMetrics(DisplayMetrics outMetrics, DisplayAdjustments displayAdjustments) { 529 getMetricsWithSize(outMetrics, displayAdjustments.getCompatibilityInfo(), 530 displayAdjustments.getConfiguration(), appWidth, appHeight); 531 } 532 getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfo ci, Configuration configuration)533 public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfo ci, 534 Configuration configuration) { 535 getMetricsWithSize(outMetrics, ci, configuration, appWidth, appHeight); 536 } 537 getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo, Configuration configuration)538 public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo, 539 Configuration configuration) { 540 getMetricsWithSize(outMetrics, compatInfo, configuration, logicalWidth, logicalHeight); 541 } 542 getNaturalWidth()543 public int getNaturalWidth() { 544 return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ? 545 logicalWidth : logicalHeight; 546 } 547 getNaturalHeight()548 public int getNaturalHeight() { 549 return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ? 550 logicalHeight : logicalWidth; 551 } 552 isHdr()553 public boolean isHdr() { 554 int[] types = hdrCapabilities != null ? hdrCapabilities.getSupportedHdrTypes() : null; 555 return types != null && types.length > 0; 556 } 557 isWideColorGamut()558 public boolean isWideColorGamut() { 559 for (int colorMode : supportedColorModes) { 560 if (colorMode == Display.COLOR_MODE_DCI_P3 || colorMode > Display.COLOR_MODE_SRGB) { 561 return true; 562 } 563 } 564 return false; 565 } 566 567 /** 568 * Returns true if the specified UID has access to this display. 569 */ hasAccess(int uid)570 public boolean hasAccess(int uid) { 571 return Display.hasAccess(uid, flags, ownerUid); 572 } 573 getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfo compatInfo, Configuration configuration, int width, int height)574 private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfo compatInfo, 575 Configuration configuration, int width, int height) { 576 outMetrics.densityDpi = outMetrics.noncompatDensityDpi = logicalDensityDpi; 577 outMetrics.density = outMetrics.noncompatDensity = 578 logicalDensityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE; 579 outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density; 580 outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi; 581 outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi; 582 583 final Rect appBounds = configuration != null 584 ? configuration.windowConfiguration.getAppBounds() : null; 585 width = appBounds != null ? appBounds.width() : width; 586 height = appBounds != null ? appBounds.height() : height; 587 588 outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width; 589 outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height; 590 591 if (!compatInfo.equals(CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO)) { 592 compatInfo.applyToDisplayMetrics(outMetrics); 593 } 594 } 595 596 // For debugging purposes 597 @Override toString()598 public String toString() { 599 StringBuilder sb = new StringBuilder(); 600 sb.append("DisplayInfo{\""); 601 sb.append(name); 602 sb.append("\", uniqueId \""); 603 sb.append(uniqueId); 604 sb.append("\", app "); 605 sb.append(appWidth); 606 sb.append(" x "); 607 sb.append(appHeight); 608 sb.append(", real "); 609 sb.append(logicalWidth); 610 sb.append(" x "); 611 sb.append(logicalHeight); 612 if (overscanLeft != 0 || overscanTop != 0 || overscanRight != 0 || overscanBottom != 0) { 613 sb.append(", overscan ("); 614 sb.append(overscanLeft); 615 sb.append(","); 616 sb.append(overscanTop); 617 sb.append(","); 618 sb.append(overscanRight); 619 sb.append(","); 620 sb.append(overscanBottom); 621 sb.append(")"); 622 } 623 sb.append(", largest app "); 624 sb.append(largestNominalAppWidth); 625 sb.append(" x "); 626 sb.append(largestNominalAppHeight); 627 sb.append(", smallest app "); 628 sb.append(smallestNominalAppWidth); 629 sb.append(" x "); 630 sb.append(smallestNominalAppHeight); 631 sb.append(", mode "); 632 sb.append(modeId); 633 sb.append(", defaultMode "); 634 sb.append(defaultModeId); 635 sb.append(", modes "); 636 sb.append(Arrays.toString(supportedModes)); 637 sb.append(", colorMode "); 638 sb.append(colorMode); 639 sb.append(", supportedColorModes "); 640 sb.append(Arrays.toString(supportedColorModes)); 641 sb.append(", hdrCapabilities "); 642 sb.append(hdrCapabilities); 643 sb.append(", rotation "); 644 sb.append(rotation); 645 sb.append(", density "); 646 sb.append(logicalDensityDpi); 647 sb.append(" ("); 648 sb.append(physicalXDpi); 649 sb.append(" x "); 650 sb.append(physicalYDpi); 651 sb.append(") dpi, layerStack "); 652 sb.append(layerStack); 653 sb.append(", appVsyncOff "); 654 sb.append(appVsyncOffsetNanos); 655 sb.append(", presDeadline "); 656 sb.append(presentationDeadlineNanos); 657 sb.append(", type "); 658 sb.append(Display.typeToString(type)); 659 if (address != null) { 660 sb.append(", address ").append(address); 661 } 662 sb.append(", state "); 663 sb.append(Display.stateToString(state)); 664 if (ownerUid != 0 || ownerPackageName != null) { 665 sb.append(", owner ").append(ownerPackageName); 666 sb.append(" (uid ").append(ownerUid).append(")"); 667 } 668 sb.append(flagsToString(flags)); 669 sb.append(", removeMode "); 670 sb.append(removeMode); 671 sb.append("}"); 672 return sb.toString(); 673 } 674 675 /** 676 * Write to a protocol buffer output stream. 677 * Protocol buffer message definition at {@link android.view.DisplayInfoProto} 678 * 679 * @param protoOutputStream Stream to write the Rect object to. 680 * @param fieldId Field Id of the DisplayInfoProto as defined in the parent message 681 */ writeToProto(ProtoOutputStream protoOutputStream, long fieldId)682 public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) { 683 final long token = protoOutputStream.start(fieldId); 684 protoOutputStream.write(LOGICAL_WIDTH, logicalWidth); 685 protoOutputStream.write(LOGICAL_HEIGHT, logicalHeight); 686 protoOutputStream.write(APP_WIDTH, appWidth); 687 protoOutputStream.write(APP_HEIGHT, appHeight); 688 protoOutputStream.write(NAME, name); 689 protoOutputStream.end(token); 690 } 691 flagsToString(int flags)692 private static String flagsToString(int flags) { 693 StringBuilder result = new StringBuilder(); 694 if ((flags & Display.FLAG_SECURE) != 0) { 695 result.append(", FLAG_SECURE"); 696 } 697 if ((flags & Display.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) { 698 result.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS"); 699 } 700 if ((flags & Display.FLAG_PRIVATE) != 0) { 701 result.append(", FLAG_PRIVATE"); 702 } 703 if ((flags & Display.FLAG_PRESENTATION) != 0) { 704 result.append(", FLAG_PRESENTATION"); 705 } 706 if ((flags & Display.FLAG_SCALING_DISABLED) != 0) { 707 result.append(", FLAG_SCALING_DISABLED"); 708 } 709 if ((flags & Display.FLAG_ROUND) != 0) { 710 result.append(", FLAG_ROUND"); 711 } 712 return result.toString(); 713 } 714 } 715