本文均属自己阅读源码的点滴总结,转账请注明出处谢谢。
欢迎和大家交流。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 proc(ProcessState::self());
sp sm = defaultServiceManager();
ALOGI("ServiceManager: %p\n", sm.get());
sp 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 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 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
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。