WindowOrganizerController概念详解

基于Android R版本分析

  • forAllWindows:对于该容器上或下面的所有窗口,调用回调;
  • forAllTasks:对于此容器上或下面的所有任务,调用回调;

WindowOrganizer

在WindowContainerTransaction的发送一文中,我们分析了WindowContainerTransaction在客户端中有两种发送方式,都是通过WindowOrganizer的相关方法,最终跨进程将WindowContainerTransaction发送给了服务端的WindowOrganizerController

  • TaskOrganizer:ActivityTaskManager/WindowManager委派任务控制的接口,主要用于监听Task变化响应;

    • SplitScreenTaskOrganizer:分屏Task Organizer,处理分屏逻辑;
    • PipTaskOrganizer:画中画Task Organizer,处理画中画逻辑;
    • TaskOrganizerImpl:多窗口的Task Organizer,没有特定的场景,对应的WindowingMode = WINDOWING_MODE_MULTI_WINDOW;
  • DisplayAreaOrganizer:WindowManager委托显示区域控制的Organizer。

以PIP为例,我们在修改WindowContainer的时候,是通过调用PipTaskOrganizer的applySyncTransaction()方法实现的;

其实PipTaskOrganizer继承了TaskOrganizer,而TaskOrganizer继承了WindowOrganizer,applySyncTransaction就是WindowOrganizer提供;

WindowOrganizer提供了两种发送WindowContainerTransaction的方式:

less 复制代码
/**
  * Apply multiple WindowContainer operations at once.
  * @param t The transaction to apply.
  */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public static void applyTransaction(@NonNull WindowContainerTransaction t) {
    try {
        getWindowOrganizerController().applyTransaction(t);
    } catch (RemoteException e) {
        throw e.rethrowFromSystemServer();
    }
}
​
/**
  * Apply multiple WindowContainer operations at once.
  * @param t The transaction to apply.
  * @param callback This transaction will use the synchronization scheme described in
  *        BLASTSyncEngine.java. The SurfaceControl transaction containing the effects of this
  *        WindowContainer transaction will be passed to this callback when ready.
  * @return An ID for the sync operation which will later be passed to transactionReady callback.
  *         This lets the caller differentiate overlapping sync operations.
  */
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public int applySyncTransaction(@NonNull WindowContainerTransaction t,
                                @NonNull WindowContainerTransactionCallback callback) {
    try {
        return getWindowOrganizerController().applySyncTransaction(t, callback.mInterface);
    } catch (RemoteException e) {
        throw e.rethrowFromSystemServer();
    }
}

这两种方式的区别在于是否有对应的Callback返回实时的操作响应结果,即同步和异步的区别;

其中都是调用了getWindowOrganizerController()方法获取WindowOrganizerController实例实现的;

TaskOrganizer

ActivityTaskManager/WindowManager委派任务控制的接口,主要用于监听Task变化响应;

TaskOrganizer提供了几个接口用于监听Task状态的变化;

less 复制代码
/**
  * Called when a task with the registered windowing mode can be controlled by this task
  * organizer. For non-root tasks, the leash may initially be hidden so it is up to the organizer
  * to show this task.
  */
// 新增Task
@BinderThread
public void onTaskAppeared(@NonNull ActivityManager.RunningTaskInfo taskInfo,
                           @NonNull SurfaceControl leash) {}
// 移除Task
@BinderThread
public void onTaskVanished(@NonNull ActivityManager.RunningTaskInfo taskInfo) {}
​
// Task状态变更
@BinderThread
public void onTaskInfoChanged(@NonNull ActivityManager.RunningTaskInfo taskInfo) {}

同时在TaskOrganizer中定义了一个变量:mInterface,该变量的类型为ITaskOrganizer:

java 复制代码
private final ITaskOrganizer mInterface = new ITaskOrganizer.Stub() {
​
    @Override
    public void onTaskAppeared(ActivityManager.RunningTaskInfo taskInfo, SurfaceControl leash) {
        TaskOrganizer.this.onTaskAppeared(taskInfo, leash);
    }
​
    @Override
    public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
        TaskOrganizer.this.onTaskVanished(taskInfo);
    }
