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将操作结果返回给客户端,客户端根据返回结果进行后续的操作;
相关推荐
张槊哲2 小时前
ROS2架构介绍
python·架构
奔跑吧 android2 小时前
【android bluetooth 协议分析 01】【HCI 层介绍 8】【ReadLocalVersionInformation命令介绍】
android·bluetooth·hci·bt·hcicmd·readlocalver·bt5.3
私人珍藏库2 小时前
[Android] 安卓彩蛋:Easter Eggs v3.4.0
android
androidwork2 小时前
Android Kotlin权限管理最佳实践
android·java·kotlin
我命由我123455 小时前
Android 动态申请 REQUEST_INSTALL_PACKAGES 权限问题:申请权限失败
android·java·开发语言·java-ee·android studio·android jetpack·android-studio
搞不懂语言的程序员5 小时前
如何设计一个二级缓存(Redis+Caffeine)架构?Redis 6.0多线程模型如何工作?
redis·架构·wpf
追随远方5 小时前
深入解析OkHttp与Retrofit:Android网络请求的黄金组合
android·okhttp·retrofit
nukix6 小时前
Android Studio Kotlin 中的方法添加灰色参数提示
android·kotlin·android studio
飞露6 小时前
android studio clone子分支
android·ide·android studio
吴胜ws6 小时前
Android Studio 中 build、assemble、assembleDebug 和 assembleRelease 构建 aar 的区别
android·ide·android studio