打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
CameraService服务启动流程

启动rc脚本文件

//frameworks\av\camera\cameraserver\cameraserver.rc

service cameraserver /system/bin/cameraserver

1

2

进程入口:

//frameworks\av\camera\cameraserver\main_cameraserver.cpp

int main(int argc __unused, char** argv __unused)

{

    signal(SIGPIPE, SIG_IGN);

    //之前讲过,会打开/dev/hwbinder,通知kernel,当前进程最大允许的binder线程池为maxThreads

    // Set 3 threads for HIDL calls

    hardware::configureRpcThreadpool(3, /*willjoin*/ false);

    //创建ProcessState单例对象

    sp<ProcessState> proc(ProcessState::self());

    //获取IServiceManager服务代理对象BpServiceManager

    //代码在/frameworks/native/libs/binder/IServiceManager.cpp

    sp<IServiceManager> sm = defaultServiceManager();

    ALOGI("ServiceManager: %p", sm.get());

    //1、创建CameraService

    //2、触发CameraService::onFirstRef()

    //3、将CameraService注册给IServiceManager

    CameraService::instantiate();

    //创建一个子线程并加入binder线程池

    ProcessState::self()->startThreadPool();

    //将主线程加入binder线程池

    IPCThreadState::self()->joinThreadPool();

}

下边对CameraService::instantiate()方法进行详细介绍下.

首先给出CameraService的类图,如下:

CameraService::instantiate()调用的是其父类BinderService的方法

// /frameworks/native/include/binder/BinderService.h

static void instantiate() { publish(); }

1

2

接着调用了publish()方法

// /frameworks/native/include/binder/BinderService.h

    static status_t publish(bool allowIsolated = false) {

    //获取IServiceManager服务代理对象BpServiceManager

        sp<IServiceManager> sm(defaultServiceManager());

        //注册服务SERVICECameraService

        return sm->addService(

                String16(SERVICE::getServiceName()),

                new SERVICE(), allowIsolated);

    }

在注册服务时,首先调用CameraService::getServiceName()获取CameraService的服务名称–"media.camera",然后新建CameraService对象。

下边介绍下BpServiceManageraddService方法。

//frameworks\native\libs\binder\IServiceManager.cpp

    virtual status_t addService(const String16& name, const sp<IBinder>& service,

            bool allowIsolated)

    {

        Parcel data, reply;

        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());

        data.writeString16(name);

        data.writeStrongBinder(service);

        data.writeInt32(allowIsolated ? 1 : 0);

        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);

        return err == NO_ERROR ? reply.readExceptionCode() : err;

    }

发现addService的第二个形参为const sp& service。而传入的CameraService对象。因此会调用spAndroid智能指针,不做详细介绍了)的自动类型转换构造函数

//system\core\libutils\include\utils\StrongPointer.h

//TIBinderUCameraService

template<typename T> template<typename U>

sp<T>::sp(U* other)

        : m_ptr(other) {

        //类型转换后调用incStrong方法

    if (other)

        (static_cast<T*>(other))->incStrong(this);

}

incStrong会触发onFirstRef方法,代码如下

//system/core/libutils/RefBase.cpp

void RefBase::incStrong(const void* id) const

{

    weakref_impl* const refs = mRefs;

    refs->incWeak(id);

    refs->addStrongRef(id);

    const int32_t c = refs->mStrong.fetch_add(1, std::memory_order_relaxed);

    if (c != INITIAL_STRONG_VALUE)  {

        return;

    }

    int32_t old = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE,

            std::memory_order_relaxed);

   //触发onFirstRef方法

    refs->mBase->onFirstRef();

}

接着会触发CameraService::onFirstRef()

void CameraService::onFirstRef()

{

    ALOGI("CameraService process starting");

    BnCameraService::onFirstRef();

    ...

    //在以前的文章中介绍过,不做详细介绍了

    res = enumerateProviders();

    ...

    CameraService::pingCameraServiceProxy();

}

enumerateProviders()函数的作用在

