android camera [一] Camera open process

Camera open process
一.上层调用
CameraActivity.java (src\com\android\camera)    101442    2015-7-23
    @Override
    public void onCreate(Bundle icicle) {
        ............
        mCameraDeviceCtrl.openCamera();
    }
    
    
CameraDeviceCtrl.java (src\com\android\camera\bridge)    64825    2015-10-16    
    public void openCamera() {
        Log.d(TAG, "[openCamera] cameraState:" + getCameraState());//D/CAM_ori/CameraDeviceCtrl( 3621): [openCamera] cameraState:STATE_OPENING_CAMERA
        if (getCameraState() != CameraState.STATE_CAMERA_CLOSED) {
            return;
        }
        mCameraStartUpThread.openCamera();
        setCameraState(CameraState.STATE_OPENING_CAMERA);
    }
    
    public synchronized void openCamera() {
            mOpenCamera = true;
            mCancel = false;
            notifyAll();
    }
    
    private int openCamera(boolean isDualCamera) {
            Log.i(TAG, "[openCamera] isDualCamera:" + isDualCamera + "mCameraId:" + mCameraId);//I/CAM_ori/CameraDeviceCtrl( 3621): [openCamera] isDualCamera:falsemCameraId:0
            int cameraId = getPreferredCameraId(mPreferences);
            if (mCameraId != cameraId) {
                SettingUtils.writePreferredCameraId(mPreferences, mCameraId);
            }
            try {
                // TODO will delete this
                if (mCameraActivity.isNeedOpenStereoCamera()) {
                    String ROPERTY_KEY_CLIENT_APPMODE = "client.appmode";
                    String APP_MODE_NAME_MTK_DUAL_CAMERA = "MtkStereo";
                    android.hardware.Camera.setProperty(ROPERTY_KEY_CLIENT_APPMODE,
                            APP_MODE_NAME_MTK_DUAL_CAMERA);
                }
                Util.openCamera(mCameraActivity, isDualCamera, mCameraId);
                mCameraDevice = CameraHolder.instance().getCameraProxy(mCameraId);
                mTopCamId = (mCameraId == CameraHolder.instance().getBackCameraId()) ? CameraHolder
                        .instance().getFrontCameraId() : CameraHolder.instance().getBackCameraId();
                mTopCamDevice = CameraHolder.instance().getCameraProxy(mTopCamId);
                // M: added for mock camera
                prepareMockCamera();
                // mIsCameraOpened = true;
            } catch (CameraHardwareException e) {
                Log.i(TAG, "[openCamera]CameraHardwareException e:" + e);
                mIsOpenCameraFail = true;
                mMainHandler.sendEmptyMessage(MSG_OPEN_CAMERA_FAIL);
                return CAMERA_HARDWARE_EXCEPTION;
            } catch (CameraDisabledException e) {
                Log.i(TAG, "[openCamera]CameraDisabledException e:" + e);
                mIsOpenCameraFail = true;
                mMainHandler.sendEmptyMessage(MSG_OPEN_CAMERA_DISABLED);
                return CAMERA_DISABLED_EXCEPTION;
            }
            mParameters = (mCameraDevice == null) ? null : CameraHolder.instance()
                    .getOriginalParameters(mCameraId);
            mTopCamParameters = (mTopCamDevice == null) ? null : CameraHolder.instance()
                    .getOriginalParameters(mTopCamId);
            mCameraActor.onCameraOpenDone();
            
            if (mCameraDevice != null && mParameters != null) {
                mCurCameraDevice = new CameraDeviceExt(mCameraActivity, mCameraDevice, mParameters,
                        mCameraId, mPreferences);
            } else {
                Log.d(TAG, "[openCamera fail],mCameraDevice:" + mCameraDevice + ",mParameters:"
                        + mParameters);
            }
            if (mTopCamDevice != null && mTopCamParameters != null) {
                mTopCameraDevice = new CameraDeviceExt(mCameraActivity, mTopCamDevice,
                        mTopCamParameters, mTopCamId, mPreferences);
            } else {
                Log.d(TAG, "[openCamera fail],mTopCamDevice:" + mTopCamDevice
                        + ",mTopCamParameters:" + mTopCamParameters);
            }
            mIsOpenCameraFail = false;
            mModuleManager.onCameraOpen();
            return CAMERA_OPEN_SUCEESS;
        }
    

Util.java (src\com\android\camera)    45751    2015-7-16    
    public static void openCamera(Activity activity, boolean isPIP, int cameraId) throws CameraHardwareException,
            CameraDisabledException {
        Log.i(TAG, "openCamera begin isPIP = " + isPIP);//I/CAM_ori/Util( 3621): openCamera begin isPIP = false
        // Check if device policy has disabled the camera.
        DevicePolicyManager dpm = (DevicePolicyManager) activity
                .getSystemService(Context.DEVICE_POLICY_SERVICE);
        if (dpm.getCameraDisabled(null)) {
            throw new CameraDisabledException();
        }
        try {
            if (isPIP) {
                MMProfileManager.startProfilePIPBottomOpen();
                retryOpen(activity, OPEN_RETRY_COUNT, CameraHolder.instance().getBackCameraId());
                MMProfileManager.stopProfilePIPBottomOpen();
                MMProfileManager.startProfilePIPTopOpen();
                retryOpen(activity, OPEN_RETRY_COUNT, CameraHolder.instance().getFrontCameraId());
                MMProfileManager.stopProfilePIPTopOpen();
            } else {
                retryOpen(activity, OPEN_RETRY_COUNT, cameraId);
            }
        } catch (CameraHardwareException e) {
            CameraHolder.instance().release();
            throw e;
        }
        Log.i(TAG, "openCamera end");
    }
    
    private static CameraManager.CameraProxy retryOpen(Activity activity, int count, int cameraId)
            throws CameraHardwareException {
        for (int i = 0; i < count; i++) {
            try {
                if (activity instanceof ActivityBase) {
                    Log.i(TAG, "[retryOpen] cameraId = " + cameraId);//I/CAM_ori/Util( 3621): [retryOpen] cameraId = 0
                    CameraProxy cameraProxy = CameraHolder.instance().open(cameraId);
                    return cameraProxy;
                } else {
                    return CameraHolder.instance().open(cameraId);
                }
            } catch (CameraHardwareException e) {
                if (i == 0) {
                    try {
                        // wait some time, and try another time
                        // Camera device may be using by VT or atv.
                        Thread.sleep(1000);
                    } catch (InterruptedException ie) {
                        ie.printStackTrace();
                    }
                    continue;
                } else {
                    // In eng build, we throw the exception so that test tool
                    // can detect it and report it
                    if ("eng".equals(Build.TYPE)) {
                        Log.i(TAG, "Open Camera fail", e);
                        throw e;
                        // QA will always consider JE as bug, so..
                        // throw new RuntimeException("openCamera failed", e);
                    } else {
                        throw e;
                    }
                }
            }
        }
        // just for build pass
        throw new CameraHardwareException(new RuntimeException("Should never get here"));
    }
        
CameraHolder.java (src\com\android\camera)    13558    2015-7-16    
    public CameraProxy open(int cameraId) throws CameraHardwareException {
        Log.i(TAG, "CameraHolder open cameraId = " + cameraId);//I/CAM_ext/CameraHolder( 3621): CameraHolder open cameraId = 0
        assertError(cameraId != UNKONW_ID);
        if (mMockCameraInfo == null) {
            return getCameraProxyWrapper(cameraId).open();
        } else {
            if (mMockCamera == null) {
                throw new RuntimeException();
            }
            getCameraProxyWrapper(cameraId).insertMockCameraProxy(mMockCamera[cameraId]);
            return mMockCamera[cameraId];
        }
    }
    
    private CameraProxyWrapper getCameraProxyWrapper(int cameraId) {
        if (cameraId == mBackCameraId) {
            if (sBackCamProxyWrapper == null) {
                sBackCameraManager = new CameraManager("BackCam");
                sBackCamProxyWrapper = new CameraProxyWrapper(cameraId, sBackCameraManager);
            }
            return sBackCamProxyWrapper;
        } else {
            if (sFrontCamProxyWrapper == null) {
                sFrontCameraManager = new CameraManager("FrontCam");
                sFrontCamProxyWrapper = new CameraProxyWrapper(cameraId, sFrontCameraManager);
            }
            return sFrontCamProxyWrapper;
        }
    }

    private CameraProxyWrapper(int cameraId, CameraManager manager) {
            Log.i(TAG, "[CameraProxyWrapper]constructor, cameraId = " + cameraId);
            mCameraId = cameraId;
            mCameraManager = manager;
            HandlerThread ht = new HandlerThread(cameraId + "'s CameraHolder ");
            ht.start();
            mHandler = new MyHandler(ht.getLooper());
        }
        
    public synchronized CameraProxy open() throws CameraHardwareException {
            Log.i(TAG, "CameraProxyWrapper open mCameraOpened = " + mCameraOpened + " mCameraId = "
                    + mCameraId);//I/CAM_ext/CameraHolder( 3621): CameraProxyWrapper open mCameraOpened = false mCameraId = 0
            assertError(!mCameraOpened);
            if (mCameraProxy == null) {
                try {
                    Log.i(TAG, "open camera " + mCameraId);
                    mCameraProxy = mCameraManager.cameraOpen(mCameraId);
                } catch (RuntimeException e) {
                    Log.i(TAG, "fail to connect Camera", e);
                    throw new CameraHardwareException(e);
                }
                mParameters = mCameraProxy.getParameters();
            } else {
                try {
                    mCameraProxy.reconnect();
                } catch (IOException e) {
                    Log.e(TAG, "reconnect failed.");
                    throw new CameraHardwareException(e);
                }
                mCameraProxy.setParameters(mParameters);
            }
            mCameraOpened = true;
            mHandler.removeMessages(RELEASE_CAMERA);
            mKeepBeforeTime = 0;
            Log.i(TAG, "open camera " + mCameraId + " end" + " mCameraProxy = " + mCameraProxy);
            return mCameraProxy;
    }
    
CameraManager.java (src\com\android\camera)    44919    2015-11-2    
    // Open camera synchronously. This method is invoked in the context of a
    // background thread.
    CameraProxy cameraOpen(int cameraId) {
        // Cannot open camera in mCameraHandler, otherwise all camera events
        // will be routed to mCameraHandler looper, which in turn will call
        // event handler like Camera.onFaceDetection, which in turn will modify
        // UI and cause exception like this:
        // CalledFromWrongThreadException: Only the original thread that created
        // a view hierarchy can touch its views.
        MMProfileManager.startProfileCameraOpen();
        mCamera = FrameworksClassFactory.openCamera(cameraId);
        Log.i(mSubTag, "openCamera cameraId = " + cameraId + " camera device = " + mCamera);//I/CAM_ori/CameraManager/FrontCam( 3621): openCamera cameraId = 0 camera device = com.android.camera.AndroidCamera@2e9153e8
        MMProfileManager.stopProfileCameraOpen();
        if (mCamera != null) {
            mParametersIsDirty = true;
            if (mParamsToSet == null) {
                mParamsToSet = mCamera.getParameters();
            }
            mCameraProxy = new CameraProxy();
            return mCameraProxy;
        } else {
            return null;
        }
    }
    
FrameworksClassFactory.java (src\com\android\camera)    4984    2015-7-16    
    import android.hardware.Camera;    
    public static ICamera openCamera(int cameraId) {
        if (MOCK_CAMERA) {
            return MockCamera.open(cameraId);
        } else {
            Camera camera = null;
            if (sTrySwitchToLegacyMode > 0) {
                   // choose legacy mode in order to enter cam hal 1.0
                   camera = Camera.openLegacy(cameraId, Camera.CAMERA_HAL_API_VERSION_1_0);
               } else {
                   camera = Camera.open(cameraId);
               }
            if (null == camera) {
                Log.e(TAG, "openCamera:got null hardware camera!");
                return null;
            }
            // wrap it with ICamera
            return new AndroidCamera(camera);
        }
    }

二、Framework 层
Camera.java (framework\base\core\android\hardware)    249186    2015-7-16
    public static Camera open(int cameraId) {
        if (!isPermissionGranted()) {
            return null;
        }
        return new Camera(cameraId);
    }
    
    
    Camera(int cameraId) {
        int err = cameraInitNormal(cameraId);
        if (checkInitErrors(err)) {
            switch(err) {
                case EACCESS:
                    throw new RuntimeException("Fail to connect to camera service");
                case ENODEV:
                    throw new RuntimeException("Camera initialization failed");
                default:
                    // Should never hit this.
                    throw new RuntimeException("Unknown camera error");
            }
        }
    }
    
    private int cameraInitNormal(int cameraId) {
        return cameraInitVersion(cameraId, CAMERA_HAL_API_VERSION_NORMAL_CONNECT);
    }    

    private int cameraInitVersion(int cameraId, int halVersion) {
        mShutterCallback = null;
        mRawImageCallback = null;
        mJpegCallback = null;
        mPreviewCallback = null;
        mPreviewRawDumpCallback = 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();

        return native_setup(new WeakReference(this), cameraId, halVersion, packageName);
    }    
    
    private native final int native_setup(Object camera_this, int cameraId, int halVersion,String packageName);
    
三、jni层

// connect to camera service
static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
    jobject weak_this, jint cameraId, jint halVersion, 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);

    sp 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);
    } else {
        jint status = Camera::connectLegacy(cameraId, halVersion, clientName,
                Camera::USE_CALLING_UID, camera);
        if (status != NO_ERROR) {
            return status;
        }
    }

    if (camera == NULL) {
        return -EACCES;
    }

    // make sure camera hardware is alive
    if (camera->getStatus() != NO_ERROR) {
        return NO_INIT;
    }

    jclass clazz = env->GetObjectClass(thiz);
    if (clazz == NULL) {
        // This should never happen
        jniThrowRuntimeException(env, "Can't find android/hardware/Camera");
        return INVALID_OPERATION;
    }

    // We use a weak reference so the Camera object can be garbage collected.
    // The reference is only used as a proxy for callbacks.
//!++
#if 1 // defined(MTK_CAMERA_BSP_SUPPORT)
    sp context = new MtkJNICameraContext(env, weak_this, clazz, camera);
#else
    sp context = new JNICameraContext(env, weak_this, clazz, camera);
#endif
//!--
    context->incStrong((void*)android_hardware_Camera_native_setup);
    camera->setListener(context);

    // save context in opaque field
    env->SetLongField(thiz, fields.context, (jlong)context.get());
    return NO_ERROR;
}

/framework/av/camera/Camera.cpp
sp Camera::connect(int cameraId, const String16& clientPackageName,
        int clientUid)
{
    return CameraBaseT::connect(cameraId, clientPackageName, clientUid);
}


/framework/av/camera/CameraBase.cpp
template
sp CameraBase::connect(int cameraId,
                                               const String16& clientPackageName,
                                               int clientUid)
{
    ALOGV("%s: connect", __FUNCTION__);
    sp c = new TCam(cameraId);
    sp cl = c;
    status_t status = NO_ERROR;
    const sp& cs = getCameraService();

    if (cs != 0) {
        TCamConnectService fnConnectService = TCamTraits::fnConnectService;
        status = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,
                                             /*out*/ c->mCamera);
    }
    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;
}


三、Services section
/framework/av/camera/CameraBase.cpp
// establish binder interface to camera service
template
const sp& CameraBase::getCameraService()
{
    Mutex::Autolock _l(gLock);
    if (gCameraService.get() == 0) {
        sp sm = defaultServiceManager();   //无法自动定位,调用的是IServiceManager.cpp(frameworks/base/libs/binder) 
        sp binder;
        do {
            binder = sm->getService(String16(kCameraServiceName)); //无法自动定位,搜索符号getService,定位到ServiceManager.java   49
            if (binder != 0) {
                break;
            }
            ALOGW("CameraService not published, waiting...");
            usleep(kCameraServicePollDelay);
        } while(true);
        if (gDeathNotifier == NULL) {
            gDeathNotifier = new DeathNotifier();
        }
        binder->linkToDeath(gDeathNotifier);
        gCameraService = interface_cast(binder);  //mCameraService是一个ICamerService类型,更加具体具体一点来讲应该是BpCameraService,因为在这个类中实现了ICameraService的方法。
    }
    ALOGE_IF(gCameraService == 0, "no CameraService!?");
    return gCameraService;
}

framework/native/libs/binder/IServiceManager.cpp
sp defaultServiceManager()
{
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
    
    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
            gDefaultServiceManager = interface_cast(
                ProcessState::self()->getContextObject(NULL));
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }
    
    return gDefaultServiceManager;
}

frameworks/base/core/java/android/os/ServiceManager.java
   /**
     * Returns a reference to a service with the given name.
     * 
     * @param name the name of the service to get
     * @return a reference to the service, or null if the service doesn't exist
     */
    public static IBinder getService(String name) {
        try {
            IBinder service = sCache.get(name);   //sCache是个Hashmap,用参数name:"media.camera"get这个IBinder,
                                                  //那么,这个media.camera是源代码里配置好的还是开机后添加进去的?何时添加的?
            if (service != null) {
                return service;
            } else {
                return getIServiceManager().getService(name);
            }
        } catch (RemoteException e) {
            Log.e(TAG, "error in getService", e);
        }
        return null;
    }

frameworks\av\services\camera\libcameraservice\CameraService.cpp
status_t CameraService::connect(                              //服务端connect()
        const sp& cameraClient,
        int cameraId,
        const String16& clientPackageName,
        int clientUid,
        /*out*/
        sp& 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;
    {
        Mutex::Autolock lock(mServiceLock);
        sp clientTmp;
        if (!canConnectUnsafe(cameraId, clientPackageName,
                              cameraClient->asBinder(),
                              /*out*/clientTmp)) {
            return -EBUSY;
        } else if (client.get() != NULL) {
            device = static_cast(clientTmp.get());
            return OK;
        }

        status = connectHelperLocked(/*out*/client,
                                     cameraClient,
                                     cameraId,
                                     clientPackageName,
                                     clientUid,
                                     callingPid);
        if (status != OK) {
            return status;
        }

    }
    // 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::connectHelperLocked(
        /*out*/
        sp& client,
        /*in*/
        const sp& cameraClient,
        int cameraId,
        const String16& clientPackageName,
        int clientUid,
        int callingPid,
        int halVersion,
        bool legacyMode) {

    int facing = -1;
    int deviceVersion = getDeviceVersion(cameraId, &facing);

    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:
            client = new CameraClient(this, cameraClient,
                    clientPackageName, cameraId,
                    facing, callingPid, clientUid, getpid(), legacyMode);
            break;
          case CAMERA_DEVICE_API_VERSION_2_0:
          case CAMERA_DEVICE_API_VERSION_2_1:
          case CAMERA_DEVICE_API_VERSION_3_0:
          case CAMERA_DEVICE_API_VERSION_3_1:
          case CAMERA_DEVICE_API_VERSION_3_2:
            client = new Camera2Client(this, cameraClient,
                    clientPackageName, cameraId,
                    facing, callingPid, clientUid, getpid(), legacyMode);
            break;
          case -1:
            ALOGE("Invalid camera id %d", cameraId);
            return BAD_VALUE;
          default:
            ALOGE("Unknown camera device HAL version: %d", deviceVersion);
            return INVALID_OPERATION;
        }
    } 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.
            client = new CameraClient(this, cameraClient,
                    clientPackageName, cameraId,
                    facing, callingPid, clientUid, getpid(), 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 INVALID_OPERATION;
        }
    }

    status_t status = connectFinishUnsafe(client, client->getRemote());
    if (status != OK) {
        // this is probably not recoverable.. maybe the client can try again
        return status;
    }

    mClient[cameraId] = client;
    LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId,
         getpid());

    return OK;
}


