Getting Started with Scalable UI in Android Automotive OS
Introduction
When developing an infotainment system using Android Automotive OS (AAOS), one of the important challenges is managing multiple applications on the same screen.
Consider a typical automotive infotainment display. We may need navigation, media controls, phone information, and other vehicle-related features to appear simultaneously. Traditionally, this could involve developing a custom launcher that manages different UI components within a single application.
This approach works, but as the number of features increases, managing layouts, application visibility, window positioning, and transitions becomes more complicated.
Scalable UI introduces a different approach to handling these requirements in AAOS.
Instead of managing everything through a monolithic launcher, Scalable UI allows the system to organize independent application tasks into configurable panels. The layout, visual states, and transitions can be defined through XML, while Android's window management system handles the underlying application windows.
For developers familiar with AOSP, Android Framework, and System UI customization, this is an interesting change because much of the layout orchestration can be moved from application code into system configuration.
In this article, I'll explain the basic building blocks of Scalable UI and the configuration needed to get started.
Understanding Scalable UI
The main idea behind Scalable UI is to separate application functionality from screen layout management.
Let's take a simple example.
An automotive display needs three areas:
- Navigation: Displays the map application.
- Media: Displays music or playback controls.
- Phone: Displays phone-related information.
In a traditional launcher implementation, we might develop custom layouts and manage how these components appear, resize, or interact.
With Scalable UI, each application can be hosted inside an independently managed panel. The system determines how those panels are positioned and how their visual states change.
This makes it possible to build layouts where multiple applications remain visible and interactive without placing their entire functionality inside one launcher activity.
The important distinction is that Scalable UI manages application windows and their presentation. It does not replace the applications themselves.
Main Content
1. Understanding the Four Core Building Blocks
Before starting the configuration, we need to understand four important components: TaskPanel, DecorPanel, Variant, and Transition.
These components form the foundation of Scalable UI.
TaskPanel: Hosting Applications
A TaskPanel is a container used to display an application task.
For example, if we want to display a navigation application on the left side of an infotainment screen, we can configure a TaskPanel for that purpose.
Similarly, another TaskPanel can host a media application.
Each panel can be managed independently, allowing the system to control its position, size, and visibility.
This is useful when developing multi-window infotainment layouts because the applications do not need to be combined into a single activity.
DecorPanel: Managing Custom UI Elements
A DecorPanel is intended for view-based UI elements rather than independently launched application tasks.
For example, we may need a custom overlay, contextual widget, or another visual element that appears alongside the application panels.
A DecorPanel can be used to position these elements and coordinate their visual behavior with other panels.
The difference is straightforward:
TaskPanel hosts application tasks, while DecorPanel hosts view-based UI content.
Variant: Defining Different UI States
A Variant defines how a panel should appear in a particular state.
For example, a navigation panel may have three visual states:
- Opened: The navigation application occupies a larger portion of the screen.
- Minimized: The navigation application appears in a smaller area.
- Closed: The navigation panel is hidden.
These states can be configured using properties such as screen bounds, visibility, Z-order, alpha, corner radius, and insets.
Instead of manually updating these properties through application code every time the layout changes, we define the required states through XML.
Transition: Moving Between States
A Transition defines how a panel changes from one variant to another.
For example, when the user opens the navigation application, the system may need to expand the navigation panel and reduce the size of another panel.
A transition connects an event to a target variant and can define the animation used during the change.
Events may come from system interactions or custom behavior.
Together, variants and transitions provide a configurable way to manage dynamic screen layouts. Android Open Source Project
2. Getting Started with Scalable UI Configuration
For the initial setup, we can divide the configuration into three major steps.
These examples focus on the configuration approach rather than a complete, ready-to-build AAOS product.
The exact setup depends on the AOSP branch, the emulator image, available applications, and the overlays included in the build.
Step 1: Enable Framework Remote Insets
The first configuration provided here enables remote control of system bar insets.
In the framework resource overlay, add:
<resources>
<bool name="config_remoteInsetsControllerControlsSystemBars">
true
</bool>
</resources>
This setting allows the relevant remote insets controller behavior to be enabled through the framework configuration.
For example, the configuration may be included in a framework Runtime Resource Overlay (RRO), such as CarFrameworkDewdRRO, depending on the implementation.
The overlay must target the appropriate framework resources.
It is also important to understand that enabling this flag alone does not activate Scalable UI. The System UI configuration must also be updated.
Step 2: Enable Scalable UI in System UI
The next step is configuring the System UI resources.
Scalable UI can be enabled using:
<resources>
<bool name="config_enableScalableUI">true</bool>
</resources>
This tells the supported System UI implementation to enable Scalable UI.
However, we also need to inform System UI about the panels available in our layout.
For this purpose, we use the window_states resource array.
<resources>
<bool name="config_enableScalableUI">true</bool>
<array name="window_states">
<item>@xml/media_panel</item>
<item>@xml/phone_panel</item>
<item>@xml/map_panel</item>
</array>
</resources>
Here, we are declaring three panel configuration files:
media_panel.xml, phone_panel.xml, and map_panel.xml.
Each XML file contains the corresponding panel definition, including its role, variants, and transitions.
The window_states array works as a central resource list that System UI uses to discover the configured panels.
We also need to associate the panels with the applications they are expected to host.
One configuration pattern from the supplied setup uses a config_default_activities array:
<string-array name="config_default_activities">
<item>
media_panel;com.android.car.carlauncher/.ControlBarActivity
</item>
<item>
phone_panel;com.android.car.dialer/.ui.TelecomActivity
</item>
<item>
map_panel;com.android.car.mapsplaceholder/.MapsPlaceholderActivity
</item>
</string-array>
The purpose of this configuration is to associate panel identifiers with activities that should be launched.
However, the exact resource support and activity-launching behavior are implementation-dependent. Current Scalable UI documentation also describes role-based component mapping through the panel's role attribute.
For example, a panel role can reference an array of application component names.
The important point is that defining panels and launching activities are related but separate responsibilities. Both must be configured correctly for the intended layout to appear.
Before building, verify that the referenced resources and application components actually exist in the selected AAOS image. Android Open Source Project
Step 3: Configure the Launcher and Boot the System
The final step is configuring the launcher.
In the proposed setup, the existing monolithic Car Launcher is replaced with StubCarLauncher.
The purpose of this approach is to provide a minimal home activity while Scalable UI manages the visible application panels.
This reduces the responsibility of the launcher for rendering the main infotainment layout.
However, simply installing a stub launcher is not enough.
We need to make sure that the selected AAOS build supports Scalable UI, the required System UI implementation is available, and all the configuration overlays are applied correctly.
The system must also support the required automotive split-screen multitasking feature:
android.software.car.splitscreen_multitasking
Conflicting legacy window-management configurations should also be checked.
After completing the configuration, rebuild the affected components and boot the emulator or target system.
If everything is configured correctly, System UI can load the panel definitions and manage the application layout according to the declared states.
At this stage, the expected result is a multi-panel layout rather than a single launcher activity controlling the entire screen.
3. Why This Approach Is Useful for AAOS Development
One of the main advantages of Scalable UI is reducing the amount of custom window-management logic required in an automotive project.
In a traditional implementation, developers may need to manage application positioning, visibility, task switching, and layout transitions through custom code.
With Scalable UI, much of this behavior can be described through configuration files.
This does not mean we can develop an entire infotainment UI without Java or Kotlin. Application functionality, custom panel controllers, event handling, and other advanced integrations may still require code.
The advantage is that the basic panel layout and visual state management can be configured separately from application functionality.
Another important consideration is Android compatibility.
Custom window-management implementations can introduce issues involving task behavior, focus handling, and application compatibility.
Scalable UI uses Android's existing window-management infrastructure and is designed to preserve important WindowManager behavior.
This can help reduce compatibility risks, but it does not automatically guarantee Compatibility Test Suite (CTS) compliance. The complete system still needs to be tested and validated.
4. What Developers Should Keep in Mind
When starting with Scalable UI, I would focus on understanding how the system manages panels before moving into complex configurations.
Start with a simple layout containing two or three TaskPanels.
Configure their initial variants and verify how the applications appear.
Once the basic layout works, introduce additional variants and transitions to understand how different system events affect the screen.
It is also worth checking that the configuration works with the selected AAOS branch. Resource names, available components, and implementation details may differ between platform versions.
For developers working on customized automotive platforms, this is particularly important because OEM-specific System UI implementations may already contain their own window-management behavior.
Scalable UI should therefore be treated as a platform-level integration rather than simply another layout library.
Conclusion
Scalable UI introduces a more structured way of managing multi-window interfaces in Android Automotive OS.
Instead of building a large launcher responsible for positioning and controlling every UI component, we can define application panels, visual states, and transitions through XML configurations.
The four building blocks—TaskPanel, DecorPanel, Variant, and Transition—are a good starting point for understanding the architecture.
For someone beginning with Scalable UI, the first goal should be straightforward: configure a few application panels, display them correctly, and understand how the system manages their states.
Once that foundation is clear, the next area worth exploring is custom Panel Controllers in Kotlin, particularly for dynamically launching activities, handling runtime events, and responding to vehicle-related interactions.
That is where we can begin connecting Scalable UI configuration with more advanced automotive HMI requirements.