Android Camera 三 CameraService 和 Client 链接到 HAL

Android Camera 一 源码路径

Android Camera 二 JNI JAVA和C/CPP图像数据传输流程分析

Android Camera 三 CameraService 和 Client 链接到 HAL

Android Camera 四 Camera HAL 分析

Android Camera 五 Camera HAL v1

Linux v4l2 一 应用层

Linux v4l2 二 驱动和 usb 摄像头

frameworks/av/camera/Camera.cpp

frameworks/av/camera/CameraBase.cpp

frameworks/av/services/camera/libcameraservice/CameraService.cpp

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

frameworks/av/services/camera/libcameraservice/common/Camera2ClientBase.cpp

frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp

 

在上一章 Android camera 二 中提到的 JNI 方法。

JNI是 JAVA 层和 native 层通讯的桥梁。在 Android 中叫 NDK (Native Development Kit )。

android_hardware_Camera_native_setup 中调用了 connect 方法,最终目标是连接到相机设备,并打开相机镜头。

// android_hardware_Camera.cpp
static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
    jobject weak_this, jint cameraId, jint halVersion, jstring clientPackageName)
{
    ......
 
    sp<Camera> camera;
    if (halVersion == CAMERA_HAL_API_VERSION_NORMAL_CONNECT) {
        // Default path: hal version is don't care, do normal camera connect.
        camera = Camera::connect(cameraId, clientName,
                Camera::USE_CALLING_UID, Camera::USE_CALLING_PID);
    } else {
        jint status = Camera::connectLegacy(cameraId, halVersion, clientName,
                Camera::USE_CALLING_UID, camera);
        if (status != NO_ERROR) {
            return status;
        }
    }
 
    if (camera == NULL) {
        return -EACCES;
    }
    ......
}

android_hardware_Camera_native_setup 创建 Camera 智能指针,调用 Camera::connect() 方法构造 Camera 类实例。

Camera 类中的 connect 方法调用 CameraBase 类的connect 方法获取系统的 cameraservice 并通过binder机制建立camera客户端链接。

// Camera.cpp
sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,
        int clientUid, int clientPid)
{
    return CameraBaseT::connect(cameraId, clientPackageName, clientUid, clientPid);
}
 
 
// CameraBase.cpp
template <typename TCam, typename TCamTraits>
sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,
        const String16& clientPackageName,
        int clientUid, int clientPid)
{
    ALOGV("%s: connect", __FUNCTION__);
    sp<TCam> c = new TCam(cameraId);
    sp<TCamCallbacks> cl = c;
    // 获取 camera 的服务
    const sp<::android::hardware::ICameraService>& cs = getCameraService();
 
    binder::Status ret;
    if(cs != nullptr)
    {
    /*
     *  定义在 /frameworks/av/camera/Camera.cpp
     *     CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService =
     *    &::android::hardware::ICameraService::connect;
     *  推测最终是对应 CameraService::connect
     *
    */
        TCamConnectService fnConnectService = TCamTraits::fnConnectService;
        ret = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,
                                            clientPid, /*out*/ &c->mCamera);
    }
    if(ret.isOk() && c->mCamera != nullptr)
    {
    // Binder对象设置死亡代理。当出现和服务端连接发生故障时,系统将自动调用死亡代理函数binderDied()
    // 为Binder对象设置死亡代理
        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;
}


CameraBase 类的connect() 调用 getCameraService() 获取camera服务

