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

Commit 0037e5f9 authored by Evan Rosky's avatar Evan Rosky
Browse files

Add TaskTile concept to Window Manager

This adds the concept of a TaskTile to the WM. Due to
complexities in the current Stack/Task relationship, tiles
can't actually be part of the hierarchy, so the Stack
level has to internally resolve configurations as if they
were.

The TaskTiles themselves *are* ActivityStacks though from
the client/sysui perspective, though.

Bug: 133381284
Test: Added TaskTileTests
Change-Id: I9baad5ec899b4fab323a36c1533a40081727a2f7
parent 39df263c
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -158,6 +158,24 @@ public class ActivityTaskManager {
                }
            };

    /** @hide */
    @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
    public static ITaskOrganizerController getTaskOrganizerController() {
        return ITaskOrganizerControllerSingleton.get();
    }

    private static final Singleton<ITaskOrganizerController> ITaskOrganizerControllerSingleton =
            new Singleton<ITaskOrganizerController>() {
                @Override
                protected ITaskOrganizerController create() {
                    try {
                        return getService().getTaskOrganizerController();
                    } catch (RemoteException e) {
                        return null;
                    }
                }
            };

    /**
     * Sets the windowing mode for a specific task. Only works on tasks of type
     * {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD}
+6 −4
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.app.IProcessObserver;
import android.app.IRequestFinishCallback;
import android.app.IServiceConnection;
import android.app.IStopUserCallback;
import android.app.ITaskOrganizerController;
import android.app.ITaskStackListener;
import android.app.IUiAutomationConnection;
import android.app.IUidObserver;
@@ -71,7 +72,6 @@ import android.view.IRecentsAnimationRunner;
import android.view.ITaskOrganizer;
import android.view.RemoteAnimationDefinition;
import android.view.RemoteAnimationAdapter;
import android.view.WindowContainerTransaction;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.os.IResultReceiver;
import com.android.internal.policy.IKeyguardDismissCallback;
@@ -123,8 +123,6 @@ interface IActivityTaskManager {
            int requestCode, int flags, in ProfilerInfo profilerInfo, in Bundle options,
            IBinder permissionToken, boolean ignoreTargetSecurity, int userId);

    void registerTaskOrganizer(in ITaskOrganizer organizer, int windowingMode);

    boolean isActivityStartAllowedOnDisplay(int displayId, in Intent intent, in String resolvedType,
            int userId);

@@ -224,7 +222,6 @@ interface IActivityTaskManager {
    void setTaskResizeable(int taskId, int resizeableMode);
    void toggleFreeformWindowingMode(in IBinder token);
    void resizeTask(int taskId, in Rect bounds, int resizeMode);
    void applyContainerTransaction(in WindowContainerTransaction t);
    void moveStackToDisplay(int stackId, int displayId);
    void removeStack(int stackId);

@@ -363,6 +360,11 @@ interface IActivityTaskManager {
            in Rect tempDockedTaskInsetBounds,
            in Rect tempOtherTaskBounds, in Rect tempOtherTaskInsetBounds);

    /**
     * Returns an interface enabling the management of task organizers.
     */
    ITaskOrganizerController getTaskOrganizerController();

    /**
     * Sets whether we are currently in an interactive split screen resize operation where we
     * are changing the docked stack size.
+51 −0
Original line number Diff line number Diff line
/**
 * Copyright (c) 2020, 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.app;

import android.app.ActivityManager;
import android.view.ITaskOrganizer;
import android.view.IWindowContainer;
import android.view.WindowContainerTransaction;

/** @hide */
interface ITaskOrganizerController {

    /**
     * Register a TaskOrganizer to manage tasks as they enter the given windowing mode.
     * If there was already a TaskOrganizer for this windowing mode it will be evicted
     * and receive taskVanished callbacks in the process.
     */
    void registerTaskOrganizer(ITaskOrganizer organizer, int windowingMode);

    /** Apply multiple WindowContainer operations at once. */
    void applyContainerTransaction(in WindowContainerTransaction t);

