最新Camera2-HAL3-框架分析,app内嵌h5页面怎么做

最后

下面是辛苦给大家整理的学习路线

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以下内容:

一、Android O上的Treble机制

二、Camera HAL3的框架更新

三、核心概念:Request

一、Android O上的Treble机制

=================================================================================

在 Android O 中,系统启动时,会启动一个 CameraProvider 服务,它是从 cameraserver 进程中分离出来,作为一个独立进程 android.hardware.camera.provider@2.4-service 用来控制 camera HAL,cameraserver通过 HIDL 机制于camera provider进行通信。HIDL源自于 Android O 版本加入的 Treble 机制,它的主要功能是将 service 与 HAL 隔离,以方便 HAL 部分进行独立升级,类似于 APP 与 Framework 之间的 Binder 通信机制,通过引入一个进程间通信机制而针对不同层级进行解耦(从 Local call 变成了 Remote call)。如下图:

cameraserver 与 provider 这两个进程启动、初始化的调用逻辑,如下图:

二、Camera HAL3的框架更新

==============================================================================

  • Application framework:

    用于给APP提供访问hardware的Camera API2,通过binder来访问camera service。

  • AIDL:

    基于Binder实现的一个用于让App fw代码访问natice fw代码的接口。其实现存在于下述路径:frameworks/av/camera/aidl/android/hardware。其中:

(1) ICameraService

是相机服务的接口。用于请求连接、添加监听等。

(2) ICameraDeviceUser

是已打开的特定相机设备的接口。应用框架可通过它访问具体设备。

(3) ICameraServiceListener 和 ICameraDeviceCallbacks

分别是从 CameraService 和 CameraDevice 到应用框架的回调。

  • Natice framework

    frameworks/av/。提供了ICameraService、ICameraDeviceUser、ICameraDeviceCallbacks、ICameraServiceListener等aidl接口的实现。以及camera server的main函数。

  • Binder IPC interface

    提供进程间通信的接口,APP和CameraService的通信、CameraService和HAL的通信。其中,AIDL、HIDL都是基于Binder实现的。

  • Camera Service

    frameworks/av/services/camera/。同APP、HAL交互的服务,起到了承上启下的作用。

  • HAL:

    Google的HAL定义了可以让Camera Service访问的标准接口。对于供应商而言,必须要实现这些接口。

##2.1 Camera HAL3 构建连路的过程

如下图(红色虚线是上行路线,黑色虚线则是下行路线):

2.2 从 App 到 CameraService的调用流程


从 Application 连接到 CameraService,这涉及到 Android 架构中的三个层次:App 层,Framework 层,Runtime 层。其中,App 层直接调用 Framework 层所封装的方法,而 Framework 层需要通过 Binder 远程调用 Runtime 中 CameraService 的函数。

这一部分主要的函数调用逻辑如下图所示:

在 App 中,需要调用打开相机的API如下:

  • CameraCharacteristics:

    描述摄像头的各种特性,我们可以通过CameraManager的getCameraCharacteristics(@NonNull String cameraId)方法来获取。

  • CameraDevice:

    描述系统摄像头,类似于早期的Camera。

  • CameraCaptureSession:

    Session类,当需要拍照、预览等功能时,需要先创建该类的实例,然后通过该实例里的方法进行控制(例如:拍照 capture())。

  • CaptureRequest:

    描述了一次操作请求,拍照、预览等操作都需要先传入CaptureRequest参数,具体的参数控制也是通过CameraRequest的成员变量来设置。

  • CaptureResult:

    描述拍照完成后的结果。

例如打开camera的java代码:


mCameraManager.openCamera(currentCameraId, stateCallback, backgroundHandler);



Camera2拍照流程如下所示:

2.2.1 Framework CameraManager

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

最初的入口就是 CameraManager 的 openCamera 方法,但通过代码可以看到,它仅仅是调用了 openCameraForUid 方法。


@RequiresPermission(android.Manifest.permission.CAMERA) public void openCamera(@NonNull String cameraId,

        @NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler) throws CameraAccessException {



    openCameraForUid(cameraId, callback, handler, USE_CALLING_UID);

}



下面的代码忽略掉了一些参数检查相关操作,最终主要调用了 openCameraDeviceUserAsync 方法。


public void openCameraForUid(@NonNull String cameraId,

        @NonNull final CameraDevice.StateCallback callback, @Nullable Handler handler, int clientUid) throws CameraAccessException { /* Do something in*/ ...... /* Do something out*/ openCameraDeviceUserAsync(cameraId, callback, handler, clientUid);

}



参考如下注释分析:


private CameraDevice openCameraDeviceUserAsync(String cameraId,

        CameraDevice.StateCallback callback, Handler handler, final int uid) throws CameraAccessException {

    CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);

    CameraDevice device = null; synchronized (mLock) {



        ICameraDeviceUser cameraUser = null;



        android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =   //实例化一个 CameraDeviceImpl。构造时传入了 CameraDevice.StateCallback 以及 Handler。

                new android.hardware.camera2.impl.CameraDeviceImpl(  

                    cameraId,

                    callback,

                    handler,

                    characteristics,

                    mContext.getApplicationInfo().targetSdkVersion);



        ICameraDeviceCallbacks callbacks = deviceImpl.getCallbacks(); //获取 CameraDeviceCallback 实例,这是提供给远端连接到 CameraDeviceImpl 的接口。



       try { if (supportsCamera2ApiLocked(cameraId)) {  //HAL3 中走的是这一部分逻辑,主要是从 CameraManagerGlobal 中获取 CameraService 的本地接口,通过它远端调用(采用 Binder 机制) connectDevice 方法连接到相机设备。

                                //注意返回的 cameraUser 实际上指向的是远端 CameraDeviceClient 的本地接口。 // 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);

            } else { // Use legacy camera implementation for HAL1 devices

                int id; try {

                    id = Integer.parseInt(cameraId);

                } catch (NumberFormatException e) { throw new IllegalArgumentException("Expected cameraId to be numeric, but it was: "

                            + cameraId);

                }



                Log.i(TAG, "Using legacy camera HAL.");

                cameraUser = CameraDeviceUserShim.connectBinderShim(callbacks, id);

            }

        } catch (ServiceSpecificException e) { /* Do something in */ ...... /* Do something out */ } // 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.

        deviceImpl.setRemoteDevice(cameraUser); //将 CameraDeviceClient 设置到 CameraDeviceImpl 中进行管理。

        device = deviceImpl;

    } return device;

}



2.2.2 CameraDeviceImpl /frameworks/base/core/java/android/hardware/camera2/Impl/CameraDeviceImpl.java

在继续向下分析打开相机流程之前,先简单看看调用到的 CameraDeviceImpl 中的setRemoteDevice 方法,主要是将获取到的远端设备保存起来:


/** * Set remote device, which triggers initial onOpened/onUnconfigured callbacks

 *

 * <p>This function may post onDisconnected and throw CAMERA_DISCONNECTED if remoteDevice dies

 * during setup.</p>

 * */

public void setRemoteDevice(ICameraDeviceUser remoteDevice) throws CameraAccessException { synchronized(mInterfaceLock) { // TODO: Move from decorator to direct binder-mediated exceptions // If setRemoteFailure already called, do nothing

        if (mInError) return;



        mRemoteDevice = new ICameraDeviceUserWrapper(remoteDevice); //通过 ICameraDeviceUserWrapper 给远端设备实例加上一层封装。

 IBinder remoteDeviceBinder = remoteDevice.asBinder(); //使用 Binder 机制的一些基本设置。 // For legacy camera device, remoteDevice is in the same process, and // asBinder returns NULL.

        if (remoteDeviceBinder != null) { try {

                remoteDeviceBinder.linkToDeath(this, /*flag*/ 0); //如果这个binder消失,为标志信息注册一个接收器。

            } catch (RemoteException e) {

                CameraDeviceImpl.this.mDeviceHandler.post(mCallOnDisconnected); throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED, "The camera device has encountered a serious error");

            }

        }



        mDeviceHandler.post(mCallOnOpened); //需此处触发 onOpened 与 onUnconfigured 这两个回调,每个回调都是通过 mDeviceHandler 启用一个新线程来调用的。

 mDeviceHandler.post(mCallOnUnconfigured);

    }

}



2.2.3 Runtime

通过 Binder 机制,我们远端调用了 connectDevice 方法(在 C++ 中称为函数,但说成方法可能更顺口一些),这个方法实现在 CameraService 类中。

2.2.4 CameraService

/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; //此处调用的 connectHelper 方法才真正实现了连接逻辑(HAL1 时最终也调用到这个方法)。需要注意的是,设定的模板类型是 ICameraDeviceCallbacks 以及 CameraDeviceClient。

    ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks,CameraDeviceClient>(cameraCb, id,

            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; //client 指向的类型是 CameraDeviceClient,其实例则是最终的返回结果。

    return ret;

}



connectHelper 内容较多,忽略掉我们还无需关注的地方分析:


template<class CALLBACK, class CLIENT> Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const String8& cameraId, int halVersion, const String16& clientPackageName, int clientUid, int clientPid,

        apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly, /*out*/sp<CLIENT>& device) {

    binder::Status ret = binder::Status::ok();



    String8 clientName8(clientPackageName); /* Do something in */ ...... /* Do something out */ sp<BasicClient> tmp = nullptr; //调用 makeClient 生成 CameraDeviceClient 实例。

        if(!(ret = makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid,

                clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel, /*out*/&tmp)).isOk()) { return ret;

        } //初始化 CLIENT 实例。注意此处的模板类型 CLIENT 即是 CameraDeviceClient,传入的参数 mCameraProviderManager 则是与 HAL service 有关。 

        client = static_cast<CLIENT*>(tmp.get());



        LOG_ALWAYS_FATAL_IF(client.get() == nullptr, "%s: CameraService in invalid state",

                __FUNCTION__);



        err = client->initialize(mCameraProviderManager); /* Do something in */ ...... /* Do something out */



    // Important: release the mutex here so the client can call back into the service from its // destructor (can be at the end of the call)

    device = client; return ret;

} 



makeClient 主要是根据 API 版本以及 HAL 版本来选择生成具体的 Client 实例,Client 就沿着前面分析下来的路径返回到 CameraDeviceImpl 实例中,被保存到 mRemoteDevice。


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) { // 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: /* Do something in */ ...... /* Do something out */

          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 route

                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get()); *client = new Camera2Client(cameraService, tmp, packageName, cameraIdToInt(cameraId),

                        facing, clientPid, clientUid, servicePid, legacyMode);

            } else { // Camera2 API route : 实例化了 CameraDeviceClient 类作为 Client(注意此处构造传入了 ICameraDeviceCallbacks,这是连接到 CameraDeviceImpl 的远端回调)

                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

            ALOGE("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 { /* Do something in */ ...... /* Do something out */ } return Status::ok();

}



至此,打开相机流程中,从 App 到 CameraService 的调用逻辑基本上就算走完了。

简图总结:

image

Ps:

  • CameraManagerGlobal 是真正的实现层,它与 JAVA 层的 CameraService 创建连接,从而创建相机的连路。

  • CameraDeviceImpl 相当于运行上下文,它取代了 Android N 之前的 JNI 层。

2.3 从 CameraService 到 HAL Service


由于 Android O 中加入了 Treble 机制,CameraServer 一端主体为 CameraService,它将会寻找现存的 Provider service,将其加入到内部的 CameraProviderManager 中进行管理,相关操作都是通过远端调用进行的。

而 Provider service 一端的主体为 CameraProvider,它在初始化时就已经连接到 libhardware 的 Camera HAL 实现层,并以 CameraModule 来进行管理。

进程的启动后,连路的 “载体” 就搭建完成了(需要注意,此时 QCamera3HWI 还未创建),可用下图简单表示:

而在打开相机时,该层的完整连路会被创建出来,主要调用逻辑如下图:

上回讲到,在 CameraService::makeClient 中,实例化了一个 CameraDeviceClient。现在我们就从它的构造函数开始,继续探索打开相机的流程。

这一部分主要活动在 Runtime 层,这里分成 CameraService 与 HAL Service 两侧来分析。

2.3.1 CameraDeviceClient

frameworks\av\services\camera\libcameraservice\api2\CameraDeviceClient.cpp


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, cameraFacing, clientPid, clientUid, servicePid),  //继承它的父类 Camera2ClientBase 

    mInputStream(),

    mStreamingRequestId(REQUEST_ID_NONE),

    mRequestIdCounter(0),

    mPrivilegedClient(false) { char value[PROPERTY_VALUE_MAX];

    property_get("persist.camera.privapp.list", value, "");

    String16 packagelist(value); if (packagelist.contains(clientPackageName.string())) {

        mPrivilegedClient = true;

    }



    ATRACE_CALL();

    ALOGI("CameraDeviceClient %s: Opened", cameraId.string());

}



CameraService 在创建 CameraDeviceClient 之后,会调用它的初始化函数:


//对外提供调用的初始化函数接口 initialize。

status_t CameraDeviceClient::initialize(sp<CameraProviderManager> manager) { return initializeImpl(manager);

} //初始化的具体实现函数,模板 TProviderPtr 在此处即是 CameraProviderManager 类。

template<typename TProviderPtr>

//首先将父类初始化,注意此处传入了 CameraProviderManager。

status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr) {

    ATRACE_CALL();

    status_t res;



    res = Camera2ClientBase::initialize(providerPtr); if (res != OK) { return res;

    } //这里是关于 FrameProcessor 的创建与初始化配置等等

 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); return OK;

}



2.3.2 Camera2ClientBase

frameworks\av\services\camera\libcameraservice\common\Camera2ClientBase.cpp**


template <typename TClientBase> //模板 TClientBase,在 CameraDeviceClient 继承 Camera2ClientBase 时被指定为 CameraDeviceClientBase。

Camera2ClientBase<TClientBase>::Camera2ClientBase( //构造的相关参数,以及初始化列表,这里面需要注意 TCamCallbacks 在 CameraDeviceClientBase 中被指定为了 ICameraDeviceCallbacks。 

        const sp<CameraService>& cameraService, const sp<TCamCallbacks>& remoteCallback, const String16& clientPackageName, const String8& cameraId, int cameraFacing, int clientPid,

        uid_t clientUid, int servicePid):

        TClientBase(cameraService, remoteCallback, clientPackageName,

                cameraId, cameraFacing, clientPid, clientUid, servicePid),

        mSharedCameraCallbacks(remoteCallback),

        mDeviceVersion(cameraService->getDeviceVersion(TClientBase::mCameraIdStr)),

        mDeviceActive(false)

{

    ALOGI("Camera %s: Opened. Client: %s (PID %d, UID %d)", cameraId.string(),

            String8(clientPackageName).string(), clientPid, clientUid);



    mInitialClientPid = clientPid;

    mDevice = new Camera3Device(cameraId); //创建了一个 Camera3Device。

    LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here.");

}



回去再看看初始化函数:


template <typename TClientBase> //初始化函数接口,真正的实现部分在 initializeImpl 中。

status_t Camera2ClientBase<TClientBase>::initialize(sp<CameraProviderManager> manager) { return initializeImpl(manager);

} //TClientBase 对应 CameraDeviceClientBase,而 TProviderPtr 对应的是 CameraProviderManager。

template <typename TClientBase> template <typename TProviderPtr> status_t Camera2ClientBase<TClientBase>::initializeImpl(TProviderPtr providerPtr) {

    ATRACE_CALL();

    ALOGV("%s: Initializing client for camera %s", __FUNCTION__,

          TClientBase::mCameraIdStr.string());

    status_t res; // Verify ops permissions

    res = TClientBase::startCameraOps(); //调用 CameraDeviceClientBase 的 startCameraOps 方法,检查 ops 的权限。

    if (res != OK) { return res;

    } if (mDevice == NULL) {

        ALOGE("%s: Camera %s: No device connected",

                __FUNCTION__, TClientBase::mCameraIdStr.string()); return NO_INIT;

    }



    res = mDevice->initialize(providerPtr); //初始化 Camera3Device 的实例,注意此处传入了 CameraProviderManager。

    if (res != OK) {

        ALOGE("%s: Camera %s: unable to initialize device: %s (%d)",

                __FUNCTION__, TClientBase::mCameraIdStr.string(), strerror(-res), res); return res;

    } //在 Camera3Device 实例中设置 Notify 回调。

    wp<CameraDeviceBase::NotificationListener> weakThis(this);

    res = mDevice->setNotifyCallback(weakThis); return OK;

}



2.3.3 Camera3Device

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)

{

    ATRACE_CALL();

  //在这个观察构造函数中设定了两个回调接口:

    camera3_callback_ops::notify = &sNotify;

    camera3_callback_ops::process_capture_result = &sProcessCaptureResult;

    ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());

}



其初始化函数篇幅较长,这里省略掉了关于 RequestMetadataQueue 的相关操作。


status_t Camera3Device::initialize(sp<CameraProviderManager> manager) {

    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;

    ATRACE_BEGIN("CameraHal::openSession");

    status_t res = manager->openSession(mId.string(), this, //调用CameraProviderManager的openSession方法,开启了远端的**Session**

            /*out*/ &session);

    ATRACE_END(); if (res != OK) {

        SET_ERR_L("Could not open camera session: %s (%d)", strerror(-res), res); return res;

    } /* Do something in */ ...... /* Do something out */



    return initializeCommonLocked();

}