// CameraBase.cpp
// establish binder interface to camera service
template <typename TCam, typename TCamTraits>
const sp<::android::hardware::ICameraService>& CameraBase<TCam, TCamTraits>::getCameraService()
{
    Mutex::Autolock _l(gLock);
    if(gCameraService.get() == 0)
    {
        // 获取系统服务列表
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder;
        do
        {
            // 通过 kCameraServiceName 字符串获取相机服务
            binder = sm->getService(String16(kCameraServiceName));
            if(binder != 0)
            {
                break;
            }
            ALOGW("CameraService not published, waiting...");
            usleep(kCameraServicePollDelay);
        }
        while(true);
        if(gDeathNotifier == NULL)
        {
            gDeathNotifier = new DeathNotifier();
        }
        binder->linkToDeath(gDeathNotifier);
         // find -name ICameraService.h 在 out 目录下有这个文件,不知道为什么编译的out目录会生成这个文件
        //  ./out/obj_arm/SHARED_LIBRARIES/libcamera_client_intermediates/aidl-generated/include/android/hardware/ICameraService.h
        //  ./out/obj/SHARED_LIBRARIES/libcamera_client_intermediates/aidl-generated/include/android/hardware/ICameraService.h
 
        gCameraService = interface_cast<::android::hardware::ICameraService>(binder);
    }
    ALOGE_IF(gCameraService == 0, "no CameraService!?");
    return gCameraService;
}

Camera 框架使用 binder 机制和CameraListener类的纯虚函数,实现跨进程传输图像数据。这里不叙述 binder 机制。

简单介绍下 cameraservice 的 serivce 和 client 端是的调用关系,是怎么连接到HAL层。

相机的 CameraService 是提供相机服务端实现的类,从 CameraService::connect() 开始逐步靠近 HAL层的厂商相机注册函数集。

// frameworks/av/services/camera/libcameraservice/CameraService.cpp
Status CameraService::connect(
        const sp<ICameraClient>& cameraClient,
        int cameraId,
        const String16& clientPackageName,
        int clientUid,
        int clientPid,
        /*out*/
        sp<ICamera>* device) {
 
    ATRACE_CALL();
    Status ret = Status::ok();
    String8 id = String8::format("%d", cameraId);
    sp<Client> client = nullptr;
    // 模板 connectHelper 里获取 camera client 代理
    ret = connectHelper<ICameraClient,Client>(cameraClient, id,
            CAMERA_DEVICE_API_VERSION_1_0/* modified */, clientPackageName, clientUid, clientPid, API_1,
            /*legacyMode*/ true/* modified */, /*shimUpdateOnly*/ false,
            /*out*/client);
 
    if(!ret.isOk()) {
        logRejected(id, getCallingPid(), String8(clientPackageName),
                ret.toString8());
        return ret;
    }
 
    *device = client;
    return ret;
}
CameraService::connectHelper 模板里调用 makeClient() 函数

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)
{
    ......
 
    if(!(ret = makeClient(this, cameraCb, clientPackageName, id, facing, clientPid,
                          clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel,
                          /*out*/&tmp)).isOk())
    {
        return ret;
    }
    ......
 
}


Android7 使用的Camera API 2.0,所以CameraService::makeClient() 调用 *client = new CameraDeviceClient  进入 CameraDeviceClient.cpp 

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)
{
 
    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, 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 创建 CameraDeviceClient
                {
                    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 \"%d\" has unknown HAL version %d",
                                        cameraId, deviceVersion);
        }
    }
    else
    {
           ......
    }
    return Status::ok();
}

CameraDeviceClient类的构造函数调用 Camera2ClientBase 模板函数执行 mDevice = new Camera3Device(cameraId);  创建 Camera3Device类的实例。

// frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
// Interface used by CameraService
CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
                                       const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
                                       const String16& clientPackageName,
                                       int cameraId,
                                       int cameraFacing,
                                       int clientPid,
                                       uid_t clientUid,
                                       int servicePid) :
    Camera2ClientBase(cameraService, remoteCallback, clientPackageName,
                      cameraId, cameraFacing, clientPid, clientUid, servicePid),
    mInputStream(),
    mStreamingRequestId(REQUEST_ID_NONE),
    mRequestIdCounter(0)
{
 
    ATRACE_CALL();
    ALOGI("CameraDeviceClient %d: Opened", cameraId);
}
 
 
// frameworks/av/services/camera/libcameraservice/common/Camera2ClientBase.cpp
// Interface used by CameraService
template <typename TClientBase>
Camera2ClientBase<TClientBase>::Camera2ClientBase(
    const sp<CameraService>& cameraService,
    const sp<TCamCallbacks>& remoteCallback,
    const String16& clientPackageName,
    int cameraId,
    int cameraFacing,
    int clientPid,
    uid_t clientUid,
    int servicePid):
    TClientBase(cameraService, remoteCallback, clientPackageName,
                cameraId, cameraFacing, clientPid, clientUid, servicePid),
    mSharedCameraCallbacks(remoteCallback),
    mDeviceVersion(cameraService->getDeviceVersion(cameraId)),
    mDeviceActive(false)
{
    ALOGI("Camera %d: Opened. Client: %s (PID %d, UID %d)", cameraId,
          String8(clientPackageName).string(), clientPid, clientUid);
 
    mInitialClientPid = clientPid;
    mDevice = new Camera3Device(cameraId);
    LOG_ALWAYS_FATAL_IF(mDevice == 0, "Device should never be NULL here.");
}


