android的Surface Flinger服务启动分析

这篇文章android启动流程讲到android的启动流程,其实中间还蕴藏了SurfaceFlinger服务的内容,但没有包括进去,目的是为尽可能简单的讲述android启动流程,从整体上把握。

好吧,现在咱们就一起学习下Surface Flinger中如何启动的。

在android4.3与android4.4版本上有所不同,下面是两个版本简单的流程图


android的Surface Flinger服务启动分析_第1张图片



在Andoird4.4系统出现以前,Surface Flinger服务是由system server启动的。

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

public class SystemServer {
<span style="white-space:pre">	</span>...

    public static void main(String[] args) {
        ...

        System.loadLibrary("android_servers");//加载库
        init1(args);//调用库函数init1()
    }
<span style="white-space:pre">	</span>public static final void init2() {
        Slog.i(TAG, "Entered the Android system server!");
        Thread thr = new ServerThread();
        thr.setName("android.server.ServerThread");
        thr.start();
    }
}


SystemServer进程首先从main静态函数开始执行。

我们看到,首先加载了android_servers的库,然后调用库里的init1()函数完成后面的工作。


小插曲:看到init2()函数没?这个函数后面会被system_init()函数调用。

继而new了一个ServerThread线程,这是非常重要,android启动流程讲到Java系统服务,就是这里被启动的。


init1()函数在下面文件实现

frameworks/base/services/jni/com_android_server_SystemServer.cpp

extern "C" int system_init();

static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
{
    system_init();//调用这个
}

/*
 * JNI registration.
 */
static JNINativeMethod gMethods[] = {
    /* name, signature, funcPtr */
    { "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 },//映射到这
};

int register_android_server_SystemServer(JNIEnv* env)
{
    return jniRegisterNativeMethods(env, "com/android/server/SystemServer",
            gMethods, NELEM(gMethods));
}

init1()函数实际上映射到android_server_SystemServer_init1()。然后调用另外一个函数system_init()完成后面的工作。

system_init1()函数由下面文件实现。

frameworks/base/cmds/system_server/library/system_init.cpp

extern "C" status_t system_init()
{
    ALOGI("Entered system_init()");

<span style="white-space:pre">	</span>...

    char propBuf[PROPERTY_VALUE_MAX];
    property_get("system_init.startsurfaceflinger", propBuf, "1");
    if (strcmp(propBuf, "1") == 0) {
        // Start the SurfaceFlinger
        SurfaceFlinger::instantiate();//启动SurfaceFlinger
    }

    property_get("system_init.startsensorservice", propBuf, "1");
    if (strcmp(propBuf, "1") == 0) {
        // Start the sensor service
        SensorService::instantiate();//启动SensorService
    }

    ...
    jclass clazz = env->FindClass("com/android/server/SystemServer");
    if (clazz == NULL) {
        return UNKNOWN_ERROR;
    }
    jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");//仔细看,这里还调用了java类的init2()函数在上面的systemserver.java里。
    if (methodId == NULL) {
        return UNKNOWN_ERROR;
    }
 ...
}

system_init()函数调用SurfaceFlinger的instantiate()函数来启动SurfaceFlinger。instantiate是实际上来自SurfaceFlinger父类BinderService

下面是函数的实现文件

frameworks/native/include/binder/BinderService.h

class BinderService
{
public:
.....

    static void instantiate() { publish(); }

 ...
};

BinderService的静态成员函数又调用了另一个静态函数publish()来完成工作。

下面是实现

template<typename SERVICE>
class BinderService
{
public:
    static status_t publish(bool allowIsolated = false) {
        sp<IServiceManager> sm(defaultServiceManager());
        return sm->addService(//注册到ServiceManager中去。
                String16(SERVICE::getServiceName()),
                new SERVICE(), allowIsolated);//new一个SurfaceFlinger实例
    }

...
};

BinderService是一个类模板,当BinderService类被SurfaceFlinger类继承时,模板参数SERVICE就是SurfaceFlinger。所以这里的publish()函数实际上是new了一个SurfaceFlinger实例,并把它注册到Service Manager中去。


sp<IServiceManager> sm(defaultServiceManager());知道sm是一个强指针。

所以addService的第二个参数SurfaceFlinger的引用是属于强指针引用,这时会调用SurfaceFlinger实例的成员函数onFristRef。关于强指针请参考Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析


onFristRef函数实现

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

void SurfaceFlinger::onFirstRef()
{
    mEventQueue.init(this);

    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);//调用父类Thread的成员函数run()完成后面工作

    // Wait for the main thread to be done with its initialization
    mReadyToRunBarrier.wait();
}


onFirstRef()调用了SurfaceFlinger父类Thread类的run成员函数,把线程跑起来

如下:

frameworks/native/libs/utils/Threads.cpp

status_t Thread::run(const char* name, int32_t priority, size_t stack)
{
    ...
    if (mCanCallJava) {
        res = createThreadEtc(_threadLoop,//创建线程__threadLoop
                this, name, priority, stack, &mThread);
    } else {
        res = androidCreateRawThreadEtc(_threadLoop,
                this, name, priority, stack, &mThread);
    }
...
}

