前言
上一篇梳理了 CameraProvider 是独立服务、通过 v4l2 框架管理物理摄像头,本篇主要描述的是 CameraService 如何与 CameraProvider 通讯; android 的 CameraService 是 Camera 子系统核心模块,Camera Api1 和 Api2 的接口、是如何与CameraService 通讯呢?笔者将分两篇来介绍。
CameraService 运行环境部署
首先看一下他的Android.mk 编译配置文件 @frameworks/av/camera/cameraserver/Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
main_cameraserver.cpp
LOCAL_SHARED_LIBRARIES := \
libcameraservice \
liblog \
libutils \
libui \
libgui \
libbinder \
libhidltransport \
android.hardware.camera.common@1.0 \
android.hardware.camera.provider@2.4 \
android.hardware.camera.device@1.0 \
android.hardware.camera.device@3.2
LOCAL_MODULE:= cameraserver
LOCAL_32_BIT_ONLY := true
LOCAL_CFLAGS += -Wall -Wextra -Werror -Wno-unused-parameter
LOCAL_INIT_RC := cameraserver.rc
include $(BUILD_EXECUTABLE)
编译生成的是可执行文件,它依赖的库文件 libcameraservice 就是 CameraService 生成的库; 依赖的 libbinder 库就是与 libcamera_client.so 通讯使用的库文件; 依赖的 android.hardware.camera.provider@2.4 库是与 CameraProvider 通讯使用的库文件.
他的入口函数在哪里呢?
@frameworks/av/camera/cameraserver/main_cameraserver.cpp
#define LOG_TAG "cameraserver"
#include "CameraService.h"
#include <hidl/HidlTransportSupport.h>
using namespace android;
int main(int argc __unused, char** argv __unused)
{
signal(SIGPIPE, SIG_IGN);
hardware::configureRpcThreadpool(3, false);
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
ALOGI("ServiceManager: %p", sm.get());
CameraService::instantiate();
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
什么时候启动这个服务的呢?
@frameworks/av/camera/cameraserver/cameraserver.rc
service cameraserver /system/bin/cameraserver
class main
user cameraserver
group audio camera input drmrpc
ioprio rt 4
writepid /dev/cpuset/camera-daemon/tasks /dev/stune/top-app/tasks
此文件中定义了 cameraserver 服务名称,启动位置在 servicemanager.rc 文件中,笔者开发板文件路径: @frameworks/native/cmds/servicemanager/servicemanager.rc
service servicemanager /system/bin/servicemanager
class core animation
user system
group system readproc
critical
onrestart restart healthd
onrestart restart zygote
onrestart restart audioserver
onrestart restart media
onrestart restart surfaceflinger
onrestart restart inputflinger
onrestart restart drm
onrestart restart cameraserver
writepid /dev/cpuset/system-background/tasks
shutdown critical
我们清楚知道 cameraserver 入口函数,以及系统什么时候开启这个服务。当服务启动时执行 CameraService::instantiate();方法是cameraserver 继承 BinderService 类的instantiate方法,他的定义如下: @frameworks/native/include/binder/BinderService.h
namespace android {
template<typename SERVICE>
class BinderService
{
public:
static status_t publish(bool allowIsolated = false) {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(
String16(SERVICE::getServiceName()),
new SERVICE(), allowIsolated);
}
static void publishAndJoinThreadPool(bool allowIsolated = false) {
publish(allowIsolated);
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();
}
};
};
addService 方法申明如下:
virtual status_t addService( const String16& name,
const sp<IBinder>& service,
bool allowIsolated = false) = 0;
在 main_cameraserver.cpp 中, 执行 CameraService::instantiate(); 调用是继承类BinderService的 instantiate() 函数,该函数调用 publish(); ==> sm->addService( String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);BinderService 提供了 Service 的创建和发布;
而 new SERVICE() 就是 new 一个 CameraService 对象、该对象返回值被 const sp& service 引用, CameraService构造函数内容如下:
CameraService::CameraService() :
mEventLog(DEFAULT_EVENT_LOG_LENGTH),
mNumberOfCameras(0), mNumberOfNormalCameras(0),
mSoundRef(0), mInitialized(false) {
ALOGI("CameraService started (pid=%d)", getpid());
this->camera_device_status_change = android::camera_device_status_change;
this->torch_mode_status_change = android::torch_mode_status_change;
mServiceLockWrapper = std::make_shared<WaitableMutexWrapper>(&mServiceLock);
}
在这一过程中,CameraService 首次被强指针引用时,就会调用 CameraService::onFirstRef() 函数执行初始化之类的业务逻辑,所以现在就看看 CameraService 在此处实现了什么;
void CameraService::onFirstRef()
{
ALOGI("CameraService process starting");
BnCameraService::onFirstRef();
BatteryNotifier& notifier(BatteryNotifier::getInstance());
notifier.noteResetCamera();
notifier.noteResetFlashlight();
status_t res = INVALID_OPERATION;
res = enumerateProviders();
if (res == OK) {
mInitialized = true;
}
CameraService::pingCameraServiceProxy();
}
该方法中调用 res = enumerateProviders() 函数,此函数就是 CameraService 与 CameraProvider 通讯关联的入口函数。
CameraService 如何与 CameraProvider 通讯
在 CameraService::onFirstRef 中调用 enumerateProviders() ,代码内容如下:
status_t CameraService::enumerateProviders() {
status_t res;
Mutex::Autolock l(mServiceLock);
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);
return res;
}
}
mNumberOfCameras = mCameraProviderManager->getCameraCount();
mNumberOfNormalCameras =
mCameraProviderManager->getAPI1CompatibleCameraCount();
mCameraProviderManager->setUpVendorTags();
if (nullptr == mFlashlight.get()) {
mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
}
res = mFlashlight->findFlashUnits();
if (res != OK) {
ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res);
}
for (auto& cameraId : mCameraProviderManager->getCameraDeviceIds()) {
String8 id8 = String8(cameraId.c_str());
bool cameraFound = false;
{
Mutex::Autolock lock(mCameraStatesLock);
auto iter = mCameraStates.find(id8);
if (iter != mCameraStates.end()) {
cameraFound = true;
}
}
if (!cameraFound) {
hardware::camera::common::V1_0::CameraResourceCost cost;
res = mCameraProviderManager->getResourceCost(cameraId, &cost);
if (res != OK) {
ALOGE("Failed to query device resource cost: %s (%d)", strerror(-res), res);
continue;
}
std::set<String8> conflicting;
for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
conflicting.emplace(String8(cost.conflictingDevices[i].c_str()));
}
{
Mutex::Autolock lock(mCameraStatesLock);
mCameraStates.emplace(id8,
std::make_shared<CameraState>(id8, cost.resourceCost, conflicting));
}
}
onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);
if (mFlashlight->hasFlashUnit(id8)) {
mTorchStatusMap.add(id8, TorchModeStatus::AVAILABLE_OFF);
}
}
return OK;
}
首先将 new CameraProviderManager() 实例化,然后调用 initialize() 接口将其初始化,传入的参数是 this 指针,指向当前 CameraService 实例的地址。 initialize 在分析具体实现之前,可以先看看它在头文件中的声明:
class CameraProviderManager : virtual public hidl::manager::V1_0::IServiceNotification {
struct HardwareServiceInteractionProxy : public ServiceInteractionProxy {
virtual bool registerForNotifications(
const std::string &serviceName,
const sp<hidl::manager::V1_0::IServiceNotification>
¬ification) override {
return hardware::camera::provider::V2_4::ICameraProvider::registerForNotifications(
serviceName, notification);
}
virtual sp<hardware::camera::provider::V2_4::ICameraProvider> getService(
const std::string &serviceName) override {
return hardware::camera::provider::V2_4::ICameraProvider::getService(serviceName);
}
};
static HardwareServiceInteractionProxy sHardwareServiceInteractionProxy;
status_t initialize(wp<StatusListener> listener,
ServiceInteractionProxy *proxy = &sHardwareServiceInteractionProxy);
}
用于初始化管理器,并给它设置一个状态监听 (即 CameraService 实例), 选择性地接受一个与服务交互的代理。 默认的代理通过 Hardware 服务管理器进行通信,在创建 HardwareServiceInteractionProxy 代理时执行了hardware:📷:provider::V2_4::ICameraProvider::getService(serviceName);也就开启了 ICameraProvider 对象构建过程,实现 cameraServer 与 CameraProvider 之间关联。
const std::string kLegacyProviderName("legacy/0");
status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,
ServiceInteractionProxy* proxy) {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
if (proxy == nullptr) {
ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);
return BAD_VALUE;
}
mListener = listener;
mServiceProxy = proxy;
bool success = mServiceProxy->registerForNotifications(
"",
this);
if (!success) {
ALOGE("%s: Unable to register with hardware service manager for notifications "
"about camera providers", __FUNCTION__);
return INVALID_OPERATION;
}
addProviderLocked(kLegacyProviderName, false);
return OK;
}
上面是CameraProviderManager的初始化过程,CameraProviderManager就是管理camera Service与camera provider之间通信的工程管理类,两个参数,其中第二个参数就是远程代理类,这个参数已经是默认赋值。
status_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) {
for (const auto& providerInfo : mProviders) {
if (providerInfo->mProviderName == newProvider) {
ALOGW("%s: Camera provider HAL with name '%s' already registered", __FUNCTION__,
newProvider.c_str());
return ALREADY_EXISTS;
}
}
sp<provider::V2_4::ICameraProvider> interface;
interface = mServiceProxy->getService(newProvider);
if (interface == nullptr) {
if (expected) {
ALOGE("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
newProvider.c_str());
return BAD_VALUE;
} else {
return OK;
}
}
sp<ProviderInfo> providerInfo =
new ProviderInfo(newProvider, interface, this);
status_t res = providerInfo->initialize();
if (res != OK) {
return res;
}
mProviders.push_back(providerInfo);
return OK;
}
这个函数主要作用是将找到的这个 Provider 通过 ProviderInfo 记录下来并初始化,并再次执行通过接口代理 执行 getService(),这儿就实现了camera service与camera provider的桥接了;
CameraProviderManager中提供了一个ProviderInfo来保存Camera provider信息,方便管理camera service调用 camera provider,下面分析一下ProviderInfo是怎么样的?源码路径在 CameraProviderManager.h 文件中,是 CameraProviderManager 类的子类内容;
struct ProviderInfo :
virtual public hardware::camera::provider::V2_4::ICameraProviderCallback,
virtual public hardware::hidl_death_recipient
{
const std::string mProviderName;
const sp<hardware::camera::provider::V2_4::ICameraProvider> mInterface;
const metadata_vendor_id_t mProviderTagid;
ProviderInfo(const std::string &providerName,
sp<hardware::camera::provider::V2_4::ICameraProvider>& interface,
CameraProviderManager *manager);
~ProviderInfo();
status_t initialize();
const std::string& getType() const;
status_t addDevice(const std::string& name,
hardware::camera::common::V1_0::CameraDeviceStatus initialStatus =
hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT,
std::string *parsedId = nullptr);
status_t dump(int fd, const Vector<String16>& args) const;
virtual hardware::Return<void> cameraDeviceStatusChange(
const hardware::hidl_string& cameraDeviceName,
hardware::camera::common::V1_0::CameraDeviceStatus newStatus) override;
virtual hardware::Return<void> torchModeStatusChange(
const hardware::hidl_string& cameraDeviceName,
hardware::camera::common::V1_0::TorchModeStatus newStatus) override;
virtual void serviceDied(uint64_t cookie, const wp<hidl::base::V1_0::IBase>& who) override;
struct DeviceInfo {
const std::string mName;
const std::string mId;
const hardware::hidl_version mVersion;
const metadata_vendor_id_t mProviderTagid;
const hardware::camera::common::V1_0::CameraResourceCost mResourceCost;
hardware::camera::common::V1_0::CameraDeviceStatus mStatus;
bool hasFlashUnit() const { return mHasFlashUnit; }
virtual status_t setTorchMode(bool enabled) = 0;
virtual status_t getCameraInfo(hardware::CameraInfo *info) const = 0;
virtual bool isAPI1Compatible() const = 0;
virtual status_t getCameraCharacteristics(CameraMetadata *characteristics) const {
(void) characteristics;
return INVALID_OPERATION;
}
DeviceInfo(const std::string& name, const metadata_vendor_id_t tagId,
const std::string &id, const hardware::hidl_version& version,
const hardware::camera::common::V1_0::CameraResourceCost& resourceCost) :
mName(name), mId(id), mVersion(version), mProviderTagid(tagId),
mResourceCost(resourceCost),
mStatus(hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT),
mHasFlashUnit(false) {}
virtual ~DeviceInfo();
protected:
bool mHasFlashUnit;
template<class InterfaceT>
static status_t setTorchMode(InterfaceT& interface, bool enabled);
};
ProviderInfo继承了 hardware:📷:provider::V2_4::ICameraProviderCallback 与 hardware::hidl_death_recipient; ICameraProviderCallback 是 cameraProvider的 回调接口,hardware::hidl_death_recipient 是hal层的死亡回调接口,方便在底层死亡的时候通知上层。 cameraDeviceStatusChange 与 torchModeStatusChange 都是 ICameraProviderCallback 的回调函数,当camera provider发生变化的时候需要通知上层这些变化。
status_t CameraProviderManager::ProviderInfo::initialize() {
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(), mInterface->isRemote());
hardware::Return<Status> status = mInterface->setCallback(this);
if (!status.isOk()) {
ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
__FUNCTION__, mProviderName.c_str(), status.description().c_str());
return DEAD_OBJECT;
}
if (status != Status::OK) {
ALOGE("%s: Unable to register callbacks with camera provider '%s'",
__FUNCTION__, mProviderName.c_str());
return mapToStatusT(status);
}
hardware::Return<bool> linked = mInterface->linkToDeath(this, mId);
if (!linked.isOk()) {
ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",
__FUNCTION__, mProviderName.c_str(), linked.description().c_str());
return DEAD_OBJECT;
} else if (!linked) {
ALOGW("%s: Unable to link to provider '%s' death notifications",
__FUNCTION__, mProviderName.c_str());
}
std::vector<std::string> devices;
hardware::Return<void> ret = mInterface->getCameraIdList([&status, &devices](
Status idStatus,
const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) {
status = idStatus;
if (status == Status::OK) {
for (size_t i = 0; i < cameraDeviceNames.size(); i++) {
devices.push_back(cameraDeviceNames[i]);
}
} });
if (!ret.isOk()) {
ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",
__FUNCTION__, mProviderName.c_str(), linked.description().c_str());
return DEAD_OBJECT;
}
if (status != Status::OK) {
ALOGE("%s: Unable to query for camera devices from provider '%s'",
__FUNCTION__, mProviderName.c_str());
return mapToStatusT(status);
}
sp<StatusListener> listener = mManager->getStatusListener();
for (auto& device : devices) {
std::string id;
status_t res = addDevice(device,
hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT, &id);
if (res != OK) {
ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
__FUNCTION__, device.c_str(), strerror(-res), res);
continue;
}
}
for (auto& device : mDevices) {
mUniqueCameraIds.insert(device->mId);
if (device->isAPI1Compatible()) {
mUniqueAPI1CompatibleCameraIds.insert(device->mId);
}
}
mUniqueDeviceCount = mUniqueCameraIds.size();
ALOGI("Camera provider %s ready with %zu camera devices",
mProviderName.c_str(), mDevices.size());
return OK;
}
initialize 函数的主要作用是初始化cameraProvider,并且IPC调用到cameraProvider 获取camera device信息,然后调用 addDevice接口将获取的camera device保存在cameraService中,防止多次跨进程调用。
至此、回答第一个问题 CameraService 如何与 CameraProvider 通讯,是通过 CameraProviderManager管理 cameraService 与 cameraProvider 间通信;
因第二个问题涉及到 Binder IPC 通讯相关内容较多、所以另外开启一篇续《详解 CameraService 都做了什么》之 CameraService 与 cameraclient 通讯 篇专门梳理分析此部分内容。
|