Treble 框架下的 Android Camera HAL3 一
frameworks/av/services/camera/libcameraservice/CameraService.cpp
frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
frameworks/av/services/camera/libcameraservice/common/Camera2ClientBase.cpp
frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp
frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp
frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.h
源码: Android 8
Android 8 和之前版本最大的变化是使用 Treble 架构分离了 framework 和 HAL
Treble 架构详见:AndroidO Treble架构下的变化(转载)
准备工作
在之前的 cameraservice 源码分析中在如下代码中得知 camera hal的版本如下
CAMERA_DEVICE_API_VERSION_1_0
CAMERA_DEVICE_API_VERSION_3_0:
CAMERA_DEVICE_API_VERSION_3_1:
CAMERA_DEVICE_API_VERSION_3_2:
CAMERA_DEVICE_API_VERSION_3_3:
CAMERA_DEVICE_API_VERSION_3_4:
本文主要分析 camera HAL3,如想了解camera 流程参考 : CameraService 和 Client 链接到 HAL
在 cameraservice 服务中实例化 CameraDeviceClient
CameraDeviceClient 调用模板 template <typename TClientBase> 实例化 Camera3Device
camera HAL3
Android7 和 Android8 的区别
如上图所示, Android 8 采用 HIDL 分离了 framework 和 HAL .
接下来分析 : sp<CameraProviderManager> manager
camera HAL1 和 HAL3 都使用了 Treble 架构
在 CameraProviderManager.cpp 中的 deviceInfo3->mInterface->open(...)
关键字 auto 修饰成员变量 deviceInfo3 ,自动推导关键字 auto 增加阅读代码的难度。
auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo); // 类型转换
status_t CameraProviderManager::openSession(const std::string &id,
const sp<hardware::camera::device::V3_2::ICameraDeviceCallback>& callback,
/*out*/
sp<hardware::camera::device::V3_2::ICameraDeviceSession> *session) {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
auto deviceInfo = findDeviceInfoLocked(id,
/*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
if (deviceInfo == nullptr) return NAME_NOT_FOUND;
auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);
Status status;
hardware::Return<void> ret;
// 调用了 open 函数
ret = deviceInfo3->mInterface->open(callback, [&status, &session]
(Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
status = s;
if (status == Status::OK) {
*session = cameraSession;
}
});
if (!ret.isOk()) {
ALOGE("%s: Transaction error opening a session for camera device %s: %s",
__FUNCTION__, id.c_str(), ret.description().c_str());
return DEAD_OBJECT;
}
return mapToStatusT(status);
}
在 CameraProviderManager.h 中找到 DeviceInfo3
struct DeviceInfo3 : public DeviceInfo{...}; // cpp 中 struct 对 C 中 struct 进行了扩充。
DeviceInfo 中定义的成员函数是虚函数,需要子类实现, cpp 中虚函数的用法不做介绍。
重点: typedef hardware::camera::device::V3_2::ICameraDevice InterfaceT;
hardware::camera::device::V3_2::ICameraDevice 中定义了 open 函数,和链接底层驱动。
因为 Android 8(O) 采用了 Treble 架构分离了 framework 和 HAL,并引入了后缀是 .hal 的文件(HAL 接口定义语言)。
// frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.h
// HALv3-specific camera fields, including the actual device interface
struct DeviceInfo3 : public DeviceInfo {
typedef hardware::camera::device::V3_2::ICameraDevice InterfaceT; // 重点
const sp<InterfaceT> mInterface;
virtual status_t setTorchMode(bool enabled) override;
virtual status_t getCameraInfo(hardware::CameraInfo *info) const override;
virtual bool isAPI1Compatible() const override;
virtual status_t getCameraCharacteristics(
CameraMetadata *characteristics) const override;
DeviceInfo3(const std::string& name, const metadata_vendor_id_t tagId,
const std::string &id, uint16_t minorVersion,
const hardware::camera::common::V1_0::CameraResourceCost& resourceCost,
sp<InterfaceT> interface);
virtual ~DeviceInfo3();
private:
CameraMetadata mCameraCharacteristics;
};
hardware::camera::device::V3_2::ICameraDevice
通过搜索和 ICameraDevice 关联的源码文件:
- vendor/mediatek/proprietary/hardware/mtkcam/main/hal/device/3.x/include/ICameraDevice3Session.h
- hardware/interfaces/camera/device/3.2/ICameraDevice.hal
两个文件中均声明了open:
// ICameraDevice.hal
open(ICameraDeviceCallback callback) generates
(Status status, ICameraDeviceSession session);
// ICameraDevice3Session.h
virtual auto open(
const ::android::sp<ICameraDeviceCallback>& callback
) -> ::android::status_t = 0;
在编译系统的时候 ICameraDevice.hal 会编译成 ICameraDevice.h
使用 find 命令查找 :find ./out -name ICameraDevice.h
打开 ICameraDevice.h
// ICameraDevice.h
using open_cb = std::function<void(::android::hardware::camera::common::V1_0::Status status, const ::android::sp<ICameraDeviceSession>& session)>;
virtual ::android::hardware::Return<void> open(const ::android::sp<ICameraDeviceCallback>& callback, open_cb _hidl_cb) = 0;
查找 ::android::hardware::Return<void> open(...) 实现的位置:
hardware/interfaces/camera/device/3.2/default/CameraDevice.cpp
打开模块的代码: 接下来定位追踪 mModule->open(...)
ATRACE_BEGIN("camera3->open");
res = mModule->open(mCameraId.c_str(),
reinterpret_cast<hw_device_t**>(&device));
ATRACE_END();
// hardware/interfaces/camera/device/3.2/default/CameraDevice.cpp
Return<void> CameraDevice::open(const sp<ICameraDeviceCallback>& callback, open_cb _hidl_cb) {
Status status = initStatus();
sp<CameraDeviceSession> session = nullptr;
if (callback == nullptr) {
ALOGE("%s: cannot open camera %s. callback is null!",
__FUNCTION__, mCameraId.c_str());
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
return Void();
}
if (status != Status::OK) {
// Provider will never pass initFailed device to client, so
// this must be a disconnected camera
ALOGE("%s: cannot open camera %s. camera is disconnected!",
__FUNCTION__, mCameraId.c_str());
_hidl_cb(Status::CAMERA_DISCONNECTED, nullptr);
return Void();
} else {
mLock.lock();
ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mCameraIdInt);
session = mSession.promote();
if (session != nullptr && !session->isClosed()) {
ALOGE("%s: cannot open an already opened camera!", __FUNCTION__);
mLock.unlock();
_hidl_cb(Status::CAMERA_IN_USE, nullptr);
return Void();
}
/** Open HAL device */
status_t res;
camera3_device_t *device;
ATRACE_BEGIN("camera3->open");
res = mModule->open(mCameraId.c_str(),
reinterpret_cast<hw_device_t**>(&device));
ATRACE_END();
if (res != OK) {
ALOGE("%s: cannot open camera %s!", __FUNCTION__, mCameraId.c_str());
mLock.unlock();
_hidl_cb(getHidlStatus(res), nullptr);
return Void();
}
/** Cross-check device version */
if (device->common.version < CAMERA_DEVICE_API_VERSION_3_2) {
ALOGE("%s: Could not open camera: "
"Camera device should be at least %x, reports %x instead",
__FUNCTION__,
CAMERA_DEVICE_API_VERSION_3_2,
device->common.version);
device->common.close(&device->common);
mLock.unlock();
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
return Void();
}
struct camera_info info;
res = mModule->getCameraInfo(mCameraIdInt, &info);
if (res != OK) {
ALOGE("%s: Could not open camera: getCameraInfo failed", __FUNCTION__);
device->common.close(&device->common);
mLock.unlock();
_hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
return Void();
}
session = createSession(
device, info.static_camera_characteristics, callback);
if (session == nullptr) {
ALOGE("%s: camera device session allocation failed", __FUNCTION__);
mLock.unlock();
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
return Void();
}
if (session->isInitFailed()) {
ALOGE("%s: camera device session init failed", __FUNCTION__);
session = nullptr;
mLock.unlock();
_hidl_cb(Status::INTERNAL_ERROR, nullptr);
return Void();
}
mSession = session;
IF_ALOGV() {
session->getInterface()->interfaceChain([](
::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
ALOGV("Session interface chain:");
for (auto iface : interfaceChain) {
ALOGV(" %s", iface.c_str());
}
});
}
mLock.unlock();
}
_hidl_cb(status, session->getInterface());
return Void();
}
mModule->open(...)
根据源码: const sp<CameraModule> mModule; 接下来分析类 CameraModule 。
hardware/interfaces/camera/common/1.0/default/CameraModule.cpp
// hardware/interfaces/camera/common/1.0/default/CameraModule.cpp
// 结合分析 Android 7 camera 的经验,推测 nModule->methods->open() 和 cameraHAL 息息相关
int CameraModule::open(const char* id, struct hw_device_t** device) {
int res;
ATRACE_BEGIN("camera_module->open");
res = filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device));
ATRACE_END();
return res;
}
Android 8 (O) 中使用 Treble 架构分离了 framework 和 HAL : 下节分析 Android 8(O) camera HAL3 的注册。
// hardware/libhardware/include/hardware/camera_common.h
typedef struct camera_module
{
...
hw_module_t common;
...
}
// hardware/libhardware/include/hardware/hardware.h
typedef struct hw_module_methods_t
{
/** Open a specific device */
int (*open)(const struct hw_module_t* module, const char* id,
struct hw_device_t** device);
} hw_module_methods_t;