Pipes Feed Preview: Android Developers Blog

  1. The Second Beta of Android 17

    Thu, 26 Feb 2026 21:08:00 -0000

    <meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrvAWzUDf-9b2pw-fuqR8566QCiIbx_or66Dm4VwsKCaNdt1ids-40mTs7l-LtWcs08Q3MeA1jZV6qn45jvfUQmXSNeVnz6lGgrWWJshGzWvvffbW6anqvLxKFFcChiJzlD6jXorHkY5dNVfQAYoodi9u9I_dGkRepRqWP_e0dthZwGhJSIBy5CyeEleo/s1024/android-17-stage2-something@2x.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></meta> <img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrvAWzUDf-9b2pw-fuqR8566QCiIbx_or66Dm4VwsKCaNdt1ids-40mTs7l-LtWcs08Q3MeA1jZV6qn45jvfUQmXSNeVnz6lGgrWWJshGzWvvffbW6anqvLxKFFcChiJzlD6jXorHkY5dNVfQAYoodi9u9I_dGkRepRqWP_e0dthZwGhJSIBy5CyeEleo/s1024/android-17-stage2-something@2x.png" style="display: none;" /> <name content="IMG" twitter:image=""><p></p><div class="separator" style="clear: both; text-align: justify;"><em style="text-align: left;">Posted by Matthew McCullough, VP Product Management, Android Developer</em></div><p></p></name> <p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrvAWzUDf-9b2pw-fuqR8566QCiIbx_or66Dm4VwsKCaNdt1ids-40mTs7l-LtWcs08Q3MeA1jZV6qn45jvfUQmXSNeVnz6lGgrWWJshGzWvvffbW6anqvLxKFFcChiJzlD6jXorHkY5dNVfQAYoodi9u9I_dGkRepRqWP_e0dthZwGhJSIBy5CyeEleo/s1024/android-17-stage2-something@2x.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="1024" data-original-width="1024" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrvAWzUDf-9b2pw-fuqR8566QCiIbx_or66Dm4VwsKCaNdt1ids-40mTs7l-LtWcs08Q3MeA1jZV6qn45jvfUQmXSNeVnz6lGgrWWJshGzWvvffbW6anqvLxKFFcChiJzlD6jXorHkY5dNVfQAYoodi9u9I_dGkRepRqWP_e0dthZwGhJSIBy5CyeEleo/s1024/android-17-stage2-something@2x.png" width="200" /></a></div><span style="font-family: inherit;"><div><br /></div><span id="docs-internal-guid-93e65ce5-7fff-b61d-bdb4-8adfcf979cfe"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Today we're releasing the second beta of </span><a href="https://developer.android.com/about/versions/17/" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">Android 17</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, continuing our work to build a platform that prioritizes privacy, security, and refined performance. </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">This update delivers a range of new capabilities, including the EyeDropper API and a privacy-preserving Contacts Picker. We're also adding advanced ranging, cross-device handoff APIs, and more.</span></span></span><br /><br /><span id="docs-internal-guid-e2ab632d-7fff-ed23-83e0-49f5db77ed97"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">This release continues the shift in our release cadence, following this annual major SDK release in Q2 with a minor SDK update.</span></span></span><br /></span><div><br /></div><div style="text-align: left;"><span id="docs-internal-guid-d0833dc4-7fff-8ba2-d4cf-58a43136c26a"><h2 dir="ltr" style="line-height: 1.38; margin-bottom: 4pt; margin-top: 0pt;"><span id="docs-internal-guid-c8350b22-7fff-243d-36e5-c1cdf6df4402" style="font-weight: normal;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: x-large;">User Experience &amp; System UI</span></span></span></h2></span></div><div><span id="docs-internal-guid-070e5329-7fff-7fca-5974-444904f3e34e"><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;">Bubbles</span></span></h3><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Bubbles is a windowing mode feature that offers a new floating UI experience separate from the </span><a href="https://developer.android.com/develop/ui/views/notifications/bubbles" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">messaging bubbles API</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">. Users can create an app bubble on their phone, foldable, or tablet by long-pressing an app icon on the launcher. On large screens, there is a bubble bar as part of the taskbar where users can organize, move between, and move bubbles to and from anchored points on the screen.</span></span></span></div><div><span face="Arial, sans-serif" style="font-size: 11pt; white-space-collapse: preserve;"><br /></span></div><div class="separator" style="clear: both; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin9Mt9tEW87aYzi91Wey3VAosVbha5Vj4EEPJerhyphenhyphenoRpZTeVnVZKNUocFmrivLoCgMB4uwO_BO0Cj8pgTjkolckbiTkZoxMwvHIR15r2OGrJK-hOiYCtru895k2SaY9QeKxleYuQx1cUryGnW46h9dnB54FLbaAUDiUdffBaAb_-HdH78Z8gP8WahATc0/w618-h640/Bubbles.gif" /></div><br /><div><span id="docs-internal-guid-9bcefda6-7fff-36e7-9faa-458a1a05837b"><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">You should follow the </span><a href="https://developer.android.com/develop/ui/compose/layouts/adaptive/support-multi-window-mode" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">guidelines for supporting multi-window mode</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> to ensure your apps work correctly as bubbles.</span></span></p><span style="font-family: inherit;"><br /></span><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">Bubbles aren't yet fully enabled in Beta 2. Look for them in a future build of Android 17.</span></span></p><div><br /></div></span></div><div><span id="docs-internal-guid-86702358-7fff-b5d8-06fc-99dedaacf58b"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: x-large;">EyeDropper API</span></span></span></div><div><br /></div><div><span id="docs-internal-guid-10c7a059-7fff-4572-b16a-a9e3e3e69e86"><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">A new system-level EyeDropper API allows your app to request a color from any pixel on the display without requiring sensitive screen capture permissions.</span></span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><br /></span><span face="Arial, sans-serif" style="font-size: 11pt;"><br /></span></span></p></span><span><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"></span></p></span><div class="separator" style="clear: both; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh93qqDxQ77bC_gAVS6tTHKR38JjKaHxk1dEir5bNCtJ5fBihwVwAXgyIoPJVU4vAs7vR4eeLtB7uMLNUOOWjhz7lk2mYoJPqCsr9yMc04jcai3Rvpxp64M7Og9mZRjqv2IsMosHVNYV_SjUQ1SdxKEX-K04_USaUQb7XRAQF4Q8mSAl0G-Gp9v0yKgUa8/w640-h360/Eyedropper%20Tester.gif" /></div><span><span face="Arial, sans-serif" style="font-size: 11pt;"><br /></span></span><p></p></div><div><pre style="color: #333333; line-height: 16.25px; margin: 0px;"><span style="color: blue;">val</span> eyeDropperLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -&gt; <span style="color: blue;">if</span> (result.resultCode == Activity.RESULT_OK) { <span style="color: blue;">val</span> color = result.data?.getIntExtra(Intent.EXTRA_COLOR, Color.BLACK) <span style="color: green;">// Use the picked color in your app</span> } } <span style="color: blue;">fun</span> launchColorPicker() { <span style="color: blue;">val</span> intent = Intent(Intent.ACTION_OPEN_EYE_DROPPER) eyeDropperLauncher.launch(intent) }</pre></div><div><br /></div><div><span id="docs-internal-guid-6d495a2b-7fff-27af-07ed-97dec011214f"><h3 dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-family: inherit; font-size: large; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Contacts Picker</span></h3><span id="docs-internal-guid-7bfb5c44-7fff-047b-21dc-7571b6280982"><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">A new system-level contacts picker via </span><a href="https://developer.android.com/reference/kotlin/android/provider/ContactsPickerSessionContract.html#ACTION_PICK_CONTACTS:kotlin.String" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">ACTION_PICK_CONTACTS</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> grants temporary, session-based read access to only the specific data fields requested by the user, reducing the need for the broad </span><a href="https://developer.android.com/reference/android/Manifest.permission#READ_CONTACTS" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">READ_CONTACTS</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> permissions. It also allows for selections from the device’s personal or work profiles.</span></span></p><div><span face="&quot;Google Sans Text&quot;, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></div></span></span></div><div><br /></div><div><br /></div><div><div><div class="separator" style="clear: both; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjk_ErNST1mNQUMSBPoM_zvPO1NrnXPdzPLae5RTNFd_SWznb_fBh6vRHS3bBX4ga_RK24nVfuQ-6dFu1CUgA5H-BvBE_zOIjG_VmSaIU0bOtDyQTy672rzVWJpYY8n7NBoGi_bqaaUc2kNe1ydBObVS5WduBy7Yb-e4DGgx7-3fy9TiH7JanTASlxNhuk/w285-h640/android-17-contact-picker.gif" /></div></div><span id="docs-internal-guid-066dd105-7fff-e29b-a7df-69c843751a2c"><div><span style="font-family: inherit; font-size: small; font-weight: normal;"><span face="&quot;Google Sans Text&quot;, sans-serif" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></span></div></span><span><div><span style="font-family: inherit; font-size: small; font-weight: normal;"><span face="&quot;Google Sans Text&quot;, sans-serif" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></span></div><div><span face="&quot;Google Sans Text&quot;, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><pre style="color: #333333; line-height: 16.25px; margin: 0px;"><span style="color: blue;">val</span> contactPicker = rememberLauncherForActivityResult(StartActivityForResult()) { <span style="color: blue;">if</span> (it.resultCode == RESULT_OK) { <span style="color: blue;">val</span> uri = it.data?.data ?: <span style="color: blue;">return</span>@rememberLauncherForActivityResult <span style="color: green;">// Handle result logic</span> processContactPickerResults(uri) } } <span style="color: blue;">val</span> dataFields = arrayListOf(Email.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE) <span style="color: blue;">val</span> intent = Intent(ACTION_PICK_CONTACTS).apply { putStringArrayListExtra(EXTRA_PICK_CONTACTS_REQUESTED_DATA_FIELDS, dataFields) putExtra(EXTRA_ALLOW_MULTIPLE, <span style="color: blue;">true</span>) putExtra(EXTRA_PICK_CONTACTS_SELECTION_LIMIT, 5) } contactPicker.launch(intent)</pre></span></div></span></div><div><br /></div><div><span id="docs-internal-guid-789b084d-7fff-4b53-4f2b-cde8de6034e8"><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;">Easier pointer capture compatibility with touchpads</span></span></h3><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">Previously, touchpads reported events in a very different way from mice when an app had captured the pointer, reporting the locations of fingers on the pad rather than the relative movements that would be reported by a mouse. This made it quite difficult to support touchpads properly in first-person games. Now, by default the system will recognize pointer movement and scrolling gestures when the touchpad is captured, and report them just like mouse events. You can still request the old, detailed finger location data by explicitly requesting capture in the new “absolute” mode. </span></span></p><div><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></div></span></div><div><pre style="color: #333333; line-height: 16.25px; margin: 0px;"><span style="color: green;">// To request the new default relative mode (mouse-like events)</span> <span style="color: green;">// This is the same as requesting with View.POINTER_CAPTURE_MODE_RELATIVE</span> view.requestPointerCapture() <span style="color: green;">// To request the legacy absolute mode (raw touch coordinates)</span> view.requestPointerCapture(View.POINTER_CAPTURE_MODE_ABSOLUTE)</pre></div><div><br /></div><div><br /></div><div><span id="docs-internal-guid-d9d517da-7fff-0ec6-4ebd-76d484dd87a9"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;"><b>Interactive Chooser resting bounds</b></span></span></span></div><div><br /></div><div><span id="docs-internal-guid-8cfa887e-7fff-3271-1b45-c02a7f3d8cb3"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">By calling</span></span><span face="&quot;Google Sans Text&quot;, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><a href="https://developer.android.com/reference/kotlin/android/service/chooser/ChooserSession#getinitialrestingbounds" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">getInitialRestingBounds</span></a><span face="&quot;Google Sans Text&quot;, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">on Android's </span></span><a href="https://developer.android.com/reference/android/service/chooser/ChooserSession" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">ChooserSession</span></a><span face="&quot;Google Sans Text&quot;, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, </span><span face="&quot;Google Sans Text&quot;, sans-serif" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">your app can identify the target position the Chooser occupies after animations and data loading are complete, enabling better UI adjustments.</span></span></div><div><br /></div><div><span id="docs-internal-guid-f6b8da79-7fff-fbb6-a1e8-a9f336cf1322"><h2 dir="ltr" style="line-height: 1.38; margin-bottom: 4pt; margin-top: 0pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: x-large;">Connectivity &amp; Cross-Device</span></span></h2><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;">Cross-device app handoff</span></span></h3><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">A new </span><a href="https://developer.android.com/reference/kotlin/android/app/Activity#sethandoffenabled" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">Handoff API</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> allows you to specify application state to be resumed on another device, such as an Android tablet. When opted in, the system synchronizes state via </span></span><a href="https://developer.android.com/reference/android/companion/CompanionDeviceManager" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">CompanionDeviceManager</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">and displays a handoff suggestion in the launcher of the user's nearby devices. This feature is designed to offer seamless task continuity, enabling users to pick up exactly where they left off in their workflow across their Android ecosystem. Critically, Handoff supports both native app-to-app transitions and app-to-web fallback, providing maximum flexibility and ensuring a complete experience even if the native app is not installed on the receiving device.</span></span></p><br /><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;">Advanced ranging APIs</span></span></h3><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">We are adding support for 2 new ranging technologies -&nbsp;</span></span></p><ol style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="1" dir="ltr" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: decimal; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap-mode: wrap; vertical-align: baseline;">UWB DL-TDOA</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"> which enables apps to use UWB for indoor navigation. This API surface is FIRA (Fine Ranging Consortium) 4.0 DL-TDOA spec compliant and enables privacy preserving indoor navigation&nbsp; (avoiding tracking of the device by the anchor).</span></span></p></li><li aria-level="1" dir="ltr" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: decimal; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap-mode: wrap; vertical-align: baseline;">Proximity Detection</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"> which enables apps to use the new ranging specification being adopted by WFA (WiFi Alliance). This technology provides improved reliability and accuracy compared to existing Wifi Aware based ranging specification.</span></span></p></li></ol><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;">Data plan enhancements</span></span></h3><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">To optimize media quality, your app can now retrieve carrier-allocated maximum data rates for streaming applications using </span></span><a href="https://developer.android.com/reference/kotlin/android/telephony/SubscriptionInfo#getstreamingappmaxdownlinkkbps" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">getStreamingAppMaxDownlinkKbps</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">and </span></span></span><a href="https://developer.android.com/reference/kotlin/android/telephony/SubscriptionInfo#getstreamingappmaxuplinkkbps" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">getStreamingAppMaxUplinkKbps</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">.</span></div><div><br /></div><div><span id="docs-internal-guid-bf27b230-7fff-f0c1-ed8b-8da57155dded"><h2 dir="ltr" style="line-height: 1.2; margin-bottom: 11.25pt; margin-top: 11.25pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: x-large;">Core Functionality, Privacy &amp; Performance</span></span></h2><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;">Local Network Access</span></span></h3><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Android 17 introduces the </span><a href="https://developer.android.com/reference/kotlin/android/Manifest.permission#access_local_network" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">ACCESS_LOCAL_NETWORK</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> runtime permission to protect users from unauthorized local network access. Because this falls under the existing </span><a href="https://developer.android.com/reference/android/Manifest.permission_group#NEARBY_DEVICES" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">NEARBY_DEVICES</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> permission group, users who have already granted other </span><a href="https://developer.android.com/reference/android/Manifest.permission_group#NEARBY_DEVICES" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">NEARBY_DEVICES</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> permissions will not be prompted again. By declaring and requesting this permission, your app can discover and connect to devices on the local area network (LAN), such as smart home devices or casting receivers. This prevents malicious apps from exploiting unrestricted local network access for covert user tracking and fingerprinting. Apps targeting Android 17 or higher will now have two paths to maintain communication with LAN devices: adopt system-mediated, privacy-preserving device pickers to skip the permission prompt, or explicitly request this new permission at runtime to maintain local network communication.</span></span></p><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;">Time zone offset change broadcast</span></span></h3><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Android now provides a reliable broadcast intent, </span><a href="https://developer.android.com/reference/kotlin/android/content/Intent#action_timezone_offset_changed" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">ACTION_TIMEZONE_OFFSET_CHANGED</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, triggered when the system's time zone offset changes, such as during Daylight Saving Time transitions. This complements the existing broadcast intents </span><a href="https://developer.android.com/reference/android/content/Intent#ACTION_TIME_CHANGED" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">ACTION_TIME_CHANGED</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> and </span><a href="https://developer.android.com/reference/android/content/Intent#ACTION_TIMEZONE_CHANGED" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">ACTION_TIMEZONE_CHANGED</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, which are triggered when the Unix timestamp changes and when the time zone ID changes, respectively.</span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></span></p><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">NPU Management and Prioritization</span></span></h3><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span><span style="font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span id="docs-internal-guid-b8525976-7fff-f911-0771-f48c9fc5aa30"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Apps targeting Android 17 that need to directly access the NPU must declare </span><a href="https://developer.android.com/reference/kotlin/android/content/pm/PackageManager#feature_neural_processing_unit" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">FEATURE_NEURAL_PROCESSING_UNIT</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> in their manifest to avoid being blocked from accessing the NPU. This includes apps that use the </span><a href="https://ai.google.dev/edge/litert/next/npu" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">LiteRT NPU delegate</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">, vendor-specific SDKs, as well as the deprecated </span><a href="https://developer.android.com/ndk/guides/neuralnetworks" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">NNAPI</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">.</span></span></span></span></p><div><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></div></span></div><div><span style="white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;"><b>ICU 78 and Unicode 17 support</b></span></span></div><div><span style="font-family: inherit;"><br /></span></div><div><span id="docs-internal-guid-d227fbc1-7fff-f66b-06b5-bcaf59fbfbde"><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span id="docs-internal-guid-55b2d01c-7fff-74f0-7da9-75bb27e935f8"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Core internationalization libraries have been updated to </span><a href="https://blog.unicode.org/2025/10/icu-78-released.html" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">ICU 78</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, expanding support for new scripts, characters, and emoji blocks, and enabling direct formatting of </span><a href="https://developer.android.com/reference/java/time/package-summary" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">time</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> objects.</span></span></span></p><h3 dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;">SMS OTP protection</span></span></h3><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Android is expanding its SMS OTP protection by automatically delaying access to SMS </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">messages with OTP. Previously, the protection was primarily focused on the SMS Retriever format wherein the delivery of messages containing an SMS retriever hash is delayed for most apps for three hours. However, for certain apps like the default SMS app, etc and the app that corresponds to the hash are exempt from this delay. This update extends the protection to all SMS messages with OTP. For most apps, SMS messages containing an OTP will only be accessible after a delay of three hours to help prevent OTP hijacking. The </span></span><a href="https://developer.android.com/reference/android/provider/Telephony.Sms.Intents#SMS_RECEIVED_ACTION" style="font-family: Arial, sans-serif; font-size: 11pt; text-decoration-line: none; white-space-collapse: preserve;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">SMS_RECEIVED_ACTION</span></a><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> broadcast will be withheld and </span><a href="https://developer.android.com/reference/android/provider/Telephony.Sms.html" style="text-decoration-line: none; white-space-collapse: preserve;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">sms provider</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> database queries will be filtered. The SMS message will be available to these apps after the delay. </span></span></p></span><span id="docs-internal-guid-811de5c5-7fff-0cb3-0409-442ddaca9f60"><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;"><b>Delayed access to WebOTP format SMS messages</b></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">If the app has the permission to read SMS messages but is not the intended recipient of the OTP (as determined by domain verification), the WebOTP format SMS message will only be accessible after three hours have elapsed. This change is designed to improve user security by ensuring that only apps associated with the domain mentioned in the message can programmatically read the verification code. This change applies to all apps regardless of their target API level.</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;"><b>Delayed access to standard SMS messages with OTP</b></span></span></p><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">For SMS messages containing an OTP that do not use the WebOTP or SMS Retriever formats, the OTP SMS will only be accessible after three hours for most apps. This change only applies to apps that target Android 17 (API level 37) or higher.</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Certain apps such as the default SMS, assistant app, along with connected device companion apps, etc will be exempt from this delay.</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">All apps that rely on reading SMS messages for OTP extraction should transition to using </span><a href="https://developer.android.com/identity/sms-retriever" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">SMS Retriever</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> or </span><a href="https://developers.google.com/identity/sms-retriever/user-consent/overview" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">SMS User Consent</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> APIs to ensure continued functionality.</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></span></div><div><br /></div><div><span id="docs-internal-guid-cfd276e1-7fff-bfd1-16c3-a647734b3ff0"><h2 dir="ltr" style="line-height: 1.2; margin-bottom: 11.25pt; margin-top: 11.25pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: x-large;">The Android 17 schedule</span></span></h2></span><span><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">We're going to be moving quickly from this Beta to our Platform Stability milestone, targeted for March. At this milestone, we'll deliver final SDK/NDK APIs. From that time forward, your app can target SDK 37 and publish to Google Play to help you complete your testing and collect user feedback in the several months before the general availability of Android 17.</span></span></p><div><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></div></span><div><div class="separator" style="clear: both;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipmOQkqAhGJhJ23cIrQvdMk3HyBlvS9YagV8gHlnAeMVbKUDzuLnR1CpL0gaLUVXJOPlF4hz6Z2c4-_-2EiUSITXg8KNgJjRBYE3GFjLhxMg0LDHYitsfZKuB_-lLEQQI3CEv8mfXlu6aSMOra00kVJdFBtogb3f57XD-q73VSdl6g5l7M82_M5bfeveg/w640-h360/Android%20Release%20Timeline.png" /></div></div></div><div><span id="docs-internal-guid-e7bdc12c-7fff-645f-0d74-58b13ae7dc2c"><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;">A year of releases</span></span></h3><p dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">We plan for Android 17 to continue to get updates in a series of quarterly releases. The upcoming release in Q2 is the only one where we introduce planned app breaking behavior changes. We plan to have a minor SDK release in Q4 with additional APIs and features.</span></span></p><div><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></div><div><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></div><div><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></div></span></div><div><div class="separator" style="clear: both; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0syxWKc8-BAn5IuMcRSbVF2hy_NPcIiBi_XqdS7U5wac7076AT1lZ0FasmnIBSUdqpeIdBnc-r7QvsWTljq5-Gn11LXuAFB7038beGtCf8zhhGk9F1u1OuXNicJ_RgHgd8jeNM1d04lcCRsSGSrBEKW3K_-8kUldiwh5KZ8sP4Ob8vDH4MDApry8aB0Y/w640-h360/Android%20Release%20Timeline%20(1)%20(1).png" /></div><span><span face="Arial, sans-serif"><br /></span></span></div><div><span id="docs-internal-guid-88c068ac-7fff-d7f7-666a-14a33c2fe749"><h2 dir="ltr" style="line-height: 1.2; margin-bottom: 11.25pt; margin-top: 11.25pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: x-large;">Get started with Android 17</span></span></h2><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">You can </span><a href="https://www.google.com/android/beta" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">enroll any supported Pixel device</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> to get this and future Android Beta updates over-the-air. If you don’t have a Pixel device, you can </span><a href="https://developer.android.com/about/versions/17/get#on_emulator" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">use the 64-bit system images with the Android Emulator</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> in Android Studio.</span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">If you are currently in the Android Beta program, you will be offered an over-the-air update to Beta 2.</span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">If you have Android 26Q1 Beta and would like to take the final stable release of 26Q1 and exit Beta, you need to ignore the over-the-air update to 26Q2 Beta 2 and wait for the release of 26Q1.</span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">We're looking for your feedback so please </span><a href="https://developer.android.com/about/versions/17/feedback" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">report issues and submit feature requests</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> on the </span><a href="https://developer.android.com/about/versions/16/feedback" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">feedback page</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">. The earlier we get your feedback, the more we can include in our work on the final release.</span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">For the best development experience with Android 17, we recommend that you use the latest preview of </span><a href="https://developer.android.com/studio/preview" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">Android Studio (Panda)</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">. Once you’re set up, here are some of the things you should do:</span></span></p><ul style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="2" dir="ltr" style="color: #202124; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; margin-left: 36pt; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="color: black; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;">Compile against the new SDK, test in CI environments, and report any issues in our tracker on the </span><a href="https://developer.android.com/about/versions/17/feedback" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap-mode: wrap; vertical-align: baseline;">feedback page</span></a><span style="color: black; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;">.</span></span></p></li><li aria-level="2" dir="ltr" style="color: #202124; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: disc; margin-left: 36pt; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="color: black; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"><span style="font-family: inherit;">Test your current app for compatibility, learn whether your app is affected by changes in Android 17, and install your app onto a device or emulator running Android 17 and extensively test it.</span></span></p></li></ul><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">We’ll update the </span><a href="https://developer.android.com/about/versions/17/download" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">preview/beta system images</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> and SDK regularly throughout the Android 17 release cycle. Once you’ve installed a beta build, you’ll automatically get future updates </span></span></span></div><div><span id="docs-internal-guid-c1e50571-7fff-2ee5-41f9-5c447a81921b"><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">over-the-air for all later previews and Betas.</span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">For complete information, visit the </span><a href="https://developer.android.com/about/versions/17" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">Android 17 developer site</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">.</span></span></p><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;">Join the conversation</span></span></h3><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">As we move toward </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;">Platform Stability</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> and the general availability of Android 17 later this year, your feedback remains our most valuable asset. Whether you’re an </span><a href="https://www.reddit.com/r/android_canary/" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">early adopter on &nbsp; the Canary channel</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> or an </span><a href="https://www.reddit.com/r/android_beta/" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">app developer testing on Beta 2</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, consider joining our communities and filing feedback. We’re listening.</span></span></span></div>
  2. Under the hood: Android 17’s lock-free MessageQueue

    Tue, 17 Feb 2026 16:00:00 -0000

    <meta content="https://your-image-url.jpg" property="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9HS-x-dS4oIQSAyvQoXlWlwO1W37v5h5a__vVR-FebAvk6RbMsaUoYrVGb5StXntTWUxnpdOoKiSJoDaiJLywZ2Nzs9cA9sUFYePmZRapVre5ZpS1dG433g-gEIFsj83u6hvly1OMWc7oNGMSv-Kh7XdxsrfnsVn7YcggG4cRjRNlPUcjkLvuU9sNBCY/s2469/Android%2017's%20Lock-Free%20Message%20Queue%20_Meta.png"></meta><i> Posted by Shai Barack, Android Platform Performance Lead and Charles Munger, Principal Software Engineer</i><p><span id="docs-internal-guid-4d74092e-7fff-8903-bcc8-0a5e5a3ec2fa"></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"></p><div class="separator" style="clear: both;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbF0aLhQt_qbYhTnODAOPjkVe_oX0gD1YcEGWy8oxv2dE705ei3plig3iKmoOZf6sd8c4x5VmrMNIOyIEy-dmFlaepcN-rz3B6_SSBqa_7VyEJ5FHR2eYcm-QDuYLOormMWbifm2x_X9_4-loSbaW1EQ4H8PKwDLBiIdvcfNNtNp1JeHacykoeTsS0TUk/s16000/Android%2017's%20Lock-Free%20Message%20Queue%20_Blog.png" /></div><span style="font-family: inherit;"><span style="color: #1f1f1f; font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><br /></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">In Android 17, apps targeting SDK 37 or higher will receive a new implementation of MessageQueue where the implementation is lock-free. The new implementation improves performance and reduces missed frames, but may break clients that reflect on MessageQueue private fields and methods. To learn more about the behavior change and how you can mitigate impact, </span><a href="http://developer.android.com/about/versions/17/changes/messagequeue" style="font-family: inherit; text-decoration-line: none;" target="_blank"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">check out the MessageQueue behavior change documentation</span></a><span style="color: #1f1f1f; font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">. This technical blog post provides an overview of the MessageQueue rearchitecture and how you can analyze lock contention issues using Perfetto.</span></p></span></span><p></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span id="docs-internal-guid-cb816bbb-7fff-c2c6-b98c-600b61b50e52"><span style="font-family: inherit;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">The </span><a href="https://developer.android.com/reference/android/os/Looper" style="text-decoration-line: none;" target="_blank"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">Looper</span></a><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> drives the UI thread of every Android application. It pulls work from a </span><a href="https://developer.android.com/reference/android/os/MessageQueue" style="text-decoration-line: none;" target="_blank"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">MessageQueue</span></a><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, dispatches it to a </span><a href="https://developer.android.com/reference/android/os/Handler" style="text-decoration-line: none;" target="_blank"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">Handler</span></a><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, and repeats. For two decades, </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">MessageQueue</span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"> used a single monitor lock (i.e. a </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">synchronized</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #1f1f1f; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">code block) to protect its state.</span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Android 17 introduces a significant update to this component: a lock-free implementation named </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">DeliQueue</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit;"><span id="docs-internal-guid-b30d8de1-7fff-4a32-cf5d-80cf540e6227"></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">This post explains how locks affect UI performance, how to analyze these issues with Perfetto, and the specific algorithms and optimizations used to improve the Android main thread.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span id="docs-internal-guid-d608e40a-7fff-aa7d-5000-bff3d09fe2fe"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: x-large;">The problem: Lock Contention and Priority Inversion</span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">The legacy </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">MessageQueue</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #1f1f1f; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">functioned as a priority queue protected by a single lock. If a background thread posts a message while the main thread performs queue maintenance, the background thread blocks the main thread.</span></span></p><span id="docs-internal-guid-fb0fbba7-7fff-7e05-79e8-768946a417ef"><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">When two or more threads are competing for exclusive use of the same lock, this is called </span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;">Lock contention</span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">. This contention can cause&nbsp;</span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;">Priority Inversion</span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, leading to UI jank and other performance problems.</span></span></p></span><span><p dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">Priority inversion can happen when a high-priority thread (like the UI thread) is made to wait for a low-priority thread. Consider this sequence:</span></span></p><ol style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="1" dir="ltr" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: decimal; margin-left: -12pt; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;">A </span><span style="color: #1f1f1f; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;">low priority</span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"> background thread acquires the</span></span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #1f1f1f; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;">MessageQueue</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #1f1f1f; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"> </span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"><span style="font-family: inherit;">lock to post the result of work that it did.</span></span></p></li><li aria-level="1" dir="ltr" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: decimal; margin-left: -12pt; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;">A </span><span style="color: #1f1f1f; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;">medium priority</span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"> thread becomes runnable and the Kernel's scheduler allocates it CPU time, preempting the low priority thread.</span></span></p></li><li aria-level="1" dir="ltr" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; list-style-type: decimal; margin-left: -12pt; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;">The </span><span style="color: #1f1f1f; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;">high priority</span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"> UI thread finishes its current task and attempts to read from the queue, but is blocked because the low priority thread holds the lock.</span></span></p></li></ol><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">The low-priority thread blocks the UI thread, and the medium-priority work delays it further.</span></span></p><div class="separator" style="clear: both; text-align: center;"><span id="docs-internal-guid-ff649ce9-7fff-0f0a-57eb-a7a10ef70f5b"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="border: none; display: inline-block; height: 213px; overflow: hidden; width: 610px;"><img alt="A visual representation of priority inversion. It shows 'Task L' (Low) holding a lock, blocking 'Task H' (High). 'Task M' (Medium) then preempts 'Task L', effectively delaying 'Task H' for the duration of 'Task M's' execution." src="https://blogger.googleusercontent.com/img/a/AVvXsEi5lpXcJrA3CKIi_DnPnYtJ8bfc3vCrdPHToFuPs6CBRpRCjILPIoTP8Z7m_tpfjLWByWLM1I0UlgacedkHg6iAhlj4Ls7v-EmmRAGvcj9WDB_j095S0SECKZkuU89Bb70vDw-B3CiOWkSuu1KAH6-Z-RLN7zjVJgtqitER1Gl6pMgGEnrWtLp9ebS36JY=s16000" style="margin-left: 0px; margin-top: 0px;" /></span></span></span></div><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span id="docs-internal-guid-e1a4c6c0-7fff-16d2-5e17-ffef6fc3dd8c"><span face="Arial, sans-serif" style="color: black; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;"><span id="docs-internal-guid-187ea446-7fff-79b9-edff-f48938fe69c4"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;">Analyzing contention with Perfetto</span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">You can diagnose these issues using </span><a href="https://perfetto.dev/" style="text-decoration: none;" target="_blank"><span style="background-color: transparent; color: #0b57d0; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Perfetto</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">. In a standard trace, a thread blocked on a monitor lock enters the sleeping state, and Perfetto shows a slice indicating the lock owner.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span id="docs-internal-guid-cf70a937-7fff-d85c-1d12-1030a3ef6c4c"></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">When you query trace data, look for slices named “monitor contention with …” followed by the name of the thread that owns the lock and the code site where the lock was acquired.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;"><span id="docs-internal-guid-800d4400-7fff-1521-47b3-09d8c8a6b964"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;">Case study: Launcher jank</span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span id="docs-internal-guid-2473b6a3-7fff-411f-4eaa-574bb03b77aa"></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">To illustrate, let’s analyze a trace where a user experienced jank while navigating home on a Pixel phone immediately after taking a photo in the camera app. Below we see a screenshot of Perfetto showing the events leading up to the missed frame:</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"></span></p></span><div class="separator" style="clear: both;"><span style="text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial;"><br /><img alt="A Perfetto trace screenshot diagnosing the Launcher jank. The 'Actual Timeline' shows a red missed frame. Coinciding with this, the main thread track contains a large green slice labeled 'monitor contention with owner BackgroundExecutor,' indicating that the UI thread was blocked because a background thread held the MessageQueue lock." border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivHqJIUgTNsk5JKoL8qpiO3vjFfZp-78mTBYD6zWLWbIpQih5o2P-1YdJU57ZEQ2zT959seF1rPzzAmdOFUcMhZqUr67u3YFk5UlqR7UdgVMYpnGU-oFcpEhMtOzaD-8KxTGtaQyL1FpkUqsluy4-cz40e4yzqmiUvG06qmXYd66QnODo-IZJ0tdfps0Q/s16000/cTMPgSaPAotGcAJ.png" /></span><span><span style="color: #1f1f1f;"></span></span></div><span><p></p><div class="separator" style="clear: both; text-align: center;"><br /></div><ul style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; margin-left: -12.75pt; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Symptom:</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> The Launcher main thread missed its frame deadline. It blocked for 18ms, which exceeds the 16ms deadline required for 60Hz rendering.</span></span></p></li><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; margin-left: -12.75pt; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Diagnosis:</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Perfetto showed the main thread blocked on the</span></span><span face="&quot;Google Sans Text&quot;, sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">MessageQueue</span><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">lock. A “BackgroundExecutor” thread owned the lock.</span></span></p></li><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; margin-left: -12.75pt; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Root Cause:</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> The BackgroundExecutor runs at </span><a href="https://developer.android.com/reference/android/os/Process#THREAD_PRIORITY_BACKGROUND" style="text-decoration: none;" target="_blank"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Process.THREAD_PRIORITY_BACKGROUND</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> (very low priority). It performed a non-urgent task (checking </span><a href="https://www.android.com/digital-wellbeing/" style="text-decoration: none;" target="_blank"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">app usage limits</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">). Simultaneously, medium priority threads were using CPU time to process data from the camera. The OS scheduler preempted the BackgroundExecutor thread to run the camera threads.</span></span></p></li></ul><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span id="docs-internal-guid-f545b923-7fff-37c6-c64a-6d96c5d01b8b"></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">This sequence caused the Launcher’s UI thread (high priority) to become indirectly blocked by the camera worker thread (medium priority), which was keeping the Launcher’s background thread (low priority) from releasing the lock.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span id="docs-internal-guid-88ee6413-7fff-8ea9-af00-483f1856b732"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;">Querying traces with PerfettoSQL</span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">You can use </span><a href="https://perfetto.dev/docs/analysis/perfetto-sql-getting-started" style="text-decoration: none;" target="_blank"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">PerfettoSQL</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> to </span><a href="https://perfetto.dev/docs/analysis/batch-trace-processor" style="text-decoration: none;" target="_blank"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">query trace data</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> for specific patterns. This is useful if you have a large bank of traces from user devices or tests, and you’re searching for specific traces that demonstrate a problem.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span id="docs-internal-guid-009e7aa8-7fff-d370-99b0-84fdc6676791"><span style="font-family: inherit;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">For example, this query finds </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 14.6667px; white-space-collapse: preserve;">MessageQueue</span><span style="font-family: inherit;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> contention coincident with dropped frames (jank):</span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"></span></span></p><pre style="color: #333333; line-height: 16.25px; margin: 0px;">INCLUDE PERFETTO MODULE android.monitor_contention; INCLUDE PERFETTO MODULE android.frames.jank_type; <span style="color: blue;">SELECT</span> process_name, <span style="color: green;">-- Convert duration from nanoseconds to milliseconds</span> <span style="color: blue;">SUM</span>(dur) / 1000000 <span style="color: blue;">AS</span> sum_dur_ms, <span style="color: blue;">COUNT</span>(*) <span style="color: blue;">AS</span> count_contention <span style="color: blue;">FROM</span> android_monitor_contention <span style="color: blue;">WHERE</span> is_blocked_thread_main <span style="color: blue;">AND</span> short_blocked_method <span style="color: blue;">LIKE</span> <span style="color: #a31515;">"%MessageQueue%"</span> <span style="color: green;">-- Only look at app processes that had jank</span> <span style="color: blue;">AND</span> upid <span style="color: blue;">IN</span> ( <span style="color: blue;">SELECT</span> <span style="color: blue;">DISTINCT</span>(upid) <span style="color: blue;">FROM</span> actual_frame_timeline_slice <span style="color: blue;">WHERE</span> android_is_app_jank_type(jank_type) = <span style="color: blue;">TRUE</span> ) <span style="color: blue;">GROUP</span> <span style="color: blue;">BY</span> process_name <span style="color: blue;">ORDER</span> <span style="color: blue;">BY</span> <span style="color: blue;">SUM</span>(dur) <span style="color: blue;">DESC</span>;</pre><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span id="docs-internal-guid-cd23b24d-7fff-511d-91a4-3bfaf9572d06"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">In this more complex example, join trace data that spans multiple tables to identify&nbsp;</span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">MessageQueue</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">contention during app startup:</span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"></span></span></p><pre style="color: #333333; line-height: 16.25px; margin: 0px;">INCLUDE PERFETTO MODULE android.monitor_contention; INCLUDE PERFETTO MODULE android.startup.startups; <span style="color: green;">-- Join package and process information for startups</span> <span style="color: blue;">DROP</span> <span style="color: blue;">VIEW</span> <span style="color: blue;">IF</span> <span style="color: blue;">EXISTS</span> startups; <span style="color: blue;">CREATE</span> <span style="color: blue;">VIEW</span> startups <span style="color: blue;">AS</span> <span style="color: blue;">SELECT</span> startup_id, ts, dur, upid <span style="color: blue;">FROM</span> android_startups <span style="color: blue;">JOIN</span> android_startup_processes <span style="color: blue;">USING</span>(startup_id); <span style="color: green;">-- Intersect monitor contention with startups in the same process.</span> <span style="color: blue;">DROP</span> <span style="color: blue;">TABLE</span> <span style="color: blue;">IF</span> <span style="color: blue;">EXISTS</span> monitor_contention_during_startup; <span style="color: blue;">CREATE</span> VIRTUAL <span style="color: blue;">TABLE</span> monitor_contention_during_startup <span style="color: blue;">USING</span> SPAN_JOIN(android_monitor_contention PARTITIONED upid, startups PARTITIONED upid); <span style="color: blue;">SELECT</span> process_name, <span style="color: blue;">SUM</span>(dur) / 1000000 <span style="color: blue;">AS</span> sum_dur_ms, <span style="color: blue;">COUNT</span>(*) <span style="color: blue;">AS</span> count_contention <span style="color: blue;">FROM</span> monitor_contention_during_startup <span style="color: blue;">WHERE</span> is_blocked_thread_main <span style="color: blue;">AND</span> short_blocked_method <span style="color: blue;">LIKE</span> <span style="color: #a31515;">"%MessageQueue%"</span> <span style="color: blue;">GROUP</span> <span style="color: blue;">BY</span> process_name <span style="color: blue;">ORDER</span> <span style="color: blue;">BY</span> <span style="color: blue;">SUM</span>(dur) <span style="color: blue;">DESC</span>;</pre><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-family: inherit; white-space-collapse: preserve;">You can use your favorite LLM to write PerfettoSQL queries to find other patterns.</span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span id="docs-internal-guid-096d9a48-7fff-80bf-ddd0-2d17c7081362"></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">At Google, we use </span><a href="https://perfetto.dev/docs/deployment/deploying-bigtrace-on-a-single-machine" style="text-decoration: none;" target="_blank"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">BigTrace</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> to run PerfettoSQL queries across millions of traces. In doing so, we confirmed that what we saw anecdotally was, in fact, a systemic issue. The data revealed that </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">MessageQueue</span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">lock contention impacts users across the entire ecosystem, substantiating the need for a fundamental architectural change.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: x-large;"><span id="docs-internal-guid-caadd956-7fff-a29d-5997-34cb35714195"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;">Solution: lock-free concurrency</span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span id="docs-internal-guid-7c4e1ceb-7fff-d28b-b090-f03cebcd5def"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">We addressed the</span></span><span face="&quot;Google Sans Text&quot;, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">MessageQueue</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">contention problem by implementing a </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;">lock-free data structure</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">, using atomic memory operations rather than exclusive locks to synchronize access to shared state. A data structure or algorithm is lock-free if at least one thread can always make progress regardless of the scheduling behavior of the other threads. This property is generally hard to achieve, and is </span><a href="https://abseil.io/docs/cpp/atomic_danger" style="text-decoration-line: none;" target="_blank"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">usually not worth pursuing for most code</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">.</span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;"><span id="docs-internal-guid-297cca04-7fff-13f2-d589-739510c50dee"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;">The atomic primitives</span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Lock-free software often relies on atomic Read-Modify-Write primitives that the hardware provides.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span id="docs-internal-guid-2a9f5f30-7fff-3bd9-b65d-16481bbb7ee9"></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">On older generation ARM64 CPUs, atomics used a Load-Link/Store-Conditional (LL/SC) loop. The CPU loads a value and marks the address. If another thread writes to that address, the store fails, and the loop retries. Because the threads can keep trying and succeed without waiting for another thread, this operation is lock-free.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"></span></span></p><pre style="color: #333333; line-height: 16.25px; margin: 0px;">ARM64 LL/SC loop example retry: ldxr x0, [x1] // <span style="color: blue;">Load</span> <span style="color: blue;">exclusive</span> <span style="color: blue;">from</span> address x1 <span style="color: blue;">to</span> x0 <span style="color: blue;">add</span> x0, x0, #1 // <span style="color: blue;">Increment</span> value <span style="color: blue;">by</span> 1 stxr w2, x0, [x1] // Store <span style="color: blue;">exclusive</span>. // w2 gets 0 <span style="color: blue;">on</span> success, 1 <span style="color: blue;">on</span> failure cbnz w2, retry // <span style="color: blue;">If</span> w2 <span style="color: blue;">is</span> non-zero (failed), branch <span style="color: blue;">to</span> retr</pre><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;"><br /></span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">(</span><a href="https://godbolt.org/z/GPs9GeGhG" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">view in Compiler Explorer</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">)</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span id="docs-internal-guid-5d564034-7fff-04d5-b5ed-235d2cce6df9"><span style="font-family: inherit;"><br /><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Newer ARM architectures (ARMv8.1) support </span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;">Large System Extensions (LSE)</span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> which include instructions in the form of Compare-And-Swap (CAS) or Load-And-Add (demonstrated below). In Android 17 we added support to the Android Runtime (ART) compiler to detect when LSE is supported and emit optimized instructions:</span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"></span></span></p><pre style="color: #333333; line-height: 16.25px; margin: 0px;">/ ARMv8.1 LSE <span style="color: blue;">atomic</span> example ldadd x0, x1, [x2] // <span style="color: blue;">Atomic</span> <span style="color: blue;">load</span>-<span style="color: blue;">add</span>. // Faster, <span style="color: blue;">no</span> loop required.</pre><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-family: inherit; white-space-collapse: preserve;">In our benchmarks, high-contention code that uses CAS achieves a ~3x speedup over the LL/SC variant.</span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span id="docs-internal-guid-655bf206-7fff-a055-5c56-2334602de691"></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">The Java programming language offers atomic primitives via</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><a href="https://developer.android.com/reference/java/util/concurrent/atomic/package-summary" style="text-decoration: none;" target="_blank"><span style="-webkit-text-decoration-skip: none; background-color: transparent; color: #1155cc; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre;">java.util.concurrent.atomic</span></a><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">that rely on these and other specialized CPU instructions.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-495eb21d-7fff-02a9-25c4-6546f5af6e15"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;"><span style="font-family: inherit; font-size: x-large;">The Data Structure: DeliQueue</span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">To remove lock contention from </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">MessageQueue</span><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">, our engineers designed a novel data structure called </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">DeliQueue</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">. DeliQueue separates </span><span style="background-color: transparent; color: #188038; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Message</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> insertion from</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Message</span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">processing:</span></span></p><ol style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: decimal; margin-left: -12pt; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">The list of </span></span><span style="background-color: transparent; color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Message</span><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">s (Treiber stack):</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> A lock-free stack. Any thread can push new </span></span><span style="background-color: transparent; color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Message</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">s here without contention.</span></span></p></li><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: decimal; margin-left: -12pt; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The priority queue (Min-heap):</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> A heap of</span></span><span face="&quot;Google Sans Text&quot;, sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Message</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">s to handle, exclusively owned by the Looper thread (hence no synchronization or locks are needed to access).</span></span></p></li></ol><h3 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 6pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Enqueue: pushing to a Treiber stack</span></span></h3><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-5c2da1f3-7fff-2f23-1a57-b87c8ed8680e"></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">The list of</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Message</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">s is kept in a Treiber stack [1], a lock-free stack that uses a CAS loop to update the head pointer.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"></span></p><pre style="color: #333333; line-height: 16.25px; margin: 0px;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> <span style="color: #2b91af;">TreiberStack</span> &lt;E&gt; { AtomicReference&lt;Node&lt;E&gt;&gt; top = <span style="color: blue;">new</span> AtomicReference&lt;Node&lt;E&gt;&gt;(); <span style="color: blue;">public</span> <span style="color: #2b91af;">void</span> push(E item) { Node&lt;E&gt; newHead = <span style="color: blue;">new</span> Node&lt;E&gt;(item); Node&lt;E&gt; oldHead; <span style="color: blue;">do</span> { oldHead = top.get(); newHead.next = oldHead; } <span style="color: blue;">while</span> (!top.compareAndSet(oldHead, newHead)); } <span style="color: blue;">public</span> E pop() { Node&lt;E&gt; oldHead; Node&lt;E&gt; newHead; <span style="color: blue;">do</span> { oldHead = top.get(); <span style="color: blue;">if</span> (oldHead == <span style="color: blue;">null</span>) <span style="color: blue;">return</span> <span style="color: blue;">null</span>; newHead = oldHead.next; } <span style="color: blue;">while</span> (!top.compareAndSet(oldHead, newHead)); <span style="color: blue;">return</span> oldHead.item; } }</pre><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span id="docs-internal-guid-86bfc1f0-7fff-7ba3-667b-6338b7f6e2d2"><span style="font-family: inherit;"><span style="font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Source code based on Java Concurrency in Practice [2], </span><a href="https://jcip.net/listings/ConcurrentStack.java" style="text-decoration-line: none;"><span style="color: #1155cc; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">available online</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> and released to the public domain</span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Any producer can push new</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Message</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">s to the stack at any time. This is like pulling a ticket at a deli counter - your number is determined by when you showed up, but the order you get your food in doesn't have to match. Because it's a linked stack, ever</span></span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">y</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Message</span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">is a sub-stack - you can see what the </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Message</span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">queue was like at any point in time by tracking the head and iterating forwards - you won't see any new</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Message</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">s pushed on top, even if they're being added during your traversal.</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><br /><br /></span></p><h3 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Dequeue: bulk transfer to a min-heap</span></span></h3><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-6fc7a392-7fff-b027-8b25-639abfd4a25c"></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">To find the next </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Message</span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">to handle, the</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Looper</span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">processes new</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Message</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">s</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">from the Treiber stack by walking the stack starting from the top and iterating until it finds the last</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Message</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;"> that it previously processed. As the</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Looper</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;"> traverses down the stack, it inserts </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Message</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">s into the deadline-ordered min-heap. Since the Looper exclusively owns the heap, it orders and processes</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Message</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">s without locks or atomics.</span></span></p><div class="separator" style="clear: both; text-align: center;"><span style="border: none; display: inline-block; height: 91px; margin-left: 1em; margin-right: 1em; overflow: hidden; width: 610px;"><img alt="A system diagram illustrating the DeliQueue architecture. Concurrent producer threads (left) push messages onto a shared 'Lock-Free Treiber Stack' using atomic CAS operations. The single consumer 'Looper Thread' (right) claims these messages via an atomic swap, merges them into a private 'Local Min-heap' sorted by timestamp, and then executes them." src="https://blogger.googleusercontent.com/img/a/AVvXsEhknkVSDfMX-ZahCjfG4tSxzMtW4QHU0mzm_9vw2wXNMM1DY3oOy-sHeejjN-huSAGJAjVJzl47NUlVlVKNswK4KHkW0dTCEoeIZqYspMEI6KIy56S9d0AQWUMa1amuWA6WAWr1naU4_5SrqSr1GYzMsekgmJgjcs43lb4C5YGznm6g3AC3uwAQDFZJnLk=s16000" style="margin-left: 0px; margin-top: 0px;" /></span></div><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-d33f0623-7fff-4d5e-99b0-5e91595e38cb"><span face="Arial, sans-serif" style="color: black; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><br /></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">In walking down the stack, the </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Looper</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #1f1f1f; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">also creates links from stacked</span></span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #1f1f1f; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Message</span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">s back to their predecessors, thus forming a doubly-linked list. Creating the linked list is safe because links pointing down the stack are added via the Treiber stack algorithm with CAS, and links up the stack are only ever read and modified by the</span></span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #1f1f1f; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Looper</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #1f1f1f; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">thread. These back links are then used to remove</span></span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #1f1f1f; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Message</span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">s from arbitrary points in the stack in O(1) time.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">This design provides<span style="font-family: inherit;">&nbsp;</span></span></span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><i>O</i>(1)</span></span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #1f1f1f; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="font-family: inherit;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">insertion for producers (threads posting work to the queue) and amortized </span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><i>O</i>(log </span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">N)</span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> processing for the consumer (the</span></span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #1f1f1f; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Looper</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #1f1f1f; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">).</span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;"><span id="docs-internal-guid-a01eb2dc-7fff-e868-f53e-1d021f344afa"></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Using a min-heap to order </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Message</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">s also addresses a fundamental flaw in the legacy </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">MessageQueue</span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">, </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">where</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Message</span><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">s were kept in a singly-linked list (rooted at the top). In the legacy implementation, removal from the head was </span><span style="background-color: transparent; color: #1f1f1f; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><i>O</i></span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">(1)</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">, but insertion had a worst case of </span><span style="background-color: transparent; color: #1f1f1f; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><i>O(N)</i></span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> – scaling poorly for overloaded queues! Conversely, insertion to and removal from the min-heap scale logarithmically, delivering competitive average performance but really excelling in tail latencies.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><span id="docs-internal-guid-1e82bf04-7fff-ce44-b440-809493782717"></span></span></span></span></span></span></p><div align="center" dir="ltr" style="margin-left: 0pt;"><table style="border-collapse: collapse; border: none;"><colgroup><col width="233"></col><col width="233"></col><col width="233"></col></colgroup><tbody><tr style="height: 0pt;"><td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;"><span style="font-family: inherit;"><br /></span></td><td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;"><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Legacy (locked) </span><span style="background-color: transparent; color: #188038; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">MessageQueue</span></span></p></td><td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;"><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">DeliQueue</span></span></p></td></tr><tr style="height: 0pt;"><td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;"><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Insert</span></span></p></td><td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;"><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><i><span style="font-family: inherit;">O(N)</span></i></span></p></td><td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;"><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><i>O</i></span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">(1)</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> for calling thread</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><i>O(logN)</i></span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> for </span><span style="background-color: transparent; color: #188038; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Looper</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> thread</span></span></p></td></tr><tr style="height: 0pt;"><td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;"><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Remove from head</span></span></p></td><td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;"><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;"><i>O</i>(1)</span></span></p></td><td style="border-bottom: solid #000000 1pt; border-color: rgb(0, 0, 0); border-left: solid #000000 1pt; border-right: solid #000000 1pt; border-style: solid; border-top: solid #000000 1pt; border-width: 1pt; overflow-wrap: break-word; overflow: hidden; padding: 5pt; vertical-align: top;"><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;"><i>O(logN)</i></span></span></p></td></tr></tbody></table></div><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span id="docs-internal-guid-d43a699a-7fff-648e-1c4d-cb8001b51340"></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">In the legacy queue implementation, producers and the consumer used a lock to coordinate exclusive access to the underlying singly-linked list. In DeliQueue, the Treiber stack handles concurrent access, and the single consumer handles ordering its work queue.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-7066d0a0-7fff-996d-8718-93fca15b620f"><span style="color: black; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;"><span style="font-family: inherit; font-size: large;">Removal: consistency via tombstones</span></span></span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">DeliQueue is a hybrid data structure, joining a lock-free Treiber stack with a single-threaded min-heap. Keeping these two structures in sync without a global lock presents a unique challenge: a message might be physically present in the stack but logically removed from the queue.</span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">To solve this, DeliQueue uses a technique called “tombstoning.” Each </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Message</span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">tracks its position in the stack via the backwards and forwards pointers, its index in the heap’s array, and a boolean flag indicating whether it has been removed. When a</span></span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Message</span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">is ready to run, the</span></span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Looper</span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">thread will CAS its removed flag, then remove it from the heap and stack.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">When another thread needs to remove a </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Message</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">, it doesn't immediately extract it from the data structure. Instead, it performs the following steps:</span></span></p><ol style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: decimal; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Logical removal: the thread uses a CAS to atomically set the </span></span><span style="background-color: transparent; color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Message</span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">’s removal flag from false to true. The</span></span><span face="Arial, sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Message</span><span face="Arial, sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">remains in the data structure as evidence of its pending removal, a so-called “tombstone”. Once a</span></span><span face="Arial, sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Message</span><span face="Arial, sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">is flagged for removal, DeliQueue treats it as if it no longer exists in the queue whenever it’s found.</span></span></p></li><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: decimal; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Deferred cleanup: The actual removal from the data structure is the responsibility of the </span></span><span style="background-color: transparent; color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Looper</span><span face="Arial, sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">thread, and is deferred until later. Rather than modifying the stack or heap, the remover thread adds the</span></span><span face="Arial, sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Message</span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;"> to another lock-free freelist stack.</span></span></p></li><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: decimal; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Structural removal: Only the </span></span><span style="background-color: transparent; color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Looper</span><span face="Arial, sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">can interact with the heap or remove elements from the stack. When it wakes up, it clears the freelist and processes the </span></span><span style="background-color: transparent; color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Messages</span><span face="Arial, sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">it contained. Each </span></span><span style="background-color: transparent; color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Message</span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;"> is then unlinked from the stack and removed from the heap.&nbsp;</span></span></p></li></ol><div><span style="white-space-collapse: preserve;"><br /></span></div><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">This approach keeps all management of the heap single-threaded. It minimizes the number of concurrent operations and memory barriers required, making the critical path faster and simpler.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span id="docs-internal-guid-0f44709f-7fff-3016-7a35-94f3ec565c5e"></span></p><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: x-large;">Traversal: benign Java memory model data races</span></span></h3><div><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-7b3bd3a2-7fff-efe7-f706-1d994d79f9ed" style="font-weight: normal;"><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">Most concurrency APIs, such as</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Future</span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">in the Java standard library, or Kotlin’s </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Job</span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">and</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Deferred</span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">, i</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">nclude a mechanism to cancel work before it completes. An instance of one of these classes matches 1:1 with a unit of underlying work, and calling</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">cancel</span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">on an object cancels the specific operations associated with them.</span></span></p><span style="font-family: inherit;"><br /></span><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">Today’s Android devices have multi-core CPUs and concurrent, generational garbage collection. But when Android was first developed, it was too expensive to allocate one object for each unit of work. Consequently, Android’s </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Handler</span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">supports cancellation via numerous overloads of </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">removeMessages</span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> -</span><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> rather than removing a </span><span style="font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">specific</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Message</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">, it removes all</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Message</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">s that match the specified criteria. In practice, this requires iterating through all</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Message</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">s inserted before</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">removeMessages</span><span face="Arial, sans-serif" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-size: 11pt;"> </span><span style="font-family: inherit;">w</span></span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">as called and removing the ones that match.</span></span></p><span style="font-family: inherit;"><br /><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">When iterating forward, a thread only requires one ordered atomic operation, to read the current head of the stack. After that, ordinary field reads are used to find the next</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Message</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">. If the</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Looper</span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">thread modifies the</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">next</span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">fields while removing</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Message</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">s, the</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Looper</span><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">’s write and another thread’s read are unsynchronized - this is a </span><span style="font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">data race</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">. Normally, a data race is a serious bug that can cause huge problems in your app - leaks, infinite loops, crashes, freezes, and more. However, under certain narrow conditions, data races can be benign within the Java Memory Model. Suppose we start with a stack of:</span></span></span></span></div></span><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"></p><div class="separator" style="clear: both; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><img alt="A diagram showing the initial state of the message stack as a linked list. The 'Head' points to 'Message A', which links sequentially to 'Message B', 'Message C', and 'Message D'." border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD58rsF7QpfHdZD0-4Y4YT4yn7pyFUvRU8ngHUs2T748AcOKAPQYJ_rn_dUg28-Q_Rc0XH3O7qlD9dGwMdoURapme0STqflbdfgUFqz9xBIjkx1Mn0GW_2H357NtAjHDiFGMEsv-GxLQTTN8qq8UycW_l-liJ6EliM76rUdhX0kMU15DjTMbT60I0-d1w/s16000/graphviz_linked.png" /><span><span style="color: #1f1f1f;"><span style="font-family: inherit;"><span><span></span></span></span></span></span></div><span><span style="color: #1f1f1f;"><span style="font-family: inherit;"><span><span><br /><span style="font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span id="docs-internal-guid-d19b183b-7fff-69c0-a5e3-ff92ce37f956"></span></span></span></span></span></span></span><p></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">We perform an atomic read of the head, and see A. A’s </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">next</span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">pointer points to B. At the same time as we process B, the looper might remove B and C, by updating A to point to C and then D.</span></span></p><span><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><span id="docs-internal-guid-da0e0bca-7fff-aea9-7d44-3ba98b9d79ec"><span face="Arial, sans-serif" style="color: black; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="border: none; display: inline-block; height: 176px; overflow: hidden; width: 610px;"><img alt="A diagram illustrating a benign data race during list traversal. The Looper thread has updated 'Message A' to point directly to 'Message D', effectively removing 'Message B' and 'Message C'. Simultaneously, a concurrent thread reads a stale 'next' pointer from A, traverses through the logically removed messages B and C, and eventually rejoins the live list at 'Message D'." src="https://blogger.googleusercontent.com/img/a/AVvXsEiBEhPBhBTaFMF-1L8t05OMQMm08iWVMG_HGWmCLG9gjEJN87ScZLxovnX8VrbO4RFbRi_Ctw1_0U_BeQVIqAZ3emlxkPhvzXIg3WB3ijOOHRnkqJnnqo43l4G7P1WVU-y8IfENFunduyHnfUewRh2yf_4EM7sbo7BIZDPG1wsDWoN6WbHEePS39mwq1ZE=s16000" style="margin-left: 0px; margin-top: 0px;" /></span></span></span></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><br /></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Even though</span></span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">B</span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;"> and </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">C</span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">are logically removed, </span><span style="background-color: transparent; color: #188038; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">B</span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> retains its next pointer to</span></span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">C</span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">,</span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;"> and</span></span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">C</span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">to </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">D</span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">. The reading thread continues traversing through the detached removed nodes and eventually rejoins the live stack at </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">D</span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">.</span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><br /></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">By designing DeliQueue to handle races between traversal and removal, we allow for safe, lock-free iteration.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit; font-size: x-large;"><span id="docs-internal-guid-b6b28ebe-7fff-e906-929e-1c17c3e00167"><span style="color: black; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;">Quitting: Native refcount</span></span></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Looper</span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">is backed by a native allocation that must be manually freed once the </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Looper</span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;"> has quit. If some other thread is adding </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Message</span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">s while the</span></span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Looper</span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">is quitting, it could use the native allocation after it’s freed, a memory safety violation. We prevent this using a </span><span style="background-color: transparent; color: black; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">tagged refcount</span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">, where one bit of the atomic is used to indicate whether the </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Looper</span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">is quitting.</span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><br /></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Before using the native allocation, a thread reads the refcount atomic. If the quitting bit is set, it returns that the</span></span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Looper</span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">is quitting and the native allocation must not be used. If not, it attempts a CAS to increment the number of active threads using the native allocation. After doing what it needs to, it decrements the count. If the quitting bit was set after its increment but before the decrement, and the count is now zero, then it wakes up the </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Looper</span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">thread.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><span style="color: black; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">When the</span></span><span face="Arial, sans-serif" style="color: black; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Looper</span><span face="Arial, sans-serif" style="color: black; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="color: black; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">thread is ready to quit, it uses CAS to set the quitting bit in the atomic. If the refcount was 0, it can proceed to free its native allocation. Otherwise, it parks itself, knowing that it will be woken up when the last user of the native allocation decrements the refcount. This approach does mean that the </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Looper</span><span style="color: black; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"> thread waits for the progress of other threads, but only when it’s quitting. That only happens once and is not performance sensitive, and it keeps the other code for using the native allocation fully lock-free.</span></span></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><span id="docs-internal-guid-852f4e36-7fff-947e-9e8f-7e83afeba2c0"><span face="Arial, sans-serif" style="color: black; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="border: none; display: inline-block; height: 165px; overflow: hidden; width: 610px;"><img alt="A state diagram illustrating the tagged refcount mechanism for safe termination. It defines three states based on the atomic value's layout (Bit 63 for teardown, Bits 0-62 for refcount): Active (Green): The teardown bit is 0. Workers successfully increment and decrement the reference count. Draining (Yellow): The Looper has set the teardown bit to 1. New worker increments fail, but existing workers continue to decrement. Terminated (Red): Occurs when the reference count reaches 0 while draining. The Looper is signaled that it is safe to destroy the native allocation." src="https://blogger.googleusercontent.com/img/a/AVvXsEhnTvDsIwwQfH8V_jK3KwyjtRolyycTjQqqezIEVYspluGZCVNIWpEJA7bFV2iEYXFpTF7XFfdoYaWVamWAre916Uv8nPhRJ7hOddqT2nEymLewlKXvRffzgYRneFMuxflq8GnPyaTf3-gMx-JDf3Jk6YIxP4fUAJ8TcSmGkcI82Pubf6R3YvSlcjoSd-U=s16000" style="margin-left: 0px; margin-top: -1.9174px;" /></span></span></span></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><br /></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><br /></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><span id="docs-internal-guid-7955d30f-7fff-1736-b4c3-4b22e234107c"></span></span></span></span></span></span></p></span><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">There’s a lot of other tricks and complexity in the implementation. You can learn more about DeliQueue by reviewing the </span></span></span><span style="font-family: inherit;">source code.</span></p><span><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit; font-size: x-large;"><span id="docs-internal-guid-3b24281c-7fff-389c-3612-edc3b2f073fb"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;">Optimization: branchless programming</span></span></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">While developing and testing DeliQueue, the team ran many benchmarks and carefully profiled the new code. One issue identified using the </span><a href="https://developer.android.com/ndk/guides/simpleperf" style="text-decoration: none;" target="_blank"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">simpleperf tool</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> was pipeline flushes caused by the</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Message</span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">comparator code.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><span id="docs-internal-guid-d54d4939-7fff-59af-c65d-7f66993a98bb"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">A standard comparator uses conditional jumps, with the condition for deciding which</span></span><span face="&quot;Google Sans Text&quot;, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Message</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">comes first simplified below:</span></span></span></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"></span></span></span></span></span></p><pre style="color: #333333; line-height: 16.25px; margin: 0px;"><span style="color: blue;">static</span> <span style="color: #2b91af;">int</span> compareMessages(@NonNull Message m1, @NonNull Message m2) { <span style="color: blue;">if</span> (m1 == m2) { <span style="color: blue;">return</span> 0; } <span style="color: green;">// Primary queue order is by when.</span> <span style="color: green;">// Messages with an earlier when should come first in the queue.</span> <span style="color: blue;">final</span> <span style="color: #2b91af;">long</span> whenDiff = m1.when - m2.when; <span style="color: blue;">if</span> (whenDiff &gt; 0) <span style="color: blue;">return</span> 1; <span style="color: blue;">if</span> (whenDiff &lt; 0) <span style="color: blue;">return</span> -1; <span style="color: green;">// Secondary queue order is by insert sequence.</span> <span style="color: green;">// If two messages were inserted with the same `when`, the one inserted</span> <span style="color: green;">// first should come first in the queue.</span> <span style="color: blue;">final</span> <span style="color: #2b91af;">long</span> insertSeqDiff = m1.insertSeq - m2.insertSeq; <span style="color: blue;">if</span> (insertSeqDiff &gt; 0) <span style="color: blue;">return</span> 1; <span style="color: blue;">if</span> (insertSeqDiff &lt; 0) <span style="color: blue;">return</span> -1; <span style="color: blue;">return</span> 0; }</pre><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><br /></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">This code compiles to conditional jumps (</span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">b.le</span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">&nbsp;</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">and&nbsp;</span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">cbnz</span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">&nbsp;</span><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">instructions). When the CPU encounters a conditional branch, it can’t know whether the branch is taken until the condition is computed, so it doesn’t know which instruction to read next, and has to guess, using a technique called </span><span style="background-color: transparent; color: #1f1f1f; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">branch prediction</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">. In a case like binary search, the branch direction will be unpredictably different at each step, so it’s likely that half the predictions will be wrong. Branch prediction is often ineffective in searching and sorting algorithms (such as the one used in a min-heap), because the cost of guessing wrong is larger than the improvement from guessing correctly. When the branch predictor guesses wrong, it must throw away the work it did after assuming the predicted value, and start again from the path that was actually taken - this is called a </span><span style="background-color: transparent; color: #1f1f1f; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">pipeline flush</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><span id="docs-internal-guid-86182231-7fff-da72-96d9-6b96aba5000f"></span></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">To find this issue, we profiled our benchmarks using the</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">branch-misses</span><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> performance counter, which records stack traces where the branch predictor guesses wrong. We then visualized the results with </span><a href="https://github.com/google/pprof" style="text-decoration: none;" target="_blank"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Google pprof</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">, as shown below:</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><span id="docs-internal-guid-514a00fc-7fff-6f2a-7a9a-dd53920fe6a1"><span face="&quot;Google Sans Text&quot;, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="border: none; display: inline-block; height: 293px; overflow: hidden; width: 610px;"><img alt="A screenshot from the pprof web UI showing branch misses in MessageQueue code to compare Message instances while performing heap operations." src="https://blogger.googleusercontent.com/img/a/AVvXsEhWzEoCloyBTPrjN-l1Z_g9erTzvYdJSAN_Kl03J5BqreA5Tdb_T9HG0LfenFzE2BkN5GTaeiIqAtQNqmcGjhTsu7vfEj2D-51hUjLaQssZo6pV8jiv8FtLFOmEnqZdfanKNYQ1oOWDAaKEzfSZbV9NVcxVYkXW_dw663Z5DDPUaS8NJwrXzSgTrxtT13k=s16000" style="margin-left: -6.78561e-14px; margin-top: 0px;" /></span></span></span></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">Recall that the original </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">MessageQueue</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #1f1f1f; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">code used a singly-linked list for the ordered queue. Insertion would traverse the list in sorted order as a linear search, stopping at the first element that’s past the point of insertion and linking the new </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Message</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #1f1f1f; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">ahead of it. Removal from the head simply required unlinking the head. Whereas DeliQueue uses a min-heap, where mutations require reordering some elements (sifting up or down) with logarithmic complexity in a balanced data structure, where any comparison has an even chance of directing the traversal to a left child or to a right child. The new algorithm is asymptotically faster, but exposes a new bottleneck as the search code stalls on branch misses half the time.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><span id="docs-internal-guid-fd635632-7fff-cd6b-4491-00a8cba98612"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Realizing that branch misses were slowing down our heap code, we optimized the code using </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;">branch-free programming</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">:</span></span></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"></span></span></span></span></span></p><pre style="color: #333333; line-height: 16.25px; margin: 0px;"><span style="color: green;">// Branchless Logic</span> <span style="color: blue;">static</span> <span style="color: #2b91af;">int</span> compareMessages(@NonNull Message m1, @NonNull Message m2) { <span style="color: blue;">final</span> <span style="color: #2b91af;">long</span> when1 = m1.when; <span style="color: blue;">final</span> <span style="color: #2b91af;">long</span> when2 = m2.when; <span style="color: blue;">final</span> <span style="color: #2b91af;">long</span> insertSeq1 = m1.insertSeq; <span style="color: blue;">final</span> <span style="color: #2b91af;">long</span> insertSeq2 = m2.insertSeq; <span style="color: green;">// signum returns the sign (-1, 0, 1) of the argument,</span> <span style="color: green;">// and is implemented as pure arithmetic:</span> <span style="color: green;">// ((num &gt;&gt; 63) | (-num &gt;&gt;&gt; 63))</span> <span style="color: blue;">final</span> <span style="color: #2b91af;">int</span> whenSign = Long.signum(when1 - when2); <span style="color: blue;">final</span> <span style="color: #2b91af;">int</span> insertSeqSign = Long.signum(insertSeq1 - insertSeq2); <span style="color: green;">// whenSign takes precedence over insertSeqSign,</span> <span style="color: green;">// so the formula below is such that insertSeqSign only matters</span> <span style="color: green;">// as a tie-breaker if whenSign is 0.</span> <span style="color: blue;">return</span> whenSign * 2 + insertSeqSign; }</pre><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><span id="docs-internal-guid-9074ac10-7fff-96c8-aade-ddfd0a0b56fb"></span></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">To understand the optimization, </span><a href="https://godbolt.org/z/bvGh7aadG" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">disassemble the two examples in Compiler Explorer</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> and use </span><a href="https://llvm.org/docs/CommandGuide/llvm-mca.html" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">LLVM-MCA</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">, a CPU simulator that can generate an </span><a href="https://godbolt.org/z/EYxn6MasE" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">estimated timeline of CPU cycles</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"></span></span></span></span></span></p><pre style="color: #333333; line-height: 16.25px; margin: 0px;">The original code: <span style="color: blue;">Index</span> 01234567890123 [0,0] DeER . . . sub x0, x2, x3 [0,1] D=eER. . . cmp x0, #0 [0,2] D==eER . . cset w0, ne [0,3] .D==eER . . cneg w0, w0, lt [0,4] .D===eER . . cmp w0, #0 [0,5] .D====eER . . b.le #12 [0,6] . DeE<span style="color: green;">---R . . mov w1, #1</span> [0,7] . DeE<span style="color: green;">---R . . b #48</span> [0,8] . D==eE-R . . tbz w0, #31, #12 [0,9] . DeE<span style="color: green;">--R . . mov w1, #-1</span> [0,10] . DeE<span style="color: green;">--R . . b #36</span> [0,11] . D=eE-R . . sub x0, x4, x5 [0,12] . D=eER . . cmp x0, #0 [0,13] . D==eER. . cset w0, ne [0,14] . D===eER . cneg w0, w0, lt [0,15] . D===eER . cmp w0, #0 [0,16] . D====eER. csetm w1, lt [0,17] . D===eE-R. cmp w0, #0 [0,18] . .D===eER. csinc w1, w1, wzr, le [0,19] . .D====eER mov x0, x1 [0,20] . .DeE<span style="color: green;">----R ret</span></pre><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><span id="docs-internal-guid-32bdaff2-7fff-460b-89b2-ff05a7840904"><span style="color: black; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">Note the one conditional branch, </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">b.le</span><span face="Arial, sans-serif" style="color: black; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">,&nbsp; </span><span style="color: black; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">which avoids comparing the</span></span><span face="Arial, sans-serif" style="color: black; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">insertSeq </span><span style="color: black; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">fields if the result is already known from comparing the </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">when</span><span style="color: black; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"> fields.</span></span></span></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"></span></span></span></span></span></p><pre style="color: #333333; line-height: 16.25px; margin: 0px;">The branchless code: <span style="color: blue;">Index</span> 012345678 [0,0] DeER . . sub x0, x2, x3 [0,1] DeER . . sub x1, x4, x5 [0,2] D=eER. . cmp x0, #0 [0,3] .D=eER . cset w0, ne [0,4] .D==eER . cneg w0, w0, lt [0,5] .DeE<span style="color: green;">--R . cmp x1, #0</span> [0,6] . DeE-R . cset w1, ne [0,7] . D=eER . cneg w1, w1, lt [0,8] . D==eeER <span style="color: blue;">add</span> w0, w1, w0, lsl #1 [0,9] . DeE<span style="color: green;">--R ret</span></pre><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;"><br /></span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Here, the branchless implementation takes fewer cycles and instructions than even the shortest path through the branchy code - it’s better in all cases. The faster implementation plus the elimination of mispredicted branches resulted in a 5x improvement in some of our benchmarks!</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><br /><span style="color: black; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">However, this technique is not always applicable. Branchless approaches generally require doing work that will be thrown away, and if the branch is predictable most of the time, that wasted work can slow your code down. In addition, removing a branch often introduces a </span><span style="color: black; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">data dependency</span><span style="color: black; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">. Modern CPUs execute multiple operations per cycle, but they can’t execute an instruction until its inputs from a previous instruction are ready. In contrast, a CPU can </span><span style="color: black; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">speculate</span><span style="color: black; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> about data in branches, and work ahead if a branch is predicted correctly.</span></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><span id="docs-internal-guid-e3d6b84f-7fff-6a01-6407-3e8247547a87"></span></span></span></span></span></span></p><h2 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: x-large;">Testing and Validation</span></span></h2><p dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Validating the correctness of lock-free algorithms is notoriously difficult!</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">In addition to standard unit tests for continuous validation during development, we also wrote rigorous </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">stress tests</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> to verify queue invariants and to attempt to induce data races if they existed. In our test labs we could run millions of test instances on emulated devices and on real hardware.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">With </span><a href="https://github.com/google/java-thread-sanitizer" style="text-decoration: none;" target="_blank"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 700; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Java ThreadSanitizer</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> (JTSan) instrumentation, we could use the same tests to also detect some data races in our code. JTSan did not find any problematic data races in DeliQueue, but - surprisingly -actually detected two concurrency bugs in the Robolectric framework, which we promptly fixed.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><span id="docs-internal-guid-340bb8b1-7fff-ad8d-a726-461114d9db30"></span></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 6pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">To improve our debugging capabilities, we built new </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">analysis tools</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">. Below is an example showing an issue in Android platform code where one thread is overloading another thread with </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">Message</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">s, causing a large backlog, visible in Perfetto thanks to the</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">MessageQueue</span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">instrumentation feature that we added.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><span id="docs-internal-guid-90c3fbfa-7fff-1a60-444e-9414aa435c50"><span face="&quot;Google Sans Text&quot;, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="border: none; display: inline-block; height: 471px; overflow: hidden; width: 610px;"><img alt="A screenshot of Perfetto UI, demonstrating flows and metadata for Messages being posted to a MessageQueue and delivered to a worker thread." src="https://blogger.googleusercontent.com/img/a/AVvXsEj6PDjipHRYCZTdaA0a9JAXFqW98l1DBKt1sJGKzSgxpYI9oevK5sjG7sdBHDCjwFyK9VZfTbmHmA5NK9Z5cJ5dLxFb7FP7Lw_07AmtaBT4yKs9Gsyz3QeeifZghO09Qk0ZTsbTIMVKmRrT34-VLQmB47qTTKPSm6BeSPiBSASooYIR5yR7AcoRV7utUKc=s16000" style="margin-left: 0px; margin-top: 0px;" /></span></span></span></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">To enable </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">MessageQueue</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #1f1f1f; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">tracing in the</span></span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #1f1f1f; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">system_server</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #1f1f1f; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">process, include the following in your Perfetto configuration:</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"></span></span></span></span></span></p><pre style="color: #333333; line-height: 16.25px; margin: 0px;">data_sources { config { name: <span style="color: #a31515;">"track_event"</span> target_buffer: 0 <span style="color: green;"># Change this per your buffers configuration</span> track_event_config { enabled_categories: <span style="color: #a31515;">"mq"</span> } } }</pre><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit; font-size: x-large;"><span id="docs-internal-guid-9d707054-7fff-6660-7d56-bf741066320f"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;">Impact</span></span></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">DeliQueue improves system and app performance by eliminating locks from </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">MessageQueue</span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">.</span></p><ul style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; margin-left: -12.75pt; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Synthetic benchmarks:</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> multi-threaded insertions into busy queues is up to </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">5,000x faster</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> than the legacy</span></span><span face="&quot;Google Sans Text&quot;, sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">MessageQueue</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">, thanks to improved concurrency (the Treiber stack) and faster insertions (the min-heap).</span></span></p></li><li aria-level="1" dir="ltr" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; margin-left: -12.75pt; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">In </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Perfetto traces acquired from internal beta testers</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">, we see a reduction of 15% in app main thread time spent in lock contention.</span></span></p></li><li aria-level="1" dir="ltr" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; margin-left: -12.75pt; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">On the same test devices, the reduced lock contention leads to significant improvements to the user experience, such as:</span></span></p></li><ul style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="2" dir="ltr" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">-4% missed frames in apps.</span></span></p></li><li aria-level="2" dir="ltr" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">-7.7% missed frames in System UI and Launcher interactions.</span></span></p></li><li aria-level="2" dir="ltr" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">-9.1% in time from app startup to the first frame drawn, at the 95%ile.</span></span></p></li></ul></ul><h2 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 6pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Next steps</span></span></h2><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">DeliQueue is rolling out to apps in Android 17. App developers should review preparing your app for the new lock-free </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">MessageQueue</span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">on the Android Developers blog to learn how to test their apps.</span></span></p><h2 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 6pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">References</span></span></h2><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">[1] Treiber, R.K., 1986. Systems programming: Coping with parallelism. International Business Machines Incorporated, Thomas J. Watson Research Center.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><span id="docs-internal-guid-fb570c95-7fff-a409-09f2-8f8855c4aabc"></span></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">[2] Goetz, B., Peierls, T., Bloch, J., Bowbeer, J., Holmes, D., &amp; Lea, D. (2006). Java Concurrency in Practice. Addison-Wesley Professional.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><br /></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><br /></span></span></span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 6pt;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;"><br /></span></span></span></span></span></p></span>
  3. Prepare your app for the resizability and orientation changes in Android 17

    Fri, 13 Feb 2026 19:34:00 -0000

    <name content="IMG" twitter:image=""><p><em>Posted by Miguel Montemayor, Developer Relations Engineer, Android&nbsp;</em></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikDKkmApg8RWitmL4i9a2Qu7sLGHQVTXkbaYcf494F7oVyFQ_VU0ogIbtc_HvduJax-kfpPgUld9ui1dQv6SG7IjJG0q0hmr-QpKcRdW49-MwDM4SDVyCm8nlH5Rhake4RUSElO4wRwNd7F6xy1Ers861Pv40MEAC_hwQ9fs76MsNMg0029dXwx4LTsWM/s4210/Android%20%2017%20KILO%20Beta%20Blog.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1254" data-original-width="4210" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikDKkmApg8RWitmL4i9a2Qu7sLGHQVTXkbaYcf494F7oVyFQ_VU0ogIbtc_HvduJax-kfpPgUld9ui1dQv6SG7IjJG0q0hmr-QpKcRdW49-MwDM4SDVyCm8nlH5Rhake4RUSElO4wRwNd7F6xy1Ers861Pv40MEAC_hwQ9fs76MsNMg0029dXwx4LTsWM/s16000/Android%20%2017%20KILO%20Beta%20Blog.png" /></a></div><div><br /></div><span id="docs-internal-guid-4f561ce1-7fff-7e75-407e-eee5bc03f550"></span><p></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">With the release of Android 16 in 2025, we shared our vision for a device ecosystem where apps adapt seamlessly to any screen—whether it’s a phone, foldable, tablet, desktop, car display, or XR. Users expect their apps to work everywhere. Whether multitasking on a tablet, unfolding a device to read comfortably, or running apps in a desktop windowing environment, users expect the UI to fill the available display space and adapt to the device posture.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">We </span><a href="https://android-developers.googleblog.com/2025/01/orientation-and-resizability-changes-in-android-16.html" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">introduced significant changes</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> to orientation and resizability APIs to facilitate adaptive behavior, while providing a temporary opt-out to help you make the transition. We’ve already seen many developers successfully adapt to this transition when targeting API level 36.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Now with the release of the Android 17 Beta, we’re moving to the next phase of our adaptive roadmap: </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Android 17 (API level 37) removes the developer opt-out for orientation and resizability restrictions on large screen devices</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> (sw &gt; 600 dp). When you target API level 37, your app must be capable of adapting to a variety of display sizes.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit;"><span id="docs-internal-guid-5ec37f72-7fff-fb22-a0ab-218209897934"></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">The behavior changes ensure that the Android ecosystem offers a consistent, high-quality experience on all device form factors.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-family: inherit; font-size: x-large; font-weight: 700; white-space-collapse: preserve;">What’s changing in Android 17</span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Apps targeting Android 17 must ensure their compatibility with the phase out of manifest attributes and runtime APIs introduced in Android 16. We understand for some apps this may be a big transition, so we’ve included best practices and tools for helping avoid common issues later in this blog post.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">No new changes have been introduced since Android 16, but the developer opt-out is no longer possible. As a reminder: when your app is running on a large screen—where </span><span style="background-color: transparent; color: #1f1f1f; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">large screen</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> means that the smaller dimension of the display is greater than or equal to 600 dp—the following manifest attributes and APIs are ignored:</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span id="docs-internal-guid-70e8f0ff-7fff-b202-a807-0b4e093db486"><span style="font-family: inherit;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;">Note: </span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">As previously mentioned with Android 16, these changes do not apply for screens that are smaller than sw 600 dp or apps categorized as games based on the </span><a href="https://developer.android.com/guide/topics/manifest/application-element#appCategory" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">android:appCategory</span></a><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> flag. </span></span></span></p><table><tbody><tr><td><b>Manifest attributes/API</b></td><td><b>Ignored values</b></td></tr><tr><td><a href="https://developer.android.com/guide/topics/manifest/activity-element#screen" target="_blank">screenOrientation</a></td><td>portrait, reversePortrait, sensorPortrait, userPortrait, landscape, reverseLandscape, sensorLandscape, userLandscape</td></tr><tr><td><a href="https://developer.android.com/reference/android/app/Activity#setRequestedOrientation%28int%29" target="_blank">setRequestedOrientation()</a></td><td>portrait, reversePortrait, sensorPortrait, userPortrait, landscape, reverseLandscape, sensorLandscape, userLandscape</td></tr><tr><td><a href="https://developer.android.com/guide/topics/manifest/application-element#resizeableActivity" target="_blank">resizeableActivity</a></td><td>all</td></tr><tr><td><a href="https://developer.android.com/reference/android/R.attr#minAspectRatio" target="_blank">minAspectRatio</a></td><td>all</td></tr><tr><td><a href="https://developer.android.com/reference/android/R.attr#maxAspectRatio" target="_blank">maxAspectRatio</a></td><td>all</td></tr></tbody></table><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span id="docs-internal-guid-50b62273-7fff-0150-2aba-00ed9b0e8d98"></span></p><div align="left" dir="ltr" style="margin-left: 0pt;"><br /></div><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Also, users retain control. In the </span><a href="https://developer.android.com/guide/practices/device-compatibility-mode#user_per-app_overrides" style="font-family: inherit; text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">aspect ratio settings</span></a><span style="color: #1f1f1f; font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, users can explicitly opt-in to using the app’s requested behavior.</span></p><h3 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Prepare your app</span></span></h3><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Apps will need to support landscape and portrait layouts for display sizes in the full range of aspect ratios in which users can choose to use apps, including resizable windows, as there will no longer be a way to restrict the aspect ratio and orientation to portrait or to landscape.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Test your app</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Your first step is to test your app with these changes to make sure the app works well across display sizes.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span id="docs-internal-guid-9c4a6081-7fff-4dde-4bd8-519c3834e65f"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">Use Android 17 Beta 1 with the Pixel Tablet and Pixel Fold series emulators in Android Studio, and set the </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">targetSdkPreview = “CinnamonBun”</span><span style="font-family: inherit;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">. Alternatively, you can use the </span><a href="https://developer.android.com/guide/app-compatibility/test-debug" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">app compatibility framework</span></a><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> by enabling the </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">UNIVERSAL_RESIZABLE_BY_DEFAULT</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">flag if your app does not target API level 36 yet.</span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">We have additional tools to ensure your layouts adapt correctly. You can automatically audit your UI and get suggestions to make your UI more adaptive with </span><a href="https://developer.android.com/develop/ui/compose/tooling/debug#compose_ui_check" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Compose UI Check</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">, and simulate specific display characteristics in your tests using </span><a href="https://developer.android.com/training/testing/different-screens/tools#deviceconfigurationoverride" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">DeviceConfigurationOverride</span></a><span style="background-color: transparent; color: #188038; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">For apps that have historically restricted orientation and aspect ratio, we commonly see issues with skewed or misoriented camera previews, stretched layouts, inaccessible buttons, or loss of user state when handling configuration changes.&nbsp;</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Let’s take a look at some strategies for addressing these common issues.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 18pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Ensure camera compatibility</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 18pt; margin-top: 0pt; text-align: left;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">A common problem on landscape foldables or for aspect ratio calculations in scenarios like multi-window, desktop windowing, or connected displays, is when the camera preview appears stretched, rotated, or cropped.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 18pt; margin-top: 0pt; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaOg_C3QfT7opQoLISKbuJZVmSGW2k3T469LhtncUPlCCeHYNmnfDNjXvoaxzctfEFNzFlro4vBJ_KSvfz8u8ihxgitmvQi8n3dW1THWQvEux0_DRaW3VfZFPe7n5vbRFv8nB__rz9B2zPU3SO6jFilPVjMZ9jKCd-s3VqKq2lbj9O7WPFwcr4SnwlIG4/s1140/camera_preview_issue.png" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" data-original-height="640" data-original-width="1140" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaOg_C3QfT7opQoLISKbuJZVmSGW2k3T469LhtncUPlCCeHYNmnfDNjXvoaxzctfEFNzFlro4vBJ_KSvfz8u8ihxgitmvQi8n3dW1THWQvEux0_DRaW3VfZFPe7n5vbRFv8nB__rz9B2zPU3SO6jFilPVjMZ9jKCd-s3VqKq2lbj9O7WPFwcr4SnwlIG4/s16000/camera_preview_issue.png" /></a><i><span style="font-family: inherit;">Ensure your camera preview isn’t stretched or rotated.</span></i></p><span style="font-family: inherit;">This issue often happens on large screen and foldable devices because apps assume fixed relationships between camera features (like aspect ratio and sensor orientation) and device features (like device orientation and natural orientation).</span><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">To ensure your camera preview adapts correctly to any window size or orientation, consider these four solutions:</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Solution 1: Jetpack CameraX (preferred)&nbsp;</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">The simplest and most robust solution is to use the Jetpack CameraX library. Its </span></span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">PreviewView</span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">UI element is designed to handle all preview complexities automatically:</span></span></p><ul style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="1" dir="ltr" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="background-color: transparent; color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">PreviewView</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">correctly adjusts for sensor orientation, device rotation, and scaling</span></span></p></li><li aria-level="1" dir="ltr" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">PreviewView</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> maintains the aspect ratio of the camera image, typically by centering and cropping </span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">(</span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">FILL_CENTER</span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">)</span></p></li><li aria-level="1" dir="ltr" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">You can set the scale type to</span></span><span face="&quot;Google Sans Text&quot;, sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">FIT_CENTER</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">to letterbox the preview if needed</span></span></p></li></ul><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">For more information, see </span><a href="https://developer.android.com/training/camerax/preview" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Implement a preview</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> in the CameraX documentation.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Solution 2: CameraViewfinder&nbsp;</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">I</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">f you are using an existing Camera2 codebase, the</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">CameraViewfinder</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;"> library (backward compatible to API level 21) is another modern solution. It simplifies displaying the camera feed by using a</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">TextureView</span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">or</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">SurfaceView</span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">and applying all the necessary transformations (aspect ratio, scale, and rotation) for you.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span id="docs-internal-guid-666b8396-7fff-facf-5950-4e095fe61a34"></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">For more information, see the </span><a href="https://android-developers.googleblog.com/2022/11/introducing-camera-viewfinder.html" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Introducing Camera Viewfinder</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> blog post and </span><a href="https://developer.android.com/media/camera/camera2/camera-preview#cameraviewfinder" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Camera preview</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> developer guide.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Solution 3: Manual Camera2 implementation&nbsp;</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">If you can't use CameraX or</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="background-color: transparent; color: #188038; font-family: 'Roboto Mono',monospace; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">CameraViewfinder</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">, you must manually calculate the orientation and aspect ratio and ensure the calculations are updated on each configuration change:</span></span></p><ul style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="1" dir="ltr" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Get the camera sensor orientation (for example, 0, 90, 180, 270 degrees) from</span></span><span face="&quot;Google Sans Text&quot;, sans-serif" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">CameraCharacteristics</span></p></li><li aria-level="1" dir="ltr" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Get the device's current display rotation (for example, 0, 90, 180, 270 degrees)</span></span></p></li><li aria-level="1" dir="ltr" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Use the camera sensor orientation and display rotation values to determine the necessary transformations for your </span></span><span style="background-color: transparent; color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">SurfaceView</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">or</span></span><span face="&quot;Google Sans Text&quot;, sans-serif" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">TextureView</span></p></li><li aria-level="1" dir="ltr" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Ensure the aspect ratio of your output </span></span><span style="background-color: transparent; color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Surface</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> </span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">matches the aspect ratio of the camera preview to prevent distortion</span></span></p></li></ul><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Important:</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> Note the camera app might be running in a portion of the screen, either in multi-window or desktop windowing mode or on a connected display. For this reason, screen size should not be used to determine the dimensions of the camera viewfinder; use </span><a href="https://developer.android.com/media/camera/camera2/camera-preview#window_metrics" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">window metrics</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> instead. Otherwise you risk a stretched camera preview.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">For more information, see the </span><a href="https://developer.android.com/media/camera/camera2/camera-preview" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Camera preview</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> developer guide and </span><a href="https://www.youtube.com/watch?v=XcJIrTedfus" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Your Camera app on different form factors</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> video.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: italic; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Solution 4: Perform basic camera actions using an Intent&nbsp;</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">If you don't need many camera features, a simple and straightforward solution is to perform basic camera actions like capturing a photo or video using the device's default camera application. In this case, you can simply use an </span><span style="background-color: transparent; color: #188038; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Intent</span><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> instead of integrating with a camera library, for easier maintenance and adaptability.&nbsp;</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">For more information, see </span><a href="https://developer.android.com/media/camera/camera-intents" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Camera intents</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">.</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><br /><br /></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 18pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Avoid stretched UI or inaccessible buttons</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span id="docs-internal-guid-75e7b15f-7fff-8b8d-e991-55af73beff6f"></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 18pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">If your app assumes a specific device orientation or display aspect ratio, the app may run into issues when it’s now used across various orientations or window sizes.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 18pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKwyymMCL3BFRz6gBW_WJtawGZhlqrAMvc2ty07RJyUl9cl8CtlDG3vJIcTMCT0o0if_liTu6zTZv7aMhBeH3r5YtzUEfPcScKY7Y51OzBABFNio__QaxeCekQMfkqYo4vsfrQAv8lnCkFD90mngpQ9FQ9HAgHnhKlmWn3xyzVL9xS9nyb43cfX7trjIk/s3998/Screenshot%202026-02-09%20at%203.03.14%E2%80%AFPM.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="2414" data-original-width="3998" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKwyymMCL3BFRz6gBW_WJtawGZhlqrAMvc2ty07RJyUl9cl8CtlDG3vJIcTMCT0o0if_liTu6zTZv7aMhBeH3r5YtzUEfPcScKY7Y51OzBABFNio__QaxeCekQMfkqYo4vsfrQAv8lnCkFD90mngpQ9FQ9HAgHnhKlmWn3xyzVL9xS9nyb43cfX7trjIk/s16000/Screenshot%202026-02-09%20at%203.03.14%E2%80%AFPM.png" /></a></span></div><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt; text-align: center;"><span style="color: #1f1f1f; font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span id="docs-internal-guid-14dbf7ac-7fff-529c-001c-7eb03fe76609"><span style="font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">Ensure buttons, textfields, and other elements aren’t stretched on large screens.</span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span id="docs-internal-guid-d400b121-7fff-91a6-26ce-773852eb2b01"></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 18pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">You may have set buttons, text fields, and cards to</span></span><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: #1f1f1f; font-size: 9pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; white-space-collapse: preserve;">fillMaxWidth</span><span face="'Google Sans Text',sans-serif" style="color: #1f1f1f; font-size: 9pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space: pre;"> or </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; white-space-collapse: preserve;">match_parent</span><span face="'Google Sans Text',sans-serif" style="color: #1f1f1f; font-size: 9pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space: pre;">. </span><span style="font-family: inherit;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">On a phone, this looks great. However, on a tablet or foldable in landscape, UI elements stretch across the entire large screen. In Jetpack Compose, you can use the </span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">widthIn</span><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> modifier to set a maximum width for components to avoid stretched content:</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"></span></p><pre style="color: #333333; line-height: 16.25px; margin: 0px;">Box( contentAlignment = Alignment.Center, modifier = Modifier.fillMaxSize() ) { Column( modifier = Modifier .widthIn(max = 300.dp) <span style="color: green;">// Prevents stretching beyond 300dp</span> .fillMaxWidth() <span style="color: green;">// Fills width up to 300dp</span> .padding(16.dp) ) { <span style="color: green;">// Your content</span> } }</pre><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span id="docs-internal-guid-006846ae-7fff-a949-e6a7-5561f957a149"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">If a user opens your app in landscape orientation on a foldable or tablet, action buttons like </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;">Save</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> or </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;">Login</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> at the bottom of the screen may be rendered offscreen. If the container is not scrollable, the user can be blocked from proceeding. In Jetpack Compose, you can add a </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">verticalScroll</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"> modifier to your component:</span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"></span></p><pre style="color: #333333; line-height: 16.25px; margin: 0px;">Column( modifier = Modifier .fillMaxSize() .verticalScroll(rememberScrollState()) .padding(16.dp) )</pre><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">By combining max-width constraints with vertical scrolling, you ensure your app remains functional and usable, regardless of how wide or short the app window size becomes.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><b id="docs-internal-guid-7b993bae-7fff-51cc-9a35-3876d92d6b53" style="font-weight: normal;"><br /></b></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">See our guide on </span><a href="https://developer.android.com/develop/ui/compose/build-adaptive-apps" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">building adaptive layouts</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><b style="font-weight: normal;"><br /></b></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 18pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Preserve state with configuration changes</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 18pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Removing orientation and aspect ratio restrictions means your app's window size will change much more frequently. Users may rotate their device, fold/unfold it, or resize your app dynamically in split-screen or desktop windowing modes.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 18pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">By default, these configuration changes destroy and recreate your activity. If your app does not properly manage this lifecycle event, users will have a frustrating experience: scroll positions are reset to the top, half-filled forms are wiped clean, and navigation history is lost. To ensure a seamless adaptive experience, it’s critical your app preserves state through these configuration changes. With Jetpack Compose, you can opt-out of recreation, and instead allow window size changes to recompose your UI to reflect the new amount of space available.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 18pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">See our guide on </span><a href="https://developer.android.com/topic/libraries/architecture/saving-states" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">saving UI state</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">.</span></span></p><h3 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Targeting API level 37 by August 2027</span></span></h3><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">If your app previously opted out of these changes when targeting API level 36, your app will only be impacted by the Android 17 opt-out removal after your app targets API level 37. To help you plan ahead and make the necessary adjustments to your app, here’s the timeline when these changes will take effect:</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><b style="font-weight: normal;"><br /></b></span></p><ul style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Android 17: Changes described above will be the baseline experience for large screen devices (smallest screen width &gt; 600 dp) for </span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">apps that target API level 37</span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">. Developers </span><span style="background-color: transparent; color: black; font-style: italic; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">will not</span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> have an option to opt-out.</span></span></p></li></ul><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="color: #1f1f1f; font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><b style="font-weight: normal;"><br /></b></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 18pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">The deadlines for targeting a specific API level are app-store specific. For Google Play, new apps and updates will be required to target API level 37, making this behavior mandatory for distribution in August 2027.</span></span></p><h3 dir="ltr" style="line-height: 1.38; margin-bottom: 6pt; margin-top: 0pt;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Preparing for Android 17</span></span></h3><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span id="docs-internal-guid-18057054-7fff-c687-6924-009cffc40710"><span style="font-family: inherit;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Refer to the </span><a href="https://developer.android.com/about/versions/17/behavior-changes-17" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">Android 17 changes page</span></a><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> for all changes impacting apps in Android 17. To test your app, download Android 17 Beta 1 and update to</span></span><span style="color: #1f1f1f; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 9pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">targetSdkPreview = “CinnamonBun”</span><span style="color: #1f1f1f; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 9pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="font-family: inherit;"><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">or use the </span><a href="https://developer.android.com/guide/app-compatibility/test-debug" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">app compatibility framework</span></a><span style="color: #1f1f1f; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> to enable specific changes.</span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The future of Android is adaptive, and we’re here to help you get there. As you prepare for Android 17, we encourage you to review our guides for </span><a href="https://developer.android.com/develop/ui/compose/build-adaptive-apps" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">building adaptive layouts</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> and our </span><a href="https://developer.android.com/docs/quality-guidelines/large-screen-app-quality" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">large screen quality guidelines</span></a><span style="background-color: transparent; color: #1f1f1f; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">. These resources are designed to help you handle multiple form factors and window sizes with confidence.</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Don’t wait. Start getting ready for Android 17 today!</span></span></p><p></p></name>
  4. The First Beta of Android 17

    Fri, 13 Feb 2026 19:23:00 -0000

    <meta content="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDYVIPcSHC3ZeYbTu-FSxsYdp1PDK62bN18DL-VuLlWbmEG9L7vPfW6CA6SfA0iaUiZ-V79edfaGQ7DWsaMH7i9zQlTNbYlKZlsEgMb6IQAIJdxMb7NXcqtETxMk2T3X1uY2U7Ok4xq1-52gDN_yH5LOUEAr6xb3wBx0XJJKBnvmKHt8JNfo7Bfp9n_0g/w1000-h1000/heptadecagraph-rounded-calm@2x.png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"></meta> <img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDYVIPcSHC3ZeYbTu-FSxsYdp1PDK62bN18DL-VuLlWbmEG9L7vPfW6CA6SfA0iaUiZ-V79edfaGQ7DWsaMH7i9zQlTNbYlKZlsEgMb6IQAIJdxMb7NXcqtETxMk2T3X1uY2U7Ok4xq1-52gDN_yH5LOUEAr6xb3wBx0XJJKBnvmKHt8JNfo7Bfp9n_0g/w1000-h1000/heptadecagraph-rounded-calm@2x.png" style="display: none;" /> <name content="IMG" twitter:image=""><p style="text-align: left;"><em>Posted by Matthew McCullough, VP of Product Management, Android Developer</em> </p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfHUXXy41tnZXO66g6CXEA5j-xhe-8Xmt4IlUR_R4CWtypOHL0BFj1HYfSp_Gb0CFaJlKzREehqqnOZwVb1ViBejiyjQl_q3r_Zj8-WsobiU_5csS6a_W3YR4ecqEJxpG-rkL4yzqCIaFG-WN3-nqTUZz74t93mUpxP6XOktYix_kFX5761qUlQHoVKlM/s320/Banner2_heptadecagraph-rounded-calm%20(1).png" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="1024" data-original-width="1024" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfHUXXy41tnZXO66g6CXEA5j-xhe-8Xmt4IlUR_R4CWtypOHL0BFj1HYfSp_Gb0CFaJlKzREehqqnOZwVb1ViBejiyjQl_q3r_Zj8-WsobiU_5csS6a_W3YR4ecqEJxpG-rkL4yzqCIaFG-WN3-nqTUZz74t93mUpxP6XOktYix_kFX5761qUlQHoVKlM/w600-h600/Banner2_heptadecagraph-rounded-calm%20(1).png" width="200" /></a></div><p><span style="font-family: inherit;">Today we're releasing the first beta of&nbsp;</span><a href="https://developer.android.com/about/versions" style="font-family: inherit; text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">Android 17</span></a><span style="font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">, continuing our work to build a platform that prioritizes privacy, security, and refined performance. This build continues our work for more adaptable Android apps, introduces significant enhancements to camera and media capabilities, new tools for optimizing connectivity, and expanded profiles for companion devices. This release also highlights a fundamental shift in the way we're bringing new releases to the developer community, </span><a href="https://android-developers.googleblog.com/2025/07/android-canary.html" style="font-family: inherit; text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline;">from the traditional Developer Preview model to the Android Canary program</span></a></p></name><div><span id="docs-internal-guid-2b19e33d-7fff-e0b9-14f9-1981c2fabd14"><h2 dir="ltr" style="line-height: 1.2; margin-bottom: 4pt; margin-top: 14pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: x-large;">Beyond the Developer Preview</span></span></h2><div style="text-align: left;"><span id="docs-internal-guid-02878592-7fff-b6a2-a251-a181b64ae300"><span style="font-family: inherit;"><p dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Android has replaced the traditional "Developer Preview" with a </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;">continuous Canary channel</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">. This new "always-on" model offers three main benefits:</span></p><ul style="text-align: left;"><li><span id="docs-internal-guid-02878592-7fff-b6a2-a251-a181b64ae300"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;">Faster Access:</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> Features and APIs land in Canary as soon as they pass internal testing, rather than waiting for a quarterly release.</span></span></li><li><span id="docs-internal-guid-02878592-7fff-b6a2-a251-a181b64ae300"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;">Better Stability:</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> Early "battle-testing" in Canary results in a more polished Beta experience with new APIs and behavior changes that are closer to being final.</span></span></li><li><span id="docs-internal-guid-02878592-7fff-b6a2-a251-a181b64ae300"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;">Easier Testing:</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> Canary supports OTA updates (no more manual flashing) and, as a separate update channel, more easily integrates with CI workflows and gives you the earliest window to give immediate feedback on upcoming potential changes.</span></span></li></ul></span></span></div><p dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-family: inherit; font-size: x-large; font-weight: 700; white-space-collapse: preserve;">The Android 17 schedule</span></p></span><div><name content="IMG" twitter:image=""><span style="font-family: inherit;">We're going to be moving quickly from this Beta to our Platform Stability milestone, targeted for March. At this milestone, we'll deliver final SDK/NDK APIs and largely final app-facing behaviors. From that time you’ll have several months before the final release to complete your testing.</span><span><span style="font-family: inherit;"><span><span><div style="white-space-collapse: preserve;"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><br /></span></div></span></span></span></span><div class="separator" style="clear: both; text-align: center;"><span id="docs-internal-guid-9ff22c46-7fff-a4fc-59a0-9f730b15efaf"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"></span></span><span style="border: none; display: inline-block; height: 123px; margin-left: 1em; margin-right: 1em; overflow: hidden; width: 610px;"><img height="343.00000000000006" src="https://blogger.googleusercontent.com/img/a/AVvXsEj9GTiqVXjiWkjoGd2LtsQUJV64ehB2uENeZbhdu7_TYJYDCfn662UAL8kh-QH6p9CXz1I2aIyBiI21RoUQyphkBb0YuPHtii_j_UWmh59cXg9jvft8DEZpmH5Lyc4WlWiNp2hqTrTGOQrxmKCtDeudjMU3JIo3pc-oZ71XAml2wlEzypwYeyR3hOLvDuE" style="margin-left: 0px; margin-top: -82px;" width="610" /></span></div><p><span id="docs-internal-guid-0db75647-7fff-eba4-ac6c-79ede54f5043"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"></span></span></p><span id="docs-internal-guid-d295d168-7fff-8fff-f148-356bbe976266"><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;"><br /></span></span></h3></span><span style="font-family: inherit;"><span style="font-size: large;"><b>A year of releases</b></span></span></name></div><div><name content="IMG" twitter:image=""><span style="font-family: inherit;"><br /></span></name></div><div><name content="IMG" twitter:image=""><span style="font-family: inherit;">We plan for Android 17 to continue to get updates in a series of quarterly releases. The upcoming release in Q2 is the only one where we introduce planned app breaking behavior changes. We plan to have a minor SDK release in Q4 with additional APIs and features.</span><span><p dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt; text-align: center;"><span id="docs-internal-guid-6b7c18f2-7fff-88c0-4c58-0998b9bde4dc"><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="border: none; display: inline-block; height: 143px; overflow: hidden; width: 610px;"><img height="343" src="https://blogger.googleusercontent.com/img/a/AVvXsEhW2Ih5qF4zhQOmL_hQ70CCu1BnjExD5gLURCcL9TS-URJIPFGsiH_VYUcGKwJCVtJ1WHUhyWerCiNeZ5fVsnDBIniAWl-av-mFwQYJOTe7j2-aebRcSuNgBqYB2N-uxO0cGcLin7eBiWm6BPWYpcp47fnZ07_3pYcDPESvf0JzduJOn3X0VoYm6oGmVGI" style="margin-left: 0px; margin-top: -85px;" width="610" /></span></span></span></p></span><h2 dir="ltr" style="line-height: 1.38; margin-bottom: 4pt; margin-top: 0pt;"><br /></h2><div><span style="font-family: inherit; font-size: x-large;"><b>Orientation and resizability restrictions</b></span></div><div><span><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">With the release of the Android 17 Beta, we’re moving to the next phase of our adaptive roadmap: </span><span style="font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;">Android 17 (API level 37) removes the developer opt-out for orientation and resizability restrictions on </span><a href="https://developer.android.com/guide/topics/large-screens" style="font-family: inherit; text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">large screen devices</span></a><span style="font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> (sw &gt; 600 dp).</span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">When your app targets SDK 37, it must be ready to adapt. Users expect their apps to work everywhere—whether multitasking on a tablet, unfolding a device, or using a desktop windowing environment—and they expect the UI to fill the space and respect their device posture.</span></span></p></span></div><h3 dir="ltr" style="line-height: 1.38; margin-bottom: 4pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Key Changes for SDK 37</span></span></h3><span style="font-family: inherit;">Apps targeting Android 17 must ensure compatibility with the phase-out of manifest attributes and runtime APIs introduced in Android 16. When running on a large screen (smaller dimension ≥ 600dp), the following attributes and APIs will be ignored:</span></name></div><div><br /><name content="IMG" twitter:image=""><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;"></span></span></p><table><tbody><tr><td><b>Manifest attributes/API</b></td><td><b>Ignored values</b></td></tr><tr><td><a href="https://developer.android.com/guide/topics/manifest/activity-element#screen" target="_blank">screenOrientation</a></td><td>portrait, reversePortrait, sensorPortrait, userPortrait, landscape, reverseLandscape, sensorLandscape, userLandscape</td></tr><tr><td><a href="https://developer.android.com/reference/android/app/Activity#setRequestedOrientation%28int%29" target="_blank">setRequestedOrientation()</a></td><td>portrait, reversePortrait, sensorPortrait, userPortrait, landscape, reverseLandscape, sensorLandscape, userLandscape</td></tr><tr><td><a href="https://developer.android.com/guide/topics/manifest/application-element#resizeableActivity" target="_blank">resizeableActivity</a></td><td>all</td></tr><tr><td><a href="https://developer.android.com/reference/android/R.attr#minAspectRatio" target="_blank">minAspectRatio</a></td><td>all</td></tr><tr><td><a href="https://developer.android.com/reference/android/R.attr#maxAspectRatio" target="_blank">maxAspectRatio</a></td><td>all</td></tr></tbody></table><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span face="'Google Sans Text',sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><span id="docs-internal-guid-7a5177b0-7fff-0fb9-6856-afc57961ed35"></span></span></p><h3 dir="ltr" style="line-height: 1.38; margin-bottom: 4pt; margin-top: 0pt;"><span style="white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;"><br /></span></span></h3><div style="line-height: 1.38; margin-bottom: 4pt; margin-top: 0pt; text-align: left;"><span id="docs-internal-guid-2195ce25-7fff-b830-c835-1cbff1e52b85"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;">Exemptions and User Control</span></span></span></div><div style="line-height: 1.38; margin-bottom: 4pt; margin-top: 0pt;"><span id="docs-internal-guid-1dd3cc92-7fff-f760-12ef-9a244503b3f7"><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">These changes are specific to large screens; they </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;">do not apply</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> to screens smaller than sw600dp (including traditional slate form factor phones). Additionally, apps categorized as games (based on the </span><a href="https://developer.android.com/guide/topics/manifest/application-element#appCategory" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">android:appCategory</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> flag) are exempt from these restrictions.</span></span></p></span><span><p dir="ltr" style="line-height: 1.38; margin-bottom: 12pt; margin-top: 0pt;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">It is also important to note that users remain in control. They can explicitly opt-in/out to using an app’s default behavior via the system's aspect ratio settings.</span></span></p></span><span style="font-family: inherit; font-size: large;"><b>Updates to configuration changes</b></span></div><div style="line-height: 1.38; margin-bottom: 4pt; margin-top: 0pt;"><span id="docs-internal-guid-968722f4-7fff-381e-317f-c822058f21d8"><span style="color: #073042; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">To improve app compatibility and help minimize interrupted video playback, dropped input, and other types of disruptive state loss, we are updating the default behavior for Activity recreation. Starting with Android 17, the system will no longer restart activities by default for specific configuration changes that typically do not require a UI recreation, including </span></span><a href="https://developer.android.com/reference/android/content/pm/ActivityInfo.html#CONFIG_KEYBOARD" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">CONFIG_KEYBOARD</span></a><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">,</span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><a href="https://developer.android.com/reference/android/content/pm/ActivityInfo.html#CONFIG_KEYBOARD_HIDDEN" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">CONFIG_KEYBOARD_HIDDEN</span></a><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, </span><a href="https://developer.android.com/reference/android/content/pm/ActivityInfo.html#CONFIG_NAVIGATION" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">CONFIG_NAVIGATION</span></a><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, </span><a href="https://developer.android.com/reference/android/content/pm/ActivityInfo.html#CONFIG_UI_MODE" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">CONFIG_UI_MODE</span></a><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #073042; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">(when only </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">UI_MODE_TYPE_DESK</span><span style="color: #073042; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"> is changed), </span></span><a href="https://developer.android.com/reference/android/content/pm/ActivityInfo.html#CONFIG_TOUCHSCREEN" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">CONFIG_TOUCHSCREEN</span></a><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, </span><span style="color: #073042; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">and</span></span><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><a href="https://developer.android.com/reference/android/content/pm/ActivityInfo.html#CONFIG_COLOR_MODE" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">CONFIG_COLOR_MODE</span></a><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">.</span><span style="color: #073042; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"> Instead, running activities will simply receive these updates via</span></span><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><a href="https://developer.android.com/reference/android/app/Activity#onConfigurationChanged(android.content.res.Configuration)" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">onConfigurationChanged</span></a><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">. </span><span style="color: #073042; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">If your application relies on a full restart to reload resources for these changes, you must now explicitly opt-in using the new</span></span><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">android:recreateOnConfigChanges</span><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #073042; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">manifest attribute, which allows you to specify which configuration changes should trigger a complete activity lifecycle (from stop, to destroy and creation again), together with the related constants</span></span><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><a href="https://developer.android.com/reference/android/content/res/Configuration#mcc" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">mcc</span></a><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, </span><a href="https://developer.android.com/reference/android/content/res/Configuration#mnc" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">mnc</span></a><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, </span><span style="color: #073042; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">and the new ones</span></span><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><a href="https://developer.android.com/reference/android/content/res/Configuration#keyboard" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">keyboard</span></a><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, </span><a href="https://developer.android.com/reference/android/content/res/Configuration#keyboardHidden" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">keyboardHidden</span></a><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, </span><a href="https://developer.android.com/reference/android/content/res/Configuration#navigation" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">navigation</span></a><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, </span><a href="https://developer.android.com/reference/android/content/res/Configuration#touchscreen" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">touchscreen</span></a><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> and </span><a href="https://developer.android.com/reference/android/content/res/Configuration#colorMode" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">colorMode</span></a><span face="Roboto, sans-serif" style="color: #073042; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">.</span></span></div><div><br /></div><span style="font-family: inherit; font-size: large;"><b>Prepare Your App</b></span><div><br /></div><div><span id="docs-internal-guid-4243f742-7fff-fe91-bb5f-57dc387e69ba"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">We’ve released tools and documentation to make it easy for you. <a href="https://android-developers.googleblog.com/2026/02/prepare-your-app-for-resizability-and.html" target="_blank">Our focused blog post has more guidance</a>, with strategies to address common issues. Apps will need to support landscape and portrait layouts for window sizes across the full range of aspect ratios, as restricting orientation or aspect ratio will no longer be an option. We recommend testing your app using the </span><a href="https://developer.android.com/about/versions" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">Android 17</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> Beta 1 with Pixel Tablet or Pixel Fold emulators (configured to </span></span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #188038; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">targetSdkPreview = "CinnamonBun"</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">)</span><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> or by using the </span><a href="https://developer.android.com/guide/topics/large-screens/large-screen-compatibility-mode" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">app compatibility framework</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> to enable </span></span><span face="&quot;Google Sans Text&quot;, sans-serif" style="color: #188038; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">UNIVERSAL_RESIZABLE_BY_DEFAULT</span><span face="&quot;Google Sans Text&quot;, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">on Android 16 devices.</span></span></span></div><div><span><span face="&quot;Google Sans Text&quot;, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></span></div><div><span><span face="&quot;Google Sans Text&quot;, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></span></div><h3 dir="ltr" style="line-height: 1.38; margin-bottom: 4pt; margin-top: 0pt;"><span style="font-weight: normal;"><div><span style="font-family: inherit; font-size: xx-large; font-weight: 700; white-space-collapse: preserve;">Performance</span></div></span></h3><div><span face="'Google Sans Text',sans-serif" style="color: black;"><h3 dir="ltr" style="background-color: transparent; font-style: normal; font-variant: normal; font-weight: 400; line-height: 1.2; margin-bottom: 4pt; margin-top: 14pt; text-decoration: none; vertical-align: baseline; white-space: pre;"><span id="docs-internal-guid-1066c108-7fff-6a69-8949-579f1e5f5e24" style="font-weight: normal;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap-mode: wrap; vertical-align: baseline;"><span style="font-family: inherit; font-size: large;">Lock-free MessageQueue</span></span></span></h3><span style="background-color: transparent; font-family: inherit; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><br /></span><p dir="ltr" style="background-color: transparent; font-style: normal; font-variant: normal; font-weight: 400; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; text-decoration: none; vertical-align: baseline; white-space: pre;"><span id="docs-internal-guid-8075debe-7fff-9e17-f147-45eea16540ce"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;">In </span><a href="https://developer.android.com/about/versions" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap-mode: wrap; vertical-align: baseline;">Android 17</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;">, apps targeting SDK 37 or higher will receive a new implementation of </span><a href="https://developer.android.com/reference/android/os/MessageQueue" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap-mode: wrap; vertical-align: baseline;">android.os.MessageQueue</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"> where the implementation is lock-free. The new implementation improves performance and reduces missed frames, but may break clients that reflect on </span><a href="https://developer.android.com/reference/android/os/MessageQueue" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap-mode: wrap; vertical-align: baseline;">MessageQueue</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"> private fields and methods.</span></span></span></p><h3 dir="ltr" style="background-color: transparent; font-style: normal; font-variant: normal; font-weight: 400; line-height: 1.2; margin-bottom: 4pt; margin-top: 14pt; text-decoration: none; vertical-align: baseline; white-space: pre;"><span id="docs-internal-guid-7b0d59ee-7fff-d74c-cf41-c190d73d2bcc" style="font-weight: normal;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap-mode: wrap; vertical-align: baseline;"><span style="font-family: inherit; font-size: large;">Generational garbage collection</span></span></span></h3><div style="background-color: transparent; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"><span style="font-family: inherit;"><br /></span></span></div><p dir="ltr" style="background-color: transparent; font-style: normal; font-variant: normal; font-weight: 400; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; text-decoration: none; vertical-align: baseline; white-space: pre;"><span id="docs-internal-guid-134b0b8b-7fff-9350-d2ff-21430f0867e0"><span style="font-family: inherit;"><a href="https://developer.android.com/about/versions" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap-mode: wrap; vertical-align: baseline;">Android 17</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"> introduces generational garbage collection to </span><a href="https://developer.android.com/guide/platform#art" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap-mode: wrap; vertical-align: baseline;">ART</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;">'s Concurrent Mark-Compact collector. This optimization introduces more frequent, less resource-intensive young-generation collections alongside full-heap collections. aiming to reduce overall garbage collection CPU cost and time duration. ART improvements are also available to over a billion devices running Android 12 (API level 31) and higher through Google Play System updates.</span></span></span></p><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Static final fields now truly final</span></span></h3><p dir="ltr" style="background-color: transparent; font-style: normal; font-variant: normal; font-weight: 400; line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt; text-decoration: none; vertical-align: baseline; white-space: pre;"><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span id="docs-internal-guid-37f785bf-7fff-b8f3-cf10-8a49d6722e0b"></span></span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Starting from Android 17 apps targeting Android 17 or later won’t be able to modify “static final” fields, allowing the runtime to apply performance optimizations more aggressively. An attempt to do so via reflection (and deep reflection) will always lead to IllegalAccessException being thrown. Modifying them via JNI’s SetStatic&lt;Type&gt;Field methods family will immediately crash the application.</span></span></p><h3 dir="ltr" style="background-color: transparent; font-style: normal; font-variant: normal; font-weight: 400; line-height: 1.2; margin-bottom: 4pt; margin-top: 14pt; text-decoration: none; vertical-align: baseline; white-space: pre;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Custom Notification View Restrictions</span></span></h3><p dir="ltr" style="background-color: transparent; font-style: normal; font-variant: normal; font-weight: 400; line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt; text-decoration: none; vertical-align: baseline; white-space: pre;"><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">To reduce memory usage we are restricting the size of </span><a href="https://developer.android.com/develop/ui/views/notifications/custom-notification" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">custom notification views</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">. This update closes a loophole that allows apps to bypass existing limits using URIs. This behavior is gated by the target SDK version and takes effect for apps targeting API 37 and higher.</span></span></p><h3 dir="ltr" style="background-color: transparent; font-style: normal; font-variant: normal; font-weight: 400; line-height: 1.2; margin-bottom: 4pt; margin-top: 14pt; text-decoration: none; vertical-align: baseline; white-space: pre;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">New performance debugging ProfilingManager triggers</span></span></h3><p dir="ltr" style="background-color: white; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">We’ve introduced several new system triggers to </span></span><a href="https://developer.android.com/topic/performance/tracing/profiling-manager/overview" style="text-decoration: none;"><span face="Arial,sans-serif" style="-webkit-text-decoration-skip: none; background-color: transparent; color: #1155cc; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre;">ProfilingManager</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;"> to help you collect in-depth data to debug performance issues. These triggers are</span></span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><a href="https://developer.android.com/reference/android/os/ProfilingTrigger#TRIGGER_TYPE_COLD_START" style="text-decoration: none;"><span face="Arial,sans-serif" style="-webkit-text-decoration-skip: none; background-color: transparent; color: #1155cc; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre;">TRIGGER_TYPE_COLD_START</span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">, </span></a><a href="https://developer.android.com/reference/android/os/ProfilingTrigger#TRIGGER_TYPE_OOM" style="text-decoration: none;"><span face="Arial,sans-serif" style="-webkit-text-decoration-skip: none; background-color: transparent; color: #1155cc; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre;">TRIGGER_TYPE_OOM</span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">, </span></span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">and</span></span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"> </span><a href="https://developer.android.com/reference/android/os/ProfilingTrigger#TRIGGER_TYPE_KILL_EXCESSIVE_CPU_USAGE" style="text-decoration: none;"><span face="Arial,sans-serif" style="-webkit-text-decoration-skip: none; background-color: transparent; color: #1155cc; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre;">TRIGGER_TYPE_KILL_EXCESSIVE_CPU_USAGE</span><span face="Arial,sans-serif" style="background-color: transparent; color: black; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;">.</span></a></p><p dir="ltr" style="background-color: white; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><br /></p><p dir="ltr" style="background-color: white; font-style: normal; font-variant: normal; font-weight: 400; line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt; text-decoration: none; vertical-align: baseline; white-space: pre;"><span id="docs-internal-guid-d604133b-7fff-b9a0-3a1e-e37d5790896e"><span style="font-family: inherit;"><span style="background-color: transparent; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;">To understand how to set up the new system triggers, check out the </span><a href="https://developer.android.com/topic/performance/tracing/profiling-manager/trigger-based-capture" style="text-decoration-line: none;"><span style="background-color: transparent; color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap-mode: wrap; vertical-align: baseline;">trigger-based profiling</span></a><span style="background-color: transparent; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"> and </span><a href="https://developer.android.com/topic/performance/tracing/profiling-manager/retrieve-and-analyze" style="text-decoration-line: none;"><span style="background-color: transparent; color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap-mode: wrap; vertical-align: baseline;">retrieve and analyze profiling data</span></a><span style="background-color: transparent; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"> documentation.</span></span></span></p><div style="background-color: transparent; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><br /></div><div style="background-color: transparent; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><span id="docs-internal-guid-55f5c8b6-7fff-efa1-c315-007fadeacdaf"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap-mode: wrap; vertical-align: baseline;"><span style="font-family: inherit; font-size: x-large;">Media and Camera</span></span></span></div><div style="background-color: transparent; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"><span style="font-family: inherit;"><br /></span></span></span></div><div style="background-color: transparent; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><span id="docs-internal-guid-4c617e9d-7fff-38c4-ecba-e3003fd9fc70"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"><span style="font-family: inherit;">Android 17 brings professional-grade tools to media and camera apps, with features like seamless transitions and standardized loudness.</span></span></span></div><div style="background-color: transparent; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><br /></div></span><div style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit; font-size: large;"><b>Dynamic Camera Session Updates</b></span><br /><span face="'Google Sans Text',sans-serif" style="color: black;"><span id="docs-internal-guid-754b342e-7fff-7ea6-e840-9144584abe4c"><span style="background-color: transparent; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-line: none; vertical-align: baseline; white-space: pre-wrap;"><div style="font-family: Arial, sans-serif; font-size: 11pt;"><span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"><br /></span></span></div></span></span><span id="docs-internal-guid-fa2d46b8-7fff-42d3-5b5b-f1a77d5d0dad"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">We have introduced</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">updateOutputConfigurations</span><a href="https://developer.android.com/reference/android/hardware/camera2/CameraCaptureSession" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">()</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">to </span></span><a href="https://developer.android.com/reference/android/hardware/camera2/CameraCaptureSession" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">CameraCaptureSession</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">. </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">This allows you to dynamically attach and detach output surfaces without the need to reconfigure the entire camera capture session. This change enables seamless transitions between camera use cases and modes (such as shooting still images vs shooting videos) without the memory cost and code complexity of configuring and holding onto all camera output surfaces that your app might need during camera start up. This helps to eliminate user-visible glitches or freezes during operation.</span></span></span></span></div><span face="'Google Sans Text',sans-serif" style="color: black;"><div style="background-color: transparent; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><span><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"><br /></span></span></span></div><div style="background-color: transparent; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre;"><pre style="color: #333333; line-height: 16.25px; margin: 0px;"><span style="color: blue;">fun</span> updateCameraSession(session: CameraCaptureSession, newOutputConfigs: List&lt;OutputConfiguration&gt;)) { <span style="color: green;">// Dynamically update the session without closing and reopening</span> <span style="color: blue;">try</span> { <span style="color: green;">// Update the output configurations</span> session.updateOutputConfigurations(newOutputConfigs) } <span style="color: blue;">catch</span> (e: CameraAccessException) { <span style="color: green;">// Handle error</span> } }</pre></div></span></div></name><div><name content="IMG" twitter:image=""><p dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span id="docs-internal-guid-47baeeaf-7fff-bd04-94d1-50588033277c"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;">Logical multi-camera device metadata</span></span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span id="docs-internal-guid-5295d0ed-7fff-bb4a-82f5-92b9c536dcaf"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">When working with logical cameras that combine multiple physical camera sensors, you can now request additional metadata from all active physical cameras involved in a capture, not just the primary one. Previously, you had to implement workarounds, sometimes allocating unnecessary physical streams, to obtain metadata from secondary active cameras (e.g., during a lens switch for zoom where a follower camera is active). This feature introduces a new key, </span></span><a href="https://developer.android.com/reference/android/hardware/camera2/CaptureRequest#LOGICAL_MULTI_CAMERA_ADDITIONAL_RESULTS" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">LOGICAL_MULTI_CAMERA_ADDITIONAL_RESULTS</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">, in</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><a href="https://developer.android.com/reference/android/hardware/camera2/CaptureRequest" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">CaptureRequest</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">and</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><a href="https://developer.android.com/reference/android/hardware/camera2/CaptureResult" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">CaptureResult</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">. By setting this key to ON in your </span></span><a href="https://developer.android.com/reference/android/hardware/camera2/CaptureRequest" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">CaptureRequest</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">, the</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><a href="https://developer.android.com/reference/android/hardware/camera2/TotalCaptureResult" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">TotalCaptureResult</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> w</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">ill include metadata from these additional active physical cameras. You can access this comprehensive metadata using </span></span><a href="https://developer.android.com/reference/android/hardware/camera2/TotalCaptureResult#getPhysicalCameraTotalResults()" style="text-decoration-line: none;"><span face="Arial, sans-serif" style="color: #1155cc; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">TotalCaptureResult.getPhysicalCameraTotalResults()</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"> to get more detailed information that may enable you to optimize resource usage in your camera applications.</span></span></span></p><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 4pt; margin-top: 14pt;"><span style="font-family: inherit; font-size: x-large; white-space-collapse: preserve;">Versatile Video Coding (VVC) Support</span></h3><p dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span id="docs-internal-guid-646ca2a8-7fff-4ef7-c420-916b50515c37"></span></span></span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-family: inherit;"><a href="https://developer.android.com/about/versions" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Android 17</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> adds support for the </span><a href="https://developer.android.com/guide/topics/media/media-formats#video-formats" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Versatile Video Coding (VVC)</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> standard. This includes defining the </span><a href="https://developer.android.com/guide/topics/media/media-formats#video-formats" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">video/vvc</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> MIME type in </span><a href="https://developer.android.com/reference/android/media/MediaFormat" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">MediaFormat</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">, adding new VVC profiles in </span><a href="https://developer.android.com/reference/android/media/MediaCodecInfo" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">MediaCodecInfo</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">, and integrating support into </span><a href="https://developer.android.com/reference/android/media/MediaExtractor" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">MediaExtractor</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">. This feature will be coming to devices with hardware decode support and capable drivers.</span></span></p><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 4pt; margin-top: 14pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Constant Quality for Video Recording</span></span></h3><p dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span id="docs-internal-guid-cdb2c501-7fff-5ac1-fe99-69646a32a140"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">We have added</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><a href="https://developer.android.com/reference/android/media/MediaRecorder#setVideoQuality(int)" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">setVideoEncodingQuality()</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">to</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><a href="https://developer.android.com/reference/android/media/MediaRecorder" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">MediaRecorder</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">.</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"> This allows you to configure a constant quality (CQ) mode for video encoders, giving you finer control over video quality beyond simple bitrate settings.</span></span></span></p><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 4pt; margin-top: 14pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Background Audio Hardening</span></span></h3><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Starting in Android 17, the audio framework will enforce restrictions on background audio interactions including audio playback, </span><a href="https://developer.android.com/media/optimize/audio-focus" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">audio focus</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> requests, and </span><a href="https://developer.android.com/reference/android/media/AudioManager#adjustStreamVolume(int,%20int,%20int)" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">volume change</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> APIs to ensure that these changes are started intentionally by the user.&nbsp;</span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span><span><span style="font-family: inherit; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">If the app tries to call audio APIs while the application is not in a valid lifecycle, the audio playback and volume change APIs will fail silently without an exception thrown or failure message provided. The audio focus API will fail with the result code </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">AUDIOFOCUS_REQUEST_FAILED</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;">.</span></span></span></span></p><h2 dir="ltr" style="line-height: 1.2; margin-bottom: 4pt; margin-top: 18pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: x-large;">Privacy and Security</span></span></h2><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 4pt; margin-top: 14pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Deprecation of Cleartext Traffic Attribute</span></span></h3><p dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span id="docs-internal-guid-e5b1de3e-7fff-c800-20c3-abad994fb01c"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">The</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><a href="https://developer.android.com/guide/topics/manifest/application-element#usesCleartextTraffic" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">android:usesCleartextTraffic</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">attribute is now deprecated. If your app targets (Android 17) or higher and relies on</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">usesCleartextTraffic="true"</span><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> without a corresponding </span><a href="https://developer.android.com/training/articles/security-config" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">Network Security Configuration</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, it will default to disallowing cleartext traffic. You are encouraged to migrate to </span><a href="https://developer.android.com/training/articles/security-config" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">Network Security Configuration</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> files for granular control.</span></span></span></p><span id="docs-internal-guid-e7ae648e-7fff-6b1b-0d26-632c3278857c"><div><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-size: large;"><div style="line-height: 1.2; margin-bottom: 4pt; margin-top: 14pt; text-align: left; white-space-collapse: collapse;"><span style="color: black; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;"><b>HPKE Hybrid Cryptography</b></span></span></div></span></span></div><p dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">We are introducing a public </span><a href="https://developer.android.com/reference/android/crypto/hpke/HpkeSpi" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">Service Provider Interface (SPI)</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> for an implementation of HPKE hybrid cryptography, enabling secure communication using a combination of public key and symmetric encryption (</span><a href="http://developer.android.com/reference/android/crypto/hpke/AeadParameterSpec" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">AEAD</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">).</span></span></p></span><p dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-family: inherit; font-size: xx-large; font-weight: 700; white-space-collapse: preserve;">Connectivity and Telecom</span></p><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 4pt; margin-top: 14pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Enhanced VoIP Call History</span></span></h3><p dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span id="docs-internal-guid-58c44997-7fff-435b-e253-ad1f12fb3cd0"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">We are introducing user preference management for app VoIP call history integration. This includes support for caller and participant avatar URIs in the system dialer, enabling granular user control over call log privacy and enriching the visual display of integrated VoIP call logs.</span></span></span></p><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 4pt; margin-top: 14pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Wi-Fi Ranging and Proximity</span></span></h3><p dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span style="font-family: inherit;"><a href="https://developer.android.com/guide/topics/connectivity/wifi-rtt" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Wi-Fi Ranging</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> has been enhanced with new Proximity Detection capabilities, supporting continuous ranging and secure peer-to-peer discovery. Updates to </span><a href="https://developer.android.com/guide/topics/connectivity/wifi-aware" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Wi-Fi Aware</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> ranging include new APIs for peer handles and PMKID caching for 11az secure ranging.</span></span></p><h2 dir="ltr" style="line-height: 1.2; margin-bottom: 4pt; margin-top: 18pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: x-large;">Developer Productivity and Tools</span></span></h2><h3 dir="ltr" style="line-height: 1.2; margin-bottom: 4pt; margin-top: 14pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit; font-size: large;">Updates for companion device apps</span></span></h3><p dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span id="docs-internal-guid-e83e967d-7fff-5160-5211-e69cb95ab6ea"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">We have introduced two new profiles to the</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><a href="https://developer.android.com/guide/topics/connectivity/companion-device-pairing" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">CompanionDeviceManager</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;"> to improve device distinction and permission handling:</span></span></span></p><ul style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 12pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Medical Devices:</span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> This profile allows medical device mobile applications to request all necessary permissions with a single tap, simplifying the setup process.</span></span></p></li><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 0pt;"><span id="docs-internal-guid-bc1cb96d-7fff-bf99-f608-1f9db2914b75"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; text-wrap-mode: wrap; vertical-align: baseline;">Fitness Trackers:</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"> The</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"> </span><a href="https://developer.android.com/reference/android/companion/AssociationRequest#DEVICE_PROFILE_FITNESS_TRACKER" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; text-wrap-mode: wrap; vertical-align: baseline;">DEVICE_PROFILE_FITNESS_TRACKER</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-wrap-mode: wrap; vertical-align: baseline;"><span style="font-family: inherit;">profile allows companion apps to explicitly indicate they are managing a fitness tracker. This ensures accurate user experiences with distinct icons while reusing existing watch role permissions.</span></span></span></p></li></ul><p dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span id="docs-internal-guid-78400345-7fff-0e11-e6a3-fb7445e19cf3"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">Also, the </span></span><a href="https://developer.android.com/guide/topics/connectivity/companion-device-pairing" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">CompanionDeviceManager</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">now offers a unified dialog for device association and Nearby permission requests. You can leverage the new</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><a href="https://developer.android.com/reference/android/companion/AssociationRequest.Builder#setExtraPermissions(java.util.Set%3Cjava.lang.String%3E)" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">setExtraPermissions</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">method in</span></span><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><a href="https://developer.android.com/reference/android/companion/AssociationRequest.Builder" style="text-decoration-line: none;"><span style="color: #1155cc; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">AssociationRequest.Builder</span></a><span face="Arial, sans-serif" style="font-size: 11pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">to bundle nearby permission prompts within the existing association flow, reducing the number of dialogs presented to the user.</span></span></span></p><span style="font-family: inherit; font-size: x-large;"><b>Get started with Android 17</b></span></name></div><div><name content="IMG" twitter:image=""><span id="docs-internal-guid-1a94494b-7fff-36be-df12-88c67fc2f56c"><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><br /></span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">You can </span><a href="https://www.google.com/android/beta" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">enroll any supported Pixel device</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> to get this and future Android Beta updates over-the-air. If you don’t have a Pixel device, you can </span><a href="https://developer.android.com/about/versions/17/get#on_emulator" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">use the 64-bit system images with the Android Emulator</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> in Android Studio.</span></span></p></span><span><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">If you are currently in the Android Beta program, you will be offered an over-the-air update to Beta 1.</span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">If you have Android 26Q1 Beta and would like to take the final stable release of 26Q1 and exit Beta, you need to ignore the over-the-air update to 26Q2 Beta 1 and wait for the release of 26Q1.</span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">We're looking for your feedback so please </span><a href="https://developer.android.com/about/versions/17/feedback" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">report issues and submit feature requests</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> on the </span><a href="https://developer.android.com/about/versions/16/feedback" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">feedback page</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">. The earlier we get your feedback, the more we can include in our work on the final release.</span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">For the best development experience with Android 17, we recommend that you use the latest preview of </span><a href="https://developer.android.com/studio/preview" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">Android Studio (Panda)</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">. Once you’re set up, here are some of the things you should do:</span></span></p><ul style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="2" dir="ltr" style="background-color: transparent; color: #202124; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; margin-left: 36pt; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Compile against the new SDK, test in CI environments, and report any issues in our tracker on the </span><a href="https://developer.android.com/about/versions/17/feedback" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">feedback page</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">.</span></span></p></li><li aria-level="2" dir="ltr" style="background-color: transparent; color: #202124; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; margin-left: 36pt; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Test your current app for compatibility, learn whether your app is affected by changes in Android 17, and install your app onto a device or emulator running Android 17 and extensively test it.</span></span></p></li></ul><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">We’ll update the </span><a href="https://developer.android.com/about/versions/17/download" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">preview/beta system images</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> and SDK regularly throughout the Android 17 release cycle. Once you’ve installed a beta build, you’ll automatically get future updates over-the-air for all later previews and Betas.</span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span id="docs-internal-guid-237c3aae-7fff-5cbd-cfa4-76554bc2affc"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">For complete information, visit the </span><a href="https://developer.android.com/about/versions/17" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">Android 17 developer site</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">.</span></span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 0pt; margin-top: 0pt;"><span><span><span style="font-family: inherit; font-size: large; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span id="docs-internal-guid-e27ac50d-7fff-d401-41d1-a09dcadbb92f"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline;">Join the conversation</span></span></span></span></span></p><p dir="ltr" style="line-height: 1.2; margin-bottom: 12pt; margin-top: 12pt;"><span id="docs-internal-guid-717838d6-7fff-c538-df2d-6378ec650f5d"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">As we move toward </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;">Platform Stability</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> and the final stable release of Android 17 later this year, your feedback remains our most valuable asset. Whether you’re an </span><a href="https://www.reddit.com/r/android_canary/" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">early adopter on &nbsp; the Canary channel</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> or an </span><a href="https://www.reddit.com/r/android_beta/" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">app developer testing on Beta 1</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">, consider joining our communities and filing feedback. We’re listening.</span></span></span></p></span><p></p></name></div></div></div>
  5. Trade-in mode on Android 16+

    Mon, 26 Jan 2026 17:00:00 -0000

    <name content="IMG" twitter:image=""><p><span style="font-family: inherit;"></span></p><h4 style="text-align: left; white-space-collapse: preserve;"><b style="font-size: x-large;"><i>Supporting Longevity through Faster Diagnostics</i></b></h4><p><span style="font-family: inherit;"><i>Posted by&nbsp;<span style="white-space-collapse: preserve;">Rachel S, Android Product Manager</span></i></span></p><p><span style="font-family: inherit;"><i></i></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: inherit;"><i><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6Aq4lb9qsSAAh7hBxqYjCIYImJREOYZUqPO7yYdvbr-81VWa3lPQdkT-ekLr3Xd-YBWbEShGKr0fuYMoW0skg_vtHrzQxYf42jUqkAgqwo-11igWWNa_gxW-Rpb1TJAGgeumE0LjzoJej8efMSW6Ce7mUmaA0x_n6RxG6-5SpYQYIofO7bRF31J2v4wI/s4209/Android_TradeIN_Mode_Blog.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="1253" data-original-width="4209" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6Aq4lb9qsSAAh7hBxqYjCIYImJREOYZUqPO7yYdvbr-81VWa3lPQdkT-ekLr3Xd-YBWbEShGKr0fuYMoW0skg_vtHrzQxYf42jUqkAgqwo-11igWWNa_gxW-Rpb1TJAGgeumE0LjzoJej8efMSW6Ce7mUmaA0x_n6RxG6-5SpYQYIofO7bRF31J2v4wI/s16000/Android_TradeIN_Mode_Blog.png" /></a></i></span></div><span style="font-family: inherit;"><span style="font-family: inherit; white-space-collapse: preserve;"><p style="font-style: italic;"><i style="font-family: inherit;">Trade-in mode: faster assessment of a factory-reset phone or tablet, bypassing setup wizard, a new feature on Android 16 and above.</i></p><h3 style="text-align: left;"><span style="font-family: inherit; font-size: x-large;">Supporting device longevity</span></h3></span></span><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">Android is committed to making devices last longer. With device longevity comes device circularity: phones and tablets traded-in and resold. <span style="font-family: inherit;"><a href="https://www.gsma.com/solutions-and-impact/connectivity-for-good/external-affairs/climate-action/rethinking-mobile-phones/" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">GSMA reported</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> that secondhand phones have around 80-90% lower carbon emissions than new phones. The secondhand device market has grown substantially both in volume and value, a trend projected to continue.</span></span></p><p><span id="docs-internal-guid-7ebb36e1-7fff-1fb1-9f1b-742bf18d2765"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline;"><span style="font-family: inherit;">Android 16 and above offers an easy way to access device information on any factory reset phone or tablet via the new </span><span style="color: #188038; font-family: Roboto Mono, monospace;"><span style="font-size: 10pt; white-space-collapse: preserve;">tradeinmode </span></span></span></span><span><span style="font-family: inherit;">parameter, accessed via adb commands. This means you can view quality indicators of a phone or tablet, skipping each setup wizard step. Simply connect a phone or tablet with adb, and use&nbsp;</span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">tradeinmode</span><span face="&quot;Google Sans&quot;, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="font-family: inherit;"><a href="https://androidsource.devsite.corp.google.com/docs/core/perf/trade-in-mode" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">commands</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span></span></span><span style="font-family: inherit;">to get information about the device.</span></p><p><span id="docs-internal-guid-aaa80139-7fff-cde7-5ee4-78a7e10ff168"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit; font-size: large;">Trade-in mode: What took minutes, now takes seconds </span></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Faster trade-in processing – </span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">By bypassing setup wizard, trade-in mode improves device trade ins. The mode enables immediate access to understand the ‘health’ of a device, helping everyone along the secondhand value chain check the quality of devices that are wiped. We’ve already seen significant increases in processing secondhand Android devices!&nbsp;</span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><br /></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 700; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Secure evaluation </span><span style="font-weight: 700; white-space-collapse: preserve;">– </span><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">To ensure the device information is only accessed in secure situations, the device must 1) be factory reset, 2) not have cellular service, 3) not have connectivity or a connected account, and 4) be running a non-debuggable build.</span></span></p><p><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">Get device health information with one command – </span></span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">You can view all the below device information with adb command from your workstation</span> </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">adb shell tradeinmode getstatus</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">, skipping setup wizard:&nbsp;</span></span></p><p></p><ul style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Device information&nbsp;</span></span></p></li><ul style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="2" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Device IMEI(s)&nbsp;</span></span></p></li><li aria-level="2" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Device serial number&nbsp;</span></span></p></li><li aria-level="2" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Brand&nbsp;</span></span></p></li><li aria-level="2" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Model&nbsp;</span></span></p></li><li aria-level="2" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Manufacturer&nbsp;</span></span></p></li><li aria-level="2" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Device model, e.g., Pixel 9</span></span></p></li><li aria-level="2" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Device brand, e.g., Google</span></span></p></li><li aria-level="2" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Device manufacturer, e.g., Google</span></span></p></li><li aria-level="2" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Device name, e.g., tokay</span></span></p></li><li aria-level="2" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">API level to ensure correct OS version, e.g., launch_level : 34</span></span></p></li></ul><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Battery heath&nbsp;</span></span></p></li><ul style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="2" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Cycle count</span></span></p></li><li aria-level="2" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Health</span></span></p></li><li aria-level="2" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">State, e.g., unknown, good, overheat, dead, over_voltage, unspecified_failure, cold, fair, not_available, inconsistent</span></span></p></li><li aria-level="2" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Battery manufacturing date&nbsp;</span></span></p></li><li aria-level="2" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Date first used&nbsp;</span></span></p></li><li aria-level="2" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Serial number (to help provide indication of genuine parts, if OEM supported)</span></span></p></li><li aria-level="2" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Part status, e.g., replaced, original, unsupported</span></span></p></li></ul><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Storage&nbsp;</span></span></p></li><ul style="margin-bottom: 0px; margin-top: 0px; padding-inline-start: 48px;"><li aria-level="2" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Useful lifetime remaining&nbsp;</span></span></p></li><li aria-level="2" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: circle; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Total capacity&nbsp;</span></span></p></li></ul><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Screen Part status, e.g., replaced, original, unsupported</span></span></p></li><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Foldables (number of times devices has been folded and total fold lifespan)&nbsp;</span></span></p></li><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Moisture intrusion&nbsp;</span></span></p></li><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">UICCS information i.e., Indication if there is an e-SIM or removable SIM and the microchip ID for the SIM slot</span></span></p></li><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Camera count and location, e.g., 3 cameras on front and 2 on back</span></span></p></li><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><span style="font-family: inherit;">Lock detection for select device locks</span></span></p></li><li aria-level="1" dir="ltr" style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; list-style-type: disc; text-decoration: none; vertical-align: baseline; white-space: pre;"><p dir="ltr" role="presentation" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">And the list keeps growing! Stay up to date </span><a href="https://androidsource.devsite.corp.google.com/docs/core/perf/trade-in-mode" style="text-decoration: none;"><span style="background-color: transparent; color: #1155cc; font-style: normal; font-variant: normal; font-weight: 400; text-decoration-skip-ink: none; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap;">here</span></a><span style="background-color: transparent; color: black; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">.&nbsp;</span></span></p></li></ul><div><span style="white-space-collapse: preserve;"><br /></span></div><div><span id="docs-internal-guid-97633792-7fff-687e-131b-86e29c702b30"><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;">Run your own tests – </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Trade-in mode enables you to run your own diagnostic commands or applications by entering the evaluation flow using </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">tradeinmode evaluate</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">. The device will automatically factory reset on reboot after evaluation mode to ensure nothing remains on the device.&nbsp;</span></span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;">Ensure the device is running an approved build – </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Further, when connected to the internet, with a single command </span></span><span style="color: #188038; font-family: &quot;Roboto Mono&quot;, monospace; font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">tradeinmode getstatus --challenge</span><span face="&quot;Google Sans&quot;, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span face="&quot;Google Sans Text&quot;, sans-serif" style="background-color: white; color: #d01884; font-size: 10pt; font-style: italic; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">CHALLENGE</span><span face="&quot;Google Sans&quot;, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: inherit;">you can test the device’s operating system (OS) authenticity, to be sure the device is running a trusted build. If the build passes the test, you can be sure the diagnostics results are coming from a trusted OS.&nbsp;</span></span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;">There’s more</span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"> – You can use commands to factory reset, power off, reboot, reboot directly into trade-in mode, check if trade-in mode is active, revert to the previous mode, and pause tests until system services are ready.&nbsp;</span></span></p><span style="font-family: inherit;"><br /></span><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: inherit;"><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; font-weight: 700; vertical-align: baseline; white-space-collapse: preserve;">Want to try it? </span><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">Learn more about the </span><a href="https://source.android.com/docs/core/perf/trade-in-mode" style="text-decoration-line: none;"><span style="color: #1155cc; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; text-decoration-line: underline; text-decoration-skip-ink: none; vertical-align: baseline; white-space-collapse: preserve;">developer steps and commands</span></a><span style="font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;">.&nbsp;</span></span></p><div><span face="&quot;Google Sans&quot;, sans-serif" style="font-size: 10pt; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-emoji: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><br /></span></div></span></div><p></p></name>