2.3.4 CameraProviderManager

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, //首先调用 findDeviceInfoLocked,获取 HAL3 相关的 DeviceInfo3

            /*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; //通过远端调用 CameraDevice 的 open 方法,创建 CameraDeviceSession 实例并将其本地调用接口通过入参 session 返回。

    ret = deviceInfo3->mInterface->open(callback, [&status, &session]

            (Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {

                status = s; if (status == Status::OK) { *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;

    } return mapToStatusT(status);

}



2.3.5 CameraDevice

hardware\interfaces\camera\device\3.2\default\CameraDevice.cpp

CameraDevice 的实例实际上在初始化 HAL Service 之后就存在了。 前面说到,通过 CameraProviderManager 中的 deviceInfo 接口,调用远端 CameraDevice 实例的 open 方法,下面就来看看它的代码实现:


Return<void> CameraDevice::open(const sp<ICameraDeviceCallback>& callback, open_cb _hidl_cb)  {

    Status status = initStatus();

    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); return Void();

    } if (status != Status::OK) { /* Do something in */ ...... /* Do something out */ } else {

        mLock.lock(); /* Do something in */ ...... /* Do something out */



        /** Open HAL device */ status_t res;

        camera3_device_t *device;



        ATRACE_BEGIN("camera3->open");

        res = mModule->open(mCameraId.c_str(), //注意 mModule 是在 HAL Service 初始化时就已经配置好的,它对从libhardware库中加载的 Camera HAL 接口进行了一层封装,从这里往下就会一路走到 QCamera3HWI 的构造流程去。

                reinterpret_cast<hw_device_t**>(&device));

        ATRACE_END(); /* Do something in */ ...... /* Do something out */



     //创建 session 并让内部成员 mSession 持有,具体实现的函数为 creatSession。

        session = createSession(

                device, info.static_camera_characteristics, callback); /* Do something in */ ...... /* Do something out */ 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();

    }

    _hidl_cb(status, session->getInterface()); return Void();

}



而 createSession 中直接创建了一个 CameraDeviceSession。当然在其构造函数中会调用内部的初始化函数,然后会进入 HAL 接口层 QCamera3HWI 的初始化流程,至此,从 CameraService 到 HAL Service 这一部分的打开相机流程就基本走通了。

简图总结:

2.4 从  HAL Service 到 Camera  HAL


在 HAL3 中,Camera HAL 的接口转化层(以及流解析层)由 QCamera3HardwareInterface 担当,而接口层与实现层与 HAL1 中基本没什么差别,都是在 mm_camera_interface.c 与 mm_camera.c 中。

那么接口转化层的实例是何时创建的,又是怎么初始化的,创建它的时候,与接口层、实现层又有什么交互?通过下图展示的主要调用流程:

image

2.4.1 CameraModule(HAL Service)

hardware\interfaces\camera\common\1.0\default\CameraModule.cpp

上回说到,CameraDevice::open 的实现中,调用了 mModule->open,即 CameraModule::open,通过代码来看,它做的事并不多,主要是调用 mModule->common.methods->open,来进入下一层级的流程。

而这里则需要注意了,open 是一个函数指针,它指向的是 QCamera2Factory 的 camera_device_open 方法,至于为什么和 QCamera2Factory 有关,这就要回头看 HAL Service 的启动初始化流程了。


int CameraModule::open(const char* id, struct hw_device_t** device) { int res;

    ATRACE_BEGIN("camera_module->open");

    res = filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device));

    ATRACE_END(); return res;

}



2.4.2 QCamera2Factory(Camera HAL)


/*===========================================================================

 * FUNCTION   : camera_device_open

 *

 * DESCRIPTION: static function to open a camera device by its ID

 *



### 最后

对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,**从来都是我们去适应环境,而不是环境来适应我们!**

最后,我再重复一次,**如果你想成为一个优秀的 Android 开发人员,请集中精力,对基础和重要的事情做深度研究**。

**对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助**。整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

为了大家能够顺利进阶中高级、架构师,我特地为大家准备了**一套高手学习的源码和框架视频等精品Android架构师教程**,保证你学了以后保证薪资上升一个台阶。

以下是今天给大家分享的一些独家干货:

![](https://img-blog.csdnimg.cn/img_convert/8a4201502c4150c8aa2cabd818d36f8c.webp?x-oss-process=image/format,png)





**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化学习资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618156601)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

 ATRACE_BEGIN("camera_module->open");

    res = filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device));

    ATRACE_END(); return res;

}



2.4.2 QCamera2Factory(Camera HAL)


/*===========================================================================

 * FUNCTION   : camera_device_open

 *

 * DESCRIPTION: static function to open a camera device by its ID

 *



### 最后

对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,**从来都是我们去适应环境,而不是环境来适应我们!**

最后,我再重复一次,**如果你想成为一个优秀的 Android 开发人员,请集中精力,对基础和重要的事情做深度研究**。

**对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助**。整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

为了大家能够顺利进阶中高级、架构师,我特地为大家准备了**一套高手学习的源码和框架视频等精品Android架构师教程**,保证你学了以后保证薪资上升一个台阶。

以下是今天给大家分享的一些独家干货:

[外链图片转存中...(img-pjC5h7Fy-1715371994273)]





**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化学习资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618156601)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值