Camera2 OpenCamera流程

文章目录

  • 1.CameraManager

  • 1.1 openCamera函数

  • 1.1.1 实现StateCallback 接口,当相机打开后会回调onOpened方法,在这个方法里面开启预览

  • 1.2 openCameraForUid()

  • 1.3 openCameraDeviceUserAsync()

  • 1.3.1 CameraDeviceImpl继承CameraDevice

  • 1.3.2 setRemoteDevice的实现

  • 1.3.3 ICameraDeviceUserWrapper

  • 1.3.4 获取当前cameraId指定相机的设备信息

  • 2. CameraService.cpp

  • 2.1 cameraService.connectDevice的实现

  • 2.2 CameraService::connectHelper 实现逻辑

  • 2.3 makeClient的实现

  • 3. CameraDeviceClient.cpp

  • 3.1 获得CameraDeviceClient之后进行initialize

  • 调用了Camera2ClientBase方法,实现代码如下:

  • 4. Camera3Device.cpp

  • 5. CameraProviderManager.cpp

  • 6. CameraDevice.cpp

  • 7. CameraModule.cpp

  • 8. CameraService

  • 9. CameraProviderManager.cpp

  • 9.1 CameraProviderManager初始化中做的事情很明了,这里我们需要关注的是addProviderLocked这里进行查找并保存Provider,实现如下:

  • 9.2这里需要关注 spprovider::V2_4::ICameraProvider interface这里的interface,最终指向了CameraProvider.cpp,不过我们需要先关注上面的构建和初始化providerInfo->initialize(),代码如下:

  • 9.3这里主要关注上面的添加设备这块儿

  • 9.4 实例化device代码如下:

  • 9.5 其中获取HAL远程接口代码如下:

  • 10. CameraProvider.cpp

  • CameraManagerGlobal.get().getCameraService()的实现

  • DeviceInfo3

  • mProviders添加的流程:

  • addDevice是如何工作的?

  • 总结:

参考链接:

Android P Camera2相机简单解析

Android 源码 Camera2 openCamera 流程分析

Android Camera 架构

[Android O] HAL3 之 Open Camera2 流程

Android P之Camera HAL3流程分析

转载 [Android O] HAL3 之 Open Camera2 流程

1.CameraManager

文件路径:framework\base\core\java\android\hardware\camera2\CameraManager.java

1.1 openCamera函数

CameraManager中两个openCamera(),一个Handler,一个Executor,Executor用于线程池来执行Camera中的耗时操作。