创建Camera3Device()实例; 在该类的初始化方法 Camera3Device::initialize(CameraModule *module) 中调用模块的open()函数,打开相机设备。进入 HAL 层。

// frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp
Camera3Device::Camera3Device(int id):
        mId(id),
        mIsConstrainedHighSpeedConfiguration(false),
        mHal3Device(NULL),
        mStatus(STATUS_UNINITIALIZED),
        mStatusWaiters(0),
        mUsePartialResult(false),
        mNumPartialResults(1),
        mTimestampOffset(0),
        mNextResultFrameNumber(0),
        mNextReprocessResultFrameNumber(0),
        mNextShutterFrameNumber(0),
        mNextReprocessShutterFrameNumber(0),
        mListener(NULL)
{
    ATRACE_CALL();
    camera3_callback_ops::notify = &sNotify;
    camera3_callback_ops::process_capture_result = &sProcessCaptureResult;
    ALOGV("%s: Created device for camera %d", __FUNCTION__, id);
}
 
 
 
// frameworks/av/services/camera/libcameraservice/device3/Camera3Device.cpp
//  该函数中 module->open() ,调用HAL层注册的相机模块 open 函数
status_t Camera3Device::initialize(CameraModule *module)
{
    ATRACE_CALL();
    Mutex::Autolock il(mInterfaceLock);
    Mutex::Autolock l(mLock);
 
    ALOGV("%s: Initializing device for camera %d", __FUNCTION__, mId);
    if (mStatus != STATUS_UNINITIALIZED) {
        CLOGE("Already initialized!");
        return INVALID_OPERATION;
    }
 
    /** Open HAL device */
 
    status_t res;
    String8 deviceName = String8::format("%d", mId);
 
    camera3_device_t *device;
 
    ATRACE_BEGIN("camera3->open");
    res = module->open(deviceName.string(),
            reinterpret_cast<hw_device_t**>(&device));  // 打开相机设备
    ATRACE_END();
 
    if (res != OK) {
        SET_ERR_L("Could not open camera: %s (%d)", strerror(-res), res);
        return res;
    }
 
    /** Cross-check device version */
    if (device->common.version < CAMERA_DEVICE_API_VERSION_3_0) {
        SET_ERR_L("Could not open camera: "
                "Camera device should be at least %x, reports %x instead",
                CAMERA_DEVICE_API_VERSION_3_0,
                device->common.version);
        device->common.close(&device->common);
        return BAD_VALUE;
    }
 
    camera_info info;
    res = module->getCameraInfo(mId, &info);
    if (res != OK) return res;
 
    if (info.device_version != device->common.version) {
        SET_ERR_L("HAL reporting mismatched camera_info version (%x)"
                " and device version (%x).",
                info.device_version, device->common.version);
        device->common.close(&device->common);
        return BAD_VALUE;
    }
 
  ......
 
    return OK;
}


至此代码进入 HAL 空间。 HAL 没有 Framework 那么复杂的。 Android其他模块代码的调用流程可参考 Camera 。如果做驱动开发又想了解 Android framework 框架,建议先跳过 Java 层代码。从 CPP 开始跟代码,逐步理解 Framework 与 HAL 的关系。然后再跟 Java 层的代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值