Android Camera Framworks C/S架构简析

Android Camera Framworks C/S架构简析

JAVA不熟悉,所以从JNI开始整理自己学习的资料

API调用native_setup方法,该方法被注册到JNI中,以实现API对JNI的调用

JNI framworks/base/core/jni/android_hardware_camera.cpp

通过函数:android_hardware_Camera_native_setup()调到

函数camera::connect()   framworks/av/camera/camera.cpp中的camera:connect请求连接cameraserver服务

cameraserver的连接

 framworks/av/camera/camera.cpp

sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
        int clientUid, int clientPid)
{
    return CameraBaseT::connect(cameraId, clientPackageName, clientUid, clientPid);
}

这里的camera类继承CameraBase<Camera>和BnCameraClient,所以调用到模版的connect函数:

该函数中通过getCameraService向servermanage获取camera的服务信息,并生成一个cameraserver服务代理BpCameraServer。该代理通过binder机制发送connect命令,当cameraserver端代理BpCameraService收到connect命令后就会执行对应的cameraservice的connect操作(具体的binder机制如何实现暂时还没有弄清楚)

framworks/av/camera/CameraBase.cpp

sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,

                                               const String16& clientPackageName,
                                               int clientUid, int clientPid)
{
    sp<TCam> c = new TCam(cameraId); //生成BnCameraClient对象
    sp<TCamCallbacks> cl = c;
    const sp<::android::hardware::ICameraService> cs = getCameraService();//生成BpCameraService对象,作为client端的server代理
    binder::Status ret;
    if (cs != nullptr) {
        TCamConnectService fnConnectService = TCamTraits::fnConnectService;
        ret = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,
                                               clientPid, /*out*/ &c->mCamera);//这里既是执行cameraservices的connect,输出结果到c->mCamera(即BnCameraClient对象)
    }
    if (ret.isOk() && c->mCamera != nullptr) {
        IInterface::asBinder(c->mCamera)->linkToDeath(c);
        c->mStatus = NO_ERROR;
    } else {
        ALOGW("An error occurred while connecting to camera %d: %s", cameraId,
                (cs != nullptr) ? "Service not available" : ret.toString8().string());
        c.clear();
    }
    return c;
}

cameraserver端受到binder发送来的connect命令后执行对应connect函数:

framworks/av/services/camera/libmmcameraservice/CameraService.cpp

Status CameraService::connect(
        const sp<ICameraClient>& cameraClient,
        int cameraId,
        const String16& clientPackageName,
        int clientUid,
        int clientPid,
        /*out*/
        sp<ICamera>* device) { //这里的参数对应上面的(cs.get()->*fnConnectService)参数


    Status ret = Status::ok();
    String8 id = String8::format("%d", cameraId);
    sp<Client> client = nullptr; //这里的BpCameraClient对象,用于参数传递返回给client
    ret = connectHelper<ICameraClient,Client>(cameraClient, id,
            CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, clientPid, API_1,
            /*legacyMode*/ false, /*shimUpdateOnly*/ false,
            /*out*/client); //具体操作实现,并把结果输出到client

    if(!ret.isOk()) {
        logRejected(id, getCallingPid(), String8(clientPackageName),
                ret.toString8());
        return ret;
    }

    *device = client; //把输出的结果赋值给用于传参的BpCameraClient对象,返回给cameraclient,作为server端的client代理
    return ret;
}

其中做具体操作的connectHelper函数实现在文件:

framworks/av/services/camera/libmmcameraservice/CameraService.h

template<class CALLBACK, class CLIENT>
binder::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);

    int originalClientPid = 0;

    sp<CLIENT> client = nullptr; // 新建client对象,用于存储输出结果,并返回给client端
    {
        std::unique_ptr<AutoConditionLock> lock =
                AutoConditionLock::waitAndAcquire(mServiceLockWrapper, DEFAULT_CONNECT_TIMEOUT_NS);

        if (shimUpdateOnly) {
            auto cameraState = getCameraState(cameraId);
            if (cameraState != nullptr) {
                if (!cameraState->getShimParams().isEmpty()) return ret;
            }
        }
        status_t err;
        sp<BasicClient> clientTmp = nullptr;
        std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;
        if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,
                IInterface::asBinder(cameraCb), clientName8, /*out*/&clientTmp,
                /*out*/&partial)) != NO_ERROR) {
            switch (err) {
                case -ENODEV:
                    return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
                            "No camera device with ID \"%s\" currently available",
                            cameraId.string());
                case -EBUSY:
                    return STATUS_ERROR_FMT(ERROR_CAMERA_IN_USE,
                            "Higher-priority client using camera, ID \"%s\" currently unavailable",
                            cameraId.string());
                default:
                    return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
                            "Unexpected error %s (%d) opening camera \"%s\"",
                            strerror(-err), err, cameraId.string());
            }
        }
        mFlashlight->prepareDeviceOpen(cameraId);
        int id = cameraIdToInt(cameraId);


        int facing = -1;
        int deviceVersion = getDeviceVersion(id, /*out*/&facing); //获取API版本,不同API版本创建不同client
        sp<BasicClient> tmp = nullptr;
        if(!(ret = makeClient(this, cameraCb, clientPackageName, id, facing, clientPid,
                clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,
                /*out*/&tmp)).isOk()) {
            return ret;
        } //创建client,具体实现在文件framworks/av/services/libmmcameraservices/CameraServices.cpp
        client = static_cast<CLIENT*>(tmp.get()); //把创建的client赋值

        if ((err = client->initialize(mModule)) != OK) 
            ALOGE("%s: Could not initialize client from HAL module.", __FUNCTION__);
//对client进行实例化,不同的API实现在不同的文件,framworks/av/servies/camera/libmmcameraservices/api
        // Update shim paremeters for legacy clients
        if (effectiveApiLevel == API_1) {
            // Assume we have always received a Client subclass for API1
            sp<Client> shimClient = reinterpret_cast<Client*>(client.get());
            String8 rawParams = shimClient->getParameters();
            CameraParameters params(rawParams);

            auto cameraState = getCameraState(cameraId);
                cameraState->setShimParams(params);
        if (shimUpdateOnly) {
            // If only updating legacy shim parameters, immediately disconnect client
            mServiceLock.unlock();
            client->disconnect();
            mServiceLock.lock();
        } else {
            // Otherwise, add client to active clients list
            finishConnectLocked(client, partial);
        }
    } 
    device = client; //最终把输出赋给devices,用于返回给cameraclient
    return ret;
}

framworks/av/services/libmmcameraservices/CameraServices.cpp

根据不同的API传见不同的camera client   (new CameraClient)  (new Camera2Client)

Status CameraService::makeClient(const sp<CameraService>& cameraService,
        const sp<IInterface>& cameraCb, const String16& packageName, int cameraId,
        int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode,
        int halVersion, int deviceVersion, apiLevel effectiveApiLevel,
        /*out*/sp<BasicClient>* client) {
        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, cameraId, 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 \"%d\" HAL version %d does not support camera2 API",
                        cameraId, 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, 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:
            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
            return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
                    "Camera device \"%d\" has unknown HAL version %d",
                    cameraId, deviceVersion);
        }
    return Status::ok();
}

CameraClient 和 Camera2Client的实例化分别实现对应在

framworks/av/service/camera/libmmcameraservices/api1/

framworks/av/service/camera/libmmcameraservices/api2/

以cameraclient为例:

status_t CameraClient::initialize(CameraModule *module) {
    int callingPid = getCallingPid();
    status_t res;
    res = startCameraOps();
    char camera_device_name[10];
    snprintf(camera_device_name, sizeof(camera_device_name), "%d", mCameraId);

    mHardware = new CameraHardwareInterface(camera_device_name); //这里创建了camera硬件接口,
    res = mHardware->initialize(module); //调用底层硬件的初始化方法
 
    mHardware->setCallbacks(notifyCallback,
            dataCallback,
            dataCallbackTimestamp,
            (void *)(uintptr_t)mCameraId); //将CamerService处的回调函数注册到HAL处
    return OK;
}

mHardware = new CameraHardwareInterface(camera_device_name);这里便进入了调用HAL层的接口,

framworks/av/services/camera/libmmcameraservices/device1/CameraHardwareInterface.h

该接口包涵了对camera的控制与数据回调,控制包括:开始和停止预览与录像,拍照,对焦等,数据回调包括:预览。录像等数据,

对应上述的mHardware->initialize(module)

    status_t initialize(CameraModule *module)
    {
        camera_info info;
        status_t res = module->getCameraInfo(atoi(mName.string()), &info);
        int rc = OK;
        if (module->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_3 &&
            info.device_version > CAMERA_DEVICE_API_VERSION_1_0) {
            // Open higher version camera device as HAL1.0 device.
            rc = module->openLegacy(mName.string(),
                                     CAMERA_DEVICE_API_VERSION_1_0,
                                     (hw_device_t **)&mDevice);
        } else {
            rc = module->open(mName.string(), (hw_device_t **)&mDevice); //用于open camera
        }
        initHalPreviewWindow(); //用于初始化preview的相关流opspreview_stream_ops
        return rc;
    }

对应上述的mHardware->setCallbacks

    void setCallbacks(notify_callback notify_cb,
                      data_callback data_cb,
                      data_callback_timestamp data_cb_timestamp,
                      void* user)
    {
        mNotifyCb = notify_cb;
        mDataCb = data_cb;
        mDataCbTimestamp = data_cb_timestamp;
        mCbUser = user;

        if (mDevice->ops->set_callbacks) {
            mDevice->ops->set_callbacks(mDevice,
                                   __notify_cb, //消息回调
                                   __data_cb, //数据回调
                                   __data_cb_timestamp, //时间戳回调
                                   __get_memory, //内存相关操作回调
                                   this);
        }
    }

module->open(mName.string(), (hw_device_t **)&mDevice)会调用到:

framworks/av/services/libmmcameraservice/common/CameraModule.cpp

int CameraModule::open(const char* id, struct hw_device_t** device) {
    int res;
    res = filterOpenErrorCode(mModule->common.methods->open(&mModule->common, id, device)); //通过mModule就调用到HAL
    return res;
}

至此,就进入了camera HAL层










猜你喜欢

转载自blog.csdn.net/wing12345678910/article/details/79088511