目录
简介
本文主要介绍CameraService的初始化过程。希望能够在了解CameraService初始化的流程
,让读者更能清晰的了解CameraService在整个Camera框架中的作用。
在阅读本文时,需要读者留意在初始化过程中,CameraService与CameraProvider进行交互的
相关操作。
1 启动流程
1.1 rc
service cameraserver /system/bin/cameraserver // 该部分定义了一个名为cameraserver的服务,他的可执行文件路径为system/bin/cameraserver
class main // 类别为main
user cameraserver // 在执行此服务之前,请更改为“cameraserver ”
group audio camera input drmrpc // 在执行此服务之前,请更改为“groupname”。除了(必需的)第一个之外的其他组名用于设置进程的补充组(通过setgroups())。
ioprio rt 4 // 通过ioprioset系统调用,为该服务设置IO优先级类别和IO优先级
task_profiles CameraServiceCapacity MaxPerformance // 设置任务配置文件。在安卓U之前,配置文件应用于服务的主线程。对于Android U及更高版本,配置文件将应用于整个服务过程。这是为了取代使用writepid选项将进程移动到cgroup中。
rlimit rtprio 10 10 // 他的将给定的rlimit应用于服务。rlimit由子进程继承,因此这将有效地将给定的rlimit应用于此服务启动的进程树。它的解析类似于下面指定的setrlimit命令。
1.2 main_cameraserver.cpp
#include "CameraService.h"
#include <hidl/HidlTransportSupport.h>
using namespace android;
int main(int argc __unused, char** argv __unused)
{
signal(SIGPIPE, SIG_IGN);
// Set 5 threads for HIDL calls. Now cameraserver will serve HIDL calls in
// addition to consuming them from the Camera HAL as well.
hardware::configureRpcThreadpool(5, /*willjoin*/ false);
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p", sm.get());
CameraService::instantiate(); //注释一,
ALOGI("ServiceManager: %p done instantiate", sm.get());
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
2 初始化流程
文件路径 | class name |
---|---|
\frameworks\native\libs\binder\include\binder\BinderService.h | template class BinderService |
\frameworks\native\libs\binder\include\binder\IBinder.h | IBinder::DeathRecipient |
\frameworks\av\services\camera\libcameraservice\common\CameraProviderManager.h | CameraProviderManager::StatusListener |
\frameworks\av\camera\aidl\android\hardware\ICameraService.aidl | ::android::hardware::BnCameraService |
在上述的表和图中,CameraService继承了BnCameraService,DeathRecipient,StatusListener,BinderService四个类, 其中继承的第四个类是以CameraService类为模板的BinderService类。BinderService类中包含了静态方法instantiate。这里我们着重看一下BindService ::instantiate这个函数
2.1 BindService ::instantiate
该函数做了以下事件:
- 将CameraService传入ServiceManager中进行统一管理(addService)
:而在这个过程中,由于调用addService时存在CameraService的sp引用,因此会调用CameraService::onFirstRef
template<typename SERVICE>
class BinderService
{
public:
static status_t publish(bool allowIsolated = false,
int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
dumpFlags);//此处的ServiceName为“media.camera”
}
static void publishAndJoinThreadPool(
bool allowIsolated = false,
int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
publish(allowIsolated, dumpFlags);
joinThreadPool();
}
static void instantiate() { publish(); }
static status_t shutdown() { return NO_ERROR; }
private:
static void joinThreadPool() {
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
ps->giveThreadPoolName();
IPCThreadState::self()->joinThreadPool();
}
};
2.2 CameraService::onFirstRef()
void CameraService::onFirstRef()
{
ALOGI("CameraService process starting");
BnCameraService::onFirstRef();
...
//枚举CameraProvider
res = enumerateProviders();
...
}
2.3 CameraService::enumerateProviders()
该函数主要完成了以下事件:
- 枚举设备的过程中先获取mServiceLock, 防止其他资源访问
- 创建CameraProviderManager对象并初始化
- 初始化后会设置vendorTags(相机静态能力)
- 创建CameraFlashlight对象
- 通过初始化完成的CameraProvidermanager对象获取CameraID
- 获取cameraid后释放mServiceLock。
- 上报camera id到framework,然后通过配置的ro.odm.build.media_performance_class决定是否需要过滤相机参数信息(过滤时依需获取mServiceLock锁资源)。
status_t CameraService::enumerateProviders() {
status_t res;
std::vector<std::string> deviceIds;
std::unordered_map<std::string, std::set<std::string>> unavailPhysicalIds;
{
Mutex::Autolock l(mServiceLock);//枚举设备的过程中先获取mServiceLock
if (nullptr == mCameraProviderManager.get()) {
mCameraProviderManager = new CameraProviderManager();
res = mCameraProviderManager->initialize(this);// 创建CameraProviderManager对象并初始化
...
// Setup vendor tags before we call get_camera_info the first time
// because HAL might need to setup static vendor keys in get_camera_info
// TODO: maybe put this into CameraProviderManager::initialize()?
mCameraProviderManager->setUpVendorTags();//初始化后会设置vendorTags
if (nullptr == mFlashlight.get()) {
//创建CameraFlashlight对象
mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
}
res = mFlashlight->findFlashUnits();
if (res != OK) {
ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res);
}
//上报camera id到framework
deviceIds = mCameraProviderManager->getCameraDeviceIds(&unavailPhysicalIds);
}
for (auto& cameraId : deviceIds) {
if (getCameraState(cameraId) == nullptr) {
onDeviceStatusChanged(cameraId, CameraDeviceStatus::PRESENT);
}
if (unavailPhysicalIds.count(cameraId) > 0) {
for (const auto& physicalId : unavailPhysicalIds[cameraId]) {
onDeviceStatusChanged(cameraId, physicalId, CameraDeviceStatus::NOT_PRESENT);
}
}
}
// Derive primary rear/front cameras, and filter their charactierstics.
// This needs to be done after all cameras are enumerated and camera ids are sorted.
if (SessionConfigurationUtils::IS_PERF_CLASS) {
// Assume internal cameras are advertised from the same
// provider. If multiple providers are registered at different time,
// and each provider contains multiple internal color cameras, the current
// logic may filter the characteristics of more than one front/rear color
// cameras.
Mutex::Autolock l(mServiceLock);
filterSPerfClassCharacteristicsLocked();
}
return OK;
}
3 总结
本文中主要介绍了CameraService的初始化流程,当然其中还有很多细节没有进行详细梳理。比较重要的内容
就是CameraProvider 服务的启动流程和初始化流程。这些内容会在之后的文章中进行逐一梳理。