网上这个文档应该相当多,早些年其实看文章简单的过了一下,并没有真正记住,但是再自己读着走遍流程并记录下,作为完整文档一部分。
安卓系统,各种Manager提供了系统层的控制接口,CameraManager也不例外,除去apk,那camera framework应该从CameraManager入口开始。
一般:CameraManager manager =(CameraManager)Context.getSystemService(Context.CAMERA_SERVICE)
可以获取CameraManager实例,然后调用他的内部函数。
首先CameraManager是本地的SystemService集合中一个service,在SystemServiceRegistry中注册,安卓框架真的是每一个层级都有一个Manager。SystemService查看资料(自己不研究了),最早是由init.rc,init进程会创建Zygote进程,这个进程是安卓的盘古进程,这个首先就创建SystemServer进程,SystemServer进程负责启动系统的关键服务。
接下来回到本文重点上来
Camera api的路径
frameworks/base/core/java/android/hardware/camera2
frameworks/base/core/java/android/hardware/camera2/CameraManager.java
public void openCamera(@NonNull String cameraId,
@NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler)
public void openCamera(@NonNull String cameraId,
@NonNull @CallbackExecutor Executor executor,
@NonNull final CameraDevice.StateCallback callback)
CameraDevice.StateCallback是在camera状态改变的时候调用,如打开,关闭,报错。
都调用openCameraForUid-> 然后
openCameraDeviceUserAsync(cameraId, callback, executor, clientUid)
throws CameraAccessException {
CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);//1.1
……
android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
new android.hardware.camera2.impl.CameraDeviceImpl(
cameraId,
callback,
executor,
characteristics,
mContext.getApplicationInfo().targetSdkVersion);
ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks();//作为参数传入cameraservice
if (supportsCamera2ApiLocked(cameraId)) {
// Use cameraservice's cameradeviceclient implementation for HAL3.2+ devices
ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
if (cameraService == null) {
throw new ServiceSpecificException(
ICameraService.ERROR_DISCONNECTED,
"Camera service is currently unavailable");
}
cameraUser = cameraService.connectDevice(callbacks, cameraId,
mContext.getOpPackageName(), uid);
}//1.2
…..
deviceImpl.setRemoteDevice(cameraUser);
device = deviceImpl;//1.3
1.1 内部调用
ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId);
characteristics = new CameraCharacteristics(info);
也就是先获取cameraService实例,这里涉及到aidl相关知识
第一个函数调用
connectCameraServiceLocked();
IBinder cameraServiceBinder = ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME);
ICameraService cameraService = ICameraService.Stub.asInterface(cameraServiceBinder);
这是通过binder获取的cameraService,I开头的都是接口类。
out\soong.intermediates\frameworks\av\camera\libcamera_client\android_arm64_armv8-a_cortex-a53_core_shared\gen\aidl\frameworks\av\camera\aidl\android\hardware\ICameraService.cpp
这是文件路径
然后通过这个调用cameraService的getCameraCharacteristics,当然前面有做老版本的兼容,就是hal1中getcamerainfo这种获取,Legacy历史遗留的东西都不管了
然后new出characteristics作为返回值这个是继承metadata
经由cameraService调用到CameraProviderManager::getCameraCharacteristicsLocked,
deviceInfo = findDeviceInfoLocked(id, /minVersion/ {3,0}, /maxVersion/ {4,0});
遍历2个provider下面的cameraid和函数调用匹配,先找到deviceInfo
deviceInfo->getCameraCharacteristics(characteristics)
CameraDevice::getCameraCharacteristics
mModule->getCameraInfo(mCameraIdInt, &info);//从hal3中获取info
convertToHidl(info.static_camera_characteristics, &cameraCharacteristics);
_hidl_cb(status, cameraCharacteristics);//hidl返回cameraCharacteristics
调用CameraModule::getCameraInfo
mModule->get_camera_info然后走到hal
Hal部分调用
NAMED_FIELD_INITIALIZER(get_camera_info) hal_get_camera_info, 说明getCameraInfo是
hal_get_camera_info函数
PlatformData::getCameraInfo,获取camera相关信息,里面包含静态metadata
CameraMetadata结构作为返回值和typedef CameraMetadata CameraMetadataNative;是同一个
里面包含了camera_metadata_t结构,相当于hal保存的直接返回给框架层了。
而且frameworks\av\camera\include\camera\CameraMetadata.h 里面
class CameraMetadata: public Parcelable 说明这个结构可以跨进程通信
deviceImpl 继承CameraDevice(java,service接口层有cpp),是创建CameraDevice实例,判断camera支持api2。
调用cameraService.connectDevice返回ICameraDeviceUser cameraUser;
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;
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);
connectHelper调用
…...
client->initialize(mCameraProviderManager, mMonitorTags);//1.2.2
……
*device = client;
返回值CameraDeviceClient转换ICameraDeviceUser(这个是父类)
对应client的返回值是sphardware::camera2::ICameraDeviceUser* device
connectHelper
->> validateConnectLocked(判断当前设备是否可用)
->> handleEvictionsLocked(检查是否被占用)
->> mFlashlight->prepareDeviceOpen(flash相关通知)
->> getDeviceVersion(判断版本)
->> makeClient
->> client-> initialize
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) {
…… //中间判断api和device版本后
sp<hardware::camera2::ICameraDeviceCallbacks> tmp =
static_cast<hardware::camera2::ICameraDeviceCallbacks*>(cameraCb.get());
*client = new CameraDeviceClient(cameraService, tmp, packageName, cameraId,
facing, clientPid, clientUid, servicePid);
就是new了一个CameraDeviceClient结构类,作为返回
Open后面做的东西其实是初始化这个返回值
具体看CameraDeviceClient做了什么
CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
const String16& clientPackageName,
const String8& cameraId,
int cameraFacing,
int clientPid,
uid_t clientUid,
int servicePid) :
Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
cameraId, /*API1 camera ID*/ -1,
cameraFacing, clientPid, clientUid, servicePid),
Camera2ClientBase<TClientBase>::Camera2ClientBase(
……
mInitialClientPid = clientPid;
mDevice = new Camera3Device(cameraId);
Camera3Device::Camera3Device
……
camera3_callback_ops::notify = &sNotify;
camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
初始化部分CameraDeviceClient以及重要Camera3Device结构。
1.2.2
status_t CameraDeviceClient::initialize(sp<CameraProviderManager> manager,
const String8& monitorTags) {
return initializeImpl(manager, monitorTags);
}
status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr, const String8& monitorTags) {
……
res = Camera2ClientBase::initialize(providerPtr, monitorTags);
mFrameProcessor = new FrameProcessorBase(mDevice);
mFrameProcessor->run(threadName.string());
mFrameProcessor->registerListener(FRAME_PROCESSOR_LISTENER_MIN_ID,
FRAME_PROCESSOR_LISTENER_MAX_ID,
/*listener*/this,
/*sendPartials*/true);
status_t Camera2ClientBase<TClientBase>::initialize(sp<CameraProviderManager> manager) {
return initializeImpl(manager);
}
status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr,
const String8& monitorTags) {
……
mDevice->initialize(providerPtr, monitorTags);//第一个参数是mCameraProviderManager
tatus_t Camera3Device::initialize(sp<CameraProviderManager> manager, const String8& monitorTags) {
……
manager->openSession(mId.string(), this,
/*out*/ &session);
……
return initializeCommonLocked();
这个会执行到CameraProviderManager::openSession,可以认为是Camera3Device访问CameraProviderManager。
auto *deviceInfo3 = static_castProviderInfo::DeviceInfo3*(deviceInfo);
deviceInfo3->mInterface->open (mInterface 的定义为const sp mInterface;
typedef hardware::device::V3_2::ICameraDevice InterfaceT)
所以open执行到CameraDevice::open
创建 CameraDeviceSession 实例并将其本地调用接口通过入参 session 返回
创建之后session->getCaptureRequestMetadataQueue获取metadataQueue
session->getCaptureRequestMetadataQueue
CameraDevice里面(CameraModule)包含hal层的调用mModule 可以操作hal层。(所以是Camera3Device调用CameraProviderManager,通过里面的deviceInfo3-> mInterface(其实是hal里面的CameraDevice)去访问hal),当然这种访问是经过hidl的
还有一个是经由CameraDeviceSession里面包含camera3_device_t访问相关接口(CameraDevice::open里面创建,打开hal模块返回camera3_device_t),Camera3Device里面包含(ICameraDeviceSession),configureStreams这种都是Camera3Device下面的 HalInterface内部的ICameraDeviceSession下发
initializeCommonLocked函数new出了
Camera3BufferManager、RequestThread、PreparerThread内部对象。看着名字像是以前hal1各芯片商实现的线程buf流转,先不管了吧。
另外在CameraDeviceClient::initializeImpl后面可以看到mFrameProcessor(CameraDeviceClient内部类)是帧处理线程,FrameProcessorBase::threadLoop函数执行
res = device->waitForNextFrame(kWaitDuration);
if (res == OK) {
processNewFrames(device);
}
1.3将获取的远程服务设置到CameraDeviceImpl实例中, CameraDeviceImpl实例中有个参数存放远端设备
openCameraDeviceUserAsync的调用函数openCameraForUid并没接收他的返回值,函数里面也就是为了获取Camera3Device(ICameraDeviceSession和ICameraDevice)
setRemoteDevice最后面有
mDeviceExecutor.execute(mCallOnOpened);
mDeviceExecutor.execute(mCallOnUnconfigured);
那是这两个函数作为callback返回设备?
mCallOnOpened会调用mDeviceCallback.onOpened(CameraDeviceImpl.this)
查看应用代码
Camera2\src\com\android\camera\one\v2\Camera2OneCameraOpenerImpl.java
mCameraManager.openCamera(cameraKey.getValue(), new CameraDevice.StateCallback() {
@Override
public void onDisconnected(CameraDevice device) {
……
@Override
public void onClosed(CameraDevice device) {
……
@Override
public void onError(CameraDevice device, int error) {
……
@Override
public void onOpened(CameraDevice device) {
……
OneCamera oneCamera = OneCameraCreator.create(
device,
……
这就相当于应用拿到了open出来的节点。
实际上这个是一个状态机,到什么状态就相应的回调,
注意下public class CameraDeviceCallbacks extends ICameraDeviceCallbacks.Stub {
CameraDeviceImpl内部有个 private final CameraDeviceCallbacks mCallbacks = new CameraDeviceCallbacks();
这个也是aidl传输对象,\frameworks\av\camera\aidl\android\hardware\camera\ ICameraDeviceCallbacks.aidl
public CameraDeviceCallbacks getCallbacks() {
return mCallbacks;
}
包含camera各种状态的回调
小结:
那么这就是打开camera个过程,其实是获取CameraDeviceImpl到应用。
重要的包含结构
CameraDeviceImpl
ICameraDeviceUserWrapper
ICameraDeviceUser(通过cameraService.connectDevice获取,framework和service交互)
对应CameraDeviceClient(framework和service交互,就是创建client)
Camera2ClientBase
Camera3Device
CameraDeviceClient属于camerasever,所以可以调用CameraProviderManager 里面的deviceInfo3-> mInterface(privder里面的CameraDevice)CameraDevice通过CameraModule(包含加载的hal模块句柄)可以访问hal,具体细节看上一节。
Camera3Device 下面的HalInterface的ICameraDeviceSession也可以作为hal访问接口
所以cameraservice正常是用Camera3Device作为对下接口,CameraDeviceClient为对上接口
Provide是是以CameraDevice和CameraDeviceSession作为对下接口。