/*
* cameraId 是一个标识,标识当前要打开的camera;
* callback 是一个状态回调,当前camera被打开的时候,这个状态回调会被触发的;
* handler 是传入的一个执行耗时操作的handler;
*/@RequiresPermission(android.Manifest.permission.CAMERA)publicvoidopenCamera(@NonNullString cameraId,@NonNullfinalCameraDevice.StateCallback callback,@NullableHandler handler)throwsCameraAccessException{//openCameraForUid(cameraId, callback,CameraDeviceImpl.checkAndWrapHandler(handler),USE_CALLING_UID);}// Executor用于线程池来执行Camera中的耗时操作@RequiresPermission(android.Manifest.permission.CAMERA)publicvoidopenCamera(@NonNullString cameraId,@NonNull@CallbackExecutorExecutor executor,@NonNullfinalCameraDevice.StateCallback callback)throwsCameraAccessException{if(executor ==null){thrownewIllegalArgumentException("executor was null");}//openCameraForUid(cameraId, callback, executor, USE_CALLING_UID);}

1.1.1 实现StateCallback 接口,当相机打开后会回调onOpened方法,在这个方法里面开启预览

privatefinalCameraDevice.StateCallback mStateCallback =newCameraDevice.StateCallback(){@OverridepublicvoidonOpened(CameraDevice cameraDevice){int id =Integer.parseInt(cameraDevice.getId());Log.d(TAG,"onOpened "+ id);mCameraOpenCloseLock.release();mCameraDevice[id]= cameraDevice;mCameraOpened[id]=true;if(isBackCamera()&&getCameraMode()== DUAL_MODE && cameraId == BAYER_ID){Message msg = mCameraHandler.obtainMessage(OPEN_CAMERA, MONO_ID,0);mCameraHandler.sendMessage(msg);}else{mCamerasOpened =true;mActivity.runOnUiThread(newRunnable(){@Overridepublicvoidrun(){mUI.onCameraOpened(mCameraIdList);}});createSessions();}}@OverridepublicvoidonDisconnected(CameraDevice cameraDevice){int id =Integer.parseInt(cameraDevice.getId());Log.d(TAG,"onDisconnected "+ id);cameraDevice.close();mCameraDevice[id]=null;mCameraOpenCloseLock.release();mCamerasOpened =false;if(null!= mActivity){Toast.makeText(mActivity,"open camera error id ="+ id,Toast.LENGTH_LONG).show();mActivity.finish();}}@OverridepublicvoidonError(CameraDevice cameraDevice,int error){int id =Integer.parseInt(cameraDevice.getId());Log.e(TAG,"onError "+ id +" "+ error);if(mCamerasOpened){mCameraDevice[id].close();mCameraDevice[id]=null;}mCameraOpenCloseLock.release();mCamerasOpened =false;if(null!= mActivity){Toast.makeText(mActivity,"open camera error id ="+ id,Toast.LENGTH_LONG).show();mActivity.finish();}}@OverridepublicvoidonClosed(CameraDevice cameraDevice){int id =Integer.parseInt(cameraDevice.getId());Log.d(TAG,"onClosed "+ id);mCameraDevice[id]=null;clearBufferLostFrames();mCameraOpenCloseLock.release();mCamerasOpened =false;}};

1.2 openCameraForUid()

两种实际都是调用了 openCameraForUid(cameraId, callback, executor, USE_CALLING_UID)这个方法,

具体实现如下:

publicvoidopenCameraForUid(@NonNullString cameraId,@NonNullfinalCameraDevice.StateCallback callback,@NonNullExecutor executor,int clientUid)throwsCameraAccessException{if(cameraId ==null){thrownewIllegalArgumentException("cameraId was null");}elseif(callback ==null){thrownewIllegalArgumentException("callback was null");}if(CameraManagerGlobal.sCameraServiceDisabled){thrownewIllegalArgumentException("No cameras available on device");}//openCameraDeviceUserAsync(cameraId, callback, executor, clientUid);}

1.3 openCameraDeviceUserAsync()

这里做了容错性判断,紧接着调用了 openCameraDeviceUserAsync(cameraId, callback, executor, clientUid),

返回值是CameraDevice,CameraDevice是抽象类,CameraDeviceImpl是其实现类,就是要获取CameraDeviceImpl的实例。

这个函数的主要作用就是到底层获取相机设备的信息,并获取当前指定cameraId的设备实例。

本函数的主要工作可以分为下面五点:

  • 获取当前cameraId指定相机的设备信息

  • 利用获取相机的设备信息创建CameraDeviceImpl实例

  • 调用远程CameraService获取当前相机的远程服务

  • 将获取的远程服务设置到CameraDeviceImpl实例中

  • 返回CameraDeviceImpl实例
    此方法的实现如下:

privateCameraDeviceopenCameraDeviceUserAsync(String cameraId,CameraDevice.StateCallback callback,Executor executor,finalint uid)throwsCameraAccessException{//getCameraCharacteristics 获取camera的一些特征CameraCharacteristics characteristics =getCameraCharacteristics(cameraId);CameraDevice device =null;synchronized(mLock){ICameraDeviceUser cameraUser =null;// 创建CameraDeviceImpl实例,返回给应用端的相机对象android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =newandroid.hardware.camera2.impl.CameraDeviceImpl(cameraId,callback,executor,characteristics,mContext.getApplicationInfo().targetSdkVersion);// 通过将ICameraDeviceCallbacks 设置到cameraservice中来获取回调.ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();try{if(supportsCamera2ApiLocked(cameraId)){// 获取Framework层CameraServer的服务代理ICameraService cameraService =CameraManagerGlobal.get().getCameraService();if(cameraService ==null){thrownewServiceSpecificException(ICameraService.ERROR_DISCONNECTED,"Camera service is currently unavailable");}/*通过cameraService跨进程获得BpCameraDeviceUser对象,连接到相机设备,返回得到远端CameraDeviceClient的本地接口*/cameraUser = cameraService.connectDevice(callbacks, cameraId,mContext.getOpPackageName(), uid);}else{// Use legacy camera implementation for HAL1 devicesint id;try{id =Integer.parseInt(cameraId);}catch(NumberFormatException e){thrownewIllegalArgumentException("Expected cameraId to be numeric, but it was: "+ cameraId);}Log.i(TAG,"Using legacy camera HAL.");cameraUser =CameraDeviceUserShim.connectBinderShim(callbacks, id,getDisplaySize());}}catch(ServiceSpecificException e){}catch(RemoteException e){}/*将CameraDeviceClient本地代理cameraUser设置到CameraDeviceImpl中进行管理,CameraDeviceImpl中的mRemoteDevice由该cameraUsr包装而来*/deviceImpl.setRemoteDevice(cameraUser);device = deviceImpl;}return device;}

这里主要关注上面的代码中的cameraService.connectDevice,这仅仅是Connect到我们的Camera设备,并不能打开我们的Camera,所以ICameraDeviceUser cameraUser = null和deviceImpl.setRemoteDevice(cameraUser)也是非常重要的,这里对应了CameraDeviceImpl .java文件。但是这里我们还是先看cameraService.connectDevice实现,实际上是ICameraService.connectDevice,这里需要注意的是ICameraService实际上是aidl文件,也是就是说CameraManager通过通过 Binder 机制调用了 connectDevice 方法,这个connectDevice方法的实现在CameraService 中。

1.3.1 CameraDeviceImpl继承CameraDevice

publicclassCameraDeviceImplextendsCameraDevicepublicCameraDeviceImpl(String cameraId,StateCallback callback,Executor executor,CameraCharacteristics characteristics,int appTargetSdkVersion){mCameraId = cameraId;//在 mCallOnOpened.run()中用到mDeviceCallback = callback;mDeviceExecutor = executor;}}

1.3.2 setRemoteDevice的实现

frameworks/base/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java

privateICameraDeviceUserWrapper mRemoteDevice;publicvoidsetRemoteDevice(ICameraDeviceUser remoteDevice)throwsCameraAccessException{synchronized(mInterfaceLock){mRemoteDevice =newICameraDeviceUserWrapper(remoteDevice);mDeviceExecutor.execute(mCallOnOpened);mDeviceExecutor.execute(mCallOnUnconfigured);}}privatefinalRunnable mCallOnOpened =newRunnable(){publicvoidrun(){sessionCallback = mSessionStateCallback;sessionCallback.onOpened(CameraDeviceImpl.this);//通知相机应用设备已打开,并且返回CameraDeviceImpl对象,相机应用已实现该函数mDeviceCallback.onOpened(CameraDeviceImpl.this);}};

1.3.3 ICameraDeviceUserWrapper

frameworks/base/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java

publicICameraDeviceUserWrapper(ICameraDeviceUser remoteDevice){mRemoteDevice = remoteDevice;}

通过以上流程,相机应用获得了CameraDevice对象,而CameraDevice保存ICameraDeviceUserWrapper对象,ICameraDeviceUserWrapper保存BpCameraDeviceUser对象,BpCameraDeviceUser具有跨进程的能力,这样应用就可以和CameraService端的CameraDeviceClient进行通信了。

1.3.4 获取当前cameraId指定相机的设备信息

CameraCharacteristics getCameraCharacteristics(@NonNull String cameraId)

一句简单的调用,返回值是CameraCharacteristics,CameraCharacteristics提供了CameraDevice的各种属性,可以通过getCameraCharacteristics函数来查询。

@NonNullpublicCameraCharacteristicsgetCameraCharacteristics(@NonNullString cameraId)throwsCameraAccessException{CameraCharacteristics characteristics =null;if(CameraManagerGlobal.sCameraServiceDisabled){thrownewIllegalArgumentException("No cameras available on device");}synchronized(mLock){/** Get the camera characteristics from the camera service directly if it supports it,* otherwise get them from the legacy shim instead.*/ICameraService cameraService =CameraManagerGlobal.get().getCameraService();if(cameraService ==null){thrownewCameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,"Camera service is currently unavailable");}try{Size displaySize =getDisplaySize();// First check isHiddenPhysicalCamera to avoid supportsCamera2ApiLocked throwing// exception in case cameraId is a hidden physical camera.if(!isHiddenPhysicalCamera(cameraId)&&!supportsCamera2ApiLocked(cameraId)){// Legacy backwards compatibility path; build static info from the camera// parametersint id =Integer.parseInt(cameraId);String parameters = cameraService.getLegacyParameters(id);CameraInfo info = cameraService.getCameraInfo(id);characteristics =LegacyMetadataMapper.createCharacteristics(parameters, info,id, displaySize);}else{/*通过binder调用到 CameraService.cpp 的getCameraCharacteristics函数,直接从相机服务获取相机特性.*/CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId);try{info.setCameraId(Integer.parseInt(cameraId));}catch(NumberFormatException e){Log.e(TAG,"Failed to parse camera Id "+ cameraId +" to integer");}info.setDisplaySize(displaySize);// 构造特征characteristics =newCameraCharacteristics(info);}}catch(ServiceSpecificException e){throwAsPublicException(e);}catch(RemoteException e){// Camera service died - act as if the camera was disconnectedthrownewCameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,"Camera service is currently unavailable", e);}}return characteristics;}

ICameraService cameraService = CameraManagerGlobal.get().getCameraService();

调用的CameraService对应的是ICameraService.aidl,对应的实现类在frameworks/av/services/camera/libcameraservice/CameraService.h

下面是CameraManager与CameraService之间的连接关系图示:

2. CameraService.cpp

文件路径:/frameworks/av/services/camera/libcameraservice/CameraService.cpp

2.1 cameraService.connectDevice的实现

跨进程调用CameraManager->CameraService,返回CameraDeviceClient,将应用端的回调函数设置给cameraService。

Status CameraService::connectDevice(const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,const String16& cameraId,const String16& clientPackageName,int clientUid,/*out*/sp<hardware::camera2::ICameraDeviceUser>* device){sp<CameraDeviceClient> client =nullptr;//调用了connectHelper来实现连接相机的逻辑ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,/*api1CameraId*/-1,CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName,clientUid, USE_CALLING_PID, API_2,/*legacyMode*/false,/*shimUpdateOnly*/false,/*out*/client);// device指针会在BnCameraService中将其打包为ICamraDeviceUser对象写到binder reply中返回*device = client;// client = CameraDeviceClientreturn ret;}

2.2 CameraService::connectHelper 实现逻辑

template<classCALLBACK,classCLIENT>
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb,const String8& cameraId,int api1CameraId,int halVersion,const String16& clientPackageName,int clientUid,int clientPid, apiLevel effectiveApiLevel,bool legacyMode,bool shimUpdateOnly,/*out*/sp<CLIENT>& device){if(!(ret =makeClient(this, cameraCb, clientPackageName,cameraId, api1CameraId, facing,clientPid, clientUid,getpid(), legacyMode,halVersion, deviceVersion, effectiveApiLevel,/*out*/&tmp)).isOk()){return ret;}//转换BasicClient类型为CLIENT=CameraDeviceClientclient =static_cast<CLIENT*>(tmp.get());//初始化CameraDeviceClient对象err = client->initialize(mCameraProviderManager, mMonitorTags);device = client;}

2.3 makeClient的实现

在connectHelper中我们通过makeClient方法完成了client的生成并初始化,具体实现如下:

StatusCameraService::makeClient(const sp<CameraService>& cameraService,const sp<IInterface>& cameraCb,constString16& packageName,constString8& cameraId,int api1CameraId,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_3_4:if(effectiveApiLevel == API_1){// Camera1 API routesp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());*client =newCamera2Client(cameraService, tmp, packageName,cameraId, api1CameraId,facing, clientPid, clientUid,servicePid, legacyMode);}else{// Camera2 API routesp<hardware::camera2::ICameraDeviceCallbacks> tmp =static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());*client =newCameraDeviceClient(cameraService, tmp, packageName, cameraId,facing, clientPid, clientUid, servicePid);}break;}}}

这一块儿基本就是根据API版本和Device版本来实例化Client的,在Android P 和Camera2的框架上,这里CameraDeviceClient方法是由CameraDeviceClient.cpp实现的。

3. CameraDeviceClient.cpp

文件路径:frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp

CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,constString16& clientPackageName,constString8& cameraId,int cameraFacing,int clientPid,uid_t clientUid,int servicePid):Camera2ClientBase(cameraService, remoteCallback, clientPackageName,cameraId,/*API1 camera ID*/-1,cameraFacing, clientPid, clientUid, servicePid),mInputStream(),mStreamingRequestId(REQUEST_ID_NONE),mRequestIdCounter(0),mPrivilegedClient(false){char value[PROPERTY_VALUE_MAX];property_get("persist.vendor.camera.privapp.list", value,"");String16packagelist(value);if(packagelist.contains(clientPackageName.string())){mPrivilegedClient =true;}ATRACE_CALL();ALOGI("CameraDeviceClient %s: Opened", cameraId.string());}

3.1 获得CameraDeviceClient之后进行initialize

status_t CameraDeviceClient::initialize(sp<CameraProviderManager> manager,constString8& monitorTags){returninitializeImpl(manager, monitorTags);}//调用父类函数,CameraDeviceClient继承Camera2ClientBase,初始化时会创建Camera3Device对象Camera2ClientBase<TClientBase>::Camera2ClientBase(){mInitialClientPid = clientPid;mDevice =newCamera3Device(cameraId);}
status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr,constString8& monitorTags){res =Camera2ClientBase::initialize(providerPtr, monitorTags);//处理图像帧的实例mFrameProcessor =newFrameProcessorBase(mDevice);//进入一个线程循环处理图像帧mFrameProcessor->run(threadName.string());mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,FRAME_PROCESSOR_LISTENER_MAX_ID,/*listener*/this,/*sendPartials*/true);}

调用了Camera2ClientBase方法,实现代码如下:

frameworks/av/services/camera/libcameraservice/common/Camera2ClientBase.cpp

status_t Camera2ClientBase<TClientBase>::initialize(sp<CameraProviderManager> manager,const String8& monitorTags){returninitializeImpl(manager, monitorTags);}
status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr,const String8& monitorTags){status_t res;res =TClientBase::startCameraOps();//初始化Camera3Device,mDevice 实际上是Camera3Deviceres = mDevice->initialize(providerPtr, monitorTags);wp<CameraDeviceBase::NotificationListener>weakThis(this);res = mDevice->setNotifyCallback(weakThis);return OK;}

mDevice = new Camera3Device(cameraId)才是重点,是由Camera3Device.cpp实现的。

4. Camera3Device.cpp

文件路径:/frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp

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),mLastTemplateId(-1){ATRACE_CALL();camera3_callback_ops::notify =&sNotify;camera3_callback_ops::process_capture_result =&sProcessCaptureResult;ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());}

到此CameraService.cpp中的makeClient工作就已经完成了并构造了"CameraDeviceClient"

接下来就是connectHelper中的client->initialize这块儿了,从上面分析我们知道这里的client 指的对象就是Camera3Device了,所以我们继续找到Camera3Device中的initialize方法,代码如下:

status_t Camera3Device::initialize(sp<CameraProviderManager> manager,const String8& monitorTags){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;// manager 的 类型是 class CameraProviderManager, this = Camera3Device 对象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;}res = manager->getCameraCharacteristics(mId.string(),&mDeviceInfo);if(res != OK){SET_ERR_L("Could not retrive camera characteristics: %s (%d)",strerror(-res), res);session->close();return res;}std::shared_ptr<RequestMetadataQueue> queue;auto requestQueueRet = session->getCaptureRequestMetadataQueue([&queue](constauto& descriptor){queue = std::make_shared<RequestMetadataQueue>(descriptor);if(!queue->isValid()|| queue->availableToWrite()<=0){ALOGE("HAL returns empty request metadata fmq, not use it");queue =nullptr;// don't use the queue onwards.}});if(!requestQueueRet.isOk()){ALOGE("Transaction error when getting request metadata fmq: %s, not use it",requestQueueRet.description().c_str());return DEAD_OBJECT;}std::unique_ptr<ResultMetadataQueue>& resQueue = mResultMetadataQueue;auto resultQueueRet = session->getCaptureResultMetadataQueue([&resQueue](constauto& descriptor){//这其实是在匿名回调函数里面resQueue = std::make_unique<ResultMetadataQueue>(descriptor);if(!resQueue->isValid()|| resQueue->availableToWrite()<=0){ALOGE("HAL returns empty result metadata fmq, not use it");resQueue =nullptr;// Don't use the resQueue onwards.}});if(!resultQueueRet.isOk()){ALOGE("Transaction error when getting result metadata queue from camera session: %s",resultQueueRet.description().c_str());return DEAD_OBJECT;}IF_ALOGV(){session->interfaceChain([](::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain){ALOGV("Session interface chain:");for(auto iface : interfaceChain){ALOGV("  %s", iface.c_str());}});}mInterface =newHalInterface(session, queue);//新建硬件抽象层接口实例std::string providerType;mVendorTagId = manager->getProviderTagIdLocked(mId.string());mTagMonitor.initialize(mVendorTagId);if(!monitorTags.isEmpty()){mTagMonitor.parseTagsToMonitor(String8(monitorTags));}returninitializeCommonLocked();}

res = manager->openSession 就是走向open的地方了,但是还是需要继续到一个方法,不难发现openSession方法由CameraProviderManager.cpp实现。此外在这里我们还需要注意

  1. auto requestQueueRet = session->getCaptureRequestMetadataQueue(

  1. auto resultQueueRet = session->getCaptureResultMetadataQueue(
    是请求队列,2中的resultQueueRet 是结果队列在下一篇中将使用到。

5. CameraProviderManager.cpp

文件路径:/frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp

具体代码如下:

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 对象,参考下面module 与 CameraDevice 相关ret = deviceInfo3->mInterface->open(callback,[&status,&session](Status s,const sp<device::V3_2::ICameraDeviceSession>& cameraSession){status = s;if(status == Status::OK){//返回session, 这个session由CameraDeviceSession::getInterface() 得到*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;}returnmapToStatusT(status);}

ret = deviceInfo3->mInterface->open 实际上通过Hidl指向了CameraDevice::open(),该方法由CameraDevice.cpp实现。

6. CameraDevice.cpp

文件路径:***/hardware/interfaces/camera/device/3.2/default/CameraDevice.cpp***

代码如下:

//V3_2::implementation::CameraDevice
Return<void>CameraDevice::open(const sp<ICameraDeviceCallback>& callback, open_cb _hidl_cb){Status status =initStatus();//注意 CameraDeviceSession::processCaptureRequest() 这个函数。device 由hal层的open()得到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);returnVoid();}if(status != Status::OK){// Provider will never pass initFailed device to client, so// this must be a disconnected cameraALOGE("%s: cannot open camera %s. camera is disconnected!",__FUNCTION__, mCameraId.c_str());_hidl_cb(Status::CAMERA_DISCONNECTED,nullptr);returnVoid();}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);returnVoid();}/** Open HAL device */status_t res;camera3_device_t *device;ATRACE_BEGIN("camera3->open");//调用hal的open函数,得到 deviceres = 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);returnVoid();}/** 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);returnVoid();}structcamera_info info;//调用hal的get_camera_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);returnVoid();}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);returnVoid();}if(session->isInitFailed()){ALOGE("%s: camera device session init failed", __FUNCTION__);session =nullptr;mLock.unlock();_hidl_cb(Status::INTERNAL_ERROR,nullptr);returnVoid();}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();}//这个回调函数在deviceInfo3->mInterface->open(...)外面套着,在 CameraProviderManager.cpp 文件中_hidl_cb(status, session->getInterface());returnVoid();}

res = mModule->open(mCameraId.c_str(), reinterpret_cast<hw_device_t**>(&device))为打开Camera的地方,但是这里还需要继续跟下去,指向了CameraModule.cpp中实现的open方法。

7. CameraModule.cpp

文件路径:***/hardware/interfaces/camera/common/1.0/default/CameraModule.cpp***

代码如下:

intCameraModule::open(constchar* id,structhw_device_t** device){int res;ATRACE_BEGIN("camera_module->open");res =filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device));ATRACE_END();return res;}

不难发现,mModule->common.methods->open紧接着就是Hal层了,在这里我们需要先把Hal层启动流程弄清楚。在系统启动后,CameraService服务跑起来就是就会启动Hal层。

8. CameraService

文件路径:***/frameworks/av/services/camera/libcameraservice/CameraService.cpp***

代码如下:

voidCameraService::onFirstRef(){ALOGI("CameraService process starting");BnCameraService::onFirstRef();// Update battery life tracking if service is restartingBatteryNotifier&notifier(BatteryNotifier::getInstance());notifier.noteResetCamera();notifier.noteResetFlashlight();status_t res = INVALID_OPERATION;res =enumerateProviders();if(res == OK){mInitialized =true;}CameraService::pingCameraServiceProxy();mUidPolicy =newUidPolicy(this);mUidPolicy->registerSelf();}

res = enumerateProviders()说明CameraService在初始化时,要先枚举Provider,实现代码如下:

status_t CameraService::enumerateProviders(){status_t res;std::vector<std::string> deviceIds;{Mutex::Autolock l(mServiceLock);if(nullptr== mCameraProviderManager.get()){mCameraProviderManager =newCameraProviderManager();// mCameraProviderManager 很关键,在CameraService::enumerateProviders()中设置res = mCameraProviderManager->initialize(this);if(res != OK){ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",__FUNCTION__,strerror(-res), res);return res;}}// Setup vendor tags before we call get_camera_info the first time// because HAL might need to setup static vendor keys in get_camera_info// TODO: maybe put this into CameraProviderManager::initialize()?mCameraProviderManager->setUpVendorTags();if(nullptr== mFlashlight.get()){mFlashlight =newCameraFlashlight(mCameraProviderManager,this);}res = mFlashlight->findFlashUnits();if(res != OK){ALOGE("Failed to enumerate flash units: %s (%d)",strerror(-res), res);}deviceIds = mCameraProviderManager->getCameraDeviceIds();}for(auto& cameraId : deviceIds){String8 id8 =String8(cameraId.c_str());onDeviceStatusChanged(id8, CameraDeviceStatus::PRESENT);}return OK;}

这里又先初始化CameraProviderManager,并获取第三方厂家TAG,获取闪光灯,获取相机设备数,其中CameraProviderManager的初始化实现如下。

9. CameraProviderManager.cpp

文件路径:***/frameworks/av/services/camera/libcameraservice/common/CameraProviderManager.cpp***

具体代码如下:

status_t CameraProviderManager::initialize(wp<CameraProviderManager::StatusListener> listener,ServiceInteractionProxy* proxy){std::lock_guard<std::mutex>lock(mInterfaceMutex);if(proxy ==nullptr){ALOGE("%s: No valid service interaction proxy provided", __FUNCTION__);return BAD_VALUE;}mListener = listener;mServiceProxy = proxy;// Registering will trigger notifications for all already-known providersbool success = mServiceProxy->registerForNotifications(/* instance name, empty means no filter */"",this);if(!success){ALOGE("%s: Unable to register with hardware service manager for notifications ""about camera providers", __FUNCTION__);return INVALID_OPERATION;}// See if there's a passthrough HAL, but let's not complain if there's notaddProviderLocked(kLegacyProviderName,/*expected*/false);addProviderLocked(kExternalProviderName,/*expected*/false);return OK;}

9.1 CameraProviderManager初始化中做的事情很明了,这里我们需要关注的是addProviderLocked这里进行查找并保存Provider,实现如下:

status_t CameraProviderManager::addProviderLocked(const std::string& newProvider,bool expected){//轮循 mProviders, 这个很关键,看下面 mProviders 相关for(constauto& providerInfo : mProviders){if(providerInfo->mProviderName == newProvider){ALOGW("%s: Camera provider HAL with name '%s' already registered", __FUNCTION__,newProvider.c_str());return ALREADY_EXISTS;}}sp<provider::V2_4::ICameraProvider> interface;interface = mServiceProxy->getService(newProvider);//获取服务if(interface ==nullptr){if(expected){ALOGE("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,newProvider.c_str());return BAD_VALUE;}else{return OK;}}sp<ProviderInfo> providerInfo =newProviderInfo(newProvider, interface,this);//构建status_t res = providerInfo->initialize();//初始化if(res != OK){return res;}mProviders.push_back(providerInfo);//备份return OK;}

9.2这里需要关注 spprovider::V2_4::ICameraProvider interface这里的interface,最终指向了CameraProvider.cpp,不过我们需要先关注上面的构建和初始化providerInfo->initialize(),代码如下:

status_t CameraProviderManager::ProviderInfo::initialize(){status_t res =parseProviderName(mProviderName,&mType,&mId);if(res != OK){ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);return BAD_VALUE;}ALOGI("Connecting to new camera provider: %s, isRemote? %d",mProviderName.c_str(), mInterface->isRemote());// cameraDeviceStatusChange callbacks may be called (and causing new devices added)// before setCallback returnshardware::Return<Status> status = mInterface->setCallback(this);if(!status.isOk()){ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",__FUNCTION__, mProviderName.c_str(), status.description().c_str());return DEAD_OBJECT;}if(status != Status::OK){ALOGE("%s: Unable to register callbacks with camera provider '%s'",__FUNCTION__, mProviderName.c_str());returnmapToStatusT(status);}hardware::Return<bool> linked = mInterface->linkToDeath(this,/*cookie*/ mId);if(!linked.isOk()){ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",__FUNCTION__, mProviderName.c_str(), linked.description().c_str());return DEAD_OBJECT;}elseif(!linked){ALOGW("%s: Unable to link to provider '%s' death notifications",__FUNCTION__, mProviderName.c_str());}// Get initial list of camera devices, if anystd::vector<std::string> devices;hardware::Return<void> ret = mInterface->getCameraIdList([&status,&devices](Status idStatus,const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames){status = idStatus;if(status == Status::OK){for(size_t i =0; i < cameraDeviceNames.size(); i++){devices.push_back(cameraDeviceNames[i]);}}});if(!ret.isOk()){ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",__FUNCTION__, mProviderName.c_str(), linked.description().c_str());return DEAD_OBJECT;}if(status != Status::OK){ALOGE("%s: Unable to query for camera devices from provider '%s'",__FUNCTION__, mProviderName.c_str());returnmapToStatusT(status);}sp<StatusListener> listener = mManager->getStatusListener();for(auto& device : devices){std::string id;status_t res =addDevice(device,hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT,&id);//添加deviceif(res != OK){ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",__FUNCTION__, device.c_str(),strerror(-res), res);continue;}}ALOGI("Camera provider %s ready with %zu camera devices",mProviderName.c_str(), mDevices.size());mInitialized =true;return OK;}

9.3这里主要关注上面的添加设备这块儿

status_t CameraProviderManager::ProviderInfo::addDevice(const std::string& name,CameraDeviceStatus initialStatus,/*out*/ std::string* parsedId){ALOGI("Enumerating new camera device: %s", name.c_str());uint16_t major, minor;std::string type, id;status_t res =parseDeviceName(name,&major,&minor,&type,&id);if(res != OK){return res;}if(type != mType){ALOGE("%s: Device type %s does not match provider type %s", __FUNCTION__,type.c_str(), mType.c_str());return BAD_VALUE;}if(mManager->isValidDeviceLocked(id, major)){ALOGE("%s: Device %s: ID %s is already in use for device major version %d", __FUNCTION__,name.c_str(), id.c_str(), major);return BAD_VALUE;}std::unique_ptr<DeviceInfo> deviceInfo;switch(major){//实例化case1:deviceInfo = initializeDeviceInfo<DeviceInfo1>(name, mProviderTagid,id, minor);break;case3:deviceInfo = initializeDeviceInfo<DeviceInfo3>(name, mProviderTagid,id, minor);break;default:ALOGE("%s: Device %s: Unknown HIDL device HAL major version %d:", __FUNCTION__,name.c_str(), major);return BAD_VALUE;}if(deviceInfo ==nullptr)return BAD_VALUE;deviceInfo->mStatus = initialStatus;bool isAPI1Compatible = deviceInfo->isAPI1Compatible();mDevices.push_back(std::move(deviceInfo));mUniqueCameraIds.insert(id);if(isAPI1Compatible){mUniqueAPI1CompatibleCameraIds.push_back(id);}if(parsedId !=nullptr){*parsedId = id;}return OK;}

9.4 实例化device代码如下:

template<classDeviceInfoT>
std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>CameraProviderManager::ProviderInfo::initializeDeviceInfo(const std::string &name,const metadata_vendor_id_t tagId,const std::string &id,uint16_t minorVersion)const{Status status;auto cameraInterface =getDeviceInterface<typenameDeviceInfoT::InterfaceT>(name);//获取HAL层远程接口if(cameraInterface ==nullptr)returnnullptr;CameraResourceCost resourceCost;cameraInterface->getResourceCost([&status,&resourceCost](Status s, CameraResourceCost cost){status = s;resourceCost = cost;});if(status != Status::OK){ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__,name.c_str(),statusToString(status));returnnullptr;}for(auto& conflictName : resourceCost.conflictingDevices){uint16_t major, minor;std::string type, id;status_t res =parseDeviceName(conflictName,&major,&minor,&type,&id);if(res != OK){ALOGE("%s: Failed to parse conflicting device %s", __FUNCTION__, conflictName.c_str());returnnullptr;}conflictName = id;}return std::unique_ptr<DeviceInfo>(newDeviceInfoT(name, tagId, id, minorVersion, resourceCost,cameraInterface));}

9.5 其中获取HAL远程接口代码如下:

template<>
sp<device::V3_2::ICameraDevice>
CameraProviderManager::ProviderInfo::getDeviceInterface<device::V3_2::ICameraDevice>(const std::string &name)const{Status status;sp<device::V3_2::ICameraDevice> cameraInterface;hardware::Return<void> ret;ret = mInterface->getCameraDeviceInterface_V3_x(name,[&status,&cameraInterface](Status s, sp<device::V3_2::ICameraDevice> interface){status = s;cameraInterface = interface;});if(!ret.isOk()){ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",__FUNCTION__, name.c_str(), ret.description().c_str());returnnullptr;}if(status != Status::OK){ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,name.c_str(),statusToString(status));returnnullptr;}return cameraInterface;}

到了这里,可以看出ICameraDevice关联到了CameraDevice.cpp,那么providerInfo->initialize()就分析得差不多了,下面的就到了硬件层,回头来我们需要继续分析CameraProvider.cpp这里了,在这里就关注其初始化就可以了。

10. CameraProvider.cpp

文件路径:***/hardware/interfaces/camera/provider/2.4/default/CameraProvider.cpp***

代码如下:

boolCameraProvider::initialize(){camera_module_t *rawModule;int err =hw_get_module(CAMERA_HARDWARE_MODULE_ID,(const hw_module_t **)&rawModule);if(err <0){ALOGE("Could not load camera HAL module: %d (%s)", err,strerror(-err));returntrue;}mModule =newCameraModule(rawModule);err = mModule->init();if(err != OK){ALOGE("Could not initialize camera HAL module: %d (%s)", err,strerror(-err));mModule.clear();returntrue;}ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());// Setup vendor tags here so HAL can setup vendor keys in camera characteristicsVendorTagDescriptor::clearGlobalVendorTagDescriptor();if(!setUpVendorTags()){ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);}// Setup callback now because we are going to try openLegacy nexterr = mModule->setCallbacks(this);if(err != OK){ALOGE("Could not set camera module callback: %d (%s)", err,strerror(-err));mModule.clear();returntrue;}mPreferredHal3MinorVersion =property_get_int32("ro.vendor.camera.wrapper.hal3TrebleMinorVersion",3);ALOGV("Preferred HAL 3 minor version is %d", mPreferredHal3MinorVersion);switch(mPreferredHal3MinorVersion){case2:case3:// OKbreak;default:ALOGW("Unknown minor camera device HAL version %d in property ""'camera.wrapper.hal3TrebleMinorVersion', defaulting to 3",mPreferredHal3MinorVersion);mPreferredHal3MinorVersion =3;}mNumberOfLegacyCameras = mModule->getNumberOfCameras();for(int i =0; i < mNumberOfLegacyCameras; i++){structcamera_info info;auto rc = mModule->getCameraInfo(i,&info);if(rc != NO_ERROR){ALOGE("%s: Camera info query failed!",__func__);mModule.clear();returntrue;}if(checkCameraVersion(i, info)!= OK){ALOGE("%s: Camera version check failed!",__func__);mModule.clear();returntrue;}char cameraId[kMaxCameraIdLen];snprintf(cameraId,sizeof(cameraId),"%d", i);std::string cameraIdStr(cameraId);mCameraStatusMap[cameraIdStr]= CAMERA_DEVICE_STATUS_PRESENT;addDeviceNames(i);}returnfalse;// mInitFailed}

这里就初始化了CameraMoudle。

CameraManagerGlobal.get().getCameraService()的实现

通过ServiceManager获的cameraService,CameraManager通过CameraManagerGlobal访问CameraService服务,并注册监听,CamreaService持有CameraServiceListener列表,并回调结果给CameraManager。

frameworks/base/core/java/android/hardware/camera2/CameraManager.java
privatestaticfinalclassCameraManagerGlobalextendsICameraServiceListener.Stub{publicICameraServicegetCameraService(){//连接服务connectCameraServiceLocked();return mCameraService;}}privatevoidconnectCameraServiceLocked(){//查询服务引用,CAMERA_SERVICE_BINDER_NAME="media.camera"IBinder cameraServiceBinder =ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME);//转换服务接口ICameraService cameraService =ICameraService.Stub.asInterface(cameraServiceBinder);//注册回调监听,camerService可以通知CameraManagerGlobal状态变化CameraStatus[] cameraStatuses = cameraService.addListener(this);//存副本mCameraService = cameraService;}
frameworks/av/services/camera/libcameraservice/CameraService.h
staticcharconst*getServiceName(){return"media.camera";}

采用camera2 api来获取相机设备的信息。

// Normal path: Get the camera characteristics directly from the camera serviceCameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId);try{info.setCameraId(Integer.parseInt(cameraId));}catch(NumberFormatException e){Log.e(TAG,"Failed to parse camera Id "+ cameraId +" to integer");}
info.setDisplaySize(displaySize);characteristics =newCameraCharacteristics(info);

DeviceInfo3

framework\av\services\camera\libcameraservice\common\CameraProviderManager.h

接下来分析Camera3Device的初始化,Camera3Device通过CameraService保存的CameraProviderManager对象获得mProviders,调用流程mProviders->DeviceInfo->CameraDevice3Impl->CameraDevice3SessionImpl,最终获得CameraDevice3SessionImpl对象,其中CameraDevice3Impl和CameraDevice3SessionImpl由厂商来实现。

DeviceInfo3是CameraProviderManager::ProviderInfo::DeviceInfo3,CameraProviderManager中的结构体,最终返回的是CameraMetadata类型,它是一个Parcelable类型,native中对应的代码是frameworks/av/camera/include/camera/CameraMetadata.h,java中对应的是frameworks/base/core/java/android/hardware/camera2/impl/CameraMetadataNative.java,Parcelable类型是可以跨进程传输的。下面是在native中定义CameraMetadata为CameraMetadataNative

framework\av\camera\include\camera\CameraMetadata.h

namespace hardware {namespace camera2 {namespace impl {using::android::CameraMetadata;typedef CameraMetadata CameraMetadataNative;}}}

framework\av\services\camera\libcameraservice\device3\Camera3Device.cpp

1.获取ICameraDeviceSession实例

sp session;

status_t res = manager->openSession(mld.string,this,&session);

2.获取RequestMetadataQueue>类型的queuemession->getCaptureRequestMetdataQueue([&queue])

3.创建HalInterface实例mInterface = new HalInterface(session,queue);

4.Common初始化initializeCommonLocked();

status_t Camera3Device::initialize(sp<CameraProviderManager> manager,const String8& monitorTags){sp<ICameraDeviceSession> session;//通过CameraProviderManager打开对应的会话,this为ICameraDeviceCallback类型status_t res = manager->openSession(mId.string(),this,/*out*/&session);//获得请求队列std::shared_ptr<RequestMetadataQueue> queue;//CameraDeviceSession::getCaptureRequestMetadataQueue()auto requestQueueRet = session->getCaptureRequestMetadataQueue([&queue](constauto& descriptor){queue = std::make_shared<RequestMetadataQueue>(descriptor);if(!queue->isValid()|| queue->availableToWrite()<=0){queue =nullptr;}});//获得结果队列,最终保存在mResultMetadataQueue对象中。std::unique_ptr<ResultMetadataQueue>& resQueue = mResultMetadataQueue;auto resultQueueRet = session->getCaptureResultMetadataQueue([&resQueue](constauto& descriptor){resQueue = std::make_unique<ResultMetadataQueue>(descriptor);});//封装CameraDevice3SessionImpl对象,包括请求队列mInterface =newHalInterface(session, queue);}

我们关注其中的一个调用函数:

framework\av\services\camera\libcameraservice\common\CameraProviderManager.cpp

status_t CameraProviderManager::getCameraCharacteristicsLocked(const std::string &id,CameraMetadata* characteristics)const{auto deviceInfo =findDeviceInfoLocked(id,/*minVersion*/{3,0},/*maxVersion*/{5,0});if(deviceInfo !=nullptr){return deviceInfo->getCameraCharacteristics(characteristics);}// 找到隐藏的物理相机特征//mDevices 在 addDevice 中设置for(auto& provider : mProviders){for(auto& deviceInfo : provider->mDevices){status_t res = deviceInfo->getPhysicalCameraCharacteristics(id, characteristics);if(res != NAME_NOT_FOUND)return res;}}return NAME_NOT_FOUND;}

发现了调用了一个findDeviceInfoLocked(…)函数,返回类型是一个DeviceInfo结构体,CameraProviderManager.h中定义了三个DeviceInfo结构体,除了DeviceInfo之外,还有DeviceInfo1与DeviceInfo3,他们都继承DeviceInfo,其中DeviceInfo1为HALv1服务,DeviceInfo3为HALv3-specific服务,都是提供camera device一些基本信息。这里主要看下findDeviceInfoLocked(…)函数:

CameraProviderManager::ProviderInfo::DeviceInfo*CameraProviderManager::findDeviceInfoLocked(const std::string& id,hardware::hidl_version minVersion, hardware::hidl_version maxVersion)const{for(auto& provider : mProviders){for(auto& deviceInfo : provider->mDevices){if(deviceInfo->mId == id &&minVersion <= deviceInfo->mVersion && maxVersion >= deviceInfo->mVersion){return deviceInfo.get();}}}returnnullptr;}

mProviders是ProviderInfo类型的列表,这个ProviderInfo也是CameraProviderManager.h中定义的结构体,并且上面3种DeviceInfo都是定义在ProviderInfo里面的。下面给出了ProviderInfo的代码大纲,裁剪了很多代码,但是我们还是能看到核心的代码:ProviderInfo是管理当前手机的camera device设备的,通过addDevice保存在mDevices中,接下来我们看下这个addDevice是如何工作的。

structProviderInfo:virtualpublic hardware::camera::provider::V2_4::ICameraProviderCallback,virtualpublic hardware::hidl_death_recipient{//......ProviderInfo(const std::string &providerName,sp<hardware::camera::provider::V2_4::ICameraProvider>& interface,CameraProviderManager *manager);~ProviderInfo();status_t initialize();const std::string&getType()const;status_t addDevice(const std::string& name,hardware::camera::common::V1_0::CameraDeviceStatus initialStatus =hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT,/*out*/ std::string *parsedId =nullptr);// ICameraProviderCallbacks interface - these lock the parent mInterfaceMutexvirtual hardware::Return<void>cameraDeviceStatusChange(const hardware::hidl_string& cameraDeviceName,hardware::camera::common::V1_0::CameraDeviceStatus newStatus) override;virtual hardware::Return<void>torchModeStatusChange(const hardware::hidl_string& cameraDeviceName,hardware::camera::common::V1_0::TorchModeStatus newStatus) override;// hidl_death_recipient interface - this locks the parent mInterfaceMutexvirtualvoidserviceDied(uint64_t cookie,const wp<hidl::base::V1_0::IBase>& who) override;// Basic device information, common to all camera devicesstructDeviceInfo{//......};std::vector<std::unique_ptr<DeviceInfo>> mDevices;std::unordered_set<std::string> mUniqueCameraIds;int mUniqueDeviceCount;// HALv1-specific camera fields, including the actual device interfacestructDeviceInfo1:publicDeviceInfo{//......};// HALv3-specific camera fields, including the actual device interfacestructDeviceInfo3:publicDeviceInfo{//......};private:voidremoveDevice(std::string id);};

mProviders添加的流程:

1.CameraService --> onFirstRef()

2.CameraService --> enumerateProviders()

3.CameraProviderManager --> initialize(this)

initialize(…)函数原型是:

status_t initialize(wp<StatusListener> listener,ServiceInteractionProxy*proxy =&sHardwareServiceInteractionProxy);

第2个参数默认是sHardwareServiceInteractionProxy类型,

structServiceInteractionProxy{virtualboolregisterForNotifications(const std::string &serviceName,const sp<hidl::manager::V1_0::IServiceNotification>&notification)=0;virtual sp<hardware::camera::provider::V2_4::ICameraProvider>getService(const std::string &serviceName)=0;virtual~ServiceInteractionProxy(){}};// Standard use case - call into the normal generated static methods which invoke// the real hardware service managerstructHardwareServiceInteractionProxy:publicServiceInteractionProxy{virtualboolregisterForNotifications(const std::string &serviceName,const sp<hidl::manager::V1_0::IServiceNotification>&notification) override {return hardware::camera::provider::V2_4::ICameraProvider::registerForNotifications(serviceName, notification);}virtual sp<hardware::camera::provider::V2_4::ICameraProvider>getService(const std::string &serviceName) override {return hardware::camera::provider::V2_4::ICameraProvider::getService(serviceName);}};

hardware:📷:provider::V2_4::ICameraProvider::getService(serviceName)出处在./hardware/interfaces/camera/provider/2.4/default/CameraProvider.cpp,传入的参数可能是下面两种的一个:

const std::string kLegacyProviderName(“legacy/0”); 代表 HALv1

const std::string kExternalProviderName(“external/0”); 代码HALv3-specific

ICameraProvider*HIDL_FETCH_ICameraProvider(constchar* name){if(strcmp(name, kLegacyProviderName)==0){CameraProvider* provider =newCameraProvider();if(provider ==nullptr){ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);returnnullptr;}if(provider->isInitFailed()){ALOGE("%s: camera provider init failed!", __FUNCTION__);delete provider;returnnullptr;}return provider;}elseif(strcmp(name, kExternalProviderName)==0){ExternalCameraProvider* provider =newExternalCameraProvider();return provider;}ALOGE("%s: unknown instance name: %s", __FUNCTION__, name);returnnullptr;}

addDevice是如何工作的?

1.CameraProviderManager::ProviderInfo::initialize()初始化的时候是检查当前的camera device,检查的执行函数是:

    std::vector<std::string> devices;hardware::Return<void> ret = mInterface->getCameraIdList([&status,&devices](Status idStatus,const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames){status = idStatus;if(status == Status::OK){for(size_t i =0; i < cameraDeviceNames.size(); i++){devices.push_back(cameraDeviceNames[i]);}}});

最终调用到./hardware/interfaces/camera/provider/2.4/default/CameraProvider.cpp中的getCameraIdList函数:CAMERA_DEVICE_STATUS_PRESENT表明当前的camera是可用的,mCameraStatusMap存储了所有的camera 设备列表。


Return<void>CameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb){std::vector<hidl_string> deviceNameList;for(autoconst& deviceNamePair : mCameraDeviceNames){if(mCameraStatusMap[deviceNamePair.first]== CAMERA_DEVICE_STATUS_PRESENT){deviceNameList.push_back(deviceNamePair.second);}}hidl_vec<hidl_string>hidlDeviceNameList(deviceNameList);_hidl_cb(Status::OK, hidlDeviceNameList);returnVoid();}

1.上面谈的camera2 api就是在framework层的,在应用程序进程中。

2.CameraService,是camera2 api binder IPC通信方式调用到服务端的,camera相关的操作都在在服务端进行。所在的位置就是./frameworks/av/services/camera/下面

3.服务端也只是一个桥梁,service也会调用到HAL,硬件抽象层,具体位置在./hardware/interfaces/camera/provider/2.4

4.camera driver,底层的驱动层了,这是真正操作硬件的地方。

总结:

Camera操作过程中最重要的四个步骤:

CameraManager–>openCamera —> 打开相机

CameraDeviceImpl–>createCaptureSession —> 创建捕获会话

CameraCaptureSession–>setRepeatingRequest —> 设置预览界面

CameraDeviceImpl–>capture —> 开始捕获图片

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值