Google announced Android 12L just weeks after the release of Android 12, and it’s the first major Android update aimed at large screen devices since the short-lived Android 3.0 Honeycomb release in 2011. After a few months of beta testing, Google has publicly released Android 12L. The update is currently available for Google’s own Pixel devices but will eventually make its way to devices from other Android device makers. Since the source code is available, any company that builds AOSP — including ourselves — can now rebase on top of Android 12L, thus incorporating all of the improvements it brings to large screen devices. So what improvements have been made, and why is Google dedicating an entire release to large screen devices?

Android has matured quite significantly in the last decade, and although Android tablets have not caught up to the iPad in terms of market share, their popularity has grown considerably owing to the COVID-19 pandemic driving work and education to peoples’ homes. Similarly, Chromebooks have been in high demand this past year due to their low cost. On the other end of the price spectrum is the foldable, phones which have captured the attention of casual and enthusiast consumers alike thanks to their novelty. Google sees the growth of these form factors as an opportunity to revitalize Android for large screen devices, which is the driving force behind the changes in Android 12L and beyond.

A summary of the IDC Quarterly Personal Computing Device Tracker report for Q2 2021. Credits: Google

In this article, we’ll dive deep into all the user interface tweaks, new features, behavior changes, and API updates in Android 12L. The bulk of these changes apply to large screen devices, but a few changes also apply to smartphones and other small screen devices.

Table of Contents

Android 12L Release Date

Android 12L, which is also called Android Sv2, Android SC-V2, or Android 12.1 in documentation, is now publicly available alongside framework API level 32. An update is available for supported Pixel devices from the Pixel 3a series onward and will be made available in the coming months for devices from other OEMs. Samsung, Lenovo, and Microsoft have confirmed plans to bring the 12L update to their respective devices later this year.

Source code for the initial Android 12L release can be found at android.googlesource.com under the android12L-release branch and android-12.1.0_r1 tag.

Although Google states that it has “been careful not to introduce any breaking changes” for app developers in the 12L release, the company will not update Google Play’s target API level requirement to mandate targeting API level 32. However, there are still several notable changes that app developers need to account for, especially if they plan to build applications that target tablets, foldables, or Chromebooks. Device makers that design or manufacture tablets or foldables should also look at what Google is building for Android 12L, even though we can expect few changes to the current compatibility requirements, as the update includes many UI changes and features that Google recommends be adopted or extended.

User Interface Changes in Android 12L

Material You for large screen devices

Material You is the third major version of Google’s Material design language, first introduced with Android 5.0 Lollipop in late 2014. Google’s updated design language embraces personalization, adaptive layouts, and accessible styles. Through a new theme engine that dynamically recolors parts of the system, Material You is personal. Through new APIs and user interface changes that make Android look better on tablets and foldables, Material You is adaptive. And finally, through a contextually aware system that customizes the text and size, Material You is accessible.

Material You, also referred to as Material Design 3 or Material Design “Next” in public documentation, made its product debut with Android 12. However, the personalization, adaptability, and accessibility improvements that Material You brought to Android 12 were designed with the smartphone form factor in mind. With the Android 12L release, Google is expanding its redesign efforts to cover large screen devices like tablets and foldables*. Devices with a screen width greater than 600dp have enough real estate to show two panes of content, which is the impetus behind the user interface changes in Android 12L.

Indeed, Android 12L adjusts the layout of multiple system interfaces to take advantage of the wider screens of tablets and foldables. The redesigned elements include the always on display (AOD), lock screen, home screen, notification shade, recent apps overview, power menu, settings, and several system applications.


*Although the term “foldables” typically refers to mobile devices with a foldable display, Google’s definition also covers dual-screen devices (where a hinge physically divides the screen). Thanks to Windows Central for pointing this out.

Lock screen

In Android 12, Google tweaked the lock screen layout to put the clock front and center when all notifications are cleared. By default, AOSP uses a digital clock style, which has been made substantially larger and separated into two rows (one for the hours and one for the minutes). The same is true for large screen devices running Android 12L, though there’s an option to choose the clock layout.

To the top left of the clock is the smart space widget, for which a very basic implementation has been provided as part of AOSP. (A more feature complete implementation can be seen in Google’s Android 12 release for Pixel devices, though the “At a Glance” widget is proprietary to Google.) When there are visible notifications, the clock shifts to the left half of the screen to make room for the notifications column on the right. After 3 notifications are shown, any further notifications will be collapsed in an overflow card. (This configuration is controlled by the integer keyguard_max_notification_count in SystemUI.)

Additional buttons may be shown on screen depending on the user’s settings. First, if there are multiple profiles on the device, the user account switcher button will appear at the top right. Next, if the user has enabled “show wallet” and “show device controls” in lock screen settings, floating buttons to access the Quick Access Wallet and Device Controls modules will be shown on the bottom right and left, respectively. (In Android 12 and higher, the Wallet UI is part of SystemUI rather than being provided by a separate QuickAccessWallet application. The default package for handling Device Controls remains SystemUI. For more information on implementing Quick Access Wallet and/or Device Controls, please refer to Google’s documentation.)

