窗口在App端是以PhoneWindow的形式存在,承载了一个Activity的View层级结构。这里我们探讨一下WMS端窗口的形式。
可以通过adb shell dumpsys activity containers 来看窗口显示的层级

窗口容器类 —— WindowContainer类

/**
 * Defines common functionality for classes that can hold windows directly or through their
 * children in a hierarchy form.
 * The test class is {@link WindowContainerTests} which must be kept up-to-date and ran anytime
 * changes are made to this class.
 */
class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<E>
        implements Comparable<WindowContainer>, Animatable, SurfaceFreezer.Freezable,
        InsetsControlTarget {
    ......
         /**
     * The parent of this window container.
     * For removing or setting new parent {@link #setParent} should be used, because it also
     * performs configuration updates based on new parent's settings.
     */
    private WindowContainer<WindowContainer> mParent = null;
    ......
    // List of children for this window container. List is in z-order as the children appear on
    // screen with the top-most window container at the tail of the list.
    protected final WindowList<E> mChildren = new WindowList<E>();

WindowContainer注释中开头就说明了其作用,即给可以直接持有窗口的自己或它的孩子定义了一些公共的方法和属性。
WindowContainer定义了能够直接或者间接以层级结构的形式持有窗口的类的通用功能。
从类的定义和名称,可以看到WindowContainer是一个容器类,可以容纳WindowContainer及其子类对象。如果另外一个容器类作为WindowState的容器,那么这个容器类需要继承WindowContainer或其子类。

其中mParent和mChildren,一个代表父节点一个代表子节点,而且子节点的list顺序代表就是z轴的层级显示顺序,list尾巴在比list的头的z轴层级要高。
1)mParent是WindowContainer类型成员变量,保存的是当前WindowContainer的父容器的引用。
2)mChildren是WindowList类型的成员变量,保存的则是当前WindowContainer持有的所有子容器。并且列表的顺序也就是子容器出现在屏幕上的顺序,最顶层的子容器位于队尾。

根窗口容器 —— RootWindowContainer

/** Root {@link WindowContainer} for the device. */
public class RootWindowContainer extends WindowContainer<DisplayContent>

根窗口容器,树的根是它。通过它遍历寻找,可以找到窗口树上的窗口。它的孩子是DisplayContent。

屏幕 —— DisplayContent

/**
 * Utility class for keeping track of the WindowStates and other pertinent contents of a
 * particular Display.
 */
class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.DisplayContentInfo {

该类是对应着显示屏幕的,Android是支持多屏幕的,所以可能存在多个DisplayContent对象。上图只画了一个对象的结构,其他对象的结构也是和画的对象的结构是相似的。


RootWindowContainer代表dumpsys containers中ROOT ,DisplayContentdumpsys containers中Display,0表示当前显示的屏幕
在这里插入图片描述


窗口 —— WindowState类

/** A window in the window manager. */
class WindowState extends WindowContainer<WindowState> implements WindowManagerPolicy.WindowState,
        InsetsControlTarget, InputTarget {

WMS窗口体系中,一个WindowState对象就代表了一个窗口,其继承WindowContainer,这就说明WindowState同样可以作为其他窗口的父容器,例如我们常见的PopupWindow
在这里插入图片描述

WindowState的容器

可直接持有WindowState的容器即WindowToken和ActivityRecord,WallpaperWindowToken也可以持有WindowState,而其是继承WindowToken的

WindowToken类

/**
 * Container of a set of related windows in the window manager. Often this is an AppWindowToken,
 * which is the handle for an Activity that it uses to display windows. For nested windows, there is
 * a WindowToken created for the parent window to manage its children.
 */
class WindowToken extends WindowContainer<WindowState> {

这个注释的意思大概是说:窗口管理器中一组相关窗口的容器。这通常是一个AppWindowToken,它是用于显示窗口的“活动”的句柄。对于嵌套窗口,会为父窗口创建一个WindowToken来管理其子窗口。
总而言之就是用WindowToken来管理WindowState
在这里插入图片描述

WallpaperWindowToken类

/**
 * A token that represents a set of wallpaper windows.
 */
class WallpaperWindowToken extends WindowToken {

WallpaperWindowToken继承WindowToken,是用来存放和Wallpaper相关的窗口。
在这里插入图片描述

ActivityRecord类

/**
 * An entry in the history task, representing an activity.
 */
public final class ActivityRecord extends WindowToken implements WindowManagerService.AppFreezeListener {

ActivityRecord是WindowToken的子类,在WMS中一个ActivityRecord对象就代表一个Activity对象

在这里插入图片描述


一般来说,一个窗口的父容器是WindowToken还是ActivityRecord,是否主动使用ViewManager.addView来添加一个窗口
父容器为WindowToken的情况:APP(含系统应用)主动调用添加窗口方法来添加窗口,如StatusBar、浮窗等。即非Activity窗口
父容器为ActivityRecord的情况:系统侧调用添加窗口方法来添加窗口,如在桌面启动一个应用等。即Activity窗口

从层级角度将窗口划分为:
App之上的窗口,父容器为WindowToken,如StatusBar和NavigationBar。
App窗口,父容器为ActivityRecord,如Launcher。
App之下的窗口,父容器为WallpaperWindowToken,如ImageWallpaper窗口


WindowToken的容器 —— DisplayArea.Tokens

    /**
     * DisplayArea that contains WindowTokens, and orders them according to their type.
     */
    public static class Tokens extends DisplayArea<WindowToken> {

包含WindowTokens的容器Tokens,并根据其类型对其进行排序。

ActivityRecord的容器 —— Task

/**
 * {@link Task} is a TaskFragment that can contain a group of activities to perform a certain job.
 * Activities of the same task affinities usually group in the same {@link Task}. A {@link Task}
 * can also be an entity that showing in the Recents Screen for a job that user interacted with.
 * A {@link Task} can also contain other {@link Task}s.
 */
class Task extends TaskFragment {

Task继承TaskFragment,它的孩子可以是Task,也可以是ActivityRecord类型。是一个TaskFragment,它可以包含一组执行特定作业的Activity。具有相同任务相似性的Activity通常在同一任务中分组。任务也可以是显示在用户交互的作业的最近屏幕中的实体。任务还可以包含其他任务。

/**
 * A basic container that can be used to contain activities or other {@link TaskFragment}, which
 * also able to manage the activity lifecycle and updates the visibilities of the activities in it.
 */
class TaskFragment extends WindowContainer<WindowContainer> {

一个基本容器,可用于包含Activity或其他TaskFragment,它还能够管理Activity生命周期并更新其中活动的可见性。

Task的容器 —— TaskDisplayArea

/**
 * {@link DisplayArea} that represents a section of a screen that contains app window containers.
 *
 * The children can be either {@link Task} or {@link TaskDisplayArea}.
 */
final class TaskDisplayArea extends DisplayArea<WindowContainer> {

TaskDisplayArea,代表了屏幕上一块专门用来存放App窗口的区域。
它的子容器可能是Task或者是TaskDisplayArea。


在这里插入图片描述DefaultTaskDisplay是TaskDisplayArea的别名,在代码中有体现,后面说明
从这个dump中我们可以看到TaskDisplayArea下面就是Task,Task下面就是ActivityRecord且有多个,而ActivityRecord下面的a9a1d8b和c4b2818是各自的WindowState


DisplayArea类

/**
 * Container for grouping WindowContainer below DisplayContent.
 *
 * DisplayAreas are managed by a {@link DisplayAreaPolicy}, and can override configurations and
 * can be leashed.
 *
 * DisplayAreas can contain nested DisplayAreas.
 *
 * DisplayAreas come in three flavors, to ensure that windows have the right Z-Order:
 * - BELOW_TASKS: Can only contain BELOW_TASK DisplayAreas and WindowTokens that go below tasks.
 * - ABOVE_TASKS: Can only contain ABOVE_TASK DisplayAreas and WindowTokens that go above tasks.
 * - ANY: Can contain any kind of DisplayArea, and any kind of WindowToken or the Task container.
 *
 * @param <T> type of the children of the DisplayArea.
 */
public class DisplayArea<T extends WindowContainer> extends WindowContainer<T> {

用于将WindowContainer分组到DisplayContent下方的容器。
DisplayArea由{@link DisplayAreaPolicy}管理,能够复写Configuration和被绑定到leash上。
DisplayArea可以包含嵌套的DisplayArea。
DisplayAreas有三种风格,以确保窗口具有正确的Z顺序:

  • BELOW_TASKS:只能包含位于任务下方的BELLOW_TASK显示区域和WindowToken。
  • ABOVE_TASKS:只能包含位于任务上方的ABOVE_TASK显示区域和WindowToken。
  • ANY:可以包含任何类型的DisplayArea,以及任何类型的WindowToken或Task容器。

@param<T>DisplayArea的子项的类型。

DisplayArea有三个直接子类,TaskDisplayArea,DisplayArea.Tokens和DisplayArea.Tokens

Task的容器 —— TaskDisplayArea

/**
 * {@link DisplayArea} that represents a section of a screen that contains app window containers.
 *
 * The children can be either {@link Task} or {@link TaskDisplayArea}.
 */
final class TaskDisplayArea extends DisplayArea<WindowContainer> {

TaskDisplayArea为DisplayContent的孩子,对应着窗口层次的第2层。第2层作为应用层,看它的定义:int APPLICATION_LAYER = 2,应用层的窗口是处于第2层。
TaskDisplayArea代表了屏幕上的一个包含App类型的WindowContainer的区域。它的子节点可以是Task,或者是TaskDisplayArea。

public DisplayAreaPolicy instantiate(WindowManagerService wmService,
                DisplayContent content, RootDisplayArea root,
                DisplayArea.Tokens imeContainer) {
        Inject.ResultOne<TaskDisplayArea> result = new Inject.ResultOne<>(new TaskDisplayArea(content, wmService,
                    "DefaultTaskDisplayArea", FEATURE_DEFAULT_TASK_CONTAINER));

在DisplayAreaPolicy.java中有创建,并更名为DefaultTaskDisplayArea

WindowTokens的容器 —— DisplayArea.Tokens

    /**
     * DisplayArea that contains WindowTokens, and orders them according to their type.
     */
    public static class Tokens extends DisplayArea<WindowToken> {

Tokens为DisplayArea的内部类,且继承DisplayArea。
即Tokens代表专门包含WindowTokens的容器,它的孩子是WindowToken,而WindowToken的孩子则为WindowState对象。WindowState是对应着一个窗口的。

输入法的容器 —— ImeContainer

    /**
     * Container for IME windows.
     *
     * This has some special behaviors:
     * - layers assignment is ignored except if setNeedsLayer() has been called before (and no
     *   layer has been assigned since), to facilitate assigning the layer from the IME target, or
     *   fall back if there is no target.
     * - the container doesn't always participate in window traversal, according to
     *   {@link #skipImeWindowsDuringTraversal()}
     */
    private static class ImeContainer extends DisplayArea.Tokens {

ImeContainer为DisplayContent.java的内部类,且继承DisplayArea.Tokens,即同样是一个WindowToken的容器,它的孩子是WindowToken类型。WindowToken的孩子为WindowState类型,而WindowState类型则对应着输入法窗口。
在这里插入图片描述

模糊效果 —— DisplayArea.Dimmable

    /**
     * DisplayArea that can be dimmed.
     */
    static class Dimmable extends DisplayArea<DisplayArea> {
        private final Dimmer mDimmer = new Dimmer(this);

Dimmable也是DisplayArea的内部类,从名字可以看出,这类的DisplayArea可以添加模糊效果,并且Dimmable也是一个DisplayArea类型的DisplayArea容器。
可以通过Dimmer对象mDimmer施加模糊效果,模糊图层可以插入到以该Dimmable对象为根节点的层级结构之下的任意两个图层之间。
且它有一个直接子类,RootDisplayArea。

DisplayArea层级结构的根节点 —— RootDisplayArea

/**
 * Root of a {@link DisplayArea} hierarchy. It can be either the {@link DisplayContent} as the root
 * of the whole logical display, or a {@link DisplayAreaGroup} as the root of a partition of the
 * logical display.
 */
class RootDisplayArea extends DisplayArea.Dimmable {

{@link DisplayArea}层次结构的根。它可以是作为整个逻辑显示的根的{@link DisplayContent},也可以是作为逻辑显示的分区的根的{@link DisplayAreaGroup}。
即:
DisplayContent,作为整个屏幕的DisplayArea层级结构根节点。
DisplayAreaGroup,作为屏幕上部分区域对应的DisplayArea层级结构的根节点

屏幕 —— DisplayContent
/**
 * Utility class for keeping track of the WindowStates and other pertinent contents of a
 * particular Display.
 */
class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.DisplayContentInfo {

用于跟踪特定显示器的WindowStates和其他相关内容的实用程序类,总而言之就是代表一个屏幕。
隶属于同一个DisplayContent的窗口将会被显示在同一个屏幕中。每一个DisplayContent都对应着唯一ID

DisplayAreaGroup
/** The root of a partition of the logical display. */
class DisplayAreaGroup extends RootDisplayArea {

逻辑显示分区的根

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
public class MyApp extends MultiDexApplication {
private int count = 0;
@Override
public void onCreate() {
initActivityLifecycle();
}
private void initActivityLifecycle() {
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
}
@Override
public void onActivityStarted(Activity activity) {
count ++;
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {

}
@Override
public void onActivityStopped(Activity activity) {
if(count > 0) {
count--;
}
boolean isBackground = isBackground();
Log.e("tyl","isBackground="+isBackground);
if(isBackground){
//app已经切入到后台
//System.exit(0);
}
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

}
@Override
public void onActivityDestroyed(Activity activity) {

}
});
}
/**
* 判断app是否在后台
* @return
*/
public boolean isBackground(){
if(count <= 0){
return true;
} else {
return false;
}
}
}

八、绘制

ViewRootImpl.performDraw

先看CPU绘制:

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
java复制代码ViewRootImpl.mTraversalRunnable.run()
| doTraversal();
| performTraversals();
| relayoutWindow //创建surface流程 + sf 创建layer流程
| hwInitialized = mAttachInfo.mThreadedRenderer.initialize(mSurface);
| mAttachInfo.mThreadedRenderer.allocateBuffers();//硬件绘制,预分配内存
| performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
| mView.measure(childWidthMeasureSpec, childHeightMeasureSpec); // measure 流程
| performLayout(lp, mWidth, mHeight);
| mView.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight()); // layout 流程
| mAttachInfo.mTreeObserver.dispatchOnGlobalLayout();//分发OnGlobalLayout事件
| View focused = mView.findFocus(); focused.restoreDefaultFocus(); //插眼WYF,这块逻辑以后再看
// 分发OnPreDraw事件
| boolean cancelDraw = mAttachInfo.mTreeObserver.dispatchOnPreDraw() || !isViewVisible; //不拦截的话 cancelDraw = FALSE
| performDraw();
| Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw");
| boolean canUseAsync = draw(fullRedrawNeeded);
| mAttachInfo.mTreeObserver.dispatchOnDraw();// 分发OnDraw,回调OnDrawListener中的onDraw()方法。
// 硬件绘制
| isHardwareEnabled()
| mAttachInfo.mThreadedRenderer.draw(mView, mAttachInfo, this);
// 如果未开启硬件绘制使用软件绘制:
| drawSoftware(surface, mAttachInfo, xOffset, yOffset, scalingRequired, dirty, surfaceInsets)
| Canvas canvas = mSurface.lockCanvas(dirty);
// /frameworks/base/core/java/android/view/Surface.java
|-->Canvas lockCanvas(Rect inOutDirty)
| | private final Canvas mCanvas = new CompatibleCanvas(); // 初始化 Canvas.mNativeCanvasWrapper
| // 把 native lock 的Surface地址保存到mLockedObject,这个mLockedObject通常情况和mNativeObject是一个地址
| | mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
| | // /frameworks/base/core/jni/android_view_Surface.cpp
| |-->nativeLockCanvas(JNIEnv* env, jclass clazz, jlong nativeObject, jobject canvasObj, jobject dirtyRectObj)
| | // 把Java层保存的地址转换为 native Surface
| | sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
| | ANativeWindow_Buffer buffer;
| | surface->lock(&buffer, dirtyRectPtr);
|-->Surface::lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
| // 1、需要先连接到SurfaceFlinger端的BufferQueueProducer,会返回宽高数据,SurfaceFlinger端的BufferQueueCore也会设置一些属性
| // 注释说在调用dequeueBuffer前,必须先调用connect,是传入生产者监听,接收 onBufferReleased 回调。
| // 但是软绘,传入的监听是StubProducerListener,onBufferReleased是个空函数
| int err = Surface::connect(NATIVE_WINDOW_API_CPU);
| | ANativeWindowBuffer* out;
| int fenceFd = -1;
| | // 2、调用dequeueBuffer获取 ANativeWindowBuffer 对象 和 fenceFd。
| | status_t err = dequeueBuffer(&out, &fenceFd); // 【进入 dequeueBuffer 章节】
| | // 3、使用ANativeWindowBuffer创建后台 GraphicBuffer 对象
| | sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out)); // GraphicBuffer 继承 ANativeWindowBuffer
| // 4、获取前台buffer
| const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
| // 宽高格式都相同时,可以把前台的buffer的 Region 复制给后台buffer
| const bool canCopyBack = (frontBuffer != nullptr && backBuffer->width == frontBuffer->width &&...);
| // 干净区域 = 上一次所重绘的区域减去接下来需要重绘的脏区域newDirtyRegion,
| // copyBlt 把干净的区域从frontBuffer拷贝到backBuffer
| if (canCopyBack) const Region copyback(mDirtyRegion.subtract(newDirtyRegion));copyBlt(...);
| // 5、锁定 GraphicBuffer,获取buffer地址
| void* vaddr; // 这变量会携带图形buffer的地址回来,图形库,其实就是在这个地址上做像素操作
| // 调用 GraphicBufferMapper::lockAsync
| backBuffer->lockAsync(...,newDirtyRegion.bounds(), &vaddr, fenceFd);
| mLockedBuffer = backBuffer; // 后台buffer变为已经lock的buffer,入队后变为 mPostedBuffer
| // 6、把获取到的这些信息,存储到 ANativeWindow_Buffer,函数返回后,会把这对象传给图形库
| outBuffer->width = backBuffer->width;
| outBuffer->height = backBuffer->height;
| outBuffer->stride = backBuffer->stride;
| outBuffer->format = backBuffer->format;
| outBuffer->bits = vaddr; // 把图形buffer的地址赋值给 ANativeWindow_Buffer.bits
| // graphics::Canvas.mCanvas = native 层的 SkiaCanvas
| | graphics::Canvas canvas(env, canvasObj);
| // 把图形缓存的地址,宽高格式啊这些,设置进图形库的 SkiaCanvas,有了这些,图形库就专注画图就行了
| canvas.setBuffer(&buffer, static_cast<int32_t>(surface->getBuffersDataSpace()));
| sp<Surface> lockedSurface(surface); // 创建新的sp引用
| lockedSurface->incStrong(&sRefBaseOwner); // 引用加一
| return (jlong) lockedSurface.get(); // 返回地址,传入Java 层的 mLockedObject
| | return mCanvas;
| mView.draw(canvas); //[View的绘制流程]
| surface.unlockCanvasAndPost(canvas); // queueBuffer流程起始
| if (mHwuiContext != null) mHwuiContext.unlockAndPost(canvas);
| else unlockSwCanvasAndPost(canvas);
| nativeUnlockCanvasAndPost(mLockedObject, canvas);
|-->nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz, jlong nativeObject, jobject canvasObj)
| sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
| graphics::Canvas canvas(env, canvasObj);
| canvas.setBuffer(nullptr, ADATASPACE_UNKNOWN);// detach the canvas from the surface
| status_t err = surface->unlockAndPost();
|-->Surface::unlockAndPost()
| int fd = -1;
| status_t err = mLockedBuffer->unlockAsync(&fd);
| err = queueBuffer(mLockedBuffer.get(), fd); // 【进入 queueBuffer 章节】
| mPostedBuffer = mLockedBuffer; // 把锁定状态的buffer转换为 已经入队的 buffer
| mLockedBuffer = nullptr;

Surface.connect–>BBQBufferQueueProducer.connect

  • 重点是注册生产者回调
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
c++复制代码status_t Surface::lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds);
| if (!mConnectedToCpu) // 没调用过 connect 时,false
| Surface::connect(NATIVE_WINDOW_API_CPU);
|-->Surface::connect(int api)
| // StubProducerListener 就是个虚假的实现,重载函数都为空函数
| static sp<IProducerListener> listener = new StubProducerListener();
| return connect(api, listener);
|-->Surface::connect(int api, const sp<IProducerListener>& listener)
| return connect(api, listener, false);
| //参数 reportBufferRemoval = false
|-->Surface::connect( int api, const sp<IProducerListener>& listener, bool reportBufferRemoval)
| IGraphicBufferProducer::QueueBufferOutput output;
| mReportRemovedBuffers = reportBufferRemoval; // false
| // mProducerControlledByApp = true; BBQSurface 创建时,传入的是 true
| int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output);
|-->BBQBufferQueueProducer.connect(IProducerListener& listener,int api,bool producerControlledByApp QueueBufferOutput* output)
| return BufferQueueProducer::connect(listener, api, producerControlledByApp, output);
|-->BufferQueueProducer::connect(IProducerListener& listener,int api, bool producerControlledByApp, QueueBufferOutput *output)
| mConsumerName = mCore->mConsumerName;//mConsumerName = "ViewRootImpl#[id](BLAST Consumer)[id]"
| // 中间有一段代码,会依据擦混入的参数producerControlledByApp再调整一次 BufferQueueCore的 mFreeSlots mUnusedSlots
| // 目前的参数为无效代码,不贴代码了
| | switch (api) {
case NATIVE_WINDOW_API_EGL:
| case NATIVE_WINDOW_API_CPU:
| case NATIVE_WINDOW_API_MEDIA:
case NATIVE_WINDOW_API_CAMERA:
| mCore->mConnectedApi = api;
// 返回给 Surface 的属性
// 这些值,在 BLASTBufferQueue.update 把SurfaceContrl的值传到BufferQueueCore,现在又从 BufferQueueCore 传回Surface
| output->width = mCore->mDefaultWidth;
| output->height = mCore->mDefaultHeight;
// 用于优化旋转。预旋转
| output->transformHint = mCore->mTransformHintInUse = mCore->mTransformHint;//初始化时为 0
// 返回当前 处于 QUEUEED 状态的 buffer 数量
| output->numPendingBuffers = static_cast<uint32_t>(mCore->mQueue.size());
output->nextFrameNumber = mCore->mFrameCounter + 1;
| output->bufferReplaced = false;
output->maxBufferCount = mCore->mMaxBufferCount;
| // 【注册生产者回调--onBufferReleased】
| mCore->mConnectedProducerListener = listener;// CPU绘制传入的 StubProducerListener,没啥用
// 用于触发 onBufferReleased 回调, mBufferReleasedCbEnabled 为true的时候才能触发
| mCore->mBufferReleasedCbEnabled = listener->needsReleaseNotify(); // CPU 绘制返回false
| // 再刷一遍 BufferQueueCore 的属性,其实这些属性 BufferQueueCore 初始化时设置的也是这些值
| mCore->mConnectedPid = BufferQueueThreadState::getCallingPid();
| mCore->mBufferHasBeenQueued = false; mCore->mDequeueBufferCannotBlock = false;
| | mCore->mQueueBufferCanDrop = false; mCore->mLegacyBufferDrop = true;
| mCore->mAllowAllocation = true; // 允许分配内存
| // 使用请求到的数据,设置 Surface 属性
| mDefaultWidth = output.width; mDefaultHeight = output.height;
| mNextFrameNumber = output.nextFrameNumber; mMaxBufferCount = output.maxBufferCount;
| mTransformHint = output.transformHint;// 这只是一个提示,实际的转换可能会有所不同。被用来提高layer的系统性能
| mConsumerRunningBehind = (output.numPendingBuffers >= 2);
| if (!err && api == NATIVE_WINDOW_API_CPU) mConnectedToCpu = true; // CPU绘制
else mDirtyRegion = Region::INVALID_REGION;
  • Surface继承 ANativeWindow
    • ANativeWindow 图形库的各种函数
  • ANativeWindow_Buffer ANativeWindow_Buffer.bits 存储图形buffer的地址
    • 用于 Surface::lock 的参数,用于图形库。
  • GraphicBuffer 继承 ANativeWindowBuffer
    • 封装图形内存分配接口 GraphicBufferMapper GraphicBufferAllocator ,以及进程间传递的序列化接口
    • ANativeWindowBuffer
      • typedef ANativeWindowBuffer ANativeWindowBuffer_t
      • typedef ANativeWindowBuffer_t android_native_buffer_t;
      • 内部有个成员 native_handle_t* handle; 存储buffer的fd

Surface.dequeueBuffer–>BufferQueueProducer.dequeueBuffer

BBQBufferQueueProducer 没有重载 BufferQueueProducer.dequeueBuffer

直接调用父类 BufferQueueProducer.dequeueBuffer

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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
c++复制代码status_t Surface::lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds);
| if (!mConnectedToCpu) // 没调用过 connect 时,false
| Surface::connect(NATIVE_WINDOW_API_CPU);
| ANativeWindowBuffer* out;
| int fenceFd = -1;
| status_t err = dequeueBuffer(&out, &fenceFd);
|-->Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd);
| | getDequeueBufferInputLocked(&dqInput);
|-->Surface::getDequeueBufferInputLocked(IGraphicBufferProducer::DequeueBufferInput* dequeueInput)
| // Req 前缀表示 request,用于请求使用的参数,软绘应该全使用的默认值
| dequeueInput->width = mReqWidth ? mReqWidth : mUserWidth;// 默认 mReqWidth = mUserWidth = 0
| dequeueInput->height = mReqHeight ? mReqHeight : mUserHeight;// 默认 mReqHeight = mUserHeight = 0
| dequeueInput->format = mReqFormat;// 默认 0
| dequeueInput->usage = mReqUsage;// 默认 0
| dequeueInput->usage = mReqUsage;// mEnableFrameTimestamps 默认false
| dequeueInput->getTimestamps = mEnableFrameTimestamps;// mEnableFrameTimestamps 默认false
| int buf = -1;
| sp<Fence> fence;
| nsecs_t startTime = systemTime();// 当前时间
| FrameEventHistoryDelta frameTimestamps;
| status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, dqInput.width,dqInput.height, dqInput.format,
dqInput.usage, &mBufferAge,dqInput.getTimestamps ? &frameTimestamps : nullptr);
|-->BufferQueueProducer.dequeueBuffer(int* outSlot, sp<android::Fence>* outFence, uint32_t width, uint32_t height,
PixelFormat format, uint64_t usage, uint64_t* outBufferAge, FrameEventHistoryDelta* outTimestamps)
| mConsumerName = mCore->mConsumerName; // consumerName = "ViewRootImpl#[id](BLAST Consumer)[id]"
| //width、height 可以都为0,但是不能一个是0,一个非零。
| if ((width && !height) || (!width && height)) return BAD_VALUE;
| if (mCore->mFreeBuffers.empty() && mCore->mIsAllocating) mCore->waitWhileAllocatingLocked(lock);//正在分配buffer,自旋等待
| if (format == 0) format = mCore->mDefaultBufferFormat; // mDefaultBufferFormat = PIXEL_FORMAT_RGBA_8888
| // mConsumerUsageBits 在BLASTBufferItemConsumer构造是赋值为 GraphicBuffer::USAGE_HW_COMPOSER |GraphicBuffer::USAGE_HW_TEXTURE
| usage |= mCore->mConsumerUsageBits
| const bool useDefaultSize = !width && !height; // 宽高都为0,使用默认尺寸
| if (useDefaultSize)
| //默认宽高在 BLASTBufferQueue.update 把SurfaceContrl的宽高值传到BufferQueueCore
| width = mCore->mDefaultWidth; height = mCore->mDefaultHeight;
| if (mCore->mAutoPrerotation && (mCore->mTransformHintInUse & NATIVE_WINDOW_TRANSFORM_ROT_90))
| std::swap(width, height); // mAutoPrerotation自动预旋转默认false,mTransformHintInUse 90度时宽高互换
| int found = BufferItem::INVALID_BUFFER_SLOT;
| //【获取可用的 BufferSlot 索引】
| waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue, lock, &found);
|-->BufferQueueProducer::waitForFreeSlotThenRelock(FreeSlotCaller caller, std::unique_lock<std::mutex>& lock, int* found)
| bool tryAgain = true;
| while (tryAgain)
| *found = BufferQueueCore::INVALID_BUFFER_SLOT;
| // 首先从list链表 BufferQueueCore->mFreeBuffers 拿 BufferSlot,如果集合是空的,会返回BufferQueueCore::INVALID_BUFFER_SLOT
| int slot = getFreeBufferLocked();
| if (slot != BufferQueueCore::INVALID_BUFFER_SLOT)
| *found = slot;
| else if (mCore->mAllowAllocation)
| // mFreeBuffers没有,就从set集合 BufferQueueCore->mFreeSlots 拿 BufferSlot,如果集合是空的,返回BufferQueueCore::INVALID_BUFFER_SLOT
| *found = getFreeSlotLocked();
| tryAgain = (*found == BufferQueueCore::INVALID_BUFFER_SLOT) || tooManyBuffers;
| // 没有 buffer了,或者 queue 太多了(这个可能性不大,mFreeSlots 这个set就三个数据,dequeue不出来那么多,queue就更不可能),
| if (tryAgain)
| if (mDequeueTimeout >= 0)// BBQ 设置的mDequeueTimeout=int64.max
| // 等待buffer(有可能是buffer被释放了,小概率因为mFreeSlots集合增加了)
| mCore->mDequeueCondition.wait_for(lock, std::chrono::nanoseconds(mDequeueTimeout));
| //拿到可用的索引found对应的 BufferSlot 的 GraphicBuffer
| const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
| //【把找到的buffer,插入到set集合 mActiveBuffers 中】
| mCore->mActiveBuffers.insert(found);
| //把索引值返回
| *outSlot = found;
| // 【把找到的 BufferSlot buffer状态转为 dequeue】
| mSlots[found].mBufferState.dequeue();
| //找到的 BufferSlot 没有关联GraphicBuffer,或者 GraphicBuffer 宽高,格式、usage、layerCount 和需求不相等的话,需要重新分配
| if ((buffer == nullptr) || buffer->needsReallocation(width, height, format, BQ_LAYER_COUNT, usage))
| mSlots[found].mAcquireCalled = false; mSlots[found].mGraphicBuffer = nullptr;
| mSlots[found].mRequestBufferCalled = false; mSlots[found].mEglDisplay = EGL_NO_DISPLAY;
| mSlots[found].mEglFence = EGL_NO_SYNC_KHR; mSlots[found].mFence = Fence::NO_FENCE;
| mCore->mBufferAge = 0; // 设置 mBufferAge 为0,新鲜的buffer啊,还没有被queue过
| mCore->mIsAllocating = true; // 设置为正在分配内存
| //【 添加 “需要重新分配buffer” flag】
| returnFlags |= BUFFER_NEEDS_REALLOCATION;
|else // 计算buffer年龄
| // mBufferAge: [(自从当前的 BufferSlot 上次被 queueBuffer 后,又queue了多少个BufferSlot) + 1]
| mCore->mBufferAge = mCore->mFrameCounter + 1 - mSlots[found].mFrameNumber;
| // 非共享内存模式下, 把当前的 buffer Fence ,传到外部参数 outFence
| *outFence = (mCore->mSharedBufferMode && mCore->mSharedBufferSlot == found) ? Fence::NO_FENCE : mSlots[found].mFence;
| // BufferSlot的Fence重新赋值为 NO_FENCE
| mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
| mSlots[found].mFence = Fence::NO_FENCE;
| // 【需要重新分配buffer情况,分配新的buffer】
| if (returnFlags & BUFFER_NEEDS_REALLOCATION)
| //GraphicBuffer构造函数中调用 GraphicBufferAllocator.allocate 分配图形buffer,并映射内存到当前进程
| sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(width, height, format, BQ_LAYER_COUNT, usage,mConsumerName);
| mCore->mIsAllocating = false; // 分配完了,要重新设置回 false 啊
| mCore->mIsAllocatingCondition.notify_all(); // 唤醒那些因为 正在分配buffer 而等待的线程
| // 如果需要等待 eglFence 释放 Fence
| if (eglFence != EGL_NO_SYNC_KHR)
| EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0,1000000000);// 等待B
| eglDestroySyncKHR(eglDisplay, eglFence);
| *outBufferAge = mCore->mBufferAge; // buffer年龄传到外部
| addAndGetFrameTimestamps(nullptr, outTimestamps);// BBQ 没有实现这方法,是个空实现。只有 BufferQueue 在消费者进程里,才会被调用。
| return returnFlags;
| //继续 Surface::dequeueBuffer
| mLastDequeueDuration = systemTime() - startTime;// 计算 dequeue 时间
| mLastDequeueStartTime = startTime;// 记录上次 dequeue 开始时间
| // 根据拿到的 slolt 下标,获取本地Surface自己的 GraphicBuffer
| sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
| if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) freeAllBuffers();
| if (dqInput.getTimestamps) mFrameEventHistory->applyDelta(frameTimestamps);
| // dequeueBuffer返回值 带有 BUFFER_NEEDS_REALLOCATION 标记,并且 gbuf == nullptr 的时候 进入此分支
| if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == nullptr)
| //【请求 GraphicBuffer】
| // requestBuffer接口很简单,直接返回 dequeueBuffer时关联/创建的 GraphicBuffer对象。
| // S版本以前,需要跨进程传递GraphicBuffer对象,反序列化时,会调用GraphicBufferMapper.importBuffer映射内存
| result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
| if (fence->isValid()) *fenceFd = fence->dup();
| // 赋值外部的 android_native_buffer_t** buffer
| *buffer = gbuf.get();
| // std::unordered_set<int> mDequeuedSlots;
| mDequeuedSlots.insert(buf); // Dequeued 的buffer的 下标 存入 mDequeuedSlots

Surface.queueBuffer

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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
c++复制代码// 前置流程:
surface.unlockCanvasAndPost(canvas); // queueBuffer
| if (mHwuiContext != null) mHwuiContext.unlockAndPost(canvas);
| else unlockSwCanvasAndPost(canvas);
| nativeUnlockCanvasAndPost(mLockedObject, canvas);
|-->nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz, jlong nativeObject, jobject canvasObj)
| sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
| graphics::Canvas canvas(env, canvasObj);
| canvas.setBuffer(nullptr, ADATASPACE_UNKNOWN);// detach the canvas from the surface
| status_t err = surface->unlockAndPost();
|-->Surface::unlockAndPost()
| | int fd = -1;
| | status_t err = mLockedBuffer->unlockAsync(&fd);
| GraphicBuffer::getBufferMapper().unlockAsync(handle, fenceFd);
| | err = queueBuffer(mLockedBuffer.get(), fd); // 进入【queueBuffer 章节】
| | mPostedBuffer = mLockedBuffer; // 把锁定的buffer转换为 已经入队的 buffer
| | mLockedBuffer = nullptr;
| nativeRelease(mLockedObject);
| mLockedObject = 0;

//【queueBuffer 章节】
Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd)
| int i = getSlotFromBufferLocked(buffer);
| // 遍历 Surface.mSlots 数组,找到 GraphicBuffer.handle 相同的 BufferSlot 索引
|-->Surface::getSlotFromBufferLocked(android_native_buffer_t* buffer)
| for (int i = 0; i < NUM_BUFFER_SLOTS; i++)
| if (mSlots[i].buffer != nullptr && mSlots[i].buffer->handle == buffer->handle)
| return i;
| IGraphicBufferProducer::QueueBufferOutput output;
| IGraphicBufferProducer::QueueBufferInput input;
| /*
Surface.mTimestamp 使用默认的 NATIVE_WINDOW_TIMESTAMP_AUTO 时,
QueueBufferInput.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
QueueBufferInput.isAutoTimestamp = true; // 这个参数标明是否在入队时,自动生成时间戳
| */
| getQueueBufferInputLocked(buffer, fenceFd, mTimestamp, &input);
| // 一些 Gralloc 的元数据 mapper.setDataspace,HdrMetadata 设置
| applyGrallocMetadataLocked(buffer, input);
| sp<Fence> fence = input.fence;
| nsecs_t now = systemTime();
| status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
|-->BufferQueueProducer::queueBuffer(int slot, const QueueBufferInput &input, QueueBufferOutput *output)
| int64_t requestedPresentTimestamp; bool isAutoTimestamp; android_dataspace dataSpace;
| Rect crop(Rect::EMPTY_RECT); int scalingMode; uint32_t transform;
| uint32_t stickyTransform; sp<Fence> acquireFence; bool getFrameTimestamps = false;
| // 读取输入参数的数据
| input.deflate(&requestedPresentTimestamp, &isAutoTimestamp, &dataSpace,
&crop, &scalingMode, &transform, &acquireFence, &stickyTransform, &getFrameTimestamps);
| const Region& surfaceDamage = input.getSurfaceDamage();
| const HdrMetadata& hdrMetadata = input.getHdrMetadata();
| sp<IConsumerListener> frameAvailableListener;// buffer 可用通知
| sp<IConsumerListener> frameReplacedListener;//buffer被替换通知
| BufferItem item; // 创建 BufferItem
| // 拿到 slot 对应的 GraphicBuffer
| const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
| // 裁剪区域
| Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
| Rect croppedRect(Rect::EMPTY_RECT);
| // crop 和 bufferRect 的交集,结果存入 croppedRect
| crop.intersect(bufferRect, &croppedRect);
| mSlots[slot].mFence = acquireFence;
| //【设置为 QUEUED 状态】
| mSlots[slot].mBufferState.queue();
| ++mCore->mFrameCounter;// 每次 queueBuffer 都+1
| currentFrameNumber = mCore->mFrameCounter;
| mSlots[slot].mFrameNumber = currentFrameNumber;//存储当前BufferSlot的帧号
| // 封装 BufferItem 信息
| item.mAcquireCalled = mSlots[slot].mAcquireCalled;
| item.mGraphicBuffer = mSlots[slot].mGraphicBuffer; //图形buffer
| item.mCrop = crop;//裁切矩形
| item.mTransform = transform & ~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);// 旋转变换
| item.mTransformToDisplayInverse = (transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
| item.mScalingMode = static_cast<uint32_t>(scalingMode);//缩放模式
| item.mTimestamp = requestedPresentTimestamp;//时间戳
| item.mIsAutoTimestamp = isAutoTimestamp;// 是否在入队时,自动生成时间戳,默认情况下 true
| item.mDataSpace = dataSpace;// 描述图像内容,依赖于图像格式
| item.mHdrMetadata = hdrMetadata;// HDR metadata 不懂
| item.mFrameNumber = currentFrameNumber;//帧号
| item.mSlot = slot;/*索引*/ item.mFence = acquireFence;/*fence*/ item.mFenceTime = acquireFenceTime;/*FenceTime*/
| // mIsDroppable 如果为true,则 queuebuffer 时,可以替换旧的buffer。
| item.mIsDroppable = mCore->mAsyncMode || ...;// 当前 mIsDroppable = false
| item.mSurfaceDamage = surfaceDamage;//已经被修改的区域
| item.mQueuedBuffer = true;// 标明buffer已经被生产者 queued,acquireBuffer后设置为false
| item.mAutoRefresh = mCore->mSharedBufferMode && mCore->mAutoRefresh;// 仅仅在共享buffer下有用,标明消费者应该尽快 acquire 下一帧
| item.mApi = mCore->mConnectedApi;//表明是 CPU还是GPU queue的buffer
| output->bufferReplaced = false;
| //【BufferItem入队】
| mCore->mQueue.push_back(item);
| // BufferQueueCore.mConsumerListener = ConsumerBase(BLASTBufferItemConsumer的父类)
| frameAvailableListener = mCore->mConsumerListener;
| mCore->mBufferHasBeenQueued = true;// 每次queueBuffer后都设置为true
| mCore->mDequeueCondition.notify_all();// 唤醒等待的线程
| mCore->mLastQueuedSlot = slot;// 赋值最新queue的 BufferSlot 索引
| // 返回给Surface的数据
| output->width = mCore->mDefaultWidth; output->height = mCore->mDefaultHeight;
| output->transformHint = mCore->mTransformHintInUse = mCore->mTransformHint;
| output->numPendingBuffers = static_cast<uint32_t>(mCore->mQueue.size());// 返回当前已经Queue的数量,代表还未被消费的数量
| output->nextFrameNumber = mCore->mFrameCounter + 1;// 返回下一帧的帧号
| // atrace 记录 mQueue 大小
| ATRACE_INT(mCore->mConsumerName.string(), static_cast<int32_t>(mCore->mQueue.size()));
| // BBQ生产者构造函数设置 mConsumerIsSurfaceFlinger = false
| if (!mConsumerIsSurfaceFlinger)
| // 清理 GraphicBuffer 指针【TODO:这里的一些比较重要联动细节待研究】
| item.mGraphicBuffer.clear();
| int connectedApi = mCore->mConnectedApi;
| sp<Fence> lastQueuedFence = std::move(mLastQueueBufferFence);
| mLastQueueBufferFence = std::move(acquireFence);
| //【消费者回调】
| // 回调到 ConsumerBase.onFrameAvailable ,再回调到 BLASTBufferQueue.onFrameAvailable
| frameAvailableListener->onFrameAvailable(item);//【转入“BufferQueueConsumer::acquireBuffer”章节】
| // 如果是 GPU 绘制,最多queueBuffer两个buffer,第二个buffer没有绘制完成,就需要等待 fence
| if (connectedApi == NATIVE_WINDOW_API_EGL)
| lastQueuedFence->waitForever("Throttling EGL Production");
| mLastQueueDuration = systemTime() - now; // 记录 queueBuffer 时间
| // 更新Surface的一些成员属性
| onBufferQueuedLocked(i, fence, output);

BufferQueueConsumer::acquireBuffer

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
c++复制代码BLASTBufferQueue::onFrameAvailable(const BufferItem& item)
| acquireNextBufferLocked(std::nullopt);
|-->BLASTBufferQueue::acquireNextBufferLocked(const std::optional<SurfaceComposerClient::Transaction*> transaction)
| // 参数 transaction = nullopt
| const bool includeExtraAcquire = !transaction;// includeExtraAcquire = true
| // 判断 mNumAcquired 是否大于等于 mMaxAcquiredBuffers + (includeExtraAcquire ? 2 : 1)
| const bool maxAcquired = maxBuffersAcquired(includeExtraAcquire);
| // Transaction 一个事务里边会填充各种需要执行的业务和业务数据,最终传递到 SurfaceFlinger,SF对事务解析的结果通常是设置Layer的各种属性
| // 每设置一种数据,都会存到ComposerState中,并添加对应的flag,SF端根据flag解析数据
| SurfaceComposerClient::Transaction localTransaction;
| bool applyTransaction = true;
| SurfaceComposerClient::Transaction* t = &localTransaction;
| BufferItem bufferItem; // 创建一个未填充数据的的栈对象 BufferItem
| //【acquireBuffer流程!!!!!!!!!!!!!!!!】
| status_t status = mBufferItemConsumer->acquireBuffer(&bufferItem, 0 /* expectedPresent */, false);
|-->BufferItemConsumer::acquireBuffer(BufferItem *item, nsecs_t presentWhen, bool waitForFence)
| acquireBufferLocked(item, presentWhen); // presentWhen = 0
|-->ConsumerBase::acquireBufferLocked(BufferItem *item, nsecs_t presentWhen, uint64_t maxFrameNumber)
| // 调用消费者的 acquireBuffer, mConsumer 为 BufferQueueConsumer
| mConsumer->acquireBuffer(item, presentWhen, maxFrameNumber);
|-->BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer, nsecs_t expectedPresent, uint64_t maxFrameNumber)
| // 参数: outBuffer 是个需要带回数据的指针; expectedPresent = 0; maxFrameNumber = 0
| // 拿到队列的迭代指针
| BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
| // 忽略一大段不执行的分支:作用就是丢弃buffer的操作、共享buffer
| int slot = front->mSlot; // 把 mQueue 队列里的第一个 BufferItem 的mSlot,赋值给 slot
| // 【把拿到的 BufferItem 通过指针参数带回】
| *outBuffer = *front;
| ATRACE_BUFFER_INDEX(slot);// trace 记录 BufferSlot 的索引值
| if (!outBuffer->mIsStale) // 如果buffer没有过时
| mSlots[slot].mAcquireCalled = true;// 设置状态为已经被acquire过了
| // 【切换状态为 acquired 状态】
| mSlots[slot].mBufferState.acquire();
| mSlots[slot].mFence = Fence::NO_FENCE; // 设置为 NO_FENCE
| if (outBuffer->mAcquireCalled) // 已经被消费过了,需要设置 GraphicBuffer 为 nullptr,避免 remapping
| outBuffer->mGraphicBuffer = nullptr;
| //【把 BufferItem 从队queued列中移除】
| mCore->mQueue.erase(front);
| mCore->mDequeueCondition.notify_all();// 唤醒等待的线程
| // atrace 记录此时的队列长度
| ATRACE_INT(mCore->mConsumerName.string(), static_cast<int32_t>(mCore->mQueue.size()));
| //返回到 ConsumerBase::acquireBufferLocked
| //BBQ生产者 BufferQueueProducer::queueBuffer 时,把 mGraphicBuffer 指针清空了,这个分支不走的
| if (item->mGraphicBuffer != nullptr)
| if (mSlots[item->mSlot].mGraphicBuffer != nullptr)
| freeBufferLocked(item->mSlot);
| mSlots[item->mSlot].mGraphicBuffer = item->mGraphicBuffer;
| // 这里的 BufferItemConsumer.mSlots 和 BufferQueueConsumer.mSlots 不是同一个对象
| mSlots[item->mSlot].mFrameNumber = item->mFrameNumber;// 帧号存到 BufferItemConsumer.mSlots 里
| mSlots[item->mSlot].mFence = item->mFence; // Fence存到 BufferItemConsumer.mSlots 里
| //返回到 BufferItemConsumer::acquireBuffer
| if (waitForFence) // waitForFence = false ,无需等待fence
| item->mFence->waitForever("BufferItemConsumer::acquireBuffer");
| // 返回的 GraphicBuffer 为 BLASTBufferItemConsumer.mSlots 的 GraphicBuffer
| item->mGraphicBuffer = mSlots[item->mSlot].mGraphicBuffer;
| //返回到BLASTBufferQueue::acquireNextBufferLocked
| auto buffer = bufferItem.mGraphicBuffer;
| mNumFrameAvailable--;
| if (buffer == nullptr) //TODO:流程上,应该是进入了此分支,现实是不可能,这里看了好几遍也没找到问题出哪里了,以后再重新分析一下吧
| mBufferItemConsumer->releaseBuffer(bufferItem, Fence::NO_FENCE);
| return;
| // 如果buffer的尺寸不匹配,直接释放buffer,请求下一个
| if (rejectBuffer(bufferItem))
| mBufferItemConsumer->releaseBuffer(bufferItem, Fence::NO_FENCE);
| acquireNextBufferLocked(transaction);
| return;
| mNumAcquired++; // Acquired数量加一,release 时减一
| mLastAcquiredFrameNumber = bufferItem.mFrameNumber;// 记录当前的帧号
| // 创建 ReleaseCallbackId ,加入到map mSubmitted,SurfaceFlinger 释放buffer,回调回来时会通过ReleaseCallbackId查找BufferItem
| ReleaseCallbackId releaseCallbackId(buffer->getId(), mLastAcquiredFrameNumber);
| mSubmitted[releaseCallbackId] = bufferItem;
| mSize = mRequestedSize;
| Rect crop = computeCrop(bufferItem);// 裁剪矩形
| //【 releaseBuffer 回调函数 !!!!!!!!!!!!!!!!】,SurfaceFlinger合成完后,就是回调的 releaseBufferCallbackThunk函数
| auto releaseBufferCallback = std::bind(releaseBufferCallbackThunk, wp<BLASTBufferQueue>(this),...);
| sp<Fence> fence = bufferItem.mFence ? new Fence(bufferItem.mFence->dup()) : Fence::NO_FENCE;//GPU绘制的fence
| //【把buffer、fence、释放buffer的回调函数 都传入事务,通过事务传递给SurfaceFlinger】
| t->setBuffer(mSurfaceControl, buffer, fence, bufferItem.mFrameNumber, releaseBufferCallback);
| // 使用 bufferItem中的数据,填充事务的其他各种数据...
| t->setDataspace(mSurfaceControl, static_cast<ui::Dataspace>(bufferItem.mDataSpace));
| t->setHdrMetadata(mSurfaceControl, bufferItem.mHdrMetadata);
| t->setBufferCrop(mSurfaceControl, crop);
| t->setAutoRefresh(mSurfaceControl, bufferItem.mAutoRefresh);
| t->setSurfaceDamageRegion(mSurfaceControl, bufferItem.mSurfaceDamage);
| //....
| // 最后调用apply,把事务传递到SurfaceFlinger
| t->setApplyToken(mApplyToken).apply(false, true);
| SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay)
| sp<ISurfaceComposer> sf(ComposerService::getComposerService());
| sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,...)

九、SurfaceFlinger 合成— Android 13 (Android T)

相对于Android 12,Android13在架构上做了微调

  • SurfaceFlinger::onMessageInvalidate 对应于 SurfaceFlinger::commit,但是结构上做了大量的调整

    一些函数像 handleMessageTransaction、handleTransaction、handleMessageInvalidate、handlePageFlip 这些都不见了

  • SurfaceFlinger::onMessageRefresh 对应于 SurfaceFlinger::composite

然后Android13 还做了GPU合成的优化

  • 对GPU合成进行预测,如果有GPU合成,那么 chooseCompositionStrategy 和 GPU合成 并行执行。用以节约时间。

SurfaceComposerClient::Transaction::apply–>SurfaceFlinger::setTransactionState

  • 事务入队。加入到队列 SurfaceFlinger.mTransactionQueue
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
c++复制代码//	frameworks/native/libs/gui/SurfaceComposerClient.cpp
SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay)
| // applyToken 来源于 BLASTBufferQueue.h
| // const sp<IBinder> mApplyToken GUARDED_BY(mMutex) = new BBinder();
| sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,
mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp,
{} /*uncacheBuffer - only set in doUncacheBufferTransaction*/,
hasListenerCallbacks, listenerCallbacks, mId);
//进入 SurfaceFlinger 进程
// frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
SurfaceFlinger::setTransactionState(const FrameTimelineInfo& frameTimelineInfo, const Vector<ComposerState>& states,
const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime,
bool isAutoTimestamp, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId)
| //...
| const int64_t postTime = systemTime();
| IPCThreadState* ipc = IPCThreadState::self();
| const int originPid = ipc->getCallingPid();
| const int originUid = ipc->getCallingUid();
| // 主要逻辑就是把这个 TransactionState 对象入队。然后请求 SF-vsync
| TransactionState state{frameTimelineInfo, states, displays, flags, applyToken, inputWindowCommands,
desiredPresentTime, isAutoTimestamp, uncacheBuffer, postTime, permissions,
hasListenerCallbacks,listenerCallbacks, originPid, originUid, transactionId};
| //...
| queueTransaction(state);
|-->SurfaceFlinger::queueTransaction(TransactionState& state)
| state.queueTime = systemTime();
| // std::deque<TransactionState> mTransactionQueue; 双端队列
| //【把 TransactionState 入队】
| // 在 SurfaceFlinger::flushTransactions() 函数中会出队
| mTransactionQueue.emplace_back(state);
| ATRACE_INT("TransactionQueue", mTransactionQueue.size());
| const auto schedule = ...;
| const auto frameHint = state.isFrameActive() ? FrameHint::kActive : FrameHint::kNone;
| // 传入的事务flag是枚举类型 eTransactionFlushNeeded = 0x10;
| setTransactionFlags(eTransactionFlushNeeded, schedule, state.applyToken, frameHint);
|-->SurfaceFlinger::setTransactionFlags(uint32_t mask, TransactionSchedule schedule, IBinder& applyToken, FrameHint frameHint)
| // 调整vsync一些时间配置
| modulateVsync(&VsyncModulator::setTransactionSchedule, schedule, applyToken);
/*
1、mTransactionFlags 添加 eTransactionFlushNeeded 标记
2、mTransactionFlags原值 同 mask 相与, 表示原先有没有这个标记。并把结果存储 scheduled
3、!scheduled 取非,表示如果原先没有这个标记,就进入此分支,执行 scheduleCommit
*/
| if (const bool scheduled = mTransactionFlags.fetch_or(mask) & mask; !scheduled)
| scheduleCommit(frameHint);
|-->SurfaceFlinger::scheduleCommit(FrameHint hint)
| if (hint == FrameHint::kActive)
| mScheduler->resetIdleTimer();
| mPowerAdvisor->notifyDisplayUpdateImminent();
| // 这个函数的调用链很长,知道这个代码是请求 SurfaceFlinger 的 vsync 就行了
| mScheduler->scheduleFrame();

MessageQueue::scheduleFrame() — 请求vsync

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
c++复制代码MessageQueue::scheduleFrame()
| mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(),
.readyDuration = 0,
.earliestVsync = mVsync.lastCallbackTime.count()});
|-->VSyncCallbackRegistration::schedule(VSyncDispatch::ScheduleTiming scheduleTiming)
| if (!mValidToken) return std::nullopt;
| // mDispatch 是 VSyncDispatchTimerQueue
| return mDispatch.get().schedule(mToken, scheduleTiming);
| VSyncDispatchTimerQueue::schedule(CallbackToken token, ScheduleTiming scheduleTiming)
| ScheduleResult result;
| // VSyncCallbackRegistration 构造的时候,调用registerCallback生成了一个 token ,这个token存储到了 map 对象 mCallbacks
| // 现在拿出来
| auto it = mCallbacks.find(token);
| auto& callback = it->second; // map 迭代器 second 中存储 VSyncDispatchTimerQueueEntry
| // VSyncDispatchTimerQueueEntry 中存储真正的回调函数 MessageQueue::vsyncCallback
| result = callback->schedule(scheduleTiming, mTracker, now);
| // 这里步骤还很多。大概是更新vsync的时间配置啥的
|-->VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTiming timing, VSyncTracker& tracker, nsecs_t now)
| //省略VSyncDispatchTimerQueueEntry函数内XXXX,太长了。抽空再研究
| //.........
| if (callback->wakeupTime() < mIntendedWakeupTime - mTimerSlack)
| // 启动vsync的定时器
| rearmTimerSkippingUpdateFor(now, it);
| return result;

sf-vsync事件分发流程

  • Android 13 把用了好多年的 onMessageInvalidate()、onMessageRefresh 体系给改了
  • 变成了 SurfaceFlinger::commit 和 SurfaceFlinger::composite ,中间不post消息了,直接无缝切换
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
c++复制代码//	frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
MessageQueue::vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime)
| mHandler->dispatchFrame(vsyncId, vsyncTime);
|-->MessageQueue::Handler::dispatchFrame(int64_t vsyncId, nsecs_t expectedVsyncTime)
| mQueue.mLooper->sendMessage(this, Message())

void MessageQueue::Handler::handleMessage(const Message&) {
mFramePending.store(false);

const nsecs_t frameTime = systemTime();
// mQueue 类型android::impl::MessageQueue
// android::impl::MessageQueue.mCompositor 类型 ICompositor
// SurfaceFlinger 继承 ICompositor
// mQueue.mCompositor 其实就是 SurfaceFlinger
auto& compositor = mQueue.mCompositor;

// 【流程1,返回false的话,直接返回,不会执行后面的合成流程composite】
if (!compositor.commit(frameTime, mVsyncId, mExpectedVsyncTime)) {
return;
}
// 【流程2,合成】
compositor.composite(frameTime, mVsyncId);

// 通过RegionSamplingThread对合成帧进行采样
compositor.sample();
}

SurfaceFlinger::commit 流程

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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
c++复制代码//	frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
SurfaceFlinger::commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expectedVsyncTime)
| // 返回 SurfaceFlinger.mTransactionFlags 是否携带 eTransactionFlushNeeded 标记。同时清除这个标记
| // eTransactionFlushNeeded 是由 queueTransaction 流程中设置的
| if (clearTransactionFlags(eTransactionFlushNeeded))
| //【1】、flushTransactions(),核心是获取所有的TransactionState,之后将作为 applyTransactions流程 的参数】
| // 把 Transaction::apply 流程中,加入 mTransactionQueue 队列的 TransactionState 出队
| std::vector<TransactionState> transactions = flushTransactions();
| // 这个函数核心就是把 mTransactionQueue 队列的数据转移到一个 vector 中返回
// 中间处理一些还没有处理完的事务。具体代码待研究
|-->SurfaceFlinger::flushTransactions()
| std::vector<TransactionState> transactions;
| while (!mTransactionQueue.empty())// 【取出setTransactionState流程中入队的所有事务】
| auto& transaction = mTransactionQueue.front();
| // 省略 X 行代码
| transactions.emplace_back(std::move(transaction));// 把事务转入向量集合 vector<TransactionState> transactions
| mTransactionQueue.pop_front();
| ATRACE_INT("TransactionQueue", mTransactionQueue.size());
| return transactions;
| // 【2】、处理以前创建的layer,核心就是把新创建的layer加入到Z轴排序集合体系 mCurrentState.layersSortedByZ 】
| // Android12以前layersSortedByZ不是在这里添加的。或许谷歌以后想仅仅通过事务的接口创建layer??
| needsTraversal |= commitCreatedLayers();
|-->SurfaceFlinger::commitCreatedLayers()
| std::vector<LayerCreatedState> createdLayers;
/* mCreatedLayers: 创建layer流程中,通过 SurfaceFlinger::addClientLayer 把layer添加到了 mCreatedLayers 这个vector中
现在开始拿来使用了 */
| createdLayers = std::move(mCreatedLayers); //数据转移到新的对象createdLayers中
| mCreatedLayers.clear();//清除mCreatedLayers所有的数据
| if (createdLayers.size() == 0)
| return false; // 如果没有新增的Layer,直接返回,那么 mLayersAdded 就不会被设置为 true
| for (const auto& createdLayer : createdLayers)
| handleLayerCreatedLocked(createdLayer);
|-->SurfaceFlinger::handleLayerCreatedLocked(const LayerCreatedState& state)
| sp<Layer> layer = state.layer.promote();
| bool addToRoot = state.addToRoot;
| sp<Layer> parent = state.initialParent.promote();
| // 如果没有父layer的话,执行以下代码。
| if (parent == nullptr && addToRoot)
| layer->setIsAtRoot(true);
| //【添加到 mCurrentState.layersSortedByZ 这个以Z轴排序的集合中】
| mCurrentState.layersSortedByZ.add(layer);
| else if (parent == nullptr)
| layer->onRemovedFromCurrentState();// Layer删除处理
| else if (parent->isRemovedFromCurrentState())
| parent->addChild(layer);
| layer->onRemovedFromCurrentState();// Layer删除处理
| else// TODO: 待验证 parent 为 ContainerLayer, addToRoot=true
| parent->addChild(layer);// BufferStateLayer 应该走这里。添加到 Layer.mCurrentChildren 集合中
| layer->updateTransformHint(mActiveDisplayTransformHint);
| mInterceptor->saveSurfaceCreation(layer);
| // 在之后的流程 commitTransactionsLocked 函数中会设置回 false
| mLayersAdded = true;
| return true;//如果有新创建的layer,需要执行合成步骤 SurfaceFlinger.composite 函数
| needsTraversal |= applyTransactions(transactions, vsyncId);
| // 因图形buffer更新放到事务中来了,所以事务这里重点关注 eBufferChanged
| //【3】、applyTransactions流程: 把事务中的对于flag的数据存入Layer.mDrawingState对应的属性
| // 对于Layer删除、调整Z轴,则是把相关数据存入 SurfaceFlinger.mCurrentState.layersSortedByZ
| // 对于图形buffer更新而言,核心就是赋值 mDrawingState.buffer
|-->SurfaceFlinger::applyTransactions(std::vector<TransactionState>& transactions,int64_t vsyncId)
| return applyTransactionsLocked(transactions, vsyncId);
|-->SurfaceFlinger::applyTransactionsLocked(std::vector<TransactionState>& transactions, int64_t vsyncId)
| bool needsTraversal = false;
| // 【遍历步骤1中flushTransactions()返回的 transactions】
| for (auto& transaction : transactions)
| needsTraversal |= applyTransactionState(...)
|-->SurfaceFlinger::applyTransactionState(..)
| uint32_t transactionFlags = 0;
| uint32_t clientStateFlags = 0;
| // 省略一大堆内容
| clientStateFlags = setClientStateLocked(frameTimelineInfo, state, desiredPresentTime,isAutoTimestamp, postTime, permissions);
|-->SurfaceFlinger::setClientStateLocked(const FrameTimelineInfo& frameTimelineInfo,ComposerState& composerState,...)
| //省略一大堆内容
| layer_state_t& s = composerState.state;
| // BLASTBufferQueue 传递buffer到SF的时候,调用Transaction::setBuffer 添加 eBufferChanged 标记
| if (what & layer_state_t::eBufferChanged)
| layer->setBuffer(buffer, *s.bufferData, postTime, desiredPresentTime,
isAutoTimestamp, dequeueBufferTimestamp, frameTimelineInfo)
| // 只有 BufferStateLayer 覆写了setBuffer,其他layer使用父类Layer.setBuffer,父类的函数直接返回false
|-->BufferStateLayer::setBuffer(std::shared_ptr<renderengine::ExternalTexture>& buffer,const BufferData& bufferData,...)
| // 省略一大堆
| // 这里的 mDrawingState 是 Layer 的,和SurfaceFlinger的 mDrawingState 不是一个类
| // 以前 Layer也有一个 mCurrentState 对象,现在没有了
| mDrawingState.frameNumber = frameNumber;
| mDrawingState.releaseBufferListener = bufferData.releaseBufferListener;
| mDrawingState.buffer = std::move(buffer);//【把buffer给到 mDrawingState.buffer】
| mDrawingState.acquireFence = ... bufferData.acquireFence;
| mDrawingState.modified = true; // 表示是否有状态被修改,几乎所有Layer事务都会设置这个变量为true
| mFlinger->mTimeStats->setPostTime(layerId, mDrawingState.frameNumber, getName().c_str(),mOwnerUid, postTime,...);
| mDrawingState.isAutoTimestamp = isAutoTimestamp;
| mDrawingState.releaseBufferEndpoint = bufferData.releaseBufferEndpoint;
| // 每次vsync事件都会伴随生成一个 vsyncId。TODO:通常情况可能没有 frameTimelineInfo,,没找到赋值过程,待研究
| else if (frameTimelineInfo.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID)
| layer->setFrameTimelineVsyncForBufferlessTransaction(frameTimelineInfo, postTime);
| transactionFlags |= clientStateFlags;// 添加 setClientStateLocked 返回的flag
| bool needsTraversal = false;
| if (transactionFlags & eTraversalNeeded)
| transactionFlags = transactionFlags & (~eTraversalNeeded);
| needsTraversal = true;
| if (transactionFlags) setTransactionFlags(transactionFlags); //如果还有eTraversalNeeded以外的flag,请求vsync
| return needsTraversal;
| if (mTransactionTracing)
| mTransactionTracing->addCommittedTransactions(transactions, vsyncId);
| return needsTraversal;//返回最终的 needsTraversal,这个为true的话,会执行 commitTransactions、composite
| // 是否需要执行事务提交。【提交的核心就是把 mCurrentState 赋值给 mDrawingState】
| // mCurrentState 保存APP传来的数据,mDrawingState 用于合成
| const bool shouldCommit = (getTransactionFlags() & ~eTransactionFlushNeeded) || needsTraversal;
| //【4】、commitTransactions()流程:核心是把mCurrentState转移到 mDrawingState
| if(shouldCommit)
| commitTransactions();
|-->SurfaceFlinger:::commitTransactions()
| State drawingState(mDrawingState);
| mDebugInTransaction = systemTime();
| modulateVsync(&VsyncModulator::onTransactionCommit);
| commitTransactionsLocked(clearTransactionFlags(eTransactionMask));
|-->SurfaceFlinger::commitTransactionsLocked(uint32_t transactionFlags);
| // 屏幕的热插拔SurfaceFlinger::onComposerHalHotplug会调用 setTransactionFlags(eDisplayTransactionNeeded),然后到这里处理
| // TODO:主线程中接收到的热插拔,不会走到这里。这里处理的可能是非主屏的热插拔,待验证。
| const bool displayTransactionNeeded = transactionFlags & eDisplayTransactionNeeded;
| // 处理显示器的事务,显示屏幕增删,显示器的尺寸变化
| if (displayTransactionNeeded)
| processDisplayChangesLocked();
| processDisplayHotplugEventsLocked();
| mCurrentState.traverse(...)
| layer->updateTransformHint(hintDisplay->getTransformHint());//更新旋转提示
| if (mLayersAdded) // 在此之前的步骤[2] commitCreatedLayers 中设置的 true
| mLayersAdded = false;
| mVisibleRegionsDirty = true;//有脏区域,【用于步骤6计算脏区域】
| if (mLayersRemoved)// 处理被移除的Layer
| mLayersRemoved = false;
| mVisibleRegionsDirty = true;
| mDrawingState.traverseInZOrder(...)
| Region visibleReg;
| visibleReg.set(layer->getScreenBounds());
| invalidateLayerStack(layer, visibleReg);//更新DisplayDevice中原有的可视脏区
| //把Layer的添加以及删除从Current状态转为Drawing状态
| doCommitTransactions();
|-->SurfaceFlinger::doCommitTransactions()
| // 处理以及被移除的layer集合 mLayersPendingRemoval。释放buffer,从layersSortedByZ移除,加入到mOffscreenLayers
| for (const auto& l : mLayersPendingRemoval)
| l->latchAndReleaseBuffer();
| mCurrentState.layersSortedByZ.remove(l);
| mOffscreenLayers.emplace(l.get());
| mLayersPendingRemoval.clear();
| //【核心步骤】
| mDrawingState = mCurrentState;
| mCurrentState.colorMatrixChanged = false;
| if (mVisibleRegionsDirty)
| for (const auto& rootLayer : mDrawingState.layersSortedByZ)
| // 遍历所有的根layer,把所有子Layer的mCurrentChildren赋值给mDrawingChildren
| rootLayer->commitChildList();
| mDrawingChildren = mCurrentChildren;
| mDrawingParent = mCurrentParent;
| mDebugInTransaction = 0;
| // 如果还有待处理的事务,请求下一个SF vsync
| if (transactionFlushNeeded())
| setTransactionFlags(eTransactionFlushNeeded);
| mustComposite |= shouldCommit;
| //【5】、latchBuffers 相当于以前的handlePageFlip 流程
| //【如果有新的buffer的layer大于0,并且拿到了buffer,SurfaceFlinger::latchBuffers()函数返回true,执行 SurfaceFlinger::composite 】
| mustComposite |= latchBuffers();
|-->SurfaceFlinger::latchBuffers() //【详细内容,见 latchBuffers() 章节】
| layer->latchBuffer(visibleRegions, latchTime, expectedPresentTime)
| //父类Layer的 latchBuffer 返回 false, 子类只有 BufferLayer 重载了 latchBuffer
|-->BufferLayer.latchBuffer(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/, nsecs_t /*expectedPresentTime*/)
| updateTexImage(recomputeVisibleRegions, latchTime, expectedPresentTime);
|-->BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime,nsecs_t /*expectedPresentTime*/)
| //【6】、计算边界、脏区域
| updateLayerGeometry();
|-->SurfaceFlinger::updateLayerGeometry()
| if (mVisibleRegionsDirty) //【mVisibleRegionsDirty在有新的Layer增加时设置为 true 】
| /* 调用每个Layer的 computeBounds 方法
计算每个Layer的以下边界:
mSourceBounds 应用任何变换之前以及由其父对象裁剪之前的Layer边界。
mBounds Layer空间中的Layer边界。mSourceBounds 和 Layer的裁剪矩形的交集,再和其父空间交集
mScreenBounds Layer在屏幕上的空间。由 mBounds transform转换而来 */
| computeLayerBounds();
|-->SurfaceFlinger::computeLayerBounds()
| const FloatRect maxBounds = getMaxDisplayBounds();
| for (const auto& layer : mDrawingState.layersSortedByZ)
| layer->computeBounds(maxBounds, ui::Transform(), 0.f /* shadowRadius */);
| // mLayersPendingRefresh 参见步骤[5] latchBuffers()
| for (auto& layer : mLayersPendingRefresh)// mLayersPendingRefresh 存储中能拿到 buffer的layer
| Region visibleReg;
| visibleReg.set(layer->getScreenBounds());
| // 对每个包含当前layer的显示器的脏区域初始化为 Layer.mScreenBounds
| invalidateLayerStack(layer, visibleReg);
| // mLayersPendingRefresh这个集合表示有新的buffer更新,并且能拿到buffer的layer。
| // 在 SurfaceFlinger::latchBuffers()流程中添加,此时清空此集合
| mLayersPendingRefresh.clear();
| // 非开机阶段,mustComposite==true情况下将执行合成步骤 SurfaceFlinger::composite
| return mustComposite && CC_LIKELY(mBootStage != BootStage::BOOTLOADER);
latchBuffers()
  • 因为使用 BufferStateLayer + BBQ , latchBuffer 流程相比Android12以前逻辑要少很多
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
96
c++复制代码// SurfaceFlinger.mLayersWithQueuedFrames 存储有新buffer的layer
// SurfaceFlinger.mLayersPendingRefresh 存储mLayersWithQueuedFrames中能拿到 buffer的layer。用于更新显示设备的脏区域
|-->SurfaceFlinger::latchBuffers()
| const nsecs_t latchTime = systemTime();// perfetto 会记录这个时间
| bool visibleRegions = false;// 用于 latchBuffer 的参数
| bool newDataLatched = false;
| // 【1、核心逻辑是把 有buffer更新的layer存储到set集合 mLayersWithQueuedFrames】
| mDrawingState.traverse(...)
| // layer 各种属性变化后都会设置 eTransactionNeeded 这个flag,比如尺寸,背景,位置,inputInfo、刷新率等等,几乎所有的变化都会设置eTransactionNeeded。
| if (layer->clearTransactionFlags(eTransactionNeeded) || mForceTransactionDisplayChange)
| // 赋值 mDrawingState.transform
| // mDrawingStateModified = mDrawingState.modified; mDrawingState.modified = false;
| const uint32_t flags = layer->doTransaction(0);
| if (flags & Layer::eVisibleRegion)
| mVisibleRegionsDirty = true;
| // layer有新buffer时,hasReadyFrame() 返回true
| if (layer->hasReadyFrame())
| // shouldPresentNow函数,对于 BufferStateLayer 而言,有buffer的来了,就返回true
| if (layer->shouldPresentNow(expectedPresentTime))
| //【2、把有新buffer的layer,加入set集合 mLayersWithQueuedFrames】
| mLayersWithQueuedFrames.emplace(layer);
| mForceTransactionDisplayChange = false;
| // 【3、mLayersWithQueuedFrames不为空,则调用集合中每个layer的 latchBuffer 函数】
| if (!mLayersWithQueuedFrames.empty())
| for (const auto& layer : mLayersWithQueuedFrames)
| // latchBuffer 判断是否需要重新计算显示区域,由参数visibleRegions带回结果
| //【4、获取buffer,并把 Layer.mDrawingState 中的属性变量转移到 BufferLayer.mBufferInfo 】
| // mBufferInfo 用于 Layer中获取各种buffer信息相关的get方法
| if (layer->latchBuffer(visibleRegions, latchTime, expectedPresentTime))
|-->BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime, nsecs_t expectedPresentTime)
| if (!fenceHasSignaled())
| // 【如果Fence还没有发送信号,请求 SF-vsync,并且函数返回,等一下次的vsync再处理这个buffer】
| mFlinger->onLayerUpdate();
| return false;
| BufferInfo oldBufferInfo = mBufferInfo;
| updateTexImage(recomputeVisibleRegions, latchTime, expectedPresentTime);
| // BufferStateLayer 和 以前使用的 BufferQueueLayer 是完全不同的步骤。大部分内容是debug用的
|-->BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime, nsecs_t /*expectedPresentTime*/)
| const int32_t layerId = getSequence();// sequence,每个layer唯一,是个递增int
| //把 acquireFence 存储到 mFlinger->mTimeStats->mTimeStatsTracker[layerId].timeRecords[layerRecord.waitData].acquireFence
| mFlinger->mTimeStats->setAcquireFence(layerId, frameNumber, acquireFence);
| mFlinger->mTimeStats->setLatchTime(layerId, frameNumber, latchTime);
| // perfetto 相应的数据源配置启用的情况下,记录 Fence 和 latchTime
| mFlinger->mFrameTracer->traceFence(...);
| mFlinger->mFrameTracer->traceTimestamp(...);
| mDrawingStateModified = false;// 修改为false,对应于步骤1中 Layer.doTransaction
| updateActiveBuffer();
|-->BufferStateLayer::updateActiveBuffer()
| const State& s(getDrawingState());
| //mPendingBufferTransactions--
| // 调用到 latchBuffer 阶段,setBuffer 的事务就算处理完了,待处理的buffer数量计数器 mPendingBufferTransactions要减一
| //这里对应于SurfaceFlinger::setTransactionState函数中:mBufferCountTracker.increment(state.surface->localBinder());
| // mBufferCountTracker.increment 函数使 mPendingBufferTransactions 自增1
| decrementPendingBufferCount();
| // 把 mDrawingState 中的buffer、acquireFence、frameNumber 转移到 mBufferInfo
| mBufferInfo.mBuffer = s.buffer;
| mBufferInfo.mFence = s.acquireFence;
| mBufferInfo.mFrameNumber = s.frameNumber;
| // mCurrentFrameNumber = mDrawingState.frameNumber; mPreviousFrameNumber = mCurrentFrameNumber;
| updateFrameNumber();
|-->BufferStateLayer::updateFrameNumber()
| mPreviousFrameNumber = mCurrentFrameNumber;
| mCurrentFrameNumber = mDrawingState.frameNumber; return NO_ERROR;
| // 这个函数就是把 mDrawingState 中buffer相关信息的各种变量转移到 mBufferInfo 中
| // mBufferInfo.mDesiredPresentTime、mFenceTime、mFence、mTransform、mDataspace、mCrop、mScaleMode、mSurfaceDamage
| // mHdrMetadata、mApi、mTransformToDisplayInverse、mBufferSlot等等赋值
| gatherBufferInfo();
|-->BufferStateLayer::gatherBufferInfo()
| BufferLayer::gatherBufferInfo();
| const State& s(getDrawingState());
| mBufferInfo.mFence = s.acquireFence;
| mBufferInfo.mCrop = computeBufferCrop(s);
| mBufferInfo.mScaleMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
| mBufferInfo.mBufferSlot = mHwcSlotGenerator->getHwcCacheSlot(s.clientCacheId);
| //....
| // 后边的代码是判断 是否需要重新计算显示区域
| // 大致情况是:当前是第一个buffer、裁剪区域变化了,旋转变了,缩放变了,宽高变了,透明度变了,mTransformToDisplayInverse变了
| // 以上情况都需要重新计算显示区域
| if(oldBufferInfo.mBuffer == nullptr || mBufferInfo.mCrop != oldBufferInfo.mCrop ....)
| | recomputeVisibleRegions = true;
| return true;
| //【5、如果 latchBuffer 返回true,把layer加入向量集合 mLayersPendingRefresh 】
| // 依据 latchBuffer 逻辑,latchBuffer 返回false,通常是由于 Fence 还没有发送信号。当然还有其他细节原因,这里未贴出代码。
| //【可以说,mLayersPendingRefresh 保存了GPU绘制已经完成的layer】
| mLayersPendingRefresh.push_back(layer);
| newDataLatched = true;
| // Layer.surfaceDamageRegion = mBufferInfo.mSurfaceDamage;
| layer->useSurfaceDamage();
| //回到 SurfaceFlinger::latchBuffers() 函数
| // latchBuffer 函数,由参数 visibleRegions 返回 是否需要重新计算显示区域
| // 这里把结果添加到 mVisibleRegionsDirty 变量中
| mVisibleRegionsDirty |= visibleRegions;
| // 如果有新的buffer的layer大于0,并且 拿到了buffer,
| // 那么SurfaceFlinger::latchBuffers()函数返回true,表示需要执行合成步骤 SurfaceFlinger::composite
| //【6、如果有新的buffer的layer数量大于0,并且 拿到了buffer,SurfaceFlinger::latchBuffers()函数返回true,执行 SurfaceFlinger::composite 】
| return !mLayersWithQueuedFrames.empty() && newDataLatched;

SurfaceFlinger::composite

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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
c++复制代码SurfaceFlinger::composite(nsecs_t frameTime, int64_t vsyncId)
| // 【1】准备合成的参数
| compositionengine::CompositionRefreshArgs refreshArgs;
| /*
SmallMap<IBinder, DisplayDevice> mDisplays;
合成是以 mDisplays 元素中的顺序去合成的
内置的显示器,是在开机的时候加入的,因此按照顺序合成的话,内置显示器要优先于 外部显示器 和 虚拟显示器
*/
| const auto& displays = FTL_FAKE_GUARD(mStateLock, mDisplays);
| // outputs 为Output的vector
| refreshArgs.outputs.reserve(displays.size());// 增加容器的大小为显示屏的大小
| // 遍历显示设备
| for (const auto& [_, display] : displays)
| // DisplayDevice.mCompositionDisplay 类型 android::compositionengine::Display,继承 Output
| // outputs 代表所有需要合成的显示器
| refreshArgs.outputs.push_back(display->getCompositionDisplay());//【所有需要合成工作的显示设备】
| // 遍历 mDrawingState.layersSortedByZ,这个 layersSortedByZ 存储了所有的的layer
| // 以Z轴顺序遍历 mDrawingState.layersSortedByZ ,从底层开始遍历
| mDrawingState.traverseInZOrder(...)
| // 并非所有种类的layer都能通过 Layer.getCompositionEngineLayerFE() 拿到LayerFE对象。是有显示界面的才有返回对象
| // 父类 Layer.getCompositionEngineLayerFE() 返回 nullptr
| // 只有 BufferLayer 和 EffectLayer 实现了这个方法
| // getCompositionEngineLayerFE 这个函数就是返回layer自身,并强转为Layer父类 compositionengine::LayerFE 类型
| if (auto layerFE = layer->getCompositionEngineLayerFE())
| // refreshArgs.layers 是 std::vector<sp<compositionengine::LayerFE>> 类型
| // 这个是以 Z 轴顺序添加到 layers 中的
| refreshArgs.layers.push_back(layerFE);//【添加所有参与合成的layer】
| // mLayersWithQueuedFrames 是有新的帧数据的Layer
| // 把有帧数据的Layer转移到 refreshArgs.layersWithQueuedFrames
| refreshArgs.layersWithQueuedFrames.reserve(mLayersWithQueuedFrames.size());
| mCompositionEngine->present(refreshArgs);
| for (auto layer : mLayersWithQueuedFrames)
| if (auto layerFE = layer->getCompositionEngineLayerFE())
| refreshArgs.layersWithQueuedFrames.push_back(layerFE);
| // 把准备好的合成的参数,传入 CompositionEngine 开始合成工作
| mCompositionEngine->present(refreshArgs);
|-->CompositionEngine::present(CompositionRefreshArgs& args)
| // 【2】如果存在新的buffer处理,mNeedsAnotherUpdate设置为true,
| preComposition(args);
| // LayerFESet 是 unordered_set 类型
| LayerFESet latchedLayers; // using LayerFESet = std::unordered_set<sp<LayerFE>, LayerFESpHash>;
| // 【3】遍历所有需要合成输出的显示设备 【核心是把显示区域相关数据转存到 OutputLayer 的mState对象】
| for (const auto& output : args.outputs)// 第一层循环,遍历所有的显示设备
| // 调用每个显示设备的 prepare 方法
| output->prepare(args, latchedLayers);
|-->Output::prepare(const compositionengine::CompositionRefreshArgs& refreshArgs, LayerFESet& geomSnapshots)
| rebuildLayerStacks(refreshArgs, geomSnapshots);
|-->Output::rebuildLayerStacks(const compositionengine::CompositionRefreshArgs& refreshArgs, LayerFESet& layerFESet)
| auto& outputState = editState();// editState() 返回 OutputCompositionState 类型的 Output.mState;
| compositionengine::Output::CoverageState coverage{layerFESet};
| // 1、从顶层到底层遍历所有参与合成的Layer,累积计算 覆盖区域、完全不透明区域、脏区域
| // 2、存储当前层的显示区域、排除透明区域的显示区域、被覆盖区域、显示器空间显示区域、阴影区域等到 当前显示设备上的OutputLayer的mState对象
| collectVisibleLayers(refreshArgs, coverage);
|-->Output::collectVisibleLayers(CompositionRefreshArgs& refreshArgs,Output::CoverageState& coverage)
| // 从顶层到底层开始遍历所有Layer,以便于计算哪些可以显示。 这个过程中,每层的显示区域是不断减少的,相反,覆盖区域是不断增大的
| for (auto layer : reversed(refreshArgs.layers))
| // 1、从顶层到底层遍历所有参与合成的Layer,累积计算 覆盖区域、完全不透明区域、脏区域
| // 2、【如果显示设备没有对应的 OutputLayer,创建 OutputLayer 同时创建 HWCLayer,并作为 OutputLayer.mState 的成员】
| // 3、存储当前层的显示区域、排除透明区域的显示区域、被覆盖区域、显示器空间显示区域、阴影区域等到 当前显示设备上的 OutputLayer 的mState对象
| //OutputLayer.mState.visibleRegion、visibleNonTransparentRegion、coveredRegion、outputSpaceVisibleRegion、shadowRegion
| //outputSpaceBlockingRegionHint
| // 4、Output.mPendingOutputLayersOrderedByZ.emplace_back(std::move(outputLayer));
| ensureOutputLayerIfVisible(layer, coverage);
| // setReleasedLayers 函数会遍历 Output.mCurrentOutputLayersOrderedByZ
| // 此时 Output.mCurrentOutputLayersOrderedByZ 中会在当前vsync显示的layer都转移到了mPendingOutputLayersOrderedByZ
| // 这里会把mCurrentOutputLayersOrderedByZ余下的Layer中,在当前vsync,入队新的buffer的layer放入到 Output.mReleasedLayers 中
| // 就是说,mReleasedLayers是一些即将移除的的layer,但是当前vsync还在生产帧数据的layer
| setReleasedLayers(refreshArgs);
| // 把 Output.mPendingOutputLayersOrderedByZ 转到 Output.mCurrentOutputLayersOrderedByZ //使用的move赋值
| // 【每个vsync内,Output中存储的OutputLayer,都是最新即将要显示的Layer】
| finalizePendingOutputLayers();
| const ui::Transform& tr = outputState.transform;
| Region undefinedRegion{outputState.displaySpace.getBoundsAsRect()};
| // 整个显示空间 减去 所有Layer的不透明覆盖区域 为未定义的区域
| undefinedRegion.subtractSelf(tr.transform(coverage.aboveOpaqueLayers));
| outputState.undefinedRegion = undefinedRegion;
| // 把计算好的脏区域传入 outputState.dirtyRegion // Output::postFramebuffer() 中被清空
| outputState.dirtyRegion.orSelf(coverage.dirtyRegion);
| // 【4】把状态属性转移到 BufferLayer.mCompositionState。这个对象是 compositionengine::LayerFECompositionState 类型
| // 可以通过 LayerFE.getCompositionState() 获取合成状态对象。不算EffectLayer的话,其实就是就是获取 BufferLayer.mCompositionState
| updateLayerStateFromFE(args);
|-->CompositionEngine::updateLayerStateFromFE(CompositionRefreshArgs& args)
| // 从前端layer中更新合成状态
| for (const auto& output : args.outputs)
| output->updateLayerStateFromFE(args);
|-->Output::updateLayerStateFromFE(const CompositionRefreshArgs& args)
| // SurfaceFlinger.mVisibleRegionsDirty 为true时, args.updatingGeometryThisFrame=true
| // 有新的Layer增加时 mVisibleRegionsDirty 为true
| layer->getLayerFE().prepareCompositionState(args.updatingGeometryThisFrame ? LayerFE::StateSubset::GeometryAndContent
: LayerFE::StateSubset::Content);
|-->Layer::prepareCompositionState(compositionengine::LayerFE::StateSubset subset)
| // 根据 StateSubset 的类型选择以下函数的几种组合去执行
| /* prepareBasicGeometry更新BufferLayer状态对象LayerFECompositionState(mCompositionState)的以下属性:
outputFilter、isVisible、isOpaque、shadowRadius、contentDirty、geomLayerBounds、geomLayerTransform、
geomInverseLayerTransform、transparentRegionHint、blendMode、alpha、backgroundBlurRadius、blurRegions、stretchEffect
同时设置 Layer.contentDirty = false;*/
| prepareBasicGeometryCompositionState();
/*更新BufferLayer状态对象mCompositionState的以下属性:
geomBufferSize、geomContentCrop、geomCrop、geomBufferTransform、
geomBufferUsesDisplayInverseTransform|geomUsesSourceCrop、isSecure、metadata
就是集合图形相关的属性*/
| prepareGeometryCompositionState();
/* preparePerFrameCompositionState更新BufferLayer状态对象mCompositionState的以下属性:
compositionType、hdrMetadata、compositionType、buffer、bufferSlot、acquireFence、frameNumber、sidebandStreamHasFrame
forceClientComposition、isColorspaceAgnostic、dataspace、colorTransform、colorTransformIsIdentity、surfaceDamage
hasProtectedContent、dimmingEnabled、isOpaque、stretchEffect、blurRegions、backgroundBlurRadius、fps
就是帧数据相关的属性*/
| preparePerFrameCompositionState();
|
| // 调用每个显示设备的 present 方法
| for (const auto& output : args.outputs)
| output->present(args);
|-->Output::present(const compositionengine::CompositionRefreshArgs& refreshArgs)
| // 2.4.1 更新Output合成状态对象OutputCompositionState
| // Output.mState的 colorMode、dataspace、renderIntent、targetDataspace 属性
| updateColorProfile(refreshArgs);
| // 2.4.2 更新 OutputLayer.mState.forceClientComposition、displayFrame、sourceCrop、bufferTransform、dataspace
| // 【显示区域相关属性已经在rebuildLayerStacks阶段更新完成,至此OutputLayer.mState的属性基本全更新完了】
| updateCompositionState(refreshArgs);
|-->Output::updateCompositionState(const compositionengine::CompositionRefreshArgs& refreshArgs)
| // 查找最顶层使用背景模糊的 OutputLayer
| mLayerRequestingBackgroundBlur = findLayerRequestingBackgroundComposition();
| // 如果有 OutputLayer 使用了背景模糊,则必须使用 GPU 合成
| bool forceClientComposition = mLayerRequestingBackgroundBlur != nullptr;
| for (auto* layer : getOutputLayersOrderedByZ())
| /* 更新每个OutputLayer OutputLayerState 的以下属性
| forceClientComposition、displayFrame、sourceCrop、bufferTransform、bufferTransform、dataspace */
| layer->updateCompositionState(refreshArgs.updatingGeometryThisFrame,refreshArgs.devOptForceClientComposition ||
| forceClientComposition, refreshArgs.internalDisplayRotationFlags)
| // 到最顶层使用背景模糊的 OutputLayer 之前都强制使用 GPU 合成
| if (mLayerRequestingBackgroundBlur == layer)
| | forceClientComposition = false;
| // 2.4.3
| planComposition();
|-->Output::planComposition()
| // 需要 ro.surface_flinger.enable_layer_caching 这个属性为true,mLayerCachingEnabled=true,然后才会启用 Planner
| // Planner 似乎还未启用,目前查几台机器都未启用
| if (!mPlanner || !getState().isEnabled)
| return;
| // 把Layer扁平化到数据结构 compositionengine::impl::OutputLayerCompositionState.overrideInfo
| // 缓存layer,扁平化到override中,下次再用其中的数据。TODO:似乎还未启用,暂时忽略
| mPlanner->plan(getOutputLayersOrderedByZ());
| // 2.4.4 把状态属性写入HWC待执行的缓存,等待执行
| writeCompositionState(refreshArgs);
|-->Output::writeCompositionState(const compositionengine::CompositionRefreshArgs& refreshArgs)
| // 遍历当前显示器的 OutputLayer
| for (auto* layer : getOutputLayersOrderedByZ())
| // 前边一大段是 透视图层 的处理
| // 如果上一个Layer的buffer和当前的Layer的buffer一样,那么忽略当前Layer
| // 下面直接看主逻辑
| layer->writeStateToHWC(includeGeometry, skipLayer, z++, overrideZ, isPeekingThrough);
|-->OutputLayer::writeStateToHWC(bool includeGeometry, bool skipLayer, uint32_t z,bool zIsOverridden, bool isPeekingThrough)
| const auto& state = getState();
| if (!state.hwc) return; //如果没有HWC接口,直接返回
| auto& hwcLayer = (*state.hwc).hwcLayer;
| if (!hwcLayer) return; // 如果没有 hwcLayer 直接返回
| // 获取 Layer 的 LayerFECompositionState ,只有 BufferLayer和 EffectLayer 有
| const auto* outputIndependentState = getLayerFE().getCompositionState();
| if (!outputIndependentState) return;
| // 合成类型
| auto requestedCompositionType = outputIndependentState->compositionType;
| // 有忽略的layer,新增的layer
| if (... skipLayer || includeGeometry)
| // 写入HWC依赖显示设备的几何图形信息
| // HWC2::Layer.setDisplayFrame、setSourceCrop、setZOrder、setTransform
| writeOutputDependentGeometryStateToHWC(hwcLayer.get(), requestedCompositionType, z);
| // 写入HWC不依赖显示设备的几何图形信息
| // HWC2::Layer.setBlendMode、setPlaneAlpha、setLayerGenericMetadata
| // skipLayer 为true的话,alpha=0.0f 颜色设置为完全透明
| writeOutputIndependentGeometryStateToHWC(hwcLayer.get(), *outputIndependentState, skipLayer);
| // 写入HWC依赖显示设备的每个帧状态
| // HWC2::Layer.etVisibleRegion、setBlockingRegion、setDataspace、setBrightness
| writeOutputDependentPerFrameStateToHWC(hwcLayer.get());
| // 写入HWC不依赖显示设备的每帧状态
| // HWC2::Layer.setColorTransform、setSurfaceDamage、setPerFrameMetadata、setBuffer
| writeOutputIndependentPerFrameStateToHWC(hwcLayer.get(), *outputIndependentState, requestedCompositionType, skipLayer);
| // 写入合成类型 HWC2::Layer.setCompositionType
| writeCompositionTypeToHWC(hwcLayer.get(), requestedCompositionType, isPeekingThrough, skipLayer);
| // 2.4.5 设置显示设备的颜色矩阵,做颜色变换,色盲、护眼模式等
| setColorTransform(refreshArgs);
| // 2.4.6 给虚拟显示屏用的。正常主屏使用 FramebufferSurface ,啥事也不做
| beginFrame();
| GpuCompositionResult result;
| // 是否可以预测合成策略--Android 13 新增
| // 去掉一些小概率原因,总结:如果上次不全是硬件合成,且存在GPU合成Layer时,返回true
| const bool predictCompositionStrategy = canPredictCompositionStrategy(refreshArgs);
| if (predictCompositionStrategy)
| // 异步执行 chooseCompositionStrategy --Android 13 新增
| // 就是 chooseCompositionStrategy 和 GPU合成 并行执行。用以节约时间
| result = prepareFrameAsync(refreshArgs);
| else
| //核心逻辑还是确认使用 客户端合成 还是 使用硬件合成
| prepareFrame();//【转“Output::prepareFrame()”章节】
|-->Output::prepareFrame()// 详情参见:prepareFrame() 章节
| auto& outputState = editState();
| std::optional<android::HWComposer::DeviceRequestedChanges> changes;
| bool success = chooseCompositionStrategy(&changes);//选择合成策略
| resetCompositionStrategy();// 重置合成策略的变量
| outputState.previousDeviceRequestedChanges = changes;
| outputState.previousDeviceRequestedSuccess = success;
| if (success)
| applyCompositionStrategy(changes);//应用合成策略
| finishPrepareFrame();// 用于虚拟屏
| //继续 Output::present(const compositionengine::CompositionRefreshArgs& refreshArgs)
| devOptRepaintFlash(refreshArgs);// doDebugFlashRegions当打开开发者选项中的“显示Surface刷新”时,额外为产生变化的图层绘制闪烁动画
| // GPU 合成,新增了一些对 prepareFrameAsync 结果的处理逻辑
| finishFrame(refreshArgs, std::move(result));//【转“Output::finishFrame”章节】
| //【转“Output::postFramebuffer()”】
| postFramebuffer();// postFramebuffer 函数就是告诉HWC开始做最后的合成了,并显示。获取释放fence,
| // 渲染最新的 cached sets,需要开启了Planner。TODO:渲染设置了预期显示时间的buffer?
| renderCachedSets(refreshArgs);
| postFrame();// 没啥东西输出log
| postComposition();// 杂七杂八的合成后处理,对于 BufferStateLayer 最终要的是 releasePendingBuffer
|-->SurfaceFlinger::postComposition()
| // 省略一大段内容
| for (const auto& layer: mLayersWithQueuedFrames)
| // 都是更新 FrameTracker、TimeStats 这些
| layer->onPostComposition(display, glCompositionDoneFenceTime,mPreviousPresentFences[0].fenceTime, compositorTiming);
| layer->releasePendingBuffer(/*dequeueReadyTime*/ now);
|-->BufferStateLayer::releasePendingBuffer(nsecs_t dequeueReadyTime)
| for (auto& handle : mDrawingState.callbackHandles)
| if (handle->releasePreviousBuffer && mDrawingState.releaseBufferEndpoint == handle->listener)
| // 这个 mPreviousReleaseCallbackId 在 BufferStateLayer::updateActiveBuffer() 赋值
| // mPreviousReleaseCallbackId = {getCurrentBufferId(), mBufferInfo.mFrameNumber};
| handle->previousReleaseCallbackId = mPreviousReleaseCallbackId;
| break;
| // 把 callback 加入 TransactionCallbackInvoker::mCompletedTransactions
| mFlinger->getTransactionCallbackInvoker().addCallbackHandles(mDrawingState.callbackHandles, jankData);
| //【这里就是通过binder通信,回调到 APP 端BBQ执行 releaseBuffer 了】
| mTransactionCallbackInvoker.sendCallbacks(false /* onCommitOnly */);
|-->BpTransactionCompletedListener::onTransactionCompleted(android::ListenerStats)
| // 如果还有新的buffer,需要请求新的vsync
| if (mCompositionEngine->needsAnotherUpdate())
| scheduleCommit(FrameHint::kNone)
Output::prepareFrame()
  • 所谓 Client 合成,就是 HWC 的客户端 SurfaceFlinger 去合成,SurfaceFlinger 合成的话使用GPU合成,因此 Client 合成,即GPU合成
  • prepareFrame 核心逻辑是确认使用 客户端合成 还是 使用硬件合成
  • prepareFrame 函数中同 HWC服务 交互去确认是否有客户端合成,如果没有客户端合成,并可以忽略验证,那么会直接显示。流程到这里基本结束了
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
c++复制代码CompositionEngine::present(CompositionRefreshArgs& args)
| //....
|-->Output::prepareFrame()
| auto& outputState = editState();
| std::optional<android::HWComposer::DeviceRequestedChanges> changes;
| bool success = chooseCompositionStrategy(&changes);
|-->Display::chooseCompositionStrategy(std::optional<android::HWComposer::DeviceRequestedChanges>* outChanges)
| // 在最近的一次合成中如果有任意一个layer是 GPU 合成,则返回true
| const bool requiresClientComposition = anyLayersRequireClientComposition();
| status_t result = hwc.getDeviceCompositionChanges(*halDisplayId, requiresClientComposition,...outChanges);
|-->HWComposer::getDeviceCompositionChanges(HalDisplayId displayId, bool frameUsesClientComposition,...outChanges)
| // 如果有需要GPU合成的layer, canSkipValidate=false;
| // 没有需要GPU合成的layer,如果Composer支持获得预期的展示时间,canSkipValidate=true;
| // 没有需要GPU合成的layer,Composer 也不支持获得预期的当前时间,只有当我们知道我们不会提前呈现时,我们才能跳过验证。
| const bool canSkipValidate = {...};
| if (canSkipValidate)
| sp<Fence> outPresentFence;
| uint32_t state = UINT32_MAX;
| //如果可以跳过验证,则直接在屏幕上显示内容,否则执行 validate(HWC 检查各个图层的状态,并确定如何进行合成)
| // numTypes返回合成类型需要变更的layer数量,numRequests 返回需要做getDisplayRequests请求的layer数量
| hwcDisplay->presentOrValidate(expectedPresentTime, &numTypes, &numRequests, &outPresentFence, &state);
| if (state == 1)
| // 跳过了验证环节,直接显示了。这时直接返回
| std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
| hwcDisplay->getReleaseFences(&releaseFences);// 显示成功,会返回 Fence fd
| displayData.releaseFences = std::move(releaseFences);
| displayData.lastPresentFence = outPresentFence;
| displayData.validateWasSkipped = true;
| displayData.presentError = error;
| return NO_ERROR;
| else
| // HWC 检查各个图层的状态,并确定如何进行合成
| // numTypes返回合成类型需要变更的layer数量,numRequests 返回需要做getDisplayRequests请求的layer数量
| hwcDisplay->validate(expectedPresentTime, &numTypes, &numRequests);
| // composer3::Composition 为枚举类型:
| //{ INVALID = 0, CLIENT = 1, DEVICE = 2, SOLID_COLOR = 3, CURSOR = 4, SIDEBAND = 5, DISPLAY_DECORATION = 6,};
| std::unordered_map<HWC2::Layer*, composer3::Composition> changedTypes;
| changedTypes.reserve(numTypes);// map扩容为numTypes
| // changedTypes 返回 map<Layer,Composition> 包含所有 与上次调用validateDisplay之前设置的合成类型不同的合成类型的Layer
| hwcDisplay->getChangedCompositionTypes(&changedTypes);
| // 枚举 hal::DisplayRequest{FLIP_CLIENT_TARGET = 1u , WRITE_CLIENT_TARGET_TO_OUTPUT = 2u ,}
| // 0 表示:指示客户端提供新的客户端目标缓冲区,即使没有为客户端合成标记任何layers。
| // 1 表示:指示客户端将客户端合成的结果直接写入虚拟显示输出缓冲区。
| auto displayRequests = static_cast<hal::DisplayRequest>(0);
| // 枚举 hal::LayerRequest{CLEAR_CLIENT_TARGET = 1 << 0, }
| // 1表示:客户端必须在该layer所在的位置使用透明像素清除其目标。如果必须混合该层,客户端可能会忽略此请求。
| std::unordered_map<HWC2::Layer*, hal::LayerRequest> layerRequests;
| layerRequests.reserve(numRequests); // map扩容为 numRequests
| // 返回 hal::DisplayRequest 和 每个Layer的 hal::LayerRequest 类型,用于指导 SurfaceFlinger 的GPU合成
| hwcDisplay->getRequests(&displayRequests, &layerRequests);
| // 返回client target属性,这个新增的,目前可能仅仅实现了亮度、调光、数据格式、数据空间相关属性
| DeviceRequestedChanges::ClientTargetProperty clientTargetProperty;
| hwcDisplay->getClientTargetProperty(&clientTargetProperty);
| // 组合成 DeviceRequestedChanges 结构体,返回
| outChanges->emplace(DeviceRequestedChanges{std::move(changedTypes), std::move(displayRequests),
std::move(layerRequests), std::move(clientTargetProperty)});
| // 注释这么说的:此函数相当于从getChangedCompositionTypes请求更改后的类型,在相应的层上设置这些类型,然后再次调用validateDisplay。
| // 但是,看源码感觉注释说的不大对,这里仅仅是把这个成员设为true: DisplayCommand::acceptDisplayChanges = true
| // 注释说的应该是命令缓存发送到HWC后,执行的流程
| hwcDisplay->acceptChanges();
| //只有正常执行会返回 true,其他,显示设备未连接、没有硬件合成、getDeviceCompositionChanges返回false,那么会 return false;
| return true;
| resetCompositionStrategy();
|-->Output::resetCompositionStrategy()
| auto& outputState = editState();
| // 先重置这些变量,在后续的流程中会使用。相当于设置默认值,因为对基本的Output实现只能进行客户端合成
| outputState.usesClientComposition = true;
| outputState.usesDeviceComposition = false;
| outputState.reusedClientComposition = false;
| // 这个previousDeviceRequestedChanges变量在 Output::canPredictCompositionStrategy 函数中用来判断是否预测合成策略
| outputState.previousDeviceRequestedChanges = changes;
| outputState.previousDeviceRequestedSuccess = success;
| if (success)// HWComposer::getDeviceCompositionChanges 执行错误,不会进入到这里。比如IComposer任意一接口调用失败
| applyCompositionStrategy(changes);
|-->Display::applyCompositionStrategy(const std::optional<DeviceRequestedChanges>& changes)
| if (changes)
| // 对每个 OutputLayer 应用HWC设备要求的合成类型更改
| applyChangedTypesToLayers(changes->changedTypes);
|-->Display::applyChangedTypesToLayers(const ChangedTypes& changedTypes)
| for (auto* layer : getOutputLayersOrderedByZ())
| auto hwcLayer = layer->getHwcLayer();// 获取 OutputLayer中存储的 HWC::Layer
| auto it = changedTypes.find(hwcLayer);
| if (it == changedTypes.end()) continue;
| layer->applyDeviceCompositionTypeChange(
static_cast<aidl::android::hardware::graphics::composer3::Composition>(it->second));
| // 应用HWC设备要求的合成类型更改
|-->OutputLayer::applyDeviceCompositionTypeChange(Composition compositionType)
| auto& state = editState();
| auto& hwcState = *state.hwc;
| // 这个 OutputLayerCompositionState::Hwc.hwcCompositionType 用于预测合成策略 Output::canPredictCompositionStrategy
| hwcState.hwcCompositionType = compositionType;//这个代表最近使用的合成类型
| applyDisplayRequests(changes->displayRequests);
|-->Display::applyDisplayRequests(const DisplayRequests& displayRequests)
| auto& state = editState();
| // 如果 displayRequests 包含flag FLIP_CLIENT_TARGET,则 flipClientTarget=true
| // 如果为true,则在执行客户端合成时应提供新的客户端目标(client target)缓冲区
| state.flipClientTarget = (static_cast<uint32_t>(displayRequests)
& static_cast<uint32_t>(hal::DisplayRequest::FLIP_CLIENT_TARGET)) != 0;
| applyLayerRequestsToLayers(changes->layerRequests);
|-->Display::applyLayerRequestsToLayers(const LayerRequests& layerRequests)
| for (auto* layer : getOutputLayersOrderedByZ())
| // OutputLayer.editState().clearClientTarget = false;
| layer->prepareForDeviceLayerRequests();
| auto hwcLayer = layer->getHwcLayer();
| if (auto it = layerRequests.find(hwcLayer); it != layerRequests.end())
| // 应用HWC的layer请求
| layer->applyDeviceLayerRequest(static_cast<Hwc2::IComposerClient::LayerRequest>(it->second));
|-->OutputLayer::applyDeviceLayerRequest(hal::LayerRequest request)
| if(request== hal::LayerRequest::CLEAR_CLIENT_TARGET:)
| // 客户端合成时,该layer所在的位置使用透明像素清除其目标
| editState().clearClientTarget = true;
| applyClientTargetRequests(changes->clientTargetProperty);
|-->Display::applyClientTargetRequests(const ClientTargetProperty& clientTargetProperty)
| editState().dataspace = static_cast<ui::Dataspace>(clientTargetProperty.clientTargetProperty.dataspace);
| editState().clientTargetBrightness = clientTargetProperty.brightness;
| editState().clientTargetDimmingStage = clientTargetProperty.dimmingStage;
| getRenderSurface()->setBufferDataspace(editState().dataspace);
| getRenderSurface()->setBufferPixelFormat(static_cast<ui::PixelFormat>(clientTargetProperty.clientTargetProperty.pixelFormat));
| auto& state = editState();
| // anyLayersRequireClientComposition:
| // Output 中有任意一个 OutputLayer 状态对象的 hwc->hwcCompositionType 为 Composition::CLIENT,则返回true
| // 就是 OutputLayer.getState().hwc->hwcCompositionType == Composition::CLIENT
| // 即,当前显示设备中有任意一个Layer的合成为 客户端合成,则 Output.getState().usesClientComposition = true;
| state.usesClientComposition = anyLayersRequireClientComposition();// true表示有使用客户端合成
| // 当前显示设备的当前帧中,不是全部使用了客户端合成,则 usesDeviceComposition = true;
| // 表示当前显示设备的当前帧可能完使用硬件合成,也可能是两者都有
| state.usesDeviceComposition = !allLayersRequireClientComposition();// true表示有使用硬件合成
| // 以上两个变量将用于接下来的 Output::finishPrepareFrame()流程,虚拟屏的prepareFrame方法 和 finishFrame 流程
| finishPrepareFrame();
| // 用于虚拟屏
|-->Output::finishPrepareFrame()
| const auto& state = getState();
| if (mPlanner)
| mPlanner->reportFinalPlan(getOutputLayersOrderedByZ());
| // 准备帧进行渲染----这里只有 虚拟屏幕 实现了prepareFrame,其他什么也不做
| mRenderSurface->prepareFrame(state.usesClientComposition, state.usesDeviceComposition);
Output::finishFrame
  • 处理Client合成(GPU合成)
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
c++复制代码Output::present(const compositionengine::CompositionRefreshArgs& refreshArgs)
//...
finishFrame(refreshArgs, std::move(result));// GPU 合成
// result 为 prepareFrameAsync 的执行结果
|-->Output::finishFrame(const CompositionRefreshArgs& refreshArgs, GpuCompositionResult&& result)
| const auto& outputState = getState();
/*
outputState.strategyPrediction
走 prepareFrame() 为 DISABLED,表示不使用预测合成策略
走 prepareFrameAsync() 为 SUCCESS 或者 FAIL 表示合预测成功或者失败
*/
| if (outputState.strategyPrediction == CompositionStrategyPredictionState::SUCCESS)
| //如果预测成功,则已经执行完 GPU 合成了,不必再dequeueRenderBuffer了
| optReadyFence = std::move(result.fence);
| else // prepareFrameAsync 中预测失败了
| // 虽然预测失败了,但是已经dequeued的buffer,会通过GpuCompositionResult传送过来,拿来复用
| if (result.bufferAvailable())
| buffer = std::move(result.buffer);
| bufferFence = std::move(result.fence);
| else // dequeueRenderBuffer失败,连dequeued的buffer都没有,那就重走一遍 prepareFrameAsync GPU 合成的那块逻辑。当然,也可能就没有执行 prepareFrameAsync
| // BufferQueue熟悉的配方 dequeueBuffer
| dequeueRenderBuffer(&bufferFence, &buffer))
|-->Output::dequeueRenderBuffer(unique_fd* bufferFence, std::shared_ptr<ExternalTexture>* tex)
| const auto& outputState = getState();
| // 有使用客户端合成 或者 设置了 flipClientTarget 都需要进行 GPU 合成
| if (outputState.usesClientComposition || outputState.flipClientTarget)
| //【dequeueBuffer,然后把dequeue的Buffer包装为 ExternalTexture】
| *tex = mRenderSurface->dequeueBuffer(bufferFence);
|-->RenderSurface::dequeueBuffer(base::unique_fd* bufferFence)
| int fd = -1;
| ANativeWindowBuffer* buffer = nullptr;
| // 调用 Surface.dequeueBuffer
| mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buffer, &fd);
| // GraphicBuffer 继承 ANativeWindowBuffer
| // GraphicBuffer::from 把父类ANativeWindowBuffer强制转换为子类 GraphicBuffer
| sp<GraphicBuffer> newBuffer = GraphicBuffer::from(buffer);
| // ExternalTexture 使用 RenderEngine 代表客户端管理GPU图像资源。
| // 渲染引擎不是GLES的话,在 ExternalTexture 构造函数中把GraphicBuffer映射到RenderEngine所需的GPU资源中。
| mTexture = new ExternalTexture(newBuffer,mCompositionEngine.getRenderEngine(),WRITEABLE)
| *bufferFence = base::unique_fd(fd);//返回fence fd
| return mTexture;// 返回纹理类
| // 执行GPU合成
| optReadyFence = composeSurfaces(Region::INVALID_REGION, refreshArgs, buffer, bufferFence);
| // BufferQueue熟悉的配方 queueBuffer
| mRenderSurface->queueBuffer(std::move(*optReadyFence));
|-->RenderSurface::queueBuffer(base::unique_fd readyFence)
| // 调用 Surface.queueBuffer
| mNativeWindow->queueBuffer(mNativeWindow.get(),mTexture->getBuffer()->getNativeBuffer(),dup(readyFence));
| // mDisplaySurface:
| // 对于非虚拟屏是 FramebufferSurface,其包装消费者、继承 DisplaySurface;对于虚拟屏是 VirtualDisplaySurface
| mDisplaySurface->advanceFrame();
|-->FramebufferSurface::advanceFrame()//就是调用 FramebufferSurface::nextBuffer
| uint32_t slot = 0;
| sp<GraphicBuffer> buf;
| sp<Fence> acquireFence(Fence::NO_FENCE);
| Dataspace dataspace = Dataspace::UNKNOWN;
| nextBuffer(slot, buf, acquireFence, dataspace);
| // 这里核心是调用 setClientTarget ,把 客户端合成输出的缓冲区句柄 传递给 HWC。
| // 当然,目前还未真正传递到HWC,只是写到命令缓冲区。需要等待执行 present 才执行传递
|-->FramebufferSurface::nextBuffer(uint32_t& outSlot,sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence,Dataspace& outDataspace)
| mHwc.setClientTarget(mDisplayId, outSlot, outFence, outBuffer, outDataspace);
Output::postFramebuffer()
  • 送显 + 获取 Layer releaseFence
  • 这个 releaseFence 并不是当前送显的fence,是上一帧的
  • Layer releaseFence 会合并 GPU合成的fence
    • 就是说APP dequeuebuffer拿到新buffer后,需要等待GPU合成完成 + HWC使用当前Layer buffer替换上一个buffer(app dequque的buffer)后,才能在这个新buffer上填充数据
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
c++复制代码//先看下结构体 FrameFences
/*
struct FrameFences {
// 这个fence,在当前帧在屏幕上显现,或者发送到面板内存时,会发送信号
sp<Fence> presentFence{Fence::NO_FENCE};
// GPU 合成的buffer的消费者 acquire fence;代表GPU合成是否完成;(注:GPU绘制的acquire fence,在latchBuffer阶段已经判断了。)
sp<Fence> clientTargetAcquireFence{Fence::NO_FENCE};
// 所有Layer的fence;在先前呈现的buffer被读取完成后发送信息;HWC生成
std::unordered_map<HWC2::Layer*, sp<Fence>> layerFences;
};
*/
Output::postFramebuffer()
| auto frame = presentAndGetFrameFences();
|-->Display::presentAndGetFrameFences()
| // 【1】这里就是赋值 FrameFences.clientTargetAcquireFence
| auto fences = impl::Output::presentAndGetFrameFences();
|-->Output::presentAndGetFrameFences()
| if (getState().usesClientComposition)
| result.clientTargetAcquireFence = mRenderSurface->getClientTargetAcquireFence();
| // 1、【在屏幕上呈现当前显示内容(如果是虚拟显示,则显示到输出缓冲区中)】
| // 2、获取device上所有layer的 ReleaseFence
| hwc.presentAndGetReleaseFences(*halDisplayIdOpt, getState().earliestPresentTime, getState().previousPresentFence);
| // getPresentFence返回 HWComposer.mDisplayData.at(displayId).lastPresentFence;
| // 这个fence,在当前帧在屏幕上显现,或者发送到面板内存时,会发送信号
| // 【2】赋值 FrameFences.presentFence
| fences.presentFence = hwc.getPresentFence(*halDisplayIdOpt);
| for (const auto* layer : getOutputLayersOrderedByZ())
| auto hwcLayer = layer->getHwcLayer();
| // 从HWC显示设备上所有Layer的fence
| // 【3】赋值 FrameFences.layerFences
| fences.layerFences.emplace(hwcLayer, hwc.getLayerReleaseFence(*halDisplayIdOpt, hwcLayer));
| // 释放GPU合成使用的buffer
| mRenderSurface->onPresentDisplayCompleted();
| for (auto* layer : getOutputLayersOrderedByZ())
| sp<Fence> releaseFence = Fence::NO_FENCE;
| // 获取HWC每个layer的releaseFence
| if (auto hwcLayer = layer->getHwcLayer())
| if (auto f = frame.layerFences.find(hwcLayer); f != frame.layerFences.end())
| releaseFence = f->second;
| // 如果有客户端合成,merge GPUbuffer的fence
| if (outputState.usesClientComposition)
| releaseFence = Fence::merge("LayerRelease", releaseFence, frame.clientTargetAcquireFence);
| //同步Fence到Layer中
| // 如果是 BufferQueueLayer 设置 mSlots[slot].mFence;
| // 如果是 BufferStateLayer 把fence关联到回调类中
| layer->getLayerFE().onLayerDisplayed(ftl::yield<FenceResult>(std::move(releaseFence)).share());
| // mReleasedLayers是一些即将移除的的layer,但是当前vsync还在生产帧数据的layer
| // 把presentFence传给这些layer使用,毕竟他们不参与合成了
| for (auto& weakLayer : mReleasedLayers)
| if (const auto layer = weakLayer.promote())
| layer->onLayerDisplayed(ftl::yield<FenceResult>(frame.presentFence).share());
| mReleasedLayers.clear();//清空 mReleasedLayers

再回到APP进程端 releaseBuffer

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
c++复制代码|-->SurfaceFlinger::postComposition() 
| // 省略一大段内容
| for (const auto& layer: mLayersWithQueuedFrames)
| // 更新FrameTracker、TimeStats这些
| layer->onPostComposition(display, glCompositionDoneFenceTime,mPreviousPresentFences[0].fenceTime, compositorTiming);
| layer->releasePendingBuffer(/*dequeueReadyTime*/ now);
|-->BufferStateLayer::releasePendingBuffer(nsecs_t dequeueReadyTime)
| for (auto& handle : mDrawingState.callbackHandles)
| if (handle->releasePreviousBuffer && mDrawingState.releaseBufferEndpoint == handle->listener)
| // 这个 mPreviousReleaseCallbackId 在 BufferStateLayer::updateActiveBuffer() 赋值
| // mPreviousReleaseCallbackId = {getCurrentBufferId(), mBufferInfo.mFrameNumber};
| handle->previousReleaseCallbackId = mPreviousReleaseCallbackId;
| break;
| // 把 callback 加入 TransactionCallbackInvoker::mCompletedTransactions
| mFlinger->getTransactionCallbackInvoker().addCallbackHandles(mDrawingState.callbackHandles, jankData);
| //【这里就是通过binder通信,回调到 APP 端BBQ执行 releaseBuffer 了】
| mTransactionCallbackInvoker.sendCallbacks(false /* onCommitOnly */);
|-->BpTransactionCompletedListener::onTransactionCompleted(android::ListenerStats)


// 跨进程进入到APP端
// frameworks/native/libs/gui/BLASTBufferQueue.cpp
releaseBufferCallbackThunk(wp<BLASTBufferQueue> context, ReleaseCallbackId& id,Fence& releaseFence, uint32_t currentMaxAcquiredBufferCount)
| sp<BLASTBufferQueue> blastBufferQueue = context.promote();
| blastBufferQueue->releaseBufferCallback(id, releaseFence, currentMaxAcquiredBufferCount);
|-->BLASTBufferQueue::releaseBufferCallback(const ReleaseCallbackId& id,Fence& releaseFence,uint32_t currentMaxAcquiredBufferCount)
| releaseBufferCallbackLocked(id, releaseFence, currentMaxAcquiredBufferCount,false /* fakeRelease */);
|-->BLASTBufferQueue::releaseBufferCallbackLocked(ReleaseCallbackId& id,Fence& releaseFence,uint32_t currentMaxAcquiredBufferCount, bool fakeRelease)
| // ReleaseCallbackId 是个包含 bufferId 和 帧号 的Parcelable, ReleasedBuffer结构体又把 releaseFence 包含进来
| auto rb = ReleasedBuffer{id, releaseFence};
| if (std::find(mPendingRelease.begin(), mPendingRelease.end(), rb) == mPendingRelease.end())
| // 队列里边没有的话,就加入队列
| mPendingRelease.emplace_back(rb);// mPendingRelease 是个 std::deque
| while (mPendingRelease.size() > numPendingBuffersToHold) // numPendingBuffersToHold 是需要保留的buffer数量
| const auto releasedBuffer = mPendingRelease.front();
| mPendingRelease.pop_front();
| releaseBuffer(releasedBuffer.callbackId, releasedBuffer.releaseFence);
|-->BLASTBufferQueue::releaseBuffer(const ReleaseCallbackId& callbackId,const sp<Fence>& releaseFence)
| // mSubmitted 是个map<ReleaseCallbackId, BufferItem>,从这个map中查找对应的 BufferItem
| auto it = mSubmitted.find(callbackId);
| mNumAcquired--;
| mBufferItemConsumer->releaseBuffer(it->second, releaseFence);
|-->BufferItemConsumer::releaseBuffer(const BufferItem &item, const sp<Fence>& releaseFence)
| // mSlots[slot].mFence = fence; 赋值releaseFence,并处理 Fence 合并情况
| addReleaseFenceLocked(item.mSlot, item.mGraphicBuffer, releaseFence);
| releaseBufferLocked(item.mSlot, item.mGraphicBuffer, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
|-->ConsumerBase::releaseBufferLocked(int slot, const sp<GraphicBuffer> graphicBuffer, EGLDisplay display, EGLSyncKHR eglFence)
| // 调用消费者的 releaseBuffer 方法
| status_t err = mConsumer->releaseBuffer(slot, mSlots[slot].mFrameNumber, display, eglFence, mSlots[slot].mFence);
|-->BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, const sp<Fence>& releaseFence,...)
| // 忽略一些容错处理
| sp<IProducerListener> listener;
| mSlots[slot].mEglDisplay = eglDisplay; // display = EGL_NO_DISPLAY;
| mSlots[slot].mEglFence = eglFence; // EGLSyncKHR eglFence = EGL_NO_SYNC_KHR
| mSlots[slot].mFence = releaseFence; // SurfaceFlinger 传递过来的 releaseFence
| mSlots[slot].mBufferState.release(); // 状态转为 released
| mCore->mActiveBuffers.erase(slot);// 从激活状态set中删除
| mCore->mFreeBuffers.push_back(slot); // 放回 Free list 中
| if (mCore->mBufferReleasedCbEnabled)
| // mConnectedProducerListener 是 BufferQueueProducer::connect 时传入的
| // CPU绘制传入的 StubProducerListener,没啥用
| listener = mCore->mConnectedProducerListener;
| // 如果有阻塞在dequeuebuffer的线程,此时会被唤醒,有新的buffer可以 Dequeue 了
| mCore->mDequeueCondition.notify_all();
| if (listener != nullptr)
| listener->onBufferReleased();// 对于CPU绘制,这个是空函数没啥
| // 如果返回 buffer过时了,需要清空这个slot的 GraphicBuffer
| if (err == IGraphicBufferConsumer::STALE_BUFFER_SLOT)
| mSlots[slotIndex].mGraphicBuffer = nullptr;
| mSlots[slotIndex].mFence = Fence::NO_FENCE;
| mSlots[slotIndex].mFrameNumber = 0;
| mPrevFinalReleaseFence = mSlots[slot].mFence;
| // 这里的mSlots是BufferItem的,和 BufferQueue 的不是一个变量
| // BufferItem 的Fence设置为 NO_FENCE
| mSlots[slot].mFence = Fence::NO_FENCE;
| mSubmitted.erase(it);

后记:

对于 Android 13 的 SurfaceFlinger 而言,参考资料真的是非常有限。

从 Android PAndroid Q小更新,Android QAndroid R 大的架构更新,

Android R~Android S 机制上的更新(BBQ+BufferStateLayer),Android S ~ Android T 又是大的架构更新,

Google还不断使用最新的c++标准去重构代码,从c11又更新到c20。更新的XX都不认识了。

最后导致能参考的资料基本失效了,只能一个个变量去查,并且都没类注释,要命的工作量啊。

最后不感谢CCTV,感谢 cs.android.com 吧,多亏了这个源码网站强大的检索能力。

一、点击桌面App图标事件分发

  • systemserver进程启动时,会启动 inputflinger 服务: native层的 InputManager
  • InputManager 启动时,启动 InputDispatcher 线程和 InputReader 线程
  • InputReader 线程循环调用 EventHub 的 getEvents 方法,linux设备节点/dev/input文件夹下的event读取事件
  • InputReader 读取到事件后,放到 InputDispatcher.mInboundQueue 队列中,并通知 InputDispatcher 线程读取数据
  • InputDispatcher 线程唤醒后,从 mInboundQueue 队列中取出事件,按事件类型进行分发。
  • 对于触屏事件,会寻找屏幕触控事件的焦点窗口,找到后把事件放入 Connection.outboundQueue 队列中
    • Connection是在窗口添加时在 WindowState.openInputChannel 调用过程中创建的,
    • 一个 Connection有一个服务端的InputChannel,一个InputChannel有一个socketpair服务端socket的fd,
    • 同时 socketpair客户端的fd会被发送到App进程,并加入epoll监听
    • 因此Connection就代表同App端的socket连接(或者说是管道)
  • 最后通过 Connection 中的 socket 把事件发送到 App

InputDispatcher分发流程

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
c复制代码InputDispatcher::start();// 这个start是SystemServer进程启动过程调用的
// 启动线程。循环执行 dispatchOnce()
| mThread = std::make_unique<InputThread>( "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
|-->InputDispatcher::dispatchOnce();
| dispatchOnceInnerLocked(&nextWakeupTime);
// 取出队列第一个数据, mPendingEvent 作为成员变量,表示待处理事件,一次循环处理一个待处理事件
| mPendingEvent = mInboundQueue.front();
// 取出后,移除第一个数据
| mInboundQueue.pop_front();
// 根据事件类别,分别调用不同的事件分发函数,比如,按键事件调用 dispatchKeyLocked
| switch (mPendingEvent->type)
// 以屏幕触控事件为例
| case EventEntry::Type::MOTION:
| // 分发屏幕触控事件
| done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
// 寻找屏幕触控事件的焦点窗口,把所有接收当前输入事件的窗口的InputChannel封装到InputTarget,并添加到集合inputTargets
| findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime, &conflictingPointerActions);
| dispatchEventLocked(currentTime, entry, inputTargets);
// 遍历集合 inputTargets
| for (const InputTarget& inputTarget : inputTargets)
// 根据 token 拿到 Connection 【见:addToDisplayAsUser 章节】
// 从map类型数据 mConnectionsByToken 依据key InputChannel.mToken 查找 Connection
// std::unordered_map<sp<IBinder>, sp<Connection>> mConnectionsByToken
// mConnectionsByToken 中的数据是 createInputChannel 是添加的
// createInputChannel 是添加窗口时在 WindowState.openInputChannel 调用过程中调用。
// 一个 Connection有一个服务端的InputChannel,一个InputChannel有一个socketpair服务端socket的fd
// 因此Connection就代表同App端的socket连接(或者说是管道)
| sp<Connection> connection = getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
| prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
| enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
| enqueueDispatchEntryLocked(connection, eventEntry, inputTarget, FLAG_DISPATCH_AS_IS);
// 把需要分发的事件加入到对于窗口的Connection.outboundQueue队列中
| connection->outboundQueue.push_back(dispatchEntry.release());
// 开始循环分发事件
| startDispatchCycleLocked(currentTime, connection);
// outboundQueue 队列不为空就一直循环处理
| while (!connection->outboundQueue.empty())
| connection->inputPublisher.publishMotionEvent(...)
| mChannel->sendMessage(&msg);
// 通过socket把事件发生给客户端
| ::send(getFd(), &cleanMsg, msgLength, MSG_DONTWAIT | MSG_NOSIGNAL);
// 删除outboundQueue队列中已发送的事件
| connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
connection->outboundQueue.end(),
dispatchEntry));
// 已发送的事件加入Connection的 waitQueue
// App端处理完事件后,会回调回来删除waitQueue中的事件
// AMR 检查时,waitQueue 中的事件超时未回调,会触发ANR
| connection->waitQueue.push_back(dispatchEntry);

// 处理ANR
| const nsecs_t nextAnrCheck = processAnrsLocked();
| mLooper->pollOnce(timeoutMillis);

App进程事件分发

  • looper epoll监听 SocketPair 的fd 【这个fd的来源见:addToDisplayAsUser 章节】

  • socket来数据后,回调 NativeInputEventReceiver::handleEvent

    • android::NativeInputEventReceiver.consumeEvent

    • native 反射调用Java层 InputEventReceiver.deliverInputEvent

    • WindowInputEventReceiver.onInputEvent

    • ViewRootImpl.enqueueInputEvent//执行入队操作—PendingInputEventQueue

    • doProcessInputEvents()

    • deliverInputEvent(q);//这里会在systrace显示 deliverInputEvent块

      • 经过若干步骤后

      • mView.dispatchPointerEvent(event);//进入view的事件分发流程

        然后 view 再处理各自的touch事件。

        比如ScrollView,在touch事件中,会调整view的坐标,然后调用 invalidate 函数,函数最终会调用 requestNextVsync 触发 vsync ,vsync 回调doframe中绘制流程中,ScrollView根据新的坐标绘制界面,然后就看到了界面滚动。

事件分发到桌面图标的view后,view自身的点击事件中调用 startActivity 启动App。

二、APP创建进程

App到systemserver进程

Activity 的 startActivity 函数会调用到 ActivityTaskManagerService 的 startActivityAsUser 或者其他几个 start 方法

  • ActivityTaskManagerService.startActivityAsUser

  • —>ActivityStarter.execute

  • —>ActivityStarter.executeRequest

    • 内部创建ActivityRecord : ActivityRecord r = new ActivityRecord.Builder(mService)
      • ActivityRecord 继承 WindowToken
      • Android 12 构造函数中 appToken = new Token
        • Token extends IApplicationToken.Stub
      • token,这个东西Android 11,Android12,Android13 这里的代码都不一样。
      • Android 13 Token extends Binder
        • ActivityRecord 没有 appToken 变量了,也是new Token,然后传递到 父类 WindowToken 中
      • 由于构造函数中传递的DisplayContent为null,新创建的 ActivityRecord 还不会加入 DisplayContent 的HashMap对象 mTokenMap
  • —>ActivityStarter.startActivityUnchecked

  • —>ActivityStarter.startActivityInner

    • setNewTask

      –>addOrReparentStartingActivity(task, “setTaskFromReuseOrCreateNewTask”); 把 ActivityRecord 添加到任务栈

      • 给 ActivityRecord 添加 parent : parent.addChild(mStartActivity); ActivityRecord.getTask 返回的就是这个 targetTask
      • addOrReparentStartingActivity 最终会把 ActivityRecord 加入到 DisplayContent .mTokenMap
    • mTargetRootTask.startActivityLocked

      • 判断当前 activity 是否需要为其新建 Task,将 ActivityRecord 加入到对应的 Task 栈顶中
      • ActivityRecord.showStartingWindow 启动过度界面
    • mTargetRootTask.moveToFront

    • RootWindowContainer.resumeFocusedTasksTopActivities===>转Task.resumeFocusedTasksTopActivities

    • mSupervisor.mRecentTasks.add(mStartActivity.getTask())

    • 其他任务栈相关的处理

  • —> Task.resumeFocusedTasksTopActivities

  • —> Task.resumeTopActivityUncheckedLocked

  • —> Task.resumeTopActivityInnerLocked // 这里写是的Android12的流程,Android 13 这里不一样了

    • ActivityRecord next = topRunningActivity(true /* focusableOnly */);
    • —>如果有关联的进程,则直接调度生命周期:mAtmService.getLifecycleManager().scheduleTransaction(transaction);
    • —>如果是新的activity【mTaskSupervisor.startSpecificActivity(next, true, true)】,事务添加 LaunchActivityItem Callback,用于app进程创建activity。如果没有进程还会创建进程
  • —>ActivityTaskSupervisor.startSpecificActivity

    • —> 如果已有进程调用 realStartActivityLocked
    • —>没有进程,创建进程流程:mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? “top-activity” : “activity”);
  • –>ATMS.startProcessAsync

    • startProcessAsync 只是把任务post给AMS,调用 AMS.startProcess
  • –>ActivityManagerInternal.startProcess

    • ActivityManagerInternal.startProcess 是个抽象方法,实现是 ActivityManagerService.LocalService.startProcess
  • –>ActivityManagerService.LocalService.startProcessLocked

    • 创建 HostingRecord ,并作为参数传给下一步
    • HostingRecord .mHostingZygote 属性用于选择 zygote 类型
    • HostingRecord 构造函数未传入 hostingZygote 参数,使用默认的 REGULAR_ZYGOTE ,即常规孵化器
  • ActivityManagerService.startProcessLocked 没啥内容,直接调用 ProcessList.startProcessLocked

  • –>16参数的ProcessList.startProcessLocked

    • 处理 badProcess,连续崩溃超过2次会变成badProcess,后台禁止启动badProcess
    • 处理隔离进程
    • 处理不同App在同一个进程情况,App正在启动情况
      • 正在启动的话,直接返回
    • 处理App已经死亡,但是死亡通知还未到来的情况
    • 处理系统还未启动完成情况,先把App存起来,之后处理
  • –>4参数的ProcessList.startProcessLocked 直接转发到6参数的 startProcessLocked

  • –>6参数的ProcessList.startProcessLocked 代码很多主要是设置启动参数

    • 进程正在启动中,返回
    • 记录启动开始的时间
    • 清理参与的 死亡通知信息
    • 清理mProcessesOnHold用于保存那些在系统还没有准备好就提前请求启动的ProcessRecord
    • 更新 Profiler 信息
    • 设置外存储挂载模式、设置App权限:gids
    • 处理 manifest中设置了android:debuggable 信息,添加debug启动参数
    • 设置 ABI、设置指令集、设置 selinux
    • 设置App进程的启动入口为 “android.app.ActivityThread
  • –>ProcessList.startProcess

    • 启动准备
    • 设置一些正在启动的标志
    • 异步启动和同步启动,默认使用异步启动
  • –>ProcessList.handleProcessStart 异步启动

    • 如果上一个App还没有死亡通知,则延迟启动,延迟时间最长默认 10 秒
    • 正常情况直接调用 ProcessList.startProcess
  • –>ProcessList.startProcess

    • 处理存储目录
    • 选择创建App进程的孵化器,由于HostingRecord .mHostingZygote 为 REGULAR_ZYGOTE ,因此调用 Process.start
  • –>Process.start 没啥内容,直接调用 ZygoteProcess.start

  • –>ZygoteProcess.start

    • 处理usap,usap启用的话,预创建APP进程,最大创建10个线程
    • Android 13 由属性 dalvik.vm.usap_pool_enabled 决定是否启用usap,这个属性默认为false
    • 之后调用 ZygoteProcess.startViaZygote
  • –>ZygoteProcess.startViaZygote 把参数封装成字符串

  • –>ZygoteProcess.zygoteSendArgsAndGetResult 处理一些字符串异常,并加入数据大小

    • 调用 openZygoteSocketIfNeeded(abi) 连接 ZygoteServer ,根据ABI确定连接 zygote(zygote64) 还是 zygote_secondary(zygote32)
  • –>ZygoteProcess.attemptZygoteSendArgsAndGetResult 写完socket,接着后读socket –>zygoteWriter.write(msgStr);
    –>使用socket 数据传输到 ZygoteServer

ZygoteServer进程

从Zygote启动讲起

ZygoteInit.main // Zygote 有两种启动方式,一种是启动system_server 一种启动App

  • main函数
    • 1、非懒加载情况下,预加载资源:jar,图形库,drawable、字体
    • 2、创建zygote进程的socket server服务端对象 ZygoteServer
    • 3、调用 ZygoteServer.runSelectLoop 进入死循环,等待 AMS 创建进程的socket消息(也会处理其他消息)
    • 4、调用 runSelectLoop 返回的 Runnable.run 方法
  • ZygoteServer.runSelectLoop
  • ZygoteServer.acceptCommandPeer // 得到一个请求连接封装对象ZygoteConnection
  • ZygoteConnection.processCommand //处理AMS客户端请求
  • Zygote.forkSimpleApps // fork创建应用子进程,
    • ZygoteCommandBuffer.forkRepeatedly // 进入native层后,调用 fork()
    • Zygote.childMain
      • ZygoteInit.zygoteInit // 开启 binder 消息监听 ,设置异常处理函数
      • RuntimeInit.applicationInit
      • RuntimeInit.findStaticMain
        • return new MethodAndArgsCaller(m, argv);

MethodAndArgsCaller 对象不再继承Exception,仅仅继承Runnable,

MethodAndArgsCaller经过层层 return 后,返回 ZygoteInit.main ,

最后调用 MethodAndArgsCaller.run 方法 通过反射创建ActivityThread对象并调用其“main”入口方法。

ZygoteInit.main
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
java复制代码ZygoteInit.main(String[] argv);
| ZygoteServer zygoteServer = null;
| Runnable caller;
// 非懒加载情况下,预加载资源
|-->static void preload(TimingsTraceLog bootTimingsTraceLog);
| preloadClasses(); // 加载 /system/etc/preloaded-classes
// 加载非启动使用的类:
// /system/framework/android.hidl.base-V1.0-java.jar
// /system/framework/android.hidl.manager-V1.0-java.jar
// /system/framework/android.test.base.jar
| cacheNonBootClasspathClassLoaders();
/*
com.android.internal.R.array.preloaded_drawables
com.android.internal.R.array.preloaded_color_state_lists
com.android.internal.R.array.preloaded_freeform_multi_window_drawables
*/
| preloadResources();
// 预加载图形缓存map库
// Gralloc4Mapper::preload();Gralloc3Mapper::preload();Gralloc2Mapper::preload();
| nativePreloadAppProcessHALs();
/* GL driver 或者 Vulkan driver 预加载 */
| maybePreloadGraphicsDriver();
// 加载共享库:libandroid.so libcompiler_rt.so libjnigraphics.so
| preloadSharedLibraries();
// TextView.preloadFontCache(); 加载字体
| preloadTextResources();
| WebViewFactory.prepareWebViewInZygote();
// native层获取socket fd; 命名空间mount rootfs; selinux_android_seapp_context_init();
| Zygote.initNativeState(isPrimaryZygote);
//如果是主Zygote,Zygote 64位,创建地址名为 zygote 的socket服务端,以及usap socket服务 usap_pool_primary
//如果是次Zygote,Zygote 32位,创建地址名为 zygote_secondary 的socket服务端,以及usap socket服务 usap_pool_secondary
| zygoteServer = new ZygoteServer(isPrimaryZygote);
// 如果argv参数中有 "start-system-server" 则fork SystemServer 进程
| if (startSystemServer)
| Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
| r.run();
| return; // for SystemServer 进程 后直接返回,退出进程
// 默认情况,运行 runSelectLoop ,开启 zygoteServer 循环,等待 AMS 创建进程的socket消息
| caller = zygoteServer.runSelectLoop(abiList);
| if (caller != null) // fork 完成的子进程,会从runSelectLoop无线循环中跳出,会进入到这里
/*
如果是子进程的话,这里返回的是 MethodAndArgsCaller,MethodAndArgsCaller 继承Runnable
这里不像以前那样抛出异常清理栈帧,就是回退到 ZygoteInit.main,通过 MethodAndArgsCaller.run调用 android.app.ActivityThread.main
*/
| caller.run();
ZygoteServer.runSelectLoop
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
java复制代码Runnable runSelectLoop(String abiList);
// socketFDs[0] 为 ZygoteServer 的fd,之后的数据为 连接客户端的 socket fd
| ArrayList<FileDescriptor> socketFDs = new ArrayList<>();
| ArrayList<ZygoteConnection> peers = new ArrayList<>();
| socketFDs.add(mZygoteSocket.getFileDescriptor());// ZygoteServer 的fd
| peers.add(null);// 先add了一个null,用于和 socketFDs 共用一个下标变量 pollIndex
| while (true)
| StructPollfd[] pollFDs;
// 循环起始先把 socketFDs 的fd加入到数组 pollFDs
// 之后再把 usapPool 的 fd 加入到 pollFDs
// usapPoolEventFDIndex 记录 usapPool 起始索引
// poll监听 socketFDs 中的文件描述符
| Os.poll(pollFDs, pollTimeoutMs);
| while (--pollIndex >= 0)
| if (pollIndex == 0)
// pollIndex == 0 表示 ZygoteServer socket 事件
| ZygoteConnection newPeer = acceptCommandPeer(abiList); // 拿到连接客户端的socket
| peers.add(newPeer);
// 把客户端的fd放到数组,下一次循环,一起加入到poll监听
| socketFDs.add(newPeer.getFileDescriptor());
| else if (pollIndex < usapPoolEventFDIndex)
// AMS 创建进程的客户端 socket 事件
| ZygoteConnection connection = peers.get(pollIndex);
// 读取socket连接的数据,并处理
| final Runnable command = connection.processCommand(this, multipleForksOK);
// //默认值为false,在子进程时,会调用 setForkChild 设置为 true
| if (mIsForkChild)
// 子进程返回的是 继承Runnable的 MethodAndArgsCaller 对象
| return command; // 子进程直接返回 command ,并结束 runSelectLoop 循环
ZygoteConnection.processCommand
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
java复制代码Runnable processCommand(ZygoteServer zygoteServer, boolean multipleOK);
// 创建 native 层对象 NativeCommandBuffer,用于读socket数据
| ZygoteCommandBuffer argBuffer = new ZygoteCommandBuffer(mSocket);
// 把 ZygoteCommandBuffer 传入ZygoteArguments
// 并调用 ZygoteArguments.parseArgs(ZygoteCommandBuffer args, int argCount)
// parseArgs 读取socket,并解析数据
| parsedArgs = ZygoteArguments.getInstance(argBuffer);
| if (parsedArgs.mPreloadPackage != null)
// 如果是 WebViewZygote,预加载 WebView 的库
| handlePreloadPackage(...);
| if (canPreloadApp() && parsedArgs.mPreloadApp != null)
// 如果是AppZygoteServer,会预加载apk
| handlePreloadApp(...);
/*
mInvokeWith InvokeWith DEBUG 使用, wrap.sh 脚本相关
mStartChildZygote 创建子zygote进程
multipleOK = true
非系统进程(systemserver、系统App),ATMS就是 SYSTEM_UID
符合以上条件调用 Zygote.forkAndSpecialize,这个和以前也不一样了
*/
| if (parsedArgs.mInvokeWith != null || parsedArgs.mStartChildZygote || !multipleOK || peer.getUid() != Process.SYSTEM_UID)
| pid = Zygote.forkAndSpecialize(...); // 以前用这个,现在不用了
|else // 通常情况是走 else 分支,调用 Zygote.forkSimpleApps
Runnable result = Zygote.forkSimpleApps(...);
|-->static @Nullable Runnable forkSimpleApps(...);
| boolean in_child = argBuffer.forkRepeatedly(...);
| return nativeForkRepeatedly(...);
| com_android_internal_os_ZygoteCommandBuffer_nativeForkRepeatedly(...);
| NativeCommandBuffer.readAllLines;
| int pid = zygote::forkApp(...); // fd 的处理
| zygote::ForkCommon(...);
| pid_t pid = fork(); // 真正fork进程的地方
//处于子进程时,pid=0,处理分配内存的设置等等
| return pid;
|//如果pid为0,处于子进程,return true;
| if (in_child) // 如果是子进程,调用 childMain
| return childMain(argBuffer, /*usapPoolSocket=*/null, /*writePipe=*/null);
|else// 如果是 Zygote 进程,return null;
|// 子进程返回时,result不为null,return result;
子进程调用 Zygote.childMain
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
java复制代码// frameworks/base/core/java/com/android/internal/os/Zygote.java
Zygote.forkSimpleApps(...);
| childMain(argBuffer, /*usapPoolSocket=*/null, /*writePipe=*/null);
|-->private static Runnable childMain(ZygoteCommandBuffer argBuffer,LocalServerSocket usapPoolSocket,FileDescriptor writePipe);
| specializeAppProcess(...);
| nativeSpecializeAppProcess(...);
| com_android_internal_os_Zygote_nativeSpecializeAppProcess();
// 设置命名空间的存储目录挂载
// 设置调度策略,selinux,调试模式,SetGids,内存分配模式 等等
| SpecializeCommon(...);
| Thread.currentThread().setPriority(Thread.NORM_PRIORITY); //设置进程优先级
| return ZygoteInit.zygoteInit(args.mTargetSdkVersion,args.mDisabledCompatChanges,args.mRemainingArgs,null);
| RuntimeInit.commonInit();
// 设置异常处理
| RuntimeHooks.setUncaughtExceptionPreHandler(loggingHandler);
| Thread.setDefaultUncaughtExceptionHandler(new KillApplicationHandler(loggingHandler));
| ZygoteInit.nativeZygoteInit(); // 开启 binder 消息监听
|--> com_android_internal_os_ZygoteInit_nativeZygoteInit
|--> gCurRuntime->onZygoteInit();
|--> frameworks/base/cmds/app_process/app_main.cpp
|--> onZygoteInit();
| sp<ProcessState> proc = ProcessState::self();
| proc->startThreadPool();
| return RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv, classLoader);
| return findStaticMain(args.startClass, args.startArgs, classLoader);
| return new MethodAndArgsCaller(m, argv); // MethodAndArgsCaller 是个 Runnable, [见:附]

// 层层 return 回退到 ZygoteInit.main,通过 MethodAndArgsCaller.run 调用 android.app.ActivityThread.main

// 附:MethodAndArgsCaller
static class MethodAndArgsCaller implements Runnable {
//...
public void run() {
mMethod.invoke(null, new Object[] { mArgs })
}
}

三、android.app.ActivityThread.main

1、ActivityThread.main 到 AMS 流程

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
java复制代码ActivityThread.main
// 1.创建主线程的 Looper 对象。 main函数最后调用 Looper.loop();启动无线循环。
| Looper.prepareMainLooper();
// 2.创建 ActivityThread 对象
| ActivityThread thread = new ActivityThread();
// 在类成员中直接创建 ApplicationThread,ApplicationThread 继承 IApplicationThread.Stub
// IApplicationThread 是 APP 同 AMS 交互的接口
| final ApplicationThread mAppThread = new ApplicationThread();
// 3. 调用 ActivityThread .attach 方法
| thread.attach(false, startSeq);
| final IActivityManager mgr = ActivityManager.getService();
// mAppThread 是 ApplicationThread
// 通过binder调用AMS的attachApplication接口将 ApplicationThread 注册到AMS中
| mgr.attachApplication(mAppThread, startSeq);
// 进入systemserver进程 的 AMS
| AMS.attachApplicationLocked //直接转到 attachApplicationLocked
| ProcessRecord app;
| 【1】thread.bindApplication(...); //binder跨进程 回调 ApplicationThread bindApplication
// bindApplication流程:
/*app进程 ApplicationThread .handleBindApplication
Dex文件的加载和Resource资源的加载
创建应用的LoadedApk对象、创建Application的Context
加载应用APK的Dex文件到内存中,加载APK的Resource资源
调用LoadedApk.makeApplication函数,创建应用的Application对象
执行应用 Application.onCreate 生命周期函数*/
// 设置 ProcessRecord.mThread = IApplicationThread(thread)
// 设置 ProcessRecord.mWindowProcessController.mThread = IApplicationThread(thread)
| app.makeActive(thread, mProcessStats);
//启动应用 Activity的 流程
| 【2】mAtmInternal.attachApplication(app.getWindowProcessController());
| mRootWindowContainer.attachApplication(wpc);
| RootWindowContainer::startActivityForAttachedApplicationIfNeeded//这里Android 13 版本有些变化
| mStackSupervisor.realStartActivityLocked(ActivityRecord r,WindowProcessController proc,boolean andResume,...)
| r.startFreezingScreenLocked(proc, 0); // 冻结屏幕
| r.setProcess(proc); // ActivityRecord 关联 WindowProcessController
// 创建 ClientTransaction
// ClientTransaction.mClient = WindowProcessController.getThread() 是 App 端的 ApplicationThread
// 使用 ActivityRecord.token 赋值 ClientTransaction.mActivityToken
// ClientTransaction.mActivityToken 会传入 客户端app进程
// 注:Android12 用的 ActivityRecord.appToken, Android 12 ActivityRecord.appToken=ActivityRecord.token
| final ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.token);
// 添加 LaunchActivityItem 回调,App进程会执行其execute方法,内部执行 handleLaunchActivity
| clientTransaction.addCallback(LaunchActivityItem.obtain(...))
| lifecycleItem = ResumeActivityItem.obtain(isTransitionForward, r.shouldSendCompatFakeFocus());
// App进程会执行 ResumeActivityItem.execute方法 ,内部调用 handleResumeActivity
| clientTransaction.setLifecycleStateRequest(lifecycleItem);
// 传递Launch和Resume生命周期事务
| mService.getLifecycleManager().scheduleTransaction(clientTransaction);
// 4. 启动loop无线循环
| Looper.loop();

2、scheduleTransaction 跨进程调用,把事务传递到 APP进程

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
java复制代码ClientLifecycleManager.scheduleTransaction(ClientTransaction transaction);
| transaction.schedule();
|-->ClientTransaction.schedule();
// IApplicationThread mClient;
| mClient.scheduleTransaction(this) //ApplicationThread 继承 IApplicationThread
|-->ApplicationThread.scheduleTransaction(ClientTransaction transaction);
| ActivityThread.this.scheduleTransaction(transaction);
// ActivityThread.scheduleTransaction 继承 ClientTransactionHandler.scheduleTransaction
|-->ClientTransactionHandler.scheduleTransaction(ClientTransaction transaction);
// 调用 LaunchActivityItem.preExecute 预处理工作
| transaction.preExecute(this);
| sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); //post到主线程去处理
|-->ActivityThread.H.handleMessage(Message msg);
| mTransactionExecutor.execute(transaction);
| executeCallbacks(transaction);
// 取出 ClientTransaction.mActivityToken 作为参数传入 LaunchActivityItem.execute
| final IBinder token = transaction.getActivityToken();
// 这个 token = ActivityRecord.appToken
| LaunchActivityItem.execute(ClientTransactionHandler client, IBinder token,...);
// 创建 ActivityClientRecord ActivityClientRecord.token = token;
// Android 12 是在 preExecute 中创建,Android 13 变更到了execute 中
| ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,...);
// 执行 ActivityThread.handleLaunchActivity
| client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
| executeLifecycleState(transaction);
| ResumeActivityItem.execute(ClientTransactionHandler client, ActivityClientRecord r,...);
// 执行 ActivityThread.handleResumeActivity
| client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,...);

ActivityClientRecord.token = ClientTransaction.mActivityToken = ActivityRecord.token

经过一系列的 事务,生命周期管理相关的代码后 调用 handleLaunchActivity 和 handleResumeActivity

3、handleLaunchActivity

  • 执行 Launch 生命周期
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
java复制代码//	frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);

// frameworks/base/core/java/android/app/ActivityThread.java
ActivityThread.handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent);
| performLaunchActivity(ActivityClientRecord r, Intent customIntent)
// 1.创建Activity的Context,Activity虽然也是Context,但是其真正的Context是Activity.mBase 成员
| ContextImpl appContext = createBaseContextForActivity(r);
// 2.调用 mInstrumentation.newActivity,通过反射创建Activity
| java.lang.ClassLoader cl = appContext.getClassLoader();
| activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent);
// 把 ActivityClientRecord 存入 mActivities
// ActivityClientRecord.activity 存储 Activity 对象
| mActivities.put(r.token, r);
// 3.调用 activity.attach 方法
| activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo,...);
// 把 performLaunchActivity 创建的 context 设置到 Activity.mBase
| attachBaseContext(context);
// 创建 PhoneWindow 对象
| mWindow = new PhoneWindow(this, window, activityConfigCallback);
| mWindowAttributes = new WindowManager.LayoutParams();
// 这个 type 在后边 Window.adjustLayoutParamsForSubWindow 会用到
| type = TYPE_APPLICATION;
// 设置Activity key dispatching, panels and menus 等回调。用于拦截点击触摸事件等等
| mWindow.setCallback(this);
//至此:
// activity.mToken = ActivityClientRecord.token = ClientTransaction.mActivityToken = ActivityRecord.token
| mToken = token;
| mApplication = application;
// 给 PhoneWindow 对象,设置 WindowManager 对象
| mWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE), mToken, ...);
// SystemServiceRegistry 静态代码中创建 getSystemService 接口的 WindowManager 实例:
| new WindowManagerImpl(ctx);
// SystemServiceRegistry 创建的WindowManagerImpl的成员 mParentWindow=null; mWindowContextToken=null;
| this(context, null /* parentWindow */, null /* clientToken */);
|-->Window.setWindowManager(WindowManager wm, IBinder appToken, String appName,boolean hardwareAccelerated);
//至此:
//PhoneWindow.mAppToken=activity.mToken = ActivityClientRecord.token = ClientTransaction.mActivityToken = ActivityRecord.token
| mAppToken = appToken;
| mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);// 参数传入 PhoneWindow
|-->WindowManagerImpl createLocalWindowManager(Window parentWindow)
| return new WindowManagerImpl(mContext, parentWindow, mWindowContextToken);
| mContext = context;
| mParentWindow = parentWindow; // 这个传入的是 PhoneWindow
| mWindowContextToken = windowContextToken; // 这个是 null
| 这个 mWindowManager 对象时new的 WindowManagerImpl
// 也就是说Activity中的 mWindowManager 对象,获取的window管理器是 WindowManagerImpl
| mWindowManager = mWindow.getWindowManager();
| r.activity = activity; // ActivityClientRecord 关联 activity
// 4.Instrumentation.callActivityOnCreate--->Activity.onCreate
| mInstrumentation.callActivityOnCreate
// 执行Activity的onCreate生命周期函数
// 在 setContentView 调用installDecor创建 DecorView 对象
// 并设置 DecorView 的window对象为 PhoneWindow
| Activity.performCreate
| Activity.onCreate
| Activity.setContentView(R.layout.activity_main);
| getWindow().setContentView
| PhoneWindow.installDecor()
| mDecor = generateDecor(-1);
| return new DecorView(context, featureId, this, getAttributes());
|-->DecorView(Context context,..., PhoneWindow window,WindowManager.LayoutParams params)
| setWindow(window);
| mWindow = window; //PhoneWindow;

4、handleResumeActivity

  • 执行Resume生命周期
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
java复制代码//	frameworks/base/core/java/android/app/servertransaction/ResumeActivityItem.java
client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward, mShouldSendCompatFakeFocus, "RESUME_ACTIVITY");

// frameworks/base/core/java/android/app/ActivityThread.java
// 执行应用Activity的onResume生命周期函数
ActivityThread.handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,boolean isForward, ...)
| performResumeActivity(r, finalStateRequest, reason);
| 执行应用Activity的onResume生命周期函数
| r.activity.performResume(r.startsNotResumed, reason);
| mInstrumentation.callActivityOnResume(this);
| activity.onResume();
// handleResumeActivity中执行完毕performResumeActivity后,继续执行以下代码:
| final Activity a = r.activity;
| r.window = r.activity.getWindow(); // 赋值 ActivityClientRecord.window
| View decor = r.window.getDecorView();
| decor.setVisibility(View.INVISIBLE);
| ViewManager wm = a.getWindowManager(); //activity.attach 中创建的 WindowManagerImpl 对象
// 返回的是 Window.mWindowAttributes,即 l = PhoneWindow.mWindowAttributes
| WindowManager.LayoutParams l = r.window.getAttributes();
| wm.addView(decor, l);
|-->WindowManagerImpl.addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params)
| applyTokens(params); // 这里虽然看上去是设置 WindowManager.LayoutParams.token 但分析下来不是,还要在后边
| final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
| if(mDefaultToken != null ) wparams.token = mDefaultToken; // 不进这个流程
| wparams.mWindowContextToken = mWindowContextToken; // 目前为止还是 null
| mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow, mContext.getUserId());
|-->WindowManagerGlobal.addView(View view, ViewGroup.LayoutParams params, Window parentWindow, ...)
| final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
// 设置 WindowManager.LayoutParams 的 token、title、packageName、flags 属性
| parentWindow.adjustLayoutParamsForSubWindow(wparams);
|-->Window.adjustLayoutParamsForSubWindow(WindowManager.LayoutParams wp)
// wp.type = TYPE_APPLICATION =2; 如果是startingwindow,这里 wp.type = 3 (startingwindow的flag)
| wp.token = mContainer == null ? mAppToken : mContainer.mAppToken;
// 因为 mContainer 是 null, 所以 wp.token = mAppToken
/*至此:
PhoneWindow.mAppToken = activity.mToken = ActivityClientRecord.token = ClientTransaction.mActivityToken = ActivityRecord.token
PhoneWindow.mWindowAttributes.token = PhoneWindow.mAppToken */
| ViewRootImpl root = new ViewRootImpl(view.getContext(), display); //创建ViewRootImpl对象
// ViewRootImpl构造函数
|-->ViewRootImpl(Context context, Display display);
| 构造函数中创建IWindowSession 对象,用于同 wms 通信
| this(context, display, WindowManagerGlobal.getWindowSession(), false /* useSfChoreographer */);
| private static IWindowSession sWindowSession = windowManager.openSession(...)
| mWindowSession = sWindowSession
// W extends IWindow.Stub ,作为参数传递给WMS,用于同 WMS 通信
| mWindow = new W(this);
| 创建 Choreographer 对象
| mChoreographer = useSfChoreographer ? Choreographer.getSfInstance() : Choreographer.getInstance();
| mChoreographer = Choreographer.getInstance();//以上代码简写
|
| view.setLayoutParams(wparams);
| mViews.add(view);
| mRoots.add(root);
| mParams.add(wparams);
// 来到关键点 ViewRootImpl.setview
| root.setView(view, wparams, panelParentView, userId);

setview之后看surface创建流程

四、ViewRootImpl 注册vsync回调

注册vsync回调流程:Choreographer

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
java复制代码WindowManagerGlobal:: mGlobal.addView
| ViewRootImpl root = new ViewRootImpl(view.getContext(), display); //创建ViewRootImpl对象
| 构造函数中创建 IWindowSession 对象,用于同 wms 通信
| this(context, display, WindowManagerGlobal.getWindowSession(), false /* useSfChoreographer */);
| private static IWindowSession sWindowSession = windowManager.openSession(...)
| mWindowSession = sWindowSession;
| 创建 Choreographer 对象
| mChoreographer = useSfChoreographer ? Choreographer.getSfInstance() : Choreographer.getInstance();
// 以上代码简写:
| mChoreographer = Choreographer.getInstance();
|-->Choreographer::Choreographer getInstance();
// 获取当前线程的 Choreographer,如果当前线程没有,就调用ThreadLocal.initialValue()创建一个新的 Choreographer
| return sThreadInstance.get();
| ThreadLocal.initialValue();
| Looper looper = Looper.myLooper();
| return new Choreographer(looper, VSYNC_SOURCE_APP); // VSYNC_SOURCE_APP = 0;
// Choreographer 构造函数:
| Choreographer(Looper looper, int vsyncSource)
| mLooper = looper;
| mHandler = new FrameHandler(looper);
// 创建 FrameDisplayEventReceiver,内部创建 IDisplayEventConnection,并创建vsync的通信socket
| mDisplayEventReceiver = new FrameDisplayEventReceiver(looper, vsyncSource);
| mFrameIntervalNanos = (long)(1000000000 / getRefreshRate());
// CALLBACK_LAST = 4
| mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];
// 创建 5 个CallbackQueue
| for (int i = 0; i <= CALLBACK_LAST; i++)
| mCallbackQueues[i] = new CallbackQueue();

注册vsync回调流程:EventThread

Choreographer 构造函数创建 FrameDisplayEventReceiver 时,会创建同SurfaceFlinger的EventThread线程通信的 IDisplayEventConnection

IDisplayEventConnection定义了以下接口:

  • void stealReceiveChannel(out BitTube outChannel);获取socket通信管道
  • void setVsyncRate(in int count); 设置vsync分发速率。0,不调用requestNextVsync不分发;1,每次vsync事件都分发;其他,每N个vsync事件分发一次
    • 系统默认为 0 ,不调用requestNextVsync不分发
  • oneway void requestNextVsync(); 请求vsync
  • ParcelableVsyncEventData getLatestVsyncEventData(); 获取最新的

获取到 IDisplayEventConnection 后,会立刻调用 stealReceiveChannel 获取socket通信管道

从 FrameDisplayEventReceiver 构造函数开始:

注册vsync回调流程:APP进程端
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
c++复制代码Choreographer choreographer = new Choreographer(Looper.myLooper(), VSYNC_SOURCE_APP);
| // Choreographer 构造函数中 new FrameDisplayEventReceiver
| mDisplayEventReceiver = new FrameDisplayEventReceiver(looper, vsyncSource);

// FrameDisplayEventReceiver 构造函数:
//参数 looper:当前线程的looper; vsyncSource = VSYNC_SOURCE_APP =0;
FrameDisplayEventReceiver(Looper looper, int vsyncSource);
| super(looper, vsyncSource, 0);
// FrameDisplayEventReceiver 继承 DisplayEventReceiver
| DisplayEventReceiver(Looper looper, int vsyncSource, int eventRegistration);
| mMessageQueue = looper.getQueue();
// 创建 NativeDisplayEventReceiver,把对象地址存储到java层的 DisplayEventReceiver.mReceiverPtr 中
| mReceiverPtr = nativeInit(this, mMessageQueue,vsyncSource, eventRegistration);
// frameworks/base/core/jni/android_view_DisplayEventReceiver.cpp
| nativeInit(..., jobject receiverWeak, jobject messageQueueObj,jint vsyncSource, jint eventRegistration)
| sp<NativeDisplayEventReceiver> receiver =
| new NativeDisplayEventReceiver(env, receiverWeak, messageQueue, vsyncSource, eventRegistration);
// NativeDisplayEventReceiver 构造函数继续调用父类 DisplayEventDispatcher 的构造函数
// DisplayEventDispatcher 构造函数中创建成员变量 DisplayEventReceiver mReceiver(vsyncSource, eventRegistration)
// DisplayEventReceiver 构造函数:
// frameworks/native/libs/gui/DisplayEventReceiver.cpp
| DisplayEventReceiver(ISurfaceComposer::VsyncSource vsyncSource,EventRegistrationFlags eventRegistration)
// 获取 SurfaceFlinger 服务
| sp<ISurfaceComposer> sf(ComposerService::getComposerService());
// 获取 IDisplayEventConnection 存储到成员变量 mEventConnection
| mEventConnection = sf->createDisplayEventConnection(vsyncSource, eventRegistration);
//进入 BpSurfaceComposer.createDisplayEventConnection 开始binder通信
|-->createDisplayEventConnection(VsyncSource vsyncSource, EventRegistrationFlags eventRegistration)
// 【见 “SurfaceFlinger进程端注册vsync流程” 章节】
| remote()->transact(BnSurfaceComposer::CREATE_DISPLAY_EVENT_CONNECTION,data, &reply);
| result = interface_cast<IDisplayEventConnection>(reply.readStrongBinder());
| return result;
| mDataChannel = std::make_unique<gui::BitTube>();
// 获取进程间通讯 socket 管道,封装到 BitTube 中,存储到成员变量 mDataChannel
// 【详情,见 “SurfaceFlinger进程端注册vsync流程” 章节】
| mEventConnection->stealReceiveChannel(mDataChannel.get());
| receiver->initialize();
| DisplayEventDispatcher.initialize()
// 把 socket 加入
| mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT, this, NULL);
| receiver->incStrong(gDisplayEventReceiverClassInfo.clazz);
| return reinterpret_cast<jlong>(receiver.get());
注册vsync回调流程:SurfaceFlinger 进程端

BpSurfaceComposer.createDisplayEventConnection 跨进程进入 SurfaceFlinger 端

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
c++复制代码//	frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
// 参数vsyncSource = VSYNC_SOURCE_APP = 0; eventRegistration = 0
SurfaceFlinger.createDisplayEventConnection(ISurfaceComposer::VsyncSource vsyncSource,EventRegistrationFlags eventRegistration);
| // eVsyncSourceSurfaceFlinger = 1
| // handle = mAppConnectionHandle
| const auto& handle = vsyncSource == eVsyncSourceSurfaceFlinger ? mSfConnectionHandle : mAppConnectionHandle;
| return mScheduler->createDisplayEventConnection(handle, eventRegistration);
|-->Scheduler.createDisplayEventConnection(ConnectionHandle handle, ISurfaceComposer::EventRegistrationFlags eventRegistration)
// std::unordered_map<ConnectionHandle, Connection> mConnections;
// mConnections 存储的 Connection 是个结构体。仅含有两个成员变量 EventThreadConnection 和 EventThread [参见:附]
// mConnections[handle].thread.get() 获取 SurfaceFlinger.mAppConnectionHandle 对应的 EventThread, App的EventThread线程
| return createConnectionInternal(mConnections[handle].thread.get(), eventRegistration);
|-->Scheduler.createConnectionInternal( EventThread* eventThread, EventRegistrationFlags eventRegistration)
| return eventThread->createEventConnection([&] { resync(); }, eventRegistration);
|-->EventThread.createEventConnection(ResyncCallback resyncCallback, EventRegistrationFlags eventRegistration)
// EventThreadConnection 继承 IDisplayEventConnection ,返回APP的IDisplayEventConnection 就是 EventThreadConnection
| return new EventThreadConnection(this,IPCThreadState::self()->getCallingUid(),resyncCallback,eventRegistration)
// EventThreadConnection 构造函数:
|-->EventThreadConnection(EventThread* eventThread, uid_t callingUid, ResyncCallback resyncCallback,...)
| : resyncCallback(std::move(resyncCallback)),
| mOwnerUid(callingUid),
| mEventRegistration(eventRegistration),
| mEventThread(eventThread),
// 创建 BitTube,BitTube 构造函数中创建 socketpair
| mChannel(gui::BitTube::DefaultSize){}
// BitTube 构造函数
| BitTube::BitTube(size_t bufsize)
| init(bufsize, bufsize);
| int sockets[2];
| socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets); // 创建 socketpair
| mReceiveFd.reset(sockets[0]); // sockets[0] 赋值给 mReceiveFd ,未来会发送到 APP 进程端
| mSendFd.reset(sockets[1]);
// EventThreadConnection 创建完成后,首次 sp 指针引用时调用 onFirstRef()
| EventThreadConnection.onFirstRef();
// 注册 vsync 回调
| mEventThread->registerDisplayEventConnection(this);
|-->EventThread::registerDisplayEventConnection(const sp<EventThreadConnection>& connection);
| // 加入vector集合 mDisplayEventConnections
| // 这个集合 mDisplayEventConnection 会在 EventThread::threadMain 循环遍历
| mDisplayEventConnections.push_back(connection);
| mCondition.notify_all();



// App进程端获取到 IDisplayEventConnection 后,立即就调用了stealReceiveChannel 接口获取 socket fd:
|-->EventThreadConnection::stealReceiveChannel(gui::BitTube* outChannel)
// 把构造EventThreadConnection时,创建的 socketpair的fd 写到APP进程的 BitTube 中
| outChannel->setReceiveFd(mChannel.moveReceiveFd());
| outChannel->setSendFd(base::unique_fd(dup(mChannel.getSendFd())));


// 附: Scheduler.Connection 结构体
struct Connection {
sp<EventThreadConnection> connection;
std::unique_ptr<EventThread> thread;
};

五、ViewRootImpl.setView

  1. 注册 vsync 回调 IDisplayEventConnection

  2. ViewRootImpl.setView 函数中调用 requestLayout 请求vsync流程

  3. ViewRootImpl.setView 函数中调用 WindowSession.

    addToDisplayAsUser

    ​ **创建 ISurfaceComposerClient **

    • addToDisplayAsUser 还有个功能是 创建 InputChannel

​ 传入一个null的 inputChannel 对象到 addToDisplayAsUser,这个 inputChannel ,在wms端创建,并赋值到inputChannel ,实际就是 socketpair

  1. vsync回调回来后 调用ViewRootImpl.**relayoutWindow 创建 Surface **

ViewRootImpl.requestLayout 请求vsync流程

衔接第三章的 setView

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
java复制代码//	frameworks/base/core/java/android/view/WindowManagerGlobal.java
root.setView(view, wparams, panelParentView, userId); // 调用ViewRootImpl 的setview方法 关键方法

// frameworks/base/core/java/android/view/ViewRootImpl.java
ViewRootImpl.setView(View view, WindowManager.LayoutParams attrs, View panelParentView)
//【一】、请求vsync:
| requestLayout(); //请求vsync ,vsync回调后,开启界面绘制流程======!!!!!!!!!!!!!**
| scheduleTraversals();
| mChoreographer.postCallback(Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
|-->Choreographer.postCallback(int callbackType, Runnable action, Object token)
| postCallbackDelayed(callbackType, action, token, 0);
| postCallbackDelayedInternal(callbackType, action, token, delayMillis);
// 这里把 mTraversalRunnable 加入到 mCallbackQueues 数组
| mCallbackQueues[callbackType].**addCallbackLocked**(dueTime, action, token);
| scheduleFrameLocked
| scheduleVsyncLocked();
| mDisplayEventReceiver.scheduleVsync();
|-->DisplayEventReceiver.scheduleVsync();
| nativeScheduleVsync(mReceiverPtr);
// android_view_DisplayEventReceiver.cpp
| nativeScheduleVsync()
// DisplayEventDispatcher.cpp
| scheduleVsync()
//IDisplayEventConnection mEventConnection=sf->createDisplayEventConnection
| mReceiver.requestNextVsync();
// 之后跨进程调用到 SurfaceFlinger 的 requestNextVsync 方法
| DisplayEventReceiver.cpp--requestNextVsync();
| mEventConnection->requestNextVsync();
| EventThreadConnection::requestNextVsync()
| EventThread::requestNextVsync(const sp<EventThreadConnection>& connection)
| mCondition.notify_all();//唤醒 app EventThread 线程
//sf 启动后 EventThread 线程会在 threadMain 循环
| EventThread::threadMain(std::unique_lock<std::mutex>& lock)
| mCondition.wait(lock);// 从阻塞中唤醒
| mVSyncSource->setVSyncEnabled(true);
| DispSyncSource::setVSyncEnabled(bool enable)
| 又经过很多代码,最终:
| VSyncDispatchTimerQueue::setTimer(nsecs_t targetTime, nsecs_t /*now*/)
| Timer::alarmAt(std::function<void()> const& cb, nsecs_t time)
| 最终的最终调用“系统调用”,timerfd_settime 设置定时发送vsync
| timerfd_settime(mTimerFd, TFD_TIMER_ABSTIME, &new_timer, &old_timer)

| 之后就是异步代码了,之后很快就启动了vsync,之后vsync事件回调app进程的doFrame方法

IWindowSession.addToDisplayAsUser–>WMS.addWindow

  • 1、创建 WindowState
  • 2、创建 InputChannel
  • 3、创建同 SurfaceFlinger 的连接 ISurfaceComposerClient
  • 4、更新焦点
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
java复制代码root.setView(view, wparams, panelParentView, userId);

// frameworks/base/core/java/android/view/ViewRootImpl.java
ViewRootImpl.setView(View view, WindowManager.LayoutParams attrs, View panelParentView);
| mView = view; // 把 DecorView 存储到 mView
// 把 WindowManagerGlobal.addView 设置过 token 的wparams数据复制到 mWindowAttributes
| mWindowAttributes.copyFrom(attrs);
/*至此:
WindowToken.token 是 IBinder 类
ActivityRecord 继承 WindowToken
ActivityRecord 有个内部类 ActivityRecord.Token 继承 Binder
ActivityRecord.token 这个成员继承自 WindowToken,是内部类 ActivityRecord.Token 的实例

PhoneWindow.mAppToken = activity.mToken = ActivityClientRecord.token = ClientTransaction.mActivityToken = ActivityRecord.token
ViewRootImpl.mWindowAttributes.mToken = PhoneWindow.mWindowAttributes.token = PhoneWindow.mAppToken
*/
// 加入 PRIVATE_FLAG_USE_BLAST flag,这个flag在创建 SurfaceControl 时会用到
| mWindowAttributes.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST;
// 【一】、请求vsync
| requestLayout();
| InputChannel inputChannel = null; // 一个null的inputChannel,传递到WMS端赋值
// 【二】、创建 ISurfaceComposerClient
// mWindow 参数为 [W extends IWindow.Stub],作为参数传递给WMS,用于同 WMS 通信
| mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes..., userId,..., inputChannel, mTempInsets,...)
// 参数 attrs.token = ActivityRecord.token
|-->WindowManagerService.mService.addWindow(this, window, attrs, viewVisibility, displayId, userId, equestedVisibility, outInputChannel, outInsetsState, outActiveControls);
// 【1】、从 DisplayContent.mTokenMap 中检索token
// 在 setNewTask 时,以ActivityRecord.token为键,已经把ActivityRecord加入了DisplayContent.mTokenMap
// 所以能取到 token, 这个token不为 null
| WindowToken token = displayContent.getWindowToken(hasParent ? parentWindow.mAttrs.token : attrs.token);
// 如果 token为null,这里会走创建token流程:
// binder 为 ViewRootImpl.mWindowAttributes.mToken = ActivityRecord.token
| final IBinder binder = attrs.token != null ? attrs.token : client.asBinder();
// WindowToken 构造函数中,传入的 DisplayContent 参数不为null时,加入 DisplayContent.mTokenMap
| token = new WindowToken.Builder(this, binder, type).setDisplayContent(displayContent)....build();
| // WindowToken 构造函数:
| WindowToken(WindowManagerService service, IBinder _token, int type...DisplayContent dc,...)
| token = _token;
| if (dc != null) dc.addWindowToken(token, this); // 加入 DisplayContent.mTokenMap
// 【2】、创建 WindowState
| WindowState win = new WindowState(this, session, client, token, parentWindow, appOp[0], attrs, viewVisibility, session.mUid, userId, session.mCanAddInternalSystemWindow);
// WindowState构造函数
|-->WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,WindowState parentWindow...)
| mSession = s;
| mClient = c;
| mToken = token;
/*至此:
PhoneWindow.mAppToken = activity.mToken = ActivityClientRecord.token = ClientTransaction.mActivityToken = ActivityRecord.token
参数attrs.token = ViewRootImpl.mWindowAttributes.mToken = PhoneWindow.mWindowAttributes.token = PhoneWindow.mAppToken
WindowState.mToken = ActivityRecord */
| mActivityRecord = mToken.asActivityRecord(); // 把token转为 ActivityRecord
| InputApplicationHandle tempIAHandle = mActivityRecord.getInputApplicationHandle(false);
|-->ActivityRecord.getInputApplicationHandle(boolean update);
| | mInputApplicationHandle = new InputApplicationHandle(token, toString(),mInputDispatchingTimeoutMillis);
| // InputApplicationHandle 构造函数:
| |-->InputApplicationHandle(@NonNull IBinder token, @NonNull String name,long dispatchingTimeoutMillis);
| | this.token = token;
| | return mInputApplicationHandle;
| //创建 InputWindowHandleWrapper,包装为InputWindowHandle,用于输入输出,焦点更新等等,是wms,SurfaceFlinger,input 传递数据的对象
| mInputWindowHandle = new InputWindowHandleWrapper(new InputWindowHandle(tempIAHandle, getDisplayId()))
| // InputWindowHandle 构造函数:
| |-->InputWindowHandle(InputApplicationHandle inputApplicationHandle, int displayId);
| | this.inputApplicationHandle = inputApplicationHandle;
| // InputWindowHandleWrapper 构造函数:
| |-->InputWindowHandleWrapper(@NonNull InputWindowHandle handle);
| // WindowState.mInputWindowHandle.mHandle 为InputWindowHandle对象,这个对象会传到 SurfaceFlinger
| // WindowState.mInputWindowHandle.mHandle.inputApplicationHandle.token = ActivityRecord.token
| | mHandle = handle;
| mWinAnimator = new WindowStateAnimator(this);// 创建 WindowStateAnimator
// 【3】、InputChannel 创建流程:
| win.openInputChannel(outInputChannel);
|-->WindowState.openInputChannel(InputChannel outInputChannel);
| mInputChannel = mWmService.mInputManager.createInputChannel(name);
|-->InputManagerService.createInputChannel(String name);
|-->NativeInputManagerService.createInputChannel(String name);
|-->nativeCreateInputChannel(JNIEnv* env, jobject nativeImplObj, jstring nameObj);
|-->NativeInputManager.createInputChannel(const std::string& name);
|-->InputDispatcher::createInputChannel(const std::string& name);
| std::unique_ptr<InputChannel> serverChannel;
| std::unique_ptr<InputChannel> clientChannel;
// 1、创建 socketpair
| InputChannel::openInputChannelPair(name, serverChannel, clientChannel);
|-->InputChannel::openInputChannelPair(...InputChannel outServerChannel,outClientChannel)
| int sockets[2];
| socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sockets);// 创建 socketpair
| sp<IBinder> token = new BBinder(); // 创建token
| std::string serverChannelName = name + " (server)";
| outServerChannel = InputChannel::create(serverChannelName, sockets[0], token);
| std::string clientChannelName = name + " (client)";
| outClientChannel = InputChannel::create(clientChannelName, sockets[1], token);
// 获取InputChannel.mToken, 这个 token = new BBinder();
| const sp<IBinder>& token = serverChannel->getConnectionToken();
// 2、使用 serverChannel 创建 connection
| sp<Connection> connection = new Connection(std::move(serverChannel), false , ...);
// 以token为键,把 connection 加入 mConnectionsByToken
// serverChannel 和 clientChannel 共用一个token,用来寻找彼此
// 服务端加入mConnectionsByToken,一个返回到WMS,WMS再返回给App
| mConnectionsByToken.emplace(token, connection);
// 3、服务端的 socket fd 加入 epoll 监听
| int fd = serverChannel->getFd();
| mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, new LooperEventCallback(callback), nullptr);
| mLooper->wake();
| return clientChannel; // 返回客户端的 InputChannel
| mInputChannelToken = mInputChannel.getToken(); // 获取 native 创建的 token
// mInputWindowHandle.
| mInputWindowHandle.setToken(mInputChannelToken);
// WindowState.InputWindowHandleWrapper.InputWindowHandle.token = native层创建的 token
// InputWindowHandle.token 这个token 很重要,是 SurfaceFlinger,input 沟通用的令牌,比如焦点更新
// InputWindowHandle.InputApplicationHandle.token = ActivityRecord.token
// wms会透过 SurfaceTransition 把InputWindowHandle传递给 SurfaceFlinger 的 Layer.mDrawingState.inputInfo
// 到这里 Inputms,wms,ams, SurfaceFlinger 就这么连接起来了。
| mHandle.token = token;
// 以 mInputChannelToken 为键,把 WindowState 存入WMS的 HashMap
| mWmService.mInputToWindowMap.put(mInputChannelToken, this);
// 把 native 层创建的客户端InputChannel返回给 APP
| mInputChannel.copyTo(outInputChannel);
| res = ADD_OKAY;
| // mUseBLAST = (settings get global use_blast_adapter_vr == 1)
| // global settings 中没有设置这个 use_blast_adapter_vr 值的话,默认值为 true
| if (mUseBLAST) res |= WindowManagerGlobal.ADD_FLAG_USE_BLAST;
// 【4】、 创建 SurfaceSession---> 创建SurfaceFlinger的客户端 ISurfaceComposerClient
| win.attach();
| mSession.windowAddedLocked();
//WindowState.mSession.mSurfaceSession.mNativeClient.mClient保存了用于SurfaceFlinger通信的 ISurfaceComposerClient
| Session.mSurfaceSession = new SurfaceSession();
// SurfaceSession 内容很少,大概60行的代码。就是个 Native 的Java包装类
// SurfaceSession.mNativeClient 是个 SurfaceComposerClient 类
// SurfaceComposerClient.mClient 成员是个 ISurfaceComposerClient, 用于SurfaceFlinger通信
| SurfaceSession.mNativeClient = nativeCreate();
// android_view_SurfaceSession.cpp
| android_view_SurfaceSession.nativeCreate
| SurfaceComposerClient* client = new SurfaceComposerClient();
// sp指针引用会调用 SurfaceComposerClient::onFirstRef()
| client->incStrong((void*)nativeCreate);
| SurfaceComposerClient::onFirstRef()
| sp<ISurfaceComposer> sf(ComposerService::getComposerService());
// SurfaceComposerClient.mClient 是 ISurfaceComposerClient
| mClient = sf->createConnection();
| return client;

// 以 IWindow 为键,把 WindowState 加入到 mWindowMap
| mWindowMap.put(client.asBinder(), win);
// 把 WindowState 加入到 ActivityRecord.token ,成为其子节点
// ActivityRecord.mSurfaceControl 和 WindowState.mSurfaceControl 应该都会创建。
// 这个流程会创建 WindowState.mSurfaceControl,继承的父类 WindowToken.mSurfaceControl
// TODO: 这里的代码应该没这么简单,具体流程待研究。创建SurfaceControl,意味着创建Layer。这里应该是创建 ContainerLayer 和 EffectLayer 相关
| win.mToken.addWindow(win);
|-->WindowToken.addWindow(final WindowState win)
| if (mSurfaceControl == null)
| createSurfaceControl(true /* force */);
// 更新焦点
| updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,false /*updateInputWindows*/);

六、vsync 回调

1、SurfaceFlinger进程端: vsync 事件分发

这里简单写写吧

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
c++复制代码EventThread::onVSyncEvent(nsecs_t timestamp, VSyncSource::VSyncData vsyncData)
| mPendingEvents.push_back(makeVSync(mVSyncState->displayId, timestamp, ++mVSyncState->count,...);
| mCondition.notify_all(); // 唤醒 EventThread::threadMain 处wait代码

EventThread::threadMain(std::unique_lock<std::mutex>& lock)
| std::vector<sp<EventThreadConnection>> consumers;
| while (mState != State::Quit)
| std::optional<DisplayEventReceiver::Event> event;
| //...
| if (mState == State::Idle) {// 界面不动,进这里wait
| mCondition.wait(lock);
| //...
| if (!mPendingEvents.empty()) // 被唤醒后开始处理 mPendingEvents
| event = mPendingEvents.front();
| mPendingEvents.pop_front();
| //...
| auto it = mDisplayEventConnections.begin();
| // mDisplayEventConnections是存储所有 EventThreadConnection 的 vector
| while (it != mDisplayEventConnections.end())
| // EventThreadConnection 为虚引用,这里 promote 提升为强引用
| if (const auto connection = it->promote())
| if (event && shouldConsumeEvent(*event, connection))
| // 对于需要消费这个事件的EventThreadConnection存入入 vector 中
| consumers.push_back(connection);
| ++it;
| else
| it = mDisplayEventConnections.erase(it);// 如果虚引用的对象销毁了,则从集合删除
| if (!consumers.empty()) {//集合不为空,开始分发事件
| dispatchEvent(*event, consumers);
|-->EventThread::dispatchEvent(const DisplayEventReceiver::Event& event, const DisplayEventConsumers& consumers)
| for (const auto& consumer : consumers)
| DisplayEventReceiver::Event copy = event;
| generateFrameTimeline(copy.vsync.vsyncData,...);
| consumer->postEvent(copy)
|-->EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event)
| DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
| gui::BitTube::sendObjects(dataChannel, events, count);
| ssize_t size = tube->write(vaddr, count * objSize);
|-->BitTube::write(void const* vaddr, size_t size)
| // mSendFd 是 socketpair 的fd
| len = ::send(mSendFd, vaddr, size, MSG_DONTWAIT | MSG_NOSIGNAL);

2、APP进程端:接收vsync回调

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
java复制代码epoll回调
| DisplayEventDispatcher::handleEvent
| processPendingEvents 使用 socketpair 的BitTube 在d中取出 VSync 事件
| DisplayEventReceiver::getEvents()
| BitTube::recvObjects
| linux 系统调用 ::recv
| dispatchVsync
// env->CallVoidMethod 回到 JAVA 层的 DisplayEventReceiver.dispatchVsync()
| DisplayEventReceiver.dispatchVsync()
// /frameworks/base/core/java/android/view/Choreographer.java
| FrameDisplayEventReceiver.onVsync
| Message msg = Message.obtain(mHandler, this);//传入的回调是this,即FrameDisplayEventReceiver.run() ;
| mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
| 之后进入FrameDisplayEventReceiver.run()方法调用 doFrame
| void doFrame(long frameTimeNanos, int frame, DisplayEventReceiver.VsyncEventData vsyncEventData)
| doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos, frameIntervalNanos)
| doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos, frameIntervalNanos);
| doCallbacks(Choreographer.CALLBACK_INSETS_ANIMATION, frameTimeNanos, frameIntervalNanos);
| doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos, frameIntervalNanos);
| ViewRootImpl.mTraversalRunnable.run()
| doTraversal();
| performTraversals();
| relayoutWindow //创建 Surface 流程
| doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos, frameIntervalNanos);

3、ViewRootImpl.relayoutWindow 创建 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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
java复制代码ViewRootImpl.mTraversalRunnable.run()
| doTraversal();
| performTraversals();
// 如果是ViewRootImpl刚创建,还没执行过performTraversals,或者窗口需要resize,或者显示属性变化,需要执行 relayoutWindow
| relayoutWindow //创建surface流程 + sf 创建layer流程

ViewRootImpl.relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,boolean insetsPending);
| mWindowSession.relayout(mWindow, params,requestedWidth, requestedHeight,...mSurfaceControl, mTempInsets, mTempControls, mRelayoutBundle);
| // 【接口层:ViewRootImpl.mSurfaceControl 构造流程】
| android.view.IWindowSession.Stub.Proxy.relayout(...android.view.SurfaceControl outSurfaceControl,...)
| // 调用 system_server 进程 Session.relayout 【转到: "system_server 进程 Session.relayout"】
| boolean _status = mRemote.transact(Stub.TRANSACTION_relayout, _data, _reply, 0);
| //若干步骤太多了不写了QTNND...
| IPCThreadState::transact(...);
| IPCThreadState::waitForResponse(...);//binder通信
| // 从 system_server 进程返回后,从 _reply 读取返回的 SurfaceControl 到 outSurfaceControl,即 ViewRootImpl.mSurfaceControl
| outSurfaceControl.readFromParcel(_reply);

// system_server 进程 Session.relayout
|-->Session.relayout(IWindow window, WindowManager.LayoutParams attrs,...SurfaceControl outSurfaceControl,...)
//进入system_server进程的 WMS
| mService.relayoutWindow(this, window, attrs,requestedWidth, requestedHeight,... outSurfaceControl,...)
|-->WindowManagerService.relayoutWindow(Session session, IWindow client, LayoutParams attrs,...SurfaceControl outSurfaceControl,...)
| int result = 0;
| //从 WindowManagerService.mWindowMap 获取之前addToDisplayAsUser流程存储的 WindowState
| final WindowState win = windowForClientLocked(session, client, false);
| // WindowState.mWinAnimator: WindowState构造函数中创建的
| WindowStateAnimator winAnimator = win.mWinAnimator;
| result = createSurfaceControl(outSurfaceControl, result, win, winAnimator);
|-->WindowManagerService.createSurfaceControl(SurfaceControl outSurfaceControl, int result,WindowState win, WindowStateAnimator winAnimator)
| WindowSurfaceController surfaceController = winAnimator.createSurfaceLocked();
|-->WindowStateAnimator.createSurfaceLocked()
| final WindowState w = mWin; // WindowState构造函数中会把WindowState自身传入WindowStateAnimator.mWin
| final WindowManager.LayoutParams attrs = w.mAttrs;
| final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
| // 1、创建 WindowSurfaceController,赋值到 WindowStateAnimator.mSurfaceController
| | mSurfaceController = new WindowSurfaceController(attrs.getTitle().toString(), format, flags, this, attrs.type);
// WindowSurfaceController 构造函数
|-->WindowSurfaceController(String name, int format, int flags, WindowStateAnimator animator,int windowType)
| mAnimator = animator; title = name; mService = animator.mService;
| final WindowState win = animator.mWin;
| mWindowType = windowType;
| mWindowSession = win.mSession;
| // 注意这里的 parent = WindowState.mSurfaceControl
| SurfaceControl.Builder b = win.makeSurface().setParent(win.getSurfaceControl()).setName(name).setFormat(format)
.setFlags(flags).setMetadata(METADATA_WINDOW_TYPE, windowType).setMetadata(...mUid).setMetadata(...mPid)...;
| //mService.mUseBLAST = (settings get global use_blast_adapter_vr == 1)
//global settings 中没有设置这个 use_blast_adapter_vr 值的话,默认值为 true
//PRIVATE_FLAG_USE_BLAST 这个 flag 是在 ViewRootImpl.setview 设置的
//综上,useBLAST = true
| boolean useBLAST = mService.mUseBLAST && ((win.getAttrs().privateFlags& LayoutParams.PRIVATE_FLAG_USE_BLAST) != 0);
| if (useBLAST) b.setBLASTLayer();
| // FX_SURFACE_BLAST = 0x00040000; 对应于 ISurfaceComposerClient.eFXSurfaceBufferState = 0x00040000
|-->SurfaceControl.Builder.setFlags(FX_SURFACE_BLAST, FX_SURFACE_MASK);
| // 2、创建Java层的 SurfaceControl ,赋值到 WindowStateAnimator.mSurfaceController.mSurfaceControl
| | mSurfaceControl = b.build();
| | | new SurfaceControl(mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata,mLocalOwnerView, mCallsite);
|-->SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, SurfaceControl parent...)
| | mName = name;mWidth = w;mHeight = h;mLocalOwnerView = localOwnerView;
| // 3、创建native层的 SurfaceControl,赋值到 WindowStateAnimator.mSurfaceController.mSurfaceControl.mNativeObject
| | mNativeObject = nativeCreate(session, name, w, h, format, flags,... metaParcel);
| | | | // /frameworks/base/core/jni/android_view_SurfaceControl.cpp
| |-->nativeCreate(..., jobject sessionObj,jstring nameStr, jint w, jint h, jint format, jint flags, ...)
| | sp<SurfaceComposerClient> client;
| client = android_view_SurfaceSession_getClient(env, sessionObj);
| sp<SurfaceControl> surface;// surface 作为引用参数传入
| client->createSurfaceChecked(String8(name.c_str()), w, h, format, &surface,flags, parentHandle...);
| // /frameworks/native/libs/gui/SurfaceComposerClient.cpp
| SurfaceComposerClient.createSurfaceChecked(const String8& name,...,sp<SurfaceControl>* outSurface,...)
| | sp<IBinder> handle;
| | | sp<IGraphicBufferProducer> gbp;
| | | int32_t id = -1;
| | mClient->createSurface(name, w, h, format, flags, parentHandle,... &handle, &gbp, &id, &transformHint);
| //surfaceflinger/Client.cpp
| | | mFlinger->createLayer
| | | // 进入SurfaceFlinger进程,创建layer流程 【转“SurfaceFlinger创建layer”章节】
| SurfaceFlinger::createLayer(name, this, w, h, format,... handle, gbp, parentHandle, outLayerId,...)
| | | *outSurface = new SurfaceControl(this, handle, gbp, id, w, h, format,...flags);
| | | // 4、使用SurfaceFlinger创建的 handle,GraphicBufferProducer,layerId 构造native层的 SurfaceControl
| | | // GraphicBufferProducer 图形buffer的生产者,handle用于layer销毁时SurfaceFlinger端回调,和layer检索
| SurfaceControl(const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle,
| const sp<IGraphicBufferProducer>& gbp, int32_t layerId,
| | uint32_t w, uint32_t h, PixelFormat format, uint32_t transform,uint32_t flags)
| | | : mClient(client), mHandle(handle), mGraphicBufferProducer(gbp), mTransformHint(transform)
| | | | mWidth(w),mHeight(h),mFormat(format),mCreateFlags(flags) {}
| | return reinterpret_cast<jlong>(surface.get());// 返回native创建的 SurfaceControl
| // 如果native有 mBbqChild ,返回 mBbqChild.mHandle,否则直接返回native SurfaceControl.mHandle
| | | | | mNativeHandle = nativeGetHandle(mNativeObject);/
| w.mInputWindowHandle.forceChange();
| return mSurfaceController;
| | surfaceController.getSurfaceControl(outSurfaceControl);//====================!!!
|-->WindowSurfaceController.getSurfaceControl(SurfaceControl outSurfaceControl)
| // 传入的是 WindowState.mWinAnimator.mSurfaceController.mSurfaceControl
| // 5、把AMS创建的 SurfaceControl 数据,复制给需要返回 App进程的对象 outSurfaceControl
| outSurfaceControl.copyFrom(mSurfaceControl, "WindowSurfaceController.getSurfaceControl");
|-->SurfaceControl.copyFrom(@NonNull SurfaceControl other, String callsite)
| // 几个重要成员复制
| mName = other.mName; mLocalOwnerView = other.mLocalOwnerView;
| mWidth = other.mWidth; mHeight = other.mHeight;
| // native层SurfaceControl复制, 以及 mNativeObject、mNativeHandle 复制
| assignNativeObject(nativeCopyFromSurfaceControl(other.mNativeObject), callsite);
|-->nativeCopyFromSurfaceControl(JNIEnv* env, jclass clazz, jlong surfaceControlNativeObj)
| sp<SurfaceControl> surface(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
| // native 层创建新的 SurfaceControl
// 把 WindowState.mWinAnimator.mSurfaceController.mSurfaceControl.mNativeObject 数据复制到新的 SurfaceControl 对象
| sp<SurfaceControl> newSurface = new SurfaceControl(surface);
|-->SurfaceControl::SurfaceControl(const sp<SurfaceControl>& other)
| mClient = other->mClient; mHandle = other->mHandle;
| mGraphicBufferProducer = other->mGraphicBufferProducer;
| mTransformHint = other->mTransformHint; mLayerId = other->mLayerId;
| mWidth = other->mWidth; mHeight = other->mHeight;
| mFormat = other->mFormat; mCreateFlags = other->mCreateFlags;
| return reinterpret_cast<jlong>(newSurface.get()); // 返回新的SurfaceControl地址到Java层的 outSurfaceControl
|-->SurfaceControl.assignNativeObject(long nativeObject, String callsite)
| mNativeObject = nativeObject; // 把native地址赋值到 SurfaceControl.mNativeObject
| //这里不展开了,没有mBbqChild,还是使用 WindowState.mWinAnimator.mSurfaceController.mSurfaceControl.mNativeObject.mHandle
| mNativeHandle = nativeGetHandle(nativeObject);
| return result; // END WindowManagerService.createSurfaceControl
|
| mWindowPlacerLocked.performSurfacePlacement(true /* force */); // 执行 Surface 的摆放工作
| // 如果焦点变化了更新焦点
| updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/)

// 回到 APP进程端:ViewRootImpl.relayoutWindow
//(1) 非 useBLAST 的情况:(Android12以后代码不会走这里)
| //6、创建 Surface
| mSurface.copyFrom(mSurfaceControl);
|-->Surface.copyFrom(SurfaceControl other)
| long surfaceControlPtr = other.mNativeObject;
| // 获取 native 层的 Surface 地址
| long newNativeObject = nativeGetFromSurfaceControl(mNativeObject, surfaceControlPtr);
|-->nativeGetFromSurfaceControl(JNIEnv* env, jclass clazz,jlong nativeObject, jlong surfaceControlNativeObj)
| sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
| sp<Surface> surface(ctrl->getSurface());// 创建native Surface
|-->SurfaceControl.getSurface()
| return generateSurfaceLocked();
|-->SurfaceControl.generateSurfaceLocked()
| // Android 11版本以前,这个函数内部直接创建 Surface 返回:new Surface(mGraphicBufferProducer, false);
| // Android 12 这里使用 BBQ ,还从这里连接 SurfaceFlinger 创建layer。ViewRootImpl不走这里,目前这里的流程不知道给谁用的
| mBbqChild = mClient->createSurface(String8("bbq-wrapper"), 0, 0, mFormat,flags, mHandle, {}, &ignore);
| // 以下流程展开参考【创建Surface:useBLAST】章节
| mBbq = sp<BLASTBufferQueue>::make("bbq-adapter", mBbqChild, mWidth, mHeight, mFormat);
| mSurfaceData = mBbq->getSurface(true); // 返回 new BBQSurface
| return mSurfaceData;
| surface->incStrong(&sRefBaseOwner);
| return reinterpret_cast<jlong>(surface.get());//返回 native 的 Surface 地址
| updateNativeObject(newNativeObject)
|-->updateNativeObject(long newNativeObject)
| setNativeObjectLocked(newNativeObject);
|-->setNativeObjectLocked(long ptr)
| mNativeObject = ptr;// 把新的native的Surface地址存储到 Surface.mNativeObject
//(2) useBLAST 的情况:(Android13 代码走这里,在Android12的基础上稍微变化了一下)
| updateBlastSurfaceIfNeeded();
| mBlastBufferQueue = new BLASTBufferQueue(mTag, mSurfaceControl, mSurfaceSize.x, mSurfaceSize.y, mWindowAttributes.format);
| mBlastBufferQueue.setTransactionHangCallback(sTransactionHangCallback);
| Surface blastSurface = mBlastBufferQueue.createSurface();
| mSurface.transferFrom(blastSurface);
创建Surface:useBLAST (BBQ)

接续上一章节“useBLAST 的情况”

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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
java复制代码// frameworks/base/core/java/android/view/ViewRootImpl.java
// useBLAST 函数:
/*
mForceDisableBLAST 使用默认值false
mUseBLASTAdapter:如果 WMS.addWindow 返回值带有flag WindowManagerGlobal.ADD_FLAG_USE_BLAST ,则为 true。[见:IWindowSession.addToDisplayAsUser]
Android 12 后有这个flag
*/
boolean useBLAST() {
return mUseBLASTAdapter && !mForceDisableBLAST;
}

// 如果 useBLAST() 返回 true,则调用 updateBlastSurfaceIfNeeded();
// 接续上一章节“useBLAST 的情况”
// frameworks/base/core/java/android/view/ViewRootImpl.java
updateBlastSurfaceIfNeeded();
| // 【1】创建 BLASTBufferQueue
| // 参数:mSurfaceControl 是在 ViewRootImpl.mWindowSession.relayout 的接口层调用 mSurfaceControl.readFromParcel 填充的数据
| mBlastBufferQueue = new BLASTBufferQueue(mTag, mSurfaceControl, mSurfaceSize.x, mSurfaceSize.y, mWindowAttributes.format);
| // Java层 BLASTBufferQueue 构造
|-->BLASTBufferQueue (String name, SurfaceControl sc, int width, int height, @PixelFormat.Format int format)
| mNativeObject = nativeCreate(name, true);// 创建 native 层 BLASTBufferQueue,返回的地址存储到 mNativeObject
| //【2】创建 native BLASTBufferQueue
| //frameworks/base/core/jni/android_graphics_BLASTBufferQueue.cpp
|-->nativeCreate(JNIEnv* env, jclass clazz, jstring jName, jboolean updateDestinationFrame)
| sp<BLASTBufferQueue> queue = new BLASTBufferQueue(name.c_str(), updateDestinationFrame);
| // native 层 BLASTBufferQueue 构造,Android 13的构造函数相比 Android 12 少了一部分内容,那部分内容放到了 BLASTBufferQueue::update
|-->BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinationFrame)
| : mSurfaceControl(nullptr),mSize(1, 1),mRequestedSize(mSize),mFormat(PIXEL_FORMAT_RGBA_8888),
| mTransactionReadyCallback(nullptr),mSyncTransaction(nullptr),mUpdateDestinationFrame(updateDestinationFrame){
| // 【3】创建 BufferQueueCore、BBQBufferQueueProducer、BufferQueueConsumer
| createBufferQueue(&mProducer, &mConsumer); //[转 BLASTBufferQueue::createBufferQueue 章节]
// BufferQueueProducer.mDequeueTimeout = int64.max
| mProducer->setDequeueTimeout(std::numeric_limits<int64_t>::max());
/*
BufferQueueCore:
std::set<int> mFreeSlots; // 初始添加 2个int
std::list<int> mUnusedSlots; // 初始添加 64 int值

setMaxDequeuedBufferCount(2)的结果:
1)从 BufferQueueCore.mUnusedSlots 中取出 1 个并删除,然后插入 BufferQueueCore.mFreeSlots;
mUnusedSlots 长度变为 63,mFreeSlots长度变为 3
(mFreeSlots,是dequeuebuffer数据来源,其长度代表最大可dequeue的数量,当前为3,表示三级缓存)
2)BufferQueueCore.mMaxDequeuedBufferCount = 2; BufferQueueCore.mMaxAcquiredBufferCount = 1;
3)调整完毕mMaxDequeuedBufferCount后,如果 dequeueBuffer 处于等待buffer状态,会被唤醒拿取buffer
函数调用完成后,如果调用 getMaxBufferCountLocked,在同步模式下:
BufferQueueCore.getMaxBufferCountLocked() = mMaxDequeuedBufferCount + mMaxAcquiredBufferCount = 3 (三级缓存)
*/
| mProducer->setMaxDequeuedBufferCount(2);
| // 【4】创建 BLASTBufferItemConsumer 并设置生产者消费者监听
| mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer,USAGE_HW_COMPOSER|USAGE_HW_TEXTURE, 1, false, this);
|-->BLASTBufferItemConsumer(IGBConsumer& consumer,uint64_t consumerUsage,int bufferCount, bool controlledByApp, wp<BLASTBufferQueue> bbq)
: BufferItemConsumer(consumer, consumerUsage, bufferCount, controlledByApp),//构造父类BufferItemConsumer
mBLASTBufferQueue(std::move(bbq)),/* 存储 BBQ*/mCurrentlyConnected(false),mPreviouslyConnected(false) {}
|-->:BufferItemConsumer(sp<IGraphicBufferConsumer>& consumer,uint64_t consumerUsage,int bufferCount, bool controlledByApp)
: ConsumerBase(consumer, controlledByApp){
// BufferQueueCore.mConsumerUsageBits = GraphicBuffer::USAGE_HW_COMPOSER |GraphicBuffer::USAGE_HW_TEXTURE;
mConsumer->setConsumerUsageBits(consumerUsage);
// 默认 BufferQueueCore->mMaxAcquiredBufferCount = 1,bufferCount=1, 所以这里无用功
mConsumer->setMaxAcquiredBufferCount(bufferCount);
}
|-->ConsumerBase.ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool controlledByApp)
: mAbandoned(false),mConsumer(bufferQueue),mPrevFinalReleaseFence(Fence::NO_FENCE){
// 创建未命令的名字,这里的名字会被之后 BLASTBufferQueue 构造函数的代码覆盖
mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
//【5】调用消费者的 connect 函数,这里的代码执行结果:
// 1、赋值 BufferQueueCore 的消费者监听: BufferQueueCore.mConsumerListener = ConsumerBase
// 2、BufferQueueCore.mConsumerControlledByApp = false
status_t err = mConsumer->consumerConnect(proxy, controlledByApp);
mConsumer->setConsumerName(mName);// 名字传给 BufferQueueConsumer、BufferQueueCore
}
// consumerName = "ViewRootImpl#[id](BLAST Consumer)[id]"
//BufferQueueCore.mConsumerName = BufferQueueConsumer.mConsumerName = BufferItemConsumer父类ConsumerBase.mName = consumerName;
| mBufferItemConsumer->setName(String8(consumerName.c_str()));
// ConsumerBase.mFrameAvailableListener = BLASTBufferQueue
| mBufferItemConsumer->setFrameAvailableListener(this); // queuebuffer后,通知消费者的监听
// BufferItemConsumer.mBufferFreedListener = BLASTBufferQueue
| mBufferItemConsumer->setBufferFreedListener(this); // 通知生产者的的监听
| ComposerService::getComposerService()->getMaxAcquiredBufferCount(&mMaxAcquiredBuffers);// 从是sf获取MaxAcquiredBufferCount
// 赋值 sf 的MaxAcquiredBufferCount
| mBufferItemConsumer->setMaxAcquiredBufferCount(mMaxAcquiredBuffers);
| mCurrentMaxAcquiredBufferCount = mMaxAcquiredBuffers;
|}
| return reinterpret_cast<jlong>(queue.get());// 返回 native BLASTBufferQueue 地址
| nativeUpdate(mNativeObject, sc.mNativeObject, width, height, format);
|-->nativeUpdate(JNIEnv* env, jclass clazz, jlong ptr, jlong surfaceControl, jlong width,jlong height, jint format)
| sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
| queue->update(reinterpret_cast<SurfaceControl*>(surfaceControl), width, height, format);
|-->BLASTBufferQueue.update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height,int32_t format)
| // 这些值,在 BufferQueueProducer::connect 函数中,会再返回 Surface
| mFormat = format; BufferQueueCore->mDefaultBufferFormat = mFormat;
| mSurfaceControl = surface;
| mTransformHint = mSurfaceControl->getTransformHint(); BufferQueueCore->mTransformHint = mTransformHint;
| // 这里的宽高,来源是 ViewRootImpl.relayout 后通过 WindowLayout::computeSurfaceSize 计算的宽高
| mRequestedSize = newSize(width, height);
| mSize = mRequestedSize;
| BufferQueueCore->mDefaultWidth = mRequestedSize.width; BufferQueueCore->mDefaultHeight = mRequestedSize.height;
| //之后再把 宽高 通过事务传递到sf
| SurfaceComposerClient::Transaction.setApplyToken(mApplyToken).apply(false, true);
| mBlastBufferQueue.setTransactionHangCallback(sTransactionHangCallback);// GPU hang 回调
| Surface blastSurface = mBlastBufferQueue.createSurface();
| | BlastBufferQueue.nativeGetSurface(mNativeObject, false /* includeSurfaceControlHandle */);
| //frameworks/base/core/jni/android_graphics_BLASTBufferQueue.cpp
|-->nativeGetSurface(JNIEnv* env, jclass clazz, jlong ptr, jboolean includeSurfaceControlHandle)
| sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr); // 地址转为 native BLASTBufferQueue 对象
| return android_view_Surface_createFromSurface(env,queue->getSurface(includeSurfaceControlHandle));
| // 【6】创建 BBQSurface
| //frameworks/native/libs/gui/BLASTBufferQueue.cpp
|-->BLASTBufferQueue.getSurface(bool includeSurfaceControlHandle)
| sp<IBinder> scHandle = nullptr;
| if (includeSurfaceControlHandle && mSurfaceControl)// includeSurfaceControlHandle = false
| scHandle = mSurfaceControl->getHandle();
| return new BBQSurface(mProducer, true, scHandle, this);
| //创建 BBQSurface,比较重要的是重载了 allocateBuffers
|-->BBQSurface(const sp<IGraphicBufferProducer>& igbp, bool controlledByApp,
const sp<IBinder>& scHandle, const sp<BLASTBufferQueue>& bbq)
: Surface(igbp, controlledByApp, scHandle), mBbq(bbq) {}
| //Surface 的构造函数内容太多了不写了
|-->Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp,...)
: mGraphicBufferProducer(bufferProducer) // 最关键的就是传入了 生产者
| mProducerControlledByApp = controlledByApp; // true
| // 【7】创建Java层的 Surface,并把 BBQSurface 的地址存入Surface.mNativeObject,(这一步就是创建个java的Surface,临时存储native的BBQSurface)
| //frameworks/base/core/jni/android_view_Surface.cpp
|-->android_view_Surface_createFromSurface(JNIEnv* env, const sp<Surface>& surface)
| // 在 JNI new Java 层的 Surface
| jobject surfaceObj = env->NewObject(gSurfaceClassInfo.clazz, gSurfaceClassInfo.ctor, (jlong)surface.get());
| // 调用Java层,参数为 long 的构造函数:
|-->Surface(long nativeObject)
| setNativeObjectLocked(nativeObject);
| mNativeObject = nativeObject;
| return surfaceObj; // 返回java层的对象
| //【8】把返回的BBQSurface地址 Surface.mNativeObject 转存入 ViewRootImpl.mSurface.mNativeObject
| mSurface.transferFrom(blastSurface); // mSurface.mNativeObject = blastSurface.mNativeObject

4、BLASTBufferQueue::createBufferQueue 生产者-消费者-BufferQueueCore

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
c++复制代码//	frameworks/native/libs/gui/BLASTBufferQueue.cpp
BLASTBufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer, sp<IGraphicBufferConsumer>* outConsumer)
| // 1、创建 BufferQueueCore
| sp<BufferQueueCore> core(new BufferQueueCore());
| // BufferQueueCore 构造函数:
|-->BufferQueueCore::BufferQueueCore()
: mMutex(), mConsumerControlledByApp(false),
mSlots(), // BufferSlot[64] mSlots; 创建 Slots
mQueue(), // Vector<BufferItem> mQueue; queuebuffer 后存储到这个变量里
// FREE 状态,没有GraphicBuffer的放到mFreeSlots里
mFreeSlots(), // std::set<int> mFreeSlots; 初始化为 2个int, mUnusedSlots 每减一个,对应的 mFreeSlots 加入一个
// FREE 状态,但是有buffer attached
mFreeBuffers(), // std::list<int> mFreeBuffers;
// 未被使用的 Slot ,起始长度为64,64 + 2个mFreeSlots的元素 其实代表了 Slot 的总数
// 依据 adjustAvailableSlotsLocked函数,可以得出 mUnusedSlots 每减一个,对应的 mFreeSlots 加入一个(加入的就是mUnusedSlots减去的那个)
mUnusedSlots(), // std::list<int> mUnusedSlots;
// 当应用申请走一个Slot时,该Slot状态会切换到DEQUEUED状态,该Slot会被放入mActiveBuffers队列
mActiveBuffers(),//std::set<int> mActiveBuffers;
// mutable std::condition_variable mDequeueCondition;
mDequeueCondition(), // dequeueBuffer 没slot时,调用 mDequeueCondition.wait 等待
mDequeueBufferCannotBlock(false), // bool mDequeueBufferCannotBlock = false; dequeueBuffer 时 阻塞
mQueueBufferCanDrop(false), mLegacyBufferDrop(true), mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),/*默认使用的格式*/
mDefaultWidth(1), mDefaultHeight(1), mDefaultBufferDataSpace(HAL_DATASPACE_UNKNOWN),
mMaxBufferCount(BufferQueueDefs::NUM_BUFFER_SLOTS), // NUM_BUFFER_SLOTS = 64; 这个值64,设置这么大其实用多少
mMaxAcquiredBufferCount(1), mMaxDequeuedBufferCount(1),...
mTransformHint(0)/*优化屏幕旋转*/,mIsAllocating(false)/*是否正在分配内存*/,mIsAllocatingCondition(),
mAllowAllocation(true), /*允许分配新buffer, BufferQueueProducer::connect时,设置为true*/
mBufferAge(0),/*当前的 BufferSlot 自从上次 queueBuffer 后,又queue了多少个BufferSlot*/
mAsyncMode(false),/*同步模式*/ mSharedBufferMode(false),...
mUniqueId(getUniqueId()),mAutoPrerotation(false)/*自动预旋转*/,mTransformHintInUse(0)/*自动预旋转的方向,90度时宽高互换*/{
int numStartingBuffers = getMaxBufferCountLocked(); //numStartingBuffers = 2
// 构造函数中 set<int> mFreeSlots 插入两个int
for (int s = 0; s < numStartingBuffers; s++) {
mFreeSlots.insert(s);
}
// 构造函数中 std::list<int> mUnusedSlots 插入 64 个int
for (int s = numStartingBuffers; s < BufferQueueDefs::NUM_BUFFER_SLOTS; s++) { // NUM_BUFFER_SLOTS = 64
mUnusedSlots.push_front(s);
}
}

| // 2、创建生产者
| sp<IGraphicBufferProducer> producer(new BBQBufferQueueProducer(core, this));
| // BBQBufferQueueProducer 没多少内容,就是重载了 connect、setMaxDequeuedBufferCount、query
|-->BBQBufferQueueProducer(const sp<BufferQueueCore>& core, wp<BLASTBufferQueue> bbq)
// mConsumerIsSurfaceFlinger 入队后,GraphicBuffer 在BufferItem 中的指针是否应该被清除
: BufferQueueProducer(core, false /* consumerIsSurfaceFlinger*/),mBLASTBufferQueue(std::move(bbq)) {}
|-->BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core, bool consumerIsSurfaceFlinger)
: mCore(core), mSlots(core->mSlots), mConsumerName(),mStickyTransform(0),
mConsumerIsSurfaceFlinger(consumerIsSurfaceFlinger/*false*/),mLastQueueBufferFence(Fence::NO_FENCE),mLastQueuedTransform(0),
mCallbackMutex(),mNextCallbackTicket(0),mCurrentCallbackTicket(0),mCallbackCondition(),
mDequeueTimeout(-1),mDequeueWaitingForAllocation(false) {}
| // 3、创建消费者
| sp<BufferQueueConsumer> consumer(new BufferQueueConsumer(core));
|-->BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core)
: mCore(core), mSlots(core->mSlots), mConsumerName() {}
| // 4、生产消费者赋值到 BLASTBufferQueue成员变量 mProducer 和 mConsumer
| *outProducer = producer;
| *outConsumer = consumer;

七、SurfaceFlinger创建layer

Android 11 以及以前的版本简述:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
c++复制代码SurfaceFlinger::createLayer

| SurfaceFlinger::createBufferQueueLayer(client, uniqueName, w, h, flags, metadata, format, handle, gbp, &layer);
| sp<BufferQueueLayer> layer;
| layer = getFactory().createBufferQueueLayer(args);
| BufferQueueLayer 对象创建完成后,在首次sp指针引用时调用 BufferQueueLayer::onFirstRef()
| onFirstRef函数中会创建 生产者,消费者,生产者会传入到客户端
| sp<IGraphicBufferProducer> producer;
| sp<IGraphicBufferConsumer> consumer;
| 设置生产者的三级缓冲
| mProducer->setMaxDequeuedBufferCount(2);
| 赋值client端的参数
| sp<IBinder> *handle = layer->getHandle();
| sp<IGraphicBufferProducer> *gbp = layer->getProducer(); //获取生产者
| sp<Layer> *outLayer = layer; //这个layer保存在 SurfaceComposerClient对象中,wms并未赋值,wms对应的是SurfaceControl
| addClientLayer
| 调用 addClientLayer,把layer按照Z轴顺序存入 layersSortedByZ

SurfaceFlinger::createLayer Android 13

  • Android 12 以后因为BBQ都在APP进程,所以 createLayer 大大简化了,内容不多。
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
c++复制代码【接续“ViewRootImpl.relayoutWindow 创建 Surface” 章节中的 “SurfaceComposerClient.createSurfaceChecked”】
SurfaceFlinger::createLayer(LayerCreationArgs& args, sp<IBinder>* outHandle,sp<IBinder>& parentHandle, int32_t* outLayerId, sp<Layer>& parentLayer, uint32_t* outTransformHint)
| sp<Layer> layer;
| switch (args.flags & ISurfaceComposerClient::eFXSurfaceMask){
case ISurfaceComposerClient::eFXSurfaceBufferQueue:
/*
eFXSurfaceBufferState = 0x00040000
WindowManagerService.createSurfaceControl 流程中
if (useBLAST) b.setBLASTLayer(); 这个函数设置的flag FX_SURFACE_BLAST = 0x00040000;
*/
case ISurfaceComposerClient::eFXSurfaceBufferState:
result = createBufferStateLayer(args, outHandle, &layer);
| createBufferStateLayer(LayerCreationArgs& args, sp<IBinder>* handle, sp<Layer>* outLayer)
| *outLayer = getFactory().createBufferStateLayer(args); // 创建的 layer
|-->BufferStateLayer::BufferStateLayer(const LayerCreationArgs& args)
| : BufferLayer(args), mHwcSlotGenerator(new HwcSlotGenerator())
| mDrawingState.dataspace = ui::Dataspace::V0_SRGB;
|-->BufferLayer::BufferLayer(const LayerCreationArgs& args)
: Layer(args), mTextureName(args.textureName),
| mCompositionState{mFlinger->getCompositionEngine().createLayerFECompositionState()}
|-->Layer::Layer(const LayerCreationArgs& args)
: sequence(args.sequence.value_or(sSequence++)),
mFlinger(args.flinger),
mName(base::StringPrintf("%s#%d", args.name.c_str(), sequence)),
mClientRef(args.client),
mWindowType(static_cast<WindowInfo::Type>(args.metadata.getInt32(METADATA_WINDOW_TYPE, 0))),
mLayerCreationFlags(args.flags)
// 然后是一堆 mDrawingState 成员属性的初始化
| *handle = (*outLayer)->getHandle(); // 把创建的 handle 传入外部,最终会返回到APP进程端,用于创建 SurfaceControl
break;
case ISurfaceComposerClient::eFXSurfaceEffect: // 这里是 Task、DefaultTaskDisplayArea
result = createEffectLayer(args, outHandle, &layer);
break;
case ISurfaceComposerClient::eFXSurfaceContainer://这里是 ActivityRecord、WindowState 等等
result = createContainerLayer(args, outHandle, &layer);
break;
default:
result = BAD_VALUE;
break;
}
|
| result = addClientLayer(args.client, *outHandle, layer, parent, addToRoot, outTransformHint);
|-->SurfaceFlinger.addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,const sp<Layer>& layer, const wp<Layer>& parent,...)
| // std::vector<LayerCreatedState> mCreatedLayers 加入到数组
| mCreatedLayers.emplace_back(layer, parent, addToRoot);
| // 缓存到 Client.mLayers 集合中 //frameworks/native/services/surfaceflinger/Client.h
| client->attachLayer(handle, layer);
| // 请求 sf-vsync,这里的代码和 SurfaceFlinger::commitCreatedLayers() 以及 mCreatedLayers 是相关联的,具体见 SurfaceFlinger 章节
| setTransactionFlags(eTransactionNeeded);
| *outLayerId = layer->sequence;
| return result;

PowerManagerService(简称PMS)主要是负责协调、管理设备CPU资源,并提供功能接口给应用框架层或应用层申请获取CPU资源的一个服务,例如:亮灭屏、关机、WakeLock管理、Dreamland(屏保模式)、休眠时间等行为。

1. PMS的启动流程

PMS是在SystemServer的startBootstrapServices()中通过SystemServiceManager.startService()启动,很多服务依赖PMS服务,所以它需要尽早的启动并注册到ServiceManage中,所以它在startBootstrapServices()中来启动

frameworks/base/services/java/com/android/server/SystemServer.java
                    
    private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
        t.traceBegin("StartPowerManager");
        mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
        t.traceEnd();
    }

SystemServiceManager.startService()通过反射拿到PowerManagerService对象

frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

    public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            final String name = serviceClass.getName();
            final T service;
            try {
                //获取类构造方法,构造对应对象
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service could not be instantiated", ex);
            } catch (IllegalAccessException ex) {
                ...
            }
            //调用startService启动服务
            startService(service);
            //返回服务对象
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }

    public void startService(@NonNull final SystemService service) {
        // Check if already started
        String className = service.getClass().getName();

        mServiceClassnames.add(className);

        // Register it.
        //注册服务
        mServices.add(service);
                
        // Start it.
        long time = SystemClock.elapsedRealtime();
        try {
            //调用服务的onStart()方法启动服务
            service.onStart();
        } catch (RuntimeException ex) {
            throw new RuntimeException("Failed to start service " + service.getClass().getName()
                    + ": onStart threw an exception", ex);
        }
        warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
    }

将服务加入mServices列表中,然后调用服务的onStart()方法,mServices列表是管理着所有需要接收系统启动过程中生命周期的服务

1.1 PowerManagerService构造方法

frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

    public PowerManagerService(Context context) {
        this(context, new Injector());  //内部类Injector对象,管理创建其他对象
    }

    PowerManagerService(Context context, Injector injector) {
        super(context);

        mContext = context;
        mBinderService = new BinderService();  //用于IPC交互, BinderService 继承于 IPowerManager.Stub
        mLocalService = new LocalService();  //用户跨线程交互(SystemServer进程内部)
        //创建一个NativeWrapper对象,管理所有的native交互
        mNativeWrapper = injector.createNativeWrapper();
        //创建SystemPropertiesWrapper对象,用于获取系统属性等信息
        mSystemProperties = injector.createSystemPropertiesWrapper();
        mClock = injector.createClock();
        //内部类Injector对象,管理创建其他对象
        mInjector = injector;
        
        //创建PMS主线程,优先级为DISPLAY级别
        mHandlerThread = new ServiceThread(TAG,
                Process.THREAD_PRIORITY_DISPLAY, /* allowIo= */ false);
        mHandlerThread.start();  //启动主线程
        //创建PMS主线程Handler
        mHandler = injector.createHandler(mHandlerThread.getLooper(),
                new PowerManagerHandlerCallback());
        //用于管理Settings.Global下的常量
        mConstants = new Constants(mHandler);
        //创建AmbientDisplayConfiguration对象,管理一些显示配置,如AOD
        mAmbientDisplayConfiguration = mInjector.createAmbientDisplayConfiguration(context);
        //创建AmbientDisplaySuppressionController对象,用于管理AmbientDisplay显示相关,和AOD显示有关
        mAmbientDisplaySuppressionController =
                mInjector.createAmbientDisplaySuppressionController(context);
        //创建AttentionDetector对象,用来检查用户活动是否需要再更新
        mAttentionDetector = new AttentionDetector(this::onUserAttention, mLock);
        
        mFaceDownDetector = new FaceDownDetector(this::onFlip);
        
        mScreenUndimDetector = new ScreenUndimDetector();
        //创建BatterySavingStats对象,用来记录电池耗电率
        mBatterySavingStats = new BatterySavingStats(mLock);
        //创建BatterySaverPolicy对象,管理一些省电策略
        mBatterySaverPolicy =
                mInjector.createBatterySaverPolicy(mLock, mContext, mBatterySavingStats);
        //创建BatterySaverController对象,管理省电策略的切换
        mBatterySaverController = mInjector.createBatterySaverController(mLock, mContext,
                mBatterySaverPolicy, mBatterySavingStats);
        //创建BatterySaverStateMachine对象,负责省电策略的开启/关闭
        mBatterySaverStateMachine = mInjector.createBatterySaverStateMachine(mLock, mContext,
                mBatterySaverController);

        mLowPowerStandbyController = mInjector.createLowPowerStandbyController(mContext,
                Looper.getMainLooper());
                
        mInattentiveSleepWarningOverlayController =
                mInjector.createInattentiveSleepWarningController();

        mAppOpsManager = injector.createAppOpsManager(mContext);

        mPowerGroupWakefulnessChangeListener = new PowerGroupWakefulnessChangeListener();
        
        ...		//获取一些配置初始值
        
        synchronized (mLock) {
            //创建SuspendBlockerImpl对象,"PowerManagerService.Booting"类型对象负责在开机时负责保活CPU
            mBootingSuspendBlocker =
                    mInjector.createSuspendBlocker(this, "PowerManagerService.Booting");
           //创建SuspendBlockerImpl对象,WakeLock的最终反映,"PowerManagerService.WakeLocks"类型对象负责保活CPU
            mWakeLockSuspendBlocker =
                    mInjector.createSuspendBlocker(this, "PowerManagerService.WakeLocks");
            //创建SuspendBlockerImpl对象,"PowerManagerService.Display"类型对象负责保持屏幕常亮
            mDisplaySuspendBlocker =
                    mInjector.createSuspendBlocker(this, "PowerManagerService.Display");
            //申请mBootingSuspendBlocker,保持开机启动过程CPU资源
            if (mBootingSuspendBlocker != null) {
                mBootingSuspendBlocker.acquire();
                mHoldingBootingSuspendBlocker = true;
            }
            //申请mDisplaySuspendBlocker,保持屏幕常亮
            if (mDisplaySuspendBlocker != null) {
                mDisplaySuspendBlocker.acquire(HOLDING_DISPLAY_SUSPEND_BLOCKER);
                mHoldingDisplaySuspendBlocker = true;
            }
            //auto-suspend 模式是否可用
            mHalAutoSuspendModeEnabled = false;
            //是否是可交互状态
            mHalInteractiveModeEnabled = true;
            //设置设备状态为唤醒状态
            mWakefulnessRaw = WAKEFULNESS_AWAKE;
            //静默模式,会控制背光的点亮,使用场景不多
            sQuiescent = mSystemProperties.get(SYSTEM_PROPERTY_QUIESCENT, "0").equals("1")
                    || InitProperties.userspace_reboot_in_progress().orElse(false);
                    
            //mNativeWrapper对象进行native层初始化工作
            mNativeWrapper.nativeInit(this);
            mNativeWrapper.nativeSetAutoSuspend(false);  //设置auto suspend状态
            mNativeWrapper.nativeSetPowerMode(Mode.INTERACTIVE, true);  //设置interactive状态
            mNativeWrapper.nativeSetPowerMode(Mode.DOUBLE_TAP_TO_WAKE, false);  //设置双击唤醒模式状态
            mInjector.invalidateIsInteractiveCaches();
        }
    }

构造方法主要做了几件事:

  1. 创建用于IPC的BinderService对象和system_server进程内跨线程交互的LocalService对象;
  2. 创建PMS的主线程,并使用该HandlerThread的Looper实例化PowerManagerHandler,将作为PMS主线程Handler进行Message的处理
  3. 相关配置参数的读取,如系统配置各种亮度参数
  4. 获取了三个Suspend锁对象,SuspendBlocker是一种锁机制,上层申请的wakelock锁在PMS中都会反映为SuspendBlocker锁
  5. 通过mNativeWrapper对象和底层进行状态交互

1.2 onStart()中注册发布服务

执行完构造方法后接着执行了onStart()

frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

    @Override
    public void onStart() {
        //向ServiceManager进程注册当前服务mBinderService(BinderServic才是PMS的Binder服务端)
        publishBinderService(Context.POWER_SERVICE, mBinderService, /* allowIsolated= */ false,
                DUMP_FLAG_PRIORITY_DEFAULT | DUMP_FLAG_PRIORITY_CRITICAL);
        //发布本地服务提供给SystemServer进程中其他组件访问
        publishLocalService(PowerManagerInternal.class, mLocalService);
        //添加watchdog监听
        Watchdog.getInstance().addMonitor(this);
        Watchdog.getInstance().addThread(mHandler);
    }

这个方法中会进行对PMS的Binder服务和Local服务的注册,BinderService注册后,其他模块中就可以通过ServiceManager获取到对应的Binder对象,进行IPC通信;LocalService注册后,在system_server进程内就可以通过获取LocalService对象跨线程交互。
PMS中的BinderService,是继承自IPowerManager.Stub的一个内部类BinderService,IPowerManager.Stub继承自Binder并且实现了IPowerManager,因此,PMS和其他模块的跨进程交互,实际上就是通过PMS.BinderService实现。

Binder服务注册的过程在SystemService中的publishBinderService方法,通过ServiceManager.addService注册:

frameworks/base/services/core/java/com/android/server/SystemService.java

    protected final void publishBinderService(String name, IBinder service,
            boolean allowIsolated, int dumpPriority) {
        ServiceManager.addService(name, service, allowIsolated, dumpPriority);
    }


frameworks/base/core/java/android/os/ServiceManager.java

    public static void addService(String name, IBinder service) {
        addService(name, service, false, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
    }

当通过ServiceManager注册后,就可以根据Context.POWER_SERVICE在其他服务中获得服务代理对象,进行跨进程交互了。

LocalService则用于system_server进程内部交互,注册的对象是另一个内部类——继承自PowerManagerInternal的LocalService(带有Internal的类一般都在System进程内使用)。Local Service的注册是在LocalServices中进行,其注册方法如下:

frameworks/base/services/core/java/com/android/server/SystemService.java

    protected final <T> void publishLocalService(Class<T> type, T service) {
        LocalServices.addService(type, service);
    }


frameworks/base/core/java/com/android/server/LocalServices.java

    public static <T> void addService(Class<T> type, T service) {
        synchronized (sLocalServiceObjects) {
            if (sLocalServiceObjects.containsKey(type)) {
                throw new IllegalStateException("Overriding service registration");
            }
            sLocalServiceObjects.put(type, service); //添加到sLocalServiceObjects容器中
        }
    }

1.3 onBootPhase()进行各个启动阶段的处理

回到SytemServer中,startBootstrapServices()方法中PMS的实例化和注册流程执行完成了,接下来会开始执行SystemService的生命周期,会开始执行SystemServiceManager.onBootPhase(),这个方法为所有的已进行实例化和注册的服务(通过前面的startService启动的服务)设置启动阶段,以便在不同的启动阶段进行不同的工作,方法如下:

frameworks/base/services/core/java/com/android/server/SystemServiceManager.java

    public void startBootPhase(@NonNull TimingsTraceAndSlog t, int phase) {
        mCurrentPhase = phase;
        try {
            final int serviceLen = mServices.size();
            for (int i = 0; i < serviceLen; i++) {
                final SystemService service = mServices.get(i);
                try {
                    service.onBootPhase(mCurrentPhase);
                } catch (Exception ex) {
                    ...
                }
            }
        } finally {
            t.traceEnd();
        }

        if (phase == SystemService.PHASE_BOOT_COMPLETED) {
            final long totalBootTime = SystemClock.uptimeMillis() - mRuntimeStartUptime;
            t.logDuration("TotalBootTime", totalBootTime);
            SystemServerInitThreadPool.shutdown();
        }
    }

在SystemServiceManager#startBootPhase()中,通过在SystemServiceManager中传入不同的形参,遍历SystemServiceManager#mServices列表,调用各个SystemService#onBootPhase(int)方法,根据参数在方法实现中完成不同的工作。在SystemService中定义了七个代表启动阶段的参数:

PHASE_WAIT_FOR_DEFAULT_DISPLAY:第一个启动阶段,用于在启动PKMS之前,需要确保已经存在默认逻辑屏,只有DisplayManagerService使用该阶段;
PHASE_LOCK_SETTINGS_READY:第二个启动阶段,该阶段的执行,意味这Lock Pattern/Password相关服务已经准备完毕,只有DisplayManagerService使用该阶段;
PHASE_SYSTEM_SERVICES_READY:第三个启动阶段,该阶段的执行,意味这其他服务可以安全地使用核心系统服务;
PHASE_DEVICE_SPECIFIC_SERVICES_READY:第四个启动阶段,该阶段的执行,意味这其他服务可以安全地使用设备指定的一些系统服务,这些服务在config_deviceSpecificSystemServices中进行配置;
PHASE_ACTIVITY_MANAGER_READY:第五个启动阶段,该阶段的执行,意味这其他AMS组件已经启动完成,可以进行广播操作;
PHASE_THIRD_PARTY_APPS_CAN_START:第六个启动阶段,该阶段的执行,意味这系统可以启动APP,并可以进行service的bind/start操作了;
PHASE_BOOT_COMPLETED:第六个启动阶段,该阶段的执行,意味这启动完成,Home应用也已经启动完成,并且可以和设备进行交互了。

PMS#onBootPhase()方法只对以上的3个阶段做了处理:

frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

    @Override
    public void onBootPhase(int phase) {
        if (phase == PHASE_SYSTEM_SERVICES_READY) {
            systemReady();  //如果是PHASE_SYSTEM_SERVICES_READY阶段则调用PMS的systemReady()

        } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
            //统计系统启动次数,adb shell settings get global boot_count可查看
            incrementBootCount();

        } else if (phase == PHASE_BOOT_COMPLETED) {
            synchronized (mLock) {
                final long now = mClock.uptimeMillis();
                mBootCompleted = true;  //表示启动完成
                mDirty |= DIRTY_BOOT_COMPLETED;  //最重要的标志位
                
                //执行BatterySaverStateMachine.onBootCompleted()
                mBatterySaverStateMachine.onBootCompleted();
                //更新用户活动时间
                userActivityNoUpdateLocked(
                        now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
                //更新全局状态信息
                updatePowerStateLocked();
                if (sQuiescent) {
                    sleepPowerGroupLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP),
                            mClock.uptimeMillis(),
                            PowerManager.GO_TO_SLEEP_REASON_QUIESCENT,
                            Process.SYSTEM_UID);
                }
                //注册DeviceStateManager服务的回调接口
                mContext.getSystemService(DeviceStateManager.class).registerCallback(
                        new HandlerExecutor(mHandler), new DeviceStateListener());
            }
        }
    }

mDirty是一个二进制的标记位,用来表示电源状态哪一部分发生了改变,通过对其进行置位(|操作)、清零(~操作),得到二进制数各个位的值(0或1),进行不同的处理,这个变量非常重要。
最后,调用updatePowerStateLocked()方法,这是整个PMS中最重要的方法,会在下面进行详细分析。
此时,启动过程中SystemService的生命周期方法全部执行完毕。

1.4 sytemReady()

当onBootPhase处于PHASE_SYSTEM_SERVICES_READY阶段时,执行sytemReady()

    private void systemReady() {
        //方法太长了
    }

这个方法中主要做了以下几个操作,方法太长了相关方法代码就不再粘贴:

获取各类本地服务和远程服务,如Dreamland服务(DreamMangerService)、窗口服务(PhoneWindowManager)、电池状态监听(BatteryService)等服务;
注册用于和其他SytemService交互的广播;
调用updateSettingsLocked()方法更新Settings中值的变化;
调用readConfigurationLocked()方法读取配置文件中的默认值;
注册SettingsObserver监听;

到此为止,PMS的启动过程完成。

2. 核心方法updatePowerStateLocked()

updatePowerStateLocked()方法是整个PMS模块的核心方法,也是整个PSM中最重要的一个方法,它用来更新整个Power状态。当Power状态发生改变时,如亮灭屏、电池状态改变、暗屏、WakeLock锁申请/释放…都会调用该方法,并调用其他同级方法进行各个状态的更新:

frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

    private void updatePowerStateLocked() {
        if (!mSystemReady || mDirty == 0 || mUpdatePowerStateInProgress) {
            return;
        }

        Trace.traceBegin(Trace.TRACE_TAG_POWER, "updatePowerState");
        mUpdatePowerStateInProgress = true;
        try {
            // Phase 0: Basic state updates. 基本状态的更新
            updateIsPoweredLocked(mDirty);  //更新充电状态
            updateStayOnLocked(mDirty);  //更新当前是否为屏幕常亮状态,由mStayOn控制
            updateScreenBrightnessBoostLocked(mDirty);  //更新是否需要增强亮度变量

            // Phase 1: Update wakefulness. 更新唤醒状态
            // Loop because the wake lock and user activity computations are influenced
            // by changes in wakefulness.
            // 循环是因为唤醒锁和用户活动计算受到唤醒状态变化的影响。
            final long now = mClock.uptimeMillis();
            int dirtyPhase2 = 0;
            for (;;) { // 循环进行更新流程,直到updateWakefulnessLocked()返回false
                int dirtyPhase1 = mDirty;
                dirtyPhase2 |= dirtyPhase1;
                mDirty = 0;  //清空标记
                // 更新用于统计wakelock的标记值mWakeLockSummary属性
                updateWakeLockSummaryLocked(dirtyPhase1);
                // 更新用于统计用户活动状态的标记值mUserActivitySummary属性
                updateUserActivitySummaryLocked(now, dirtyPhase1);
                // 更新细微模式状态
                updateAttentiveStateLocked(now, dirtyPhase1);
                // 更新唤醒状态,如果状态改变返回true
                if (!updateWakefulnessLocked(dirtyPhase1)) {
                    break;
                }
            }

            // Phase 2: Lock profiles that became inactive/not kept awake.
            updateProfilesLocked(now);

            // Phase 3: Update power state of all PowerGroups. 更新PowerGroups状态
            final boolean powerGroupsBecameReady = updatePowerGroupsLocked(dirtyPhase2);

            // Phase 4: Update dream state (depends on power group ready signal). 更新Dreamland状态
            updateDreamLocked(dirtyPhase2, powerGroupsBecameReady);

            // Phase 5: Send notifications, if needed. 如果wakefulness改变,做最后的收尾工作
            finishWakefulnessChangeIfNeededLocked();

            // Phase 6: Update suspend blocker.
            // Because we might release the last suspend blocker here, we need to make sure
            // we finished everything else first! 更新SuspendBlocker锁状态
            updateSuspendBlockerLocked();
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_POWER);
            mUpdatePowerStateInProgress = false;
        }
    }

下面对以上内容中所有方法逐个进行分析

2.1 updateIsPoweredLocked()更新充电状态

这个方法用于更新mIsPowered属性,它代表当前的充电状态。插拔USB点亮屏幕功能的逻辑,就是在这个方法中。该方法如下:

    private void updateIsPoweredLocked(int dirty) {
        if ((dirty & DIRTY_BATTERY_STATE) != 0) {
            // 记录旧值
            final boolean wasPowered = mIsPowered;
            final int oldPlugType = mPlugType;
            // 获取新值
            mIsPowered = mBatteryManagerInternal.isPowered(BatteryManager.BATTERY_PLUGGED_ANY);
            mPlugType = mBatteryManagerInternal.getPlugType();
            mBatteryLevel = mBatteryManagerInternal.getBatteryLevel();
            mBatteryLevelLow = mBatteryManagerInternal.getBatteryLevelLow();

                        // 当充电状态发生变化
            if (wasPowered != mIsPowered || oldPlugType != mPlugType) {
                mDirty |= DIRTY_IS_POWERED; // 设置标记位DIRTY_IS_POWERED

                // 更新无线充电状态
                final boolean dockedOnWirelessCharger = mWirelessChargerDetector.update(
                        mIsPowered, mPlugType);

                final long now = mClock.uptimeMillis();
                // 插拔USB是否需要亮屏
                if (shouldWakeUpWhenPluggedOrUnpluggedLocked(wasPowered, oldPlugType,
                        dockedOnWirelessCharger)) {
                    // 亮屏流程
                    wakePowerGroupLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP),
                            now, PowerManager.WAKE_REASON_PLUGGED_IN,
                            "android.server.power:PLUGGED:" + mIsPowered, Process.SYSTEM_UID,
                            mContext.getOpPackageName(), Process.SYSTEM_UID);
                }
                // 更新用户活动时间
                userActivityNoUpdateLocked(mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP), now,
                        PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);

                // 播放充电提示音和动画
                if (mBootCompleted) {  //只有在开机完成后才允许播放充电提示声
                    if (mIsPowered && !BatteryManager.isPlugWired(oldPlugType)
                            && BatteryManager.isPlugWired(mPlugType)) {
                        mNotifier.onWiredChargingStarted(mUserId);
                    } else if (dockedOnWirelessCharger) {
                        mNotifier.onWirelessChargingStarted(mBatteryLevel, mUserId);
                    }
                }
            }
            //将充电状态更新到BatterySaverStateMachine
            mBatterySaverStateMachine.setBatteryStatus(mIsPowered, mBatteryLevel, mBatteryLevelLow);
        }
    }

只有对mDirty设置了DIRTY_BATTERY_STATE标记时才会进入这个方法中,那么DIRTY_BATTERY_STATE在什么时候会设置呢?一是当PMS执行systemReady()时,二是当电池信息变化后,由healthd模块上报给BatteryService,BatteryService中则会发出广播Intent.ACTION_BATTERY_CHANGED来通知其他组件,PMS中会接收这个广播并作出处理:

frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

    final class BatteryReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            synchronized (mLock) {
                handleBatteryStateChangedLocked();
            }
        }
    }

    private void handleBatteryStateChangedLocked() {
        mDirty |= DIRTY_BATTERY_STATE;
        updatePowerStateLocked();
    }

因此,只要电池状态发生变化,就会执行这个方法。在这个方法中:

  1. 首先,更新一些如mIsPowered等全局变量。
  2. 然后,通过shouldWakeUpWhenPluggedOrUnpluggedLocked()方法判断是否需要亮屏,这就是插拔USB点亮屏幕功能的逻辑。
  3. 接下来,执行userActivityNoUpdateLocked()方法更新用户活动时间,这个时间决定了何时会自动灭屏,用户每次操作手机(触摸、按键、Other)都会更新到当前时间,用户最后活动时间 + 设置自动休眠时间 = 最终自动灭屏的时间点,这个方法会在后面部分分析。
  4. 再接下来,则调用Notifier对象播放插拔USB音效或动画,Notifier类是PMS模块中用于发送广播、异步通知其他组件的一个类。
  5. 最后,将充电状态传递给mBatterySaverStateMachine中,进行省电策略的调整。

2.2 updateStayOnLocked()更新屏幕常亮状态

这个方法用来更新全局变量mStayOn的值,如果把”开发者选项—不锁定屏幕”这个选项开启后,则在充电时将保持常亮不会自动休眠:

frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

    private void updateStayOnLocked(int dirty) {
        if ((dirty & (DIRTY_BATTERY_STATE | DIRTY_SETTINGS)) != 0) {
            final boolean wasStayOn = mStayOn;
            if (mStayOnWhilePluggedInSetting != 0
                    && !isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
                // 如果任意方式充电(AC/USB/wireless),返回true
                mStayOn = mBatteryManagerInternal.isPowered(mStayOnWhilePluggedInSetting);
            } else {
                mStayOn = false;
            }
            // 状态发生变化时,向mDirty设置DIRTY_STAY_ON标记
            if (mStayOn != wasStayOn) {
                mDirty |= DIRTY_STAY_ON;
            }
        }
    }

只有mDirty设置了DIRTY_BATTERY_STATE或DIRTY_SETTINGS标记位后,才会执行该方法。DIRTY_BATTERY_STATE在电池状态发生变化后设置,DIRTY_SETTINGS是在Settings中的值发生变化后设置,mStayOnWhilePluggedInSetting就是从来自于Settings中”不锁定屏幕”的值,如果发生变化,且处于充电状态,则会更新mStayOn变量的值。在自动灭屏流程中,一旦mStayOn值为true,则永远不会灭屏,从而实现了“不锁定屏幕”这个功能。

2.3 updateScreenBrightnessBoostLocked()更新是否增强亮度

这个方法会更新表示增强亮度的全局变量mScreenBrightnessBoostInProgress,PMS.BinderService提供了boostScreenBrightness()方法,允许其他组件通过该接口将亮度调节到最大(短时间保持),并保持5s后恢复:

    private void updateScreenBrightnessBoostLocked(int dirty) {
        if ((dirty & DIRTY_SCREEN_BRIGHTNESS_BOOST) != 0) {
            if (mScreenBrightnessBoostInProgress) {
                final long now = mClock.uptimeMillis();
                mHandler.removeMessages(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
                if (mLastScreenBrightnessBoostTime > mLastGlobalSleepTime) {
                    final long boostTimeout = mLastScreenBrightnessBoostTime +
                            SCREEN_BRIGHTNESS_BOOST_TIMEOUT;
                    // 向主线程mHandler发出一个异步消息,5s后会再次更新
                    if (boostTimeout > now) {
                        Message msg = mHandler.obtainMessage(MSG_SCREEN_BRIGHTNESS_BOOST_TIMEOUT);
                        msg.setAsynchronous(true);
                        mHandler.sendMessageAtTime(msg, boostTimeout);
                        return;
                    }
                }
                // 表示增强亮度结束
                mScreenBrightnessBoostInProgress = false;
                // 更新用户活动时间
                userActivityNoUpdateLocked(now,
                        PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
            }
        }
    }

只有当mDirty设置了DIRTY_SCREEN_BRIGHTNESS_BOOST标记时,才会执行这个方法。这个标记位就是通过boostScreenBrightness()设置,这个功能在Google原生逻辑中有一个使用场景:

// frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

//是否开启双击Power键定制行为(例如双击打开NFC,相机等)
mDoublePressOnPowerBehavior = mContext.getResources().getInteger(
        com.android.internal.R.integer.config_doublePressOnPowerBehavior);

    // must match: config_doublePressOnPowerBehavior in config.xml
    static final int MULTI_PRESS_POWER_NOTHING = 0;  //默认无
    static final int MULTI_PRESS_POWER_THEATER_MODE = 1;  //剧场模式
    static final int MULTI_PRESS_POWER_BRIGHTNESS_BOOST = 2;  //双击电源键会将亮度调到最大
    static final int MULTI_PRESS_POWER_LAUNCH_TARGET_ACTIVITY = 3;  //双击打开特定应用

2.4 updateWakeLockSummaryLocked()更新WakeLock统计值

从这个方法开始到,直到updateWakefulnessLocked()结束,将会在一个for循环中执行。
该方法用来更新mWakeLockSummary属性,它是用来记录所有WakeLock锁状态的状态值,代表了所有的WakeLock,在请求Display状时作为判断条件确定具体的请求状态。系统规定了系统休眠状态对WakeLock锁的使用影响,如当系统休眠后,常亮锁(PowerManager.SCREEN_BRIGHT等)将会被忽略;系统唤醒后,Doze锁(PowerManager.DOZE_WAKE_LOCK等)将会被忽略:

    private void updateWakeLockSummaryLocked(int dirty) {
        if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_WAKEFULNESS | DIRTY_DISPLAY_GROUP_WAKEFULNESS))
                != 0) {

            mWakeLockSummary = 0;  //初始值为0
            // 将每个ProfilePowerState的mWakeLockSummary也进行重置
            final int numProfiles = mProfilePowerState.size();
            for (int i = 0; i < numProfiles; i++) {
                mProfilePowerState.valueAt(i).mWakeLockSummary = 0;
            }
            // 将每个mPowerGroups的setWakeLockSummaryLocked也进行重置
            for (int idx = 0; idx < mPowerGroups.size(); idx++) {
                mPowerGroups.valueAt(idx).setWakeLockSummaryLocked(0);
            }

            int invalidGroupWakeLockSummary = 0;
            final int numWakeLocks = mWakeLocks.size();
            // 遍历mWakeLocks列表
            for (int i = 0; i < numWakeLocks; i++) {
                final WakeLock wakeLock = mWakeLocks.get(i);
                final Integer groupId = wakeLock.getPowerGroupId();
                // a wakelock with an invalid group ID should affect all groups
                if (groupId == null || (groupId != Display.INVALID_DISPLAY_GROUP
                        && !mPowerGroups.contains(groupId))) {
                    continue;
                }

                final PowerGroup powerGroup = mPowerGroups.get(groupId);
                // 获取每个WakeLock对应的Flag标记
                final int wakeLockFlags = getWakeLockSummaryFlags(wakeLock);
                 // 标记在mWakeLockSummary上
                mWakeLockSummary |= wakeLockFlags;

                if (groupId != Display.INVALID_DISPLAY_GROUP) {
                    int wakeLockSummary = powerGroup.getWakeLockSummaryLocked();
                    wakeLockSummary |= wakeLockFlags;
                    powerGroup.setWakeLockSummaryLocked(wakeLockSummary);
                } else {
                    invalidGroupWakeLockSummary |= wakeLockFlags;
                }
                // 对每个ProfilePowerState#mWakeLockSummary也进行标记
                for (int j = 0; j < numProfiles; j++) {
                    final ProfilePowerState profile = mProfilePowerState.valueAt(j);
                    if (wakeLockAffectsUser(wakeLock, profile.mUserId)) {
                        profile.mWakeLockSummary |= wakeLockFlags;
                    }
                }
            }

            for (int idx = 0; idx < mPowerGroups.size(); idx++) {
                final PowerGroup powerGroup = mPowerGroups.valueAt(idx);
                final int wakeLockSummary = adjustWakeLockSummary(powerGroup.getWakefulnessLocked(),
                        invalidGroupWakeLockSummary | powerGroup.getWakeLockSummaryLocked());
                powerGroup.setWakeLockSummaryLocked(wakeLockSummary);
            }
            // 根据系统状态对mWakeLockSummary进行调整
            mWakeLockSummary = adjustWakeLockSummary(getGlobalWakefulnessLocked(),
                    mWakeLockSummary);
            // 对每个ProfilePowerState#mWakeLockSummary也进行调整
            for (int i = 0; i < numProfiles; i++) {
                final ProfilePowerState profile = mProfilePowerState.valueAt(i);
                profile.mWakeLockSummary = adjustWakeLockSummary(getGlobalWakefulnessLocked(),
                        profile.mWakeLockSummary);
            }
        }
    }

只有当mDirty设置了DIRTY_WAKE_LOCKS和DIRTY_WAKEFULNESS标记位时,才会执行该方法。DIRTY_WAKE_LOCKS在申请WakeLock锁时设置,DIRTY_WAKEFULNESS在系统唤醒状态发生变化时设置。
进入该方法后,首先从保存了WakeLock的List中进行遍历,并根据WakeLock类型给mWakeLockSummary设置标记,这些标记位如下:

// frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

    // Summarizes the state of all active wakelocks.
    static final int WAKE_LOCK_CPU = 1 << 0;  // 表示需要CPU保持唤醒状态
    static final int WAKE_LOCK_SCREEN_BRIGHT = 1 << 1;  // 表示持有FULL_WAKE_LOCK锁,需要屏幕常亮
    static final int WAKE_LOCK_SCREEN_DIM = 1 << 2;  // 表示持有SCREEN_DIM_WAKE_LOCK锁,需要保持dim不灭屏
    static final int WAKE_LOCK_BUTTON_BRIGHT = 1 << 3;  //表示持有FULL_WAKE_LOCK锁,需要按键灯常亮
    static final int WAKE_LOCK_PROXIMITY_SCREEN_OFF = 1 << 4;  // 表示持有Psensor WakeLock锁
    static final int WAKE_LOCK_STAY_AWAKE = 1 << 5; // only set if already awake  // 表示保持屏幕常亮(只能用在awake状态时)
    static final int WAKE_LOCK_DOZE = 1 << 6;   // 表示持有DOZE_WAKE_LOCK锁
    static final int WAKE_LOCK_DRAW = 1 << 7;   //表示持有DRAW_WAKE_LOCK锁

然后将根据系统状态进行调整:

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
// frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

private static int adjustWakeLockSummary(int wakefulness, int wakeLockSummary) {
// Cancel wake locks that make no sense based on the current state.
// 唤醒状态不处于Doze状态时,忽略掉PowerManager.DOZE_WAKE_LOCK和PowerManager.DRAW_WAKE_LOCK两类型锁
if (wakefulness != WAKEFULNESS_DOZING) {
wakeLockSummary &= ~(WAKE_LOCK_DOZE | WAKE_LOCK_DRAW);
}
// 唤醒状态处于Asleep状态或者Doze状态时,忽略掉屏幕常亮锁、PSensor锁
if (wakefulness == WAKEFULNESS_ASLEEP
|| (wakeLockSummary & WAKE_LOCK_DOZE) != 0) {
wakeLockSummary &= ~(WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM
| WAKE_LOCK_BUTTON_BRIGHT);
if (wakefulness == WAKEFULNESS_ASLEEP) {
wakeLockSummary &= ~WAKE_LOCK_PROXIMITY_SCREEN_OFF;
}
}

// Infer implied wake locks where necessary based on the current state.
if ((wakeLockSummary & (WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_SCREEN_DIM)) != 0) {
// 唤醒状态处于Awake状态,WAKE_LOCK_STAY_AWAKE只用于awake状态时
if (wakefulness == WAKEFULNESS_AWAKE) {
wakeLockSummary |= WAKE_LOCK_CPU | WAKE_LOCK_STAY_AWAKE;
} else if (wakefulness == WAKEFULNESS_DREAMING) { // 唤醒状态处于Awake状态,WAKE_LOCK_STAY_AWAKE只用于awake状态时
wakeLockSummary |= WAKE_LOCK_CPU;
}
}
// 有DRAW_WAKE_LOCK锁时,需要CPU保持唤醒
if ((wakeLockSummary & WAKE_LOCK_DRAW) != 0) {
wakeLockSummary |= WAKE_LOCK_CPU;
}

return wakeLockSummary;
}

在平时分析处理不灭屏相关Bug时,通过该值可确定当前系统持有哪些类型的锁。

最终得到mWakeLockSummary,在自动灭屏流程中将使用起到重要作用,当自动灭屏时,如果mWakeLockSummary设置有WAKE_LOCK_STAY_AWAKE标记位,那么将不会灭屏。
此外,上面方法中出现了对ProfilePowerState对象的处理,它用来对不同user进行不同参数的设置,在多用户模式下,可以支持不同的状态,这部分略去。

2.5 updateUserActivitySummaryLocked()更新用户活动状态

这个方法用来更新全局变量mUserActivitySummary,它表示用户活动状态,有三个值:

    // Summarizes the user activity state.
    static final int USER_ACTIVITY_SCREEN_BRIGHT = 1 << 0;  // 表示亮屏状态下的交互
    static final int USER_ACTIVITY_SCREEN_DIM = 1 << 1;  // 表示Dim状态下的交互
    static final int USER_ACTIVITY_SCREEN_DREAM = 1 << 2;  // 表示Dreamland状态下的交互

何时开始自动灭屏,就是这个方法中实现的。当设备和用户有交互时,都会根据当前时间和自动灭屏时间、Dim时长、当前唤醒状态计算下次休眠的时间,完成自动灭屏的操作。由亮屏进入Dim的时长、Dim到灭屏的时长、亮屏到屏保的时长,都是在这里计算的,这个方法的详细分析见后面的灭屏流程篇。

2.6 updateAttentiveStateLocked()更新细微模式状态

这个方法用来更新细微模式状态,这是Android R上新添加的一个功能,其目的就是解决用户长时间没有操作但一直持有亮屏锁导致系统不灭屏这个场景的,算是一个省电优化项,看下是如何实现的:

//frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

    private void updateAttentiveStateLocked(long now, int dirty) {
        // 触发细微模式的时间阈值
        long attentiveTimeout = getAttentiveTimeoutLocked();
        // Attentive state only applies to the default display group.
        // 自动休眠时间
        long goToSleepTime = mPowerGroups.get(
                Display.DEFAULT_DISPLAY_GROUP).getLastUserActivityTimeLocked() + attentiveTimeout;
         // 细微模式提示Dialog弹出时间
        long showWarningTime = goToSleepTime - mAttentiveWarningDurationConfig;
        // 是否已经弹出提升对话框
        boolean warningDismissed = maybeHideInattentiveSleepWarningLocked(now, showWarningTime);

        if (attentiveTimeout >= 0 && (warningDismissed
                || (dirty & (DIRTY_ATTENTIVE | DIRTY_STAY_ON | DIRTY_SCREEN_BRIGHTNESS_BOOST
                | DIRTY_PROXIMITY_POSITIVE | DIRTY_WAKEFULNESS | DIRTY_BOOT_COMPLETED
                | DIRTY_SETTINGS)) != 0)) {

            mHandler.removeMessages(MSG_ATTENTIVE_TIMEOUT);
            // 是否需要弹出警告
            if (isBeingKeptFromInattentiveSleepLocked()) {
                return;
            }

            long nextTimeout = -1;

            if (now < showWarningTime) {
                nextTimeout = showWarningTime;
            } else if (now < goToSleepTime) {
                // 弹出警告给用户
                mInattentiveSleepWarningOverlayController.show();
                nextTimeout = goToSleepTime;
            }
             // 下一次进入时将会灭屏
            if (nextTimeout >= 0) {
                scheduleAttentiveTimeout(nextTimeout);
            }
        }
    }

这里提供了两个配置值:

  • mAttentiveWarningDurationConfig表示触发细微模式前,弹出警告的时长,到达该时间时,会弹出对话框提示用户是否还要亮屏;
  • mAttentiveTimeoutConfig表示触发细微模式的时间阈值,到达该时长后,会进行自动灭屏;
    这种情况下,即使没有达到用户设置的自动休眠时间,也会进行自动灭屏。

2.7 updateWakefulnessLocked()是否需要更新唤醒状态

这个方法也和自动灭屏流程有关。如果满足自动灭屏条件,会更新系统唤醒状态。
这三个方法放在for(;;)循环中执行,是因为它们共同决定了设备的唤醒状态,前两个方法是汇总状态,后一个方法是根据前两个方法汇总的值而进行判断是否要改变当前的设备唤醒状态,汇总状态会受mWakefulness的影响,因此会进行循环处理。
同时,也仅仅会在超时灭屏进入睡眠或屏保时,for循环会执行两次,其他情况下,只会执行一次。这个方法的详细分析见PMS灭屏流程。

2.8 updateProfilesLocked()

以上几个方法针对全局状态进行更新,这个方法则根据ProfilePowerState中保存的状态,更新不同用户是否进入锁定状态,由于使用场景不是很高,这里暂且略过。

2.9 updatePowerGroupsLocked

该方法用于请求并更新Display状态,在这个方法中,会确定多个影响Display状态的属性,并将这些值封装到DisplayPowerRequest对象中,向DisplayMangerService发起请求,最终由DMS完成Display亮度、状态的更新:

    private boolean updatePowerGroupsLocked(int dirty) {
        final boolean oldPowerGroupsReady = areAllPowerGroupsReadyLocked();
        if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY | DIRTY_WAKEFULNESS
                | DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED | DIRTY_BOOT_COMPLETED
                | DIRTY_SETTINGS | DIRTY_SCREEN_BRIGHTNESS_BOOST | DIRTY_VR_MODE_CHANGED |
                DIRTY_QUIESCENT | DIRTY_DISPLAY_GROUP_WAKEFULNESS)) != 0) {
            if ((dirty & DIRTY_QUIESCENT) != 0) {
                if (areAllPowerGroupsReadyLocked()) {
                    sQuiescent = false;
                } else {
                    mDirty |= DIRTY_QUIESCENT;
                }
            }

            for (int idx = 0; idx < mPowerGroups.size(); idx++) {
                final PowerGroup powerGroup = mPowerGroups.valueAt(idx);
                final int groupId = powerGroup.getGroupId();

                // Determine appropriate screen brightness and auto-brightness adjustments.
                final boolean autoBrightness;  // 自动亮度是否开启
                final float screenBrightnessOverride;  // 是否有覆盖亮度
                if (!mBootCompleted) {
                    //启动过程中要求亮度稳定,要求默认亮度和Bootloader中设定的亮度值保持一致
                    autoBrightness = false;  //不开启自动亮度
                    screenBrightnessOverride = mScreenBrightnessDefault;  //使用默认值
                } else if (isValidBrightness(mScreenBrightnessOverrideFromWindowManager)) {
                    //使用WindowManager覆盖的亮度值
                    autoBrightness = false;
                    screenBrightnessOverride = mScreenBrightnessOverrideFromWindowManager;
                } else {
                    autoBrightness = (mScreenBrightnessModeSetting
                            == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
                    screenBrightnessOverride = PowerManager.BRIGHTNESS_INVALID_FLOAT;
                }
                //向DisplayMangerService发起请
                boolean ready = powerGroup.updateLocked(screenBrightnessOverride, autoBrightness,
                        shouldUseProximitySensorLocked(), shouldBoostScreenBrightness(),
                        mDozeScreenStateOverrideFromDreamManager,
                        mDozeScreenBrightnessOverrideFromDreamManagerFloat,
                        mDrawWakeLockOverrideFromSidekick,
                        mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.SCREEN_BRIGHTNESS),
                        sQuiescent, mDozeAfterScreenOff, mIsVrModeEnabled, mBootCompleted,
                        mScreenBrightnessBoostInProgress, mRequestWaitForNegativeProximity);
                int wakefulness = powerGroup.getWakefulnessLocked();

                final boolean displayReadyStateChanged = powerGroup.setReadyLocked(ready);
                final boolean poweringOn = powerGroup.isPoweringOnLocked();
                if (ready && displayReadyStateChanged && poweringOn
                        && wakefulness == WAKEFULNESS_AWAKE) {
                    powerGroup.setIsPoweringOnLocked(false);
                    LatencyTracker.getInstance(mContext).onActionEnd(ACTION_TURN_ON_SCREEN);
                    Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, TRACE_SCREEN_ON, groupId);
                    final int latencyMs = (int) (mClock.uptimeMillis()
                            - powerGroup.getLastPowerOnTimeLocked());
                    // 如果亮屏流程超过200ms,输出亮屏所用时间
                    if (latencyMs >= SCREEN_ON_LATENCY_WARNING_MS) {
                        Slog.w(TAG, "Screen on took " + latencyMs + " ms");
                    }
                }
            }
            // 释放PSensor WakeLock锁时的一个标记
            mRequestWaitForNegativeProximity = false;
        }

        return areAllPowerGroupsReadyLocked() && !oldPowerGroupsReady;
    }
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
  boolean updateLocked(float screenBrightnessOverride, boolean autoBrightness,
boolean useProximitySensor, boolean boostScreenBrightness, int dozeScreenState,
float dozeScreenBrightness, boolean overrideDrawWakeLock,
PowerSaveState powerSaverState, boolean quiescent, boolean dozeAfterScreenOff,
boolean vrModeEnabled, boolean bootCompleted, boolean screenBrightnessBoostInProgress,
boolean waitForNegativeProximity) {
// 根据系统唤醒状态获取请求的'策略': off, doze, dim or bright.
mDisplayPowerRequest.policy = getDesiredScreenPolicyLocked(quiescent, dozeAfterScreenOff,
vrModeEnabled, bootCompleted, screenBrightnessBoostInProgress);
// WindowManager覆盖的亮度值,如播放视频时调节亮度
mDisplayPowerRequest.screenBrightnessOverride = screenBrightnessOverride;
// 是否使用自动亮度
mDisplayPowerRequest.useAutoBrightness = autoBrightness;
// 是否存在PSensor Wakelock锁
mDisplayPowerRequest.useProximitySensor = useProximitySensor;
// 是否有增强亮度
mDisplayPowerRequest.boostScreenBrightness = boostScreenBrightness;
// 唤醒状态为Doze时,确定display的状态
if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) {
mDisplayPowerRequest.dozeScreenState = dozeScreenState;
if ((getWakeLockSummaryLocked() & WAKE_LOCK_DRAW) != 0 && !overrideDrawWakeLock) {
if (mDisplayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND) {
mDisplayPowerRequest.dozeScreenState = Display.STATE_DOZE;
}
if (mDisplayPowerRequest.dozeScreenState == Display.STATE_ON_SUSPEND) {
mDisplayPowerRequest.dozeScreenState = Display.STATE_ON;
}
}
// Doze时的屏幕亮度
mDisplayPowerRequest.dozeScreenBrightness = dozeScreenBrightness;
} else {
mDisplayPowerRequest.dozeScreenState = Display.STATE_UNKNOWN;
mDisplayPowerRequest.dozeScreenBrightness = PowerManager.BRIGHTNESS_INVALID_FLOAT;
}
mDisplayPowerRequest.lowPowerMode = powerSaverState.batterySaverEnabled;
mDisplayPowerRequest.screenLowPowerBrightnessFactor = powerSaverState.brightnessFactor;
// 发起请求,返回值表示DisplayPowerController中是否完成这次请求
boolean ready = mDisplayManagerInternal.requestPowerState(mGroupId, mDisplayPowerRequest,
waitForNegativeProximity);
mNotifier.onScreenPolicyUpdate(mGroupId, mDisplayPowerRequest.policy);
return ready;
}

在向DisplayManagerService发起请求时,会将所有的信息封装到DisplayPowerRequest对象中,其中,policy属性值有五类:

  • POLICY_OFF:请求屏幕进入灭屏状态;
  • POLICY_DOZE:请求屏幕进入Doze状态;
  • POLICY_DIM:请求屏幕进入Dim状态,
  • POLICY_BRIGHT:请求屏幕处于正常亮屏状态;
  • POLICY_VR:VR模式相关;

在请求前,通过getDesiredScreenPolicyLocked()方法,根据当前唤醒状态和WakeLock统计状态来决定要请求的Display状态:

    int getDesiredScreenPolicyLocked(boolean quiescent, boolean dozeAfterScreenOff,
            boolean vrModeEnabled, boolean bootCompleted, boolean screenBrightnessBoostInProgress) {
        final int wakefulness = getWakefulnessLocked();
        final int wakeLockSummary = getWakeLockSummaryLocked();
        // 当前唤醒状态为Asleep,则Display状态会设置为OFF
        if (wakefulness == WAKEFULNESS_ASLEEP || quiescent) {
            return DisplayPowerRequest.POLICY_OFF;
        } else if (wakefulness == WAKEFULNESS_DOZING) {  // 当前唤醒状态为Doze,则Display状态会设置为Doze指定的状态
            if ((wakeLockSummary & WAKE_LOCK_DOZE) != 0) {
                return DisplayPowerRequest.POLICY_DOZE;
            }
            // 表示跳过Doze的状态,直接设置成OFF
            if (dozeAfterScreenOff) {
                return DisplayPowerRequest.POLICY_OFF;
            }
            // Fall through and preserve the current screen policy if not configured to
            // doze after screen off.  This causes the screen off transition to be skipped.
        }

        //如果开启了VR模式则设置为VR模式
        if (vrModeEnabled) {
            return DisplayPowerRequest.POLICY_VR;
        }
        // 如果存在亮屏锁、用户活动状态为亮屏、进行增强亮度,则Display状态将设置为ON
        if ((wakeLockSummary & WAKE_LOCK_SCREEN_BRIGHT) != 0
                || !bootCompleted
                || (getUserActivitySummaryLocked() & USER_ACTIVITY_SCREEN_BRIGHT) != 0
                || screenBrightnessBoostInProgress) {
            return DisplayPowerRequest.POLICY_BRIGHT;
        }
        // 不满足以上条件,默认设置DIM
        return DisplayPowerRequest.POLICY_DIM;
    }

2.10 updateDreamLocked()

该方法用来更新设备Dreamland状态,比如是否进入Dream、Doze或者开始休眠:

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
// frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

private void updateDreamLocked(int dirty, boolean powerGroupBecameReady) {
if ((dirty & (DIRTY_WAKEFULNESS
| DIRTY_USER_ACTIVITY
| DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED
| DIRTY_ATTENTIVE
| DIRTY_WAKE_LOCKS
| DIRTY_BOOT_COMPLETED
| DIRTY_SETTINGS
| DIRTY_IS_POWERED
| DIRTY_STAY_ON
| DIRTY_PROXIMITY_POSITIVE
| DIRTY_BATTERY_STATE)) != 0 || powerGroupBecameReady) {
if (areAllPowerGroupsReadyLocked()) { //areAllPowerGroupsReadyLocked为ture后,才会进一步执行
//通过Handler异步发送一个消息
scheduleSandmanLocked();
}
}
}

private boolean areAllPowerGroupsReadyLocked() {
final int size = mPowerGroups.size();
for (int i = 0; i < size; i++) {
if (!mPowerGroups.valueAt(i).isReadyLocked()) {
return false;
}
}
return true;
}

可以看到,对于Dreamland相关状态的更新,依赖areAllPowerGroupsReadyLocked的返回值,它表示每一个display是否已经准备就绪,因此只有在准备就绪的情况下才会进一步调用该方法的方法体。最后会PMS主线程中,调用handleSandman()方法执行Dreamland的操作:

// frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

    private void handleSandman(int groupId) { // runs on handler thread
        // Handle preconditions.
        final boolean startDreaming;
        final int wakefulness;
        synchronized (mLock) {
            mSandmanScheduled = false;

            final PowerGroup powerGroup = mPowerGroups.get(groupId);
            wakefulness = powerGroup.getWakefulnessLocked();
            // 如果召唤了"睡魔",且每个Display状态已经准备完毕
            if ((wakefulness == WAKEFULNESS_DREAMING || wakefulness == WAKEFULNESS_DOZING) &&
                    powerGroup.isSandmanSummonedLocked() && powerGroup.isReadyLocked()) {
                // 判断是否可以进入Dreamland
                startDreaming = canDreamLocked(powerGroup) || canDozeLocked(powerGroup);
                powerGroup.setSandmanSummonedLocked(/* isSandmanSummoned= */ false);
            } else {
                startDreaming = false;
            }
        }

        // Start dreaming if needed.
        // We only control the dream on the handler thread, so we don't need to worry about
        // concurrent attempts to start or stop the dream.
        final boolean isDreaming;
        if (mDreamManager != null) {
            // Restart the dream whenever the sandman is summoned.
            if (startDreaming) {
                mDreamManager.stopDream(/* immediate= */ false);
                // 开始进入Dreamland
                mDreamManager.startDream(wakefulness == WAKEFULNESS_DOZING);
            }
            isDreaming = mDreamManager.isDreaming();
        } else {
            isDreaming = false;
        }

        // At this point, we either attempted to start the dream or no attempt will be made,
        // so stop holding the display suspend blocker for Doze.
        mDozeStartInProgress = false;

        // Update dream state.
        synchronized (mLock) {
            ...

            // Remember the initial battery level when the dream started.
            // 记录下进入Dream模式前的初始电量值
            if (startDreaming && isDreaming) {
                mBatteryLevelWhenDreamStarted = mBatteryLevel;
                if (wakefulness == WAKEFULNESS_DOZING) {
                    Slog.i(TAG, "Dozing...");
                } else {
                    Slog.i(TAG, "Dreaming...");
                }
            }

            // If preconditions changed, wait for the next iteration to determine
            // whether the dream should continue (or be restarted).
            final PowerGroup powerGroup = mPowerGroups.get(groupId);
            if (powerGroup.isSandmanSummonedLocked()
                    || powerGroup.getWakefulnessLocked() != wakefulness) {
                return; // wait for next cycle
            }

            // Determine whether the dream should continue.
            long now = mClock.uptimeMillis();
            if (wakefulness == WAKEFULNESS_DREAMING) {
                if (isDreaming && canDreamLocked(powerGroup)) {
                    if (mDreamsBatteryLevelDrainCutoffConfig >= 0
                            && mBatteryLevel < mBatteryLevelWhenDreamStarted
                                    - mDreamsBatteryLevelDrainCutoffConfig
                            && !isBeingKeptAwakeLocked(powerGroup)) {
                            //充电速度慢于消耗速度或者用户活动timeout已过则退出Dream进入睡眠
                    } else {
                        return; // continue dreaming 继续维持Dream状态
                    }
                }

                // Dream has ended or will be stopped.  Update the power state.
                // 退出Dreamland,进入休眠状态
                if (isItBedTimeYetLocked(powerGroup)) {
                    if (isAttentiveTimeoutExpired(powerGroup, now)) {
                        //更新睡眠状态
                        sleepPowerGroupLocked(powerGroup, now,
                                PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, Process.SYSTEM_UID);
                    } else {
                        //更新doze状态
                        dozePowerGroupLocked(powerGroup, now,
                                PowerManager.GO_TO_SLEEP_REASON_TIMEOUT, Process.SYSTEM_UID);
                    }
                } else {
                    // 唤醒设备
                    wakePowerGroupLocked(powerGroup, now,
                            PowerManager.WAKE_REASON_DREAM_FINISHED,
                            "android.server.power:DREAM_FINISHED", Process.SYSTEM_UID,
                            mContext.getOpPackageName(), Process.SYSTEM_UID);
                }
            } else if (wakefulness == WAKEFULNESS_DOZING) {
                if (isDreaming) {
                    return; // continue dozing 继续保持doze状态
                }
                
                // Doze has ended or will be stopped.  Update the power state.
                // 更新睡眠状态
                sleepPowerGroupLocked(powerGroup, now,  PowerManager.GO_TO_SLEEP_REASON_TIMEOUT,
                        Process.SYSTEM_UID);
            }
        }

        // Stop dream.
        if (isDreaming) {
            mDreamManager.stopDream(/* immediate= */ false);
        }
    }

在以上方法中,将会调用DreamManager处理具体的Dreamland逻辑,这部分流程的分析,在DreamManagerService模块分析时会进行详细分析。

2.11 finishWakefulnessChangeIfNeededLocked()

该方法主要做唤醒状态发生变化后,后半部分更新工作:

//frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

    @GuardedBy("mLock")
    private void finishWakefulnessChangeIfNeededLocked() {
        if (mWakefulnessChanging && areAllPowerGroupsReadyLocked()) {
            if (getGlobalWakefulnessLocked() == WAKEFULNESS_DOZING
                    && (mWakeLockSummary & WAKE_LOCK_DOZE) == 0) {
                return; // wait until dream has enabled dozing
            } else {
                // Doze wakelock acquired (doze started) or device is no longer dozing.
                mDozeStartInProgress = false;
            }Android采码蜂:
            if (getGlobalWakefulnessLocked() == WAKEFULNESS_DOZING
                    || getGlobalWakefulnessLocked() == WAKEFULNESS_ASLEEP) {
                logSleepTimeoutRecapturedLocked();
            }
            mWakefulnessChanging = false;
            mNotifier.onWakefulnessChangeFinished();
        }
    }

只有当屏幕状态改变后,才会执行该方法。进入该方法后,将通过Notifier#onWakefulnessChangeFinished()方法发送亮屏、灭屏广播等。

该方法中的logScreenOn()方法将打印出整个亮屏流程的耗时,在平时处理问题时很有帮助。

2.12 updateSuspendBlockerLocked()

这个方法用来更新SuspendBlocker锁状态。Suspend锁机制是Android框架中锁机的一种锁,它代表了框架层以上所有的WakeLock。Wakelock锁是APP或其他组建向PMS模块申请,而Suspend锁是PMS模块中对WakeLock锁的最终表现,或者说上层应用或system_server其他组件申请了wakelock锁后,在PMS中最终都会表现为Suspend锁,通过Suspend锁向Hal层写入节点,Kernal层会读取节点,从而唤醒或者休眠CPU
该方法的详细分析在PMS WakeLock机制中进行汇总。
到此为止,对PMS中所有核心方法进行了简单的分析,有些方法仅仅说明了下作用,会在后面具体业务中进行详细分析。

跟着学习自: Android R PowerManagerService模块(1) 启动流程和核心方法

前面我们已经梳理了input事件在native层的传递,这一篇我们接着探索input事件在应用中的传递与处理,我们将按键事件和触摸事件分开梳理,这一篇就只涉及触摸事件。

一、事件的接收

从前面的篇幅我们知道,framework native层InputDispatcher向应用通过socket方式发送事件,应用的Looper 通过epoll方式监听sockcet的fd, 当应用的socket变为可读时(例如,inputDispatcher向socket中写入数据),Looper将回调handleEvent。 此时,应用应读取已进入套接字的事件。 只要socket中有未读事件,函数 handleEvent 就会继续触发。

NativeInputEventReceiver::handleEvent
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
//frameworks/base/core/jni/android_view_InputEventReceiver.cpp

int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) {
// Allowed return values of this function as documented in LooperCallback::handleEvent
constexpr int REMOVE_CALLBACK = 0;
constexpr int KEEP_CALLBACK = 1;
//注意:下面这个event不是真正的输入事件,只是Looper的event
if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
//当inputdispatcher异常导致socket被关闭或者目标窗口正在被移除或者传递窗口时输入法,但是输入法正在关闭时会直接抛弃这个事件
return REMOVE_CALLBACK;
}
//如果是传入的事件,即是inputDispatcher传递过来的事件时需要处理时
//回调java层的consumeEvents方法
if (events & ALOOPER_EVENT_INPUT) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
status_t status = consumeEvents(env, false /*consumeBatches*/, -1, nullptr);
mMessageQueue->raiseAndClearException(env, "handleReceiveCallback");
return status == OK || status == NO_MEMORY ? KEEP_CALLBACK : REMOVE_CALLBACK;
}
//如果是要传出的事件,即已处理的事件需要告知inputdispatcher这个事件已处理时
if (events & ALOOPER_EVENT_OUTPUT) {
const status_t status = processOutboundEvents();
if (status == OK || status == WOULD_BLOCK) {
return KEEP_CALLBACK;
} else {
return REMOVE_CALLBACK;
}
}

return KEEP_CALLBACK;
}

这里既会监视inputDispatcher发送过来的事件(准确的说应该是InputPublisher发过来的)也监视当前进程发送已经消费的事件发给Looper的行为,无论是接收来自InputPublisher的事件,还是来自当前进程的事件,都会被looper监听到并回调handleEvent。这里就用events中的标志位来区分(ALOOPER_EVENT_INPUTALOOPER_EVENT_OUTPUT)对于接收来自InputPublisher的事件则调consumeEvents方法处理.

NativeInputEventReceiver::consumeEvents
//frameworks/base/core/jni/android_view_InputEventReceiver.cpp

status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
        bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) {
    ...

    ScopedLocalRef<jobject> receiverObj(env, nullptr);
    bool skipCallbacks = false;
    for (;;) {
        uint32_t seq;
        InputEvent* inputEvent;
        //获取mInputConsumer发过来的事件,并构建成具体的某种InputEvent,例如MotionEvent
        status_t status = mInputConsumer.consume(&mInputEventFactory,
                consumeBatches, frameTime, &seq, &inputEvent);
        if (status != OK && status != WOULD_BLOCK) {
            ALOGE("channel '%s' ~ Failed to consume input event.  status=%s(%d)",
                  getInputChannelName().c_str(), statusToString(status).c_str(), status);
            return status;
        }
        ...
InputConsumer::consume
//frameworks/native/libs/input/InputTransport.cpp

status_t InputConsumer::consume(InputEventFactoryInterface* factory, bool consumeBatches,
                                nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {
    ...
    *outSeq = 0;
    *outEvent = nullptr;

    // Fetch the next input message.
    // Loop until an event can be returned or no additional events are received.
    while (!*outEvent) {  //获取到一次真正的事件就退出
        if (mMsgDeferred) {
            ...
        } else {
            // Receive a fresh message.
            status_t result = mChannel->receiveMessage(&mMsg);  //通过InputChannel来接收socket中真正的InputMessage(描述事件的结构体)
            ...
        }
        ...
        }
    }
    return OK;
}

InputConsumer::consume中获取事件实际上是通过InputChannel去读取

InputChannel::receiveMessage
frameworks/native/libs/input/InputTransport.cpp

status_t InputChannel::receiveMessage(InputMessage* msg) {
    ssize_t nRead;
    do {
        nRead = ::recv(getFd(), msg, sizeof(InputMessage), MSG_DONTWAIT); //在这里真正的读取socket fd,并将输入事件信息装入msg(InputMessage)
    } while (nRead == -1 && errno == EINTR);
    
    ...
    
    return OK;  //最后返回OK
}

通过InputChannel去读取真正的事件信息,并装入InputMessage对象,最后返回OK

InputChannel::receiveMessage
frameworks/native/libs/input/InputTransport.cpp

status_t InputChannel::receiveMessage(InputMessage* msg) {
    ssize_t nRead;
    do {
        nRead = ::recv(getFd(), msg, sizeof(InputMessage), MSG_DONTWAIT); //在这里真正的读取socket fd,并将输入事件信息装入msg(InputMessage)
    } while (nRead == -1 && errno == EINTR);
    
    ...
    
    return OK;  //最后返回OK
}

通过InputChannel去读取真正的事件信息,并装入InputMessage对象,最后返回OK;

创建并使用InputMessager中的事件信息填充MotionEvent,然后继续往下执行 NativeInputEventReceiver::consumeEvents

NativeInputEventReceiver::consumeEvents
//frameworks/base/core/jni/android_view_InputEventReceiver.cpp

status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
        bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) {
    ...
    for (;;) {
        uint32_t seq;
        InputEvent* inputEvent;
        //真正的去获取socket发过来的事件,并构建成具体的某种InputEvent,例MotionEvent
        //上面的分析从这里进入的,返回到这里继续往下分析
        status_t status = mInputConsumer.consume(&mInputEventFactory,
                consumeBatches, frameTime, &seq, &inputEvent);
        ...
        if (!skipCallbacks) {
            jobject inputEventObj;
            switch (inputEvent->getType()) {
            case AINPUT_EVENT_TYPE_MOTION: {
                MotionEvent* motionEvent = static_cast<MotionEvent*>(inputEvent);
                if ((motionEvent->getAction() & AMOTION_EVENT_ACTION_MOVE) && outConsumedBatch) {
                    *outConsumedBatch = true;
                }
                //创建一个java层MotionEvent对象
                inputEventObj = android_view_MotionEvent_obtainAsCopy(env, motionEvent);
                break;
                }
            }
            ...
            if (inputEventObj) {
                ...//jni调用InputEventReceiver.java中的InputEventReceiver,将事件传递到java的世界
                //
                env->CallVoidMethod(receiverObj.get(),
                        gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj);  
                ...
                env->DeleteLocalRef(inputEventObj);
            }
            ...
        }
    }
}
dispatchInputEvent
1
2
3
4
5
6
7
8
9
10
11
12
13
//frameworks/base/core/java/android/view/InputEventReceiver.java

public abstract class InputEventReceiver {
...
// //从native执行的调用
@SuppressWarnings("unused")
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
private void dispatchInputEvent(int seq, InputEvent event) {
mSeqMap.put(event.getSequenceNumber(), seq);
onInputEvent(event);
}
...
}

InputEventReceiver是一个抽象类,但是对应的dispatchInputEvent方法,它的子类WindowInputEventReceiver并没有实现,所以native层调用父类的InputEventReceiver的方法,这个方法中接着调用了onInputEvent接着处理。onInputEvent子类是有实现的,所以会走子类的方法。

onInputEvent
//frameworks/base/core/java/android/view/ViewRootImpl.java
    ...
    final class WindowInputEventReceiver extends InputEventReceiver {
        public WindowInputEventReceiver(InputChannel inputChannel, Looper looper) {
            super(inputChannel, looper);
        }

        @Override
        public void onInputEvent(InputEvent event) {
            Trace.traceBegin(Trace.TRACE_TAG_VIEW, "processInputEventForCompatibility");
            List<InputEvent> processedEvents;
            try {
                //对M版本之前的触摸事件的兼容处理
                processedEvents =
                    mInputCompatProcessor.processInputEventForCompatibility(event); 
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
            }
            if (processedEvents != null) {
                ...
            } else {  //因为上面返回null 所以走到这里
                //在这里将自己this传入
                //processImmediately 为true意味着需要马上处理,而不是延迟处理       
                enqueueInputEvent(event, this, 0, true);
            }
        }
    ...

onInputEvent中会通过QueuedInputEventenqueueInputEvent将事件加入队列中再处理

enqueueInputEvent
//frameworks/base/core/java/android/view/ViewRootImpl.java
        
    @UnsupportedAppUsage
    void enqueueInputEvent(InputEvent event,
            InputEventReceiver receiver, int flags, boolean processImmediately) {
        QueuedInputEvent q = obtainQueuedInputEvent(event, receiver, flags);  //将事件加入队列,确保事件的有序处理

        if (event instanceof MotionEvent) {
            MotionEvent me = (MotionEvent) event;
            if (me.getAction() == MotionEvent.ACTION_CANCEL) {
                //inputDispatcher中会根据实际焦点和触摸坐标的关系或者事件是有down无up情形设置ACTION_CANCEL
            }
        } else if (event instanceof KeyEvent) {
            ...
        }
        // Always enqueue the input event in order, regardless of its time stamp.
        // We do this because the application or the IME may inject key events
        // in response to touch events and we want to ensure that the injected keys
        // are processed in the order they were received and we cannot trust that
        // the time stamp of injected events are monotonic.
        // 无论时间戳如何,始终按顺序排列输入事件。
        // 我们这样做是因为应用程序或 IME 可能会注入按键事件以响应触摸事件,
        // 我们希望确保注入的按键按照接收到的顺序进行处理,不能仅仅通过时间戳的前后来确定顺序。
        QueuedInputEvent last = mPendingInputEventTail;
        if (last == null) {
            mPendingInputEventHead = q;
            mPendingInputEventTail = q;
        } else {
            last.mNext = q;
            mPendingInputEventTail = q;
        }
        mPendingInputEventCount += 1;
        Trace.traceCounter(Trace.TRACE_TAG_INPUT, mPendingInputEventQueueLengthCounterName,
                mPendingInputEventCount);

        if (processImmediately) {
            doProcessInputEvents();  //前面传进来的processImmediately = true所以走这里处理
        } else {
            scheduleProcessInputEvents();
        }
    }
doProcessInputEvents
//frameworks/base/core/java/android/view/ViewRootImpl.java

    void doProcessInputEvents() {
        // Deliver all pending input events in the queue.
        while (mPendingInputEventHead != null) {
            QueuedInputEvent q = mPendingInputEventHead;  //从队头开始处理
            mPendingInputEventHead = q.mNext;
            if (mPendingInputEventHead == null) {
                mPendingInputEventTail = null;
            }
            q.mNext = null;

            mPendingInputEventCount -= 1;
            Trace.traceCounter(Trace.TRACE_TAG_INPUT, mPendingInputEventQueueLengthCounterName,
                    mPendingInputEventCount);

            mViewFrameInfo.setInputEvent(mInputEventAssigner.processEvent(q.mEvent));

            deliverInputEvent(q);  //开始分发事件
        }

        // We are done processing all input events that we can process right now
        // so we can clear the pending flag immediately.
        //已经处理完所有待办的输入事件,是时候移除主线程mHandler中的MSG_PROCESS_INPUT_EVENTS消息了
        if (mProcessInputEventsScheduled) {
            mProcessInputEventsScheduled = false;
            mHandler.removeMessages(MSG_PROCESS_INPUT_EVENTS);
        }
    }

二、事件的传递

前面将事件入队,然后在doProcessInputEvents就开始从队头拿出并通过deliverInputEvent开始分发

deliverInputEvent
//frameworks/base/core/java/android/view/ViewRootImpl.java

    private void deliverInputEvent(QueuedInputEvent q) {
        Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, "deliverInputEvent",
                q.mEvent.getId());
        ...
        try {
            ...
            InputStage stage;
            if (q.shouldSendToSynthesizer()) {
                stage = mSyntheticInputStage;
            } else {
                //如果忽略输入法窗口则从mFirstPostImeInputStage阶段开始分发,否则从mFirstInputStage开始
                stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage;
            }
            ...
            if (stage != null) {
                handleWindowFocusChanged();  //在分发前确认是否焦点窗口变化了,如果变化就需要更新焦点的信息
                stage.deliver(q);  //调用对应的stage阶段的deliver方法分发事件
            } else {
                finishInputEvent(q);
            }
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
        }
    }

把事件从拿出,下一步就是往view或者IME分发,分发的过程这里会分为多个阶段(InputStage)来顺序执行, 这些阶段在ViewRootImpl中setView时会指定

setView
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
//frameworks/base/core/java/android/view/ViewRootImpl.java

/**
* We have one child
*/
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
int userId) {
synchronized (this) {
if (mView == null) {

...
// Set up the input pipeline.
CharSequence counterSuffix = attrs.getTitle();
//这里进行的赋值;
mSyntheticInputStage = new SyntheticInputStage();
InputStage viewPostImeStage = new ViewPostImeInputStage(mSyntheticInputStage);
InputStage nativePostImeStage = new NativePostImeInputStage(viewPostImeStage,
"aq:native-post-ime:" + counterSuffix);
InputStage earlyPostImeStage = new EarlyPostImeInputStage(nativePostImeStage);
InputStage imeStage = new ImeInputStage(earlyPostImeStage,
"aq:ime:" + counterSuffix);
InputStage viewPreImeStage = new ViewPreImeInputStage(imeStage);
InputStage nativePreImeStage = new NativePreImeInputStage(viewPreImeStage,
"aq:native-pre-ime:" + counterSuffix);

mFirstInputStage = nativePreImeStage;
mFirstPostImeInputStage = earlyPostImeStage;
mPendingInputEventQueueLengthCounterName = "aq:pending:" + counterSuffix;
}
}
}

InputStage这里采用责任链的设计模式,从抽象类InputStage内容可以知道,每一个子类都会将next指向下一个stage子类对象

InputStage
//frameworks/base/core/java/android/view/ViewRootImpl.java

    abstract class InputStage {
        private final InputStage mNext;

        protected static final int FORWARD = 0;
        protected static final int FINISH_HANDLED = 1;
        protected static final int FINISH_NOT_HANDLED = 2;

        private String mTracePrefix;

        /**
         * Creates an input stage.
         * 将所有的阶段都组成一个链表,next指向下一个阶段
         * @param next The next stage to which events should be forwarded.
         */
        public InputStage(InputStage next) {
            mNext = next;
        }
        ...

setView方法中的内容,我们得出整个链条的结构

image-20240107104408898

分发阶段就会从第一个创建的stage子类开始执行到最后一个stage子类,无论要不要处理,都要从链表的头传递到尾。
回到deliverInputEvent方法中stage.deliver(q)正式进入stage的分发中,观察下完整的一个stage的处理流程

//frameworks/base/core/java/android/view/ViewRootImpl.java

        /**
         * Delivers an event to be processed.
         */
        public final void deliver(QueuedInputEvent q) {
            if ((q.mFlags & QueuedInputEvent.FLAG_FINISHED) != 0) {  //如果上一stage中事件被处理(FLAG_FINISHED)那么本stage就不会再处理(onProcess),直接传递到下一个stage(无论是要处理,链表都要走完)
                forward(q);
            } else if (shouldDropInputEvent(q)) {
                finish(q, false);
            } else {
                traceEvent(q, Trace.TRACE_TAG_VIEW);
                final int result;
                try {
                    result = onProcess(q);  //如果前面的阶段没有被处理,本stage就需要走处理流程
                } finally {
                    Trace.traceEnd(Trace.TRACE_TAG_VIEW);
                }
                apply(q, result);  //判断是否需要下一个阶段走处理流程
            }
        }

        /**
         * Marks the input event as finished then forwards it to the next stage.
         *  如果事件在当前阶段被结束,q.mFlags被标记为FLAG_FINISHED,并通过forward(q)传递给下一个阶段
         */
        protected void finish(QueuedInputEvent q, boolean handled) {
            q.mFlags |= QueuedInputEvent.FLAG_FINISHED;
            if (handled) {
                q.mFlags |= QueuedInputEvent.FLAG_FINISHED_HANDLED;
            }
            forward(q);
        }

        /**
         * Forwards the event to the next stage.
         * 往下一个阶段分发
         */
        protected void forward(QueuedInputEvent q) {
            onDeliverToNext(q);// 继续往下一个阶段传递
        }

        /**
         * Applies a result code from {@link #onProcess} to the specified event.
         * 判断是否需要继续接着往下一个阶段分发
         */
        protected void apply(QueuedInputEvent q, int result) {
            if (result == FORWARD) {  //如果上一个阶段还没处理这个事件,则继续往下一个阶段分发处理
                forward(q);
            } else if (result == FINISH_HANDLED) {   //如果事件被处理了,就标记为FLAG_FINISHED|FLAG_FINISHED_HANDLED,然后继续传递给下一个阶段(但不走onProcess()了)
                finish(q, true);
            } else if (result == FINISH_NOT_HANDLED) {  //如果事件没有被处理则标记为FLAG_FINISHED,然后继续传递给下一个阶段(但不走onProcess()了)
                finish(q, false);
            } else {
                throw new IllegalArgumentException("Invalid result: " + result);
            }
        }

        /**
         * Called when an event is ready to be processed.
         * @return A result code indicating how the event was handled.
         */
        protected int onProcess(QueuedInputEvent q) {
            return FORWARD;
        }

        /**
         * Called when an event is being delivered to the next stage.
         * 继续执行下一阶段的deliver
         */
        protected void onDeliverToNext(QueuedInputEvent q) {
            if (DEBUG_INPUT_STAGES) {
                Log.v(mTag, "Done with " + getClass().getSimpleName() + ". " + q);
            }
            if (mNext != null) {
                mNext.deliver(q);  //如果下一阶段不为空就继续执行下一阶段的deliver,继续往下一阶段传递
            } else {
                finishInputEvent(q);
            }
        }

具体如流程图:

image-20240107104610042

NativePreImeInputStage开始deliver,事件经过每一个stage, 如果该事件没有被处理(标记为)FLAG_FINISHED或者该事件应该被抛弃(shouldDropInputEvent),那么就应该传给本阶段(stage)处理(onProcess),按照这个逻辑一直跑完整个链表。

三、View树的分发

在这里阶段里我们本篇比较关心往View树分发的阶段,即ViewPostImeInputStage

ViewPostImeInputStage
    /**
     * Delivers post-ime input events to the view hierarchy.
     */
    final class ViewPostImeInputStage extends InputStage {
        public ViewPostImeInputStage(InputStage next) {
            super(next);
        }

        @Override
        protected int onProcess(QueuedInputEvent q) {
            if (q.mEvent instanceof KeyEvent) {
                return processKeyEvent(q);  //按键事件
            } else {
                final int source = q.mEvent.getSource();
                if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {
                    return processPointerEvent(q);  //pointer类型(包含触摸事件)
                } else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
                    return processTrackballEvent(q);  //轨迹球
                } else {
                    return processGenericMotionEvent(q);  //其他
                }
            }
        }

        @Override
        protected void onDeliverToNext(QueuedInputEvent q) {
            ...
            super.onDeliverToNext(q);
        }

        private int processPointerEvent(QueuedInputEvent q) {
            final MotionEvent event = (MotionEvent)q.mEvent;
            mHandwritingInitiator.onTouchEvent(event);

            mAttachInfo.mUnbufferedDispatchRequested = false;
            mAttachInfo.mHandlingPointerEvent = true;
            
            boolean handled = mView.dispatchPointerEvent(event);  //mView实际上是DecorView, 在addView时添加
            
            maybeUpdatePointerIcon(event);
            maybeUpdateTooltip(event);
            mAttachInfo.mHandlingPointerEvent = false;
            if (mAttachInfo.mUnbufferedDispatchRequested && !mUnbufferedInputDispatch) {
                mUnbufferedInputDispatch = true;
                if (mConsumeBatchedInputScheduled) {
                    scheduleConsumeBatchedInputImmediately();
                }
            }
            return handled ? FINISH_HANDLED : FORWARD;
        }
        ...
 }

回顾下继承关系:DecorView->FrameLayout->ViewGroup->View
dispatchPointerEvent方法并没有被DecorView->FrameLayout->ViewGroup实现,是祖父类View实现了这个方法

View::dispatchPointerEvent
    public final boolean dispatchPointerEvent(MotionEvent event) {
        if (event.isTouchEvent()) {  //根据MotionEvent事件的类型,如果是触摸事件
            return dispatchTouchEvent(event);  //此时是this对象是DecorView子类对象,所以调的是它的dispatchTouchEvent
        } else {  //其他(如鼠标)
            return dispatchGenericMotionEvent(event);
        }
    }
DecorView::dispatchTouchEvent
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        final Window.Callback cb = mWindow.getCallback();
        //这个cb实际上是Activity对象,(当调Activity的attach方法时, 通过mWindow.setCallback(this)传入)
        //这里判断条件为真,走cb.dispatchTouchEvent(ev),也就是Activity的方法
        return cb != null && !mWindow.isDestroyed() && mFeatureId < 0
                ? cb.dispatchTouchEvent(ev) : super.dispatchTouchEvent(ev);
    }
Activity::dispatchTouchEvent
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            onUserInteraction(); //按下时通知通知栏进行相应的变化
        }
        //getWindow获取到的是PhoneWindow对象(在Activity的attach方法中创建的)
        //所以这里会传递给PhoneWindow::superDispatchTouchEvent
        if (getWindow().superDispatchTouchEvent(ev)) {
            return true;
        }
        //如果上面的链路都没人处理,一路都是返回的false,那么最终还是由Activity来消费
        return onTouchEvent(ev);
    }
PhoneWindow::superDispatchTouchEvent
    @Override
    public boolean superDispatchTouchEvent(MotionEvent event) {
        // 兜兜转转又到DecorView手里,原因就是它是View树的最顶部ViewGroup呀,还是得从它开始的
        return mDecor.superDispatchTouchEvent(event);
    }
DecorView::superDispatchTouchEvent
    public boolean superDispatchTouchEvent(MotionEvent event) {
        //调用父类ViewGroup的dispatchTouchEvent开始遍历子成员分发
         //step ViewGroup.java dispatchTouchEvent();
        return super.dispatchTouchEvent(event);
    }
ViewGroup::dispatchTouchEvent
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        ...

        boolean handled = false;
        if (onFilterTouchEventForSecurity(ev)) {
            final int action = ev.getAction();
            final int actionMasked = action & MotionEvent.ACTION_MASK;

            // Handle an initial down.
            //如果这是个ACTION_DOWN事件说明是一个新触摸行为的开始,那么重置相关的状态
            if (actionMasked == MotionEvent.ACTION_DOWN) {
                // Throw away all previous state when starting a new touch gesture.
                // The framework may have dropped the up or cancel event for the previous gesture
                // due to an app switch, ANR, or some other state change.
                cancelAndClearTouchTargets(ev);
                resetTouchState();
            }

            // Check for interception.
            //ViewGroup是否拦截当前事件,通过onInterceptTouchEvent方法。这个方法只有ViewGroup有
            final boolean intercepted;
            if (actionMasked == MotionEvent.ACTION_DOWN
                    || mFirstTouchTarget != null) {
                final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
                if (!disallowIntercept) {
                    intercepted = onInterceptTouchEvent(ev);  //
                    ev.setAction(action); // restore action in case it was changed
                } else {
                    intercepted = false;
                }
            } else {
                // There are no touch targets and this action is not an initial down
                // so this view group continues to intercept touches.
                intercepted = true;
            }
            
            ...
            
            if (!canceled && !intercepted) {
                //当这时一个ACTION_DOWN事件进这里
                if (actionMasked == MotionEvent.ACTION_DOWN
                        || (split && actionMasked == MotionEvent.ACTION_POINTER_DOWN)
                        || actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
                    final int actionIndex = ev.getActionIndex(); // always 0 for down
                    final int idBitsToAssign = split ? 1 << ev.getPointerId(actionIndex)
                            : TouchTarget.ALL_POINTER_IDS;

                    // Clean up earlier touch targets for this pointer id in case they
                    // have become out of sync.
                    removePointersFromTouchTargets(idBitsToAssign);

                    final int childrenCount = mChildrenCount;
                    if (newTouchTarget == null && childrenCount != 0) {
                        final float x =
                                isMouseEvent ? ev.getXCursorPosition() : ev.getX(actionIndex);
                        final float y =
                                isMouseEvent ? ev.getYCursorPosition() : ev.getY(actionIndex);
                                
                        // Find a child that can receive the event.
                        // Scan children from front to back.
                        //在当前ViewGroup中找到能处理这个事件的子View或者Viewgroup
                        final ArrayList<View> preorderedList = buildTouchDispatchChildList();
                        final boolean customOrder = preorderedList == null
                                && isChildrenDrawingOrderEnabled();
                        final View[] children = mChildren;
                        for (int i = childrenCount - 1; i >= 0; i--) {
                            final int childIndex = getAndVerifyPreorderedIndex(
                                    childrenCount, i, customOrder);
                            final View child = getAndVerifyPreorderedView(
                                    preorderedList, children, childIndex);
                               ....

                            newTouchTarget = getTouchTarget(child);

                            resetCancelNextUpFlag(child);
                            //传递到child,调用dispatchTouchEvent,或者如果当前ViewGroup没有child,则调用View的dispatchTouchEvent交由当前ViewGroup处理
                            if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
                                // Child wants to receive touch within its bounds.
                                ...
                                mLastTouchDownX = ev.getX();
                                mLastTouchDownY = ev.getY();
                                //记录下这个能消费触摸事件的View target
                                newTouchTarget = addTouchTarget(child, idBitsToAssign);
                                alreadyDispatchedToNewTouchTarget = true;  //这个标识通过这个Down事件找到了能处理这个触摸行为的View target
                                break;
                            }

                            // The accessibility focus didn't handle the event, so clear
                            // the flag and do a normal dispatch to all children.
                            ev.setTargetAccessibilityFocus(false);
                        }
                        if (preorderedList != null) preorderedList.clear();
                    }

                    ...
                }
            }

            // Dispatch to touch targets.
            if (mFirstTouchTarget == null) {
                // No touch targets so treat this as an ordinary view.
                //如果找不到mFirstTouchTarget,则交给当前ViewGroup处理,即通过super.dispatchTouchEvent(event)
                handled = dispatchTransformedTouchEvent(ev, canceled, null,
                        TouchTarget.ALL_POINTER_IDS);
            } else {
                // Dispatch to touch targets, excluding the new touch target if we already
                // dispatched to it.  Cancel touch targets if necessary.
                TouchTarget predecessor = null;
                TouchTarget target = mFirstTouchTarget;
                while (target != null) {
                    final TouchTarget next = target.next;
                    if (alreadyDispatchedToNewTouchTarget && target == newTouchTarget) {
                        //前面的dispatchTransformedTouchEvent已经处理了这个Down事件,直接标识为已消费
                        handled = true;
                    } else {
                        final boolean cancelChild = resetCancelNextUpFlag(target.child)
                                || intercepted;

                        //如果被拦截,则给子child发ACTION_CANCEL事件
                        //如果没有拦截则正常分发到子类,包括MOVE和UP事件
                        if (dispatchTransformedTouchEvent(ev, cancelChild,
                                target.child, target.pointerIdBits)) {
                            handled = true;
                        }
                        if (cancelChild) {
                            if (predecessor == null) {
                                mFirstTouchTarget = next;
                            } else {
                                predecessor.next = next;
                            }
                            target.recycle();
                            target = next;
                            continue;
                        }
                    }
                    predecessor = target;
                    target = next;
                }
            }

        ...
        return handled;
    }
ViewGroup::dispatchTransformedTouchEvent
    private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,
            View child, int desiredPointerIdBits) {
        final boolean handled;

        ...

        final MotionEvent transformedEvent;
        if (newPointerIdBits == oldPointerIdBits) {
            if (child == null || child.hasIdentityMatrix()) {
                if (child == null) { //如果当前ViewGroup没有子View或者子ViewGroup,则调用View的dispatchTouchEvent,即由当前ViewGroup来处理
                    handled = super.dispatchTouchEvent(event);
                } else {
                    final float offsetX = mScrollX - child.mLeft;
                    final float offsetY = mScrollY - child.mTop;
                    event.offsetLocation(offsetX, offsetY);

                    handled = child.dispatchTouchEvent(event);  //由子View或者子ViewGroup的dispatchTouchEvent处理

                    event.offsetLocation(-offsetX, -offsetY);
                }
                return handled;
            }
            transformedEvent = MotionEvent.obtain(event);
        } else {
            transformedEvent = event.split(newPointerIdBits);
        }

        ...
        return handled;
    }
View::dispatchTouchEvent
    public boolean dispatchTouchEvent(MotionEvent event) {
        ...

        if (onFilterTouchEventForSecurity(event)) {
            ...
            //noinspection SimplifiableIfStatement
            ListenerInfo li = mListenerInfo;
            if (li != null && li.mOnTouchListener != null
                    && (mViewFlags & ENABLED_MASK) == ENABLED
                    && li.mOnTouchListener.onTouch(this, event)) {  //如果实现了onTouch方法,则不往下执行
                result = true;
            }

            if (!result && onTouchEvent(event)) {  //调用当前View的onTouchEvent(这个View可能是View也可能是ViewGroup)
                result = true;
            }
        }

        ...

        return result;
    }
View::onTouchEvent
    public boolean onTouchEvent(MotionEvent event) {
   
        final float x = event.getX();
        final float y = event.getY();
        final int viewFlags = mViewFlags;
        final int action = event.getAction();

        final boolean clickable = ((viewFlags & CLICKABLE) == CLICKABLE
                || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)
                || (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE;

        ...

        if (clickable || (viewFlags & TOOLTIP) == TOOLTIP) {  //根据action进行处理
            switch (action) {
                case MotionEvent.ACTION_UP:
                     ...
                    break;

                case MotionEvent.ACTION_DOWN:
                    ...
                    break;

                case MotionEvent.ACTION_CANCEL:
                    ...
                    break;

                case MotionEvent.ACTION_MOVE:
                    ...
                    break;
            }
            return true;
        }
        return false;
    }

这个方法也是又臭又长,核心方法了, 还是用图来说明更直接,也结束触摸事件的分析。

在这里插入图片描述

InputDispatcher::dispatchOnce()

frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp

void InputDispatcher::dispatchOnce() {
    nsecs_t nextWakeupTime = LONG_LONG_MAX;
    { // acquire lock
        std::scoped_lock _l(mLock);
        mDispatcherIsAlive.notify_all();  //唤醒在这个condition上wait的所有地方
        
        // Run a dispatch loop if there are no pending commands.
        // The dispatch loop might enqueue commands to run afterwards.
        // 如果当前没有待办的command需要处理(command一般是需要处理一些异常情况,比如ANR)
        // 就进行事件的分发
        if (!haveCommandsLocked()) {
            dispatchOnceInnerLocked(&nextWakeupTime);  //事件分发
        }

        // Run all pending commands if there are any.
        // If any commands were run then force the next poll to wake up immediately.
        // 如果mCommandQueue不为空,就执行完所有command,并将下次唤醒时间设置为最小值,强制下一次poll唤醒线程
        if (runCommandsLockedInterruptable()) {
            nextWakeupTime = LONG_LONG_MIN;
        }

        // If we are still waiting for ack on some events,
        // we might have to wake up earlier to check if an app is anr'ing.
        // 如果此时正在等待分发出去的事件的ack(目标应用的响应),我们需要早点唤醒去检查这个应用是否正在ANR
        const nsecs_t nextAnrCheck = processAnrsLocked();
        nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);

        // We are about to enter an infinitely long sleep, because we have no commands or
        // pending or queued events
        // 如果唤醒时间还是LONG_LONG_MAX没有被修改
        // 说明上面没有待处理的事件也没有待处理的command,那么将进入无限期的休眠中
        if (nextWakeupTime == LONG_LONG_MAX) {
            mDispatcherEnteredIdle.notify_all();  //唤醒等待进入idle状态的condition
        }
    } // release lock

    // Wait for callback or timeout or wake.  (make sure we round up, not down)
    nsecs_t currentTime = now();
    int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
    mLooper->pollOnce(timeoutMillis);  //进入阻塞等待唤醒或者timeout或者callback回调
}

InputDispatcher::dispatchOnceInnerLocked

void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
    nsecs_t currentTime = now();

    // Reset the key repeat timer whenever normal dispatch is suspended while the
    // device is in a non-interactive state.  This is to ensure that we abort a key
    // repeat if the device is just coming out of sleep.
    // 如果设备处于不可交互时,则不进行事件的分发
    // 如果处于不可分发状态则重置按键重复计时器
    if (!mDispatchEnabled) {
        resetKeyRepeatLocked();
    }

    // If dispatching is frozen, do not process timeouts or try to deliver any new events.
    // 如果处于frozen状态,则不处理任何有关目标进程是否有简单窗口的timeout行为,也不会进行事件的分发
    if (mDispatchFrozen) {
        if (DEBUG_FOCUS) {
            ALOGD("Dispatch frozen.  Waiting some more.");
        }
        return;
    }

    // Optimize latency of app switches.
    // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
    // been pressed.  When it expires, we preempt dispatch and drop all other pending events.
    // 对APP切换时的优化措施,当按下类似HOME键时,启动一个超时机制(0.5s),当timeout时,会立即分发事件并抛弃其他的未处理事件
    bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
    if (mAppSwitchDueTime < *nextWakeupTime) {
        *nextWakeupTime = mAppSwitchDueTime;
    }

    // Ready to start a new event.
    // If we don't already have a pending event, go grab one.
    if (!mPendingEvent) {  //正常一次分发前mPendingEvent = nullptr
        if (mInboundQueue.empty()) {
            ...
        } else {  //因为inputReader已经往Inbound queue中添加了事件,所以不为空
            // Inbound queue has at least one entry.
            mPendingEvent = mInboundQueue.front(); //拿出一个待分发的事件
            mInboundQueue.pop_front(); //从mInboundQueue中移除这个事件
            traceInboundQueueLengthLocked();  //systrace、perfetto中可以看到这个队列size发生变化
        }

        // Poke user activity for this event.
        // 每次分发事件时都调PMS的updatePowerStateLocked更新电源的状态
        if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
            pokeUserActivityLocked(*mPendingEvent);
        }
    }

    // Now we have an event to dispatch.
    // All events are eventually dequeued and processed this way, even if we intend to drop them.
    ALOG_ASSERT(mPendingEvent != nullptr);
    bool done = false;
    DropReason dropReason = DropReason::NOT_DROPPED;
    if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {  //如果事件不是分发给用户的则抛弃drop
        dropReason = DropReason::POLICY;
    } else if (!mDispatchEnabled) {  //如果当前属于不可交互的状态则drop
        dropReason = DropReason::DISABLED;
    }

    if (mNextUnblockedEvent == mPendingEvent) {
        mNextUnblockedEvent = nullptr;
    }

    switch (mPendingEvent->type) {
        ...
        case EventEntry::Type::KEY: {
            ...
        }

        case EventEntry::Type::MOTION: {
            std::shared_ptr<MotionEntry> motionEntry =
                    std::static_pointer_cast<MotionEntry>(mPendingEvent);
            if (dropReason == DropReason::NOT_DROPPED && isAppSwitchDue) {
                dropReason = DropReason::APP_SWITCH;  //处于APP切换情形drop的事件
            }
            if (dropReason == DropReason::NOT_DROPPED && isStaleEvent(currentTime, *motionEntry)) {
                   //事件超过了一个事件允许分发的最大时间(10s)(事件太老)则drop这个事件
                   //时间计算:currentTime - entry.eventTime
                dropReason = DropReason::STALE;
            }
            if (dropReason == DropReason::NOT_DROPPED && mNextUnblockedEvent) {
                //当焦点将要移到到新的应用上,则抛弃期间的事件
                dropReason = DropReason::BLOCKED;
            }
            //事件的分发(无论这个事件要分发还是要drop都要走这里)
            done = dispatchMotionLocked(currentTime, motionEntry, &dropReason, nextWakeupTime);
            break;
        }
        ...
    }

    if (done) {
        if (dropReason != DropReason::NOT_DROPPED) {
            dropInboundEventLocked(*mPendingEvent, dropReason);
        }
        mLastDropReason = dropReason;

        releasePendingEventLocked();  //将mPendingEvent设置为nullptr,重置为下一个事件分发准备
        //  强制下一个poll中立即唤醒inputDispatcher线程来干活
        *nextWakeupTime = LONG_LONG_MIN; // force next poll to wake up immediately
    }
}

InputDispatcher::dispatchMotionLocked

bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<MotionEntry> entry,
                                           DropReason* dropReason, nsecs_t* nextWakeupTime) {
    ATRACE_CALL();
    // Preprocessing.
    //将当前事件的dispatchInProgress设置为true表示处理中
    if (!entry->dispatchInProgress) {
        entry->dispatchInProgress = true;

        logOutboundMotionDetails("dispatchMotion - ", *entry);
    }

    // Clean up if dropping the event.
    //如果事件需要抛弃
    if (*dropReason != DropReason::NOT_DROPPED) {
        setInjectionResult(*entry,
                           *dropReason == DropReason::POLICY ? InputEventInjectionResult::SUCCEEDED
                                                             : InputEventInjectionResult::FAILED);
        return true;
    }
    //从entry->source判断事件的源类型
    const bool isPointerEvent = isFromSource(entry->source, AINPUT_SOURCE_CLASS_POINTER);

    // Identify targets.
    std::vector<InputTarget> inputTargets;

    bool conflictingPointerActions = false;
    InputEventInjectionResult injectionResult;
    if (isPointerEvent) {  //触屏这这里
        // Pointer event.  (eg. touchscreen)
        //重要的方法,获取当前焦点窗口,后续单独展开分析这个,这里就展开
        //获取到的焦点窗口为inputTargets
        injectionResult =
                findTouchedWindowTargetsLocked(currentTime, *entry, inputTargets, nextWakeupTime,
                                               &conflictingPointerActions);
    } else {
        ...
    }
    ...

    setInjectionResult(*entry, injectionResult);
    ...

    // Add monitor channels from event's or focused display.
    //将全局的监视器窗口加入分发的目标窗口列表中(举个例子:开发者选项中的显示触摸轨迹图层就一个全局监视器)
    //只要事件在前面没有被抛弃,那么无论后面的流程是否拦截事件,这些全局监视器都能收到事件
    addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));

    // Dispatch the motion.
    ...
    dispatchEventLocked(currentTime, entry, inputTargets);  //往目标窗口分发事件
    return true;  //return true就可以进行下一次从iq中读取新事件并分发
}

InputDispatcher::dispatchEventLocked

void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
                                          std::shared_ptr<EventEntry> eventEntry,
                                          const std::vector<InputTarget>& inputTargets) {
    ATRACE_CALL();

    updateInteractionTokensLocked(*eventEntry, inputTargets);

    ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true

    pokeUserActivityLocked(*eventEntry);  //再次更新电源状态,避免进入息屏等行为

    //遍历所有找到的目标窗口inputTargets,通过他们的向他们inputChannel分发当前的事件
    for (const InputTarget& inputTarget : inputTargets) {
        sp<Connection> connection =
                getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
        if (connection != nullptr) {
            prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
        } else {
            if (DEBUG_FOCUS) {
                ALOGD("Dropping event delivery to target with channel '%s' because it "
                      "is no longer registered with the input dispatcher.",
                      inputTarget.inputChannel->getName().c_str());
            }
        }
    }
}

InputDispatcher::prepareDispatchCycleLocked

void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
                                                 const sp<Connection>& connection,
                                                 std::shared_ptr<EventEntry> eventEntry,
                                                 const InputTarget& inputTarget) {
    ...
    // Skip this event if the connection status is not normal.
    // We don't want to enqueue additional outbound events if the connection is broken.
    // 如果目标窗口的连接状态不正常,比如进程已经死了,那么就不向它分发了
    if (connection->status != Connection::Status::NORMAL) {
        return;
    }

    // Split a motion event if needed.
    // 如果当前系统处于分屏的状态,就需要考虑分离触摸的情形,检查目标窗口是否设置分离触摸标志
    if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
        const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
        if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
            std::unique_ptr<MotionEntry> splitMotionEntry =
                    splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
            if (!splitMotionEntry) {
                return; // split event was dropped
            }
            if (splitMotionEntry->action == AMOTION_EVENT_ACTION_CANCEL) {
                std::string reason = std::string("reason=pointer cancel on split window");
                android_log_event_list(LOGTAG_INPUT_CANCEL)
                        << connection->getInputChannelName().c_str() << reason << LOG_ID_EVENTS;
            }

            enqueueDispatchEntriesLocked(currentTime, connection, std::move(splitMotionEntry),
                                         inputTarget);
            return;
        }
    }

    // Not splitting.  Enqueue dispatch entries for the event as is.
    //一般走这里,继续事件的分发,将事件加入目标窗口的即将分发的队列中
    enqueueDispatchEntriesLocked(currentTime, connection, eventEntry, inputTarget);
}

InputDispatcher::enqueueDispatchEntriesLocked

void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
                                                   const sp<Connection>& connection,
                                                   std::shared_ptr<EventEntry> eventEntry,
                                                   const InputTarget& inputTarget) {

    bool wasEmpty = connection->outboundQueue.empty();

    // Enqueue dispatch entries for the requested modes.
    // 将事件加入分发队列outboundQueue,这里有些复杂
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
                               InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT);  //2048
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
                               InputTarget::FLAG_DISPATCH_AS_OUTSIDE);  //512
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
                               InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER);  //1024
    //FLAG_DISPATCH_AS_IS表示事件按原样分发,不改变事件的分发模式,一般都是走这里,其他的是特殊情形
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
                               InputTarget::FLAG_DISPATCH_AS_IS);  //256  
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
                               InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT);  //4096
    enqueueDispatchEntryLocked(connection, eventEntry, inputTarget,
                               InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER);  //8192

    // If the outbound queue was previously empty, start the dispatch cycle going.
    if (wasEmpty && !connection->outboundQueue.empty()) {
        startDispatchCycleLocked(currentTime, connection);  //outboundQueue中已经有事件,可以分发
    }
}

InputDispatcher::enqueueDispatchEntryLocked

void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
                                                 std::shared_ptr<EventEntry> eventEntry,
                                                 const InputTarget& inputTarget,
                                                 int32_t dispatchMode) {
                                                 
    int32_t inputTargetFlags = inputTarget.flags;
    //这里很关键,enqueueDispatchEntryLocked从上面来看,貌似会调五次,但是
    // 这里有限制条件,根据inputTargetFlags是否等于本次传入的dispatchMode,不同则return
    // 所以是否入队还是由inputTargetFlags决定,正常事件都是inputTargetFlags = FLAG_DISPATCH_AS_IS
    // 所以一般只有dispatchMode = FLAG_DISPATCH_AS_IS时才会往下执行
    if (!(inputTargetFlags & dispatchMode)) {
        return;
    }
    inputTargetFlags = (inputTargetFlags & ~InputTarget::FLAG_DISPATCH_MASK) | dispatchMode;

    // This is a new event.
    // Enqueue a new dispatch entry onto the outbound queue for this connection.
    // 创建DispatchEntry,DispatchEntry是对EventEntry的包装,加入分发的一些跟踪状态属性值
    // 关联eventEntry,inputTarget,inputTarget,
    std::unique_ptr<DispatchEntry> dispatchEntry =
            createDispatchEntry(inputTarget, eventEntry, inputTarget);

    // Use the eventEntry from dispatchEntry since the entry may have changed and can now be a
    // different EventEntry than what was passed in.
    EventEntry& newEntry = *(dispatchEntry->eventEntry);
    // Apply target flags and update the connection's input state.
    switch (newEntry.type) {
        case EventEntry::Type::KEY: {
            ...
            break;
        }

        case EventEntry::Type::MOTION: {
            const MotionEntry& motionEntry = static_cast<const MotionEntry&>(newEntry);
            // Assign a default value to dispatchEntry that will never be generated by InputReader,
            // and assign a InputDispatcher value if it doesn't change in the if-else chain below.
            constexpr int32_t DEFAULT_RESOLVED_EVENT_ID =
                    static_cast<int32_t>(IdGenerator::Source::OTHER);
            dispatchEntry->resolvedEventId = DEFAULT_RESOLVED_EVENT_ID;
            
            if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_OUTSIDE) {
                dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_OUTSIDE;
            } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_EXIT) {
                dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_EXIT;
            } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_HOVER_ENTER) {
                dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
            } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_EXIT) {
                dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_CANCEL;
            } else if (dispatchMode & InputTarget::FLAG_DISPATCH_AS_SLIPPERY_ENTER) {
                dispatchEntry->resolvedAction = AMOTION_EVENT_ACTION_DOWN;
            } else {  //由上面可知dispatchMode = FLAG_DISPATCH_AS_IS所以走else,保留事件原本的action和id
                dispatchEntry->resolvedAction = motionEntry.action;
                dispatchEntry->resolvedEventId = motionEntry.id;
            }
            
            if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
                ...
            }

            dispatchEntry->resolvedFlags = motionEntry.flags;
            //判断当前目标窗口是否被其他可见窗口遮挡的情况并设置到dispatchEntry->resolvedFlags, 全遮挡还是部分遮挡
            if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
                dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
            }
            if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_PARTIALLY_OBSCURED) {
                dispatchEntry->resolvedFlags |= AMOTION_EVENT_FLAG_WINDOW_IS_PARTIALLY_OBSCURED;
            }
            ...
            // 从上面可知,当dispatchMode = FLAG_DISPATCH_AS_IS时
            // 事件的resolvedEventId仍然保留原有motionEntry.id
            dispatchEntry->resolvedEventId =
                    dispatchEntry->resolvedEventId == DEFAULT_RESOLVED_EVENT_ID
                    ? mIdGenerator.nextId()
                    : motionEntry.id;

            if ((motionEntry.flags & AMOTION_EVENT_FLAG_NO_FOCUS_CHANGE) &&
                (motionEntry.policyFlags & POLICY_FLAG_TRUSTED)) {
                // Skip reporting pointer down outside focus to the policy.
                break;
            }
            //处理分发事件目标窗口不是当前焦点窗口的情况
            dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
                                            inputTarget.inputChannel->getConnectionToken());

            break;
        }
        ...
    }

    // Remember that we are waiting for this dispatch to complete.
    if (dispatchEntry->hasForegroundTarget()) {
        incrementPendingForegroundDispatches(newEntry);
    }

    // Enqueue the dispatch entry.
    // 将dispatchEntry加入当前目标窗口的outboundQueue
    connection->outboundQueue.push_back(dispatchEntry.release());
    traceOutboundQueueLength(*connection);  //systrace可以看到outboundQueue的size发生改变
}

InputDispatcher::startDispatchCycleLocked

void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
                                               const sp<Connection>& connection) {

    //循环从outboundQueue中取出事件通过目标窗口的inputchannel向目标窗口分发
    while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
        DispatchEntry* dispatchEntry = connection->outboundQueue.front();  //取出DispatchEntry
        dispatchEntry->deliveryTime = currentTime;  //记录分发事件
        const std::chrono::nanoseconds timeout = getDispatchingTimeoutLocked(connection);
         //事件处理的超时时间点 = currentTime + 5s  超时会引发ANR
        dispatchEntry->timeoutTime = currentTime + timeout.count();

        // Publish the event.
        status_t status;
        const EventEntry& eventEntry = *(dispatchEntry->eventEntry);  //获取EventEntry
        switch (eventEntry.type) {
            case EventEntry::Type::KEY: {
                ...
            }

            case EventEntry::Type::MOTION: {
                const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);  //转化为触摸对应MotionEntry

                PointerCoords scaledCoords[MAX_POINTERS];
                const PointerCoords* usingCoords = motionEntry.pointerCoords;

                // Set the X and Y offset and X and Y scale depending on the input source.
                //根据输入源设置 X 和 Y 偏移以及 X 和 Y 比例。
                if ((motionEntry.source & AINPUT_SOURCE_CLASS_POINTER) &&
                    !(dispatchEntry->targetFlags & InputTarget::FLAG_ZERO_COORDS)) {  //模拟器走这里
                    float globalScaleFactor = dispatchEntry->globalScaleFactor;
                    if (globalScaleFactor != 1.0f) {
                        for (uint32_t i = 0; i < motionEntry.pointerCount; i++) {
                            scaledCoords[i] = motionEntry.pointerCoords[i];
                            // Don't apply window scale here since we don't want scale to affect raw
                            // coordinates. The scale will be sent back to the client and applied
                            // later when requesting relative coordinates.
                            //如果当前窗口的全局坐标比例不是1.0f,那么这里先把每个pointer的比例设置为1.0f
                            scaledCoords[i].scale(globalScaleFactor, 1 /* windowXScale */,
                                                  1 /* windowYScale */);
                        }
                        usingCoords = scaledCoords;
                    }
                } else {
                    ...
                }

                std::array<uint8_t, 32> hmac = getSignature(motionEntry, *dispatchEntry);

                // Publish the motion event.
                // 向目标窗口分发触摸事件
                status = connection->inputPublisher
                                 .publishMotionEvent(dispatchEntry->seq,
                                                     dispatchEntry->resolvedEventId,
                                                     motionEntry.deviceId, motionEntry.source,
                                                     motionEntry.displayId, std::move(hmac),
                                                     dispatchEntry->resolvedAction,
                                                     motionEntry.actionButton,
                                                     dispatchEntry->resolvedFlags,
                                                     motionEntry.edgeFlags, motionEntry.metaState,
                                                     motionEntry.buttonState,
                                                     motionEntry.classification,
                                                     dispatchEntry->transform,
                                                     motionEntry.xPrecision, motionEntry.yPrecision,
                                                     motionEntry.xCursorPosition,
                                                     motionEntry.yCursorPosition,
                                                     dispatchEntry->rawTransform,
                                                     motionEntry.downTime, motionEntry.eventTime,
                                                     motionEntry.pointerCount,
                                                     motionEntry.pointerProperties, usingCoords);
                break;
            }
            ...
        }

        // Check the result.
        // 检测分发的结果,正常时status = 0
        if (status) {
            if (status == WOULD_BLOCK) {
                if (connection->waitQueue.empty()) {
                    // 当前waitQueue是空的,说明socket中也应该是空的,但是却是WOULD_BLOCK,说明这时一个异常的情况,中断分发
                    abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
                } else {
                    // Pipe is full and we are waiting for the app to finish process some events
                    // before sending more events to it.
                    // socket满了,等待应用进程处理掉一些事件
                }
            } else {
                //其他异常的情况
                abortBrokenDispatchCycleLocked(currentTime, connection, true /*notify*/);
            }
            return;
        }

        // Re-enqueue the event on the wait queue.
        // 将已经分发的事件dispatchEntry从outboundQueue中移除
        connection->outboundQueue.erase(std::remove(connection->outboundQueue.begin(),
                                                    connection->outboundQueue.end(),
                                                    dispatchEntry));
        traceOutboundQueueLength(*connection); //systrace中跟踪outboundQueue的长度
        
        // 将已经分发的事件dispatchEntry加入目标窗口waitQueue中,记录下已经分发到目标窗口侧的事件,便于监控ANR等行为
        connection->waitQueue.push_back(dispatchEntry);

      //如果目标窗口进程(例如应用进程)可响应,则将这个事件超时事件点和目标窗口连接对象token加入mAnrTracker中监控
      //如果不可响应,则不再向它分发更多的事件,直到它消耗了已经分发给它的事件
        if (connection->responsive) {
            mAnrTracker.insert(dispatchEntry->timeoutTime,
                               connection->inputChannel->getConnectionToken());
        }
        traceWaitQueueLength(*connection); //systrace中跟踪waitQueue的长度
    }
}

InputPublisher::publishMotionEvent

frameworks/native/libs/input/InputTransport.cpp

status_t InputPublisher::publishMotionEvent(
        uint32_t seq, int32_t eventId, int32_t deviceId, int32_t source, int32_t displayId,
        std::array<uint8_t, 32> hmac, int32_t action, int32_t actionButton, int32_t flags,
        int32_t edgeFlags, int32_t metaState, int32_t buttonState,
        MotionClassification classification, const ui::Transform& transform, float xPrecision,
        float yPrecision, float xCursorPosition, float yCursorPosition,
        const ui::Transform& rawTransform, nsecs_t downTime, nsecs_t eventTime,
        uint32_t pointerCount, const PointerProperties* pointerProperties,
        const PointerCoords* pointerCoords) {

    //创建InputMessage,将dispatchEntry转化为InputMessage
    InputMessage msg;
    msg.header.type = InputMessage::Type::MOTION;
    msg.header.seq = seq;
    msg.body.motion.eventId = eventId;
    msg.body.motion.deviceId = deviceId;
    msg.body.motion.source = source;
    msg.body.motion.displayId = displayId;
    msg.body.motion.hmac = std::move(hmac);
    msg.body.motion.action = action;
    msg.body.motion.actionButton = actionButton;
    msg.body.motion.flags = flags;
    msg.body.motion.edgeFlags = edgeFlags;
    msg.body.motion.metaState = metaState;
    msg.body.motion.buttonState = buttonState;
    msg.body.motion.classification = classification;
    msg.body.motion.dsdx = transform.dsdx();
    msg.body.motion.dtdx = transform.dtdx();
    msg.body.motion.dtdy = transform.dtdy();
    msg.body.motion.dsdy = transform.dsdy();
    msg.body.motion.tx = transform.tx();
    msg.body.motion.ty = transform.ty();
    msg.body.motion.xPrecision = xPrecision;
    msg.body.motion.yPrecision = yPrecision;
    msg.body.motion.xCursorPosition = xCursorPosition;
    msg.body.motion.yCursorPosition = yCursorPosition;
    msg.body.motion.dsdxRaw = rawTransform.dsdx();
    msg.body.motion.dtdxRaw = rawTransform.dtdx();
    msg.body.motion.dtdyRaw = rawTransform.dtdy();
    msg.body.motion.dsdyRaw = rawTransform.dsdy();
    msg.body.motion.txRaw = rawTransform.tx();
    msg.body.motion.tyRaw = rawTransform.ty();
    msg.body.motion.downTime = downTime;
    msg.body.motion.eventTime = eventTime;
    msg.body.motion.pointerCount = pointerCount;
    for (uint32_t i = 0; i < pointerCount; i++) { //多指的情况
        msg.body.motion.pointers[i].properties.copyFrom(pointerProperties[i]);
        msg.body.motion.pointers[i].coords.copyFrom(pointerCoords[i]);
    }

    return mChannel->sendMessage(&msg);  //通过socketpair传递到目标窗口所在的进程中
}

到这里InputDispatcher的Native层分发就分析完了。

从前面inputflinger的启动分析中,我们知道事件来源是在EventHub::getEvents, 所以我们重点看下这个方法的流程来了解事件是如何从驱动上报中获取的。

EventHub::getEvents

frameworks/native/services/inputflinger/reader/EventHub.cpp

size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) {
    ALOG_ASSERT(bufferSize >= 1);
        
    std::scoped_lock _l(mLock);
    //创建一个input_event数组,用于存放从epoll中读取到的input_events
    struct input_event readBuffer[bufferSize];
    //buffer是inputReader传入的RawEvent数组首地址,数组大小为256,将事件构造成RawEvent并装入后返回给inputReader
    //用这里把数组地址赋给event指针,后续使用这个指针操作这个数组
    RawEvent* event = buffer; //传入的RawEvent数组首地址
    //一次处理事件的最大容量为256个
    size_t capacity = bufferSize;
    bool awoken = false;
    for (;;) {
        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);  //获取当前时间戳

        //处理有关设备状态变化的逻辑
        // Reopen input devices if needed.
        if (mNeedToReopenDevices) {
            mNeedToReopenDevices = false;

            ALOGI("Reopening all input devices due to a configuration change.");

            closeAllDevicesLocked();
            mNeedToScanDevices = true;
            break; // return to the caller before we actually rescan
        }

        // Report any devices that had last been added/removed.
        //当调用closeDeviceLocked时,就会把需要关闭的设备加入mClosingDevices,下一次循环到这里时就遍历这个列表处理
        for (auto it = mClosingDevices.begin(); it != mClosingDevices.end();) {
            //移除一个设备就构建一个DEVICE_REMOVED类型的event并加入RawEvent数组中
            std::unique_ptr<Device> device = std::move(*it);
            ALOGV("Reporting device closed: id=%d, name=%s\n", device->id, device->path.c_str());
            event->when = now;
            event->deviceId = (device->id == mBuiltInKeyboardId)
                    ? ReservedInputDeviceId::BUILT_IN_KEYBOARD_ID
                    : device->id;
            event->type = DEVICE_REMOVED;
            event += 1;
            it = mClosingDevices.erase(it);  //从mClosingDevices中移除device
            mNeedToSendFinishedDeviceScan = true;
            if (--capacity == 0) {
                break;
            }
        }

        //当EventHub初始化时,mNeedToScanDevices = true, 所以首次进入需要scan输入设备
        if (mNeedToScanDevices) {
            mNeedToScanDevices = false;
            scanDevicesLocked();  //扫描设备"/dev/input"下的设备,例如event1、event2,这个方法很复杂,
            mNeedToSendFinishedDeviceScan = true;
        }
        //上一步进行了scan device的操作,现在mOpeningDevices是记录着获取到的Device
        while (!mOpeningDevices.empty()) {
            //遍历取出mOpeningDevices中Device,构建RawEvent->DEVICE_ADDED事件,写入event缓冲区中
            std::unique_ptr<Device> device = std::move(*mOpeningDevices.rbegin());
            mOpeningDevices.pop_back();//把这个device对象从移除mOpeningDevices中
            ALOGV("Reporting device opened: id=%d, name=%s\n", device->id, device->path.c_str());
            //构建一个RawEvent时间,type = DEVICE_ADDED
            event->when = now;
            event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
            event->type = DEVICE_ADDED;
            event += 1; //RawEvent对象偏移 + 1(RawEvent数组中RawEvent数量)
        
            ...
            //从已经处理的设备中mOpeningDevices中的device加入mDevices Map中,以device->id标记
            auto [dev_it, inserted] = mDevices.insert_or_assign(device->id, std::move(device));

            mNeedToSendFinishedDeviceScan = true;  //标记扫描完成,可以退出扫描状态(退出也要发退出事件)
            //如果RawEvent数组装满了,就跳出循环往下执行(需要等数组中数据分发释放后进入这里再处理)
            if (--capacity == 0) {  
                break;
            }
        }
        //如果扫描结束需要发一个mNeedToSendFinishedDeviceScan事件,将这个事件构造并写入event(RawEvent)数组中
        if (mNeedToSendFinishedDeviceScan) {
            mNeedToSendFinishedDeviceScan = false;
            event->when = now;
            event->type = FINISHED_DEVICE_SCAN;
            event += 1;  //RawEvent对象偏移 + 1(RawEvent数组中RawEvent数量)
            if (--capacity == 0) {
                break;
            }
        }

        // Grab the next input event.
        //从epoll中下一个输入事件
        bool deviceChanged = false;  //这个变量标记当前设备是否有变化(拔插、配置改变等)
        //mPendingEventCount指epoll中返回的事件(在epoll event数组中)的数量
        //mPendingEventIndex指要处理的epoll事件在epoll返回列表中的下标
        //循环处理epoll返回列表中的epoll事件
        while (mPendingEventIndex < mPendingEventCount) {
            const struct epoll_event& eventItem = mPendingEventItems[mPendingEventIndex++];
            if (eventItem.data.fd == mINotifyFd) {
                if (eventItem.events & EPOLLIN) {
                    mPendingINotify = true;
                } else {
                    ALOGW("Received unexpected epoll event 0x%08x for INotify.", eventItem.events);
                }
                continue;
            }

            if (eventItem.data.fd == mWakeReadPipeFd) {
                if (eventItem.events & EPOLLIN) {
                    ALOGV("awoken after wake()");
                    awoken = true;
                    char wakeReadBuffer[16];
                    ssize_t nRead;
                    do {
                        nRead = read(mWakeReadPipeFd, wakeReadBuffer, sizeof(wakeReadBuffer));
                    } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(wakeReadBuffer));
                } else {
                    ALOGW("Received unexpected epoll event 0x%08x for wake read pipe.",
                          eventItem.events);
                }
                continue;
            }

            //如果非mINotifyFd和非mWakeReadPipeFd,则是底层输入驱动上报的输入事件,那么通过fd获取这个事件对应的Device
            Device* device = getDeviceByFdLocked(eventItem.data.fd);
            
             ...
            // This must be an input event
            //如果是个epoll读事件
            if (eventItem.events & EPOLLIN) {
                //通过read方法获取读缓冲区大小和数据。写入readBuffer,读取size为256个input_event
                int32_t readSize =
                        read(device->fd, readBuffer, sizeof(struct input_event) * capacity);
                        
                if (readSize == 0 || (readSize < 0 && errno == ENODEV)) {
                    // Device was removed before INotify noticed.
                    //如果读取的size <= 0 且返回异常可能是设备已经被移除了,只是INotify还没通知,
                    //那么就标记这个设备状态改变,并移除这个设备
                    deviceChanged = true;  //标记这个设备状态改变
                    closeDeviceLocked(*device);  //移除这个设备
                } else if (readSize < 0) {
                    ...
                } else if ((readSize % sizeof(struct input_event)) != 0) {
                    ...
                } else { //正常读到数据了
                    //(特殊)如果读到的device是内置键盘,name就设置它的device->id = 0
                    int32_t deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
                    //计算这次读到的epoll读事件中的readBuffer中包含的input_event数量
                    size_t count = size_t(readSize) / sizeof(struct input_event);
                    //从readBuffer循环取出读到的的input_event对象
                    //构造RawEvent对象写入RawEvent数组中,指针依次往后偏移
                    for (size_t i = 0; i < count; i++) {
                        struct input_event& iev = readBuffer[i];
                        event->when = processEventTimestamp(iev);
                        event->readTime = systemTime(SYSTEM_TIME_MONOTONIC);
                        event->deviceId = deviceId;
                        event->type = iev.type;
                        event->code = iev.code;
                        event->value = iev.value;
                        event += 1;
                        capacity -= 1;
                    }
                    //如果写满了RawEvent数组
                    if (capacity == 0) {
                        // The result buffer is full.  Reset the pending event index
                        // so we will try to read the device again on the next iteration.
                        // 如果RawEvent数组写满了,就把mPendingEventIndex - 1,(因为下次循环开始会加一,提前减一这样处理的就还是当前这个epoll事件)
                        // 说明我们本次epoll读事件我们没有处理完,下一个循环还要继续处理这个epoll事件
                        mPendingEventIndex -= 1;
                        break;
                    }
                }
            } else if (eventItem.events & EPOLLHUP) {  //如果是hang-up事件说明设备拔出,就移除这个设备,通知设备状态变化
                ALOGI("Removing device %s due to epoll hang-up event.",
                      device->identifier.name.c_str());
                deviceChanged = true;
                closeDeviceLocked(*device);
            } else {  //收到异常的epoll事件,不处理
                ALOGW("Received unexpected epoll event 0x%08x for device %s.", eventItem.events,
                      device->identifier.name.c_str());
            }
        }

        // readNotify() will modify the list of devices so this must be done after
        // processing all other events to ensure that we read all remaining events
        // before closing the devices.
        //当处理完一次一次epoll_wait返回列表中所有epoll事件后,检测下是否有底层设备变化(mPendingINotify = true)
        //如果有就通知设备状态改变
        if (mPendingINotify && mPendingEventIndex >= mPendingEventCount) {
            mPendingINotify = false;
            readNotifyLocked();  //通过read去读取INotify fd返回的事件,判断设备状态,是需要重新获取设备还是移除设备
            deviceChanged = true;  //标记设备状态改变,
        }

        // Report added or removed devices immediately.
        // 如果有设备状态改变(新增或者移除)需要马上到下一个循环处理
        if (deviceChanged) {
            continue;
        }

        // Return now if we have collected any events or if we were explicitly awoken.
        //1.如果其他地方调用了`mEventHub->wake()`则会唤醒阻塞在epoll_wait()中的inputReader线程,下一次循环时然后从这里跳出getEvents方法,往下执行loopOnce,处理输入事件
        //2. 或者RawEvent数组中有数据则跳出getEvents方法,往下执行loopOnce,处理输入事件
        if (event != buffer || awoken) {
            break;
        }

        //如果RawEvent数组为空且没有inputReader线程没有被外部唤醒,则下面就准备开始获取下一次epoll事件(进入阻塞等待)
        mPendingEventIndex = 0; //准备进入下一次事件接收前,重置mPendingEventIndex下标

        mLock.unlock(); // release lock before poll
        //进入epoll_wait阻塞等待驱动上报事件
        int pollResult = epoll_wait(mEpollFd, mPendingEventItems, EPOLL_MAX_EVENTS, timeoutMillis);
        //从epoll_wait中唤醒
        //也许是外部调用mEventHub->wake()唤醒
        //或者内核通知事件上报唤醒
        //或者是超时退出休眠
        
        mLock.lock(); // reacquire lock after poll

        if (pollResult == 0) {
            // Timed out.
            // 超时退出的情况
            mPendingEventCount = 0;
            break;
        }

        if (pollResult < 0) {
            // An error occurred.
            mPendingEventCount = 0;

            // Sleep after errors to avoid locking up the system.
            // Hopefully the error is transient.
            if (errno != EINTR) {
                ALOGW("poll failed (errno=%d)\n", errno);
                usleep(100000);
            }
        } else {
            // Some events occurred.
            // 获取到epoll事件,将事件数量赋给mPendingEventCount
            mPendingEventCount = size_t(pollResult);
        }
    }

    // All done, return the number of events we read.
    // 处理结束,退出循环将事件返回到inputReader的loopOnce中处理
    return event - buffer;
}

EventHub::scanDevicesLocked()

void EventHub::scanDevicesLocked() {
    status_t result;
    std::error_code errorCode;
            
    if (std::filesystem::exists(DEVICE_INPUT_PATH, errorCode)) {
        result = scanDirLocked(DEVICE_INPUT_PATH);
        
    } else {
        ...
    }
    ...
}

status_t EventHub::scanDirLocked(const std::string& dirname) {
    //遍历 /dev/input/event* 路径,打开这些设备并获取相关设备信息
    for (const auto& entry : std::filesystem::directory_iterator(dirname)) {
        openDeviceLocked(entry.path());
    }
    return 0;
}

EventHub::openDeviceLocked

这个方法很长,主要作用就是打开/dev/input/eventX设备节点,用返回的fd通过ioctl向驱动获取输入设备device相关信息。

void EventHub::openDeviceLocked(const std::string& devicePath) {
    //如果目标路径是当前已存在的设备(之前扫描过的设备)的,就不再扫描这个路径了,避免出现重复设备
    for (const auto& [deviceId, device] : mDevices) {
        if (device->path == devicePath) {
            return; // device was already registered
        }
    }

    char buffer[80];

    ALOGV("Opening device: %s", devicePath.c_str());
    //通过open打开设备节点,返回该设备节点的fd
    int fd = open(devicePath.c_str(), O_RDWR | O_CLOEXEC | O_NONBLOCK);
            
    InputDeviceIdentifier identifier;  //一个硬件设备的结构体在用户空间中描述, 包括name、vendor、product、descriptor等

    // Get device name.
    //获取设备 device name
    if (ioctl(fd, EVIOCGNAME(sizeof(buffer) - 1), &buffer) < 1) {
        ALOGE("Could not get device name for %s: %s", devicePath.c_str(), strerror(errno));
    } else {
        buffer[sizeof(buffer) - 1] = '\0';
        identifier.name = buffer;
    }

    // Check to see if the device is on our excluded list
    //通过device name检测下这个设备是不是在排除名单,如果是就忽略这个设备
    for (size_t i = 0; i < mExcludedDevices.size(); i++) {
        const std::string& item = mExcludedDevices[i];
        if (identifier.name == item) {
            ALOGI("ignoring event id %s driver %s\n", devicePath.c_str(), item.c_str());
            close(fd);
            return;
        }
    }

    // Get device driver version.
    //获取设备驱动版本
    int driverVersion;
    if (ioctl(fd, EVIOCGVERSION, &driverVersion)) {
    }

    // Get device identifier.
    //获取设备的identifier,是设备在内核空间的描述
    //内核描述为input_id结构体,内容为:bustype、product、product、version
    struct input_id inputId;
    if (ioctl(fd, EVIOCGID, &inputId)) {
    }
    identifier.bus = inputId.bustype;
    identifier.product = inputId.product;
    identifier.vendor = inputId.product;
    identifier.version = inputId.version;

    // Get device physical location.
    //获取设备的物理位置(物理拓扑中的位置)
    if (ioctl(fd, EVIOCGPHYS(sizeof(buffer) - 1), &buffer) < 1) {
        // fprintf(stderr, "could not get location for %s, %s\n", devicePath, strerror(errno));
    } else {
        buffer[sizeof(buffer) - 1] = '\0';
        identifier.location = buffer;
    }

    // Get device unique id.
    //获取设备的unique id(一般的设备这个字段都是没有的,为空)
    if (ioctl(fd, EVIOCGUNIQ(sizeof(buffer) - 1), &buffer) < 1) {
        // fprintf(stderr, "could not get idstring for %s, %s\n", devicePath, strerror(errno));
    } else {
        buffer[sizeof(buffer) - 1] = '\0';
        identifier.uniqueId = buffer;
    }

    // Fill in the descriptor.
    // 获取设备的descriptor,这个字段很重要,它是用于标识这个设备的标识符,无论重启、拔插、升级都不会变
    //根据unique_id、vendor_id、product_id、随机数组合后sha1转化生成,赋值给identifier.descriptor
    assignDescriptorLocked(identifier);

    // Allocate device.  (The device object takes ownership of the fd at this point.)
    //创建Device结构体,用于描述当前从驱动获取到的这个输入设备,将前面获取的设备fd、设备节点路径devicePath、设备硬件描述identifier赋给这个Device,
    //同时还有deviceId,这个id并不是驱动传上来的,而是我们每次通过ioctl获取到新设备时计数 + 1
    int32_t deviceId = mNextDeviceId++;
    std::unique_ptr<Device> device = std::make_unique<Device>(fd, deviceId, devicePath, identifier);

    //我们可以通过这个打印或者dumpsys input获取设备的信息
    ALOGV("add device %d: %s\n", deviceId, devicePath.c_str());
    ALOGV("  bus:        %04x\n"
          "  vendor      %04x\n"
          "  product     %04x\n"
          "  version     %04x\n",
          identifier.bus, identifier.vendor, identifier.product, identifier.version);
    ALOGV("  name:       \"%s\"\n", identifier.name.c_str());
    ALOGV("  location:   \"%s\"\n", identifier.location.c_str());
    ALOGV("  unique id:  \"%s\"\n", identifier.uniqueId.c_str());
    ALOGV("  descriptor: \"%s\"\n", identifier.descriptor.c_str());
    ALOGV("  driver:     v%d.%d.%d\n", driverVersion >> 16, (driverVersion >> 8) & 0xff,
          driverVersion & 0xff);

    // Load the configuration file for the device.
    //为当前获取到的设备加载`.idc`配置文件,格式一般是:/vendor/usr/idc/Vendor_XXXX_Product_XXXX_Version_XXXX.idc
    //通过product/vendor/version来检索主要路径下符合条件的`idc`文件
    //解析该文件后保存在device对象的configuration变量中
    device->loadConfigurationLocked();

    // 针对带电池,有LED灯的输入设备,需要设备associatedDevice来关联它的额外能力
    bool hasBattery = false;
    bool hasLights = false;
    // Check the sysfs root path
    std::optional<std::filesystem::path> sysfsRootPath = getSysfsRootPath(devicePath.c_str());
    if (sysfsRootPath.has_value()) {
        std::shared_ptr<AssociatedDevice> associatedDevice;
        for (const auto& [id, dev] : mDevices) {
            if (device->identifier.descriptor == dev->identifier.descriptor &&
                !dev->associatedDevice) {
                associatedDevice = dev->associatedDevice;
            }
        }
        if (!associatedDevice) {
            associatedDevice = std::make_shared<AssociatedDevice>(sysfsRootPath.value());
        }
        hasBattery = associatedDevice->configureBatteryLocked();
        hasLights = associatedDevice->configureLightsLocked();

        device->associatedDevice = associatedDevice;
    }

    //向ioctl驱动查询这个设备会上报那种类型的事件,每个类型都问一下支不支持,有点...
    //设备会上报哪一种事件,对应的XXBitmask就会有对应的值,用于判断它是什么类型的设备
    // Figure out the kinds of events the device reports.
    device->readDeviceBitMask(EVIOCGBIT(EV_KEY, 0), device->keyBitmask);
    device->readDeviceBitMask(EVIOCGBIT(EV_ABS, 0), device->absBitmask);
    device->readDeviceBitMask(EVIOCGBIT(EV_REL, 0), device->relBitmask);
    device->readDeviceBitMask(EVIOCGBIT(EV_SW, 0), device->swBitmask);
    device->readDeviceBitMask(EVIOCGBIT(EV_LED, 0), device->ledBitmask);
    device->readDeviceBitMask(EVIOCGBIT(EV_FF, 0), device->ffBitmask);
    device->readDeviceBitMask(EVIOCGBIT(EV_MSC, 0), device->mscBitmask);
    device->readDeviceBitMask(EVIOCGPROP(0), device->propBitmask);

    // See if this is a keyboard.  Ignore everything in the button range except for
    // joystick and gamepad buttons which are handled like keyboards for the most part.
    // 判断是否是键盘、游戏手柄等
    bool haveKeyboardKeys =
            device->keyBitmask.any(0, BTN_MISC) || device->keyBitmask.any(BTN_WHEEL, KEY_MAX + 1);
    bool haveGamepadButtons = device->keyBitmask.any(BTN_MISC, BTN_MOUSE) ||
            device->keyBitmask.any(BTN_JOYSTICK, BTN_DIGI);
    if (haveKeyboardKeys || haveGamepadButtons) {
        device->classes |= InputDeviceClass::KEYBOARD;
    }

    // See if this is a cursor device such as a trackball or mouse.
    //判断设备是不是鼠标或者轨迹球类型
    if (device->keyBitmask.test(BTN_MOUSE) && device->relBitmask.test(REL_X) &&
        device->relBitmask.test(REL_Y)) {
        device->classes |= InputDeviceClass::CURSOR;
    }

    // See if this is a rotary encoder type device.
    //判断设备是不是旋转编码器类型(旋钮)
    String8 deviceType = String8();
    if (device->configuration &&
        device->configuration->tryGetProperty(String8("device.type"), deviceType)) {
        if (!deviceType.compare(String8("rotaryEncoder"))) {
            device->classes |= InputDeviceClass::ROTARY_ENCODER;
        }
    }

    // See if this is a touch pad.
    // Is this a new modern multi-touch driver?
    //是不是触摸板,支不支持多点触摸
    if (device->absBitmask.test(ABS_MT_POSITION_X) && device->absBitmask.test(ABS_MT_POSITION_Y)) {
        // Some joysticks such as the PS3 controller report axes that conflict
        // with the ABS_MT range.  Try to confirm that the device really is
        // a touch screen.
        if (device->keyBitmask.test(BTN_TOUCH) || !haveGamepadButtons) {
            device->classes |= (InputDeviceClass::TOUCH | InputDeviceClass::TOUCH_MT);
        }
        // Is this an old style single-touch driver?
        //是不是老版的单点触摸驱动
    } else if (device->keyBitmask.test(BTN_TOUCH) && device->absBitmask.test(ABS_X) &&
               device->absBitmask.test(ABS_Y)) {
        device->classes |= InputDeviceClass::TOUCH;
        // Is this a BT stylus?
        //是不是蓝牙手写笔
    } else if ((device->absBitmask.test(ABS_PRESSURE) || device->keyBitmask.test(BTN_TOUCH)) &&
               !device->absBitmask.test(ABS_X) && !device->absBitmask.test(ABS_Y)) {
        device->classes |= InputDeviceClass::EXTERNAL_STYLUS;
        // Keyboard will try to claim some of the buttons but we really want to reserve those so we
        // can fuse it with the touch screen data, so just take them back. Note this means an
        // external stylus cannot also be a keyboard device.
        //外部手写笔不能同时是键盘设备
        device->classes &= ~InputDeviceClass::KEYBOARD;
    }

    // See if this device is a joystick.
    // Assumes that joysticks always have gamepad buttons in order to distinguish them
    // from other devices such as accelerometers that also have absolute axes.
    //是不是操作杆
    if (haveGamepadButtons) {
        auto assumedClasses = device->classes | InputDeviceClass::JOYSTICK;
        for (int i = 0; i <= ABS_MAX; i++) {
            if (device->absBitmask.test(i) &&
                (getAbsAxisUsage(i, assumedClasses).test(InputDeviceClass::JOYSTICK))) {
                device->classes = assumedClasses;
                break;
            }
        }
    }

    // Check whether this device is an accelerometer.
    //是不是加速计
    if (device->propBitmask.test(INPUT_PROP_ACCELEROMETER)) {
        device->classes |= InputDeviceClass::SENSOR;
    }

    // Check whether this device has switches.
    //是不是有开关
    for (int i = 0; i <= SW_MAX; i++) {
        if (device->swBitmask.test(i)) {
            device->classes |= InputDeviceClass::SWITCH;
            break;
        }
    }

    // Check whether this device supports the vibrator.
    //支不支持震动
    if (device->ffBitmask.test(FF_RUMBLE)) {
        device->classes |= InputDeviceClass::VIBRATOR;
    }

    // Configure virtual keys.
    //虚拟按键(类似于老手机上面三个虚拟按键back、home、recent)
    if ((device->classes.test(InputDeviceClass::TOUCH))) {
        // Load the virtual keys for the touch screen, if any.
        // We do this now so that we can make sure to load the keymap if necessary.
        bool success = device->loadVirtualKeyMapLocked();
        if (success) {
            device->classes |= InputDeviceClass::KEYBOARD;
        }
    }

    // Load the key map.
    // We need to do this for joysticks too because the key layout may specify axes, and for
    // sensor as well because the key layout may specify the axes to sensor data mapping.
    //如果设备是键盘等设备就加载按键映射配置文件,
    //包括kl(keyLayout)文件、kcm(KeyCharacterMap)文件
    status_t keyMapStatus = NAME_NOT_FOUND;
    if (device->classes.any(InputDeviceClass::KEYBOARD | InputDeviceClass::JOYSTICK |
                            InputDeviceClass::SENSOR)) {
        // Load the keymap for the device.
        keyMapStatus = device->loadKeyMapLocked();  //加载过程和idc文件类似
    }

    // Configure the keyboard, gamepad or virtual keyboard.
    //配置键盘、手柄、虚拟键盘相关
    if (device->classes.test(InputDeviceClass::KEYBOARD)) {
        // Register the keyboard as a built-in keyboard if it is eligible.
        //如果符合内置键盘的条件就把这个device指定为内置键盘
        if (!keyMapStatus && mBuiltInKeyboardId == NO_BUILT_IN_KEYBOARD &&
            isEligibleBuiltInKeyboard(device->identifier, device->configuration.get(),
                                      &device->keyMap)) {
            mBuiltInKeyboardId = device->id;
        }

        // 'Q' key support = cheap test of whether this is an alpha-capable kbd
        //如果有Q键就说明是一个标准全功能键盘,设置为ALPHAKEY类型
        if (device->hasKeycodeLocked(AKEYCODE_Q)) {
            device->classes |= InputDeviceClass::ALPHAKEY;
        }

        // See if this device has a DPAD.
        //如果有方向键
        if (device->hasKeycodeLocked(AKEYCODE_DPAD_UP) &&
            device->hasKeycodeLocked(AKEYCODE_DPAD_DOWN) &&
            device->hasKeycodeLocked(AKEYCODE_DPAD_LEFT) &&
            device->hasKeycodeLocked(AKEYCODE_DPAD_RIGHT) &&
            device->hasKeycodeLocked(AKEYCODE_DPAD_CENTER)) {
            device->classes |= InputDeviceClass::DPAD;
        }

        // See if this device has a gamepad.
        //如果是游戏手柄
        for (size_t i = 0; i < sizeof(GAMEPAD_KEYCODES) / sizeof(GAMEPAD_KEYCODES[0]); i++) {
            if (device->hasKeycodeLocked(GAMEPAD_KEYCODES[i])) {
                device->classes |= InputDeviceClass::GAMEPAD;
                break;
            }
        }
    }

    // If the device isn't recognized as something we handle, don't monitor it.
    //如果这个设备上面的类型都不符合,那么这个设备就是个屑,不用往下处理了,忽略,直接返回
    if (device->classes == ftl::Flags<InputDeviceClass>(0)) {
        ALOGV("Dropping device: id=%d, path='%s', name='%s'", deviceId, devicePath.c_str(),
              device->identifier.name.c_str());
        return;
    }

    // Classify InputDeviceClass::BATTERY.
    //如果这个设备还有关联的电池
    if (hasBattery) {
        device->classes |= InputDeviceClass::BATTERY;
    }

    // Classify InputDeviceClass::LIGHT.
    //如果这个设备还有先进的LED灯
    if (hasLights) {
        device->classes |= InputDeviceClass::LIGHT;
    }

    // Determine whether the device has a mic.
    //如果这个设备还有麦克风
    if (device->deviceHasMicLocked()) {
        device->classes |= InputDeviceClass::MIC;
    }

    // Determine whether the device is external or internal.
    //从设备的idc文件中获取这个设备是内部设备还是外接设备,这个会影响一些优先级等,比如多屏
    if (device->isExternalDeviceLocked()) {
        device->classes |= InputDeviceClass::EXTERNAL;
    }

    //游戏手柄和操作杆有时会有多个controller
    if (device->classes.any(InputDeviceClass::JOYSTICK | InputDeviceClass::DPAD) &&
        device->classes.test(InputDeviceClass::GAMEPAD)) {
        device->controllerNumber = getNextControllerNumberLocked(device->identifier.name);
        device->setLedForControllerLocked();
    }

    //将这个设备的fd加入epoll的监听
    if (registerDeviceForEpollLocked(*device) != OK) {
        return;
    }
    //使用ioctl设置fd参数,例如按键重复、挂起块和时钟类型
    device->configureFd();

    ALOGI("New device: id=%d, fd=%d, path='%s', name='%s', classes=%s, "
          "configuration='%s', keyLayout='%s', keyCharacterMap='%s', builtinKeyboard=%s, ",
          deviceId, fd, devicePath.c_str(), device->identifier.name.c_str(),
          device->classes.string().c_str(), device->configurationFile.c_str(),
          device->keyMap.keyLayoutFile.c_str(), device->keyMap.keyCharacterMapFile.c_str(),
          toString(mBuiltInKeyboardId == deviceId));

    //到这里从驱动获取到的这个设备已经完成各种初始化和配置,是时候加到mOpeningDevices中了,继续下一个循环,最后读取所有的设备
    addDeviceLocked(std::move(device));
}

这个方法很长,总的概括来看就做了几件事情:

  1. 打开设备节点,从设备驱动中获取设备的各种描述信息并构造出Device对象
  2. 根据设备的信息加载这个设备的idc文件
  3. 向驱动查询这个设备支持的事件类型
  4. 判断设备的类型,设置相关的属性到device->classes
  5. 如果是键盘灯设备还需要加载设备对应的kl文件和kcm文件,
  6. 将这个设备的fd加入epoll的监听中
  7. 通过ioctl设置fd参数,例如按键重复、挂起块和时钟类型
  8. 最后再把这个设备加到mOpeningDevices中管理

服务的启动

frameworks/base/services/java/com/android/server/SystemServer.java

    private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
        t.traceBegin("startOtherServices");
        ...
        WindowManagerService wm = null;
        InputManagerService inputManager = null;

        try {
            //1. 获取InputManagerService,并走初始化inputManager流程
            ...
            t.traceBegin("StartInputManagerService");
            inputManager = new InputManagerService(context);
            t.traceEnd();
            ...
            //2. WindowManagerService服务持有inputManager对象
            t.traceBegin("StartWindowManagerService");
            wm = WindowManagerService.main(context, inputManager, !mFirstBoot, mOnlyCore,
                    new PhoneWindowManager(), mActivityManagerService.mActivityTaskManager);
               ...
               //3. 向ServiceManager注册java层ims服务,name = "input",(native层的服务name = "inputflinger")
            ServiceManager.addService(Context.INPUT_SERVICE, inputManager,
                    /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
            t.traceEnd();

            ...
            //4. 启动inputflinger,处理输入事件
            t.traceBegin("StartInputManager");
            inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
            inputManager.start();
            t.traceEnd();
            ...
        } catch (Throwable e) {
            ...
        }
  1. 获取InputManagerService,并走初始化inputManager(java层和native层)流程
  2. WindowManagerService服务构造时传入inputManager对象,用户wms和ims交互
  3. 向ServiceManager注册java层ims服务
  4. 启动inputflinger,处理输入事件

我们重点看下1和4

1. 初始化InputFlinger

frameworks/base/services/core/java/com/android/server/input/InputManagerService.java

    public InputManagerService(Context context) {
        this(new Injector(context, DisplayThread.get().getLooper()));
    }

    @VisibleForTesting
    InputManagerService(Injector injector) {
        ...
        mContext = injector.getContext();
        mHandler = new InputManagerHandler(injector.getLooper());  //创建一个handle(使用DisplayThread,这个线程用户
       //wms,display,input三个服务使用,对延迟敏感)
        mNative = injector.getNativeService(this);  //创建native input服务(NativeInputManagerService)
        ...
        injector.registerLocalService(new LocalService());  //将InputManagerService中的InputManagerInternal实现类加入LocalServices,供同进程其他服务调用相关功能
    }

    @VisibleForTesting
    static class Injector {
        private final Context mContext;
        private final Looper mLooper;

        Injector(Context context, Looper looper) {
            mContext = context;
            mLooper = looper;
        }

        Context getContext() {
            return mContext;
        }

        Looper getLooper() {
            return mLooper;
        }
        //创建native层对应的service
        NativeInputManagerService getNativeService(InputManagerService service) {
            return new NativeInputManagerService.NativeImpl(service, mContext, mLooper.getQueue());
        }
        //将InputManagerService中的InputManagerInternal实现类加入LocalServices,供同进程其他服务调用相关功能
        void registerLocalService(InputManagerInternal localService) {
            LocalServices.addService(InputManagerInternal.class, localService);
        }
    }

NativeInputManagerService.NativeImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public interface NativeInputManagerService {
...
class NativeImpl implements NativeInputManagerService {
/** Pointer to native input manager service object, used by native code. */
@SuppressWarnings({"unused", "FieldCanBeLocal"})
private final long mPtr;

NativeImpl(InputManagerService service, Context context, MessageQueue messageQueue) {
mPtr = init(service, context, messageQueue); //初始化native层服务并返回该服务的对象指针到java层
}

private native long init(InputManagerService service, Context context,
MessageQueue messageQueue);
...
}
...
}

nativeInit

frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp

static const JNINativeMethod gInputManagerMethods[] = {
        {"init",
         "(Lcom/android/server/input/InputManagerService;Landroid/content/Context;Landroid/os/"
         "MessageQueue;)J",
         (void*)nativeInit},  //init(java)->nativeInit(native)
        ...
};
    
static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
        jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
    ...
    // 创建native层NativeInputManager,保存java层的context对象、ims对象、msgqueue
    NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
            messageQueue->getLooper());
    im->incStrong(0);  //NativeInputManager对象强引用 + 1
    return reinterpret_cast<jlong>(im);  //将native层NativeInputManager对象地址返回给java层,这个地址可以在native层获取出同一个对象
}

//NativeInputManager类声明,实现了三个重要接口抽象类
/*class NativeInputManager : public virtual RefBase,
    public virtual InputReaderPolicyInterface,
    public virtual InputDispatcherPolicyInterface,
    public virtual PointerControllerPolicyInterface {
    */
    
NativeInputManager::NativeInputManager(jobject contextObj,
        jobject serviceObj, const sp<Looper>& looper) :
        mLooper(looper), mInteractive(true) {
    JNIEnv* env = jniEnv();  //获取虚拟机环境指针
        
    mServiceObj = env->NewGlobalRef(serviceObj);  //将java层的ims对象保存为全局引用

    {
        AutoMutex _l(mLock);
        mLocked.systemUiLightsOut = false;
        mLocked.pointerSpeed = 0;
        mLocked.pointerAcceleration = android::os::IInputConstants::DEFAULT_POINTER_ACCELERATION;
        mLocked.pointerGesturesEnabled = true;
        mLocked.showTouches = false;
        mLocked.pointerDisplayId = ADISPLAY_ID_DEFAULT;
    }
    mInteractive = true;

    InputManager* im = new InputManager(this, this);  //创建native层InputManager
    mInputManager = im;
    defaultServiceManager()->addService(String16("inputflinger"), im);  //向ServiceManager注册native层inputflinger服务
}

new InputManager

frameworks/native/services/inputflinger/InputManager.cpp

/**
 * The event flow is via the "InputListener" interface, as follows:
 * InputReader -> UnwantedInteractionBlocker -> InputClassifier -> InputDispatcher
 */
InputManager::InputManager(
        const sp<InputReaderPolicyInterface>& readerPolicy,
        const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
    mDispatcher = createInputDispatcher(dispatcherPolicy);
    mClassifier = std::make_unique<InputClassifier>(*mDispatcher);
    mBlocker = std::make_unique<UnwantedInteractionBlocker>(*mClassifier);
    mReader = createInputReader(readerPolicy, *mBlocker);
}

创建并初始化四个event flow中的重要对象, 事件从前到后传递,前面的对象依次持有下一个阶段的对象引用
event flow: InputReader -> UnwantedInteractionBlocker -> InputClassifier -> InputDispatcher

createInputDispatcher

frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp

//InputDispatcherFactory.cpp
std::unique_ptr<InputDispatcherInterface> createInputDispatcher(
        const sp<InputDispatcherPolicyInterface>& policy) {
    return std::make_unique<android::inputdispatcher::InputDispatcher>(policy);
}
//  InputDispatcher.cpp
InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy)
      : InputDispatcher(policy, STALE_EVENT_TIMEOUT) {}

InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy,
                                 std::chrono::nanoseconds staleEventTimeout)
      : mPolicy(policy),  //将接口实现对象传进来,用户和wms服务交互
     ...//一些成员变量初始化,太多了不列出
     {
     
    mLooper = new Looper(false);  //用于InputDispatcher线程
    mReporter = createInputReporter();
    //注册SurfaceComposer监听,当window状态改变时回调此接口onWindowInfosChanged通知inputflinger
    mWindowInfoListener = new DispatcherWindowListener(*this);
    SurfaceComposerClient::getDefault()->addWindowInfosListener(mWindowInfoListener);

    mKeyRepeatState.lastKeyEntry = nullptr;

    policy->getDispatcherConfiguration(&mConfig);
}

InputClassifier

frameworks/native/services/inputflinger/InputClassifier.cpp

//构建InputClassifier,传入mQueuedListener = listener 这个就是mDispatcher对象,这样就可以回调mDispatcher的方法
InputClassifier::InputClassifier(InputListenerInterface& listener) : mQueuedListener(listener) {}

UnwantedInteractionBlocker

//UnwantedInteractionBlocker是所有输入事件都会经历的一个阶段
//inputReader通过它notifyXXX方法向InputDispatcher传递对应事件
//其中对于触摸事件,如果支持手掌误触等功能,则会在这里有特殊处理
UnwantedInteractionBlocker::UnwantedInteractionBlocker(InputListenerInterface& listener)
      : UnwantedInteractionBlocker(listener, isPalmRejectionEnabled()){};
//isPalmRejectionEnabled 检测是否开始手掌误触功能
UnwantedInteractionBlocker::UnwantedInteractionBlocker(InputListenerInterface& listener,
                                                       bool enablePalmRejection)
      : mQueuedListener(listener), mEnablePalmRejection(enablePalmRejection) {}

InputReader

frameworks/native/services/inputflinger/reader/InputReader.cpp

std::unique_ptr<InputReaderInterface> createInputReader(
        const sp<InputReaderPolicyInterface>& policy, InputListenerInterface& listener) {
    return std::make_unique<InputReader>(std::make_unique<EventHub>(), policy, listener);
}

InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,
                         const sp<InputReaderPolicyInterface>& policy,
                         InputListenerInterface& listener)
      : mContext(this),
        mEventHub(eventHub), //1.初始化EventHub
        mPolicy(policy),
        mQueuedListener(listener),  //2. 传入UnwantedInteractionBlocker对象
        mGlobalMetaState(AMETA_NONE),
        mLedMetaState(AMETA_NONE),
        mGeneration(1),
        mNextInputDeviceId(END_RESERVED_ID),
        mDisableVirtualKeysTimeout(LLONG_MIN),
        mNextTimeout(LLONG_MAX),
        mConfigurationChangesToRefresh(0) {
    refreshConfigurationLocked(0);
    updateGlobalMetaStateLocked();
}

InputReader最重要就是:

  1. 创建并初始化EventHub, 通过它向驱动获取上报的事件
  2. 注册UnwantedInteractionBlocker listener, 通过它向inputDispater传递事件

EventHub

frameworks/native/services/inputflinger/reader/EventHub.cpp

EventHub::EventHub(void)
      : mBuiltInKeyboardId(NO_BUILT_IN_KEYBOARD),
        mNextDeviceId(1),
        mControllerNumbers(),
        mNeedToSendFinishedDeviceScan(false),
        mNeedToReopenDevices(false),
        mNeedToScanDevices(true),
        mPendingEventCount(0),
        mPendingEventIndex(0),
        mPendingINotify(false) {
    ensureProcessCanBlockSuspend();
    //初始化epoll (用于监听文件描述符上的事件,用于监听具体/dev/input/eventX的fd的事件)
    mEpollFd = epoll_create1(EPOLL_CLOEXEC);
    LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance: %s", strerror(errno));
    //初始化inotify (用于监听文件和目录的变化,这里主要时用于监听/dev/input/下面的目录变化)
    mINotifyFd = inotify_init1(IN_CLOEXEC);

    std::error_code errorCode;
    bool isDeviceInotifyAdded = false;
    //检测 "/dev/input" 文件节点是否存在
    if (std::filesystem::exists(DEVICE_INPUT_PATH, errorCode)) {
        //如果当前"/dev/input" 文件节点存在则将这个路径加入Inotify监听
        addDeviceInputInotify();
    } else {
        //如果当前"/dev/input" 文件节点不存在,则先将这个路径"/dev"加入Inotify监听(监听dev所有节点)
        //因为有些嵌入式设备不一定一直存在输入设备,那么仅当/dev/input出现时(插入输入设备)才添加对/dev/input内容的监听, 
        addDeviceInotify();
        isDeviceInotifyAdded = true;
    }
    
    //V4L视频设备相关
    if (isV4lScanningEnabled() && !isDeviceInotifyAdded) {
        addDeviceInotify();
    } else {
        ALOGI("Video device scanning disabled");
    }

    struct epoll_event eventItem = {};
    eventItem.events = EPOLLIN | EPOLLWAKEUP; //设置监听epoll事件类型
    eventItem.data.fd = mINotifyFd;//要处理的事件相关的文件描述符
    
    //将mINotifyFd加入epoll监听的fd池子
    int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &eventItem);

    //创建一个管道
    int wakeFds[2];
    result = pipe2(wakeFds, O_CLOEXEC);

    mWakeReadPipeFd = wakeFds[0];  //0为读端
    mWakeWritePipeFd = wakeFds[1];  //1为写端

    result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);

    result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);

    eventItem.data.fd = mWakeReadPipeFd;  //将mWakeReadPipeFd设置到eventItem.data.fd,当epoll有event到来会
    //将管道读端fd加入epoll监听的fd池子,当管道写端写入数据时,读端就换监听到epoll事件
    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, &eventItem);
}

到这里初始化InputFlinger就完成了

2. 启动inputflinger,处理输入事件

前面SystemServer的1、2、3步都完成后,会往下执行

    //4. 启动inputflinger,处理输入事件
          t.traceBegin("StartInputManager");
          //ims也注册wms的回调,用于通知wms一些事件发生
          inputManager.setWindowManagerCallbacks(wm.getInputManagerCallback());
          inputManager.start();  //启动ims,开始处理输入事件
          t.traceEnd();

start()

frameworks/base/services/core/java/com/android/server/input/InputManagerService.java

    public void start() {
        Slog.i(TAG, "Starting input manager");
        mNative.start();  //到native中的方法

        // Add ourselves to the Watchdog monitors.
        Watchdog.getInstance().addMonitor(this); //加入Watchdog的检测列表中

        //一系列对settings中开关的状态值监听
        ...
    }

nativeStart

frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp

static void nativeStart(JNIEnv* env, jobject nativeImplObj) {
    NativeInputManager* im = getNativeInputManager(env, nativeImplObj);
    
    status_t result = im->getInputManager()->start();
}

InputManager::start()

status_t InputManager::start() {
    status_t result = mDispatcher->start();
    result = mReader->start();

    return OK;
}

分别调用inputDispatcherinputReaderstart方法

InputDispatcher::start()

//InputManager.cpp
status_t InputDispatcher::start() {

    //创建线程InputDispatcher,线程体函数dispatchOnce(), 线程唤醒函数mLooper->wake()
    mThread = std::make_unique<InputThread>(
            "InputDispatcher", [this]() { dispatchOnce(); }, [this]() { mLooper->wake(); });
    return OK;
}

InputThread继承与Thead
frameworks/native/services/inputflinger/InputThread.cpp

InputThread::InputThread(std::string name, std::function<void()> loop, std::function<void()> wake)
      : mName(name), mThreadWake(wake) {
    mThread = new InputThreadImpl(loop);
    mThread->run(mName.c_str(), ANDROID_PRIORITY_URGENT_DISPLAY);  //启动线程,线程优先级很高
}
        
class InputThreadImpl : public Thread {
public:
    explicit InputThreadImpl(std::function<void()> loop)
          : Thread(/* canCallJava */ true), mThreadLoop(loop) {}

    ~InputThreadImpl() {}

private:
    std::function<void()> mThreadLoop;

    bool threadLoop() override {
        mThreadLoop();
        return true;
    }
};

创建一个线程,用于分发事件,线程执行体dispatchOnce()

void InputDispatcher::dispatchOnce() {
    nsecs_t nextWakeupTime = LONG_LONG_MAX;
    { // acquire lock
        std::scoped_lock _l(mLock);
        mDispatcherIsAlive.notify_all();

        // Run a dispatch loop if there are no pending commands.
        // The dispatch loop might enqueue commands to run afterwards.
        if (!haveCommandsLocked()) {
            dispatchOnceInnerLocked(&nextWakeupTime);  //处理事件的分发
        }

        // Run all pending commands if there are any.
        // If any commands were run then force the next poll to wake up immediately.
        if (runCommandsLockedInterruptable()) {  //处理命令队列中的命令
            nextWakeupTime = LONG_LONG_MIN;
        }

        // If we are still waiting for ack on some events,
        // we might have to wake up earlier to check if an app is anr'ing.
        const nsecs_t nextAnrCheck = processAnrsLocked();  //处理input ANR相关
        nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);

        // We are about to enter an infinitely long sleep, because we have no commands or
        // pending or queued events
        if (nextWakeupTime == LONG_LONG_MAX) {
            mDispatcherEnteredIdle.notify_all();  //线程进入idle状态
        }
    } // release lock

    // Wait for callback or timeout or wake.  (make sure we round up, not down)
    nsecs_t currentTime = now();
    int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
    mLooper->pollOnce(timeoutMillis);  //再次进入阻塞等待中
}

InputReader::start()

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
status_t InputReader::start() {

//创建线程InputReader,线程体函数loopOnce(), 线程唤醒函数mEventHub->wake()(调用EventHub的wake方法来唤醒)
mThread = std::make_unique<InputThread>(
"InputReader", [this]() { loopOnce(); }, [this]() { mEventHub->wake(); });
return OK;
}

void InputReader::loopOnce() {
int32_t oldGeneration;
int32_t timeoutMillis;
bool inputDevicesChanged = false;
std::vector<InputDeviceInfo> inputDevices;
...
//调用EventHub的getEvents获取输入事件
size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);

{ // acquire lock
std::scoped_lock _l(mLock);
mReaderIsAliveCondition.notify_all();

if (count) {
processEventsLocked(mEventBuffer, count);
}

if (mNextTimeout != LLONG_MAX) {
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
if (now >= mNextTimeout) {
if (DEBUG_RAW_EVENTS) {
ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
}
mNextTimeout = LLONG_MAX;
timeoutExpiredLocked(now);
}
}

if (oldGeneration != mGeneration) {
inputDevicesChanged = true;
inputDevices = getInputDevicesLocked();
}
} // release lock

// Send out a message that the describes the changed input devices.
//如果输入设备有变化,通知其他服务
if (inputDevicesChanged) {
mPolicy->notifyInputDevicesChanged(inputDevices);
}
mQueuedListener.flush();
}

线程在循环从mEventHub->getEvents获取输入事件(这个方法会引起阻塞),如果获取到事件,EventHub会唤醒此线程,返回后会刷新mQueuedListener的事件队列, 唤醒InputDispatcher线程来消费。
到这里inputflinger的启动就完成,开始正常等待输入事件的上报并处理。

####回顾

从前面的InputFlinger的启动可知,InputReader线程启动后会循环执行loopOnce()方法,然后阻塞在getEvents等待事件的上报,这里就从loopOnce获取到事件被唤醒后来分析InputReader对事件的处理。

InputReader::loopOnce()

frameworks/native/services/inputflinger/reader/InputReader.cpp

void InputReader::loopOnce() {
    int32_t oldGeneration;
    int32_t timeoutMillis;
    bool inputDevicesChanged = false;
    std::vector<InputDeviceInfo> inputDevices;
    
    ...
    //从EventHub中读取事件
    size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
        
    { // acquire lock
        ...
        if (count) {
            //处理事件
            processEventsLocked(mEventBuffer, count);
        }
        ...
        
    } // release lock

    // Send out a message that the describes the changed input devices.
    //如果输入设备状态改变则通过回调通知java层
    if (inputDevicesChanged) {
        mPolicy->notifyInputDevicesChanged(inputDevices);
    }

    // Flush queued events out to the listener.
    mQueuedListener.flush();
}

一、处理事件

InputReader::processEventsLocked

void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
    for (const RawEvent* rawEvent = rawEvents; count;) {
        int32_t type = rawEvent->type;
        size_t batchSize = 1;
        //除了设备添加、移除、结束扫描事件之外的普通事件采用批处理方式方式处理
        if (type < EventHubInterface::FIRST_SYNTHETIC_EVENT) {
            int32_t deviceId = rawEvent->deviceId;
            while (batchSize < count) {
                //如果出现不符合批处理的事件(一般上面的判断已经足够)则退出本次事件流程
                if (rawEvent[batchSize].type >= EventHubInterface::FIRST_SYNTHETIC_EVENT ||
                    rawEvent[batchSize].deviceId != deviceId) {
                    break;
                }
                batchSize += 1;
            }
            //处理普通事件(批量处理)
            processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
        } else {
            switch (rawEvent->type) {
                //如果是设备添加事件
                case EventHubInterface::DEVICE_ADDED:
                    //添加设备主要就是创建设备对应的inputDevice
                    //通过设备的class类型创建对应的mapper
                    //将对应的mapper和EventHub、inputReader关联(InputDeviceContext)
                    //然后将对应的deviceId、mapper、InputDeviceContext加入inputDevice容器中
                    addDeviceLocked(rawEvent->when, rawEvent->deviceId);
                    break;
                //如果是设备移除事件
                case EventHubInterface::DEVICE_REMOVED:
                    removeDeviceLocked(rawEvent->when, rawEvent->deviceId);
                    break;
                //如果是设备结束扫描事件
                case EventHubInterface::FINISHED_DEVICE_SCAN:
                    handleConfigurationChangedLocked(rawEvent->when);
                    break;
                default:
                    ALOG_ASSERT(false); // can't happen
                    break;
            }
        }
        count -= batchSize;
        rawEvent += batchSize;
    }
}

InputReader::processEventsForDeviceLocked

void InputReader::processEventsForDeviceLocked(int32_t eventHubId, const RawEvent* rawEvents,
                                               size_t count) {
    auto deviceIt = mDevices.find(eventHubId);  //通过device id找到事件对应的inputDevice对象
    ...
    device->process(rawEvents, count);  //调用事件对应的inputDevice对象process处理当前事件
}

InputDevice::process

frameworks/native/services/inputflinger/reader/InputDevice.cpp

void InputDevice::process(const RawEvent* rawEvents, size_t count) {
    //按顺序分发给对应的mapper处理,要求事件按照时间顺序处理
    for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) {

        if (mDropUntilNextSync) {  //抛弃下一个SYN事件前的所有事件
            ...
        } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) {
            ...
        } else {  //正常走这里
            //通过deviceId查询mDevices中对应的mapper(这个是在设备add事件时添加的)
            for_each_mapper_in_subdevice(rawEvent->deviceId, [rawEvent](InputMapper& mapper) {
                mapper.process(rawEvent);
            });
        }
        --count;
    }
}

for_each_mapper_in_subdevice

frameworks/native/services/inputflinger/reader/include/InputDevice.h

    // run a function against every mapper on a specific subdevice
    inline void for_each_mapper_in_subdevice(int32_t eventHubDevice,
                                             std::function<void(InputMapper&)> f) {
        auto deviceIt = mDevices.find(eventHubDevice);
        if (deviceIt != mDevices.end()) {
            auto& devicePair = deviceIt->second;
            auto& mappers = devicePair.second;
            for (auto& mapperPtr : mappers) {
                f(*mapperPtr);
            }
        }
    }

通过rawEvent->deviceId来查询这个事件对应的设备在设备add事件时添加的mapper,这个mapper是根据deviceclass类型来决定的

MultiTouchInputMapper::process

InputReader::addDeviceLocked中可以知道触摸现在走的是MultiTouchInputMapper
frameworks/native/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp

void MultiTouchInputMapper::process(const RawEvent* rawEvent) {
    TouchInputMapper::process(rawEvent);
    //处理常规触摸EV_ABS事件,包括多指情况(多个slot)
    mMultiTouchMotionAccumulator.process(rawEvent);
}

void TouchInputMapper::process(const RawEvent* rawEvent) {
    mCursorButtonAccumulator.process(rawEvent);  //如果是光标按键事件,一般不是
    mCursorScrollAccumulator.process(rawEvent);  //如果是光标滚动事件,一般不是
    mTouchButtonAccumulator.process(rawEvent);   //如果是触摸按键事件,(手写笔有时有)

    //只有当收到一次EV_SYN事件上上报本次触摸的事件集
    if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) {
        sync(rawEvent->when, rawEvent->readTime);
    }
}
    
void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
    if (rawEvent->type == EV_ABS) {
        bool newSlot = false;
        if (mUsingSlotsProtocol) {  //如果支持多指触摸协议
            if (rawEvent->code == ABS_MT_SLOT) {
                mCurrentSlot = rawEvent->value;
                newSlot = true;
            }
        } else if (mCurrentSlot < 0) {
            mCurrentSlot = 0;
        }

        if (mCurrentSlot < 0 || size_t(mCurrentSlot) >= mSlotCount) {
            ...
        } else {
            Slot* slot = &mSlots[mCurrentSlot];
            // If mUsingSlotsProtocol is true, it means the raw pointer has axis info of
            // ABS_MT_TRACKING_ID and ABS_MT_SLOT, so driver should send a valid trackingId while
            // updating the slot.
            //如果支持多指触摸协议,那么驱动就需要上报有效的trackingId来给上层区分
            if (!mUsingSlotsProtocol) {
                slot->mInUse = true;
            }
            //根据事件的code来更新slot的信息
            switch (rawEvent->code) {
                case ABS_MT_POSITION_X:
                    slot->mAbsMTPositionX = rawEvent->value;
                    warnIfNotInUse(*rawEvent, *slot);
                    break;
                case ABS_MT_POSITION_Y:
                    slot->mAbsMTPositionY = rawEvent->value;
                    warnIfNotInUse(*rawEvent, *slot);
                    break;
                case ABS_MT_TOUCH_MAJOR:
                    slot->mAbsMTTouchMajor = rawEvent->value;
                    break;
                case ABS_MT_TOUCH_MINOR:
                    slot->mAbsMTTouchMinor = rawEvent->value;
                    slot->mHaveAbsMTTouchMinor = true;
                    break;
                case ABS_MT_WIDTH_MAJOR:
                    slot->mAbsMTWidthMajor = rawEvent->value;
                    break;
                case ABS_MT_WIDTH_MINOR:
                    slot->mAbsMTWidthMinor = rawEvent->value;
                    slot->mHaveAbsMTWidthMinor = true;
                    break;
                case ABS_MT_ORIENTATION:
                    slot->mAbsMTOrientation = rawEvent->value;
                    break;
                case ABS_MT_TRACKING_ID:
                    if (mUsingSlotsProtocol && rawEvent->value < 0) {
                        // The slot is no longer in use but it retains its previous contents,
                        // which may be reused for subsequent touches.
                        slot->mInUse = false;
                    } else {
                        slot->mInUse = true;
                        slot->mAbsMTTrackingId = rawEvent->value;
                    }
                    break;
                case ABS_MT_PRESSURE:
                    slot->mAbsMTPressure = rawEvent->value;
                    break;
                case ABS_MT_DISTANCE:
                    slot->mAbsMTDistance = rawEvent->value;
                    break;
                case ABS_MT_TOOL_TYPE:
                    slot->mAbsMTToolType = rawEvent->value;
                    slot->mHaveAbsMTToolType = true;
                    break;
            }
        }
    } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) {
        // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
        mCurrentSlot += 1;
    }
}

TouchInputMapper::sync

void TouchInputMapper::sync(nsecs_t when, nsecs_t readTime) {
    //创建一个RawState并加入mRawStatesPending列表
    // Push a new state.
    mRawStatesPending.emplace_back();
    //初始化上面的RawState, 将相关的各个mapper.process()中记录的事件的属性写入(sync)
    RawState& next = mRawStatesPending.back();
    next.clear();
    next.when = when;
    next.readTime = readTime;
    ...
    // Sync touch
    //同步触摸的状态,这里是调用子类MultiTouchInputMapper的实现,将子类的process中赋值的多指触摸相关属性赋值给next
    syncTouch(when, &next);

    // The last RawState is the actually second to last, since we just added a new state
    const RawState& last =
            mRawStatesPending.size() == 1 ? mCurrentRawState : mRawStatesPending.rbegin()[1];

    ...

    processRawTouches(false /*timeout*/);
}

TouchInputMapper::processRawTouches

frameworks/native/services/inputflinger/reader/mapper/TouchInputMapper.cpp

void TouchInputMapper::processRawTouches(bool timeout) {
    //如果当前事件的设备被禁用,则中断这个触摸事件集的传递
    if (mDeviceMode == DeviceMode::DISABLED) {
        // Drop all input if the device is disabled.
        cancelTouch(mCurrentRawState.when, mCurrentRawState.readTime);
        mCurrentCookedState.clear();
        updateTouchSpots();
        return;
    }

    // Drain any pending touch states. The invariant here is that the mCurrentRawState is always
    // valid and must go through the full cook and dispatch cycle. This ensures that anything
    // touching the current state will only observe the events that have been dispatched to the
    // rest of the pipeline.
    const size_t N = mRawStatesPending.size();
    size_t count;
    for (count = 0; count < N; count++) {
        const RawState& next = mRawStatesPending[count];

        // A failure to assign the stylus id means that we're waiting on stylus data
        // and so should defer the rest of the pipeline.
        //检测手写笔id是否可以获取到,如果无法获取就中断本次触摸批事件处理
        if (assignExternalStylusId(next, timeout)) {
            break;
        }

        // All ready to go.
        clearStylusDataPendingFlags();  //移除手写笔状态相关变量
        mCurrentRawState.copyFrom(next);  //将next赋给mCurrentRawState
        ...
        cookAndDispatch(mCurrentRawState.when, mCurrentRawState.readTime);
    }
    if (count != 0) {
        //从mRawStatesPending移除本次已处理的RawState,一个RawState对应一次SYNC包含的触摸事件集
        mRawStatesPending.erase(mRawStatesPending.begin(), mRawStatesPending.begin() + count);
    }
    ...
}

TouchInputMapper::cookAndDispatch

void TouchInputMapper::cookAndDispatch(nsecs_t when, nsecs_t readTime) {
    // Always start with a clean state.
    mCurrentCookedState.clear();

    // Apply stylus buttons to current raw state.
    applyExternalStylusButtonState(when);  //处理手写笔按键状态

    // Handle policy on initial down or hover events.
    bool initialDown = mLastRawState.rawPointerData.pointerCount == 0 &&
            mCurrentRawState.rawPointerData.pointerCount != 0;

    uint32_t policyFlags = 0;
    bool buttonsPressed = mCurrentRawState.buttonState & ~mLastRawState.buttonState;
    if (initialDown || buttonsPressed) {
        // If this is a touch screen, hide the pointer on an initial down.
        if (mDeviceMode == DeviceMode::DIRECT) {
            getContext()->fadePointer();
        }

        if (mParameters.wake) {
            policyFlags |= POLICY_FLAG_WAKE;
        }
    }

    // Consume raw off-screen touches before cooking pointer data.
    // If touches are consumed, subsequent code will not receive any pointer data.
    //处理一些非屏幕区域的触摸行为,比如屏幕外的虚拟按键等,
    //如果本次触摸是虚拟按键,那么本次触摸事件将会被虚拟按键逻辑消费,不在往下处理
    if (consumeRawTouches(when, readTime, policyFlags)) {
        mCurrentRawState.rawPointerData.clear();
    }

    // Cook pointer data.  This call populates the mCurrentCookedState.cookedPointerData structure
    // with cooked pointer data that has the same ids and indices as the raw data.
    // The following code can use either the raw or cooked data, as needed.
    //这里就是将触摸设备(TP)的坐标范围映射到实际屏幕的坐标范围等(常识:TP的坐标不一定和屏幕的坐标对应,所以需要转化)
    cookPointerData();
    
    // Apply stylus pressure to current cooked state.
    applyExternalStylusTouchState(when);  处理手写笔触摸状态

    // Synthesize key down from raw buttons if needed.
    // 如果上面有处理触摸按键相关的事件,在这里会进行按键事件的分发,走按键分发逻辑(notifyKey)
    synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, readTime, getDeviceId(),
                         mSource, mViewport.displayId, policyFlags, mLastCookedState.buttonState,
                         mCurrentCookedState.buttonState);

    // Dispatch the touches either directly or by translation through a pointer on screen.
    if (mDeviceMode == DeviceMode::POINTER) {  //pointer光标
        ...
    } else {  //触摸 DeviceMode::DIRECT touchscreen
        if (!mCurrentMotionAborted) {
            updateTouchSpots();  //更新触摸点相关
            dispatchButtonRelease(when, readTime, policyFlags);  //一般触摸不涉及,不进行任何处理
            dispatchHoverExit(when, readTime, policyFlags);  //一般触摸不涉及,不进行任何处理
            dispatchTouches(when, readTime, policyFlags);  // 分发触摸事件,主要是这里
            dispatchHoverEnterAndMove(when, readTime, policyFlags);  //一般触摸不涉及,不进行任何处理
            dispatchButtonPress(when, readTime, policyFlags);  //一般触摸不涉及,不进行任何处理
        }

        if (mCurrentCookedState.cookedPointerData.pointerCount == 0) {
            mCurrentMotionAborted = false;
        }
    }

    // Synthesize key up from raw buttons if needed.
    synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, readTime, getDeviceId(), mSource,
                         mViewport.displayId, policyFlags, mLastCookedState.buttonState,
                         mCurrentCookedState.buttonState);
        
    // Clear some transient state.
    mCurrentRawState.rawVScroll = 0;
    mCurrentRawState.rawHScroll = 0;

    // Copy current touch to last touch in preparation for the next cycle.
    mLastRawState.copyFrom(mCurrentRawState);
    mLastCookedState.copyFrom(mCurrentCookedState);
}

TouchInputMapper::cookPointerData

void TouchInputMapper::cookPointerData() {
    uint32_t currentPointerCount = mCurrentRawState.rawPointerData.pointerCount;
    
    mCurrentCookedState.cookedPointerData.clear();
    mCurrentCookedState.cookedPointerData.pointerCount = currentPointerCount;
    mCurrentCookedState.cookedPointerData.hoveringIdBits =
            mCurrentRawState.rawPointerData.hoveringIdBits;
    mCurrentCookedState.cookedPointerData.touchingIdBits =
            mCurrentRawState.rawPointerData.touchingIdBits;
    mCurrentCookedState.cookedPointerData.canceledIdBits =
            mCurrentRawState.rawPointerData.canceledIdBits;

    if (mCurrentCookedState.cookedPointerData.pointerCount == 0) {
        mCurrentCookedState.buttonState = 0;
    } else {
        mCurrentCookedState.buttonState = mCurrentRawState.buttonState;
    }


    // Walk through the the active pointers and map device coordinates onto
    // display coordinates and adjust for display orientation.
    // 遍历活动指针并将设备坐标映射到显示坐标并调整显示方向。
    // 并将相关的转化值写入mCurrentCookedState.cookedPointerData
    for (uint32_t i = 0; i < currentPointerCount; i++) {
        const RawPointerData::Pointer& in = mCurrentRawState.rawPointerData.pointers[i];

        // Size
        // 长短轴大小校准
        float touchMajor, touchMinor, toolMajor, toolMinor, size;
        switch (mCalibration.sizeCalibration) {
            case Calibration::SizeCalibration::GEOMETRIC:  //几何类型
            case Calibration::SizeCalibration::DIAMETER:  //直径类型
            case Calibration::SizeCalibration::BOX:  // 方型?
            case Calibration::SizeCalibration::AREA:  //面积类型?
                if (mRawPointerAxes.touchMajor.valid && mRawPointerAxes.toolMajor.valid) {
                    touchMajor = in.touchMajor;
                    touchMinor = mRawPointerAxes.touchMinor.valid ? in.touchMinor : in.touchMajor;
                    toolMajor = in.toolMajor;
                    toolMinor = mRawPointerAxes.toolMinor.valid ? in.toolMinor : in.toolMajor;
                    size = mRawPointerAxes.touchMinor.valid ? avg(in.touchMajor, in.touchMinor)
                                                            : in.touchMajor;
                } else if (mRawPointerAxes.touchMajor.valid) {
                    toolMajor = touchMajor = in.touchMajor;
                    toolMinor = touchMinor =
                            mRawPointerAxes.touchMinor.valid ? in.touchMinor : in.touchMajor;
                    size = mRawPointerAxes.touchMinor.valid ? avg(in.touchMajor, in.touchMinor)
                                                            : in.touchMajor;
                } else if (mRawPointerAxes.toolMajor.valid) {
                    touchMajor = toolMajor = in.toolMajor;
                    touchMinor = toolMinor =
                            mRawPointerAxes.toolMinor.valid ? in.toolMinor : in.toolMajor;
                    size = mRawPointerAxes.toolMinor.valid ? avg(in.toolMajor, in.toolMinor)
                                                           : in.toolMajor;
                } else {
                    ...
                }

                if (mCalibration.haveSizeIsSummed && mCalibration.sizeIsSummed) {
                    uint32_t touchingCount = mCurrentRawState.rawPointerData.touchingIdBits.count();
                    if (touchingCount > 1) {
                        touchMajor /= touchingCount;
                        touchMinor /= touchingCount;
                        toolMajor /= touchingCount;
                        toolMinor /= touchingCount;
                        size /= touchingCount;
                    }
                }

                if (mCalibration.sizeCalibration == Calibration::SizeCalibration::GEOMETRIC) {
                    touchMajor *= mGeometricScale;
                    touchMinor *= mGeometricScale;
                    toolMajor *= mGeometricScale;
                    toolMinor *= mGeometricScale;
                } else if (mCalibration.sizeCalibration == Calibration::SizeCalibration::AREA) {
                    touchMajor = touchMajor > 0 ? sqrtf(touchMajor) : 0;
                    touchMinor = touchMajor;
                    toolMajor = toolMajor > 0 ? sqrtf(toolMajor) : 0;
                    toolMinor = toolMajor;
                } else if (mCalibration.sizeCalibration == Calibration::SizeCalibration::DIAMETER) {
                    touchMinor = touchMajor;
                    toolMinor = toolMajor;
                }

                mCalibration.applySizeScaleAndBias(&touchMajor);
                mCalibration.applySizeScaleAndBias(&touchMinor);
                mCalibration.applySizeScaleAndBias(&toolMajor);
                mCalibration.applySizeScaleAndBias(&toolMinor);
                size *= mSizeScale;
                break;
            default:
                touchMajor = 0;
                touchMinor = 0;
                toolMajor = 0;
                toolMinor = 0;
                size = 0;
                break;
        }

        // Pressure
        //压感校准
        float pressure;
        switch (mCalibration.pressureCalibration) {
            case Calibration::PressureCalibration::PHYSICAL:
            case Calibration::PressureCalibration::AMPLITUDE:
                pressure = in.pressure * mPressureScale;
                break;
            default:
                pressure = in.isHovering ? 0 : 1;
                break;
        }

        // Tilt and Orientation
        //倾斜角度和方向
        float tilt;
        float orientation;
        if (mHaveTilt) {
            float tiltXAngle = (in.tiltX - mTiltXCenter) * mTiltXScale;
            float tiltYAngle = (in.tiltY - mTiltYCenter) * mTiltYScale;
            orientation = atan2f(-sinf(tiltXAngle), sinf(tiltYAngle));
            tilt = acosf(cosf(tiltXAngle) * cosf(tiltYAngle));
        } else {
            tilt = 0;

            switch (mCalibration.orientationCalibration) {
                case Calibration::OrientationCalibration::INTERPOLATED:
                    orientation = in.orientation * mOrientationScale;
                    break;
                case Calibration::OrientationCalibration::VECTOR: {
                    int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4);
                    int32_t c2 = signExtendNybble(in.orientation & 0x0f);
                    if (c1 != 0 || c2 != 0) {
                        orientation = atan2f(c1, c2) * 0.5f;
                        float confidence = hypotf(c1, c2);
                        float scale = 1.0f + confidence / 16.0f;
                        touchMajor *= scale;
                        touchMinor /= scale;
                        toolMajor *= scale;
                        toolMinor /= scale;
                    } else {
                        orientation = 0;
                    }
                    break;
                }
                default:
                    orientation = 0;
            }
        }

        // Distance
        //距离校准
        float distance;
        switch (mCalibration.distanceCalibration) {
            case Calibration::DistanceCalibration::SCALED:
                distance = in.distance * mDistanceScale;
                break;
            default:
                distance = 0;
        }

        // Coverage
        // 覆盖校准?
        int32_t rawLeft, rawTop, rawRight, rawBottom;
        switch (mCalibration.coverageCalibration) {
            case Calibration::CoverageCalibration::BOX:
                rawLeft = (in.toolMinor & 0xffff0000) >> 16;
                rawRight = in.toolMinor & 0x0000ffff;
                rawBottom = in.toolMajor & 0x0000ffff;
                rawTop = (in.toolMajor & 0xffff0000) >> 16;
                break;
            default:
                rawLeft = rawTop = rawRight = rawBottom = 0;
                break;
        }

        // Adjust X,Y coords for device calibration
        // TODO: Adjust coverage coords?
        float xTransformed = in.x, yTransformed = in.y;
        mAffineTransform.applyTo(xTransformed, yTransformed);
        rotateAndScale(xTransformed, yTransformed);

        // Adjust X, Y, and coverage coords for input device orientation.
        float left, top, right, bottom;
        // 转换触摸设备坐标到实际的屏幕方向上的坐标
        switch (mInputDeviceOrientation) {
            case DISPLAY_ORIENTATION_90:
                left = float(rawTop - mRawPointerAxes.y.minValue) * mYScale;
                right = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale;
                bottom = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale;
                top = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale;
                orientation -= M_PI_2;
                if (mOrientedRanges.haveOrientation &&
                    orientation < mOrientedRanges.orientation.min) {
                    orientation +=
                            (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
                }
                break;
            case DISPLAY_ORIENTATION_180:
                left = float(mRawPointerAxes.x.maxValue - rawRight) * mXScale;
                right = float(mRawPointerAxes.x.maxValue - rawLeft) * mXScale;
                bottom = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale;
                top = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale;
                orientation -= M_PI;
                if (mOrientedRanges.haveOrientation &&
                    orientation < mOrientedRanges.orientation.min) {
                    orientation +=
                            (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
                }
                break;
            case DISPLAY_ORIENTATION_270:
                left = float(mRawPointerAxes.y.maxValue - rawBottom) * mYScale;
                right = float(mRawPointerAxes.y.maxValue - rawTop) * mYScale;
                bottom = float(rawRight - mRawPointerAxes.x.minValue) * mXScale;
                top = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale;
                orientation += M_PI_2;
                if (mOrientedRanges.haveOrientation &&
                    orientation > mOrientedRanges.orientation.max) {
                    orientation -=
                            (mOrientedRanges.orientation.max - mOrientedRanges.orientation.min);
                }
                break;
            default:
                left = float(rawLeft - mRawPointerAxes.x.minValue) * mXScale;
                right = float(rawRight - mRawPointerAxes.x.minValue) * mXScale;
                bottom = float(rawBottom - mRawPointerAxes.y.minValue) * mYScale;
                top = float(rawTop - mRawPointerAxes.y.minValue) * mYScale;
                break;
        }

        // Write output coords.
        PointerCoords& out = mCurrentCookedState.cookedPointerData.pointerCoords[i];
        out.clear();
        out.setAxisValue(AMOTION_EVENT_AXIS_X, xTransformed);
        out.setAxisValue(AMOTION_EVENT_AXIS_Y, yTransformed);
        out.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, pressure);
        out.setAxisValue(AMOTION_EVENT_AXIS_SIZE, size);
        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR, touchMajor);
        out.setAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR, touchMinor);
        out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
        out.setAxisValue(AMOTION_EVENT_AXIS_TILT, tilt);
        out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
        if (mCalibration.coverageCalibration == Calibration::CoverageCalibration::BOX) {
            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_1, left);
            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_2, top);
            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_3, right);
            out.setAxisValue(AMOTION_EVENT_AXIS_GENERIC_4, bottom);
        } else {
            out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);
            out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);
        }

        // Write output relative fields if applicable.
        uint32_t id = in.id;
        if (mSource == AINPUT_SOURCE_TOUCHPAD &&
            mLastCookedState.cookedPointerData.hasPointerCoordsForId(id)) {
            const PointerCoords& p = mLastCookedState.cookedPointerData.pointerCoordsForId(id);
            float dx = xTransformed - p.getAxisValue(AMOTION_EVENT_AXIS_X);
            float dy = yTransformed - p.getAxisValue(AMOTION_EVENT_AXIS_Y);
            out.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_X, dx);
            out.setAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y, dy);
        }

        // Write output properties.
        PointerProperties& properties = mCurrentCookedState.cookedPointerData.pointerProperties[i];
        properties.clear();
        properties.id = id;
        properties.toolType = in.toolType;

        // Write id index and mark id as valid.
        mCurrentCookedState.cookedPointerData.idToIndex[id] = i;
        mCurrentCookedState.cookedPointerData.validIdBits.markBit(id);
    }
}

TouchInputMapper::dispatchTouches

void TouchInputMapper::dispatchTouches(nsecs_t when, nsecs_t readTime, uint32_t policyFlags) {
    BitSet32 currentIdBits = mCurrentCookedState.cookedPointerData.touchingIdBits;
    BitSet32 lastIdBits = mLastCookedState.cookedPointerData.touchingIdBits;
    int32_t metaState = getContext()->getGlobalMetaState();
    int32_t buttonState = mCurrentCookedState.buttonState;
        
    if (currentIdBits == lastIdBits) {  //pointer id 没有改变
        if (!currentIdBits.isEmpty()) {
            // No pointer id changes so this is a move event.
            // The listener takes care of batching moves so we don't have to deal with that here.
            // 如果pointer id 没有改变,说明是个move事件,这里不进行处理,直接分发到listener
            dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_MOVE, 0, 0,
                           metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
                           mCurrentCookedState.cookedPointerData.pointerProperties,
                           mCurrentCookedState.cookedPointerData.pointerCoords,
                           mCurrentCookedState.cookedPointerData.idToIndex, currentIdBits, -1,
                           mOrientedXPrecision, mOrientedYPrecision, mDownTime);
        }
    } else {
        // There may be pointers going up and pointers going down and pointers moving
        // all at the same time.
        // 获取并更新四个方向pointers的值,判断本次是down、up、move的哪一种
        BitSet32 upIdBits(lastIdBits.value & ~currentIdBits.value);
        BitSet32 downIdBits(currentIdBits.value & ~lastIdBits.value);
        BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value);
        BitSet32 dispatchedIdBits(lastIdBits.value);  //用于记录上一次分发的事件

        // Update last coordinates of pointers that have moved so that we observe the new
        // pointer positions at the same time as other pointers that have just gone up.
        //更新最后一个pointers的坐标
        bool moveNeeded =
                updateMovedPointers(mCurrentCookedState.cookedPointerData.pointerProperties,
                                    mCurrentCookedState.cookedPointerData.pointerCoords,
                                    mCurrentCookedState.cookedPointerData.idToIndex,
                                    mLastCookedState.cookedPointerData.pointerProperties,
                                    mLastCookedState.cookedPointerData.pointerCoords,
                                    mLastCookedState.cookedPointerData.idToIndex, moveIdBits);
        if (buttonState != mLastCookedState.buttonState) {
            moveNeeded = true;
        }

        // Dispatch pointer up events.
        //分发up事件
        while (!upIdBits.isEmpty()) {
            uint32_t upId = upIdBits.clearFirstMarkedBit();  //这个id应该和downId相同(看上面的更新四个方向BitSet32可知)
            bool isCanceled = mCurrentCookedState.cookedPointerData.canceledIdBits.hasBit(uplastIdBitsId);
            if (isCanceled) {
                ALOGI("Canceling pointer %d for the palm event was detected.", upId);
            }
            dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_POINTER_UP, 0,
                           isCanceled ? AMOTION_EVENT_FLAG_CANCELED : 0, metaState, buttonState, 0,
                           mLastCookedState.cookedPointerData.pointerProperties,
                           mLastCookedState.cookedPointerData.pointerCoords,
                           mLastCookedState.cookedPointerData.idToIndex, dispatchedIdBits, upId,
                           mOrientedXPrecision, mOrientedYPrecision, mDownTime);
            dispatchedIdBits.clearBit(upId);  //up事件分发后,重置dispatchedIdBits
            mCurrentCookedState.cookedPointerData.canceledIdBits.clearBit(upId);
        }

        // Dispatch move events if any of the remaining pointers moved from their old locations.
        // Although applications receive new locations as part of individual pointer up
        // events, they do not generally handle them except when presented in a move event.
        //分发move事件
        if (moveNeeded && !moveIdBits.isEmpty()) {
            ALOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
            dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_MOVE, 0, 0,
                           metaState, buttonState, 0,
                           mCurrentCookedState.cookedPointerData.pointerProperties,
                           mCurrentCookedState.cookedPointerData.pointerCoords,
                           mCurrentCookedState.cookedPointerData.idToIndex, dispatchedIdBits, -1,
                           mOrientedXPrecision, mOrientedYPrecision, mDownTime);
        }

        // Dispatch pointer down events using the new pointer locations.
        //分发down事件
        while (!downIdBits.isEmpty()) {
            uint32_t downId = downIdBits.clearFirstMarkedBit();
            dispatchedIdBits.markBit(downId); //记录分发的down事件

            if (dispatchedIdBits.count() == 1) {
                // First pointer is going down.  Set down time.
                mDownTime = when;
            }

            dispatchMotion(when, readTime, policyFlags, mSource, AMOTION_EVENT_ACTION_POINTER_DOWN,
                           0, 0, metaState, buttonState, 0,
                           mCurrentCookedState.cookedPointerData.pointerProperties,
                           mCurrentCookedState.cookedPointerData.pointerCoords,
                           mCurrentCookedState.cookedPointerData.idToIndex, dispatchedIdBits,
                           downId, mOrientedXPrecision, mOrientedYPrecision, mDownTime);
        }
    }
}

TouchInputMapper::dispatchMotion

void TouchInputMapper::dispatchMotion(nsecs_t when, nsecs_t readTime, uint32_t policyFlags,
                                      uint32_t source, int32_t action, int32_t actionButton,
                                      int32_t flags, int32_t metaState, int32_t buttonState,
                                      int32_t edgeFlags, const PointerProperties* properties,
                                      const PointerCoords* coords, const uint32_t* idToIndex,
                                      BitSet32 idBits, int32_t changedId, float xPrecision,
                                      float yPrecision, nsecs_t downTime) {
    PointerCoords pointerCoords[MAX_POINTERS];
    PointerProperties pointerProperties[MAX_POINTERS];
    uint32_t pointerCount = 0;
    while (!idBits.isEmpty()) {
        uint32_t id = idBits.clearFirstMarkedBit();
        uint32_t index = idToIndex[id];
        pointerProperties[pointerCount].copyFrom(properties[index]);
        pointerCoords[pointerCount].copyFrom(coords[index]);

        if (changedId >= 0 && id == uint32_t(changedId)) {
            action |= pointerCount << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
        }

        pointerCount += 1;
    }

    ALOG_ASSERT(pointerCount != 0);

    if (changedId >= 0 && pointerCount == 1) {
        // Replace initial down and final up action.
        // We can compare the action without masking off the changed pointer index
        // because we know the index is 0.
        if (action == AMOTION_EVENT_ACTION_POINTER_DOWN) {
            action = AMOTION_EVENT_ACTION_DOWN;
        } else if (action == AMOTION_EVENT_ACTION_POINTER_UP) {
            if ((flags & AMOTION_EVENT_FLAG_CANCELED) != 0) {
                action = AMOTION_EVENT_ACTION_CANCEL;
            } else {
                action = AMOTION_EVENT_ACTION_UP;
            }
        } else {
            // Can't happen.
            ALOG_ASSERT(false);
        }
    }
    float xCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
    float yCursorPosition = AMOTION_EVENT_INVALID_CURSOR_POSITION;
    if (mDeviceMode == DeviceMode::POINTER) {  //是否是pointer模式,触摸是DIRECT模式,所以一般不设置这个
        mPointerController->getPosition(&xCursorPosition, &yCursorPosition);
    }
    //获取当前物理屏幕的id(有些设备有多个屏幕)
    //获取displayId主要从DisplayViewport中,而DisplayViewport主要来自:
    // 1. inputDevice中通过configure中指定。
      // 2. WindowManagerService指定。
      // 3.通过idc文件中的唯一id或显示类型获取匹配的Viewport
    const int32_t displayId = getAssociatedDisplayId().value_or(ADISPLAY_ID_NONE);
    const int32_t deviceId = getDeviceId();
    std::vector<TouchVideoFrame> frames = getDeviceContext().getVideoFrames();  //有关视频触摸事件的,一般不是
    std::for_each(frames.begin(), frames.end(),
                  [this](TouchVideoFrame& frame) { frame.rotate(this->mInputDeviceOrientation); });
    //创建NotifyMotionArgs对象
    NotifyMotionArgs args(getContext()->getNextId(), when, readTime, deviceId, source, displayId,
                          policyFlags, action, actionButton, flags, metaState, buttonState,
                          MotionClassification::NONE, edgeFlags, pointerCount, pointerProperties,
                          pointerCoords, xPrecision, yPrecision, xCursorPosition, yCursorPosition,
                          downTime, std::move(frames));
     // 调用mapper创建时关联的context持有的QueuedInputListener对象的notifyMotion
     // 这里是getListener是UnwantedInteractionBlocker
    getListener().notifyMotion(&args);
}

QueuedInputListener::notifyMotion

void QueuedInputListener::notifyMotion(const NotifyMotionArgs* args) {
    ALOGD("hongxi.zhu: QueuedInputListener::notifyMotion() -> mArgsQueue.emplace_back(NotifyMotionArgs)");
    traceEvent(__func__, args->id);
    mArgsQueue.emplace_back(std::make_unique<NotifyMotionArgs>(*args));
}

QueuedInputListener::notifyMotion只是将NotifyMotionArgs加入当前listener对象的mArgsQueue列表, 到这里我们InputReader::processEventsLocked方法就执行结束,回到loopOnce()中继续往下执行到mQueuedListener.flush(),开始事件的传递。

二、mQueuedListener.flush()事件传递

接着上面,在InputReader::loopOnce()中往下执行到mQueuedListener.flush()

QueuedInputListener::flush()

frameworks/native/services/inputflinger/InputListener.cpp

void QueuedInputListener::flush() {
    for (const std::unique_ptr<NotifyArgs>& args : mArgsQueue) {
        args->notify(mInnerListener);  //args这里是前面传进来的NotifyMotionArgs
    }
    mArgsQueue.clear();
}

NotifyMotionArgs::notify

frameworks/native/services/inputflinger/InputListener.cpp

void NotifyMotionArgs::notify(InputListenerInterface& listener) const {
    listener.notifyMotion(this);
}

这个listener是一个InputListenerInterface子类对象,到底是哪个呢?回顾下InputManager的构造方法,
frameworks/native/services/inputflinger/InputManager.cpp

InputManager::InputManager(
        const sp<InputReaderPolicyInterface>& readerPolicy,
        const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
    mDispatcher = createInputDispatcher(dispatcherPolicy);
    mClassifier = std::make_unique<InputClassifier>(*mDispatcher);
    mBlocker = std::make_unique<UnwantedInteractionBlocker>(*mClassifier);
    mReader = createInputReader(readerPolicy, *mBlocker);
}

mDispatchermClassifiermBlocker都是InputListenerInterface的子类,从构造方法的传参得出事件传递的过程:
InputReader->UnwantedInteractionBlocker->InputClassifier->InputDispatcher
结合类继承关系,可知上面InputReader::loopOnce()中的mQueuedListenerUnwantedInteractionBlocker,调用它的flush方法(这几个子类都没有实现flush方法,所以执行的是QueuedInputListenerflush方法),QueuedInputListener中的mInnerListenerUnwantedInteractionBlocker,那么listener.notifyMotion(this)实际就是:UnwantedInteractionBlocker::notifyMotion(NotifyMotionArgs)

UnwantedInteractionBlocker::notifyMotion

frameworks/native/services/inputflinger/UnwantedInteractionBlocker.cpp

void UnwantedInteractionBlocker::notifyMotion(const NotifyMotionArgs* args) {
    { // acquire lock
        std::scoped_lock lock(mLock);
        const std::vector<NotifyMotionArgs> processedArgs =
                mPreferStylusOverTouchBlocker.processMotion(*args);
        for (const NotifyMotionArgs& loopArgs : processedArgs) {
            notifyMotionLocked(&loopArgs);
        }
    } // release lock

    // Call out to the next stage without holding the lock
    mQueuedListener.flush();
}

UnwantedInteractionBlocker::notifyMotionLocked

void UnwantedInteractionBlocker::notifyMotionLocked(const NotifyMotionArgs* args) {
    auto it = mPalmRejectors.find(args->deviceId);
    const bool sendToPalmRejector = it != mPalmRejectors.end() && isFromTouchscreen(args->source);
    if (!sendToPalmRejector) {  //如果不支持手掌误触处理,走这里,一般走这里
        //调用UnwantedInteractionBlocker中持有的QueuedListener对象的notifyMotion
        //mQueuedListener这里是
        mQueuedListener.notifyMotion(args);  //一般走这里, 按照前面
        return;
    }
    //如果支持手掌误触
    std::vector<NotifyMotionArgs> processedArgs = it->second.processMotion(*args);
processedArgs.size());
    for (const NotifyMotionArgs& loopArgs : processedArgs) {
        mQueuedListener.notifyMotion(&loopArgs);  //同理这里的mQueuedListener是InputClassifier
    }
}

然后又是同样的走法notifyMotion->flush->notifyMotion, mInnerListenerInputClassifier

QueuedInputListener::notifyMotion

void QueuedInputListener::notifyMotion(const NotifyMotionArgs* args) {
    traceEvent(__func__, args->id);
    mArgsQueue.emplace_back(std::make_unique<NotifyMotionArgs>(*args));
}

void QueuedInputListener::flush() {
    for (const std::unique_ptr<NotifyArgs>& args : mArgsQueue) {
           //args这里是前面传进来的NotifyMotionArgs,mInnerListener是InputClassifier
        args->notify(mInnerListener);
    }
    mArgsQueue.clear();
}

void NotifyMotionArgs::notify(InputListenerInterface& listener) const {
    listener.notifyMotion(this);
}

InputClassifier::notifyMotion

void InputClassifier::notifyMotion(const NotifyMotionArgs* args) {
    { // acquire lock
        std::scoped_lock lock(mLock);
        // MotionClassifier is only used for touch events, for now
        const bool sendToMotionClassifier = mMotionClassifier && isTouchEvent(*args);
        if (!sendToMotionClassifier) {  //目前模拟器走这里,真机不清楚
            mQueuedListener.notifyMotion(args);
        } else {
            NotifyMotionArgs newArgs(*args);
            newArgs.classification = mMotionClassifier->classify(newArgs);
            mQueuedListener.notifyMotion(&newArgs);
        }
    } // release lock
    mQueuedListener.flush();
}

然后又是同样的走法notifyMotion->flush->notifyMotion, mInnerListenerInputDispatcher

QueuedInputListener::notifyMotion

void QueuedInputListener::notifyMotion(const NotifyMotionArgs* args) {
    traceEvent(__func__, args->id);
    mArgsQueue.emplace_back(std::make_unique<NotifyMotionArgs>(*args));
}

void QueuedInputListener::flush() {
    for (const std::unique_ptr<NotifyArgs>& args : mArgsQueue) {
           //args这里是前面传进来的NotifyMotionArgs,mInnerListener是InputClassifier
        args->notify(mInnerListener);
    }
    mArgsQueue.clear();
}

InputDispatcher::notifyMotion

void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
    ...
    uint32_t policyFlags = args->policyFlags;
    policyFlags |= POLICY_FLAG_TRUSTED;

    android::base::Timer t;
    //回调wms中的interceptMotionBeforeQueueingNonInteractive方法
    mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
        
    bool needWake = false;
    { // acquire lock
        mLock.lock();
        ...

        // Just enqueue a new motion event.
        //创建一个MotionEntry对象,将NotifyMotionArgs转化为MotionEntry
        std::unique_ptr<MotionEntry> newEntry =
                std::make_unique<MotionEntry>(args->id, args->eventTime, args->deviceId,
                                              args->source, args->displayId, policyFlags,
                                              args->action, args->actionButton, args->flags,
                                              args->metaState, args->buttonState,
                                              args->classification, args->edgeFlags,
                                              args->xPrecision, args->yPrecision,
                                              args->xCursorPosition, args->yCursorPosition,
                                              args->downTime, args->pointerCount,
                                              args->pointerProperties, args->pointerCoords);
        ...
        //将MotionEntry加入InboundQueue
        needWake = enqueueInboundEventLocked(std::move(newEntry)); 
        mLock.unlock();
    } // release lock

    if (needWake) {
        mLooper->wake();  //唤醒InputDispatcher线程,处理InboundQueue中的MotionEntry
    }
}

InputDispatcher::enqueueInboundEventLocked

bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newEntry) {
    bool needWake = mInboundQueue.empty();
    mInboundQueue.push_back(std::move(newEntry));
    EventEntry& entry = *(mInboundQueue.back());
    traceInboundQueueLengthLocked();

    switch (entry.type) {
        case EventEntry::Type::KEY: {
              ...
            break;
        }

        case EventEntry::Type::MOTION: {
            LOG_ALWAYS_FATAL_IF((entry.policyFlags & POLICY_FLAG_TRUSTED) == 0,
                                "Unexpected untrusted event.");
            if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(entry))) {
                mNextUnblockedEvent = mInboundQueue.back();
                needWake = true;
            }
            break;
            ...
    }

    return needWake;
}

到此,InputReader线程就将事件传递到InputDispatcher线程,InputDispatcher线程被唤醒开始处理触摸事件,而InputReader线程继续循环执行loopOnce()方法,再次阻塞在getEvents方法中等待事件的上报。