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