​
    @Override
    public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
        TaskOrganizer.this.onTaskInfoChanged(info);
    }
​
    @Override
    public void onBackPressedOnTaskRoot(ActivityManager.RunningTaskInfo info) {
        TaskOrganizer.this.onBackPressedOnTaskRoot(info);
    }
};

在后续TaskOrganizerController的registerOrganizer的过程中,会将其与WindowingMode绑定,一起注册到WindowOrganizerController中;

TaskOrganizerController

用于存储与给定窗口模式关联的TaskOrganizer及其关联状态;

scala 复制代码
class TaskOrganizerController extends ITaskOrganizerController.Stub {
    // 用于存储TaskOrganizer,该集合中的元素为LinkedList<IBinder>,即TaskOrganizer的集合为value,以WindowingMode为key
    // 每一种WindowingMode对应一个TaskOrganizer集合
    private final SparseArray<LinkedList<IBinder>> mTaskOrganizersForWindowingMode =
        new SparseArray<>();
    // 用于存储TaskOrganizer对应的TaskOrganizerState实例,每一个TaskOrganizer对应一个TaskOrganizerState实例
    private final HashMap<IBinder, TaskOrganizerState> mTaskOrganizerStates = new HashMap<>();
    // 
    private final WeakHashMap<Task, RunningTaskInfo> mLastSentTaskInfos = new WeakHashMap<>();
    // 
    private final ArrayList<Task> mPendingTaskInfoChanges = new ArrayList<>();
​
    private final ActivityTaskManagerService mService;
​
    private RunningTaskInfo mTmpTaskInfo;
    private Consumer<Runnable> mDeferTaskOrgCallbacksConsumer;
}
TaskOrganizerState
arduino 复制代码
private class TaskOrganizerState {
    // TaskOrganizerCallbacks实例,每一个TaskOrganizerState对应一个TaskOrganizerState实例
    private final TaskOrganizerCallbacks mOrganizer;
    // 死亡代理
    private final DeathRecipient mDeathRecipient;
    // 用于存储Task实例的集合,当执行onTaskAppeared()回调方法的时候,会将新增的Task添加到该集合中进行维护,在onTaskVanished()回调时,会将对应的Task实例移除
    private final ArrayList<Task> mOrganizedTasks = new ArrayList<>();
    // 获取调用者的UID
    private final int mUid;
    private boolean mInterceptBackPressedOnTaskRoot;
}

TaskOrganizerState提供了add、remove、dispose等操作,用于管理Task,然后将Task的状态信息通过TaskOrganizerCallbacks上报到对应的TaskOrganizer;

TaskOrganizerCallbacks
swift 复制代码
/**
  * A wrapper class around ITaskOrganizer to ensure that the calls are made in the right
  * lifecycle order since we may be updating the visibility of task surface controls in a pending
  * transaction before they are presented to the task org.
  */
private class TaskOrganizerCallbacks {
    final WindowManagerService mService;
    // 这个就是在register过程中传入的ITaskOrganizer实例,用于调用自定义的TaskOrganizer中的onTaskAppeared、onTaskVanished、onTaskInfoChanged等
    final ITaskOrganizer mTaskOrganizer;
    // 这就是在创建Callbacks的时候从TaskOrganizerController中传入的mDeferTaskOrgCallbacksConsumer
    final Consumer<Runnable> mDeferTaskOrgCallbacksConsumer;
​
    private final SurfaceControl.Transaction mTransaction;
}

围绕ITaskOrganizer的包装器类,以确保以正确的生命周期顺序进行调用,因为我们可能会在挂起事务中更新任务表面控件的可见性,然后再将它们呈现给TaskOrganizer;

WindowOrganizerController

php 复制代码
/**
 * 用于组织窗口的接口的服务器端实现
 * Server side implementation for the interface for organizing windows
 * @see android.window.WindowOrganizer
 */
