概述

CaptionWindowDecoration 是 Android WindowManager Shell (WMShell) 框架中的核心组件,负责为自由形态窗口提供标题栏装饰功能。它采用多层 Surface 架构来实现窗口装饰的渲染和交互,确保应用内容与装饰元素能够独立渲染、精确控制,同时保持良好的性能和用户体验。

完整多层 Surface 架构图

包含应用内容的完整架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

┌─────────────────────────────────────────────────────────────────────────────────┐

│ Display Surface (屏幕显示层) │

├─────────────────────────────────────────────────────────────────────────────────┤

│ Task Display Area Surface (任务显示区域) │

│ ┌─────────────────────────────────────────────────────────────────────────────┐ │

│ │ Task Surface (mTaskSurface) - 应用内容容器 │ │

│ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │

│ │ │ Application Surface (应用 Surface) │ │ │

│ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │

│ │ │ │ Activity Surface (Activity 渲染 Surface) │ │ │ │

│ │ │ │ - Activity 的 UI 内容 │ │ │ │

│ │ │ │ - View Hierarchy 渲染 │ │ │ │

│ │ │ │ - 应用逻辑和交互 │ │ │ │

│ │ │ └─────────────────────────────────────────────────────────────┘ │ │ │

│ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │

│ │ │ │ Starting Window Surface (启动窗口 Surface) │ │ │ │

│ │ │ │ - 应用启动时的临时界面 │ │ │ │

│ │ │ └─────────────────────────────────────────────────────────────┘ │ │ │

│ │ └─────────────────────────────────────────────────────────────────────┘ │ │

│ │ ┌─────────────────────────────────────────────────────────────────────┐ │ │

│ │ │ Decoration Container Surface (mDecorationContainerSurface) │ │ │

│ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │

│ │ │ │ Caption Container Surface (mCaptionContainerSurface) │ │ │ │

│ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ │

│ │ │ │ │ SurfaceControlViewHost (mViewHost) │ │ │ │ │

│ │ │ │ │ ┌─────────────────────────────────────────────┐ │ │ │ │ │

│ │ │ │ │ │ Caption UI (caption_window_decor.xml) │ │ │ │ │ │

│ │ │ │ │ │ - Back Button (返回按钮) │ │ │ │ │ │

│ │ │ │ │ │ - Minimize Button (最小化按钮) │ │ │ │ │ │

│ │ │ │ │ │ - Maximize Button (最大化按钮) │ │ │ │ │ │

│ │ │ │ │ │ - Close Button (关闭按钮) │ │ │ │ │ │

│ │ │ │ │ └─────────────────────────────────────────────┘ │ │ │ │ │

│ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │

│ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ │

│ │ │ │ │ Input Sink Surface (mInputSinkSurface) │ │ │ │ │

│ │ │ │ │ - 拖拽调整大小输入处理 │ │ │ │ │

│ │ │ │ │ - 边缘和角落输入事件 │ │ │ │ │

│ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │

│ │ │ └─────────────────────────────────────────────────────────────┘ │ │ │

│ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │

│ │ │ │ Shadow Surface (阴影 Surface) │ │ │ │

│ │ │ │ - 窗口阴影效果 │ │ │ │

│ │ │ │ - 深度视觉层次 │ │ │ │

│ │ │ └─────────────────────────────────────────────────────────────┘ │ │ │

│ │ └─────────────────────────────────────────────────────────────────────┘ │ │

│ └─────────────────────────────────────────────────────────────────────────────┘ │

└─────────────────────────────────────────────────────────────────────────────────┘

Surface 层级关系 (Z-Order)

1
2
3
4
5
6
7
8
9
10
11

Z-Order: +1 ┌─ Caption Container Surface (标题栏)

Z-Order: 0 ┌─ Decoration Container Surface (装饰容器)

Z-Order: -1 ┌─ Application Surface (应用内容)

Z-Order: -2 ┌─ Input Sink Surface (输入处理)

Z-Order: -3 ┌─ Shadow Surface (阴影效果)

核心组件分析

1. CaptionWindowDecoration 类结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

