浅析Android Camera架构

来源:互联网 发布:淘宝代销退货如处理 编辑:程序博客网 时间:2024/05/02 00:20

本博文是基于Android 4.4讲解

  1、application 层:

               当我们Android工程师想打开camera时通常直接调用Camera.java中的  Camer.open(cameraId)静态函数

                camera.java 位于 frameworks/base/core/java/android/hardware目录下

                //以下是部分代码

               

 public static Camera open(int cameraId) {        return new Camera(cameraId);    }
</pre><pre code_snippet_id="1846209" snippet_file_name="blog_20160823_3_8904287" name="code" class="html"><pre name="code" class="html">Camera(int cameraId) {        mShutterCallback = null;        mRawImageCallback = null;        mJpegCallback = null;        mPreviewCallback = null;        mPostviewCallback = null;        mUsingPreviewAllocation = false;        mZoomListener = null;        Looper looper;        if ((looper = Looper.myLooper()) != null) {            mEventHandler = new EventHandler(this, looper);        } else if ((looper = Looper.getMainLooper()) != null) {            mEventHandler = new EventHandler(this, looper);        } else {            mEventHandler = null;        }        String packageName = ActivityThread.currentPackageName();        <span style="color:#ff0000;">native_setup(new WeakReference<Camera>(this), cameraId, packageName);</span>    }


      其中native_setup接口是native接口其函数声明如下

            

private native final void native_setup(Object camera_this, int cameraId,                                           String packageName);

       2、jni层

             在camera.java中会调用到native_setup函数,此jni接口定义在  frameworks/base/core/jni下面的android_hardware_Camera.cpp中

             

// connect to camera servicestatic void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,    jobject weak_this, jint cameraId, jstring clientPackageName){    // Convert jstring to String16    const char16_t *rawClientName = env->GetStringChars(clientPackageName, NULL);    jsize rawClientNameLen = env->GetStringLength(clientPackageName);    String16 clientName(rawClientName, rawClientNameLen);    env->ReleaseStringChars(clientPackageName, rawClientName);   <span style="color:#ff0000;"> sp<Camera> camera = Camera::connect(cameraId, clientName,            Camera::USE_CALLING_UID);</span>    if (camera == NULL) {        jniThrowRuntimeException(env, "Fail to connect to camera service");        return;    }    // make sure camera hardware is alive    if (camera->getStatus() != NO_ERROR) {        jniThrowRuntimeException(env, "Camera initialization failed");        return;    }    jclass clazz = env->GetObjectClass(thiz);    if (clazz == NULL) {        jniThrowRuntimeException(env, "Can't find android/hardware/Camera");        return;    }    // We use a weak reference so the Camera object can be garbage collected.    // The reference is only used as a proxy for callbacks.    sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);    context->incStrong((void*)android_hardware_Camera_native_setup);    camera->setListener(context);    // save context in opaque field    env->SetIntField(thiz, fields.context, (int)context.get());}
其中上面会调Camera::connect接口此类是frameworks/av/camera/Camera.cpp

sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName,        int clientUid){    return <span style="color:#ff0000;">CameraBaseT::connect</span>(cameraId, clientPackageName, clientUid);//调用了父类的connect接口}
frameworks/av/camera/CameraBase.cpp

template <typename TCam, typename TCamTraits>sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId,                                               const String16& clientPackageName,                                               int clientUid){    ALOGV("%s: connect", __FUNCTION__);    sp<TCam> c = new TCam(cameraId);    sp<TCamCallbacks> cl = c;    status_t status = NO_ERROR;    <span style="color:#ff0000;">const sp<ICameraService>& cs = getCameraService();  //得到CameraService.cpp实例</span>    if (cs != 0) {       <span style="color:#ff0000;"> TCamConnectService fnConnectService = TCamTraits::fnConnectService;        status = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,                                             /*out*/ c->mCamera);                                   //此行最终会调用到CameraService.cpp中的connect接口</span>    }    if (status == OK && c->mCamera != 0) {        c->mCamera->asBinder()->linkToDeath(c);        c->mStatus = NO_ERROR;    } else {        ALOGW("An error occurred while connecting to camera: %d", cameraId);        c.clear();    }    return c;}
frameworks/av/services/camera/libcameraservicw/CameraService.cpp

status_t CameraService::connect(        const sp<ICameraClient>& cameraClient,        int cameraId,        const String16& clientPackageName,        int clientUid,        /*out*/        sp<ICamera>& device) {    String8 clientName8(clientPackageName);    int callingPid = getCallingPid();    LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid,            clientName8.string(), cameraId);    status_t status = validateConnect(cameraId, /*inout*/clientUid);    if (status != OK) {        return status;    }    sp<Client> client;    {        Mutex::Autolock lock(mServiceLock);        sp<BasicClient> clientTmp;        if (!canConnectUnsafe(cameraId, clientPackageName,                              cameraClient->asBinder(),                              /*out*/clientTmp)) {            return -EBUSY;        } else if (client.get() != NULL) {            device = static_cast<Client*>(clientTmp.get());            return OK;        }        int facing = -1;        int deviceVersion = getDeviceVersion(cameraId, &facing);        // If there are other non-exclusive users of the camera,        //  this will tear them down before we can reuse the camera        if (isValidCameraId(cameraId)) {            // transition from PRESENT -> NOT_AVAILABLE            updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,                         cameraId);        }        switch(deviceVersion) {          case CAMERA_DEVICE_API_VERSION_1_0:            <span style="color:#ff0000;">client = new CameraClient(this, cameraClient,                    clientPackageName, cameraId,                    facing, callingPid, clientUid, getpid());    //我用的是camer1</span>            break;          case CAMERA_DEVICE_API_VERSION_2_0:          case CAMERA_DEVICE_API_VERSION_2_1:          case CAMERA_DEVICE_API_VERSION_3_0:            client = new Camera2Client(this, cameraClient,                    clientPackageName, cameraId,                    facing, callingPid, clientUid, getpid(),                    deviceVersion);            break;          case -1:            ALOGE("Invalid camera id %d", cameraId);            return BAD_VALUE;          default:            ALOGE("Unknown camera device HAL version: %d", deviceVersion);            return INVALID_OPERATION;        }       <span style="color:#ff0000;"> status_t status = connectFinishUnsafe(client, client->getRemote()); //见下面定义</span>        if (status != OK) {            // this is probably not recoverable.. maybe the client can try again            // OK: we can only get here if we were originally in PRESENT state            updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);            return status;        }        mClient[cameraId] = client;        LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId,             getpid());    }    // 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 OK;}

status_t CameraService::connectFinishUnsafe(const sp<BasicClient>& client,                                            const sp<IBinder>& remoteCallback) {   <span style="color:#ff0000;"> status_t status = client->initialize(mModule);   //其中  camera_module_t   *mModule为一个结构体指针,此指针会在onFirstRef()接口中初始化见下面代码</span>    if (status != OK) {        return status;    }    remoteCallback->linkToDeath(this);    return OK;}

//此接口会在CameraService实例化后调用,其中用到了sp机制,目前尚未研究通。

void CameraService::onFirstRef() {    LOG1("CameraService::onFirstRef");    BnCameraService::onFirstRef();    if (<span style="color:#ff0000;">hw_get_module</span>(CAMERA_HARDWARE_MODULE_ID,//此句代码是关键之处                (const hw_module_t **)&mModule) < 0) {        ALOGE("Could not load camera HAL module");        mNumberOfCameras = 0;    }    else {        ALOGI("Loaded \"%s\" camera module", mModule->common.name);        mNumberOfCameras = mModule->get_number_of_cameras();        if (mNumberOfCameras > MAX_CAMERAS) {            ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",                    mNumberOfCameras, MAX_CAMERAS);            mNumberOfCameras = MAX_CAMERAS;        }        for (int i = 0; i < mNumberOfCameras; i++) {            setCameraFree(i);        }        if (mModule->common.module_api_version >=                CAMERA_MODULE_API_VERSION_2_1) {            mModule->set_callbacks(this);        }        CameraDeviceFactory::registerService(this);    }}

hw_get_module位于Android源码目录下  hardware/libhardware/Hardware.c
int hw_get_module(const char *id, const struct hw_module_t **module){    return hw_get_module_by_class(id, NULL, module);}
//此函数会加载动态库
"/system/lib/hw"下面有名字为class_id的动态库
int hw_get_module_by_class(const char *class_id, const char *inst,                           const struct hw_module_t **module){    int status;    int i;    const struct hw_module_t *hmi = NULL;    char prop[PATH_MAX];    char path[PATH_MAX];    char name[PATH_MAX];    if (inst)        snprintf(name, PATH_MAX, "%s.%s", class_id, inst);    else        strlcpy(name, class_id, PATH_MAX);    /*     * Here we rely on the fact that calling dlopen multiple times on     * the same .so will simply increment a refcount (and not load     * a new copy of the library).     * We also assume that dlopen() is thread-safe.     */    /* Loop through the configuration variants looking for a module */    for (i=0 ; i<HAL_VARIANT_KEYS_COUNT+1 ; i++) {        if (i < HAL_VARIANT_KEYS_COUNT) {            if (property_get(variant_keys[i], prop, NULL) == 0) {                continue;            }            snprintf(path, sizeof(path), "%s/%s.%s.so",                     HAL_LIBRARY_PATH2, name, prop);    //         PATH2: "/vendor/lib/hw"            if (access(path, R_OK) == 0) break;             snprintf(path, sizeof(path), "%s/%s.%s.so",                     HAL_LIBRARY_PATH1, name, prop);   //PATH1: "/system/lib/hw"            if (access(path, R_OK) == 0) break;        } else {            snprintf(path, sizeof(path), "%s/%s.default.so",                     HAL_LIBRARY_PATH2, name);            if (access(path, R_OK) == 0) break;            snprintf(path, sizeof(path), "%s/%s.default.so",                     HAL_LIBRARY_PATH1, name);            if (access(path, R_OK) == 0) break;        }    }    status = -ENOENT;    if (i < HAL_VARIANT_KEYS_COUNT+1) {        /* load the module, if this fails, we're doomed, and we should not try         * to load a different variant. */        status = load(class_id, path, module);    }    return status;}

<span style="color:#ff0000;">//</span>
static int load(const char *id,        const char *path,        const struct hw_module_t **pHmi){    int status;    void *handle;    struct hw_module_t *hmi;    /*     * load the symbols resolving undefined symbols before     * dlopen returns. Since RTLD_GLOBAL is not or'd in with     * RTLD_NOW the external symbols will not be global     */    handle = dlopen(path, RTLD_NOW);    if (handle == NULL) {        char const *err_str = dlerror();        ALOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");        status = -EINVAL;        goto done;    }    /* Get the address of the struct hal_module_info. */    const char *sym = HAL_MODULE_INFO_SYM_AS_STR;   //HAL_MODULE_INFO_SYM_AS_STR 为 "HMI"
    <span style="color:#ff0000;">//dlsym根据sym去实例化hmi,其中Camera_Moduel.cpp下有"HMI"名字的camera_module_t变量,见下面代码</span>    hmi = (struct hw_module_t *)dlsym(handle, sym);    if (hmi == NULL) {        ALOGE("load: couldn't find symbol %s", sym);        status = -EINVAL;        goto done;    }    /* Check that the id matches */    if (strcmp(id, hmi->id) != 0) {        ALOGE("load: id=%s != hmi->id=%s", id, hmi->id);        status = -EINVAL;        goto done;    }    hmi->dso = handle;    /* success */    status = 0;    done:    if (status != 0) {        hmi = NULL;        if (handle != NULL) {            dlclose(handle);            handle = NULL;        }    } else {        ALOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",                id, path, *pHmi, handle);    }    *pHmi = hmi;    return status;}

CameraHal_Module.cpp   //此类位于hardware/rk29/camera/camerahal目录下,这是我的源代码camera模块

camera_module_t HAL_MODULE_INFO_SYM = {    common: {         tag: HARDWARE_MODULE_TAG,         version_major: ((CONFIG_CAMERAHAL_VERSION&0xff00)>>8),         version_minor: CONFIG_CAMERAHAL_VERSION&0xff,         id: CAMERA_HARDWARE_MODULE_ID,         name: CAMERA_MODULE_NAME,         author: "RockChip",         <span style="color:#ff0000;">methods: &camera_module_methods,</span>         dso: NULL, /* remove compilation warnings */         reserved: {0}, /* remove compilation warnings */    },    get_number_of_cameras: camera_get_number_of_cameras,    get_camera_info: camera_get_camera_info,    set_callbacks:NULL,    get_vendor_tag_ops:NULL,    reserved: {0}};

到此frameworks/av/services/camera/libcameraservicw/CameraService.cpp下的mModule实例化完成

我们在进入到CameraClient.cpp(frameworks/av/services/camera/libcameraservice/api1)中(上面的CameraService.cpp实例化了CameraClient并且调用了它内部的initialize(camera_module_t *module)接口)

status_t CameraClient::initialize(camera_module_t *module) {    int callingPid = getCallingPid();    status_t res;    LOG1("CameraClient::initialize E (pid %d, id %d)", callingPid, mCameraId);    // Verify ops permissions    res = startCameraOps();    if (res != OK) {        return res;    }    char camera_device_name[10];    snprintf(camera_device_name, sizeof(camera_device_name), "%d", mCameraId);    <span style="color:#ff0000;">mHardware = new CameraHardwareInterface(camera_device_name);</span>    res = mHardware->initialize(&module->common);    if (res != OK) {        ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",                __FUNCTION__, mCameraId, strerror(-res), res);        mHardware.clear();        return NO_INIT;    }    mHardware->setCallbacks(notifyCallback,            dataCallback,            dataCallbackTimestamp,            (void *)mCameraId);    // Enable zoom, error, focus, and metadata messages by default    enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |                  CAMERA_MSG_PREVIEW_METADATA | CAMERA_MSG_FOCUS_MOVE);    LOG1("CameraClient::initialize X (pid %d, id %d)", callingPid, mCameraId);    return OK;}

CameraHardwareInterface.h位于 frameworks/av/services/camera/libcameraservice/device1

 status_t initialize(hw_module_t *module)    {        ALOGI("Opening camera %s", mName.string());        <span style="color:#ff0000;">int rc = module->methods->open(module, mName.string(),                                       (hw_device_t **)&mDevice);  //调用了上面CameraHal_Module.cpp下的</span><span style="color: rgb(255, 0, 0); font-family: Arial, Helvetica, sans-serif;">camera_module_t HAL_MODULE_INFO_SYM的open函数</span><span style="color:#ff0000;">,此函数定义见下面代码</span>        if (rc != OK) {            ALOGE("Could not open camera %s: %d", mName.string(), rc);            return rc;        }        initHalPreviewWindow();        return rc;    }


static struct hw_module_methods_t camera_module_methods = {        open: camera_device_open};
int camera_device_open(const hw_module_t* module, const char* name,                hw_device_t** device){    int rv = 0;    int cameraid;    rk_camera_device_t* camera_device = NULL;    camera_device_ops_t* camera_ops = NULL;    android::CameraHal* camera = NULL;    android::Mutex::Autolock lock(gCameraHalDeviceLock);    LOGI("camera_device open");    if (name != NULL) {        cameraid = atoi(name);        if(cameraid > gCamerasNumber) {            LOGE("camera service provided cameraid out of bounds, "                    "cameraid = %d, num supported = %d",                    cameraid, gCamerasNumber);            rv = -EINVAL;            goto fail;        }        if(gCamerasOpen >= CAMERAS_SUPPORTED_SIMUL_MAX) {            LOGE("maximum number(%d) of cameras already open",gCamerasOpen);            rv = -ENOMEM;            goto fail;        }        camera_device = (rk_camera_device_t*)malloc(sizeof(*camera_device));        if(!camera_device) {            LOGE("camera_device allocation fail");            rv = -ENOMEM;            goto fail;        }        camera_ops = (camera_device_ops_t*)malloc(sizeof(*camera_ops));        if(!camera_ops) {            LOGE("camera_ops allocation fail");            rv = -ENOMEM;            goto fail;        }        memset(camera_device, 0, sizeof(*camera_device));        memset(camera_ops, 0, sizeof(*camera_ops));        camera_device->base.common.tag = HARDWARE_DEVICE_TAG;        camera_device->base.common.version = 0;        camera_device->base.common.module = (hw_module_t *)(module);        camera_device->base.common.close = camera_device_close;        camera_device->base.ops = camera_ops;        camera_ops->set_preview_window = camera_set_preview_window;        camera_ops->set_callbacks = camera_set_callbacks;        camera_ops->enable_msg_type = camera_enable_msg_type;        camera_ops->disable_msg_type = camera_disable_msg_type;        camera_ops->msg_type_enabled = camera_msg_type_enabled;        camera_ops->start_preview = camera_start_preview;        camera_ops->stop_preview = camera_stop_preview;        camera_ops->preview_enabled = camera_preview_enabled;        camera_ops->store_meta_data_in_buffers = camera_store_meta_data_in_buffers;        camera_ops->start_recording = camera_start_recording;        camera_ops->stop_recording = camera_stop_recording;        camera_ops->recording_enabled = camera_recording_enabled;        camera_ops->release_recording_frame = camera_release_recording_frame;        camera_ops->auto_focus = camera_auto_focus;        camera_ops->cancel_auto_focus = camera_cancel_auto_focus;        camera_ops->take_picture = camera_take_picture;        camera_ops->cancel_picture = camera_cancel_picture;        camera_ops->set_parameters = camera_set_parameters;        camera_ops->get_parameters = camera_get_parameters;        camera_ops->put_parameters = camera_put_parameters;        camera_ops->send_command = camera_send_command;        camera_ops->release = camera_release;        camera_ops->dump = camera_dump;        *device = &camera_device->base.common;        // -------- RockChip specific stuff --------        camera_device->cameraid = cameraid;                <span style="color:#ff0000;">camera = new android::CameraHal(cameraid); //进入hal层</span>        if(!camera) {            LOGE("Couldn't create instance of CameraHal class");            rv = -ENOMEM;            goto fail;        }        gCameraHals[cameraid] = camera;        gCamerasOpen++;    }    return rv;fail:    if(camera_device) {        free(camera_device);        camera_device = NULL;    }    if(camera_ops) {        free(camera_ops);        camera_ops = NULL;    }    if(camera) {        delete camera;        camera = NULL;    }    *device = NULL;    return rv;}


3、hal层

    hardware/rk29/camera/camerahal/CameraHal.cpp

     //以下会根据camera硬件分类uvc soc isp等,实例化成对应的adapter.cpp(数据适配器,此类会调用iotrl系统接口和驱动层进行通信)

CameraHal::CameraHal(int cameraId)          :commandThreadCommandQ("commandCmdQ"){LOG_FUNCTION_NAME    {        char trace_level[PROPERTY_VALUE_MAX];        int level;        property_get(CAMERAHAL_TRACE_LEVEL_PROPERTY_KEY, trace_level, "0");        sscanf(trace_level,"%d",&level);                setTracerLevel(level);}    mCamId = cameraId;    mCamFd = -1;    mCommandRunning = -1;mCameraStatus = 0;    #if (CONFIG_CAMERA_MEM == CAMERA_MEM_ION)        mCamMemManager = new IonMemManager();        LOG1("%s(%d): Camera Hal memory is alloced from ION device",__FUNCTION__,__LINE__);#elif(CONFIG_CAMERA_MEM == CAMERA_MEM_IONDMA)        if((strcmp(gCamInfos[cameraId].driver,"uvcvideo") == 0) //uvc camera            || (gCamInfos[cameraId].pcam_total_info->mHardInfo.mSensorInfo.mPhy.type == CamSys_Phy_end)// soc cif            ) {            gCamInfos[cameraId].pcam_total_info->mIsIommuEnabled = (IOMMU_ENABLED == 1)? true:false;        }mCamMemManager = new IonDmaMemManager(gCamInfos[cameraId].pcam_total_info->mIsIommuEnabled);        LOG1("%s(%d): Camera Hal memory is alloced from ION device",__FUNCTION__,__LINE__);    #elif(CONFIG_CAMERA_MEM == CAMERA_MEM_PMEM)        if(access(CAMERA_PMEM_NAME, O_RDWR) < 0) {            LOGE("%s(%d): %s isn't registered, CameraHal_Mem current configuration isn't support ION memory!!!",                __FUNCTION__,__LINE__,CAMERA_PMEM_NAME);        } else {            mCamMemManager = new PmemManager((char*)CAMERA_PMEM_NAME);            LOG1("%s(%d): Camera Hal memory is alloced from %s device",__FUNCTION__,__LINE__,CAMERA_PMEM_NAME);        }    #endif        mPreviewBuf = new PreviewBufferProvider(mCamMemManager);    mVideoBuf = new BufferProvider(mCamMemManager);    mRawBuf = new BufferProvider(mCamMemManager);    mJpegBuf = new BufferProvider(mCamMemManager);    char value[PROPERTY_VALUE_MAX];    property_get(/*CAMERAHAL_TYPE_PROPERTY_KEY*/"sys.cam_hal.type", value, "none");    if (!strcmp(value, "fakecamera")) {        LOGD("it is a fake camera!");        mCameraAdapter = new CameraFakeAdapter(cameraId);    } else {    if((strcmp(gCamInfos[cameraId].driver,"uvcvideo") == 0)) {        LOGD("it is a uvc camera!");        mCameraAdapter = new CameraUSBAdapter(cameraId);    }    else if(gCamInfos[cameraId].pcam_total_info->mHardInfo.mSensorInfo.mPhy.type == CamSys_Phy_Cif){        LOGD("it is a isp soc camera");        if(gCamInfos[cameraId].pcam_total_info->mHardInfo.mSensorInfo.mPhy.info.cif.fmt == CamSys_Fmt_Raw_10b)            mCameraAdapter = new CameraIspSOCAdapter(cameraId);        else            mCameraAdapter = new CameraIspAdapter(cameraId);    }    else if(gCamInfos[cameraId].pcam_total_info->mHardInfo.mSensorInfo.mPhy.type == CamSys_Phy_Mipi){        LOGD("it is a isp  camera");        mCameraAdapter = new CameraIspAdapter(cameraId);    }    else{        LOGD("it is a soc camera!");        mCameraAdapter = new CameraSOCAdapter(cameraId);    }    }        //initialize        {        char *call_process = getCallingProcess();    if(strstr(call_process,"com.android.cts.verifier")) {            mCameraAdapter->setImageAllFov(true);    } else {            mCameraAdapter->setImageAllFov(false);    }    }    mDisplayAdapter = new DisplayAdapter();    mEventNotifier = new AppMsgNotifier(mCameraAdapter);        mCameraAdapter->setEventNotifierRef(*mEventNotifier);    mCameraAdapter->initialize();    updateParameters(mParameters);    mCameraAdapter->setPreviewBufProvider(mPreviewBuf);    mCameraAdapter->setDisplayAdapterRef(*mDisplayAdapter);        mDisplayAdapter->setFrameProvider(mCameraAdapter);        mEventNotifier->setPictureRawBufProvider(mRawBuf);    mEventNotifier->setPictureJpegBufProvider(mJpegBuf);    mEventNotifier->setVideoBufProvider(mVideoBuf);    mEventNotifier->setFrameProvider(mCameraAdapter);    //command thread    mCommandThread = new CommandThread(this);mCommandThread->run("CameraCmdThread", ANDROID_PRIORITY_URGENT_DISPLAY);bool dataCbFrontMirror;bool dataCbFrontFlip;#if CONFIG_CAMERA_FRONT_MIRROR_MDATACB    if (gCamInfos[cameraId].facing_info.facing == CAMERA_FACING_FRONT) {#if CONFIG_CAMERA_FRONT_MIRROR_MDATACB_ALL        dataCbFrontMirror = true;#elseconst char* cameraCallProcess = getCallingProcess();        if (strstr(CONFIG_CAMERA_FRONT_MIRROR_MDATACB_APK,cameraCallProcess)) {            dataCbFrontMirror = true;         } else {            dataCbFrontMirror = false;        }        if (strstr(CONFIG_CAMERA_FRONT_FLIP_MDATACB_APK,cameraCallProcess)) {            dataCbFrontFlip = true;         } else {            dataCbFrontFlip = false;        }#endif    } else {        dataCbFrontMirror = false;        dataCbFrontFlip = false;    }#else    dataCbFrontMirror = false;#endif mEventNotifier->setDatacbFrontMirrorFlipState(dataCbFrontMirror,dataCbFrontFlip);      // register for sensor events    mSensorListener = new SensorListener();    if (mSensorListener.get()) {        if (mSensorListener->initialize() == NO_ERROR) {            mSensorListener->setCallbacks(gsensor_orientation_cb, this);            mSensorListener->enableSensor(SensorListener::SENSOR_ORIENTATION);        } else {            LOGE("Error initializing SensorListener. not fatal, continuing");            mSensorListener.clear();            mSensorListener = NULL;        }    }      LOG_FUNCTION_NAME_EXIT    }


0 0