上一篇咱們從最新的Camera架構來分析Camera子系統,今天咱們將從全局的視角從舊版本到新版本架構總體通覽一遍,從Framework層的API(1和2)到硬件抽象層的HAL(1和3)。廢話少說一塊兒來看一下總體架構:java
從總體架構圖來看,上層API相互獨立,中間Camera庫耦合度低,HAL層構建合理;APIv1對應HAL1和HAL2。先後兩套API耦合度低,APIv2幾乎是重寫了整個結構。廢話少說咱們直接上代碼。android
1. Camera和JNICameraContext
frameworks\base\core\java\android\hardware\Camera.java
frameworks\base\core\jni\android_hardware_Camera.cppapi
建立相機時,執行相機初始化架構
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層ide
private native final void native_takePicture(int msgType);
1
調用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實例ui
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.hthis
typedef CameraBase<TCam> CameraBaseT; // what ? 哪來的 TCam
1
TCam來自於模板類聲明.net
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 { ...... }
1
Client繼承了BnCamera,如此一來如架構圖所述,Camera和CameraClient經過ICameraClient和ICamera跨進程通信
class Client : public hardware::BnCamera, public BasicClient { ...... }
1
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 { ...... }
1
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系統還有不少東西,不可能一蹴而就。在之後分析其餘子系統或情景時再回過頭來穿插,會理解得更深一點。 ———————————————— 版權聲明:本文爲CSDN博主「SherlockCharlie」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。 原文連接:https://blog.csdn.net/u013928208/article/details/82181786