If the user sets a PIN or pattern to unlock the keyguard, the entry UI will be shown on the left or right half of the screen depending on the side the user swiped from. If the user taps on either the left or right side, the PIN/pattern entry UI will then shift to that side of the screen. This behavior enables one-handed keyguard dismissal on large screen devices. The password entry UI remains centered, with the input method entering its full screen mode.

The lockscreen PIN/pattern can shift to the left or right side on Android 12L. Credits: Esper

Always on display

AOSP’s always on display (AOD) implementation does not feature substantial UI differences from the lock screen, as users expect to see a smooth transition between the AOD and lock screen. Like the lock screen, the AOD puts the clock right in the middle of the screen, and it takes up a substantial portion of the viewing area to make the time easy to view at a glance. Beneath the clock, in a much smaller font, is the current battery level. To reduce the number of pixels lit up on the screen on OLED panels, and visual clutter when viewing at a distance, notification previews remain hidden on the AOD in favor of icons.

Home screen

On large screen devices, Launcher3 is capable of showing two home screen pages simultaneously. This is currently controlled by the Launcher3 flags ENABLE_TWO_PANEL_HOME and ENABLE_TWO_PANEL_HOME_IN_PORTRAIT, however, this feature does not work in current builds.

The launcher’s widget picker now covers more of the screen when browsing through widgets for a particular application. It also now supports grouping widgets together into categories instead of just by package. In AOSP, the Conversation widget is placed under the Conversations category, for example. Meanwhile, Google’s Pixel Launcher fork places weather widgets under their own widget category in Android 12L. Launcher developers can define custom categories to place widgets into by editing widget_sections.xml.

The app drawer (“AllApps”) interface has added support for two-line labels in Android 12L. Currently, this feature is gated behind the “ENABLE_TWOLINE_ALLAPPS” feature flag.

Lastly, a new launcher flag called “ENABLE_BULK_ALL_APPS_ICON_LOADING” has been added. When enabled, the launcher loads all icons in the app drawer in a series of bulk SQL queries, reducing the cost of SQL lookups and thus improving the loading time.

Notification shade

In Android 12, and by extension Android 12L, Google significantly revamped the user interface of the notification panel. The brightness slider and Quick Settings tiles have been made substantially larger than before, leaving room for only 8 tiles to be displayed at a time in a 4×2 grid. (On large screen devices, Quick Settings is shown in a 3×3 grid when the device is in portrait orientation.) Text and background color clearly describe the purpose of the tile and its status, though the tile’s description is still shown in the notification panel’s “expanded” state. Expansion of the shade also reveals the build number and allows the user to swipe between pages of Quick Settings tiles. 

The notification shade in Android 12L
The notification shade in Android 12L, with a new two-pane layout. Credits: Esper

Beneath the Quick Settings tiles is a row of up to 4 buttons: Edit, Profiles, Power Menu, and Settings. The Edit and Settings buttons perform the same actions as before, that is launch the Quick Settings edit flow and the Settings app respectively. Meanwhile, the Power Menu button launches the new compact power menu of Android 12+ in place of the full-screen power menu that integrated the Device Controls and Quick Access Wallet modules of Android 11.

Google has also introduced a new animation for expanding the notifications panel. The height of the Quick Settings tiles expand as the notification panel expands downward.

Power menu

The new, more compact power menu of Android 12+ features up to 2 rows of buttons. The visibility of this new power menu, known internally as “PMLite”, is set to true by default in AOSP. The power menu is no longer shown by default when the user performs a long-press gesture on the device’s power button; rather, the component set as the default Assistant service is launched when the user long presses the power button. This behavior can be overridden, however. Device makers can also choose whether to surface the setting to change the long press on power button behavior.

The power menu in Android 12L. By default, it’s a 1×3 grid, but it gains an additional row once you add the ‘lockdown’ button. Credits: Esper

Settings

Settings is one of the key system applications updated to support a two pane layout. This interface is enabled by default for large screen devices.

The left pane will always show the top-level Settings page, while the right pane will show any Settings subpages that the user opens. If the application supports it, Settings can also embed the Activity specified by the application.

The two pane Settings layout in Android 12L. Credits: Esper

Recents overview

Google made multiple UI changes to the recents overview in Android 12L to accommodate large screen devices. First, the preview card for the app currently in use is much larger. Second, the “split” button to launch the app in split-screen mode is now prominently displayed rather than tucked away behind the context menu that appears when long-pressing the app’s icon. Third, the preview cards for all the previously used apps have been made much smaller to fit within two rows. These UI changes make Android’s multitasking system more discoverable and make switching between recent tasks easier. Coupled with the new taskbar feature, it’s clear that multitasking is a key focus for Google in Android 12L.

Whenever two apps have been paired in split-screen mode, their icons are placed side by side in the recents overview. To create an app pair, simply launch both apps in split-screen mode. Tapping on an app pair in the recents overview will reopen both apps in split-screen mode.

One subtle UI change is the redesign of the “clear all” button that appears all the way at the end of the recents list. The button now has an opaque, pill-shaped background to make it stand out against the background.

An even subtler UX change in the recents overview is the addition of haptic feedback when scrolling through apps.

Miscellaneous UI changes

  • When exiting an app through the back gesture/button, the icon now gracefully animates towards its home screen location. In Android 12, this animation only occurred when exiting an app through the home gesture/button.
The new animation in Android 12L when exiting an app to the homescreen through a back swipe gesture/back button press. Credits: Esper
  • The Internet panel and screen recorder panels now appear anchored at the center of the screen rather than at the bottom.
  • When resizing windows in split-screen mode, Android will no longer show a live preview of the windows being resized. Rather, Android replaces the window contents with the app’s icon centered on an opaque light or dark background.
Image
Resizing windows in split-screen mode in Android 12L. Credits: Esper
  • The multi-user switcher UI has been revamped. When tapping the user switcher button in the notifications panel, the multi-user switcher now opens in a centered pop-up window that floats above other system interfaces. The old UI comes from the days of Android 5.0 Lollipop, while the new UI is more in line with modern Android design. When tapping the user switcher on the lock screen, a semi-transparent dropdown menu lets you switch between users.
  • Settings > Display > Colors now has additional sample photos to showcase how screen mode changes affect color reproduction.
  • The screen cast Quick Setting tile now has a chevron indicating it opens a menu rather than acts as an on/off toggle.
  • The default position of the slider in audio adjustment settings is now properly centered.
  • The default wallpaper included in AOSP has been changed.
  • The Internet panel now shows a “turn off airplane mode” button when the panel is expanded and airplane mode is enabled.
  • A new 6×5 grid option for the Launcher.
  • A new fingerprint unlock animation.

These UI changes, while beneficial for large screen consumer hardware, may not be appropriate for enterprise or fleet devices. Because Esper builds Android from source, we can customize, extend, or strip many of these changes. Contact us if you have any requests.

New Features in Android 12L

Taskbar

A staple of desktop operating systems, the taskbar finally makes an appearance in AOSP with Android 12L. Android’s taskbar, like the aforementioned UI changes, only appears on devices with a screen above 600dp. The taskbar is built into Launcher3 and is integrated with the application dock at the bottom of the home screen.

The user’s selection of applications will appear on the taskbar at the bottom of the screen in every application. Google chose an opaque gray color for the taskbar’s background to visually distinguish it from the application window. When the user returns to the home screen, the taskbar’s background becomes transparent to show the wallpaper. The taskbar will automatically minimize when viewing a full-screen application or entering the launcher’s app tray, but it can also be minimized by long-pressing on any part of the taskbar.

A demo of the taskbar in Android 12L. Credits: Esper

The taskbar in Android 12L is rather simple in current builds. Users can tap on an app to quickly switch to it, or they can long-press and drag an app’s icon to either half of the screen to quickly launch that app in split-screen mode.

The taskbar currently does not support showing recently launched applications, more than 6 applications at a time (unless apps are placed in a folder), or a context menu when long pressing an app. The feature flag “ENABLE_TASKBAR_POPUP_MENU” enables long pressing the taskbar icons to show the context menu, but it is currently disabled by default.

The taskbar also does not integrate any elements currently found in the status bar, such as the date and time, but it does integrate the 3-button navigation keys which are shown on the right edge.

The 3-button navigation bar, integrated into Android 12L’s taskbar. Credits: Google

If you wish to test split-screen mode behavior in Android 12L, you can use the new Window Manager shell commands accessed through:

dumpsys activity service SystemUIService WMShell <command>

Here is the documentation for this CLI:

Window Manager Shell commands:
  help
      Print this help text.
  
    Dump Window Manager Shell internal state
  pair  
  unpair 
    Pairs/unpairs tasks with given ids.
  moveToSideStage  
    Move a task with given id in split-screen mode.
  removeFromSideStage 
    Remove a task with given id in split-screen mode.
  setSideStagePosition 
    Sets the position of the side-stage.
  setSideStageVisibility 
    Show/hide side-stage.

Notification to window

In addition to the taskbar, Google is testing another method in Android 12L to quickly launch an app in split-screen mode. Called notification to window, the feature allows a user to start an app’s PendingIntent (ie. an Activity from a notification) through a notification drag-and-drop gesture. The user can launch an app Activity to a pop-up or split-screen window by long-pressing on a heads-up notification or a notification in the notifications panel and then dragging it to the left or right side of the screen.

A demo of the ‘notification to window’ feature. Credits: Esper

This feature is not currently enabled by default in Android 12L, but it can be by setting the SystemUI configuration value config_notificationToContents to true. With superuser access, this value can be quickly set to true by creating an overlay through the Fabricated Overlay API or CLI. For example:

cmd overlay fabricate --target com.android.systemui --name NotificationToContents android:bool/config_notificationToContents 0x12 0x01

The generated overlay can then be enabled by running:

cmd overlay enable com.android.shell:NotificationToContents

Note that this feature does not work properly without additional patches; oftentimes, a long press of a heads-up notification will expand to show that notification’s settings rather than pop out as intended. This gesture will likely be optimized in future preview releases.

Dynamic colors in AOSP

Although Google markets its dynamic coloring theme engine as a marquee feature of Android 12, the company did not provide a fully open-source implementation of its theme engine with the AOSP Android 12 source code release. However, that has changed with AOSP Android 12L, as not only is the theme engine fully open source, but it is enabled by default in AOSP builds. (This feature is controlled by a SystemUI configuration value called flag_monet.)