public class CaptionWindowDecoration extends WindowDecoration<WindowDecorLinearLayout> {

// 核心组件

final Handler mHandler;

private final Choreographer mChoreographer;

private final SyncTransactionQueue mSyncQueue;

// 事件监听器

private View.OnClickListener mOnCaptionButtonClickListener;

private View.OnTouchListener mOnCaptionTouchListener;

private DragPositioningCallback mDragPositioningCallback;

private DragResizeInputListener mDragResizeListener;

private DragDetector mDragDetector;

// 布局参数和结果

public RelayoutParams mRelayoutParams = new RelayoutParams();

private final RelayoutResult<WindowDecorLinearLayout> mResult = new RelayoutResult<>();

// 自由形态装饰组件

FreeformCaptionWindowDecoration mFreeformCaptionWindowDecoration;

}

2. WindowDecoration 基类架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

public abstract class WindowDecoration<T extends ViewGroup> {

// 核心 Surface 引用

final SurfaceControl mTaskSurface; // 任务 Surface

SurfaceControl mDecorationContainerSurface; // 装饰容器 Surface

SurfaceControl mCaptionContainerSurface; // 标题栏容器 Surface

SurfaceControl mInputSinkSurface; // 输入处理 Surface

// View 管理

SurfaceControlViewHost mViewHost; // View 宿主

WindowlessWindowManager mCaptionWindowManager; // 无窗口管理器

T mRootView; // 根视图

// 常量定义

private static final int CAPTION_LAYER_Z_ORDER = -1; // 标题栏 Z 层级

private static final int INPUT_SINK_Z_ORDER = -2; // 输入处理 Z 层级

}

Surface 创建和管理流程

1. Surface 创建顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

// 1. Task Surface (由系统创建)

mTaskSurface = cloneSurfaceControl(taskSurface, surfaceControlSupplier);



// 2. Decoration Container Surface

mDecorationContainerSurface = builder

.setName("Decor container of Task=" + mTaskInfo.taskId)

.setContainerLayer()

.setParent(mTaskSurface) // 父级是 Task Surface

.setCallsite("WindowDecoration.updateDecorationContainerSurface")

.build();



// 3. Caption Container Surface

mCaptionContainerSurface = builder

.setName("Caption container of Task=" + mTaskInfo.taskId)

.setContainerLayer()

.setParent(mDecorationContainerSurface) // 父级是 Decoration Container

.setCallsite("WindowDecoration.updateCaptionContainerSurface")

.build();



// 4. Input Sink Surface

mInputSinkSurface = builder

.setName("Input sink of Task=" + mTaskInfo.taskId)

.setParent(mDecorationContainerSurface)

.setCallsite("WindowDecoration.updateInputSinkSurface")

.build();

2. Surface 层级建立

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

// 设置 Surface 层级

startT.setLayer(mDecorationContainerSurface, TaskConstants.TASK_CHILD_LAYER_WINDOW_DECORATIONS)

.setLayer(mCaptionContainerSurface, CAPTION_LAYER_Z_ORDER)

.setLayer(mInputSinkSurface, INPUT_SINK_Z_ORDER);



// 设置 Surface 可见性

startT.show(mDecorationContainerSurface)

.show(mCaptionContainerSurface)

.show(mInputSinkSurface);

View 渲染机制

1. SurfaceControlViewHost 集成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

// 创建无窗口管理器

mCaptionWindowManager = new WindowlessWindowManager(

mTaskInfo.getConfiguration(),

mCaptionContainerSurface

);



// 创建 View 宿主

mViewHost = new SurfaceControlViewHost(

mDecorWindowContext,

mDisplay,

mCaptionWindowManager

);



// 附加 View 到 Surface

mViewHost.setView(mRootView, mRootView.getLayoutParams());

2. 布局文件结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

<!-- caption_window_decor.xml -->

<com.android.wm.shell.windowdecor.WindowDecorLinearLayout

android:id="@+id/caption"

android:layout_width="match_parent"

android:layout_height="wrap_content">

<ImageButton android:id="@+id/back_button" />

<ImageButton android:id="@+id/minimize_window" />

<ImageButton android:id="@+id/maximize_window" />

<ImageButton android:id="@+id/close_window" />

</com.android.wm.shell.windowdecor.WindowDecorLinearLayout>

输入事件处理架构

1. 多层输入处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

// 标题栏触摸事件

mOnCaptionTouchListener = new View.OnTouchListener() {

@Override

public boolean onTouch(View v, MotionEvent event) {

// 处理标题栏拖拽

return mDragDetector.onTouchEvent(event);

}

};



