1fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown/* 2fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * Copyright (C) 2012 The Android Open Source Project 3fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * 4fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 5fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * you may not use this file except in compliance with the License. 6fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * You may obtain a copy of the License at 7fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * 8fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 9fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * 10fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * Unless required by applicable law or agreed to in writing, software 11fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 12fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * See the License for the specific language governing permissions and 14fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * limitations under the License. 15fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown */ 16fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown 17fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brownpackage com.android.server.display; 18fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown 194ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brownimport android.hardware.display.DisplayViewport; 20cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownimport android.util.DisplayMetrics; 2192130f6407dc51c58b3b941d28a6daf4e04b8d62Jeff Brownimport android.view.Display; 2227f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brownimport android.view.Surface; 23cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 243f145a2f958320766ae9240c7a57debc20d578aaMichael Wrightimport java.util.Arrays; 253f145a2f958320766ae9240c7a57debc20d578aaMichael Wright 264ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownimport libcore.util.Objects; 274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 28fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown/** 29fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * Describes the characteristics of a physical display device. 30fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown */ 314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brownfinal class DisplayDeviceInfo { 324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown /** 334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * Flag: Indicates that this display device should be considered the default display 344ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown * device of the system. 354ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown */ 36bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown public static final int FLAG_DEFAULT_DISPLAY = 1 << 0; 374ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 384ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown /** 3927f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * Flag: Indicates that the orientation of this display device is coupled to the 4027f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * rotation of its associated logical display. 4127f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * <p> 4227f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * This flag should be applied to the default display to indicate that the user 4327f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * physically rotates the display when content is presented in a different orientation. 4427f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * The display manager will apply a coordinate transformation assuming that the 4527f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * physical orientation of the display matches the logical orientation of its content. 4627f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * </p><p> 4727f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * The flag should not be set when the display device is mounted in a fixed orientation 4827f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * such as on a desk. The display manager will apply a coordinate transformation 4927f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * such as a scale and translation to letterbox or pillarbox format under the 5027f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * assumption that the physical orientation of the display is invariant. 5127f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * </p> 524ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown */ 5327f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown public static final int FLAG_ROTATES_WITH_CONTENT = 1 << 1; 54c5df37c285221d0fb113f55b9e78b35632241d3fJeff Brown 55c5df37c285221d0fb113f55b9e78b35632241d3fJeff Brown /** 5677aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown * Flag: Indicates that this display device has secure video output, such as HDCP. 57c5df37c285221d0fb113f55b9e78b35632241d3fJeff Brown */ 5877aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown public static final int FLAG_SECURE = 1 << 2; 5977aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown 6077aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown /** 6177aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown * Flag: Indicates that this display device supports compositing 6277aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown * from gralloc protected buffers. 6377aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown */ 6477aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1 << 3; 654ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 664ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown /** 67a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown * Flag: Indicates that the display device is owned by a particular application 68a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown * and that no other application should be able to interact with it. 69d14c8c9039c0056e1f30ad5d410c8fde20d63df5Jeff Brown * Should typically be used together with {@link #FLAG_OWN_CONTENT_ONLY}. 70a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown */ 71a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown public static final int FLAG_PRIVATE = 1 << 4; 72a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown 73a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown /** 74a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown * Flag: Indicates that the display device is not blanked automatically by 75a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown * the power manager. 76a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown */ 77a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown public static final int FLAG_NEVER_BLANK = 1 << 5; 78a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown 79a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown /** 807d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown * Flag: Indicates that the display is suitable for presentations. 817d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown */ 827d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown public static final int FLAG_PRESENTATION = 1 << 6; 837d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown 847d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown /** 85d14c8c9039c0056e1f30ad5d410c8fde20d63df5Jeff Brown * Flag: Only show this display's own content; do not mirror 86d14c8c9039c0056e1f30ad5d410c8fde20d63df5Jeff Brown * the content of another display. 87d14c8c9039c0056e1f30ad5d410c8fde20d63df5Jeff Brown */ 88d14c8c9039c0056e1f30ad5d410c8fde20d63df5Jeff Brown public static final int FLAG_OWN_CONTENT_ONLY = 1 << 7; 89d14c8c9039c0056e1f30ad5d410c8fde20d63df5Jeff Brown 90d14c8c9039c0056e1f30ad5d410c8fde20d63df5Jeff Brown /** 9149e7ff9647e6547c2b852944a5435a05794b9951Adam Powell * Flag: This display device has a round shape. 9249e7ff9647e6547c2b852944a5435a05794b9951Adam Powell */ 9349e7ff9647e6547c2b852944a5435a05794b9951Adam Powell public static final int FLAG_ROUND = 1 << 8; 9449e7ff9647e6547c2b852944a5435a05794b9951Adam Powell 9549e7ff9647e6547c2b852944a5435a05794b9951Adam Powell /** 96fc8f82bc6b587bddd2aeaddc54c1ea3f598bb9c3Andrii Kulian * Flag: This display can show its content when non-secure keyguard is shown. 97fc8f82bc6b587bddd2aeaddc54c1ea3f598bb9c3Andrii Kulian */ 987211d2eba8e02b5e7462313798fc25c0bd36ab2dAndrii Kulian public static final int FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 1 << 9; 99fc8f82bc6b587bddd2aeaddc54c1ea3f598bb9c3Andrii Kulian 100fc8f82bc6b587bddd2aeaddc54c1ea3f598bb9c3Andrii Kulian /** 101d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown * Touch attachment: Display does not receive touch. 102d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown */ 103d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown public static final int TOUCH_NONE = 0; 104d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown 105d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown /** 106d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown * Touch attachment: Touch input is via the internal interface. 107d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown */ 108d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown public static final int TOUCH_INTERNAL = 1; 109d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown 110d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown /** 111d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown * Touch attachment: Touch input is via an external interface, such as USB. 112d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown */ 113d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown public static final int TOUCH_EXTERNAL = 2; 114d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown 115d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown /** 116b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon * Touch attachment: Touch input is via an input device matching {@link VirtualDisplay}'s 117b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon * uniqueId. 118b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon * @hide 119b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon */ 120b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon public static final int TOUCH_VIRTUAL = 3; 121b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon 122b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon /** 12310acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown * Diff result: The {@link #state} fields differ. 12410acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown */ 12510acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown public static final int DIFF_STATE = 1 << 0; 12610acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown 12710acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown /** 12810acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown * Diff result: Other fields differ. 12910acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown */ 13010acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown public static final int DIFF_OTHER = 1 << 1; 13110acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown 13210acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown /** 1331c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright * Diff result: The color mode fields differ. 1341c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright */ 1351c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright public static final int DIFF_COLOR_MODE = 1 << 2; 1361c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright 1371c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright /** 138361ca21acc0831a9f8bbb259bb30218c252a2aa0Wale Ogunwale * Gets the name of the display device, which may be derived from EDID or 139361ca21acc0831a9f8bbb259bb30218c252a2aa0Wale Ogunwale * other sources. The name may be localized and displayed to the user. 140848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown */ 141848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown public String name; 142848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown 143848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown /** 144361ca21acc0831a9f8bbb259bb30218c252a2aa0Wale Ogunwale * Unique Id of display device. 145361ca21acc0831a9f8bbb259bb30218c252a2aa0Wale Ogunwale */ 146361ca21acc0831a9f8bbb259bb30218c252a2aa0Wale Ogunwale public String uniqueId; 147361ca21acc0831a9f8bbb259bb30218c252a2aa0Wale Ogunwale 148361ca21acc0831a9f8bbb259bb30218c252a2aa0Wale Ogunwale /** 149fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * The width of the display in its natural orientation, in pixels. 150fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * This value is not affected by display rotation. 151fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown */ 152fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown public int width; 153fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown 154fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown /** 155fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * The height of the display in its natural orientation, in pixels. 156fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown * This value is not affected by display rotation. 157fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown */ 158fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown public int height; 159fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown 160cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown /** 161b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand * The active mode of the display. 162cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown */ 163b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand public int modeId; 164cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 165cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown /** 166b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand * The default mode of the display. 1673f145a2f958320766ae9240c7a57debc20d578aaMichael Wright */ 168b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand public int defaultModeId; 169b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand 170b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand /** 171b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand * The supported modes of the display. 172b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand */ 173b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY; 1743f145a2f958320766ae9240c7a57debc20d578aaMichael Wright 1751c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright /** The active color mode of the display */ 1761c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright public int colorMode; 17758e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright 1781c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright /** The supported color modes of the display */ 1791c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright public int[] supportedColorModes = { Display.COLOR_MODE_DEFAULT }; 18058e829f71d2c525309e5bb5a1c02dc64397df221Michael Wright 1813f145a2f958320766ae9240c7a57debc20d578aaMichael Wright /** 1829ff94c0251722c44eece7c3561b4ed36b286d4a8Michael Wright * The HDR capabilities this display claims to support. 1839ff94c0251722c44eece7c3561b4ed36b286d4a8Michael Wright */ 1849ff94c0251722c44eece7c3561b4ed36b286d4a8Michael Wright public Display.HdrCapabilities hdrCapabilities; 1859ff94c0251722c44eece7c3561b4ed36b286d4a8Michael Wright 1869ff94c0251722c44eece7c3561b4ed36b286d4a8Michael Wright /** 187cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * The nominal apparent density of the display in DPI used for layout calculations. 188cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * This density is sensitive to the viewing distance. A big TV and a tablet may have 189cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * the same apparent density even though the pixels on the TV are much bigger than 190cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * those on the tablet. 191cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown */ 192908aecc3a63c5520d5b11da14a9383f885b7d126Dianne Hackborn public int densityDpi; 193cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 194cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown /** 195cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * The physical density of the display in DPI in the X direction. 196cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * This density should specify the physical size of each pixel. 197cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown */ 198fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown public float xDpi; 199cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 200cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown /** 201cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * The physical density of the display in DPI in the X direction. 202cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * This density should specify the physical size of each pixel. 203cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown */ 204fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown public float yDpi; 205fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown 206cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown /** 207e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden * This is a positive value indicating the phase offset of the VSYNC events provided by 208e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden * Choreographer relative to the display refresh. For example, if Choreographer reports 209e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos). 210e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden */ 211e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden public long appVsyncOffsetNanos; 212e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden 213e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden /** 214e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden * This is how far in advance a buffer must be queued for presentation at 215e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden * a given time. If you want a buffer to appear on the screen at 216e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden * time N, you must submit the buffer before (N - bufferDeadlineNanos). 217e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden */ 218e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden public long presentationDeadlineNanos; 219e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden 220e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden /** 221cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown * Display flags. 222cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown */ 223bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown public int flags; 224bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 225d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown /** 226d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown * The touch attachment, per {@link DisplayViewport#touch}. 227d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown */ 228d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown public int touch; 229d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown 23027f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown /** 23127f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * The additional rotation to apply to all content presented on the display device 23227f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * relative to its physical coordinate system. Default is {@link Surface#ROTATION_0}. 23327f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * <p> 23427f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * This field can be used to compensate for the fact that the display has been 23527f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * physically rotated relative to its natural orientation such as an HDMI monitor 23627f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * that has been mounted sideways to appear to be portrait rather than landscape. 23727f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown * </p> 23827f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown */ 23927f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown public int rotation = Surface.ROTATION_0; 24027f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown 24192130f6407dc51c58b3b941d28a6daf4e04b8d62Jeff Brown /** 24292130f6407dc51c58b3b941d28a6daf4e04b8d62Jeff Brown * Display type. 24392130f6407dc51c58b3b941d28a6daf4e04b8d62Jeff Brown */ 24492130f6407dc51c58b3b941d28a6daf4e04b8d62Jeff Brown public int type; 24592130f6407dc51c58b3b941d28a6daf4e04b8d62Jeff Brown 24692130f6407dc51c58b3b941d28a6daf4e04b8d62Jeff Brown /** 24792130f6407dc51c58b3b941d28a6daf4e04b8d62Jeff Brown * Display address, or null if none. 24892130f6407dc51c58b3b941d28a6daf4e04b8d62Jeff Brown * Interpretation varies by display type. 24992130f6407dc51c58b3b941d28a6daf4e04b8d62Jeff Brown */ 25092130f6407dc51c58b3b941d28a6daf4e04b8d62Jeff Brown public String address; 25192130f6407dc51c58b3b941d28a6daf4e04b8d62Jeff Brown 252a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown /** 253037c33eae74bee2774897d969d48947f9abe254fJeff Brown * Display state. 254037c33eae74bee2774897d969d48947f9abe254fJeff Brown */ 255037c33eae74bee2774897d969d48947f9abe254fJeff Brown public int state = Display.STATE_ON; 256037c33eae74bee2774897d969d48947f9abe254fJeff Brown 257037c33eae74bee2774897d969d48947f9abe254fJeff Brown /** 258a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown * The UID of the application that owns this display, or zero if it is owned by the system. 259a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown * <p> 260a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown * If the display is private, then only the owner can use it. 261a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown * </p> 262a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown */ 263a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown public int ownerUid; 264a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown 265a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown /** 266a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown * The package name of the application that owns this display, or null if it is 267a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown * owned by the system. 268a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown * <p> 269a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown * If the display is private, then only the owner can use it. 270a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown * </p> 271a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown */ 272a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown public String ownerPackageName; 273a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown 274cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown public void setAssumedDensityForExternalDisplay(int width, int height) { 275cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080; 276cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown // Technically, these values should be smaller than the apparent density 277cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown // but we don't know the physical size of the display. 278cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown xDpi = densityDpi; 279cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown yDpi = densityDpi; 280cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown } 281cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown 2824ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 2834ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public boolean equals(Object o) { 2844ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return o instanceof DisplayDeviceInfo && equals((DisplayDeviceInfo)o); 2854ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 2864ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 2874ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public boolean equals(DisplayDeviceInfo other) { 28810acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown return other != null && diff(other) == 0; 28910acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown } 29010acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown 29110acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown /** 29210acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown * Computes the difference between display device infos. 29310acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown * Assumes other is not null. 29410acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown */ 29510acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown public int diff(DisplayDeviceInfo other) { 29610acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown int diff = 0; 29710acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown if (state != other.state) { 29810acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown diff |= DIFF_STATE; 29910acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown } 3001c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright if (colorMode != other.colorMode) { 3011c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright diff |= DIFF_COLOR_MODE; 3021c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright } 30310acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown if (!Objects.equal(name, other.name) 30410acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown || !Objects.equal(uniqueId, other.uniqueId) 30510acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown || width != other.width 30610acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown || height != other.height 307b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand || modeId != other.modeId 308b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand || defaultModeId != other.defaultModeId 309b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand || !Arrays.equals(supportedModes, other.supportedModes) 3101c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright || !Arrays.equals(supportedColorModes, other.supportedColorModes) 3119ff94c0251722c44eece7c3561b4ed36b286d4a8Michael Wright || !Objects.equal(hdrCapabilities, other.hdrCapabilities) 31210acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown || densityDpi != other.densityDpi 31310acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown || xDpi != other.xDpi 31410acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown || yDpi != other.yDpi 31510acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown || appVsyncOffsetNanos != other.appVsyncOffsetNanos 31610acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown || presentationDeadlineNanos != other.presentationDeadlineNanos 31710acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown || flags != other.flags 31810acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown || touch != other.touch 31910acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown || rotation != other.rotation 32010acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown || type != other.type 32110acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown || !Objects.equal(address, other.address) 32210acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown || ownerUid != other.ownerUid 32310acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown || !Objects.equal(ownerPackageName, other.ownerPackageName)) { 32410acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown diff |= DIFF_OTHER; 32510acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown } 32610acf6d3efde60977d2d2e82b90c53d722d9d357Jeff Brown return diff; 3274ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3284ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 3294ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown @Override 3304ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown public int hashCode() { 3314ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown return 0; // don't care 3324ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown } 3334ed8fe75e1dde1a2b9576f3862aecc5a572c56b5Jeff Brown 334fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown public void copyFrom(DisplayDeviceInfo other) { 335848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown name = other.name; 336361ca21acc0831a9f8bbb259bb30218c252a2aa0Wale Ogunwale uniqueId = other.uniqueId; 337fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown width = other.width; 338fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown height = other.height; 339b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand modeId = other.modeId; 340b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand defaultModeId = other.defaultModeId; 341b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand supportedModes = other.supportedModes; 3421c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright colorMode = other.colorMode; 3431c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright supportedColorModes = other.supportedColorModes; 3449ff94c0251722c44eece7c3561b4ed36b286d4a8Michael Wright hdrCapabilities = other.hdrCapabilities; 345908aecc3a63c5520d5b11da14a9383f885b7d126Dianne Hackborn densityDpi = other.densityDpi; 346fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown xDpi = other.xDpi; 347fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown yDpi = other.yDpi; 348e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden appVsyncOffsetNanos = other.appVsyncOffsetNanos; 349e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden presentationDeadlineNanos = other.presentationDeadlineNanos; 350bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown flags = other.flags; 351d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown touch = other.touch; 35227f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown rotation = other.rotation; 35392130f6407dc51c58b3b941d28a6daf4e04b8d62Jeff Brown type = other.type; 35492130f6407dc51c58b3b941d28a6daf4e04b8d62Jeff Brown address = other.address; 355037c33eae74bee2774897d969d48947f9abe254fJeff Brown state = other.state; 356a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown ownerUid = other.ownerUid; 357a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown ownerPackageName = other.ownerPackageName; 358fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown } 359fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown 360848c2dc93b6795e171f3dd6f64ea0be65e2762caJeff Brown // For debugging purposes 361fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown @Override 362fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown public String toString() { 363a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown StringBuilder sb = new StringBuilder(); 364a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown sb.append("DisplayDeviceInfo{\""); 365361ca21acc0831a9f8bbb259bb30218c252a2aa0Wale Ogunwale sb.append(name).append("\": uniqueId=\"").append(uniqueId).append("\", "); 366361ca21acc0831a9f8bbb259bb30218c252a2aa0Wale Ogunwale sb.append(width).append(" x ").append(height); 367b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand sb.append(", modeId ").append(modeId); 368b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand sb.append(", defaultModeId ").append(defaultModeId); 369b3b9eb3cfc5b3b3609a5d01258315798b38a5cf9P.Y. Laligand sb.append(", supportedModes ").append(Arrays.toString(supportedModes)); 3701c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright sb.append(", colorMode ").append(colorMode); 3711c9977b762b4bac46b4470f04c898bfd17da5d90Michael Wright sb.append(", supportedColorModes ").append(Arrays.toString(supportedColorModes)); 3729ff94c0251722c44eece7c3561b4ed36b286d4a8Michael Wright sb.append(", HdrCapabilities ").append(hdrCapabilities); 3733f145a2f958320766ae9240c7a57debc20d578aaMichael Wright sb.append(", density ").append(densityDpi); 374a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi"); 375e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden sb.append(", appVsyncOff ").append(appVsyncOffsetNanos); 376e8b1aeb51e1e5da64f1d4fd40f2ee1e815886fe5Andy McFadden sb.append(", presDeadline ").append(presentationDeadlineNanos); 377a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown sb.append(", touch ").append(touchToString(touch)); 378a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown sb.append(", rotation ").append(rotation); 379a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown sb.append(", type ").append(Display.typeToString(type)); 380a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown if (address != null) { 381a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown sb.append(", address ").append(address); 382a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown } 383037c33eae74bee2774897d969d48947f9abe254fJeff Brown sb.append(", state ").append(Display.stateToString(state)); 384a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown if (ownerUid != 0 || ownerPackageName != null) { 385a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown sb.append(", owner ").append(ownerPackageName); 386a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown sb.append(" (uid ").append(ownerUid).append(")"); 387a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown } 388a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown sb.append(flagsToString(flags)); 389a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown sb.append("}"); 390a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown return sb.toString(); 391d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown } 392d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown 393d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown private static String touchToString(int touch) { 394d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown switch (touch) { 395d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown case TOUCH_NONE: 396d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown return "NONE"; 397d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown case TOUCH_INTERNAL: 398d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown return "INTERNAL"; 399d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown case TOUCH_EXTERNAL: 400d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown return "EXTERNAL"; 401b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon case TOUCH_VIRTUAL: 402b0608636a29bcec8ecb4391cd50f29f68b3e7e81Santos Cordon return "VIRTUAL"; 403d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown default: 404d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown return Integer.toString(touch); 405d728bf514f257670fcb9aa22c6eaf97626072c93Jeff Brown } 406bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 407bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown 408bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown private static String flagsToString(int flags) { 409bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown StringBuilder msg = new StringBuilder(); 410bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown if ((flags & FLAG_DEFAULT_DISPLAY) != 0) { 411bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown msg.append(", FLAG_DEFAULT_DISPLAY"); 412bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 41327f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown if ((flags & FLAG_ROTATES_WITH_CONTENT) != 0) { 41427f1d674bf9fb53af7facdcb746912e036d5bf75Jeff Brown msg.append(", FLAG_ROTATES_WITH_CONTENT"); 415c5df37c285221d0fb113f55b9e78b35632241d3fJeff Brown } 41677aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown if ((flags & FLAG_SECURE) != 0) { 41777aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown msg.append(", FLAG_SECURE"); 41877aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown } 41977aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown if ((flags & FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) { 42077aebfdbae489c3712ae3f9bca29d01fb1f09dc2Jeff Brown msg.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS"); 421bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown } 422a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown if ((flags & FLAG_PRIVATE) != 0) { 423a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown msg.append(", FLAG_PRIVATE"); 424a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown } 425a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown if ((flags & FLAG_NEVER_BLANK) != 0) { 426a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown msg.append(", FLAG_NEVER_BLANK"); 427a506a6ec94863a35acca9feb165db76ddac3892cJeff Brown } 4287d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown if ((flags & FLAG_PRESENTATION) != 0) { 4297d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown msg.append(", FLAG_PRESENTATION"); 4307d00affce6e25b22fd8fc135933b3bf6b547a0dcJeff Brown } 431d14c8c9039c0056e1f30ad5d410c8fde20d63df5Jeff Brown if ((flags & FLAG_OWN_CONTENT_ONLY) != 0) { 432d14c8c9039c0056e1f30ad5d410c8fde20d63df5Jeff Brown msg.append(", FLAG_OWN_CONTENT_ONLY"); 433d14c8c9039c0056e1f30ad5d410c8fde20d63df5Jeff Brown } 43449e7ff9647e6547c2b852944a5435a05794b9951Adam Powell if ((flags & FLAG_ROUND) != 0) { 43549e7ff9647e6547c2b852944a5435a05794b9951Adam Powell msg.append(", FLAG_ROUND"); 43649e7ff9647e6547c2b852944a5435a05794b9951Adam Powell } 4377211d2eba8e02b5e7462313798fc25c0bd36ab2dAndrii Kulian if ((flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) { 4387211d2eba8e02b5e7462313798fc25c0bd36ab2dAndrii Kulian msg.append(", FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD"); 439fc8f82bc6b587bddd2aeaddc54c1ea3f598bb9c3Andrii Kulian } 440bd6e1500aedc5461e832f69e76341bff0e55fa2bJeff Brown return msg.toString(); 441fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown } 442fa25bf5382467b1018bd9af7f1cb30a23d7d59f7Jeff Brown} 443