CameraService启动流程-获取ICameraProvider服务代理对象BpHwCameraProvider并由此获取所有相机设备代理对象BpHwCameraDevice的流程中详细介绍了。这里不做详细介绍了。

至此分析完了CameraService::instantiate()的流程

总结:CameraService::instantiate()完成的三个任务,按先后顺序排列,有:

新建CameraService对象

触发CameraService onFirstRef类方法

注册服务给ServiceManager

下面继续分析下ProcessState::self()->startThreadPool();

代码如下:

//frameworks\native\libs\binder\ProcessState.cpp

void ProcessState::startThreadPool()

{

    AutoMutex _l(mLock);

    if (!mThreadPoolStarted) {

        mThreadPoolStarted = true;

        //创建一个新的线程

        spawnPooledThread(true);

    }

}

接着分析下spawnPooledThread,代码如下:

////frameworks\native\libs\binder\ProcessState.cpp

//isMaintrue,说明是主线程

void ProcessState::spawnPooledThread(bool isMain)

{

    if (mThreadPoolStarted) {

         //创建线程的名字Binder:PID_%X

        String8 name = makeBinderThreadName();

        ALOGV("Spawning new pooled thread, name=%s\n", name.string());

        //创建一个新线程并启动

        sp<Thread> t = new PoolThread(isMain);

        t->run(name.string());

    }

}

接着分析下线程循环threadLoop

//frameworks\native\libs\binder\ProcessState.cpp

class PoolThread : public Thread

{

public:

    explicit PoolThread(bool isMain)

        : mIsMain(isMain)

    {

    }

protected:

    //子线程循环

    virtual bool threadLoop()

    {   //子线程开启循环,不断读取/dev/binder以获取其他进程发来的命令并执行

        IPCThreadState::self()->joinThreadPool(mIsMain);

        return false;

    }

    const bool mIsMain;

};

