Camera应用调用Framework Camera类API

        在Android Kitkat原生Camera2应用(packages/apps/Camera2/)的PhotoModule, VideoModule, WideAnglePanoramaModule类中用CameraUtil.open()方法来打开Camera。然后依次调 用:CameraHolder的open()方法,AndroidCameraManagerImpl的cameraOpen()方 法,CameraHandler的handleMessage()【message为OPEN_CAMERA】,直到调用Framework Camera类(frameworks/base/core/java/android/hardware/Camera.java)的open()方 法。在这里,Camera2应用程序暂不做分析,我们着重看程序向下调用的服务请求过程。

mCameraDevice = CameraUtil.openCamera( mActivity, mCameraId, mHandler, mActivity.getCameraOpenErrorCallback()); // (1)

public class CameraUtil {    public static CameraManager.CameraProxy openCamera(            Activity activity, final int cameraId,            Handler handler, final CameraManager.CameraOpenErrorCallback cb) {        try {            throwIfCameraDisabled(activity);            return CameraHolder.instance().open(handler, cameraId, cb); // (2)        } catch (CameraDisabledException ex) {            handler.post(new Runnable() {                @Override                public void run() {                    cb.onCameraDisabled(cameraId);                }            });        }        return null;    }}

public class CameraHolder {    public synchronized CameraProxy open(            Handler handler, int cameraId,            CameraManager.CameraOpenErrorCallback cb) {        …………        if (mCameraDevice == null) {            Log.v(TAG, "open camera " + cameraId);            if (mMockCameraInfo == null) {                mCameraDevice = CameraManagerFactory                        .getAndroidCameraManager().cameraOpen(handler, cameraId, cb); // (3)            …………        } else {            …………        }        mCameraOpened = true;        mHandler.removeMessages(RELEASE_CAMERA);        …………        return mCameraDevice;    }}

class AndroidCameraManagerImpl implements CameraManager {    public CameraManager.CameraProxy cameraOpen(        Handler handler, int cameraId, CameraOpenErrorCallback callback) {        mCameraHandler.obtainMessage(OPEN_CAMERA, cameraId, 0,                CameraOpenErrorCallbackForward.getNewInstance(                        handler, callback)).sendToTarget(); // (4)        …………    }}

    private class CameraHandler extends Handler {        @Override        public void handleMessage(final Message msg) {            try {                switch (msg.what) {                    case OPEN_CAMERA:                        mCamera = android.hardware.Camera.open(msg.arg1); // (5)                        …………                        return;                }            }        }    }

 

JNI层调用

        Framework Camera类API调用本地方法,而本地方法被注册到JNI,因此通过JNI调用 android_hardware_Camera.cpp(/framworks/base/core/jni/)中对应的方法。在打开相机的过程 中,Framework Camera类的open()方法调用本地方法native_setup()。native_setup()被注册到JNI,通过JNI调用 android_hardware_Camera_native_setup()方法。再通过 android_hardware_Camera_native_setup()调用Camera::connect()函数 (frameworks/av/camera/Camera.cpp)请求连接CameraService服务。

public class Camera {    public static Camera open(int cameraId) {        return new Camera(cameraId);    }    Camera(int cameraId) {        …………        String packageName = ActivityThread.currentPackageName();        native_setup(new WeakReference(this), cameraId, packageName);    }}

JNI层注册native_setup方法

static JNINativeMethod camMethods[] = {  { "native_setup",    "(Ljava/lang/Object;ILjava/lang/String;)V",    (void*)android_hardware_Camera_native_setup }    ……};

// connect to camera servicestatic void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,    jobject weak_this, jint cameraId, jstring clientPackageName){    …………    sp camera = Camera::connect(cameraId, clientName,            Camera::USE_CALLING_UID);    …………}

 

CameraService服务连接(IPC通信)