class WindowOrganizerController extends IWindowOrganizerController.Stub
    implements BLASTSyncEngine.TransactionReadyListener {
​
    private static final String TAG = "WindowOrganizerController";
​
    /** Flag indicating that an applied transaction may have effected lifecycle */
    private static final int TRANSACT_EFFECTS_CLIENT_CONFIG = 1;
    private static final int TRANSACT_EFFECTS_LIFECYCLE = 1 << 1;
​
    /**
     * Masks specifying which configurations task-organizers can control. Incoming transactions
     * will be filtered to only include these.
     */
    static final int CONTROLLABLE_CONFIGS = ActivityInfo.CONFIG_WINDOW_CONFIGURATION
            | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE | ActivityInfo.CONFIG_SCREEN_SIZE;
    static final int CONTROLLABLE_WINDOW_CONFIGS = WindowConfiguration.WINDOW_CONFIG_BOUNDS
            | WindowConfiguration.WINDOW_CONFIG_APP_BOUNDS;
​
    private final ActivityTaskManagerService mService;
    private final WindowManagerGlobalLock mGlobalLock;
​
    // 用于收集将合并事务的windowcontainer的实用程序类
    private final BLASTSyncEngine mBLASTSyncEngine = new BLASTSyncEngine();
    // 用于保存同步的WindowContainerTransactionCallback
    private final HashMap<Integer, IWindowContainerTransactionCallback>
            mTransactionCallbacksByPendingSyncId = new HashMap();
​
    // 这两个Organizer实例,都是继承自WindowOrganizer,这个WindowOrganizerController就用于控制、管理所有子类的OrganizerController
    // TaskOrganizerController实例
    final TaskOrganizerController mTaskOrganizerController;
    // DisplayAreaOrganizerController实例
    final DisplayAreaOrganizerController mDisplayAreaOrganizerController;
}

applyTransaction和applySyncTransaction方法都是在WindowOrganizerController中实现,其中applyTransaction同样也是调用了applySyncTransaction方法,其中通过判断callback是否为空,决定是否需要进行同步、有序的进行执行;

java 复制代码
@Override
public void applyTransaction(WindowContainerTransaction t) {
    applySyncTransaction(t, null /*callback*/);
}
​
@Override
public int applySyncTransaction(WindowContainerTransaction t,
                                IWindowContainerTransactionCallback callback) {
    enforceStackPermission("applySyncTransaction()");
    int syncId = -1;
    if (t == null) {
        throw new IllegalArgumentException(
            "Null transaction passed to applySyncTransaction");
    }
    long ident = Binder.clearCallingIdentity();
    try {
        synchronized (mGlobalLock) {
            int effects = 0;
​
            // 同步:callback不为空
            // 异步:callback为空
            if (callback != null) {
                // 为IWindowContainerTransactionCallback创建对应的SyncState,并
                // 将其保存到mTransactionCallbacksByPendingSyncId集合中
                syncId = startSyncWithOrganizer(callback);
            }
            mService.deferWindowLayout();
            try {
                ........................
                // addToSyncSet -- 将Task与对应子窗口加入到同步集合中
                // 1.遍历所有的WindowContainerTransaction.Change,将其对应的BLASTSyncEngine实例以及WindowContainer实例保存到BLASTSyncEngine的mPendingSyncs集合中进行保存维护
                // 2.遍历所有的WindowContainerTransaction.HierarchyOp,将其对应的BLASTSyncEngine实例以及WindowContainer实例保存到BLASTSyncEngine的mPendingSyncs集合中进行保存维护
            } finally {
                mService.continueWindowLayout();
                if (syncId >= 0) {
                    // 这一块会将后续的TransactionReady更新为true
                    setSyncReady(syncId);
                }
            }
        }
    } finally {
        Binder.restoreCallingIdentity(ident);
    }
    return syncId;
}
BLASTSyncEngine

用于收集将合并事务的windowcontainer的实用程序类;

java 复制代码
class BLASTSyncEngine {
    // 这个就是用于标识SyncState实例
    private int mNextSyncId = 0;
    // 用于存储SyncState实例
    //     key = mNextSyncId++
    //     Value为SyncState实例
    private final ArrayMap<Integer, SyncState> mPendingSyncs = new ArrayMap<>();
    
    // WindowOrganizerController实例了该Listener
    interface TransactionReadyListener {
        void onTransactionReady(int mSyncId, Set<WindowContainer> windowContainersReady);
    };
    