Material You’s wallpaper-based theming engine, code-named “monet,” generates a rich pastel color palette from the user’s wallpaper. A color extraction engine employing a clustering algorithm with Material color targets determines the dominant and less dominant colors of the user’s wallpaper. A palette generation algorithm then creates a rich palette of 5 colors — 2 neutral and 3 accent colors — and 12 shades of Material color that are used to determine the hues closest to the user’s wallpaper. Finally, these color values are stored in an index that apps can call through an API. (For more information on dynamic color, visit Google’s Material Design 3 documentation.)

With the Android 12L source code release, monet’s palette generation algorithm has been included. The core color extraction algorithm, color appearance model (CAM), and a post-processing/filtering algorithm were already included in the current AOSP Android 12 release, thus many device makers are already moving forward with implementing dynamic colors using their own palette generation algorithm. 

For developers looking to test dynamic colors, Android’s “paint chips” widget, which can be added after viewing Android 12’s Easter egg, offers a quick glance at every color generated by the dynamic coloring system.

AOSP does not provide a user affordance to opt out of palette generation once “monet” is enabled, thus every wallpaper change will trigger a change in colors*. This has the added side effect of recreating the activities of every application, akin to a normal configuration change. However, AOSP does not provide a new configuration change type to account for this, so third-party applications cannot opt out of having their activities be destroyed and recreated, as pointed out by CommonsWare. Repeated background wallpaper changes can thus be abused to create a denial-of-service attack, as pointed out by XDA-Developers. Fortunately, this issue has been resolved in Android 12L as theme changes are no longer permitted to occur when an app changes the wallpaper while in the background.

01-18 19:11:04.847 2793 2793 I ThemeOverlayController: Wallpaper changed from background app, keep deferring color events. Accepting: true

*Although Android does not allow the end-user to opt-out of theme changes when the wallpaper updates, Esper can disable ‘monet’ at the platform level if your business decides it needs to remotely update the wallpaper from our Console.

Dynamic colors in boot animation

Android 12L enables support for dynamic color boot animations, a feature that has since been backported to the first Android 12 Quarterly Platform Release (QPR1). As boot animations are traditionally a sequence of static PNG images, dynamic color is applied to them in a rather clever way. Rather than directly rendering the PNG images contained within the boot animation file, the new dynamic coloring render mode treats the R, G, B, and A channels of each image as area masks, interpolating between the start and end colors based on the progression of the animation. 

Device makers can enable dynamic colors for the boot animation by adding the following line as the second line to desc.txt:

dynamic_colors PATH #RGBHEX0 #RGBHEX1 #RGBHEX2 #RGBHEX3

where PATH is the file path of the part to apply the dynamic color transition to, RGBHEX0 is the first start color masked by the R channel, RGBHEX1 is the second start color masked by the G channel, RGBHEX2 is the third start color masked by the B channel, and RGBHEX4 is the fourth start color masked by the A channel.

The end colors, meanwhile, are read from the following four system properties: persist.bootanim.color1, persist.bootanim.color2, persist.bootanim.color3, and persist.bootanim.color4.

Device makers should prepare their PNG images so that the R, G, B, A channels indicate the areas to draw color1, color2, color3 and color4 respectively.

Sample video demonstrating the boot animation using dynamic colors. Credits: Esper

The bootanimation-dark.zip file in Android 12L for Pixel devices contains an implementation of this feature. More sample videos can be viewed here.

Press & hold duration for the long-press power button gesture

If the device maker chooses to surface the setting to change the long press on power button gesture, then the user will have the ability to adjust the gesture’s sensitivity in Android 12L. A new “press & hold duration” slider has been added to the “Press and hold power button” settings page, which lets the user “adjust [the] sensitivity [of the gesture] by choosing how long to press & hold the power button.” The slider ranges from “short” (250ms) to “long” (750ms), with three intermediary values (350, 500, or 650ms). AOSP defaults to a duration of 500ms for triggering this gesture. This feature was backported to Android 12 QPR1.

Android 12L adds a sensitivity slider for the press & hold power button gesture. Credits: Esper

Esper can customize the behavior of the power button to meet your needs, whether that’s to disable the assistant invocation, hide the power menu, or do something else.

Quick wallpaper picker

Launcher3’s Developer Options added a new feature flag called “QUICK_WALLPAPER_PICKER.” Its description reads: “Shows quick wallpaper picker in long-press menu.” When enabled on AOSP, the feature does not seem to function, as the implementation is missing from Launcher3 and WallpaperPicker. In Google builds of Android 12L, however, support for the feature is present, and it is enabled by default.

Google’s implementation stores the 5 most recent wallpapers in an array of JSON objects, with the wallpaper’s id, collectionId, thumbnail uri, component, and color. When the user opens the context menu by long-pressing anywhere on the home screen, a carousel containing the thumbnails of these 5 wallpapers is shown at the top.

The Quick Wallpaper Picker in Pixel Launcher from Android 12L. Credits: Esper

Google Emoji 14.0

In September, the Unicode Consortium released version 14.0.0 of the Unicode Standard. The updated standard brings 37 new emoji characters. As part of the Android 12L release, Google has updated its Noto Emoji fonts to include the new Emoji 14.0 characters. For a thorough look at the new emoji in Google’s Emoji 14.0 library, we recommend reading Emojipedia’s changelog.