接着会调用`IPCThreadState::self()->joinThreadPool(mIsMain)``,代码如下:

//frameworks\native\libs\binder\IPCThreadState.cpp

void IPCThreadState::joinThreadPool(bool isMain)

{

    LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());

    //将当前线程加入到 binder线程池中。

    //在上边的代码中可知,现在是将子线程加入到Binder线程池

    //maintrue

    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);

    status_t result;

    //开启循环,与dev/binder通讯,将mOut中的cmd写入binder驱动

    do {

        processPendingDerefs();

        //获取命令并执行或者等待命令

        // now get the next command to be processed, waiting if necessary

        result = getAndExecuteCommand();

        if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {

            ALOGE("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",

                  mProcess->mDriverFD, result);

            abort();

        }

        // Let this thread exit the thread pool if it is no longer

        // needed and it is not the main process thread.

        if(result == TIMED_OUT && !isMain) {

            break;

        }

    } while (result != -ECONNREFUSED && result != -EBADF);

    LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%d\n",

        (void*)pthread_self(), getpid(), result);

    mOut.writeInt32(BC_EXIT_LOOPER);

    talkWithDriver(false);

}

接着分析下getAndExecuteCommand,代码如下:

//frameworks\native\libs\binder\IPCThreadState.cpp

status_t IPCThreadState::getAndExecuteCommand()

{

    status_t result;

    int32_t cmd;

    ///dev/binder通讯

    result = talkWithDriver();

    if (result >= NO_ERROR) {

        size_t IN = mIn.dataAvail();

        if (IN < sizeof(int32_t)) return result;

        //获取cmd

        cmd = mIn.readInt32();

        ....

        pthread_mutex_lock(&mProcess->mThreadCountLock);

        mProcess->mExecutingThreadsCount++;

        if (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads &&

                mProcess->mStarvationStartTimeMs == 0) {

            mProcess->mStarvationStartTimeMs = uptimeMillis();

        }

        pthread_mutex_unlock(&mProcess->mThreadCountLock);

        //执行命令

        result = executeCommand(cmd);

        pthread_mutex_lock(&mProcess->mThreadCountLock);

        mProcess->mExecutingThreadsCount--;

        if (mProcess->mExecutingThreadsCount < mProcess->mMaxThreads &&

                mProcess->mStarvationStartTimeMs != 0) {

            int64_t starvationTimeMs = uptimeMillis() - mProcess->mStarvationStartTimeMs;

            if (starvationTimeMs > 100) {

                ALOGE("binder thread pool (%zu threads) starved for %" PRId64 " ms",

                      mProcess->mMaxThreads, starvationTimeMs);

            }

            mProcess->mStarvationStartTimeMs = 0;

        }

        pthread_cond_broadcast(&mProcess->mThreadCountDecrement);

        pthread_mutex_unlock(&mProcess->mThreadCountLock);

    }

    return result;

}

先将讲解下executeCommand,代码如下:

//frameworks\native\libs\binder\IPCThreadState.cpp

status_t IPCThreadState::executeCommand(int32_t cmd)

{

    BBinder* obj;

    RefBase::weakref_type* refs;

    status_t result = NO_ERROR;

    switch ((uint32_t)cmd) {

     ...

        //其他进程发来的消息

    case BR_TRANSACTION:

        {

            binder_transaction_data tr;

            result = mIn.read(&tr, sizeof(tr));

            ALOG_ASSERT(result == NO_ERROR,

                "Not enough command data for brTRANSACTION");

            if (result != NO_ERROR) break;

            Parcel buffer;

            buffer.ipcSetDataReference(

                reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),

                tr.data_size,

                reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),

                tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);

            const pid_t origPid = mCallingPid;

            const uid_t origUid = mCallingUid;

            const int32_t origStrictModePolicy = mStrictModePolicy;

            const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;

            mCallingPid = tr.sender_pid;

            mCallingUid = tr.sender_euid;

            mLastTransactionBinderFlags = tr.flags;

            //ALOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);

            Parcel reply;

            status_t error;

            .....

            if (tr.target.ptr) {

                // We only have a weak reference on the target object, so we must first try to

                // safely acquire a strong reference before doing anything else with it.

                if (reinterpret_cast<RefBase::weakref_type*>(

                        tr.target.ptr)->attemptIncStrong(this)) {

                    //调用BnCameraService transact方法

                    error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,

                            &reply, tr.flags);

                    reinterpret_cast<BBinder*>(tr.cookie)->decStrong(this);

                } else {

                    error = UNKNOWN_TRANSACTION;

                }

            } else {

                error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);

            }

            //ALOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",

            //     mCallingPid, origPid, origUid);

            if ((tr.flags & TF_ONE_WAY) == 0) {

                LOG_ONEWAY("Sending reply to %d!", mCallingPid);

                if (error < NO_ERROR) reply.setError(error);

                sendReply(reply, 0);

            } else {

                LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);

            }

            mCallingPid = origPid;

            mCallingUid = origUid;

            mStrictModePolicy = origStrictModePolicy;

            mLastTransactionBinderFlags = origTransactionBinderFlags;

           ......

        }

        break;

   ....

    default:

        ALOGE("*** BAD COMMAND %d received from Binder driver\n", cmd);

        result = UNKNOWN_ERROR;

        break;

    }

    if (result != NO_ERROR) {

        mLastError = result;

    }

    return result;

}

至于如何与binder通讯的这里就不做详细介绍了,以后会专门研究。

至此分析完成了cameraserver的启动流程

总结下:

创建CameraService对象

CameraService注册给ServiceManager时,首先触发了CameraService::onFirstRef

CameraService注册给ServiceManager

新建binder线程池,不断读取/dev/binder。如果有消息会调用BBinder::transact并触发CameraServiceonTransact方法

————————————————

版权声明:本文为CSDN博主「gaojian.shi」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/u010116586/java/article/details/96476132

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Android FrameWork
Android平台——Binder机制 — Windows Live
Android的Camera架构介绍
Android-IPC-Binder(1)
Android系统Surface机制的SurfaceFlinger服务的启动过程分析
Android SurfaceFlinger服务启动过程源码分析
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服