Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4fe65297 authored by Andrii Kulian's avatar Andrii Kulian
Browse files

Experimental Bubbles client controller

Certain privileged applications that are tightly integrated with the
system and SysUI need to be able to create and control multitasking
features to achieve a well-integrated and polished user experience.

The change adds a hidden API for interacting with the multi-tasking
controller that allows applications to request actions and
configurations related to system multitasking features like Bubbles
implemented in WM Shell through the client interface.

The calls from the client first come to a controller class in WM Core
(MultitaskingController), where the policy layer verifies the
eligibility of the requests and then relays them to the registered
delegate in WM Shell (BubbleMultitaskingDelegate).

The change introduces a new privileged permission required to
interact with the new APIs.

The new APIs are added in WM Extensions in BubbleContainerManager for
the application clients.

Bug: 407149510
Test: Manual, using DroidNavigator app
Flag: com.android.window.flags.enable_experimental_bubbles_controller
Change-Id: Idc2523f7de0773b6c97171903c9772b78d1d957f
parent b468ac46
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line
/**
 * Copyright (c) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.window;

import android.os.Bundle;
import android.os.IBinder;
import android.content.Intent;
import android.window.IMultitaskingDelegate;

/**
 * System private API for interacting with the multi-tasking controller that allows applications to
 * request actions and configurations related to some multi-window features and modes implemented
 * in WM Shell through the client interface.
 * The client interface is not meant to serve as an implementation for public APIs. This is because
 * exposing information or functions related to specific windowing modes in the public SDK limits
 * the platform's ability to evolve the UX, and hurts app compatibility with existing or future
 * OEM system UX customizations.
 * Therefore, this interface is only meant to be used for experimental purposes.
 * The supported actions are functionally equivalent to SysUI interactions, so all delegate
 * methods require REQUEST_SYSTEM_MULTITASKING_CONTROLS permission.
 * @hide
 */
interface IMultitaskingController {
    /**
     * Method used by WMShell to register itself as a delegate that can respond to the app requests.
     */
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)")
    oneway void registerMultitaskingDelegate(in IMultitaskingDelegate delegate);

    /**
     * Returns an instance of an interface for use by applications to make requests to the system.
     */
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.REQUEST_SYSTEM_MULTITASKING_CONTROLS)")
    @nullable IMultitaskingDelegate getClientInterface();
}
+39 −0
Original line number Diff line number Diff line
/**
 * Copyright (c) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.window;

import android.os.IBinder;
import android.content.Intent;

/**
 * System private API for requesting actions and configurations related to some multi-window
 * features and modes like Bubbles.
 * @hide
 */
interface IMultitaskingDelegate {
    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.REQUEST_SYSTEM_MULTITASKING_CONTROLS)")
    oneway void createBubble(in IBinder token, in Intent intent, boolean collapsed);

    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.REQUEST_SYSTEM_MULTITASKING_CONTROLS)")
    oneway void updateBubbleState(in IBinder token, boolean collapsed);

    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.REQUEST_SYSTEM_MULTITASKING_CONTROLS)")
    oneway void updateBubbleMessage(in IBinder token, String message);

    @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.REQUEST_SYSTEM_MULTITASKING_CONTROLS)")
    oneway void removeBubble(in IBinder token);
}
+4 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.view.SurfaceControl;
import android.os.IBinder;
import android.view.RemoteAnimationAdapter;
import android.window.IDisplayAreaOrganizerController;
import android.window.IMultitaskingController;
import android.window.ITaskFragmentOrganizerController;
import android.window.ITaskOrganizerController;
import android.window.ITransitionMetricsReporter;
@@ -81,6 +82,9 @@ interface IWindowOrganizerController {
    /** @return An interface enabling the management of task fragment organizers. */
    ITaskFragmentOrganizerController getTaskFragmentOrganizerController();

    /** @return An interface enabling the management of some multi-window features like Bubbles. */
    IMultitaskingController getMultitaskingController();

    /**
     * Registers a transition player with Core. There is only one of these active at a time so
     * calling this will replace the existing one (if set) until it is unregistered.
+7 −0
Original line number Diff line number Diff line
@@ -4343,6 +4343,13 @@
    <permission android:name="android.permission.EMBED_ANY_APP_IN_UNTRUSTED_MODE"
                android:protectionLevel="internal|role" />

    <!-- Allows an application to make requests to WM Shell for actions or
         configurations related to select multitasking features like Bubbles.
         @hide -->
    <permission android:name="android.permission.REQUEST_SYSTEM_MULTITASKING_CONTROLS"
        android:protectionLevel="signature|privileged"
        android:featureFlag="com.android.window.flags.enable_experimental_bubbles_controller" />

    <!-- Allows an application to start any activity, regardless of permission
         protection or exported state.
         @hide -->
+1 −0
Original line number Diff line number Diff line
@@ -286,6 +286,7 @@ applications that come with the platform
        <permission name="android.permission.DUMP"/>
        <permission name="android.permission.CONTROL_UI_TRACING"/>
        <permission name="android.permission.ACTIVITY_EMBEDDING"/>
        <permission name="android.permission.REQUEST_SYSTEM_MULTITASKING_CONTROLS" />
        <permission name="android.permission.FORCE_STOP_PACKAGES"/>
        <permission name="android.permission.GET_APP_OPS_STATS"/>
        <permission name="android.permission.WATCH_APPOPS"/>
Loading