[Android Camera精讲]CameraServer启动
1、环境
代码基于Android 13,代码分支为aosp android-13.0.0_r44;调试机型为Google Pixel5。
2、Camera架构
这张图是我另一篇文章里的,直接拿过来。
cameraserver进程是承上启下的,对上是Camera Api,对应Camera App进程,
对下是CameraProvider进程,也就是Camera HAL。
为什么要讲启动流程呢,因为启动过程中初始化了很多东西,如果这部分略过不看的话,
在看Camera打开、预览等流程时就会很懵,有很多东西不知道哪里来的,其实就是开
机时,进程启动过程初始化的,所以这个很重要。
3、启动流程
整体流程图如下,可以看到,主要都在CameraProviderManager.cpp和对应的ProviderInfo文件中。
3.1 入口
代码目录
frameworks/av/camera/cameraserver/
这里包含如下四个文件
其中Android.bp里面有如下内容
init_rc: ["cameraserver.rc"],
这样的话系统在编译时会将cameraserver.rc放到system/etc/init目录下,
init进程启动的时候会解析这个目录下的所有.rc文件。
编译完成之后的out目录
cameraserver.rc内容如下:
service cameraserver /system/bin/cameraserver
class main
user cameraserver
group audio camera input drmrpc
ioprio rt 4
task_profiles CameraServiceCapacity MaxPerformance
rlimit rtprio 10 10
上面的语法规则说明,将会以二进制/system/bin/cameraserver启动一个名称为cameraserver的服务
cameraserver进程
Android.bp里有如下内容
cc_binary {
name: "cameraserver",
srcs: ["main_cameraserver.cpp"],
// 这里说明二进制cameraserver的入口函数在
// main_cameraserver.cpp文件的main函数里
#define LOG_TAG "cameraserver"
//#define LOG_NDEBUG 0
#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();
}
// 这里处了binder相关的,剩下的就是下面一行了
CameraService::instantiate();
// 下面我们就从CameraService继续分析。
3.2 CameraService
从上图可以看出,CameraService类中并没有定义instantiate()函数,所以它最终调用的是父类
BinderService的instantiate()函数。这个类的代码比较少,我们全贴出来看下。可以看到
instantiate()里面直接调用了publish()方法。
// frameworks/native/libs/binder/include/binder/BinderService.h
namespace android {
// 模板类,对于CameraServer来说,
// 这里的SERVICE是CameraService,
// 因为CameraService继承的是
// BinderService<CameraService>
template<typename SERVICE>
class BinderService
{
public:
// instantiate() 直接调用的这个方法,
// 两个参数都用默认值。
static status_t publish(bool allowIsolated = false,
int dumpFlags =IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
sp<IServiceManager> sm(defaultServiceManager());
// 这里SERVICE是CameraService,
// 所以这里调用的CameraService
// 的静态方法getServiceName()
// 并且创建了一个CameraService对象。
// 最后使用ServiceManager的
// addService方法进行了binder服务注册
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated, dumpFlags);
}
// 这里是带显示参数的使用
static void publishAndJoinThreadPool(
bool allowIsolated = false,
int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
publish(allowIsolated, dumpFlags);
joinThreadPool();
}
// 直接调用了publish()方法
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();
}
};
} // namespace android
下面再看下上面提到的CameraService中的方法
// frameworks/av/services/camera/libcameraservice/CameraService.h
class CameraService :
// 继承BinderService指定泛型类型为CameraService
public BinderService<CameraService>,
public virtual ::android::hardware::BnCameraService,
public virtual IBinder::DeathRecipient,
public virtual CameraProviderManager::StatusListener
{
...
public:
...
// 注册的binder服务名称为“media.camera”
static char const* getServiceName() {
return "media.camera";
}
...
}
接下来我们看下上面提到的ServiceManager的addService方法
这里有一个神奇的地方,所以拿出来提一下,讲清楚。
// frameworks/native/libs/binder/include/binder/IServiceManager.h
// 第一个参数是字符串media.camera
// 第二个参数是new的CameraService对象
// 这里相当于const sp<IBinder>& service = new CameraService()
virtual status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated = false,
int dumpsysFlags = DUMP_FLAG_PRIORITY_DEFAULT) = 0;
我们看下class sp的实现
// system/core/libutils/include/utils/StrongPointer.h
// 下面的T就是CameraService*
template <typename T>
sp<T>& sp<T>::operator=(T* other) {
T* oldPtr(*const_cast<T* volatile*>(&m_ptr));
if (other) {
check_not_on_stack(other);
// 可以看到如果指针不为空的话
// 会调用自身的incStrong方法
other->incStrong(this);
}
if (oldPtr) oldPtr->decStrong(this);
if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race();
m_ptr = other;
return *this;
}
但是我们发现CameraService里并没有incStrong方法,那么一定
是它的父类的方法,由此引出了一个非常重要的类RefBase。
RefBase是Android中所有C++对象的基类。
// system/core/libutils/RefBase.cpp
RefBase::RefBase()
// 这里的this是CameraService*
: mRefs(new weakref_impl(this))
{
}
explicit weakref_impl(RefBase* base)
: mStrong(INITIAL_STRONG_VALUE)
, mWeak(0)
// 这里的mBase其实还是CameraService*
, mBase(base)
, mFlags(OBJECT_LIFETIME_STRONG)
{
}
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);
ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs);
#if PRINT_REFS
ALOGD("incStrong of %p from %p: cnt=%d\n", this, id, c);
#endif
if (c != INITIAL_STRONG_VALUE) {
return;
}
int32_t old __unused = refs->mStrong.fetch_sub(INITIAL_STRONG_VALUE, std::memory_order_relaxed);
// A decStrong() must still happen after us.
ALOG_ASSERT(old > INITIAL_STRONG_VALUE, "0x%x too small", old);
// 如上可知refs->mBase是CameraService*,
// 所以这里会调用CameraService的onFirstRef()方法。
refs->mBase->onFirstRef();
}
可以看到,基类RefBase中有一个空实现,当子类未重新该方法时,将调用基类的这个空实现的方法。
void RefBase::onFirstRef()
{
}
所以,有上面的分析得出一个结论:被sp引用的对象在创建后会执行自身的onFirstRef函数。所以在addService的时候,会执行CameraService的onFirstRef函数,而CameraService是重写了onFirstRef函数的,所以我们下面开始接着分析其构造函数和onFirstRef函数。
构造函数比较简单,进行了一些初始化操作
CameraService::CameraService() :
mEventLog(DEFAULT_EVENT_LOG_LENGTH),
mNumberOfCameras(0),
mNumberOfCamerasWithoutSystemCamera(0),
mSoundRef(0), mInitialized(false),
mAudioRestriction(hardware::camera2::ICameraDeviceUser::AUDIO_RESTRICTION_NONE) {
ALOGI("CameraService started (pid=%d)", getpid());
mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
mMemFd = memfd_create(sFileName, MFD_ALLOW_SEALING);
if (mMemFd == -1) {
ALOGE("%s: Error while creating the file: %s", __FUNCTION__, sFileName);
}
}
这里面的核心是enumerateProviders
void CameraService::onFirstRef()
{
ALOGI("CameraService process starting");
BnCameraService::onFirstRef();
// Update battery life tracking if service is restarting
BatteryNotifier& notifier(BatteryNotifier::getInstance());
notifier.noteResetCamera();
notifier.noteResetFlashlight();
status_t res = INVALID_OPERATION;
// 核心实现,从命令可以看出主要是枚举系统的CameraProviders,
// 也就是Camera HAL所在进程,CameraProvider可能有多个
res = enumerateProviders();
if (res == OK) {
// 上面执行ok后,mInitialized赋值为true
mInitialized = true;
}
mUidPolicy = new UidPolicy(this);
mUidPolicy->registerSelf();
mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
mSensorPrivacyPolicy->registerSelf();
mInjectionStatusListener = new InjectionStatusListener(this);
mAppOps.setCameraAudioRestriction(mAudioRestriction);
sp<HidlCameraService> hcs = HidlCameraService::getInstance(this);
if (hcs->registerAsService() != android::OK) {
ALOGE("%s: Failed to register default android.frameworks.cameraservice.service@1.0",
__FUNCTION__);
}
// This needs to be last call in this function, so that it's as close to
// ServiceManager::addService() as possible.
CameraServiceProxyWrapper::pingCameraServiceProxy();
ALOGI("CameraService pinged cameraservice proxy");
}
3.2.1 enumerateProviders
下面重点看下enumerateProviders()函数的实现
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);
// 创建CameraProvider对象,并且调用初始化方法initialize
// 这里是实现的核心,在initialize方法里会遍历系统中配置
// 的CameraProvider,我们先重点分析这部分
if (nullptr == mCameraProviderManager.get()) {
mCameraProviderManager = new CameraProviderManager();
res = mCameraProviderManager->initialize(this);
if (res != OK) {
ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
__FUNCTION__, strerror(-res), res);
logServiceError(String8::format("Unable to initialize camera provider manager"),
ERROR_DISCONNECTED);
return res;
}
}
...
return OK;
}
CameraProviderManager没有显示构造函数,所以直接看其initialize方法
// frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp
// 这里的第二个参数有默认值,在CameraProviderManager.h当中。
status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
HidlServiceInteractionProxy* hidlProxy) {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
if (hidlProxy == nullptr) {
ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
return BAD_VALUE;
}
mListener = listener;
mDeviceState = 0;
// 遍历HIDL实现的CameraProviders
auto res = tryToInitAndAddHidlProvidersLocked(hidlProxy);
// 这里容易让人误解,以为如果hidl CameraProviders初始化失败,
// 将直接返回,不再遍历aidl的CameraProviders。
// 实际并不是,只要registerForNotifications返回OK就可以。
if (res != OK) {
// Logging done in called function;
return res;
}
// 遍历AIDL实现的CameraProviders
res = tryToAddAidlProvidersLocked();
IPCThreadState::self()->flushCommands();
return res;
}
// 遍历HIDL和AIDL CameraProviders将在下面分别详解
先记住下面这个类图,下面会用到。
3.2.2 tryToInitAndAddHidlProvidersLocked
先看tryToInitAndAddHidlProvidersLocked的实现
status_t CameraProviderManager::tryToInitAndAddHidlProvidersLocked(
HidlServiceInteractionProxy *hidlProxy) {
mHidlServiceProxy = hidlProxy;
// Registering will trigger notifications for all already-known providers
// 这里是注册回调,当binder服务成功注册后,会回调onServiceRegistration方法
// 我们可以看到,这里的第二个参数是this,因为CameraProviderManager是继承了
// IServiceNotification的,也实现了onServiceRegistration方法
bool success = mHidlServiceProxy->registerForNotifications(
/* instance name, empty means no filter */ "",
this);
// 在Pixel5 Android13设备上,这里的success为true
if (!success) {
ALOGE("%s: Unable to register with hardware service manager for notifications "
"about camera providers", __FUNCTION__);
return INVALID_OPERATION;
}
// 这里是核心,mHidlServiceProxy->listServices()是获取到所有HIDL实现
// 的CameraProvider的服务名称的集合,然后通过addHidlProviderLocked进行保存
// 在Pixel5 Android13设备上,这里的listServices为空,表示没有hidl类型的CameraProvider
for (const auto& instance : mHidlServiceProxy->listServices()) {
this->addHidlProviderLocked(instance);
}
// 即使上面没有找到HIDL方式实现的CameraProvider,但是这里还是会返回OK,
// 以便进行下一步遍历AIDL方式实现的CameraProviders
return OK;
}
// Hidl CameraProvider的流程先将这么多,其流程跟Aidl CameraProvider的流程基本一致,
// 下面会针对Aidl CameraProvider流程进行详细讲解。
3.2.3 tryToAddAidlProvidersLocked
这部分主要查找使用AIDL方式实现的CameraProvider
status_t CameraProviderManager::tryToAddAidlProvidersLocked() {
// 这里的值是 android.hardware.camera.provider.ICameraProvider
// 其赋值的地方在ICameraProvider.cpp中,注意这个文件是编译后生成在out目录下的。
const char * aidlHalServiceDescriptor =
aidl::android::hardware::camera::provider::ICameraProvider::descriptor;
auto sm = defaultServiceManager();
// 这里返回的是所有AIDL的CameraProvider服务的instance的名称集合。
// 在pixel5上只有一个AIDL实现的CameraProvdier,其instance的名称是internal/0
// 可以在如下文件找到:
// hardware/google/camera/common/hal/aidl_service/aidl_service.cc
// 其中定义了instance的名称,如下:
// const std::string kProviderInstance = "/internal/0";
auto aidlProviders = sm->getDeclaredInstances(
String16(aidlHalServiceDescriptor));
for (const auto &aidlInstance : aidlProviders) {
// 在pixel5上这个循环执行一次,这里的aidlInstance为"/internal/0"
// aidlServiceName是CameraProvider对应的binder服务名称
// 也在aidl_service.cc中有定义,如下:
// std::string instance =
// std::string() + AidlCameraProvider::descriptor + kProviderInstance;
// 其中AidlCameraProvider::descriptor是android.hardware.camera.provider.ICameraProvider
// 所以服务名称为:
// android.hardware.camera.provider.ICameraProvider/internal/0
std::string aidlServiceName =
getFullAidlProviderName(std::string(String8(aidlInstance).c_str()));
// 上面的操作其实就是拿到了CameraProvider进程的服务名称
// 下面就要开始使用了
// 这里是注册回调,当binder服务成功注册后,会回调onServiceRegistration方法
// 我们可以看到,这里的第二个参数是this,因为CameraProviderManager是继承了
// IServiceNotification的,也实现了onServiceRegistration方法,
// 后面会看到其用法。
auto res = sm->registerForNotifications(String16(aidlServiceName.c_str()), this);
// 如果注册失败,则直接返回,可见这个函数的重要性。
if (res != OK) {
ALOGE("%s Unable to register for notifications with AIDL service manager",
__FUNCTION__);
return res;
}
// 下面我们分析这个函数,注意这里的aidlServiceName
// 是android.hardware.camera.provider.ICameraProvider/internal/0
addAidlProviderLocked(aidlServiceName);
}
return OK;
}
status_t CameraProviderManager::addAidlProviderLocked(const std::string& newProvider) {
// Several camera provider instances can be temporarily present.
// Defer initialization of a new instance until the older instance is properly removed.
// mProviderInstanceId初始值为0
// 这里考虑到多个CameraProvider的场景,所以对每个CameraProvider添加了一个id
// android.hardware.camera.provider.ICameraProvider/internal/0-0
auto providerInstance = newProvider + "-" + std::to_string(mProviderInstanceId);
bool providerPresent = false;
// mAidlProviderWithBinders是一个string集合,用来保存provider实例
bool preexisting =
(mAidlProviderWithBinders.find(newProvider) != mAidlProviderWithBinders.end());
// We need to use the extracted provider name here since 'newProvider' has
// the fully qualified name of the provider service in case of AIDL. We want
// just instance name.
using aidl::android::hardware::camera::provider::ICameraProvider;
// 这里拿到的是internal/0
std::string extractedProviderName =
newProvider.substr(std::string(ICameraProvider::descriptor).size() + 1);
// mProviders是ProviderInfo的集合,初始为空
// 第一次执行时mProviders肯定为空,所以不会执行下面的代码。
for (const auto& providerInfo : mProviders) {
// 如果mProviders中已经有了要要添加的provider
if (providerInfo->mProviderName == extractedProviderName) {
ALOGW("%s: Camera provider HAL with name '%s' already registered",
__FUNCTION__, newProvider.c_str());
// Do not add new instances for lazy HAL external provider or aidl
// binders previously seen.
// 如果已经存在或者是lazy HAL external provider,则返回ALREADY_EXISTS
if (preexisting || providerInfo->isExternalLazyHAL()) {
return ALREADY_EXISTS;
} else {
// 这里想到的一个场景是,下面的tryToInitializeAidlProviderLocked
// 执行失败时preexisting就是false
ALOGW("%s: The new provider instance will get initialized immediately after the"
" currently present instance is removed!", __FUNCTION__);
providerPresent = true;
break;
}
}
}
// 构造AidlProviderInfo对象
sp<AidlProviderInfo> providerInfo =
new AidlProviderInfo(extractedProviderName, providerInstance, this);
// 第一次添加provider时providerPresent肯定是false
if (!providerPresent) {
status_t res = tryToInitializeAidlProviderLocked(newProvider, providerInfo);
if (res != OK) {
return res;
}
// 上述初始化成功后加入mAidlProviderWithBinders集合
mAidlProviderWithBinders.emplace(newProvider);
}
// 将providerInfo添加到mProviders
mProviders.push_back(providerInfo);
// mProviderInstanceId递增,下一个provider的instance id
mProviderInstanceId++;
return OK;
}
下面看下tryToInitializeAidlProviderLocked的实现。
status_t CameraProviderManager::tryToInitializeAidlProviderLocked(
const std::string& providerName, const sp<ProviderInfo>& providerInfo) {
using aidl::android::hardware::camera::provider::ICameraProvider;
// 获取CameraProvider服务的binder代理对象
std::shared_ptr<ICameraProvider> interface =
ICameraProvider::fromBinder(ndk::SpAIBinder(
AServiceManager_getService(providerName.c_str())));
// 如果为空,说明无法获取CameraProvider服务,可能这时还未启动,也可能发生异常。
// 在Pixel5上,执行到这里时为空,因为此时CameraProvider服务还未启动完成。
if (interface == nullptr) {
ALOGW("%s: AIDL Camera provider HAL '%s' is not actually available", __FUNCTION__,
providerName.c_str());
return BAD_VALUE;
}
// 所以下面的代码第一次到这里时未执行到,但是我们上面说过,当CameraProvider服务注册成功后,
// 会回调onServiceRegistration方法,在这个回调中会调用addAidlProviderLocked,然后
// 还会走到这里来,所以第二次的时候才会真正执行下面的代码。
AidlProviderInfo *aidlProviderInfo = static_cast<AidlProviderInfo *>(providerInfo.get());
// 主要调用了initializeAidlProvider方法
// mDeviceState初始值为0
return aidlProviderInfo->initializeAidlProvider(interface, mDeviceState);
}
我们发现,当onServiceRegistration函数回调时,还会调用addAidlProviderLocked方法
void CameraProviderManager::onServiceRegistration(const String16 &name, const sp<IBinder>&) {
ALOGE("onServiceRegistration name:%s", String8(name).c_str());
status_t res = OK;
std::lock_guard<std::mutex> providerLock(mProviderLifecycleLock);
{
std::lock_guard<std::mutex> lock(mInterfaceMutex);
res = addAidlProviderLocked(String8(name).c_str());
}
sp<StatusListener> listener = getStatusListener();
if (nullptr != listener.get() && res == OK) {
listener->onNewProviderRegistered();
}
IPCThreadState::self()->flushCommands();
}
下面看下initializeAidlProvider
// frameworks/av/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
status_t AidlProviderInfo::initializeAidlProvider(
std::shared_ptr<ICameraProvider>& interface, int64_t currentDeviceState) {
// 这里的mProviderName是上面构造AidlProviderInfo的时候赋值的
// 其值为:internal/0
// 这里对mProviderName的名称进行了校验,看是否符合命名规则
// 解析后mType=internal mId=0,也就是对mProviderName进行了拆分
status_t res = parseProviderName(mProviderName, &mType, &mId);
if (res != OK) {
ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
return BAD_VALUE;
}
ALOGI("Connecting to new camera provider: %s, isRemote? %d",
mProviderName.c_str(), interface->isRemote());
// cameraDeviceStatusChange callbacks may be called (and causing new devices added)
// before setCallback returns
mCallbacks =
ndk::SharedRefBase::make<AidlProviderCallbacks>(this);
// 这里设置一个callback到CameraProvider,回调的内容
// 可以看下AidlProviderCallbacks的定义
ndk::ScopedAStatus status =
interface->setCallback(mCallbacks);
if (!status.isOk()) {
ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
__FUNCTION__, mProviderName.c_str(), status.getMessage());
return mapToStatusT(status);
}
mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(binderDied));
// CameraProvider服务死亡回调通知
auto link = AIBinder_linkToDeath(interface->asBinder().get(), mDeathRecipient.get(), this);
if (link != STATUS_OK) {
ALOGW("%s: Unable to link to provider '%s' death notifications",
__FUNCTION__, mProviderName.c_str());
return DEAD_OBJECT;
}
if (!kEnableLazyHal) {
// Save HAL reference indefinitely
mSavedInterface = interface;
} else {
mActiveInterface = interface;
}
ALOGV("%s: Setting device state for %s: 0x%" PRIx64,
__FUNCTION__, mProviderName.c_str(), mDeviceState);
// 这里调用的是interface->notifyDeviceStateChange(mDeviceState);
// 通知CameraHal currentDeviceState状态
notifyDeviceStateChange(currentDeviceState);
res = setUpVendorTags();
if (res != OK) {
ALOGE("%s: Unable to set up vendor tags from provider '%s'",
__FUNCTION__, mProviderName.c_str());
return res;
}
// Get initial list of camera devices, if any
std::vector<std::string> devices;
std::vector<std::string> retDevices;
// 这里返回的是CameraDevice相关的信息,每个Camera id对应一个CameraDevice
status = interface->getCameraIdList(&retDevices);
if (!status.isOk()) {
ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",
__FUNCTION__, mProviderName.c_str(), status.getMessage());
return mapToStatusT(status);
}
// 在pixel5上有两个摄像头,后摄和前摄,cameraid分别为0和1
// 所以这里retDevices有两个,其值分别为
// device@1.1/internal/0
// device@1.1/internal/1
// 其赋值的地方在
// hardware/google/camera/common/hal/aidl_service/aidl_camera_provider.cc
/*
for (uint32_t i = 0; i < camera_ids_ret->size(); i++) {
// camera ID is in the form of "device@<major>.<minor>/<type>/<id>"
(*camera_ids_ret)[i] =
"device@" + device::implementation::AidlCameraDevice::kDeviceVersion +
"/" + kProviderName + "/" + std::to_string(camera_ids[i]);
}
*/
for (auto& name : retDevices) {
uint16_t major, minor;
std::string type, id;
// 解析校验,其值为:
// major:1, minor:1,type:internal,id:0
// major:1, minor:1,type:internal,id:1
status_t res = parseDeviceName(name, &major, &minor, &type, &id);
if (res != OK) {
ALOGE("%s: Error parsing deviceName: %s: %d", __FUNCTION__, name.c_str(), res);
return res;
} else {
// 保存信息
devices.push_back(name);
mProviderPublicCameraIds.push_back(id);
}
}
// Get list of concurrent streaming camera device combinations
// 这里查询和返回可以同时使用的cameradevice信息,
// 笔者理解是可同时使用的camera集合,比如同时打开前置和后置摄像头
res = getConcurrentCameraIdsInternalLocked(interface);
if (res != OK) {
return res;
}
mSetTorchModeSupported = true;
mIsRemote = interface->isRemote();
// 这个下面展开分析
initializeProviderInfoCommon(devices);
return OK;
}
我们继续分析initializeProviderInfoCommon
void CameraProviderManager::ProviderInfo::initializeProviderInfoCommon(
const std::vector<std::string> &devices) {
for (auto& device : devices) {
std::string id;
// 这里最重要的是addDevice函数,我们下面展开讲
status_t res = addDevice(device, CameraDeviceStatus::PRESENT, &id);
if (res != OK) {
ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
__FUNCTION__, device.c_str(), strerror(-res), res);
continue;
}
}
ALOGI("Camera provider %s ready with %zu camera devices",
mProviderName.c_str(), mDevices.size());
// 处理掉缓存的回调
// Process cached status callbacks
{
std::lock_guard<std::mutex> lock(mInitLock);
for (auto& statusInfo : mCachedStatus) {
std::string id, physicalId;
if (statusInfo.isPhysicalCameraStatus) {
physicalCameraDeviceStatusChangeLocked(&id, &physicalId,
statusInfo.cameraId, statusInfo.physicalCameraId, statusInfo.status);
} else {
cameraDeviceStatusChangeLocked(&id, statusInfo.cameraId, statusInfo.status);
}
}
mCachedStatus.clear();
// 执行到这里AidlProviderInfo初始化成功
mInitialized = true;
}
}
下面我们看下addDevice的实现
status_t CameraProviderManager::ProviderInfo::addDevice(
const std::string& name, CameraDeviceStatus initialStatus,
/*out*/ std::string* parsedId) {
ALOGI("Enumerating new camera device: %s", name.c_str());
uint16_t major, minor;
std::string type, id;
IPCTransport transport = getIPCTransport();
// 这个函数之前已经执行过一次,这里还需要使用,所以又调用一次
// major:1, minor:1,type:internal,id:0
// major:1, minor:1,type:internal,id:1
status_t res = parseDeviceName(name, &major, &minor, &type, &id);
if (res != OK) {
return res;
}
// 这里的mType是parseProviderName函数执行时解析出来的是:internal
// type是parseDeviceName的值,目前也是internal
// 如果两者的type不一致的话这里直接返回。
if (type != mType) {
ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,
type.c_str(), mType.c_str());
return BAD_VALUE;
}
// 检查目前从cameradevice是否已经被使用
if (mManager->isValidDeviceLocked(id, major, transport)) {
ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__,
name.c_str(), id.c_str(), major);
return BAD_VALUE;
}
std::unique_ptr<DeviceInfo> deviceInfo;
switch (transport) {
case IPCTransport::HIDL:
switch (major) {
case 3:
break;
default:
ALOGE("%s: Device %s: Unsupported HIDL device HAL major version %d:",
__FUNCTION__, name.c_str(), major);
return BAD_VALUE;
}
break;
// 这里我们将的是Aidl CameraProvider,所以肯定走这里。
// 目前大版本号是1,如果不是的话直接返回
case IPCTransport::AIDL:
if (major != 1) {
ALOGE("%s: Device %s: Unsupported AIDL device HAL major version %d:", __FUNCTION__,
name.c_str(), major);
return BAD_VALUE;
}
break;
default:
ALOGE("%s Invalid transport %d", __FUNCTION__, transport);
return BAD_VALUE;
}
// 创建DeviceInfo对象,这个函数下面展开讲
deviceInfo = initializeDeviceInfo(name, mProviderTagid, id, minor);
if (deviceInfo == nullptr) return BAD_VALUE;
// 目前DeviceState为0
deviceInfo->notifyDeviceStateChange(getDeviceState());
// mStatus=CameraDeviceStatus::PRESENT
deviceInfo->mStatus = initialStatus;
bool isAPI1Compatible = deviceInfo->isAPI1Compatible();
// 保存到mDevices中
mDevices.push_back(std::move(deviceInfo));
mUniqueCameraIds.insert(id);
if (isAPI1Compatible) {
// addDevice can be called more than once for the same camera id if HAL
// supports openLegacy.
if (std::find(mUniqueAPI1CompatibleCameraIds.begin(), mUniqueAPI1CompatibleCameraIds.end(),
id) == mUniqueAPI1CompatibleCameraIds.end()) {
mUniqueAPI1CompatibleCameraIds.push_back(id);
}
}
if (parsedId != nullptr) {
*parsedId = id;
}
return OK;
}
我们具体看下initializeDeviceInfo
std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
AidlProviderInfo::initializeDeviceInfo(
const std::string &name, const metadata_vendor_id_t tagId,
const std::string &id, uint16_t minorVersion) {
::ndk::ScopedAStatus status;
// 这里是获取CameraDevice对象的binder代理camera::device::ICameraDevice
auto cameraInterface = startDeviceInterface(name);
if (cameraInterface == nullptr) return nullptr;
camera::common::CameraResourceCost resourceCost;
// 获取CameraDevice对应的resourceCost,这个值在openCamera时会用到
// 可以看另一篇open流程的讲解文章
status = cameraInterface->getResourceCost(&resourceCost);
if (!status.isOk()) {
ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__,
name.c_str(), status.getMessage());
return nullptr;
}
// 打印出与其有冲突的设备,这个是在Camera hal库中定义的
for (auto& conflictName : resourceCost.conflictingDevices) {
uint16_t major, minor;
std::string type, id;
status_t res = parseDeviceName(conflictName, &major, &minor, &type, &id);
if (res != OK) {
ALOGE("%s: Failed to parse conflicting device %s", __FUNCTION__, conflictName.c_str());
return nullptr;
}
conflictName = id;
}
// 创建AidlDeviceInfo3对象返回
return std::unique_ptr<DeviceInfo3>(
new AidlDeviceInfo3(name, tagId, id, minorVersion, HalToFrameworkResourceCost(resourceCost),
this, mProviderPublicCameraIds, cameraInterface));
}
最后看下DeviceInfo的类图