//frameworks\av\camera\cameraserver\cameraserver.rc service cameraserver /system/bin/cameraserver
//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()); //一、建立CameraService //二、触发CameraService::onFirstRef() //三、将CameraService注册给IServiceManager CameraService::instantiate(); //建立一个子线程并加入binder线程池 ProcessState::self()->startThreadPool(); //将主线程加入binder线程池 IPCThreadState::self()->joinThreadPool(); }
下边对 CameraService::instantiate()方法进行详细介绍下.
首先给出CameraService的类图,以下:
CameraService::instantiate()调用的是其父类BinderService的方法web
// /frameworks/native/include/binder/BinderService.h static void instantiate() { publish(); }
接着调用了publish()方法cookie
// /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对象。ide
下边介绍下BpServiceManager的addService方法。svg
//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方法,代码以下oop
//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()fetch
void CameraService::onFirstRef() { ALOGI("CameraService process starting"); BnCameraService::onFirstRef(); ... //在之前的文章中介绍过,不作详细介绍了 res = enumerateProviders(); ... CameraService::pingCameraServiceProxy(); }
enumerateProviders()函数的做用在
CameraService启动流程-获取ICameraProvider服务代理对象BpHwCameraProvider并由此获取全部相机设备代理对象BpHwCameraDevice的流程中详细介绍了。这里不作详细介绍了。ui
至此分析完了CameraService::instantiate()的流程
总结:CameraService::instantiate()完成的三个任务,按前后顺序排列,有:this
下面继续分析下 ProcessState::self()->startThreadPool();
代码以下:spa
//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的启动流程
总结下: