本文均属自己阅读源码的点滴总结,转账请注明出处谢谢。
欢迎和大家交流。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/surfaceflinger 470 class main 471 user system 472 group graphics drmrpc 473 onrestart restart zygote 474
对于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。