概述
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> {
final SurfaceControl mTaskSurface;
SurfaceControl mDecorationContainerSurface;
SurfaceControl mCaptionContainerSurface;
SurfaceControl mInputSinkSurface;
SurfaceControlViewHost mViewHost;
WindowlessWindowManager mCaptionWindowManager;
T mRootView;
private static final int CAPTION_LAYER_Z_ORDER = -1;
private static final int INPUT_SINK_Z_ORDER = -2;
}
|
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
|
mTaskSurface = cloneSurfaceControl(taskSurface, surfaceControlSupplier);
mDecorationContainerSurface = builder
.setName("Decor container of Task=" + mTaskInfo.taskId)
.setContainerLayer()
.setParent(mTaskSurface)
.setCallsite("WindowDecoration.updateDecorationContainerSurface")
.build();
mCaptionContainerSurface = builder
.setName("Caption container of Task=" + mTaskInfo.taskId)
.setContainerLayer()
.setParent(mDecorationContainerSurface)
.setCallsite("WindowDecoration.updateCaptionContainerSurface")
.build();
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
|
startT.setLayer(mDecorationContainerSurface, TaskConstants.TASK_CHILD_LAYER_WINDOW_DECORATIONS)
.setLayer(mCaptionContainerSurface, CAPTION_LAYER_Z_ORDER)
.setLayer(mInputSinkSurface, INPUT_SINK_Z_ORDER);
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
);
mViewHost = new SurfaceControlViewHost(
mDecorWindowContext,
mDisplay,
mCaptionWindowManager
);
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
|
<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
|
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
|
if (mCaptionContainerSurface == null) {
mCaptionContainerSurface = builder.build();
} else {
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
|
@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
|
adb shell dumpsys SurfaceFlinger --layers
adb shell dumpsys SurfaceFlinger | grep "Task="
adb shell dumpsys SurfaceFlinger | grep -A 10 -B 5 "Caption\|Decoration"
|
2. 性能监控
1 2 3 4 5 6 7 8 9 10 11
|
adb shell dumpsys SurfaceFlinger --latency
adb shell dumpsys SurfaceFlinger --meminfo
|
3. 日志调试
1 2 3 4 5 6 7 8 9 10 11
|
adb logcat | grep -E "Surface|WindowDecoration|CaptionWindow"
adb logcat | grep -E "Transaction|SurfaceControl"
|
最佳实践
1. Surface 生命周期管理
2. 事务管理
3. 性能优化
总结
CaptionWindowDecoration 的多层 Surface 架构展现了 Android 窗口系统设计的精妙之处:
分层设计:通过多层 Surface 实现应用内容与装饰元素的分离
精确控制:每个 Surface 层都有明确的职责和 Z-order 层级
高效渲染:SurfaceControlViewHost 实现了 View 到 Surface 的高效转换
灵活交互:多层输入处理机制支持复杂的用户交互
性能优化:事务批处理和 Surface 复用确保了良好的性能表现
这种架构不仅满足了窗口装饰的功能需求,还为未来的扩展和优化提供了坚实的基础。