status_t CameraService::connectFinishUnsafe(const sp& client,
                                            const sp& remoteCallback) {
    status_t status = client->initialize(mModule);
    if (status != OK) {
        return status;
    }
    if (remoteCallback != NULL) {
        remoteCallback->linkToDeath(this);
    }

    return OK;
}

frameworks\av\services\camera\libcameraservice\api1\CameraClient.cpp
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);

    mHardware = new CameraHardwareInterface(camera_device_name);
    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 res;
    }

    mHardware->setCallbacks(notifyCallback,
            dataCallback,
            dataCallbackTimestamp,
            (void *)(uintptr_t)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);

//!++
#if 1
    // Enable MTK-extended messages by default
    enableMsgType(MTK_CAMERA_MSG_EXT_NOTIFY | MTK_CAMERA_MSG_EXT_DATA);
#endif
//!--

    LOG1("CameraClient::initialize X (pid %d, id %d)", callingPid, mCameraId);
    return OK;
}

frameworks\av\services\camera\libcameraservice\device1\CameraHardwareInterface.h
status_t initialize(hw_module_t *module)
    {
        ALOGI("Opening camera %s", mName.string());
        camera_module_t *cameraModule = reinterpret_cast(module);
        camera_info info;
        status_t res = cameraModule->get_camera_info(atoi(mName.string()), &info);
        if (res != OK) return res;

        int rc = OK;
        if (module->module_api_version >= 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 = cameraModule->open_legacy(module, mName.string(),
                                               CAMERA_DEVICE_API_VERSION_1_0,
                                               (hw_device_t **)&mDevice);
        } else {
            rc = CameraService::filterOpenErrorCode(module->methods->open(
                module, mName.string(), (hw_device_t **)&mDevice));
        }
        if (rc != OK) {
            ALOGE("Could not open camera %s: %d", mName.string(), rc);
            return rc;
        }
        initHalPreviewWindow();
        return rc;
    }
    
这里进行初始化Camera的相关信息, 我们所需要的情景模式保存在结构体 camera_info中    
在CameraService.cpp中getCameraCharacteristics()方法中获取CameraInfo信息
status_t CameraService::getCameraCharacteristics(int cameraId,
                                                CameraMetadata* cameraInfo) {
    if (!cameraInfo) {
        ALOGE("%s: cameraInfo is NULL", __FUNCTION__);
        return BAD_VALUE;
    }

    if (!mModule) {
        ALOGE("%s: camera hardware module doesn't exist", __FUNCTION__);
        return -ENODEV;
    }

    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
        ALOGE("%s: Invalid camera id: %d", __FUNCTION__, cameraId);
        return BAD_VALUE;
    }

    int facing;
    status_t ret = OK;
    if (mModule->common.module_api_version < CAMERA_MODULE_API_VERSION_2_0 ||
            getDeviceVersion(cameraId, &facing) <= CAMERA_DEVICE_API_VERSION_2_1 ) {
        /**
         * Backwards compatibility mode for old HALs:
         * - Convert CameraInfo into static CameraMetadata properties.
         * - Retrieve cached CameraParameters for this camera.  If none exist,
         *   attempt to open CameraClient and retrieve the CameraParameters.
         * - Convert cached CameraParameters into static CameraMetadata
         *   properties.
         */
        ALOGI("%s: Switching to HAL1 shim implementation...", __FUNCTION__);

        if ((ret = generateShimMetadata(cameraId, cameraInfo)) != OK) {
            return ret;
        }

    } else {
        /**
         * Normal HAL 2.1+ codepath.
         */
        struct camera_info info;
        ret = filterGetInfoErrorCode(mModule->get_camera_info(cameraId, &info));
        *cameraInfo = info.static_camera_characteristics;
    }

    return ret;
}

你可能感兴趣的:(android,camera)