SystemUIOverlayWindow codelab

This page explains how to create a view in the SystemUIOverlayWindow.

Before you start

The content provided below presumes you've read these System UI articles:

This article:

  • Presumes you're familiar with use cases for the Android Automotive OS and its SystemUIOverlayWindow.
  • Provides examples of certain subclasses of the OverlayViewController.
  • Doesn't address subclasses of the OverlayViewController.
  • Doesn't explain how to set up Android for development.
  • Doesn't describe each option that can be overridden in base classes. Rather it describes only those needed to set up a basic view.

Complete the codelab

Step 1: Create a layout for the OverlayViewController

Create a file named frameworks/base/packages/CarSystemUI/res/layout/codelab_layout.xml to contain the following:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/codelab_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/black">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:gravity="center"
            android:text="Code Lab View!"
            android:color="@*android:color/car_accent"
            android:textStyle="italic"
            android:textSize="34sp"/>
        <Button
            android:id="@+id/codelab_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            android:text="Hide!"
            android:background="@*android:color/car_accent"/>
    </LinearLayout>
</FrameLayout>

This layout creates the following view:

OverlayViewController
Figure 1. OverlayViewController

Step 2: Add a ViewStub to SysUIOverlayWindow

Add the view to your window by adding a ViewStub to the SystemUIOverlayWindow.

Add the following code to frameworks/base/packages/CarSystemUI/res/layout/sysui_overlay_window.xml in the root FrameLayout:

<ViewStub android:id="@+id/codelab_stub"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:layout="@layout/codelab_layout"/>

The order in which ViewStubs are defined in the root FrameLayout defines the Z-ordering of views in the window. Since this codelab doesn't involve layering views, you can add the code snippet anywhere in the root FrameLayout.

Step 3: Create an OverlayViewController

To be shown and hidden, the new layout must be linked to an OverlayViewController.

To create an injectable OverlayViewController named frameworks/base/packages/CarSystemUI/src/com/android/systemui/car/codelab/CodeLabViewController.java with the following content:

package com.android.systemui.car.codelab;

import com.android.systemui.R;
import com.android.systemui.car.window.OverlayViewController;
import com.android.systemui.car.window.OverlayViewGlobalStateController;
import com.android.systemui.dagger.SysUISingleton;

import javax.inject.Singleton;

@SysUISingleton
public class CodeLabViewController extends OverlayViewController {

    @Inject
    public CodeLabViewController(
            OverlayViewGlobalStateController overlayViewGlobalStateController) {
        super(R.id.codelab_stub, overlayViewGlobalStateController);
    }
}

Step 4: Create an OverlayViewMediator

An OverlayViewMediator to trigger when new view is shown or hidden is required.

Create a new injectable OverlayViewMediator named frameworks/base/packages/CarSystemUI/src/com/android/systemui/car/codelab/CodeLabViewMediator.java with the following content:
package com.android.systemui.car.codelab;

import android.bluetooth.BluetoothAdapter; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter;
import com.android.systemui.car.window.OverlayViewMediator; import com.android.systemui.dagger.SysUISingleton;
import javax.inject.Inject;
@SysUISingleton public class CodeLabViewMediator implements OverlayViewMediator { Context mContext; CodeLabViewController mCodeLabViewController;
@Inject public CodeLabViewMediator(Context context, CodeLabViewController codeLabViewController) { mContext = context; mCodeLabViewController = codeLabViewController; }
@Override public void registerListeners() { // no-op }
@Override public void setupOverlayContentViewControllers() { // no-op } }

Step 5: Show the view

For ease of understanding and to trigger the our view, use Bluetooth when status is off.

Replace // no-op in CodeLabViewMediator#registerListeners with the following:

// Register Show Listener
mContext.registerReceiver(new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();

if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); switch (state) { case BluetoothAdapter.STATE_OFF: // Show OverlayViewController mCodeLabViewController.start(); break; } } } }, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));

Step 6: Hide the view

The view will be hidden when the "Hide!" button is clicked. Since this action only on the inflated view's button, add this directly to you OverlayViewController.

Add the following method to CodeLabViewController:

@Override
protected void onFinishInflate() {
    getLayout().findViewById(R.id.codelab_button).setOnClickListener(v -> {
        stop();
    });
}

Step 7: Configure the new OverlayViewMediator

  1. To add the new OverlayViewMediator to OverlayWindowModule, add the following code to OverlayWindowModule:
    /** Injects CodeLabViewMediator. */
    @Binds
    @IntoMap
    @ClassKey(CodeLabViewMediator.class)
    public abstract OverlayViewMediator bindCodeLabViewMediator(
            CodeLabViewMediator overlayViewsMediator);
    
  2. To add the new OverlayViewMediator to config_carSystemUIOverlayViewsMediators, add the following line to config_carSystemUIOverlayViewsMediators in frameworks/base/packages/CarSystemUI/res/values/config.xml:
    <item>com.android.systemui.car.codelab.CodeLabViewMediator</item>
    

Result

Congratulations! You created a view in the SystemUIOverlayWindow:

SystemUIOverlayWindow
Figure 2. SystemUIOverlayWindow

Additional resources

To learn more, see the resources provided below.

Sample OverlayViewController

See the full screen user switcher as a straightforward application of SystemUIOverlayWindow::

Other OverlayViewControllers

OverlayPanelViewController

An OverlayPanelViewController is used to provide basic dragging animation when showing and hiding views inside SystemUIOverlayWindow. See the Notification panel to learn more: