WindowManager Extensions

The Jetpack WindowManager library enables application developers to support new device form factors and multi‑window environments.

WindowManager Extensions (Extensions) is an opt-in Android platform module that enables a variety of Jetpack WindowManager features. The module is implemented in AOSP in frameworks/base/libs/WindowManager/Jetpack and shipped on devices that support the WindowManager features.

Extensions module distribution

Extensions are compiled into a .jar library and placed in the system_ext partition on a device if Extensions are enabled in the device makefile.

To enable Extensions on a device, add the following to the product device makefile:

$(call inherit-product, $(SRC_TARGET_DIR)/product/window_extensions.mk)

This enables the androidx.window.extensions and androidx.window.sidecar packages on the device and sets the persist.wm.extensions.enabled property. Including these packages in the makefile also places declarations in etc/permissions/, making them available to application processes. Normally the modules are loaded into and executed as part of the application process at runtime when used by the Jetpack WindowManager library, which makes its operation similar to client-side framework code, as shown in the following figure:

Figure 1. WindowManager Extensions loaded into the application process similar to platform code.

The androidx.window.extensions module is the current Extensions module under active development. The androidx.window.sidecar module is a legacy module included for compatibility with the earliest versions of Jetpack WindowManager, but the sidecar is no longer actively maintained.

The following figure shows the logic for determining the use of androidx.window.extensions or androidx.window.sidecar.

Figure 2. Decision tree for accessing androidx.window.extensions or androidx.window.sidecar.

Extensions modules

Extensions provide windowing features for foldable large screen devices and devices that support windowing on external displays. The feature areas include:

OEM implementations of Extensions can provide null components or components with default or stub implementations of the methods in the WindowExtensions interface if the device hardware doesn't support the corresponding features, unless the feature is specifically requested in Compatibility Definition Document (CDD) 7.1.1.1.

Extensions and Jetpack APIs

The WindowManager Extensions module provides its own API surface in addition to the public platform APIs. The Extensions module is developed publicly in a non‑developer–facing androidx.window.extensions Jetpack library, so that Jetpack WindowManager (androidx.window) can link against it at compile time. The Extensions API surface typically provides lower‑level APIs.

The APIs that Extensions provide are meant to be used by the Jetpack WindowManager library only. The Extensions APIs aren't meant to be called by application developers directly. The Extensions library mustn't be added as a dependency for an application in the Gradle build file to ensure correct functionality. Avoid pre-compiling the Extensions library into an application directly; instead, rely on runtime loading to prevent the case of loading a mix of pre-compiled and runtime‑provided Extensions classes.

Jetpack WindowManager (androidx.window) is meant to be added as an application dependency and provides the public developer‑facing APIs, including those for WindowManager Extensions features. The WindowManager library automatically loads Extensions into the application process and wraps the lower‑level Extensions APIs into higher‑level abstractions and more focused interfaces. The WindowManager Jetpack APIs follow the standards of modern Android application development and are meant to provide convenient interoperability by integrating well with codebases that use other AndroidX libraries.

Extensions versions and updates

The Extensions module can be updated along with the Android platform yearly or quarterly updates. Quarterly updates enable the Extensions API level to be increased between Android platform API updates, allowing quicker iteration and providing OEMs with an opportunity to add official API access to new features close to hardware launches.

The following table lists the androidx.window.extensions API versions for various Android releases.

Android platform version WindowManager Extensions API level androidx.window.extensions API version
Android 14 3 1.2.0
Android 13 QPR3 2 1.1.0
Android 13 1 1.0.0
Android 12L 1 1.0.0

The Extensions API level (center column) is increased every time there is an addition to the existing stable API surface (right column).

Backward and forward compatibility

Jetpack WindowManager handles the complexity of dealing with frequent API level updates, fast API evolution, and backward compatibility. When the library code is executed in the application process, the library checks the declared Extensions API level and provides access to features according to the declared level.

To protect an application from crashing at runtime, WindowManager also performs a runtime Java reflection check of the available Extensions APIs according to the declared Extensions API level. If there is a mismatch, WindowManager can disable the use of Extensions (partly or completely) and report the relevant features as not available to the application.

WindowManager Extensions are implemented as a system_ext module that uses private platform APIs to call into WindowManager core, DeviceStateManager, and other system services in the implementation of the Extensions features.

Compatibility may not be maintained with pre-release versions of Extensions prior to the corresponding quarterly or yearly Android platform release with which the versions are finalized. The complete history of Extensions APIs can be found in the release branch window:extensions:extensions API text files.

Newer versions of Extensions must continue working with older versions of WindowManager compiled into applications to maintain forward compatibility. To ensure this, any new version of the Extensions API only adds new APIs and doesn't remove older ones. As a result, applications with older WindowManager versions can continue using the older Extensions APIs the apps were compiled against.

CTS verification ensures that for any declared version of Extensions APIs on the device, all APIs for that and previous versions are present and functional.

Performance

The Extensions module is cached in non‑bootclasspath system class loaders by default starting with Android 14 (API level 34), so there is no performance impact due to loading the module into memory at app startup. Using individual module features might have a slight influence on the performance characteristics of apps when additional IPC calls are performed between the client and the server.

Modules

Activity embedding

The Activity embedding component provides a set of features that enable applications to organize activity window presentation within the bounds of the parent application. This includes showing two activities simultaneously side by side in a multi‑pane layout, facilitating large screen optimization for legacy applications.

The activity embedding component must be available on all devices that have a built‑in display of size equal to or larger than sw600 dp. Activity embedding must also be enabled on devices that support external display connections, as the application might be shown in a larger size when external displays are connected at runtime.

Device configuration

No specific device configuration is necessary other than enabling the Extensions module as described in the Extensions module distribution section. It makes sense to enable Extensions on all devices that support multi‑window mode. Future Android versions are likely to make Extensions required on common handheld and large screen device configurations.

Window layout information

The window layout information component identifies the position and state of the hinge on a foldable device when the hinge crosses an application window. Window layout information enables applications to respond to and show optimized layouts in tabletop mode on foldables. See Make your app fold aware for usage details.

Foldable Android devices that include a hinge that connects separate or continuous display panel areas must make the information about the hinge available to applications through WindowLayoutComponent.

The hinge position and bounds must be reported relative to the application window identified by a Context passed into the API. If the application window bounds don't intersect with the hinge bounds, the hinge DisplayFeature mustn't be reported. It is also acceptable to not report the display features when their position might not be reported reliably, such as when an application window can be freely moved by the user in multi‑window mode or compatibility letterboxing mode.

For folding features, the state updates must be reported when the hinge position changes between the stable states. By default in a flat display state, the API must report FoldingFeature.State.FLAT. If the device hardware can be left in a half-folded mode in a stable state, the API must report FoldingFeature.State.HALF_OPENED. There is no closed state in the API, since in such a case the application window would either not be visible or wouldn't be crossing the hinge bounds.

Device configuration

To support the folding feature implementation, OEMs must do the following:

  • Configure the device states in device_state_configuration.xml to be used by DeviceStateManagerService. See DeviceStateProviderImpl.java for reference.

    If the default implementations of DeviceStateProvider or DeviceStatePolicy aren't suitable for the device, a custom implementation can be used.

  • Enable the Extensions module as described in the Extensions module distribution section.

  • Specify the location of the display features in the com.android.internal.R.string.config_display_features string resource (usually in frameworks/base/core/res/res/values/config.xml in device overlay).

    The expected format for the string is:

    <type>-[<left>,<top>,<right>,<bottom>]

    The type can be either fold or hinge. Values for left, top, right and bottom are integer pixel coordinates in the display coordinate space in the natural display orientation. The configuration string can contain multiple display features separated by semicolons.

    For example:

    <!-- Jetpack WindowManager display features -->
    <string name="config_display_features" translatable="false">fold-[1000,0,1000,2000]</string>
    
  • Define the mapping between the internal device state identifiers used in DeviceStateManager and the public state constants sent to developers in com.android.internal.R.array.config_device_state_postures.

    The expected format for each entry is:

    <device_specific_state_identifier>:<Jetpack WindowManager state identifier>

    The supported state identifiers are:

    • COMMON_STATE_NO_FOLDING_FEATURES = 1: The state has no folding features to report. For example, it can be the closed state of the typical in-folding device with the main screen on the inner side.
    • COMMON_STATE_HALF_OPENED = 2: The folding feature is half opened.
    • COMMON_STATE_FLAT = 3: The folding feature is flat. For example, it can be the opened state of the typical in-folding device with the main screen on the inner side.
    • COMMON_STATE_USE_BASE_STATE = 1000: In Android 14, a value that can be used for emulated states where the hinge state is derived using the base state, as defined in CommonFoldingFeature.java

    See DeviceStateManager.DeviceStateCallback#onBaseStateChanged(int) for more information.

    For example:

    <!-- Map of System DeviceState supplied by DeviceStateManager to WindowManager posture.-->
    <string-array name="config_device_state_postures" translatable="false">
        <item>0:1</item>    <!-- CLOSED       : COMMON_STATE_NO_FOLDING_FEATURES -->
        <item>1:2</item>    <!-- HALF_OPENED  : COMMON_STATE_HALF_OPENED -->
        <item>2:3</item>    <!-- OPENED       : COMMON_STATE_FLAT -->
        <item>3:1</item>    <!-- REAR_DISPLAY : COMMON_STATE_NO_FOLDING_FEATURES -->
        <item>4:1000</item> <!-- CONCURRENT   : COMMON_STATE_USE_BASE_STATE -->
    </string-array>
    

