当前位置: 代码迷 >> Android >> Android4.2.2 SurfaceFlinger启动流程详解(1)
  详细解决方案

Android4.2.2 SurfaceFlinger启动流程详解(1)

热度:31   发布时间:2016-04-28 06:27:32.0
Android4.2.2 SurfaceFlinger启动流程详解(一)

本文均属自己阅读源码的点滴总结,转账请注明出处谢谢。

欢迎和大家交流。qq:1037701636 email:[email protected]

 

Android源码版本Version:4.2.2; 硬件平台 全志A31

 

这周继续我的Blog,前面几篇博文简单的介绍了阅读Android FW的源码所需要的基础知识,主要和C++相关。从这篇博文开始将会和大家一起学习并总结SurfaceFlinger模块在Android中的相关内容,本文主要描述的是SurfaceFlinger的详细启动流程。

 

1.SurfaceFlinger在哪里启动?

在android系统中一个核心的Service都有ServiceManager管理,核心Service启动一般是在SystemServer来启动,但是比较重要的Service会在Zygote启动前,由init进程来负责直接启动。故SurfaceFlinger作为一个核心Service,一般有下面2种启动方式。

a.在systemserver中如何启动。

源码目录/android/frameworks/base/cmds/system_server/library/system_init.cpp.

extern "C" status_t system_init(){    ALOGI("Entered system_init()");    sp<ProcessState> proc(ProcessState::self());    sp<IServiceManager> sm = defaultServiceManager();    ALOGI("ServiceManager: %p\n", sm.get());    sp<GrimReaper> grim = new GrimReaper();    sm->asBinder()->linkToDeath(grim, grim.get(), 0);    char propBuf[PROPERTY_VALUE_MAX];    property_get("system_init.startsurfaceflinger", propBuf, "1");    if (strcmp(propBuf, "1") == 0) {        // Start the SurfaceFlinger        SurfaceFlinger::instantiate();    }    property_get("system_init.startsensorservice", propBuf, "1");    if (strcmp(propBuf, "1") == 0) {        // Start the sensor service        SensorService::instantiate();    }......}

在这里可以看到在systemserver的启动过程中,property_get通过获取system_init.startsurfaceflinger的属性值,这个属性值一般在init.rc中进配置,如果该数值为0,则赋值propBuf=1,故以此会使用system_init中来启动SF。

 

b.相对比上面的启动,另一种启动就是直接像ServiceManager一样,作为init进程中的一个Service来启动。

在init.rc中添加如下配置代码:

# Set this property so surfaceflinger is not started by system_init
setprop system_init.startsurfaceflinger 0

启动SurfaceFlinger的过程:

469 service surfaceflinger /system/bin/surfaceflinger470     class main471     user system472     group graphics drmrpc473     onrestart restart zygote474 

对于Service如何启动,可以查看Blog:android系统启动流程启动画面学习之init和init.rc分析的相关内容即可理解。

 

2.以第二种方式启动来进一步分析SF,看看SurfaceFlinger的main函数源码。

路径:android/frameworks/native/cmds/surfaceflinger/main_surfaceflinger.cpp

int main(int argc, char** argv) {    SurfaceFlinger::publishAndJoinThreadPool(true);    // When SF is launched in its own process, limit the number of    // binder threads to 4.    ProcessState::self()->setThreadPoolMaxThreadCount(4);    return 0;}

要开始结束SurfaceFlinger的函数处理过程时,有必要先进SF的基本UML图提出来,如下所示:

 

 

step1: 调用publishAndJoinThreadPool函数:

该函数是C++里一个带默认参数的函数的,这里传入的参数的true。
 

    static void publishAndJoinThreadPool(bool allowIsolated = false) {        sp<IServiceManager> sm(defaultServiceManager());        sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);        ProcessState::self()->startThreadPool();        IPCThreadState::self()->joinThreadPool();    }

这里会涉及到和ServerManger的交互,变量sm是SM在当前进程的一个代理proxy,用于Binder驱动的交互,而addService正是将SurfaceFlinger做为一个核心的系统服务注册到SM当中。随后就是当前进程由ProcessState通过依次调用会新run起来一个thread如下所示,Poolthread继承与Thread类,故一旦run起来就运行thread的run函数故而依旧前面介绍的thread类是依次会执行PoolThread类的readyToRun和threadLoop;

void ProcessState::spawnPooledThread(bool isMain){    if (mThreadPoolStarted) {        int32_t s = android_atomic_add(1, &mThreadPoolSeq);        char buf[16];        snprintf(buf, sizeof(buf), "Binder_%X", s);        ALOGV("Spawning new pooled thread, name=%s\n", buf);        sp<Thread> t = new PoolThread(isMain);        t->run(buf);    }}

在对应的threadLoop里面可以找到IPCThreadState::self()->joinThreadPool(mIsMain);即新建一个IPCThreadState进程间通信的线程状态类,该类的函数joinThreadPool
即是与Binder驱动交互的接口,核心是和内核Binder驱动进行talkWithDriver()以及executeCommand(), 因为当前的SurfaceFlinger已经进入了正常的运行状态。

当然在本主线程也会 调用IPCThreadState::self()->joinThreadPool();进行Binder间的通信,确保通信的稳定性。

 

step2: 回归SurfaceFlinger对象的创建
作为继承了public BinderService<SurfaceFlinger>模板类的SF,他的创建就在上文提到的publishAndJoinThreadPool函数中的

       sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);

new SERVICE() = new SurfaceFlinger().从这里该进入SF的创建和相关初始化了

SF类的定义和初始化成员函数的文件目录:

源文件/android/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp;头文件/android/frameworks/native/services/surfaceflinger/SurfaceFlinger.h;

如下是SF的狗构造函数,首先对基类BnSurfaceComposer、Thread进行初始化

SurfaceFlinger::SurfaceFlinger()    :   BnSurfaceComposer(), Thread(false),        mTransactionFlags(0),        mTransactionPending(false),        mAnimTransactionPending(false),        mLayersRemoved(false),        mRepaintEverything(0),        mBootTime(systemTime()),        mVisibleRegionsDirty(false),        mHwWorkListDirty(false),        mDebugRegion(0),        mDebugDDMS(0),        mDebugDisableHWC(0),        mDebugDisableTransformHint(0),        mDebugInSwapBuffers(0),        mLastSwapBufferTime(0),        mDebugInTransaction(0),        mLastTransactionTime(0),        mBootFinished(false)

这里乘热打铁来看thread类,很容易知道必然有地方会run起thread类所属的线程,好吧接下去揭开谜底所在,来看这个:

void SurfaceFlinger::onFirstRef(){    mEventQueue.init(this);    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);//启动一个新的thread线程,调用thread类的run函数    // Wait for the main thread to be done with its initialization    mReadyToRunBarrier.wait();//等待线程完成相关的初始化}

OK这个onFirstRef似乎特别熟悉,的确在Android FrameWork中的SP、RefBase、weakref_impl,Thread类里面详细说明了他的由来,其实也就是和RefBase的关系特别密切。一般new一个SP的模板类,会最终调用该类对象对Refase重载的onFirstRef()。这里就可以看到进行了mEventQueue(在介绍SF的消息机制时再深入分析)的初始化以及启动一个run函数。故最终调用SF的readyToRun和threadLoop。

 

 

 


 


 

 

1楼soledadzz前天 16:55
您的文章已被推荐到博客首页和个人页侧边栏推荐文章,感谢您的分享。欢迎加入博客QQ群374041348进行交流。
  相关解决方案