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());

//注册服务SERVICE为CameraService

return sm->addService(

String16(SERVICE::getServiceName()),

new SERVICE(), allowIsolated);

}

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

下边介绍下BpServiceManager的addService方法。

//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对象。因此会调用sp(Android智能指针,不做详细介绍了)的自动类型转换构造函数

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

//T为IBinder;U为CameraService

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

//isMain为true,说明是主线程

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线程池

//main为true

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并触发CameraService的onTransact方法

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

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

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

(0)

相关推荐