The new emoji in Android 12L. Credits: Esper

App developers should be aware that as of February 2, 2022, Google Play requires apps running on Android 12 or later to support the latest Unicode Emoji library within 4 months of its release, as pointed out by Android Police. Developers have a few options to remain compliant with this policy update: Enable emoji if AppCompat is in use, use an existing EmojiCompat library across all surfaces within the app, or update the handling and font/images for emoji based on the latest Unicode version. You can read more about Google Play’s upcoming policy changes here, and more specifically about the new Android Emoji policy here.

Merging the home screen and app drawer search boxes

A feature flag called “ENABLE_ONE_SEARCH” was added to the developer options of Launcher3 during Android 12L’s development, but it was removed before launch. When this flag was enabled, tapping the Google search box on the home screen would launch the new, much faster on-device search interface introduced in Android 12 for the app drawer. This feature can be seen in action in this video. Note that the search provider is handled by a proprietary Google app and is not a part of AOSP, which is also the case for the Google search box.

Quickly launch an app in split screen mode from its PiP window

When an app is put into picture-in-picture mode, Android 12L can show a split screen button in the PiP window whenever another app is open. Tapping this button will launch both apps in split screen mode as an app pair.

This button is not shown by default. To enable it, the SystemUI flag config_pipEnableEnterSplitButton must be set to true.

Opportunistic switching between 5G and 4G network stacks

For devices that don’t support simultaneous 5G connections on both SIMs, operators can use Android 12L’s new opportunistic switching capability. One new configuration lets operators decide how long to wait before the opportunistic 4G network stack goes out of service before switching to the primary 5G network stack. Another configuration lets operators control how long to wait to scan after switching back to the primary 5G network stack. The idea is to minimize the ping-ponging effect of the device constantly switching back and forth between the primary and opportunistic stacks.

Voice over 5G

A new carrier configuration lets operators show a VoNR (Voice over New Radio) toggle in settings. This is intended for devices that support routing voice calls over 5G. The toggle’s visibility defaults to true.

Removed features

  • Android 12L removes code related to “Content Push”, which placed a button labeled “Push” in the recents overview. This button, when pressed, would have likely started mirroring that app to a connected PC. While this button has been scrapped, Google’s app mirroring plans live on.
  • Another feature that has been removed from Launcher3 in Android 12L is proactive chips in the recents overview. For a brief period, Google used this feature to surface Google Lens-powered translation hints in the recents overview.
  • The screen recorder built into SystemUI no longer shows the “show touches on screen” option. Google says this option was removed “because the touch points currently cannot be recorded due to changes in how the cursor is drawn.”

Behavior Changes in Android 12L

Broader support for multi-window mode

According to Google’s documentation, Android 12 and later releases make multi-window mode standard behavior. 

On larger screens (≥ 600dp), Android will force all applications to be resizable regardless of the value they set for the android:resizeableActivity attribute. However, if this attribute is set to false, then the platform will launch the app in screen compatibility mode to conform to display dimensions. Compatibility mode has been around since the early days of Android, but it has been significantly improved in Android 12L.

On smaller screens (< 600dp), Android will check an activity’s minWidth and minHeight to determine if it can run in multi-window mode, assuming that the android:resizeableActivity attribute is set to true. If it’s false, then Android will not allow the app to run in multi-window mode.

Device makers can override these behaviors by changing the values of config_supportsNonResizableMultiWindow and config_respectsActivityMinWidthHeightMultiWindow respectively. These values both default to ‘0’ in AOSP. Developers can override these behaviors at runtime through the ‘wm’ shell command, or by toggling the “force activities to be resizable” and “enable non-resizable in multi window” features in developer options.

Here are the new multi-window shell commands accessed through ‘wm’:

    set-multi-window-config
       Sets options to determine if activity should be shown in multi window:
         --supportsNonResizable [configValue]
           Whether the device supports non-resizable activity in multi window.
           -1: The device doesn't support non-resizable in multi window.
            0: The device supports non-resizable in multi window only if
                this is a large screen device.
            1: The device always supports non-resizable in multi window.
         --respectsActivityMinWidthHeight [configValue]
           Whether the device checks the activity min width/height to determine
           if it can be shown in multi window.
           -1: The device ignores the activity min width/height when determining
                if it can be shown in multi window.
            0: If this is a small screen, the device compares the activity min
                width/height with the min multi window modes dimensions
                the device supports to determine if the activity can be shown in
                multi window.
            1: The device always compare the activity min width/height with the
                min multi window dimensions the device supports to determine if
                the activity can be shown in multi window.
     get-multi-window-config
       Prints values of the multi window config options.
     reset-multi-window-config
       Resets overrides to default values of the multi window config options.

Improved letterboxing

Developers are encouraged to build responsive layouts for their apps that adapt to large screen devices. For those apps that have not yet been optimized, such as those that maintain a fixed size or orientation, Android 12L’s screen compatibility mode can letterbox the app and tweak the window frame to provide the best experience on large screens. Apps will be letterboxed if their minimum or maximum aspect ratio is incompatible with the aspect ratio of the display. 

