由于camera 1网上大家分析的文章比较多,这里就截取各处细节在做继续深究.
前段部分流程可以看:Android Camera 流程学习记录(二)—— Camera Open 调用流程,这里分析CameraService.cpp以下部分.
1.C/C++ 层:
1.1 CameraService.cp
- 位置:
frameworks/av/services/camera/libcameraservice/CameraService.cpp
connect()
:- 注意这里真正实现逻辑是在
connectHelper()
函数中。 - 获得一个客户端实例并且通过
*device
返回。
- 注意这里真正实现逻辑是在
上面分析得知,Java 层中会通过 binder 跨进程调用 CameraService::connect(), camera2 会调用到CameraService::connectDevice(),注意里面connectHelper的参数API_1, camera2会对应API_2,
Status CameraService::connect(
const sp<ICameraClient>& cameraClient,
int cameraId,
const String16& clientPackageName,
int clientUid,
int clientPid,
/*out*/
sp<ICamera>* device) {
ATRACE_CALL();
Status ret = Status::ok();
String8 id = String8::format("%d", cameraId);
sp<Client> client = nullptr;
ret = connectHelper<ICameraClient,Client>(cameraClient, id,
CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, clientPid, API_1,
/*legacyMode*/ false, /*shimUpdateOnly*/ false,
/*out*/client);
if(!ret.isOk()) {
logRejected(id, getCallingPid(), String8(clientPackageName),
ret.toString8());
return ret;
}
*device = client;
return ret;
}
CameraService.h
位置:frameworks/av/services/camera/libcameraservice/CameraService.h
注意这个文件中定义了 CameraService::Client 类,这个类通过它的子类 CameraClient 真正实现了 ICamera 的接口。
connectHelper():
- HAL1 /HAL2 最终也都调用到这个方法
- 这个函数实现比较长,截取其中的一段。
- 首先,如果客户端实例已经存在于 MediaRecorder ,则直接将其取出返回。
- 若不存在,则先获取 deviceVersion,然后再调用 makeClient() 函数创建一个客户端。
- 创建客户端后,需要调用其 initialize() 函数进行初始化,注意其传入的参数是 mModule,这个参数是连接 Libraries 与 HAL 的关键参数。
template<class CALLBACK, class CLIENT>
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId,
int halVersion, const String16& clientPackageName, int clientUid, int clientPid,
apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly,
/*out*/sp<CLIENT>& device) {
...
sp<BasicClient> tmp = nullptr;
ALOGE("%s halVersion = %d , deviceVersion = %d ", __FUNCTION__, halVersion, deviceVersion);
/* makeClient() 很重要, 后面分析 */
if(!(ret = makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid,
clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,
/*out*/&tmp)).isOk()) {
return ret;
}
client = static_cast<CLIENT*>(tmp.get());
LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",
__FUNCTION__);
err = client->initialize(mCameraProviderManager);
...
device = client;
return ret;
}
makeClent:
Status CameraService::makeClient(const sp<CameraService>& cameraService,
const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,
int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
/*out*/sp<BasicClient>* client) {
...
if (halVersion < 0 || halVersion == deviceVersion) {
// Default path: HAL version is unspecified by caller, create CameraClient
// based on device version reported by the HAL.
switch(deviceVersion) {
case CAMERA_DEVICE_API_VERSION_1_0:
if (effectiveApiLevel == API_1) { // Camera1 API route
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
*client = new CameraClient(cameraService, tmp, packageName, cameraIdToInt(cameraId),
facing, clientPid, clientUid, getpid(), legacyMode);
} else { // Camera2 API route
ALOGW("Camera using old HAL version: %d", deviceVersion);
return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
"Camera device \"%s\" HAL version %d does not support camera2 API",
cameraId.string(), deviceVersion);
}
break;
case CAMERA_DEVICE_API_VERSION_3_0:
case CAMERA_DEVICE_API_VERSION_3_1:
case CAMERA_DEVICE_API_VERSION_3_2:
case CAMERA_DEVICE_API_VERSION_3_3:
case CAMERA_DEVICE_API_VERSION_3_4:
if (effectiveApiLevel == API_1) { // Camera1 API route
ALOGE("%s luozh test --->",__FUNCTION__);
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
*client = new Camera2Client(cameraService, tmp, packageName, cameraIdToInt(cameraId),
facing, clientPid, clientUid, servicePid, legacyMode);
} else { // Camera2 API route
sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
*client = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,
facing, clientPid, clientUid, servicePid);
}
break;
default:
// Should not be reachable
ALOGE("Unknown camera device HAL version: %d", deviceVersion);
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
"Camera device \"%s\" has unknown HAL version %d",
cameraId.string(), deviceVersion);
}
} else {
...
}
makeClient
主要是根据 API 版本以及 HAL 版本来选择生成具体的 Client
实例。
目前项目走的是hal3 + camera1,即走的Camera2Client函数.
此时client对象实例被返回去,继续看connectHelper函数里面:
err = client->initialize(mCameraProviderManager);
//此client就是我们返回去的Camera2Client实例,实际主要是在initializeImpl里面实现。
1.1.2 Camera2Client.cpp
位置:frameworks/av/services/camera/libcameraservice/api1/Camera2Client.cpp
- 从文件位置也可以看得出,我们现在走的都是
Camera API 1
的流程。 Camera2Client
继承了CameraService::Client,头文件里面可以看到
。Camera2Client::initialize()
:- initializeImpl里面调用到了Camera2ClientBase::initialize
//Camera2Client.h
//继承模板类Camera2ClientBase,用CameraService::Client实例化
class Camera2Client :
public Camera2ClientBase<CameraService::Client>
{
public:
...
}
//Camera2Client.cpp
Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
const sp<hardware::ICameraClient>& cameraClient,
const String16& clientPackageName,
int cameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
int servicePid,
bool legacyMode):
Camera2ClientBase(cameraService, cameraClient, clientPackageName,
String8::format("%d", cameraId), cameraFacing,
clientPid, clientUid, servicePid),
mParameters(cameraId, cameraFacing)
{
ATRACE_CALL();
SharedParameters::Lock l(mParameters);
l.mParameters.state = Parameters::DISCONNECTED;
mLegacyMode = legacyMode;
}
...
status_t Camera2Client::initialize(sp<CameraProviderManager> manager) {
return initializeImpl(manager);
}
template<typename TProviderPtr>
status_t Camera2Client::initializeImpl(TProviderPtr providerPtr)
{
ATRACE_CALL();
ALOGE("%s: luozh Initializing client for camera %d", __FUNCTION__, mCameraId);
status_t res;
res = Camera2ClientBase::initialize(providerPtr);
if (res != OK) {
return res;
}
{
SharedParameters::Lock l(mParameters);
res = l.mParameters.initialize(&(mDevice->info()), mDeviceVersion);
if (res != OK) {
ALOGE("%s: Camera %d: unable to build defaults: %s (%d)",
__FUNCTION__, mCameraId, strerror(-res), res);
return NO_INIT;
}
l.mParameters.isDeviceZslSupported = isZslEnabledInStillTemplate();
}
String8 threadName;
//preview和recorder 完成各个模块的创建,后续取数据有关系
mStreamingProcessor = new StreamingProcessor(this);
threadName = String8::format("C2-%d-StreamProc",
mCameraId);
mFrameProcessor = new FrameProcessor(mDevice, this);
threadName = String8::format("C2-%d-FrameProc",
mCameraId);
mFrameProcessor->run(threadName.string());
...
}
1.1.3 Camera2ClientBase.cpp
位置:frameworks/av/services/camera/libcameraservice/common/
Camera2ClientBase.cpp
- 构造函数里面创建了一个 Camera3Device
Camera2Client::initialize()-->Camera2ClientBase::initialize()
- 初始化 Camera3Device 的实例,注意此处传入了 CameraProviderManager
- 最后在 Camera3Device 实例中设置 Notify 回调
template <typename TClientBase>
Camera2ClientBase<TClientBase>::Camera2ClientBase(
const sp<CameraService>& cameraService,
const sp<TCamCallbacks>& remoteCallback,
const String16& clientPackageName,
const String8& cameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
int servicePid):
TClientBase(cameraService, remoteCallback, clientPackageName,
cameraId, cameraFacing, clientPid, clientUid, servicePid),
mSharedCameraCallbacks(remoteCallback),
mDeviceVersion(cameraService->getDeviceVersion(TClientBase::mCameraIdStr)),
mDeviceActive(false)
{
ALOGE("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.string(),
String8(clientPackageName).string(), clientPid, clientUid);
mInitialClientPid = clientPid;
mDevice = new Camera3Device(cameraId);
LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here.");
}
...
template <typename TClientBase>
status_t Camera2ClientBase<TClientBase>::initialize(sp<CameraProviderManager> manager) {
return initializeImpl(manager);
}
template <typename TClientBase>
template <typename TProviderPtr>
status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr) {
ATRACE_CALL();
ALOGE("%s: luozh Initializing client for camera %s", __FUNCTION__,
TClientBase::mCameraIdStr.string());
status_t res;
// Verify ops permissions
res = TClientBase::startCameraOps();
if (res != OK) {
return res;
}
if (mDevice == NULL) {
ALOGE("%s: Camera %s: No device connected",
__FUNCTION__, TClientBase::mCameraIdStr.string());
return NO_INIT;
}
res = mDevice->initialize(providerPtr);
if (res != OK) {
ALOGE("%s: Camera %s: unable to initialize device: %s (%d)",
__FUNCTION__, TClientBase::mCameraIdStr.string(), strerror(-res), res);
return res;
}
wp<CameraDeviceBase::NotificationListener> weakThis(this);
res = mDevice->setNotifyCallback(weakThis);
return OK;
}
1.1.4 Camera3Device.cpp
位置:frameworks/av/services/camera/libcameraservice/device3/
Camera3Device.cpp
观察构造函数,注意第 18、19 行设定了两个回调接口。
Camera3Device::Camera3Device(const String8 &id):
mId(id),
mOperatingMode(NO_MODE),
mIsConstrainedHighSpeedConfiguration(false),
mStatus(STATUS_UNINITIALIZED),
mStatusWaiters(0),
mUsePartialResult(false),
mNumPartialResults(1),
mTimestampOffset(0),
mNextResultFrameNumber(0),
mNextReprocessResultFrameNumber(0),
mNextShutterFrameNumber(0),
mNextReprocessShutterFrameNumber(0),
mListener(NULL),
mVendorTagId(CAMERA_METADATA_INVALID_VENDOR_ID)
{
ATRACE_CALL();
camera3_callback_ops::notify = &sNotify;
camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());
}
其初始化函数篇幅较长,这里省略掉了关于 RequestMetadataQueue 的相关操作。我们需要关注的是,在初始化时,调用了 CameraProviderManager 的 openSession
方法(第 13~21 行),开启了远端的 Session。
status_t Camera3Device::initialize(sp<CameraProviderManager> manager) {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
ALOGV("%s: Initializing HIDL device for camera %s", __FUNCTION__, mId.string());
if (mStatus != STATUS_UNINITIALIZED) {
CLOGE("Already initialized!");
return INVALID_OPERATION;
}
if (manager == nullptr) return INVALID_OPERATION;
sp<ICameraDeviceSession> session;
ATRACE_BEGIN("CameraHal::openSession");
status_t res = manager->openSession(mId.string(), this,
/*out*/ &session);
ATRACE_END();
if (res != OK) {
SET_ERR_L("Could not open camera session: %s (%d)", strerror(-res), res);
return res;
}
/* Do something in */
......
/* Do something out */
return initializeCommonLocked();
}
CameraProviderManager.cpp
文件位置:frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp
来看看 openSession 是如何实现的:
第 8~12 行,首先调用 findDeviceInfoLocked,获取 HAL3 相关的 DeviceInfo3,这个东西在服务启动与初始化的时候就已经创建出来,并保存下来了。
NOTE:CameraProviderManager 开机cameraservice初始化的时候已经初始化到,详细可参看在Android 8.0 Camera架构源码分析 - CameraProvider And CameraService启动
第 16~22 行,注意此处,通过远端调用 CameraDevice 的 open 方法,创建 CameraDeviceSession 实例并将其本地调用接口通过入参 session 返回。 (DeviceInfo3 这个类的 mInterface 成员类型是 ICameraDevice,通过它可以调用远端 CameraDevice 中的方法。)
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;
/* mInterface 它实际上是 CameraDevice 对象
* 所以就是调用 CameraDevice::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);
}
CameraDevice.cpp
位置:hardware/interfaces/camera/device/3.2/default/CameraDevice.cpp
CameraDevice在开机CameraProvider启动的时候已经启动,流程参考CameraProvider启动流程(hardware/interfaces/camera/provider/2.4/default/CameraProvider.cpp里面有队CameraDevice的操作)
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) {
/* Do something in */
......
/* Do something out */
} else {
mLock.lock();
/* Do something in */
......
/* Do something out */
/** Open HAL device */
status_t res;
camera3_device_t *device;
ATRACE_BEGIN("camera3->open");
//具体的hal层open函数,此处的open会调用到CameraModule.cpp里面的open函数
res = mModule->open(mCameraId.c_str(),
reinterpret_cast<hw_device_t**>(&device));
ATRACE_END();
/* Do something in */
......
/* Do something out */
session = createSession(
device, info.static_camera_characteristics, callback);
/* Do something in */
......
/* Do something out */
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();
}
res = mModule->open(mCameraId.c_str(),
reinterpret_cast<hw_device_t**>(&device));
此处的open调用的是之前开机已经启动的CameraModule.cpp里面的open函数,之前我们已经分析,CameraModule.cpp链接的是具体的hal层
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;
}
static hw_module_t camera_common = {
.tag = HARDWARE_MODULE_TAG,
.module_api_version = CAMERA_MODULE_API_VERSION_2_4,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = CAMERA_HARDWARE_MODULE_ID,
.name = "Camera Module",
.author = "XXTronix",
.methods = &camera::Camera2Factory::mModuleMethods,
.dso = NULL,
.reserved = {0}
};
mModuleMethods:
struct hw_module_methods_t Camera2Factory::mModuleMethods = {
.open = Camera2Factory::camera_device_open,
};
而 creatSession 中的实现就非常简单了,直接创建了一个 CameraDeviceSession。当然在其构造函数中会调用内部的初始化函数,然后会进入 HAL 接口层 QCamera3HWI 的初始化流程,这里就先不分析了。
至此,从 CameraService 到 HAL Service 这一部分的打开相机流程就基本走通了。