__threadLoop线程实现


int Thread::_threadLoop(void* user)
{
    ....
    do {
        bool result;
        if (first) {
            first = false;
            self->mStatus = self->readyToRun();//readyToRun函数,在SurfaceFlinger实例里实现
            ...
                result = self->threadLoop();
            }
        } else {
            result = self->threadLoop();//threadLoop函数,在SurfaceFlinger实例里实现
        }

        ....
        }
        
        ...
    } while(strong != 0);
    
    return 0;
}

从上面看出,__threadLoop线程分别调用了readyToRun函数,然后就循环执行threadLoop()函数。

这两个函数都在SurfaceFlinger实例里重写了。

如下:

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

status_t SurfaceFlinger::readyToRun()
{
    ALOGI(  "SurfaceFlinger's main thread ready to run. "
            "Initializing graphics H/W...");

    .....

    for (size_t i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) {
        DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
        // set-up the displays that are already connected
        if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
            // All non-virtual displays are currently considered secure.
            bool isSecure = true;
            createBuiltinDisplayLocked(type);
            wp<IBinder> token = mBuiltinDisplays[i];

            sp<DisplayDevice> hw = new DisplayDevice(this,
                    type, allocateHwcDisplayId(type), isSecure, token,
                    new FramebufferSurface(*mHwc, i),
                    mEGLConfig);
            if (i > DisplayDevice::DISPLAY_PRIMARY) {
                // FIXME: currently we don't get blank/unblank requests
                // for displays other than the main display, so we always
                // assume a connected display is unblanked.
                ALOGD("marking display %d as acquired/unblanked", i);
                hw->acquireScreen();
            }
            mDisplays.add(token, hw);
        }
    }

...

    //  initialize OpenGL ES
    DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);
    initializeGL(mEGLDisplay);

    // start the EventThread
    mEventThread = new EventThread(this);
    mEventQueue.setEventThread(mEventThread);

....

如上ReadyToRun开始初步化display devices,然后创建消息线程,然后就调用startBootAnim();

好吧,可以看见开机动画了。

--------------------------------------------------------------------------------------------------------------------------------------------------

上面是android4.3的流程,下面分析一下android4.4流程,有点不太一样哦

android4.3是systemserver进程调用init1()函数来完成surfaceFlinger启动的。

android4.4则不同,由init直接创建。


init.rc

service surfaceflinger /system/bin/surfaceflinger
    class main
    user system
    group graphics drmrpc
    onrestart restart zygote

init进程直接根据init.rc配置启动了surfaceflinger进程。


frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

int main(int argc, char** argv) {
....

    // instantiate surfaceflinger
    sp<SurfaceFlinger> flinger = new SurfaceFlinger();//新实例

...

    // initialize before clients can connect
    flinger->init();//调用surfaceflinger的初始化函数

    // publish surface flinger
    sp<IServiceManager> sm(defaultServiceManager());
    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);//向service manager注册服务

    // run in this thread
    flinger->run();//开跑

    return 0;
}

来到surfaceflinger进程的main函数,new一个SurfaceFlinger实例,跟着调用SurfaceFlinger类的init()函数完成后面工作,然后向service manager注册服务

然后thread开跑。

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

void SurfaceFlinger::init() {
    ALOGI(  "SurfaceFlinger's main thread ready to run. "
            "Initializing graphics H/W...");

    
.....

    // initialize our non-virtual displays
    for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
        DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
        // set-up the displays that are already connected
        if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
            // All non-virtual displays are currently considered secure.
            bool isSecure = true;
            createBuiltinDisplayLocked(type);
            wp<IBinder> token = mBuiltinDisplays[i];

            sp<BufferQueue> bq = new BufferQueue(new GraphicBufferAlloc());
            sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, bq);
            sp<DisplayDevice> hw = new DisplayDevice(this,
                    type, allocateHwcDisplayId(type), isSecure, token,
                    fbs, bq,
                    mEGLConfig);
            if (i > DisplayDevice::DISPLAY_PRIMARY) {
                // FIXME: currently we don't get blank/unblank requests
                // for displays other than the main display, so we always
                // assume a connected display is unblanked.
                ALOGD("marking display %d as acquired/unblanked", i);
                hw->acquireScreen();
            }
            mDisplays.add(token, hw);
        }
    }

...
    // start the EventThread
    ...
    mSFEventThread = new EventThread(sfVsyncSrc);
    mEventQueue.setEventThread(mSFEventThread);

    mEventControlThread = new EventControlThread(this);
    mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);

...

    // set initial conditions (e.g. unblank default device)
    initializeDisplays();

    // start boot animation
    startBootAnim();
}

这个init()函数与4.3系统的ReadyToRun()函数的功能是一样的,内容上有些不同,但大体也分成三个部分,第一硬件初始化,第二建立消息线程,第三启动开机动画。


void SurfaceFlinger::run() {
    do {
        waitForEvent();
    } while (true);
}

最后调用run()函数开跑,看见没有,一直在等待消息呢。

后续我还会分析android L的代码,看看有什么不同。



你可能感兴趣的:(android的Surface Flinger服务启动分析)