// 拖拽调整大小输入

mDragResizeListener = new DragResizeInputListener(

mInputSinkSurface,

mDragPositioningCallback,

mHandler

);

2. 输入事件分发

1
2
3

用户输入 → Input Sink Surface → DragResizeInputListener → DragPositioningCallback → WindowContainerTransaction

事务同步机制

1. SyncTransactionQueue 使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

// 同步事务队列

private final SyncTransactionQueue mSyncQueue;



// 提交事务

mSyncQueue.runInSync(t -> {

t.setPosition(mCaptionContainerSurface, x, y)

.setWindowCrop(mCaptionContainerSurface, width, height)

.show(mCaptionContainerSurface);

});

2. 事务批处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

// 批量 Surface 操作

SurfaceControl.Transaction transaction = mSurfaceControlTransactionSupplier.get();

transaction.setPosition(mCaptionContainerSurface, outResult.mCaptionX, outResult.mCaptionY)

.setWindowCrop(mCaptionContainerSurface, outResult.mCaptionWidth, outResult.mCaptionHeight)

.setLayer(mCaptionContainerSurface, CAPTION_LAYER_Z_ORDER)

.show(mCaptionContainerSurface);

transaction.apply();

性能优化策略

1. Surface 复用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

// 检查 Surface 是否已存在

if (mCaptionContainerSurface == null) {

// 创建新 Surface

mCaptionContainerSurface = builder.build();

} else {

// 复用现有 Surface

startT.setPosition(mCaptionContainerSurface, x, y);

}

2. 事务优化

1
2
3
4
5
6
7
8
9
10
11
12
13

// 批量操作减少事务数量

SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();

transaction.setPosition(surface1, x1, y1)

.setPosition(surface2, x2, y2)

.setPosition(surface3, x3, y3);

transaction.apply();

3. 内存管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

// Surface 释放

@Override

protected void finalize() throws Throwable {

try {

if (mCaptionContainerSurface != null) {

mCaptionContainerSurface.release();

}

} finally {

super.finalize();

}

}

调试和监控

1. Surface 状态检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 查看 Surface 层次结构

adb shell dumpsys SurfaceFlinger --layers



# 查看特定任务的 Surface

adb shell dumpsys SurfaceFlinger | grep "Task="



# 查看窗口装饰 Surface

adb shell dumpsys SurfaceFlinger | grep -A 10 -B 5 "Caption\|Decoration"

2. 性能监控

1
2
3
4
5
6
7
8
9
10
11

# 查看 Surface 性能统计

adb shell dumpsys SurfaceFlinger --latency



# 查看 Surface 内存使用

adb shell dumpsys SurfaceFlinger --meminfo

3. 日志调试

1
2
3
4
5
6
7
8
9
10
11

# 监控 Surface 创建和销毁

adb logcat | grep -E "Surface|WindowDecoration|CaptionWindow"



# 监控事务提交

adb logcat | grep -E "Transaction|SurfaceControl"

最佳实践

1. Surface 生命周期管理

  • 及时释放:Surface 使用完毕后及时调用 release()

  • 异常处理:在 finalize() 方法中确保 Surface 被正确释放

  • 状态检查:操作前检查 Surface 是否有效

2. 事务管理

  • 批量操作:将多个 Surface 操作合并到单个事务中

  • 同步提交:使用 SyncTransactionQueue 确保事务同步

  • 错误处理:事务失败时进行适当的回滚处理

3. 性能优化

  • Surface 复用:避免频繁创建和销毁 Surface

  • 内存优化:合理管理 Surface 内存使用

  • 渲染优化:减少不必要的 Surface 更新

总结

CaptionWindowDecoration 的多层 Surface 架构展现了 Android 窗口系统设计的精妙之处:

  1. 分层设计:通过多层 Surface 实现应用内容与装饰元素的分离

  2. 精确控制:每个 Surface 层都有明确的职责和 Z-order 层级

  3. 高效渲染:SurfaceControlViewHost 实现了 View 到 Surface 的高效转换

  4. 灵活交互:多层输入处理机制支持复杂的用户交互

  5. 性能优化:事务批处理和 Surface 复用确保了良好的性能表现

这种架构不仅满足了窗口装饰的功能需求,还为未来的扩展和优化提供了坚实的基础。