啟動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); //創(chuàng)建ProcessState單例對象 sp<ProcessState> proc(ProcessState::self()); //獲取IServiceManager服務(wù)代理對象BpServiceManager //代碼在/frameworks/native/libs/binder/IServiceManager.cpp sp<IServiceManager> sm = defaultServiceManager(); ALOGI("ServiceManager: %p", sm.get()); //1、創(chuàng)建CameraService //2、觸發(fā)CameraService::onFirstRef() //3、將CameraService注冊給IServiceManager CameraService::instantiate(); //創(chuàng)建一個子線程并加入binder線程池 ProcessState::self()->startThreadPool(); //將主線程加入binder線程池 IPCThreadState::self()->joinThreadPool(); } 下邊對CameraService::instantiate()方法進行詳細介紹下. 首先給出CameraService的類圖,如下: CameraService::instantiate()調(diào)用的是其父類BinderService的方法 // /frameworks/native/include/binder/BinderService.h static void instantiate() { publish(); } 1 2 接著調(diào)用了publish()方法 // /frameworks/native/include/binder/BinderService.h static status_t publish(bool allowIsolated = false) { //獲取IServiceManager服務(wù)代理對象BpServiceManager sp<IServiceManager> sm(defaultServiceManager()); //注冊服務(wù)SERVICE為CameraService return sm->addService( String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated); } 在注冊服務(wù)時,首先調(diào)用CameraService::getServiceName()獲取CameraService的服務(wù)名稱–"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; } 發(fā)現(xiàn)addService的第二個形參為const sp& service。而傳入的CameraService對象。因此會調(diào)用sp(Android智能指針,不做詳細介紹了)的自動類型轉(zhuǎn)換構(gòu)造函數(shù) //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) { //類型轉(zhuǎn)換后調(diào)用incStrong方法 if (other) (static_cast<T*>(other))->incStrong(this); } incStrong會觸發(fā)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); //觸發(fā)onFirstRef方法 refs->mBase->onFirstRef(); } 接著會觸發(fā)CameraService::onFirstRef() void CameraService::onFirstRef() { ALOGI("CameraService process starting"); BnCameraService::onFirstRef(); ... //在以前的文章中介紹過,不做詳細介紹了 res = enumerateProviders(); ... CameraService::pingCameraServiceProxy(); } enumerateProviders()函數(shù)的作用在 CameraService啟動流程-獲取ICameraProvider服務(wù)代理對象BpHwCameraProvider并由此獲取所有相機設(shè)備代理對象BpHwCameraDevice的流程中詳細介紹了。這里不做詳細介紹了。 至此分析完了CameraService::instantiate()的流程 總結(jié):CameraService::instantiate()完成的三個任務(wù),按先后順序排列,有: 新建CameraService對象 觸發(fā)CameraService onFirstRef類方法 注冊服務(wù)給ServiceManager 下面繼續(xù)分析下ProcessState::self()->startThreadPool(); 代碼如下: //frameworks\native\libs\binder\ProcessState.cpp void ProcessState::startThreadPool() { AutoMutex _l(mLock); if (!mThreadPoolStarted) { mThreadPoolStarted = true; //創(chuàng)建一個新的線程 spawnPooledThread(true); } } 接著分析下spawnPooledThread,代碼如下: ////frameworks\native\libs\binder\ProcessState.cpp //isMain為true,說明是主線程 void ProcessState::spawnPooledThread(bool isMain) { if (mThreadPoolStarted) { //創(chuàng)建線程的名字Binder:PID_%X String8 name = makeBinderThreadName(); ALOGV("Spawning new pooled thread, name=%s\n", name.string()); //創(chuàng)建一個新線程并啟動 sp<Thread> t = new PoolThread(isMain); t->run(name.string()); } } 接著分析下線程循環(huán)threadLoop //frameworks\native\libs\binder\ProcessState.cpp class PoolThread : public Thread { public: explicit PoolThread(bool isMain) : mIsMain(isMain) { } protected: //子線程循環(huán) virtual bool threadLoop() { //子線程開啟循環(huán),不斷讀取/dev/binder以獲取其他進程發(fā)來的命令并執(zhí)行 IPCThreadState::self()->joinThreadPool(mIsMain); return false; } const bool mIsMain; }; 接著會調(diào)用`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線程池中。 //在上邊的代碼中可知,現(xiàn)在是將子線程加入到Binder線程池 //main為true mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); status_t result; //開啟循環(huán),與dev/binder通訊,將mOut中的cmd寫入binder驅(qū)動 do { processPendingDerefs(); //獲取命令并執(zhí)行或者等待命令 // 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); //執(zhí)行命令 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) { ... //其他進程發(fā)來的消息 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)) { //調(diào)用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的啟動流程 總結(jié)下: 創(chuàng)建CameraService對象 將CameraService注冊給ServiceManager時,首先觸發(fā)了CameraService::onFirstRef 將CameraService注冊給ServiceManager 新建binder線程池,不斷讀取/dev/binder。如果有消息會調(diào)用BBinder::transact并觸發(fā)CameraService的onTransact方法 ———————————————— 版權(quán)聲明:本文為CSDN博主「gaojian.shi」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。 原文鏈接:https://blog.csdn.net/u010116586/java/article/details/96476132 |
|
來自: 新用戶8389DdzY > 《camera》