        JNI调用Camera::connect()请求CameraService服务。Camera类继承模板类 CameraBase和BnCameraClient。首先调用模板类的connect()函数,在函数中向 ServiceManager获取Camera服务信息,并生成CameraService服务代理 BpCameraService(/frameworks/av/camera/ICameraService.cpp),然后通过Binder通信发送 CONNECT命令,当BnCameraService收到CONNECT命令后调用CameraService的connect()成员函数来做相应的 处理。

template sp CameraBase::connect(int cameraId,                                               const String16& clientPackageName,                                               int clientUid){    sp c = new TCam(cameraId);    // BnCameraClient    sp cl = c;    status_t status = NO_ERROR;    const sp& cs = getCameraService();    // return BpCameraService    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;}

       下面我们来分析BpCameraService的connect()成员函数。首先将传递过来的Camera对象转换成IBinder类型,将调用的参数写到Parcel中,通过BpBinder的transact()函数发送消息,然后由BnCameraService去响应该连接,最后就是等待服务端返回,如果成功这里为我们生成一个BpCamera实例。

class BpCameraService: public BpInterface{    // connect to camera service (android.hardware.Camera)    virtual status_t connect(const sp& cameraClient, int cameraId,                             const String16 &clientPackageName, int clientUid,                             /*out*/                             sp& device)    {        Parcel data, reply;        data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());        data.writeStrongBinder(cameraClient->asBinder());        data.writeInt32(cameraId);        data.writeString16(clientPackageName);        data.writeInt32(clientUid);        remote()->transact(BnCameraService::CONNECT, data, &reply); // BpBinder的transact()函数向IPCThreadState实例发送消息,通知其有消息要发送给binder driver        if (readExceptionCode(reply)) return -EPROTO;        status_t status = reply.readInt32();        if (reply.readInt32() != 0) {            device = interface_cast(reply.readStrongBinder()); // client端读出server返回的binder        }        return status;    }}

        BnCameraService的onTransact()函数负责解包收到的Parcel并执行client端的请求的方法。服务端收到CONNECT命令之后,

(1) 使用Camera的Binder对象生成Camera客户代理BpCameraClient实例;

(2) 将生成的BpCameraClient对象作为参数传递到CameraService(/frameworks/av/services/camera /libcameraservice/CameraService.cpp)的connect()函数中,该函数会返回一个BpCamera实例;

(3) 将在(2)中返回的实例对象以IBinder的形式打包到Parcel中返回。

status_t BnCameraService::onTransact(    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){    switch(code) {        case CONNECT: {            CHECK_INTERFACE(ICameraService, data, reply);            sp cameraClient =                    interface_cast(data.readStrongBinder()); // (1)            int32_t cameraId = data.readInt32();            const String16 clientName = data.readString16();            int32_t clientUid = data.readInt32();            sp camera;            status_t status = connect(cameraClient, cameraId,                    clientName, clientUid, /*out*/ camera); // (2)            reply->writeNoException();            reply->writeInt32(status);            if (camera != NULL) {                reply->writeInt32(1);                reply->writeStrongBinder(camera->asBinder()); // (3)            } else {                reply->writeInt32(0);            }            return NO_ERROR;        } break;    }}

        接下来看CameraService::connect()函数,该函数返回一个BpCamera实例。

status_t CameraService::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;        }        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);        }        /* 根据HAL不同API的版本创建不同的client实例 */        switch(deviceVersion) {          case CAMERA_DEVICE_API_VERSION_1_0:            client = new CameraClient(this, cameraClient,                    clientPackageName, cameraId,                    facing, callingPid, clientUid, getpid());            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;        }        status_t status = connectFinishUnsafe(client, client->getRemote());        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; // every camera is a Client class        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; // 返回的camera device实例    return OK;}

 

         至此,一次Framework层的Camera服务请求过程完成。



更多相关文章

  1. C语言函数的递归(上)
  2. Android(安卓)中判断是否存在虚拟按键
  3. WebView深究之Android是如何实现webview初始化的
  4. Android(安卓)webview加载富文本 屏幕简单适配
  5. android中setVisibility的用法
  6. Android(安卓)混淆配置文件及常用第三方混淆
  7. 下载 android 源码错误curl: (6) couldn't connect to host的解
  8. Android消息机制2-Handler(Native层)
  9. 监听Android键盘上的按钮

随机推荐

  1. 12月28日圣杯布局(grid版)
  2. 【北亚数据恢复】EMC Unity 400存储误操
  3. 12月27日媒体查询作业
  4. 开发常用镜像站 - 阿里云镜像站
  5. 12月22日弹窗作业
  6. Centos7.x环境下 安装Diszz
  7. vue项目的进一轮学习
  8. 小鸟云服务器如何安装rstudio-server?
  9. 电影奇迹•笨小孩迅雷BT完整下载[MKV/3.1
  10. 怎样练习手绘线条?练习画线条的方法