    /** Creates a persistent root task in WM for a particular windowing-mode. */
    ActivityManager.RunningTaskInfo createRootTask(int displayId, int windowingMode);

    /** Deletes a persistent root task in WM */
    boolean deleteRootTask(IWindowContainer task);

    /** Get the root task which contains the current ime target */
    IWindowContainer getImeTarget(int display);

    /**
     * Set's the root task to launch new tasks into on a display. {@code null} means no launch root
     * and thus new tasks just end up directly on the display.
     */
    void setLaunchRoot(int displayId, in IWindowContainer root);
}
+28 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.app;

import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
@@ -25,6 +27,7 @@ import android.content.res.Configuration;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.Log;
import android.view.IWindowContainer;

/**
 * Stores information about a particular Task.
@@ -138,6 +141,19 @@ public class TaskInfo {
    @UnsupportedAppUsage
    public final Configuration configuration = new Configuration();

    /**
     * Used as an opaque identifier for this task.
     * @hide
     */
    @NonNull
    public IWindowContainer token;

    /**
     * The activity type of the top activity in this task.
     * @hide
     */
    public @WindowConfiguration.ActivityType int topActivityType;

    TaskInfo() {
        // Do nothing
    }
@@ -160,6 +176,11 @@ public class TaskInfo {
        }
    }

    /** @hide */
    public boolean isResizable() {
        return resizeMode != RESIZE_MODE_UNRESIZEABLE;
    }

    /**
     * Reads the TaskInfo from a parcel.
     */
@@ -186,6 +207,8 @@ public class TaskInfo {
        supportsSplitScreenMultiWindow = source.readBoolean();
        resizeMode = source.readInt();
        configuration.readFromParcel(source);
        token = IWindowContainer.Stub.asInterface(source.readStrongBinder());
        topActivityType = source.readInt();
    }

    /**
@@ -221,6 +244,8 @@ public class TaskInfo {
        dest.writeBoolean(supportsSplitScreenMultiWindow);
        dest.writeInt(resizeMode);
        configuration.writeToParcel(dest, flags);
        dest.writeStrongInterface(token);
        dest.writeInt(topActivityType);
    }

    @Override
@@ -234,6 +259,8 @@ public class TaskInfo {
                + " numActivities=" + numActivities
                + " lastActiveTime=" + lastActiveTime
                + " supportsSplitScreenMultiWindow=" + supportsSplitScreenMultiWindow
                + " resizeMode=" + resizeMode;
                + " resizeMode=" + resizeMode
                + " token=" + token
                + " topActivityType=" + topActivityType;
    }
}
+16 −2
Original line number Diff line number Diff line
@@ -26,8 +26,7 @@ import android.app.ActivityManager;
 * {@hide}
 */
oneway interface ITaskOrganizer {
    void taskAppeared(in IWindowContainer container,
        in ActivityManager.RunningTaskInfo taskInfo);
    void taskAppeared(in ActivityManager.RunningTaskInfo taskInfo);
    void taskVanished(in IWindowContainer container);

    /**
@@ -35,4 +34,19 @@ oneway interface ITaskOrganizer {
     * ActivityTaskManagerService#applyTaskOrganizerTransaction
     */
    void transactionReady(int id, in SurfaceControl.Transaction t);

    /**
     * Will fire when core attributes of a Task's info change. Relevant properties include the
     * {@link WindowConfiguration.ActivityType} and whether it is resizable.
     *
     * This is used, for example, during split-screen. The flow for starting is: Something sends an
     * Intent with windowingmode. Then WM finds a matching root task and launches the new task into
     * it. This causes the root task's info to change because now it has a task when it didn't
     * before. The default Divider implementation interprets this as a request to enter
     * split-screen mode and will move all other Tasks into the secondary root task. When WM
     * applies this change, it triggers an info change in the secondary root task because it now
     * has children. The Divider impl looks at the info and can see that the secondary root task
     * has adopted an ActivityType of HOME and proceeds to show the minimized dock UX.
     */
    void onTaskInfoChanged(in ActivityManager.RunningTaskInfo info);
}
 No newline at end of file
Loading