camera应用调用之---open camera流程(1)

网上这个文档应该相当多,早些年其实看文章简单的过了一下,并没有真正记住,但是再自己读着走遍流程并记录下,作为完整文档一部分。

安卓系统,各种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-> 然后

1

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

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 说明这个结构可以跨进程通信

1.2

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::initialize(sp manager) {
    return initializeImpl(manager);
}
status_t Camera2ClientBase::initializeImpl(TProviderPtr providerPtr,
        const String8& monitorTags) {
……
mDevice->initialize(providerPtr, monitorTags);//第一个参数是mCameraProviderManager
tatus_t Camera3Device::initialize(sp 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作为对下接口。

你可能感兴趣的:(camera,framework,调用)