    // Holds state associated with a single synchronous set of operations.
    // 保存与单个同步操作集相关联的状态
    class SyncState implements TransactionReadyListener {
        // SyncState的ID
        int mSyncId;
        // 用于统计ContainerTransaction个数
        int mRemainingTransactions;
        // 用于承接WindowOrganizerController实现TransactionReadyListener的逻辑
        TransactionReadyListener mListener;
        // 用于描述Transaction是否准备就绪
        boolean mReady = false;
        // 代表已经Ready的WindowContainer集合
        Set<WindowContainer> mWindowContainersReady = new ArraySet<>();
    }
}

SurfaceControl

SurfaceControl,顾明思议它是Surface的控制管理者,我们知道Surface是应用层用户进行UI绘制的绘图表面,它由WindowManagerService创建,WindowManagerService管理着窗口对象WindowState,Window是一个抽象的概念,它属于设计层面使用的类,而Surface实际上才是实现上的窗口实体;

当WMS对Window做了改变,比如调整layerStack、Z-order、大小、位置等后需要通过SurfaceControl来告知SurfaceFlinger,以便SurfaceFlinger更新其在SF端的Layer图层进行合成渲染,这个Layer图层实际上和应用层使用的Surface是对应的;

Transaction

对一组SurfaceControl的原子更改集;

创建SurfaceControl.Transaction对象,然后调用一些set方法设置某个SurfaceControl的状态,最后调用apply方法提交状态设置;

scss 复制代码
final SurfaceControl.Transaction sft = new SurfaceControl.Transaction();
// 从对应的Task中获取对应的SurfaceControl实例
final SurfaceControl sc = task.getSurfaceControl();
// 设置SurfaceControl的位置
sft.setPosition(sc, surfaceBounds.left, surfaceBounds.top);
if (surfaceBounds.isEmpty()) {
    // setWindowCrop: 将表面及其子表面的边界设置为指定的边界。表面的大小将被忽略,只使用裁剪和缓冲区大小来确定表面的边界。如果未指定裁剪且曲面没有缓冲区,则曲面边界仅受其父边界大小的约束
    sft.setWindowCrop(sc, null);
} else {
    sft.setWindowCrop(sc, surfaceBounds.width(), surfaceBounds.height());
}
// 此事务将由层次结构中的下一个BASE_APPLICATION窗口使用以调整大小,并且它将延迟事务,直到调整大小框架完成。
task.setMainWindowSizeChangeTransaction(sft);

总结

  1. 客户端创建一个WindowContainerTransaction对象;
  2. 调用WindowContainerTransaction的相关方法,这一步需要将期望修改的WindowContainer对应的WindowContainerToken对象作为参数传入;
  3. 通过WindowOrganizer将WindowContainerTransaction发送到服务端,最终服务端读取WindowContainerTransaction中保存的参数完成相应操作;
  4. 服务端操作完成之后,通过WindowContainerTransactionCallback将操作结果返回给客户端,客户端根据返回结果进行后续的操作;
相关推荐
刘立军32 分钟前
本地大模型编程实战(33)用SSE实现大模型的流式输出
架构·langchain·全栈
一直_在路上44 分钟前
Go 语言微服务演进路径:从小型项目到企业级架构
架构·go
黄林晴3 小时前
如何判断手机是否是纯血鸿蒙系统
android
火柴就是我3 小时前
flutter 之真手势冲突处理
android·flutter
法的空间3 小时前
Flutter JsonToDart 支持 JsonSchema
android·flutter·ios
循环不息优化不止3 小时前
深入解析安卓 Handle 机制
android
恋猫de小郭4 小时前
Android 将强制应用使用主题图标,你怎么看?
android·前端·flutter
jctech4 小时前
这才是2025年的插件化!ComboLite 2.0:为Compose开发者带来极致“爽”感
android·开源
用户2018792831674 小时前
为何Handler的postDelayed不适合精准定时任务?
android
叽哥4 小时前
Kotlin学习第 8 课:Kotlin 进阶特性:简化代码与提升效率
android·java·kotlin