上一篇我们从最新的Camera架构来分析Camera子系统,今天我们将从全局的视角从旧版本到新版本架构整体通览一遍,从Framework层的API(1和2)到硬件抽象层的HAL(1和3)。废话少说一起来看一下整体架构:
从整体架构图来看,上层API相互独立,中间Camera库耦合度低,HAL层构建合理;APIv1对应HAL1和HAL2。前后两套API耦合度低,APIv2几乎是重写了整个结构。废话少说我们直接上代码。
1. Camera和JNICameraContext
frameworks\base\core\java\android\hardware\Camera.java
frameworks\base\core\jni\android_hardware_Camera.cpp
创建相机时,执行相机初始化
private native final int native_setup(Object camera_this, int cameraId, int halVersion, String packageName);
frameworks\base\core\jni\android_hardware_Camera.cpp
执行初始化时会进行,HAL版本判断
// connect to camera service
static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
jobject weak_this, jint cameraId, jint halVersion, jstring clientPackageName)
{
//
sp<Camera> camera;
if (halVersion == CAMERA_HAL_API_VERSION_NORMAL_CONNECT) { //不关心HAL版本
// Default path: hal version is don't care, do normal camera connect.
camera = Camera::connect(cameraId, clientName,
Camera::USE_CALLING_UID, Camera::USE_CALLING_PID);
} else {
jint status = Camera::connectLegacy(cameraId, halVersion, clientName,
Camera::USE_CALLING_UID, camera);
}
sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);//存副本
context->incStrong((void*)android_hardware_Camera_native_setup);
camera->setListener(context);
env->SetLongField(thiz, fields.context, (jlong)context.get()); //存上下文
CameraInfo cameraInfo;
status_t rc = Camera::getCameraInfo(cameraId, &cameraInfo); //获取相机信息
return NO_ERROR;
}
从拍照调用看JNI层
private native final void native_takePicture(int msgType);
调用Camera拍照
static void android_hardware_Camera_takePicture(JNIEnv *env, jobject thiz, jint msgType)
{
JNICameraContext* context;
sp<Camera> camera = get_native_camera(env, thiz, &context); //获取C++层的Camera
if (camera == 0) return;
if (camera->takePicture(msgType) != NO_ERROR) {//进行拍照
return;
}
}
2. Camera与CameraClient
不关心HAL版本,返回一个Camera实例
sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
int clientUid, int clientPid)
{ //CameraBaseT来自哪
return CameraBaseT::connect(cameraId, clientPackageName, clientUid, clientPid);
}
frameworks\av\camera\include\camera\CameraBase.h
typedef CameraBase<TCam> CameraBaseT; // what ? 哪来的 TCam
TCam来自于模板类声明
template <typename TCam>
struct CameraTraits { //啥都没有的结构体
};
template <typename TCam, typename TCamTraits = CameraTraits<TCam> >
class CameraBase : public IBinder::DeathRecipient { ...... }
frameworks\av\camera\include\camera\Camera.h
在Camera的头文件中,可以看出 TCam = Camera
template <>
struct CameraTraits<Camera>
{
typedef CameraListener TCamListener;
typedef ::android::hardware::ICamera TCamUser;
typedef ::android::hardware::ICameraClient TCamCallbacks;
typedef ::android::binder::Status(::android::hardware::ICameraService::*TCamConnectService)
(const sp<::android::hardware::ICameraClient>&,
int, const String16&, int, int,
/*out*/
sp<::android::hardware::ICamera>*);
static TCamConnectService fnConnectService;
};
class Camera :
public CameraBase<Camera>,
public ::android::hardware::BnCameraClient { ...... } //CameraClient的服务端
frameworks\av\camera\CameraBase.cpp
Camera的connect函数调用
template <typename TCam, typename TCamTraits>
sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,
const String16& clientPackageName,
int clientUid, int clientPid)
{
sp<TCam> c = new TCam(cameraId);
sp<TCamCallbacks> cl = c;
const sp<::android::hardware::ICameraService> cs = getCameraService(); //获取CameraService
binder::Status ret;
if (cs != nullptr) {
TCamConnectService fnConnectService = TCamTraits::fnConnectService;
ret = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,
clientPid, /*out*/ &c->mCamera);
}
......
return c;
}
frameworks\av\camera\Camera.cpp
我的天,我看到了什么,直接调用了CameraService的connect函数
CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService =
&::android::hardware::ICameraService::connect;
上一篇在CameraService执行connect函数时会执行makeclient(),此时会根据各参数返回不同类型的camera实例,让我们重温一下:
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) { //未指定特殊硬件抽象层版本
switch(deviceVersion) {
case CAMERA_DEVICE_API_VERSION_1_0: //版本 HAL v1.0
if (effectiveApiLevel == API_1) { //版本 API v1.0
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
//创建CameraClient实例
*client = new CameraClient(cameraService, tmp, packageName, cameraIdToInt(cameraId),
facing, clientPid, clientUid, getpid(), legacyMode);
}else { //版本 API v2.0
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: //版本 HAL3
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) { // 版本API1
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
*client = new Camera2Client(cameraService, tmp, packageName, cameraIdToInt(cameraId),
facing, clientPid, clientUid, servicePid, legacyMode);
} else { // 版本API2 最新版本
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 ......
}
} else { //指定了特殊硬件抽象层版本
// A particular HAL version is requested by caller. Create CameraClient
// based on the requested HAL version.
if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
// Only support higher HAL version device opened as HAL1.0 device.
sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
*client = new CameraClient(cameraService, tmp, packageName, cameraIdToInt(cameraId),
facing, clientPid, clientUid, servicePid, legacyMode);
} else {
// Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
" opened as HAL %x device", halVersion, deviceVersion,
CAMERA_DEVICE_API_VERSION_1_0);
return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
"Camera device \"%s\" (HAL version %d) cannot be opened as HAL version %d",
cameraId.string(), deviceVersion, halVersion);
}
}
return Status::ok();
}
根据判断我们来看 API v1.0和/版本HAL v1.0下的CameraClient
class CameraClient : public CameraService::Client { ...... }
Client继承了BnCamera,如此一来如架构图所述,Camera和CameraClient通过ICameraClient和ICamera跨进程通讯
class Client : public hardware::BnCamera, public BasicClient { ...... }
frameworks\av\services\camera\libcameraservice\api1\Camera2Client.h
那么在API v1.0和/版本HAL v3的Camera2Client 又是咋样的呢
class Camera2Client :
public Camera2ClientBase<CameraService::Client>
{
果不其然 Camera2Client 继承自 Camera2ClientBase 间接继承自 CameraService::Client
template <typename TClientBase>
class Camera2ClientBase :
public TClientBase,
public CameraDeviceBase::NotificationListener { ...... }
3. Camera硬件抽象层
frameworks\av\camera\Camera.cpp
// take a picture
status_t Camera::takePicture(int msgType)
{
ALOGV("takePicture: 0x%x", msgType);
sp <::android::hardware::ICamera> c = mCamera;
if (c == 0) return NO_INIT;
return c->takePicture(msgType);
}
frameworks\av\services\camera\libcameraservice\api1\CameraClient
// take a picture - image is returned in callback
status_t CameraClient::takePicture(int msgType) {
......
return mHardware->takePicture();
}
sp<CameraHardwareInterface> mHardware; // cleared after disconnect()
在makeclient的时候也进行了initialize
status_t CameraHardwareInterface::initialize(sp<CameraProviderManager> manager) {
//mHidlDevice将代表硬件Binder远程引用
status_t ret = manager->openSession(mName.string(), this, &mHidlDevice);
......
return ret;
}
//在头文件中存在申明 ICameraDevice 类型
sp<hardware::camera::device::V1_0::ICameraDevice> mHidlDevice;
hardware\interfaces\camera\device\1.0\default\CameraDevice_1_0.h
新Treble架构下的HAL顶层调用接口
struct CameraDevice : public ICameraDevice { ...... }
frameworks\av\services\camera\libcameraservice\api1\Camera2Client.cpp
我们来看看Camera2Client
status_t Camera2Client::initialize(sp<CameraProviderManager> manager) {
return initializeImpl(manager);
}
初始化StreamingProcessor
template<typename TProviderPtr>
status_t Camera2Client::initializeImpl(TProviderPtr providerPtr)
{
res = Camera2ClientBase::initialize(providerPtr);
......
mStreamingProcessor = new StreamingProcessor(this);
......
return OK;
}
frameworks\av\services\camera\libcameraservice\api1\client2\StreamingProcessor.cpp
mDevice被初始化
StreamingProcessor::StreamingProcessor(sp<Camera2Client> client):
mClient(client),
mDevice(client->getCameraDevice()), //初始化备
mId(client->getCameraId()),
mActiveRequest(NONE),
mPaused(false),
mPreviewRequestId(Camera2Client::kPreviewRequestIdStart),
mPreviewStreamId(NO_STREAM),
mRecordingRequestId(Camera2Client::kRecordingRequestIdStart),
mRecordingStreamId(NO_STREAM){ ...... }
从父类 Camera2ClientBase 中调用
template <typename TClientBase>
const sp<CameraDeviceBase>& Camera2ClientBase<TClientBase>::getCameraDevice() {
return mDevice;
}
那么 mDevice 哪里来的呢
template <typename TClientBase>
Camera2ClientBase<TClientBase>::Camera2ClientBase( ...... )
{
mInitialClientPid = clientPid;
mDevice = new Camera3Device(cameraId); //新建HAL3 Device
LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here.");
}
至此,Camera子系统整体框架分析到此结束,新老框架的交汇点是在CameraService的makeclient函数,在这里会根据传入的参数决定创建具体的硬件抽象层,可以说实现得十分精巧。关于Camera系统还有很多东西,不可能一蹴而就。在以后分析其他子系统或情景时再回过头来穿插,会理解得更深一点。