Camera2-HAL3-框架分析


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。


                
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值