Android Camera Framworks C/S架构简析
JAVA不熟悉,所以从JNI开始整理自己学习的资料
API调用native_setup方法,该方法被注册到JNI中,以实现API对JNI的调用
JNI framworks/base/core/jni/android_hardware_camera.cpp
通过函数:android_hardware_Camera_native_setup()调到
函数camera::connect() framworks/av/camera/camera.cpp中的camera:connect请求连接cameraserver服务
cameraserver的连接
framworks/av/camera/camera.cpp
sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
int clientUid, int clientPid)
{
return CameraBaseT::connect(cameraId, clientPackageName, clientUid, clientPid);
}
这里的camera类继承CameraBase<Camera>和BnCameraClient,所以调用到模版的connect函数:
该函数中通过getCameraService向servermanage获取camera的服务信息,并生成一个cameraserver服务代理BpCameraServer。该代理通过binder机制发送connect命令,当cameraserver端代理BpCameraService收到connect命令后就会执行对应的cameraservice的connect操作(具体的binder机制如何实现暂时还没有弄清楚)
framworks/av/camera/CameraBase.cpp
sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,
const String16& clientPackageName,
int clientUid, int clientPid)
{
sp<TCam> c = new TCam(cameraId); //生成BnCameraClient对象
sp<TCamCallbacks> cl = c;
const sp<::android::hardware::ICameraService> cs = getCameraService();//生成BpCameraService对象,作为client端的server代理
binder::Status ret;
if (cs != nullptr) {
TCamConnectService fnConnectService = TCamTraits::fnConnectService;
ret = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,
clientPid, /*out*/ &c->mCamera);//这里既是执行cameraservices的connect,输出结果到c->mCamera(即BnCameraClient对象)
}
if (ret.isOk() && c->mCamera != nullptr) {
IInterface::asBinder(c->mCamera)->linkToDeath(c);
c->mStatus = NO_ERROR;
} else {
ALOGW("An error occurred while connecting to camera %d: %s", cameraId,
(cs != nullptr) ? "Service not available" : ret.toString8().string());
c.clear();
}
return c;
}
cameraserver端受到binder发送来的connect命令后执行对应connect函数:
framworks/av/services/camera/libmmcameraservice/CameraService.cpp
Status CameraService::connect(
const sp<ICameraClient>& cameraClient,
int cameraId,
const String16& clientPackageName,
int clientUid,
int clientPid,
/*out*/
sp<ICamera>* device) { //这里的参数对应上面的(cs.get()->*fnConnectService)参数
Status ret = Status::ok();
String8 id = String8::format("%d", cameraId);
sp<Client> client = nullptr; //这里的BpCameraClient对象,用于参数传递返回给client
ret = connectHelper<ICameraClient,Client>(cameraClient, id,
CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, clientPid, API_1,
/*legacyMode*/ false, /*shimUpdateOnly*/ false,
/*out*/client); //具体操作实现,并把结果输出到client
if(!ret.isOk()) {
logRejected(id, getCallingPid(), String8(clientPackageName),
ret.toString8());
return ret;
}
*device = client; //把输出的结果赋值给用于传参的BpCameraClient对象,返回给cameraclient,作为server端的client代理
return ret;
}
其中做具体操作的connectHelper函数实现在文件:
framworks/av/services/camera/libmmcameraservice/CameraService.h
template<class CALLBACK, class CLIENT>
binder::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) {
binder::Status ret = binder::Status::ok();
String8 clientName8(clientPackageName);
int originalClientPid = 0;
sp<CLIENT> client = nullptr; // 新建client对象,用于存储输出结果,并返回给client端
{
std::unique_ptr<AutoConditionLock> lock =
AutoConditionLock::waitAndAcquire(mServiceLockWrapper, DEFAULT_CONNECT_TIMEOUT_NS);
if (shimUpdateOnly) {
auto cameraState = getCameraState(cameraId);
if (cameraState != nullptr) {
if (!cameraState->getShimParams().isEmpty()) return ret;
}
}
status_t err;
sp<BasicClient> clientTmp = nullptr;
std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;
if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,
IInterface::asBinder(cameraCb), clientName8, /*out*/&clientTmp,
/*out*/&partial)) != NO_ERROR) {
switch (err) {
case -ENODEV:
return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
"No camera device with ID \"%s\" currently available",
cameraId.string());
case -EBUSY:
return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
"Higher-priority client using camera, ID \"%s\" currently unavailable",
cameraId.string());
default:
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
"Unexpected error %s (%d) opening camera \"%s\"",
strerror(-err), err, cameraId.string());
}
}
mFlashlight->prepareDeviceOpen(cameraId);
int id = cameraIdToInt(cameraId);
int facing = -1;
int deviceVersion = getDeviceVersion(id, /*out*/&facing); //获取API版本,不同API版本创建不同client
sp<BasicClient> tmp = nullptr;
if(!(ret = makeClient(this, cameraCb, clientPackageName, id, facing, clientPid,
clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,
/*out*/&tmp)).isOk()) {
return ret;
} //创建client,具体实现在文件framworks/av/services/libmmcameraservices/CameraServices.cpp
client = static_cast<CLIENT*>(tmp.get()); //把创建的client赋值
if ((err = client->initialize(mModule)) != OK)
ALOGE("%s: Could not initialize client from HAL module.", __FUNCTION__);
//对client进行实例化,不同的API实现在不同的文件,framworks/av/servies/camera/libmmcameraservices/api
// Update shim paremeters for legacy clients
if (effectiveApiLevel == API_1) {
// Assume we have always received a Client subclass for API1
sp<Client> shimClient = reinterpret_cast<Client*>(client.get());
String8 rawParams = shimClient->getParameters();
CameraParameters params(rawParams);
auto cameraState = getCameraState(cameraId);
cameraState->setShimParams(params);
if (shimUpdateOnly) {
// If only updating legacy shim parameters, immediately disconnect client
mServiceLock.unlock();
client->disconnect();
mServiceLock.lock();
} else {
// Otherwise, add client to active clients list
finishConnectLocked(client, partial);
}
}
device = client; //最终把输出赋给devices,用于返回给cameraclient
return ret;
}
framworks/av/services/libmmcameraservices/CameraServices.cpp
根据不同的API传见不同的camera client (new CameraClient) (new Camera2Client)
Status CameraService::makeClient(const sp<CameraService>& cameraService,
const sp<IInterface>& cameraCb, const String16& packageName, int cameraId,
int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
/*out*/sp<BasicClient>* client) {
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, 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 \"%d\" HAL version %d does not support camera2 API",
cameraId, 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
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
*client = new Camera2Client(cameraService, tmp, packageName, 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:
ALOGE("Unknown camera device HAL version: %d", deviceVersion);
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
"Camera device \"%d\" has unknown HAL version %d",
cameraId, deviceVersion);
}
return Status::ok();
}
CameraClient 和 Camera2Client的实例化分别实现对应在
framworks/av/service/camera/libmmcameraservices/api1/
framworks/av/service/camera/libmmcameraservices/api2/
以cameraclient为例:
status_t CameraClient::initialize(CameraModule *module) {
int callingPid = getCallingPid();
status_t res;
res = startCameraOps();
char camera_device_name[10];
snprintf(camera_device_name, sizeof(camera_device_name), "%d", mCameraId);
mHardware = new CameraHardwareInterface(camera_device_name); //这里创建了camera硬件接口,
res = mHardware->initialize(module); //调用底层硬件的初始化方法
mHardware->setCallbacks(notifyCallback,
dataCallback,
dataCallbackTimestamp,
(void *)(uintptr_t)mCameraId); //将CamerService处的回调函数注册到HAL处
return OK;
}
mHardware = new CameraHardwareInterface(camera_device_name);这里便进入了调用HAL层的接口,
framworks/av/services/camera/libmmcameraservices/device1/CameraHardwareInterface.h
该接口包涵了对camera的控制与数据回调,控制包括:开始和停止预览与录像,拍照,对焦等,数据回调包括:预览。录像等数据,
对应上述的mHardware->initialize(module)
status_t initialize(CameraModule *module)
{
camera_info info;
status_t res = module->getCameraInfo(atoi(mName.string()), &info);
int rc = OK;
if (module->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_3 &&
info.device_version > CAMERA_DEVICE_API_VERSION_1_0) {
// Open higher version camera device as HAL1.0 device.
rc = module->openLegacy(mName.string(),
CAMERA_DEVICE_API_VERSION_1_0,
(hw_device_t **)&mDevice);
} else {
rc = module->open(mName.string(), (hw_device_t **)&mDevice); //用于open camera
}
initHalPreviewWindow(); //用于初始化preview的相关流opspreview_stream_ops
return rc;
}
对应上述的mHardware->setCallbacks
void setCallbacks(notify_callback notify_cb,
data_callback data_cb,
data_callback_timestamp data_cb_timestamp,
void* user)
{
mNotifyCb = notify_cb;
mDataCb = data_cb;
mDataCbTimestamp = data_cb_timestamp;
mCbUser = user;
if (mDevice->ops->set_callbacks) {
mDevice->ops->set_callbacks(mDevice,
__notify_cb, //消息回调
__data_cb, //数据回调
__data_cb_timestamp, //时间戳回调
__get_memory, //内存相关操作回调
this);
}
}
module->open(mName.string(), (hw_device_t **)&mDevice)会调用到:
framworks/av/services/libmmcameraservice/common/CameraModule.cpp
int CameraModule::open(const char* id, struct hw_device_t** device) {
int res;
res = filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device)); //通过mModule就调用到HAL
return res;
}
至此,就进入了camera HAL层