Android supports the following UI enhancements to letterboxing:

  • Android 12
    • App windows can be configured to have rounded corners
    • Status bars can be configured to be semitransparent
    • An app’s aspect ratio can be configured
    • The background type can be configured
  • Android 12L
    • The default horizontal position of an app window center can be configured
    • The restart button UI can be configured

Device makers are responsible for configuring the letterboxing effects, which can be done by overlaying the values config_fixedOrientationLetterboxAspectRatio, config_letterboxActivityCornersRadius, config_letterboxBackgroundType, config_letterboxBackgroundColor, config_letterboxBackgroundWallpaperBlurRadius, config_letterboxBackgroundWallaperDarkScrimAlpha, config_letterboxHorizontalPositionMultiplier, and config_letterboxDefaultPositionMultiplierForReachability in the framework. By default, AOSP positions the letterboxed app in the center, does not apply rounded corners to letterboxed app windows, and uses the color #ff76757f for the background (an opaque dark gray).

On Android 12L, device makers and app developers can override these behaviors at runtime through the new ‘wm set-letterbox-style’ command.

Here are the new letterboxing shell commands accessed through ‘wm’:

    set-letterbox-style
      Sets letterbox style using the following options:
        --aspectRatio aspectRatio
          Aspect ratio of letterbox for fixed orientation. If aspectRatio <= 1.0
          both it and R.dimen.config_fixedOrientationLetterboxAspectRatio will
          be ignored and framework implementation will determine aspect ratio.
        --cornerRadius radius
          Corners radius for activities in the letterbox mode. If radius < 0,
          both it and R.integer.config_letterboxActivityCornersRadius will be
          ignored and corners of the activity won't be rounded.
        --backgroundType [reset|solid_color|app_color_background
          |app_color_background_floating|wallpaper]
          Type of background used in the letterbox mode.
        --backgroundColor color
          Color of letterbox which is be used when letterbox background type
          is 'solid-color'. Use (set)get-letterbox-style to check and control
          letterbox background type. See Color#parseColor for allowed color
          formats (#RRGGBB and some colors by name, e.g. magenta or olive).
        --backgroundColorResource resource_name
          Color resource name of letterbox background which is used when
          background type is 'solid-color'. Use (set)get-letterbox-style to
          check and control background type. Parameter is a color resource
          name, for example, @android:color/system_accent2_50.
        --wallpaperBlurRadius radius
          Blur radius for 'wallpaper' letterbox background. If radius <= 0
          both it and R.dimen.config_letterboxBackgroundWallpaperBlurRadius
          are ignored and 0 is used.
        --wallpaperDarkScrimAlpha alpha
          Alpha of a black translucent scrim shown over 'wallpaper'
          letterbox background. If alpha < 0 or >= 1 both it and
          R.dimen.config_letterboxBackgroundWallaperDarkScrimAlpha are ignored
          and 0.0 (transparent) is used instead.
        --horizontalPositionMultiplier multiplier
          Horizontal position of app window center. If multiplier < 0 or > 1,
          both it and R.dimen.config_letterboxHorizontalPositionMultiplier
          are ignored and central position (0.5) is used.
        --isReachabilityEnabled [true|1|false|0]
          Whether reachability repositioning is allowed for letterboxed
          fullscreen apps in landscape device orientation.
        --defaultPositionForReachability [left|center|right]
          Default horizontal position of app window  when reachability is.
          enabled.
    reset-letterbox-style [aspectRatio|cornerRadius|backgroundType
      |backgroundColor|wallpaperBlurRadius|wallpaperDarkScrimAlpha
      |horizontalPositionMultiplier|isReachabilityEnabled
      |defaultPositionMultiplierForReachability]
      Resets overrides to default values for specified properties separated
      by space, e.g. 'reset-letterbox-style aspectRatio cornerRadius'.
      If no arguments provided, all values will be reset.
    get-letterbox-style
      Prints letterbox style configuration.

Letterboxing can provide the best experience possible without needing to update an app, but it should not be used as a crutch. If your hardware has an uncommon aspect ratio and the app you want to run cannot be updated, consider tweaking the letterboxing effects to display the app in the best light.

New scaling method for media projection

Google is improving the screen casting experience in Android 12L. When an app uses the media projection API to project the real device’s display onto a virtual display, the system will scale the virtual display to maximize the size of the image on the application-provided Surface while maintaining the proper aspect ratio, in a process similar to ImageView’s centerInside scale type.

Device makers can override an app’s preferred orientation 

Through the screenOrientation Manifest attribute, app developers can specify the orientation that their applications should run in, regardless of the orientation of the device. This lets developers present their app in a fixed aspect ratio, but it results in usability issues on foldable devices that can be oriented based on their fold.

In Android 12 and above, device makers can configure individual device screens to ignore the screenOrientation attribute, overriding an app’s request for a preferred orientation.

This behavior can be controlled at runtime through the ‘wm’ shell command:

    fixed-to-user-rotation [-d DISPLAY_ID] [enabled|disabled|default]
      Print or set rotating display for app requested orientation.
    set-ignore-orientation-request [-d DISPLAY_ID] [true|1|false|0]
    get-ignore-orientation-request [-d DISPLAY_ID]
      If app requested orientation should be ignored.

Re-enable volume adjustment for remote media sessions

Casting audio to an external device is a common feature of many media player apps, and for user convenience, most media players also support remote volume adjustment. After configuring a media session to use remote volume handling through MediaSessionCompat.setPlaybackToRemote(VolumeProviderCompat volumeProvider), apps can receive volume key events. However, this was not the case in the initial release of Android 12, as the platform no longer passed the volume key event to remote sessions.

Fortunately, in early January, Google released android-12.0.0_r26 with a patch that tweaked the volume adjustment behavior to re-enable volume adjustment for ungrouped remote media sessions. Esper analyzed this patch to explain how Google tweaked Android’s media framework in response to its patent dispute with Sonos. This new volume adjustment behavior is now present in Android 12L.

Thus, in Android 12L, the platform supports sending the volume key event to remote media sessions regardless of how many routes are in the session. On Pixel devices, however, the volume key event cannot be passed to remote media sessions contained speaker groups as the framework configuration value ‘config_volumeAdjustmentForRemoteGroupSessions’ is overridden to false.

Developer option to toggle monitoring of phantom processes

Android 12 quietly introduced a new mechanism to monitor forked child processes started by apps and kill them off if they consume too much CPU while their parent process is in the background. Android also limits how many child processes can be spawned in total across the system (32), which has proven to be a headache for advanced users of terminal emulator applications.

Fortunately for power users, Google has added a toggle in developer options to disable the monitoring of these so-called “phantom processes”. The toggle is available under the “feature flags” page of Developer Options which is only populated if the build type is userdebug or eng. Users can override the flag by running the following shell command:

settings put global settings_enable_monitor_phantom_procs [false|true]

Scrolling screenshot support for WebViews

Android 12 introduced scrolling screenshots so users can take full page screenshots. AOSP’s scrolling screenshot implementation follows a different approach than most third-party implementations, which usually automatically scroll the page and take multiple screenshots to stitch together. Instead, AOSP’s works directly on Views, making it faster and more reliable. However, this approach also makes it less versatile, because it may not work out of the box with apps that use a non-View-based UI or a heavily customized UI. It also doesn’t work on WebViews, which are views that display web content.

Late last year, Google Chrome added support for Android 12’s ScrollCapture API which is how apps can give the scroll capture system information on the view to be captured. However, this only made scrolling screenshots work in browsers based on Chromium but not in WebViews. Android 12L, however, enables scroll capture support for WebViews, letting users take full page screenshots of any content embedded in a WebView.

Backing up and restoring home screen layouts across form factors

In order to accommodate foldable devices, Launcher3 now supports backing up and restoring the home screen layout. This means that the user can set up two different home screen layouts, one for when the device is folded and one for when it’s unfolded, and easily swap between the two without having to recreate the layout each time.

Bubbles are now hidden when entering focus mode

Bubbles that are created before an app is suspended (eg. via Digital Wellbeing’s “Focus Mode”) are now hidden in Android 12L.

API Updates in Android 12L

As a feature update, Android 12L does not include many new APIs. There are, however, a few notable additions to the platform, which we’ll summarize in this section.

Activity embedding for two-pane browsing

Activity embedding is one of the key ways that apps can take advantage of the larger screens of tablets, foldables, and Chromebooks. As its name suggests, activity embedding enables showing multiple activities at once, usually side by side. The app task window is split into two containers (primary and secondary) that hold activities launched from the main activity or from other activities already in the containers. Activities in the secondary container are stacked as they’re launched. Note that only system and pre-installed apps holding the permission android.permission.LAUNCH_TWO_PANE_SETTINGS_DEEP_LINK can show their activity in the secondary container of the Settings app.

An example of Activity Embedding. On the left is Settings, and on the right is the Google App. Credits: Esper

As the feature handles device orientation and foldable state changes seamlessly, it will be useful for providing an enhanced user experience on large screen devices. Support for activity embedding is baked into Android 12L, but Google says that it will be available on some devices running earlier versions of Android. App developers can check whether activity embedding is supported on a device by calling SplitController.isSplitSupported() method.

Rather than calling the new platform API directly, Google has added support for activity embedding in the latest Jetpack WindowManager release. Version 1.0.0-beta03 includes experimental support for activity embedding. The initial release allows for showing two activities side by side, though only the activity that created the split can occupy the primary container, while the secondary container can contain a stack of activities.

For more information, including how back navigation is handled, how to build a multi-pane layout, how to proportion the task window, how to configure split rules, and what the current limitations are, read Google’s documentation on activity embedding.

Audio spatialization with dynamic head tracking

Spatial audio is a feature that has existed for years, but thanks to new consumer hardware from the likes of Sony, Apple, and Oculus, it has never been more popular. The feature creates the effect of 3D audio, “[simulating] sounds originating around the listener as if they were coming from virtual speakers placed around the listener,” as explained by Google in its documentation for the new Spatializer API in Android 12L. 

The new Spatializer API lets developers query the capabilities and behavior of sound spatialization on the device. Google says that support for audio spatialization is optional, and if supported, the AudioManager#getSpatializer() method will return a handle to the platform’s Spatializer instance. Developers can also query whether the device supports multichannel spatialization, whether audio of a particular AudioFormat can be spatialized, and more.

The following shell command reveals the spatial audio capabilities of the device:

dumpsys audio | grep -A 4 Spatial

Sample output:

    Spatial audio:
    mHasSpatializerEffect:false
    isSpatializerEnabled:false
    isSpatialAudioEnabled:true

The system property ro.audio.spatializer_enabled should be set to true if the device ships with a spatializer effect. Settings.Secure.SPATIAL_AUDIO_ENABLED and Settings.Secure.SPATIAL_AUDIO_ENABLED_DEFAULT hold the current state of the feature.

While the developer documentation doesn’t mention it, AOSP code commits reveal that Android 12L includes head tracking support for spatial audio. Dynamic head tracking is a feature that’s available on the latest iPhone and iPad when paired to Apple’s latest audio accessories. Head tracking builds upon spatial audio by tracking the position of the user’s head to virtually reposition the sound channels accordingly, providing an even more immersive audio experience. Head tracking is handled by the headphones worn by the user; the accelerometer and gyroscope within the paired accessory determine the position of the user’s head, while additional data from the mobile device determines the position relative to the screen. Like iOS, Android 12L appears to include support for full screen-to-head tracking. There are three head tracking modes: static (ie. no head tracking), world relative (no screen tracking), and screen relative (full screen-to-head tracking). 

Another aspect that’s undocumented is the supported spatialization modes. In Android 12L, there will be two supported modes: binaural and transaural. The former means that the spatializer supports producing spatial audio over headphones, while the latter means that it supports it over the loudspeaker.

Accessibility actions for drag-and-drop

Android’s Accessibility API lets developers build services that help users with accessibility needs. Users who find it difficult to interact with a touchscreen may be unable to perform certain gestures, such as a drag-and-drop. In Android 12L, a drag-and-drop gesture is used to launch an app in split-screen mode from the taskbar. To accommodate those users who may have trouble performing this gesture, which is also used to share data between apps in split-screen view, the Accessibility API has added the following three actions: ACTION_DRAG_DROP, ACTION_DRAG_START, and ACTION_DRAG_CANCEL.

Undeprecated APIs

Android’s shared “external” storage contains media files, some application data, and other files that are readable by other applications or the user. Before Android 10, applications could gain broad read/write access to the external storage through the READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE runtime permissions. With the introduction of Scoped Storage in Android 10 (API level 29), however, Google began to restrict access to external storage. As a consequence, two widely used external storage APIs — Environment.getExternalStorageDirectory() and Environment.getExternalStoragePublicDirectory() — were deprecated. The former returned the primary external storage root directory, while the latter returned the public external storage directory for saving files of a particular type. With API level 32, Google has decided to undeprecate these two APIs. The reason is that while Android 10 did not support file path operations for apps restricted by Scoped Storage, Android 11 largely restored read access to external storage.

As noted by CommonsWare, however, this does not change storage access rights. Scoped Storage rules still apply, which means that apps cannot read or write to content created by other apps in public directories unless given proper permissions.

Another API that has been undeprecated is the DATA constant in MediaStore.MediaColumns. This field was also deprecated with API level 29 when Scoped Storage was first implemented.

More contextual assistant with VoiceInteractionSession updates

Android, through the VoiceInteractionSession API, lets virtual assistant applications receive data from the application that the user is currently viewing when the assistant was invoked. That information can come in the form of a screenshot of what the user is currently viewing, which can then be analyzed via OCR. The Assistant can even request a list of supported actions from within an app. Google’s own Assistant app utilizes this API to obtain contextual information about the app the user is viewing, and in Android 12L, the API is getting even more powerful.

VoiceInteractionSession has added two new callbacks: registerVisibleActivityCallback and unregisterVisibleActivityCallback. The former will let the assistant app register a callback to be notified when there’s a change in the visible activity, while the latter simply unregisters the callback. This will enable more powerful uses of the assistant service, as the service can track what activities are opened within an app. This lets the assistant listen to changes in the visible activity, providing actionable context on what the user is actually doing within an app. The “new” Google Assistant, a faster version of the Google Assistant that’s exclusive to select Pixel devices, will likely make use of this new capability, according to the commit description adding these callbacks.

Hidden DevicePolicyManager APIs to end the current user session

Two hidden methods have been added to DevicePolicyManager: getLogoutUserId() and clearLogoutUser(). Android Automotive’s SystemUI will use these methods to end the current user session.

Drop input events on SurfaceControl

Android 12L has added a new setDropInputMode API under SurfaceControl. This API can be used to drop input events on SurfaceControl and its children. According to the commit description, this API is used to “enable features that allow for a less trusted interaction model between apps.”

Conclusion

At Esper, we support Android on a variety of form factors, including large screen devices like tablets and POS terminals. Although the release of Android 12L is several months away, we’re diligently monitoring the update to see which large screen UI changes to pick, what behavior changes we need to account for, and what features we’ll support. Android is a constantly evolving operating system, so it’s easy to fall behind given the rapid pace of development. Let Esper manage the software that runs on your device fleet; we care about the nitty-gritty implementation details so you don’t have to.


Update @ 1:15 PM PT on 3/7/2022: Updated to reflect the stable release and source code drop for Android 12L.

Update @ 05:40 PM PT on 3/8/2022: Updated to reflect new findings based on analysis of the AOSP commit history.