分享

Camera的Binder实现

 新用户8389DdzY 2021-09-22

Camera API2怎么调用cameraservice

Cameraservice继承BnCameraService 类,这个类中有onTransact函数

获取CameraManager对象

CameraManager mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);

openCamera

mCameraManager.openCamera(cameraId, callback, handler);

调用的是CameraManager 中的 openCameraDeviceUserAsync 方法

    private CameraDevice openCameraDeviceUserAsync(String cameraId,
            CameraDevice.StateCallback callback, Executor executor, final int uid)
            throws CameraAccessException {... ...
                    // 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);... ...
 
        return device;
    }

ICameraService是 aidl,来看一下它的对象实例化过程,它的实例化时在 CameraManager 的内部类 CameraManagerGlobal 的connectCameraServiceLocked 方法中

        private void connectCameraServiceLocked() {
            // Only reconnect if necessary
            if (mCameraService != null || sCameraServiceDisabled) return;
 
            Log.i(TAG, "Connecting to camera service");
 
            IBinder cameraServiceBinder = ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME);
            if (cameraServiceBinder == null) {
                // Camera service is now down, leave mCameraService as null
                return;
            }
            try {
                cameraServiceBinder.linkToDeath(this, /*flags*/ 0);
            } catch (RemoteException e) {
                // Camera service is now down, leave mCameraService as null
                return;
            }
 
            ICameraService cameraService = ICameraService.Stub.asInterface(cameraServiceBinder);... ...
        }

ServiceManager.getService(CAMERA_SERVICE_BINDER_NAME)也是通过 aidl 获取 CameraService 在 Native 中注册的 binder 对象,然后我们通过这个 binder 对象实例化 ICameraService 对象,我们看一下 ICameraService.aidl 通过编译生成的ICameraService.java 中 asInterface 方法的实现(文件路径:/android/out/soong/.intermediates/frameworks/base/framework/android_common/gen/aidl/frameworks/av/camera/aidl/android/hardware/ICameraService.java)

public static android.hardware.ICameraService asInterface(android.os.IBinder obj) {
    if ((obj == null)) {
        return null;
    }
    android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
    if (((iin != null) && (iin instanceof android.hardware.ICameraService))) {
        return ((android.hardware.ICameraService) iin);
    }
    return new android.hardware.ICameraService.Stub.Proxy(obj);}

首先会通过queryLocalInterface根据标识DESCRIPTOR在本地搜索接口,搜索到的是 ICameraService 内部类 Stub 构造函数内调用 attachInterface 与 binder 绑定的接口

public Stub() {
    this.attachInterface(this, DESCRIPTOR);}

如果没有实例化 Stub 对象的话则会返回代理类的对象(ICameraService 就没有 Stub 对象),代理类也是 Aidl 自动生成的;所以调用的 connectDevice 方法其实是 Proxy 类的

@Overridepublic android.hardware.camera2.ICameraDeviceUser connectDevice(android.hardware.camera2.ICameraDeviceCallbacks callbacks, java.lang.String cameraId, java.lang.String opPackageName, int clientUid) throws android.os.RemoteException {
    android.os.Parcel _data = android.os.Parcel.obtain();
    android.os.Parcel _reply = android.os.Parcel.obtain();
    android.hardware.camera2.ICameraDeviceUser _result;
    try {
        _data.writeInterfaceToken(DESCRIPTOR);
        _data.writeStrongBinder((((callbacks != null)) ? (callbacks.asBinder()) : (null)));
        _data.writeString(cameraId);
        _data.writeString(opPackageName);
        _data.writeInt(clientUid);
        mRemote.transact(Stub.TRANSACTION_connectDevice, _data, _reply, 0);
        _reply.readException();
        _result = android.hardware.camera2.ICameraDeviceUser.Stub.asInterface(_reply.readStrongBinder());
    } finally {
        _reply.recycle();
        _data.recycle();
    }
    return _result;}

调用transact 方法发起 RPC (远程过程调用)请求,同时当前线程挂起,然后服务端的 onTransact 方法会被调用,直到 RPC 过程返回,当前线程继续执行,从 _reply 中取出 RPC 过程中返回的结果

public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
            java.lang.String descriptor = DESCRIPTOR;
            switch (code) {... ...
                case TRANSACTION_connectDevice: {
                    data.enforceInterface(descriptor);
                    android.hardware.camera2.ICameraDeviceCallbacks _arg0;
                    _arg0 = android.hardware.camera2.ICameraDeviceCallbacks.Stub.asInterface(data.readStrongBinder());
                    java.lang.String _arg1;
                    _arg1 = data.readString();
                    java.lang.String _arg2;
                    _arg2 = data.readString();
                    int _arg3;
                    _arg3 = data.readInt();
                    android.hardware.camera2.ICameraDeviceUser _result = this.connectDevice(_arg0, _arg1, _arg2, _arg3);
                    reply.writeNoException();
                    reply.writeStrongBinder((((_result != null)) ? (_result.asBinder()) : (null)));
                    return true;
                }... ...
            }
        }

对应ICameraService.java, aidl 同时也在Native 生成了 ICameraService.cpp,内有 BpCameraService (Native Proxy),及 BnCameraService 的实现;最终是在 BnCameraService 的 onTransact 方法内调用其子类 CameraService 的 connectDevice 方法实现 openCamera 的操作的

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);
 
    if(!ret.isOk()) {
        logRejected(id, getCallingPid(), String8(clientPackageName),
                ret.toString8());
        return ret;
    }
 
    *device = client;
    return ret;}



作者:trythinking
链接:https://www.jianshu.com/p/5bff9691787c
来源:简书

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多