美文网首页android Cameracamera
Android Camera原理之openCamera模块(一)

Android Camera原理之openCamera模块(一)

作者: 码上就说 | 来源:发表于2018-11-08 11:12 被阅读962次

    《Android Camera架构》
    《Android Camera进程间通信类总结》
    《Android Camera模块解析之拍照》
    《Android Camera模块解析之视频录制》
    《Android Camera原理之CameraDeviceCallbacks回调模块》
    《Android Camera原理之openCamera模块(一)》
    《Android Camera原理之openCamera模块(二)》
    《Android Camera原理之createCaptureSession模块》
    《Android Camera原理之setRepeatingRequest与capture模块》
    《Android Camera原理之编译》
    《Android Camera原理之camera provider启动》
    《Android Camera原理之cameraserver与cameraprovider是怎样联系的》
    《Android Camera原理之camera service与camera provider session会话与capture request轮转》
    《Android Camera原理之camera HAL底层数据结构与类总结》
    《Android Camera原理之camera service类与接口关系》

    我们平时开发,知道怎么调度api,怎么调起camera,怎么调用camera的实例来操作camera就可以了,但是这些调度的背后都做了什么事情,我们可能不太清楚,本文打算从openCamera这个调用谈起,展开说下camera调起之后底层是怎么工作的?

    Camera操作过程中最重要的四个步骤:

    • CameraManager-->openCamera ---> 打开相机
    • CameraDeviceImpl-->createCaptureSession ---> 创建捕获会话
    • CameraCaptureSession-->setRepeatingRequest ---> 设置预览界面
    • CameraDeviceImpl-->capture ---> 开始捕获图片

    1.CameraManager

    CameraManager是本地的SystemService集合中一个service,在SystemServiceRegistry中注册:

            registerService(Context.CAMERA_SERVICE, CameraManager.class,
                    new CachedServiceFetcher<CameraManager>() {
                @Override
                public CameraManager createService(ContextImpl ctx) {
                    return new CameraManager(ctx);
                }});
    

    SystemServiceRegistry中有两个HashMap集合来存储本地的SystemService数据,有一点要注意点一些,这和Binder的service不同,他们不是binder service,只是普通的调用模块,集成到一个本地service中,便于管理。

        private static final HashMap<Class<?>, String> SYSTEM_SERVICE_NAMES =
                new HashMap<Class<?>, String>();
        private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
                new HashMap<String, ServiceFetcher<?>>();
    

    2.openCamera函数

    CameraManager中两个openCamera(...),只是一个传入Handler,一个传入Executor,是想用线程池来执行Camera中耗时操作。

    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)
    
    • cameraId 是一个标识,标识当前要打开的camera
    • callback 是一个状态回调,当前camera被打开的时候,这个状态回调会被触发的。
    • handler 是传入的一个执行耗时操作的handler
    • executor 操作线程池

    了解一下openCamera的调用流程:


    openCamera流程.jpg
    2.1 openCameraDeviceUserAsync函数
    private CameraDevice openCameraDeviceUserAsync(String cameraId,
                CameraDevice.StateCallback callback, Executor executor, final int uid)
                throws CameraAccessException
    {
    //......
    }
    

    返回值是CameraDevice,从《Android Camera模块解析之拍照》中讲解了Camera framework模块中主要类之间的关系,CameraDevice是抽象类,CameraDeviceImpl是其实现类,就是要获取CameraDeviceImpl的实例。
    这个函数的主要作用就是到底层获取相机设备的信息,并获取当前指定cameraId的设备实例。
    本函数的主要工作可以分为下面五点:

    • 获取当前cameraId指定相机的设备信息
    • 利用获取相机的设备信息创建CameraDeviceImpl实例
    • 调用远程CameraService获取当前相机的远程服务
    • 将获取的远程服务设置到CameraDeviceImpl实例中
    • 返回CameraDeviceImpl实例
    2.2 获取当前cameraId指定相机的设备信息
    CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
    

    一句简单的调用,返回值是CameraCharacteristics,CameraCharacteristics提供了CameraDevice的各种属性,可以通过getCameraCharacteristics函数来查询。

        public CameraCharacteristics getCameraCharacteristics(@NonNull String cameraId)
                throws CameraAccessException {
            CameraCharacteristics characteristics = null;
            if (CameraManagerGlobal.sCameraServiceDisabled) {
                throw new IllegalArgumentException("No cameras available on device");
            }
            synchronized (mLock) {
                ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
                if (cameraService == null) {
                    throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
                            "Camera service is currently unavailable");
                }
                try {
                    if (!supportsCamera2ApiLocked(cameraId)) {
                        int id = Integer.parseInt(cameraId);
                        String parameters = cameraService.getLegacyParameters(id);
                        CameraInfo info = cameraService.getCameraInfo(id);
                        characteristics = LegacyMetadataMapper.createCharacteristics(parameters, info);
                    } else {
                        CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId);
                        characteristics = new CameraCharacteristics(info);
                    }
                } catch (ServiceSpecificException e) {
                    throwAsPublicException(e);
                } catch (RemoteException e) {
                    throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
                            "Camera service is currently unavailable", e);
                }
            }
            return characteristics;
        }
    

    一个关键的函数----> supportsCamera2ApiLocked(cameraId),这个函数的意思是 当前camera服务是否支持camera2 api,如果支持,返回true,如果不支持,返回false。

        private boolean supportsCameraApiLocked(String cameraId, int apiVersion) {
            /*
             * Possible return values:
             * - NO_ERROR => CameraX API is supported
             * - CAMERA_DEPRECATED_HAL => CameraX API is *not* supported (thrown as an exception)
             * - Remote exception => If the camera service died
             *
             * Anything else is an unexpected error we don't want to recover from.
             */
            try {
                ICameraService cameraService = CameraManagerGlobal.get().getCameraService();
                // If no camera service, no support
                if (cameraService == null) return false;
    
                return cameraService.supportsCameraApi(cameraId, apiVersion);
            } catch (RemoteException e) {
                // Camera service is now down, no support for any API level
            }
            return false;
        }
    

    调用的CameraService对应的是ICameraService.aidl,对应的实现类在frameworks/av/services/camera/libcameraservice/CameraService.h
    下面是CameraManager与CameraService之间的连接关系图示:

    CameraService生成.jpg
    CameraManagerGlobal是CameraManager中的内部类,服务端在native层,《Android Camera模块解析之拍照》中camera2介绍的时候已经说明了当前cameraservice是放在frameworks/av/services/camera/libcameraservice/中的,编译好了之后会生成一个libcameraservices.so的共享库。熟悉camera代码,首先应该熟悉camera架构的代码。

    这儿监测的是当前camera架构是基于HAL什么版本的,看下面的switch判断:

    • 当前device是基于HAL1.0 HAL3.0 HAL3.1,并且apiversion不是API_VERSION_2,此时支持,这里要搞清楚了,这里的API_VERSION_2不是api level 2,而是camera1还是camera2.
    • 当前device是基于HAL3.2 HAL3.3 HAL3.4,此时支持
    • 目前android版本,正常情况下都是支持camera2的
    Status CameraService::supportsCameraApi(const String16& cameraId, int apiVersion,
            /*out*/ bool *isSupported) {
        ATRACE_CALL();
    
        const String8 id = String8(cameraId);
    
        ALOGV("%s: for camera ID = %s", __FUNCTION__, id.string());
    
        switch (apiVersion) {
            case API_VERSION_1:
            case API_VERSION_2:
                break;
            default:
                String8 msg = String8::format("Unknown API version %d", apiVersion);
                ALOGE("%s: %s", __FUNCTION__, msg.string());
                return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
        }
    
        int deviceVersion = getDeviceVersion(id);
        switch(deviceVersion) {
            case CAMERA_DEVICE_API_VERSION_1_0:
            case CAMERA_DEVICE_API_VERSION_3_0:
            case CAMERA_DEVICE_API_VERSION_3_1:
                if (apiVersion == API_VERSION_2) {
                    ALOGV("%s: Camera id %s uses HAL version %d <3.2, doesn't support api2 without shim",
                            __FUNCTION__, id.string(), deviceVersion);
                    *isSupported = false;
                } else { // if (apiVersion == API_VERSION_1) {
                    ALOGV("%s: Camera id %s uses older HAL before 3.2, but api1 is always supported",
                            __FUNCTION__, id.string());
                    *isSupported = true;
                }
                break;
            case CAMERA_DEVICE_API_VERSION_3_2:
            case CAMERA_DEVICE_API_VERSION_3_3:
            case CAMERA_DEVICE_API_VERSION_3_4:
                ALOGV("%s: Camera id %s uses HAL3.2 or newer, supports api1/api2 directly",
                        __FUNCTION__, id.string());
                *isSupported = true;
                break;
            case -1: {
                String8 msg = String8::format("Unknown camera ID %s", id.string());
                ALOGE("%s: %s", __FUNCTION__, msg.string());
                return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
            }
            default: {
                String8 msg = String8::format("Unknown device version %x for device %s",
                        deviceVersion, id.string());
                ALOGE("%s: %s", __FUNCTION__, msg.string());
                return STATUS_ERROR(ERROR_INVALID_OPERATION, msg.string());
            }
        }
    
        return Status::ok();
    }
    

    采用camera2 api来获取相机设备的信息。

    CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId);
    characteristics = new CameraCharacteristics(info);
    
    getCameraCharacteristics调用流程.jpg

    其中DeviceInfo3是CameraProviderManager::ProviderInfo::DeviceInfo3,CameraProviderManager中的结构体,最终返回的是CameraMetadata类型,它是一个Parcelable类型,native中对应的代码是frameworks/av/camera/include/camera/CameraMetadata.h,java中对应的是frameworks/base/core/java/android/hardware/camera2/impl/CameraMetadataNative.java,Parcelable类型是可以跨进程传输的。下面是在native中定义CameraMetadata为CameraMetadataNative

    namespace hardware {
    namespace camera2 {
    namespace impl {
    using ::android::CameraMetadata;
    typedef CameraMetadata CameraMetadataNative;
    }
    }
    }
    

    我们关注其中的一个调用函数:

    status_t CameraProviderManager::getCameraCharacteristicsLocked(const std::string &id,
            CameraMetadata* characteristics) const {
        auto deviceInfo = findDeviceInfoLocked(id, /*minVersion*/ {3,0}, /*maxVersion*/ {4,0});
        if (deviceInfo == nullptr) return NAME_NOT_FOUND;
    
        return deviceInfo->getCameraCharacteristics(characteristics);
    }
    

    发现了调用了一个findDeviceInfoLocked(...)函数,返回类型是一个DeviceInfo结构体,CameraProviderManager.h中定义了三个DeviceInfo结构体,除了DeviceInfo之外,还有DeviceInfo1与DeviceInfo3,他们都继承DeviceInfo,其中DeviceInfo1为HALv1服务,DeviceInfo3为HALv3-specific服务,都是提供camera device一些基本信息。这里主要看下findDeviceInfoLocked(...)函数:

    CameraProviderManager::ProviderInfo::DeviceInfo* CameraProviderManager::findDeviceInfoLocked(
            const std::string& id,
            hardware::hidl_version minVersion, hardware::hidl_version maxVersion) const {
        for (auto& provider : mProviders) {
            for (auto& deviceInfo : provider->mDevices) {
                if (deviceInfo->mId == id &&
                        minVersion <= deviceInfo->mVersion && maxVersion >= deviceInfo->mVersion) {
                    return deviceInfo.get();
                }
            }
        }
        return nullptr;
    }
    

    这儿的是mProviders是ProviderInfo类型的列表,这个ProviderInfo也是CameraProviderManager.h中定义的结构体,并且上面3种DeviceInfo都是定义在ProviderInfo里面的。下面给出了ProviderInfo的代码大纲,裁剪了很多代码,但是我们还是能看到核心的代码:ProviderInfo是管理当前手机的camera device设备的,通过addDevice保存在mDevices中,接下来我们看下这个addDevice是如何工作的。

        struct ProviderInfo :
                virtual public hardware::camera::provider::V2_4::ICameraProviderCallback,
                virtual public hardware::hidl_death_recipient
        {
        //......
            ProviderInfo(const std::string &providerName,
                    sp<hardware::camera::provider::V2_4::ICameraProvider>& interface,
                    CameraProviderManager *manager);
            ~ProviderInfo();
    
            status_t initialize();
    
            const std::string& getType() const;
    
            status_t addDevice(const std::string& name,
                    hardware::camera::common::V1_0::CameraDeviceStatus initialStatus =
                    hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT,
                    /*out*/ std::string *parsedId = nullptr);
    
            // ICameraProviderCallbacks interface - these lock the parent mInterfaceMutex
            virtual hardware::Return<void> cameraDeviceStatusChange(
                    const hardware::hidl_string& cameraDeviceName,
                    hardware::camera::common::V1_0::CameraDeviceStatus newStatus) override;
            virtual hardware::Return<void> torchModeStatusChange(
                    const hardware::hidl_string& cameraDeviceName,
                    hardware::camera::common::V1_0::TorchModeStatus newStatus) override;
    
            // hidl_death_recipient interface - this locks the parent mInterfaceMutex
            virtual void serviceDied(uint64_t cookie, const wp<hidl::base::V1_0::IBase>& who) override;
    
            // Basic device information, common to all camera devices
            struct DeviceInfo {
                //......
            };
            std::vector<std::unique_ptr<DeviceInfo>> mDevices;
            std::unordered_set<std::string> mUniqueCameraIds;
            int mUniqueDeviceCount;
    
            // HALv1-specific camera fields, including the actual device interface
            struct DeviceInfo1 : public DeviceInfo {
                //......
            };
    
            // HALv3-specific camera fields, including the actual device interface
            struct DeviceInfo3 : public DeviceInfo {
                //......
            };
    
        private:
            void removeDevice(std::string id);
        };
    
    • mProviders是如何添加的?
    • addDevice是如何工作的?

    mProviders添加的流程:
    1.CameraService --> onFirstRef()
    2.CameraService --> enumerateProviders()
    3.CameraProviderManager --> initialize(this)
    initialize(...)函数原型是:

    status_t initialize(wp<StatusListener> listener,
                ServiceInteractionProxy *proxy = &sHardwareServiceInteractionProxy);
    

    第2个参数默认是sHardwareServiceInteractionProxy类型,

        struct ServiceInteractionProxy {
            virtual bool registerForNotifications(
                    const std::string &serviceName,
                    const sp<hidl::manager::V1_0::IServiceNotification>
                    &notification) = 0;
            virtual sp<hardware::camera::provider::V2_4::ICameraProvider> getService(
                    const std::string &serviceName) = 0;
            virtual ~ServiceInteractionProxy() {}
        };
    
        // Standard use case - call into the normal generated static methods which invoke
        // the real hardware service manager
        struct HardwareServiceInteractionProxy : public ServiceInteractionProxy {
            virtual bool registerForNotifications(
                    const std::string &serviceName,
                    const sp<hidl::manager::V1_0::IServiceNotification>
                    &notification) override {
                return hardware::camera::provider::V2_4::ICameraProvider::registerForNotifications(
                        serviceName, notification);
            }
            virtual sp<hardware::camera::provider::V2_4::ICameraProvider> getService(
                    const std::string &serviceName) override {
                return hardware::camera::provider::V2_4::ICameraProvider::getService(serviceName);
            }
        };
    

    hardware::camera::provider::V2_4::ICameraProvider::getService(serviceName)出处在./hardware/interfaces/camera/provider/2.4/default/CameraProvider.cpp,传入的参数可能是下面两种的一个:
    const std::string kLegacyProviderName("legacy/0"); 代表 HALv1
    const std::string kExternalProviderName("external/0"); 代码HALv3-specific

    ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
        if (strcmp(name, kLegacyProviderName) == 0) {
            CameraProvider* provider = new CameraProvider();
            if (provider == nullptr) {
                ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
                return nullptr;
            }
            if (provider->isInitFailed()) {
                ALOGE("%s: camera provider init failed!", __FUNCTION__);
                delete provider;
                return nullptr;
            }
            return provider;
        } else if (strcmp(name, kExternalProviderName) == 0) {
            ExternalCameraProvider* provider = new ExternalCameraProvider();
            return provider;
        }
        ALOGE("%s: unknown instance name: %s", __FUNCTION__, name);
        return nullptr;
    }
    

    addDevice是如何工作的?
    1.CameraProviderManager::ProviderInfo::initialize()初始化的时候是检查当前的camera device,检查的执行函数是:

        std::vector<std::string> devices;
        hardware::Return<void> ret = mInterface->getCameraIdList([&status, &devices](
                Status idStatus,
                const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) {
            status = idStatus;
            if (status == Status::OK) {
                for (size_t i = 0; i < cameraDeviceNames.size(); i++) {
                    devices.push_back(cameraDeviceNames[i]);
                }
            } });
    

    最终调用到./hardware/interfaces/camera/provider/2.4/default/CameraProvider.cpp中的getCameraIdList函数:CAMERA_DEVICE_STATUS_PRESENT表明当前的camera是可用的,mCameraStatusMap存储了所有的camera 设备列表。

    Return<void> CameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb)  {
        std::vector<hidl_string> deviceNameList;
        for (auto const& deviceNamePair : mCameraDeviceNames) {
            if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) {
                deviceNameList.push_back(deviceNamePair.second);
            }
        }
        hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
        _hidl_cb(Status::OK, hidlDeviceNameList);
        return Void();
    }
    

    我们理一下整体的调用结构:


    Camera分层体系.jpg

    1.上面谈的camera2 api就是在framework层的,在应用程序进程中。
    2.CameraService,是camera2 api binder IPC通信方式调用到服务端的,camera相关的操作都在在服务端进行。所在的位置就是./frameworks/av/services/camera/下面
    3.服务端也只是一个桥梁,service也会调用到HAL,硬件抽象层,具体位置在./hardware/interfaces/camera/provider/2.4
    4.camera driver,底层的驱动层了,这是真正操作硬件的地方。

    2.3 利用获取相机的设备信息创建CameraDeviceImpl实例
    android.hardware.camera2.impl.CameraDeviceImpl deviceImpl =
                        new android.hardware.camera2.impl.CameraDeviceImpl(
                            cameraId,
                            callback,
                            executor,
                            characteristics,
                            mContext.getApplicationInfo().targetSdkVersion);
    

    创建CameraDevice实例,传入了刚刚获取的characteristics参数(camera设备信息赋值为CameraDevice实例)。这个实例接下来还是使用,使用的时候再谈一下。

    2.4 调用远程CameraService获取当前相机的远程服务
                        // 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);
    

    这个函数的主要目的就是连接当前的cameraDevice设备。调用到CameraService::connectDevice中。


    connectDevice调用流程.jpg
    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;
    }
    
    • connectDevice函数的第5个参数就是当前binder ipc的返回值,我们connectDevice之后,会得到一个cameraDeviceClient对象,这个对象会返回到应用程序进程中。我们接下来主要看看这个对象是如何生成的。
    • validateConnectLocked:检查当前的camera device是否可用,这儿的判断比较简单,只是简单判断当前设备是否存在。
    • handleEvictionsLocked:处理camera独占情况,主要的工作是当前的cameradevice如果已经被其他的设备使用了,或者是否有比当前调用优先级更高的调用等等,在执行完这个函数之后,才能完全判断当前的camera device是可用的,并且开始获取camera device的一些信息开始工作了。
    • CameraFlashlight-->prepareDeviceOpen:此时准备连接camera device 了,需要判断一下如果当前的camera device有可用的flashlight,那就要开始准备好了,但是flashlight被占用的那就没有办法了。只是一个通知作用。
    • getDeviceVersion:判断一下当前的camera device的version 版本,主要判断在CameraProviderManager::getHighestSupportedVersion函数中,这个函数中将camera device支持的最高和最低版本查清楚,然后我们判断当前的camera facing,只有两种情况CAMERA_FACING_BACK = 0与CAMERA_FACING_FRONT = 1,这些都是先置判断条件,只有这些检查都通过,说明当前camera device是确实可用的。
    • makeClient:是根据当前的CAMERA_DEVICE_API_VERSION来判断的,当前最新的HAL架构都是基于HALv3的,所以我们采用的client都是CameraDeviceClient
    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) {
    
        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:
                if (effectiveApiLevel == API_1) {  // Camera1 API route
                    sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
                    *client = new CameraClient(cameraService, tmp, packageName,
                            api1CameraId, facing, clientPid, clientUid,
                            getpid(), legacyMode);
                } else { // Camera2 API route
                    ALOGW("Camera using old HAL version: %d", deviceVersion);
                    return STATUS_ERROR_FMT(ERROR_DEPRECATED_HAL,
                            "Camera device \"%s\" HAL version %d does not support camera2 API",
                            cameraId.string(), deviceVersion);
                }
                break;
              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,
                            cameraId, api1CameraId,
                            facing, clientPid, clientUid,
                            servicePid, legacyMode);
                } else { // Camera2 API route
                    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 {
            // A particular HAL version is requested by caller. Create CameraClient
            // based on the requested HAL version.
            if (deviceVersion > CAMERA_DEVICE_API_VERSION_1_0 &&
                halVersion == CAMERA_DEVICE_API_VERSION_1_0) {
                // Only support higher HAL version device opened as HAL1.0 device.
                sp<ICameraClient> tmp = static_cast<ICameraClient*>(cameraCb.get());
                *client = new CameraClient(cameraService, tmp, packageName,
                        api1CameraId, facing, clientPid, clientUid,
                        servicePid, legacyMode);
            } else {
                // Other combinations (e.g. HAL3.x open as HAL2.x) are not supported yet.
                ALOGE("Invalid camera HAL version %x: HAL %x device can only be"
                        " opened as HAL %x device", halVersion, deviceVersion,
                        CAMERA_DEVICE_API_VERSION_1_0);
                return STATUS_ERROR_FMT(ERROR_ILLEGAL_ARGUMENT,
                        "Camera device \"%s\" (HAL version %d) cannot be opened as HAL version %d",
                        cameraId.string(), deviceVersion, halVersion);
            }
        }
        return Status::ok();
    }
    
    CameraClient.jpg

    CameraClient与Camera2Client是之前系统版本使用的camera client对象,现在都使用CameraDeviceClient了
    BnCamera --> ./frameworks/av/camera/include/camera/android/hardware/ICamera.h
    ICamera --> ./frameworks/av/camera/include/camera/android/hardware/ICamera.h
    BnCameraDeviceUser --> android/hardware/camera2/BnCameraDeviceUser.h 这是ICameraDeviceUser.aidl自动生成的binder 对象。所以最终得到的client对象就是ICameraDeviceUser.Stub对象。

    2.5 将获取的远程服务设置到CameraDeviceImpl实例中
    deviceImpl.setRemoteDevice(cameraUser);
    device = deviceImpl;
    

    这个cameraUser就是cameraservice端设置的ICameraDeviceUser.Stub对象,

        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);
    
                IBinder remoteDeviceBinder = remoteDevice.asBinder();
                // For legacy camera device, remoteDevice is in the same process, and
                // asBinder returns NULL.
                if (remoteDeviceBinder != null) {
                    try {
                        remoteDeviceBinder.linkToDeath(this, /*flag*/ 0);
                    } catch (RemoteException e) {
                        CameraDeviceImpl.this.mDeviceExecutor.execute(mCallOnDisconnected);
    
                        throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
                                "The camera device has encountered a serious error");
                    }
                }
    
                mDeviceExecutor.execute(mCallOnOpened);
                mDeviceExecutor.execute(mCallOnUnconfigured);
            }
        }
    

    这个mRemoteDevice是应用程序进程和android camera service端之间链接的桥梁,上层操作camera的方法会通过调用mRemoteDevice来调用到camera service端来实现操作底层camera驱动的目的。

    小结

    本文通过我们熟知的openCamera函数讲起,openCamera串起应用程序和cameraService之间的联系,通过研究cameraservice代码,我们知道了底层是如何通过HAL调用camera驱动设备的。下面会逐渐深入讲解camera底层知识,不足之处,敬请谅解。

    相关文章

      网友评论

        本文标题:Android Camera原理之openCamera模块(一)

        本文链接:https://www.haomeiwen.com/subject/zpkexqtx.html