openCamera

  • openCamera() 方法参数解析
  • openCamera() 代码流程
  • 时序图
  • 关系图

openCamera() 方法参数解析

1、 打开 camera我们可以直接调用系统service,获得CameraManager,然后调用openCamera();
CameraManager cameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
cameraManager.openCamera(mCameraId, mStateCallback, mCameraHandler);

openCamera() 需要传递三个参数,第一个参数是当前你要具体使用的cameraId。

            for (String cameraId : cameraManager.getCameraIdList()) {//描述相机设备的属性类cameraId = cameraId;CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);//获取是前置还是后置摄像头Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);//使用后置摄像头if (facing != null && facing == CameraCharacteristics.LENS_FACING_BACK) {StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);if (map != null) {Size[] sizeMap = map.getOutputSizes(SurfaceTexture.class);LogUtil.d("preview->" + previewSize.toString());mCameraId = cameraId;}}

openCamera() 第二个参数是open 摄像头的状态,回调三个方法分别是打开成功、摄像头没有连接、打开失败。需要继承自CameraDevice.StateCallback 接口类。

private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {@Overridepublic void onOpened(CameraDevice camera) {}@Overridepublic void onDisconnected(CameraDevice camera) {}@Overridepublic void onError(CameraDevice camera, int error) {}};

openCamera() 第三个参数就是主线程的handler。

mCameraHandler = new Handler(handlerThread.getLooper());

openCamera() 代码流程

frameworks/base/core/java/android/hardware/camera2/CameraManager.java

    @RequiresPermission(android.Manifest.permission.CAMERA)public void openCamera(@NonNull String cameraId,@NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)throws CameraAccessException {// 1、checkAndWrapHandler()就是判断handler是不是null,USE_CALLING_UID 系统默认为-1openCameraForUid(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),USE_CALLING_UID);}public void openCameraForUid(@NonNull String cameraId,@NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor,int clientUid)throws CameraAccessException {if (cameraId == null) {throw new IllegalArgumentException("cameraId was null");} else if (callback == null) {throw new IllegalArgumentException("callback was null");}if (CameraManagerGlobal.sCameraServiceDisabled) {throw new IllegalArgumentException("No cameras available on device");}// 2.0openCameraDeviceUserAsync(cameraId, callback, executor, clientUid);}private CameraDevice openCameraDeviceUserAsync(String cameraId,CameraDevice.StateCallback callback, Executor executor, final int uid)throws CameraAccessException {CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);CameraDevice device = null;synchronized (mLock) {ICameraDeviceUser cameraUser = null;// 2.1 这里new deviceImpl里面没做什么事,就是把一些属性值进行了赋值android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =new android.hardware.camera2.impl.CameraDeviceImpl(cameraId,callback,executor,characteristics,mContext.getApplicationInfo().targetSdkVersion);// 2.2 接着deviceImpl.getCallbacks() 返回的就是 mCallbacks = new CameraDeviceCallbacks();// public class CameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub{}ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();try {if (supportsCamera2ApiLocked(cameraId)) {// 2.3 这里的ICameraService 的实现类是 CameraService// class CameraService : public BinderService<CameraService>,//                       public virtual ::android::hardware::BnCameraService,//                      public virtual IBinder::DeathRecipient,//                       public virtual CameraProviderManager::StatusListener// BinderService 的实现在//out\soong\.intermediates\frameworks\av\camera\libcamera_client\android_arm64_armv8-a_core_shared_cfi\gen\aidl\android\hardware\BnCameraService.h// class BnCameraService : public ::android::BnInterface<ICameraService>ICameraService cameraService = CameraManagerGlobal.get().getCameraService();...... 省略部分代码....../* 通过 ICameraService::connectDevice() 连接设备,* 返回的 cameraUser 实际上是远端CameraDeviceClient的本地代理。通过* cameraUser 访问到具体实现类CameraDeviceClient的方法。* class BnCameraDeviceUser : public ::android::BnInterface<ICameraDeviceUser>* * struct CameraDeviceClientBase : public hardware::camera2::BnCameraDeviceUser * * class CameraDeviceClient : public Camera2ClientBase<CameraDeviceClientBase>,*/cameraUser = cameraService.connectDevice(callbacks, cameraId,mContext.getOpPackageName(), uid);} else {...... 省略部分代码......}} catch (ServiceSpecificException e) {...... 省略部分代码......}// TODO: factor out callback to be non-nested, then move setter to constructor// For now, calling setRemoteDevice will fire initial// onOpened/onUnconfigured callbacks.// This function call may post onDisconnected and throw CAMERA_DISCONNECTED if// cameraUser dies during setup.// 2.4 上面cameraService.connectDevicedeviceImpl.setRemoteDevice(cameraUser);device = deviceImpl;}return device;}

frameworks\av\services\camera\libcameraservice\CameraService.cpp

Status CameraService::connectDevice(const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,const String16& cameraId,const String16& clientPackageName,int clientUid,/*out*/sp<hardware::camera2::ICameraDeviceUser>* device) {ATRACE_CALL();Status ret = Status::ok();String8 id = String8(cameraId);sp<CameraDeviceClient> client = nullptr;// 2.3.1看这里, client 的赋值在connectHelper(......., /*out*/client) 中。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);if(!ret.isOk()) {logRejected(id, getCallingPid(), String8(clientPackageName),ret.toString8());return ret;}*device = client;return ret;
}// CALLBACK是CameraDeviceCallbacks, CLIENT是CameraDeviceClient
//2.3.2 看这里, client 的赋值是在connectHelper(......., /*out*/client) 中。
template<class CALLBACK, class CLIENT>
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 (clientTmp.get() != nullptr) {// Handle special case for API1 MediaRecorder where the existing client is returned// 处理API1 MediaRecorder返回现有客户端的特殊情况device = static_cast<CLIENT*>(clientTmp.get());return ret;}
......省略部分代码......sp<BasicClient> tmp = nullptr;// 2.3.3 makeClient中会new CameraDeviceClientif(!(ret = makeClient(this, cameraCb, clientPackageName,cameraId, api1CameraId, 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__);// 2.3.4err = client->initialize(mCameraProviderManager, mMonitorTags);
......省略部分代码......device = client;return ret;}Status CameraService::makeClient(const sp<CameraService>& cameraService,const sp<IInterface>& cameraCb, const String16& packageName, const String8& cameraId,int api1CameraId, int facing, int clientPid, uid_t clientUid, int servicePid,bool legacyMode, int halVersion, int deviceVersion, apiLevel effectiveApiLevel,/*out*/sp<BasicClient>* client) {// 我们知道这里apiLevel = API_2 = 2; 路由走的是api2所以*client = new CameraDeviceClient()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 routesp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());*client = new CameraClient(cameraService, tmp, packageName,api1CameraId, facing, clientPid, clientUid,getpid(), legacyMode);} else { // Camera2 API routeALOGW("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 routesp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());*client = new Camera2Client(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 = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,facing, clientPid, clientUid, servicePid);}break;default:// Should not be reachableALOGE("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 {.......省略部分代码.......}return Status::ok();
}

CameraDeviceClient::initialize(mCameraProviderManager, mMonitorTags)
framework\base\core\java\android\hardware\camera2\impl\CameraDeviceImpl.java


status_t CameraDeviceClient::initialize(sp<CameraProviderManager> manager,const String8& monitorTags) {return initializeImpl(manager, monitorTags);
}template<typename TProviderPtr>
status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr, const String8& monitorTags) {ATRACE_CALL();status_t res;// 2.3.4.1res = Camera2ClientBase::initialize(providerPtr, monitorTags);if (res != OK) {return res;}String8 threadName;mFrameProcessor = new FrameProcessorBase(mDevice);threadName = String8::format("CDU-%s-FrameProc", mCameraIdStr.string());mFrameProcessor->run(threadName.string());mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,FRAME_PROCESSOR_LISTENER_MAX_ID,/*listener*/this,/*sendPartials*/true);auto deviceInfo = mDevice->info();camera_metadata_entry_t physicalKeysEntry = deviceInfo.find(ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS);if (physicalKeysEntry.count > 0) {mSupportedPhysicalRequestKeys.insert(mSupportedPhysicalRequestKeys.begin(),physicalKeysEntry.data.i32,physicalKeysEntry.data.i32 + physicalKeysEntry.count);}return OK;
}

Camera2ClientBase::initialize

template <typename TClientBase>
status_t Camera2ClientBase<TClientBase>::initialize(sp<CameraProviderManager> manager,const String8& monitorTags) {return initializeImpl(manager, monitorTags);
}template <typename TClientBase>
template <typename TProviderPtr>
status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr,const String8& monitorTags) {// Verify ops permissionsres = TClientBase::startCameraOps();if (res != OK) {return res;}..... 省略部分代码.......// mDevice 是 Camera3Device,赋值在Camera2ClientBase的构造函数,前面知道// CameraDeviceClient继承自public Camera2ClientBase<CameraDeviceClientBase>,所以// 在new CameraDeviceClient时候也就调用了Camera2ClientBaseres = mDevice->initialize(providerPtr, monitorTags);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;
}

Camera3Device::initialize()
frameworks\av\services\camera\libcameraservice\device3\Camera3Device.cpp

status_t Camera3Device::initialize(sp<CameraProviderManager> manager, const String8& monitorTags) {..... 省略部分代码.......status_t res = manager->openSession(mId.string(), this,/*out*/ &session);..... 省略部分代码.......
}

CameraProviderManager::openSession()
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) {/* 从 CameraProviderManager 的 mProviders 查找对应 id 的 mDevices,* 而后调用相对应的 deviceInfo3->mInterface->open(),其中,mInterface* 是在CameraProvider adddevice 时,通过DeviceInfo3的构造函数传递进来的,* mInterface 最终为* android::hardware::camera::device::V3_4::implementation::CameraDevice*/ret = deviceInfo3->mInterface->open(callback, [&status, &session](Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {status = s;if (status == Status::OK) {*session = cameraSession;}});..... 省略部分代码.......}

CameraDevice::open()
hardware\interfaces\camera\device\1.0\default\CameraDevice.cpp

Return<Status> CameraDevice::open(const sp<ICameraDeviceCallback>& callback) {ALOGI("Opening camera %s", mCameraId.c_str());Mutex::Autolock _l(mLock);camera_info info;status_t res = mModule->getCameraInfo(mCameraIdInt, &info);if (res != OK) {ALOGE("Could not get camera info: %s: %d", mCameraId.c_str(), res);return getHidlStatus(res);}int rc = OK;if (mModule->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 = mModule->openLegacy(mCameraId.c_str(),CAMERA_DEVICE_API_VERSION_1_0,(hw_device_t **)&mDevice);} else {//这个mModule就是CameraModule类,hal层实现的就是CameraModule,各个厂家可以做成so来加载,不对外公开。rc = mModule->open(mCameraId.c_str(), (hw_device_t **)&mDevice);}..... 省略部分代码.......return getHidlStatus(rc);
}

上面就是大体openCamera的整个过程。如果上面的整个过程没有error,下面接着会回调到应用。

接着上面的deviceImpl.setRemoteDevice(cameraUser),得到 CameraDeviceClient,然后给到 CameraDeviceImpl。

    public void setRemoteDevice(ICameraDeviceUser remoteDevice) throws CameraAccessException {synchronized(mInterfaceLock) {// TODO: Move from decorator to direct binder-mediated exceptions// If setRemoteFailure already called, do nothingif (mInError) return;mRemoteDevice = new ICameraDeviceUserWrapper(remoteDevice);IBinder remoteDeviceBinder = remoteDevice.asBinder();// For legacy camera device, remoteDevice is in the same process, and// asBinder returns NULL.if (remoteDeviceBinder != null) {try {remoteDeviceBinder.linkToDeath(this, /*flag*/ 0);} catch (RemoteException e) {CameraDeviceImpl.this.mDeviceExecutor.execute(mCallOnDisconnected);throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,"The camera device has encountered a serious error");}}// 2.4.1这里会执行这个线程 mCallOnOpenedmDeviceExecutor.execute(mCallOnOpened);mDeviceExecutor.execute(mCallOnUnconfigured);}}private final Runnable mCallOnOpened = new Runnable() {@Overridepublic void run() {StateCallbackKK sessionCallback = null;synchronized(mInterfaceLock) {if (mRemoteDevice == null) return; // Camera already closedsessionCallback = mSessionStateCallback;}if (sessionCallback != null) {sessionCallback.onOpened(CameraDeviceImpl.this);}//2.4.1.1这里的mDeviceCallback就是前面new CameraDeviceImpl时传进来的应用实现的CameraDevice.StateCallback,调用StateCallback方法onOpened(). mDeviceCallback.onOpened(CameraDeviceImpl.this);}};

时序图

关系图

参考:https://blog.csdn.net/weixin_41944449/article/details/99684653

camera 之 openCamera相关推荐

  1. Camera: SnapdragonCamera OpenCamera(一)

    高通SnapdragonCamera相机研究一系列OpenCamer相关的流程,以及比较重要的需要check的Error状态的捕捉和监听.  1.应用层OpenCamera  CameraActivi ...

  2. AIS Camera流程-opencamera

    本文主要介绍AIS camera打开相机流程. 上篇文章中介绍了ais_v4l2_proxy 这个服务的启动,作用是遍历ais_v4l2loopback_config.xml中的配置的 所有camer ...

  3. 展锐camera 调用流程

    本文将要为您介绍的是[Camera专题]Sprd-深入浅出Camera驱动框架1(HAL层-Kernel层),具体完成步骤: 一.前言 本文主要研究展讯平台Camera驱动和HAL层代码架构,熟悉展讯 ...

  4. fritz_如何使用Fritz.ai将机器学习应用于Android

    fritz 本文介绍如何使用Fritz.ai将机器学习应用于Android . 在深入探讨如何开发机器学习Android应用程序的细节之前,简要介绍一下什么是Fritz.ai平台很有用. 如您所知,机 ...

  5. android申请多个运行时权限,Android 6.0(API 23) 运行时权限(二)之权限申请

    Android M 在上一篇中简单介绍了运行时权限,今天就讲讲怎么去申请权限.这个项目中本来用了一个第三方的权限框架,但是不太好用,我就在github上选择了start最多的PermissionsDi ...

  6. android camera2预览方向,Android camera2预览无法在横向模式下正常工作

    我只想在textureView中显示相机预览. 在纵向模式下它看起来很好但在横向模式下它顺时针旋转90度. 我知道这样的事情可以解决这个问题: private static final SparseI ...

  7. Android surfaceview 自定义相机 拍照(闪光灯、前后摄像头)

    在我们app中经常会调用相机进行拍照,然后把拍下来的图片保存在本地,再上传到服务端,网上有不少自定义的相机,也下载了不少,但是效果还是不满意,所以决定自定义下,不多说了,直接上代码: public c ...

  8. Android 卡片、证件识别

    无需原生开发基础,也能完美呈现京东商城.<混合开发京东商城系统,提前布局大前端>课程融合vue.Android.IOS等目前流行的前端和移动端技术,混合开发经典电商APP--京东.课程将各 ...

  9. 微信小程序使用前置摄像头拍照

    1.拍照页面: <template><view title="拍照"><camera v-if="openCamera" devi ...

最新文章

  1. 美化浏览器的radio和checkbox样式
  2. RocketMQ源码:Broker启动过程介绍
  3. 让陌生人迅速相爱的36个问题
  4. 离散数学实验题目-关系
  5. c语言吗 程序语言,编程语言为什么从c语言开始,那有没有a语言b语言呢?
  6. php正则表达式正向预查,javascript正则表达式-----正向预查
  7. 云计算开发教程:Python自动化运维开发实战流程控制
  8. Vuejs 写法实例
  9. python open函数参数_python open函数的用法笔记
  10. CMS:文章管理之视图(6)
  11. IP addresses in C#
  12. 黑苹果白果序列号_黑苹果从入门到放弃黑苹果:OC配置入门
  13. ios开发 方形到圆的动画_3Blue1Brown 动画制作教程(1)--制作第一个自己的动画
  14. python 闭包_一起看流畅的python:函数装饰器和闭包
  15. ubuntu 中安装 Redis
  16. Markdown MarkdownPad2 win10上显示awesomium
  17. 部队计算机操作使用教案,计算机基础教案2(键盘鼠标操作).doc
  18. Hibernate中类的继承使用union-subclass实现
  19. cad工具箱详细讲解_CAD工具箱的12种功能详解
  20. Windows10优化系统,优化达到30多项,速度大幅提升,

热门文章

  1. Saturn的系统架构
  2. 适用于影视剧场景的智能配音算法实现
  3. vue 中编写404页面
  4. DOS命令 基础命令
  5. 微服务启动读取jar包失败:java: 读取D:\repository\org\aspectj\aspectjweaver\1.9.6\aspectjweaver-1.9.6.jar时出错; erro
  6. 关于力控无法插入图片
  7. 头脑风暴-移动搜索和传统搜索的不同之处
  8. Linux安装与常见基本操作命令
  9. bartender打印二维码油墨太多,修改打印机设置
  10. 总结蛋糕店如何制定产品策略