Window area

The window area component provides a set of features that give applications access to additional displays and display areas on some foldable and multi‑display devices.

Rear display mode enables an application to show the camera preview UI on the cover display of a foldable device to allow use of the main device camera for selfies and videos. Devices that have an Android‑compatible (as defined by the Android CDD in terms of attributes such as size, density, and available navigation affordances) cover display that aligns with the rear device cameras must provide access to rear display mode.

On Android 14, the dual display mode enables applications that run on the inner display of a foldable device to show additional content on the cover display facing other users; for example, the cover display can show the camera preview to the person being photographed or recorded.

Device configuration

To support the folding feature implementation, OEMs must do the following:

  • Configure the device states in device_state_configuration.xml to be used by DeviceStateManagerService. See DeviceStateProviderImpl.java for more information.

    If the default implementation of DeviceStateProvider or DeviceStatePolicy isn't suitable for the device, a custom implementation can be used.

  • For foldable devices that support open or flat mode, specify the corresponding state identifiers in com.android.internal.R.array.config_openDeviceStates.

  • For in-folding devices that support folded states, list the corresponding state identifiers in com.android.internal.R.array.config_foldedDeviceStates.

  • For in-folding devices that support a half-folded state (hinge is half opened like a laptop), list the corresponding states in com.android.internal.R.array.config_halfFoldedDeviceStates.

  • For devices that support rear display mode:

    • List the corresponding states in com.android.internal.R.array.config_rearDisplayDeviceStates for DeviceStateManager.
    • Specify the physical display address of the rear display in com.android.internal.R.string.config_rearDisplayPhysicalAddress.
    • Specify the state identifier in com.android.internal.R.integer.config_deviceStateRearDisplay to be used by Extensions.
    • Add the state identifier in com.android.internal.R.array.config_deviceStatesAvailableForAppRequests to make it available to applications.
  • On Android 14, for devices that support dual (concurrent) display mode:

    • Set com.android.internal.R.bool.config_supportsConcurrentInternalDisplays to true.
    • Specify the physical display address of the rear display in com.android.internal.R.config_deviceStateConcurrentRearDisplay.
    • Specify the state identifier in com.android.internal.R.integer.config_deviceStateConcurrentRearDisplay to be used by Extensions if the identifier is meant to be made available for applications.
    • Add the state identifier in com.android.internal.R.array.config_deviceStatesAvailableForAppRequests to make it available to applications.

Verification

OEMs must verify their implementations to ensure expected behavior in common scenarios. CTS tests and tests using Jetpack WindowManager are available to OEMs for testing implementations.

CTS tests

To run the CTS tests, see Run CTS tests. The CTS tests related to Jetpack WindowManager are under cts/tests/framework/base/windowmanager/jetpack/. The test module name is CtsWindowManagerJetpackTestCases.

WindowManager tests

To download the Jetpack WindowManager tests, follow the Android Jetpack Instructions. The tests are located in the window library under the window:window module: window/window/src/androidTest/.

To run the device tests for the window:window module from the command line, do the following:

  1. Plug in a device that has developer options and USB debugging enabled.
  2. Allow the computer to debug the device.
  3. Open a shell in the root directory of the androidx repository.
  4. Change directory to framework/support.
  5. Run the following command: ./gradlew window:window:connectedAndroidTest.
  6. Analyze the results.

To run the tests from Android Studio, do the following:

  1. Open Android Studio.
  2. Plug in a device that has developer options and USB debugging enabled.
  3. Allow the computer to debug the device.
  4. Navigate to a test within the window library of the window module.
  5. Open a test class and run using the green arrows on the right side of the editor.

Alternatively, you can create a configuration in Android Studio to run a test method, a test class, or all the tests in a module.

Results can be analyzed manually by looking at the output of the shell. Some tests are skipped if the device doesn't meet certain assumptions. Results are saved in a standard location, and analysts can write a script to automate analysis of the results.