博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
sc7731 Android 5.1 Camera 学习之一Camera 两个对象
阅读量:6233 次
发布时间:2019-06-21

本文共 28218 字,大约阅读时间需要 94 分钟。

众所周知,在Android中Camera采用了C/S架构,其中Camera server 与 Camera client之间通过Android Binder IPC机制进行通信。

在Camera实现的框架中,除开HAL层以及驱动层以下是采用的C语言进行编写以外,其余的都是c++ 和java这两大经典面向对象的语言来实现的。
网络上大部分的分析,是基于一个client端对server端的过程调用,一步一步的深入到驱动底层。而我自己,更愿意从对象的角度来分析camera的脉络。
其实,整个Camera框架,主体上来说,就两类对象,这里可以简化为两个对象,其中一个是Camera server对象,另外一个是Camera client对象。
这两个对象之间的交流沟通,是通过第三方对象来搞定的,主要是binder对象,当然也还有一些其他辅助的对象。

在参阅网络上大量优秀博客文章以及源代码后,对自己的分析做一个简要的笔记。

一、Camera Server 对象

1. Camera Server 对象的定义

class CameraService 定义在了frameworks/av/services/camera/libcameraservice/CameraService.h文件中:
(这个类太牛逼了,300多行,简化吧)

1 class CameraService :  2     public BinderService
, 3 public BnCameraService, 4 public IBinder::DeathRecipient, 5 public camera_module_callbacks_t 6 { 7 // Implementation of BinderService
8 static char const* getServiceName() { return "media.camera"; } 9 10 CameraService(); 11 virtual ~CameraService(); 12 13 //... 14 15 / 16 // HAL Callbacks 17 virtual void onDeviceStatusChanged(int cameraId, 18 int newStatus); 19 20 / 21 22 //... 23 24 / 25 // ICameraService 26 virtual int32_t getNumberOfCameras(); 27 virtual status_t getCameraInfo(int cameraId, 28 struct CameraInfo* cameraInfo); 29 virtual status_t getCameraCharacteristics(int cameraId, 30 CameraMetadata* cameraInfo); 31 virtual status_t getCameraVendorTagDescriptor(/*out*/ sp
& desc); 32 33 virtual status_t connect(const sp
& cameraClient, int cameraId, 34 const String16& clientPackageName, int clientUid, 35 /*out*/ 36 sp
& device); 37 38 virtual status_t connectLegacy(const sp
& cameraClient, int cameraId, 39 int halVersion, const String16& clientPackageName, int clientUid, 40 /*out*/ 41 sp
& device); 42 43 virtual status_t connectPro(const sp
& cameraCb, 44 int cameraId, const String16& clientPackageName, int clientUid, 45 /*out*/ 46 sp
& device); 47 48 virtual status_t connectDevice( 49 const sp
& cameraCb, 50 int cameraId, 51 const String16& clientPackageName, 52 int clientUid, 53 /*out*/ 54 sp
& device); 55 56 virtual status_t addListener(const sp
& listener); 57 virtual status_t removeListener( 58 const sp
& listener); 59 60 virtual status_t getLegacyParameters( 61 int cameraId, 62 /*out*/ 63 String16* parameters); 64 65 // OK = supports api of that version, -EOPNOTSUPP = does not support 66 virtual status_t supportsCameraApi( 67 int cameraId, int apiVersion); 68 69 // Extra permissions checks 70 virtual status_t onTransact(uint32_t code, const Parcel& data, 71 Parcel* reply, uint32_t flags); 72 73 //... 74 75 / 76 // CameraClient functionality 77 class BasicClient : public virtual RefBase { 78 public: 79 virtual status_t initialize(camera_module_t *module) = 0; 80 virtual void disconnect(); 81 //.... 82 }; 83 84 //... 85 class Client : public BnCamera, public BasicClient 86 { 87 public: 88 typedef ICameraClient TCamCallbacks; 89 90 // ICamera interface (see ICamera for details) 91 virtual void disconnect(); 92 virtual status_t connect(const sp
& client) = 0; 93 virtual status_t lock() = 0; 94 virtual status_t unlock() = 0; 95 virtual status_t setPreviewTarget(const sp
& bufferProducer)=0; 96 virtual void setPreviewCallbackFlag(int flag) = 0; 97 virtual status_t setPreviewCallbackTarget( 98 const sp
& callbackProducer) = 0; 99 virtual status_t startPreview() = 0;100 virtual void stopPreview() = 0;101 virtual bool previewEnabled() = 0;102 virtual status_t storeMetaDataInBuffers(bool enabled) = 0;103 virtual status_t startRecording() = 0;104 virtual void stopRecording() = 0;105 virtual bool recordingEnabled() = 0;106 virtual void releaseRecordingFrame(const sp
& mem) = 0;107 virtual status_t autoFocus() = 0;108 virtual status_t cancelAutoFocus() = 0;109 virtual status_t takePicture(int msgType) = 0;110 virtual status_t setParameters(const String8& params) = 0;111 virtual String8 getParameters() const = 0;112 virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) = 0;113 114 // Interface used by CameraService115 Client(const sp
& cameraService,116 const sp
& cameraClient,117 const String16& clientPackageName,118 int cameraId,119 int cameraFacing,120 int clientPid,121 uid_t clientUid,122 int servicePid);123 ~Client();124 125 // return our camera client126 const sp
& getRemoteCallback() {127 return mRemoteCallback;128 }129 130 virtual sp
asBinderWrapper() {131 return asBinder();132 }133 134 protected:135 static Mutex* getClientLockFromCookie(void* user);136 // convert client from cookie. Client lock should be acquired before getting Client.137 static Client* getClientFromCookie(void* user);138 139 virtual void notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,140 const CaptureResultExtras& resultExtras);141 142 // Initialized in constructor143 144 // - The app-side Binder interface to receive callbacks from us145 sp
mRemoteCallback;146 147 }; // class Client 148 149 class ProClient : public BnProCameraUser, public BasicClient { //...};150 151 private:152 153 // Delay-load the Camera HAL module154 virtual void onFirstRef();155 156 // Step 1. Check if we can connect, before we acquire the service lock.157 status_t validateConnect(int cameraId,158 /*inout*/159 int& clientUid) const;160 161 // Step 2. Check if we can connect, after we acquire the service lock.162 bool canConnectUnsafe(int cameraId,163 const String16& clientPackageName,164 const sp
& remoteCallback,165 /*out*/166 sp
&client);167 168 // When connection is successful, initialize client and track its death169 status_t connectFinishUnsafe(const sp
& client,170 const sp
& remoteCallback);171 172 virtual sp
getClientByRemote(const wp
& cameraClient);173 174 //.... 175 176 camera_module_t *mModule;177 //...178 179 };
View Code

这个类定义的东西太多了,300多行的东西。其实,简而言之,它分为这几个部分:

(1). 和binder通信有关的东西,比如:

static char const* getServiceName() { return "media.camera"; }

(2). 和client有关的东西:

在CameraService 的内部,定义了一个Client类。当远端Client对server进行调用操作的时候,其最终会把该动作落实到 在CameraService 内部的这个Client 类实例化上来.

1 class Client : public BnCamera, public BasicClient2 {3  //...4 };

(3). 和HAL层有关的东西,比如:

// HAL Callbacks    virtual void        onDeviceStatusChanged(int cameraId,                                              int newStatus);---
camera_module_t *mModule;

就整个类来说,CameraService 主要有这三大部分。当然,这只是一部分,还有其他很多重要的部分,比如 MediaPlayer 等等,此处进行简化。

从以上列出来的三部分可以知道CameraServer的大概工作内容了: 通过Binder联系Client;通过HAL联系底层驱动。

2.Camera Server 对象的产生过程

因为Binder的关系,Camera server对象是需要向Binder的相关机构进行注册,否则client无法通过Binder找到它。当Camera server注册以后,它就静静的等待着Client的到来。
(1). init.rc 文件
以展讯sc7731为例,在 device/sprd/scx35/recovery/init.rc 文件中,将camera归属到media的组类别中:

service media /system/bin/mediaserver    class factorytest    user media    group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm                                                    ioprio rt 4

该文件在Android 的第一个应用程序/init 中会被解析的,在system/core/init/init.c 文件中:

int main(int argc, char **argv){    //...    init_parse_config_file("/init.rc");    //...}

在这里会将上述的mediaserver的服务解析出来,至于解析后详细的去向经过,此处略去。

(2). 将 CameraService 注册到Binder ServiceManager里面

在文件 frameworks/av/media/mediaserver/main_mediaserver.cpp 中进行注册:

int main(int argc __unused, char** argv){    //...    CameraService::instantiate();    //...}

至于 CameraService::instantiate() 的实现,在BinderService这个模板基类里面已经实现过了,在文件 frameworks/native/include/binder/BinderService.h 中:

template
class BinderService{public: static status_t publish(bool allowIsolated = false) { sp
sm(defaultServiceManager()); return sm->addService( String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated); } static void instantiate() { publish(); } //...};

将 SERVICE::getServiceName() 替换成 CameraService::getServiceName()即可。在frameworks/av/services/camera/libcameraservice/CameraService.h 文件中:

class CameraService :    public BinderService
, public BnCameraService, public IBinder::DeathRecipient, public camera_module_callbacks_t{ static char const* getServiceName() { return "media.camera"; }};

将new SERVICE() 替换成 new CameraService(), 那么,有意思的事情就发生了,就这样,一个camera server 的对象产生了。

二、Camera Client对象

1. Camera Client在jni层的定义
在 frameworks/av/include/camera/Camera.h 文件中定义如下:

1 class Camera :  2     public CameraBase
, 3 public BnCameraClient 4 { 5 public: 6 enum { 7 USE_CALLING_UID = ICameraService::USE_CALLING_UID 8 }; 9 10 // construct a camera client from an existing remote 11 static sp
create(const sp
& camera); 12 static sp
connect(int cameraId, 13 const String16& clientPackageName, 14 int clientUid); 15 16 static status_t connectLegacy(int cameraId, int halVersion, 17 const String16& clientPackageName, 18 int clientUid, sp
& camera); 19 20 virtual ~Camera(); 21 22 status_t reconnect(); 23 status_t lock(); 24 status_t unlock(); 25 26 // pass the buffered IGraphicBufferProducer to the camera service 27 status_t setPreviewTarget(const sp
& bufferProducer); 28 29 // start preview mode, must call setPreviewTarget first 30 status_t startPreview(); 31 32 // stop preview mode 33 void stopPreview(); 34 35 // get preview state 36 bool previewEnabled(); 37 38 // start recording mode, must call setPreviewTarget first 39 status_t startRecording(); 40 41 // stop recording mode 42 void stopRecording(); 43 44 // get recording state 45 bool recordingEnabled(); 46 47 // release a recording frame 48 void releaseRecordingFrame(const sp
& mem); 49 50 // autoFocus - status returned from callback 51 status_t autoFocus(); 52 53 // cancel auto focus 54 status_t cancelAutoFocus(); 55 56 // take a picture - picture returned from callback 57 status_t takePicture(int msgType); 58 59 // set preview/capture parameters - key/value pairs 60 status_t setParameters(const String8& params); 61 62 // get preview/capture parameters - key/value pairs 63 String8 getParameters() const; 64 65 // send command to camera driver 66 status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2); 67 68 // tell camera hal to store meta data or real YUV in video buffers. 69 status_t storeMetaDataInBuffers(bool enabled); 70 71 void setListener(const sp
& listener); 72 void setRecordingProxyListener(const sp
& listener); 73 74 // Configure preview callbacks to app. Only one of the older 75 // callbacks or the callback surface can be active at the same time; 76 // enabling one will disable the other if active. Flags can be 77 // disabled by calling it with CAMERA_FRAME_CALLBACK_FLAG_NOOP, and 78 // Target by calling it with a NULL interface. 79 void setPreviewCallbackFlags(int preview_callback_flag); 80 status_t setPreviewCallbackTarget( 81 const sp
& callbackProducer); 82 83 sp
getRecordingProxy(); 84 85 // ICameraClient interface 86 virtual void notifyCallback(int32_t msgType, int32_t ext, int32_t ext2); 87 virtual void dataCallback(int32_t msgType, const sp
& dataPtr, 88 camera_frame_metadata_t *metadata); 89 virtual void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp
& dataPtr); 90 91 class RecordingProxy : public BnCameraRecordingProxy 92 { 93 public: 94 RecordingProxy(const sp
& camera); 95 96 // ICameraRecordingProxy interface 97 virtual status_t startRecording(const sp
& listener); 98 virtual void stopRecording(); 99 virtual void releaseRecordingFrame(const sp
& mem);100 101 private:102 sp
mCamera;103 };104 105 protected:106 Camera(int cameraId);107 Camera(const Camera&);108 Camera& operator=(const Camera);109 110 sp
mRecordingProxyListener;111 112 friend class CameraBase;113 };

相比较server端的定义来说,该类非常的简单和清晰。它实质上是,为jni的实现封装了对应的c++接口而已。它和 jni 文件 android_hardware_Camera.cpp 中的接口,几乎是一一对应的。

在 frameworks/base/core/jni/android_hardware_Camera.cpp 文件中,有以下表格:

1 static JNINativeMethod camMethods[] = { 2   { "getNumberOfCameras", 3     "()I", 4     (void *)android_hardware_Camera_getNumberOfCameras }, 5   { "_getCameraInfo", 6     "(ILandroid/hardware/Camera$CameraInfo;)V", 7     (void*)android_hardware_Camera_getCameraInfo }, 8   { "native_setup", 9     "(Ljava/lang/Object;IILjava/lang/String;)I",10     (void*)android_hardware_Camera_native_setup },11   { "native_release",12     "()V",13     (void*)android_hardware_Camera_release },14   { "setPreviewSurface",15     "(Landroid/view/Surface;)V",16     (void *)android_hardware_Camera_setPreviewSurface },17   { "setPreviewTexture",18     "(Landroid/graphics/SurfaceTexture;)V",19     (void *)android_hardware_Camera_setPreviewTexture },20   { "setPreviewCallbackSurface",21     "(Landroid/view/Surface;)V",22     (void *)android_hardware_Camera_setPreviewCallbackSurface },23   { "startPreview",24     "()V",25     (void *)android_hardware_Camera_startPreview },26   { "_stopPreview",27     "()V",28     (void *)android_hardware_Camera_stopPreview },29   { "previewEnabled",30     "()Z",31     (void *)android_hardware_Camera_previewEnabled },32   { "setHasPreviewCallback",33     "(ZZ)V",34     (void *)android_hardware_Camera_setHasPreviewCallback },35   { "_addCallbackBuffer",36     "([BI)V",37     (void *)android_hardware_Camera_addCallbackBuffer },38   { "native_autoFocus",39     "()V",40     (void *)android_hardware_Camera_autoFocus },41   { "native_cancelAutoFocus",42     "()V",43     (void *)android_hardware_Camera_cancelAutoFocus },44   { "native_takePicture",45     "(I)V",46     (void *)android_hardware_Camera_takePicture },47   { "native_setParameters",48     "(Ljava/lang/String;)V",49     (void *)android_hardware_Camera_setParameters },50   { "native_getParameters",51     "()Ljava/lang/String;",52     (void *)android_hardware_Camera_getParameters },53   { "reconnect",54     "()V",55     (void*)android_hardware_Camera_reconnect },56   { "lock",57     "()V",58     (void*)android_hardware_Camera_lock },59   { "unlock",60     "()V",61     (void*)android_hardware_Camera_unlock },62   { "startSmoothZoom",63     "(I)V",64     (void *)android_hardware_Camera_startSmoothZoom },65   { "stopSmoothZoom",66     "()V",67     (void *)android_hardware_Camera_stopSmoothZoom },68   { "setDisplayOrientation",69     "(I)V",70     (void *)android_hardware_Camera_setDisplayOrientation },71   { "_enableShutterSound",72     "(Z)Z",73     (void *)android_hardware_Camera_enableShutterSound },74   { "_startFaceDetection",75     "(I)V",76     (void *)android_hardware_Camera_startFaceDetection },77   { "_stopFaceDetection",78     "()V",79     (void *)android_hardware_Camera_stopFaceDetection},80   { "enableFocusMoveCallback",81     "(I)V",82     (void *)android_hardware_Camera_enableFocusMoveCallback},83 };

2. Camera Client对象的产生过程

(1). App 层
当App试图打开摄像头时,会启动一个线程,用于打开摄像头,在文件 packages/apps/LegacyCamera/src/com/android/camera/Camera.java 中:

1     Thread mCameraOpenThread = new Thread(new Runnable() { 2         public void run() { 3             //... 4                 mCameraDevice = Util.openCamera(Camera.this, mCameraId); //open camera 5             //... 6         } 7     }); 8  9 public void onCreate(Bundle icicle) {10     mCameraOpenThread.start();11 };

(2)frame -java 层

frameworks/base/core/java/android/hardware/Camera.java 文件中

1 public static Camera open(int cameraId) { 2     return new Camera(cameraId); 3 } 4  5 /** used by Camera#open, Camera#open(int) */ 6 Camera(int cameraId) { 7     int err = cameraInitNormal(cameraId); 8  //... 9 }10 11 private int cameraInitNormal(int cameraId) {12     return cameraInitVersion(cameraId, CAMERA_HAL_API_VERSION_NORMAL_CONNECT);13 }14 15 private int cameraInitVersion(int cameraId, int halVersion) {16 //....17     return native_setup(new WeakReference
(this), cameraId, halVersion, packageName);18 }

native_setup 通过上面的methods[]表格可以看出,是jni提供的。

(3)JNI层

在 jni/android_hardware_Camera.cpp 文件中,native_setup 对应着jni的 android_hardware_Camera_native_setup()方法:

1 // connect to camera service 2 static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, 3     jobject weak_this, jint cameraId, jint halVersion, jstring clientPackageName) 4 { 5     // Convert jstring to String16 6  7     sp
camera; 8 9 // Default path: hal version is don't care, do normal camera connect.10 camera = Camera::connect(cameraId, clientName,11 Camera::USE_CALLING_UID);12 13 // We use a weak reference so the Camera object can be garbage collected.14 // The reference is only used as a proxy for callbacks.15 sp
context = new JNICameraContext(env, weak_this, clazz, camera);16 context->incStrong((void*)android_hardware_Camera_native_setup);17 camera->setListener(context);18 19 // save context in opaque field20 env->SetLongField(thiz, fields.context, (jlong)context.get());21 return NO_ERROR;22 }

可以简单粗暴的认为, sp<Camera> camera; 这句代码就是声明了一个 Camera相关的指针或者是引用,它会指向一个Camera对象。----当然,实质上,这是Android中的智能指针,表面对象引用计数的一个东西。

那这里就主要看下Camera::connect()是怎么返回一个对象指针(引用)的。

(4)frame-c++层

在 frameworks/av/camera/Camera.cpp 文件中:

1 sp
Camera::connect(int cameraId, const String16& clientPackageName,2 int clientUid)3 {4 return CameraBaseT::connect(cameraId, clientPackageName, clientUid);5 }

类Camera 继承于类 CameraBaseT,CameraBaseT定义在了 frameworks/av/include/camera/CameraBase.h 文件中,成员函数实现在了 frameworks/av/camera/CameraBase.cpp 文件中。

这里看下CameraBaseT::connect()的动作:

1 template 
2 sp
CameraBase
::connect(int cameraId, 3 const String16& clientPackageName, 4 int clientUid) 5 { 6 sp
c = new TCam(cameraId); 7 8 //通过SM获取CameraService在本地的一个引用。调用connect函数后最终调用CameraService侧的connect()函数 9 const sp
& cs = getCameraService();10 11 if (cs != 0) {12 TCamConnectService fnConnectService = TCamTraits::fnConnectService;13 status = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid,14 /*out*/ c->mCamera);15 }16 //...17 }

获取CameraService在本地的一个引用,这行代码很简单。而比较有意思的是,是如何将client端的connect交换到server端。

由于这里是一个模板,模板的原则是带入或者说用实例去替换。
上面的 TCam 可以使用 Camera 来替换;但是TCamTraits可没人传进来,怎么替换呢?
在 frameworks/av/include/camera/CameraBase.h 文件中:

1 template 
>2 class CameraBase : public IBinder::DeathRecipient3 {4 //...5 };

在CameraBase模板定义的时候,可以看到了 typename TCamTraits = CameraTraits<TCam> 简而言之,就是TCamTraits使用默认的CameraTraits<TCam>的来代替就行了。

而CameraTraits<TCam>中的 TCam 再次使用 Camera 来代替,那就形成了这个格式:

1 TCamConnectService fnConnectService = TCamTraits::fnConnectService;  =>  TCamConnectService fnConnectService = CameraTraits
::fnConnectService;

而 CameraTraits<Camera>::fnConnectService 在 frameworks/av/camera/Camera.cpp 文件中有明确的表示:

1 CameraTraits
::TCamConnectService CameraTraits
::fnConnectService =2 &ICameraService::connect;

于是,这样,就把client端的connect交换到了 ICameraService 的名录下了。而这个ICameraService 与 server是有着远亲继承关系的:

可以回头看下 CameraService 的继承关系:

1 class CameraService :2     public BinderService
,3 public BnCameraService,4 public IBinder::DeathRecipient,5 public camera_module_callbacks_t6 {7 //...8 };

这里有继承 BnCameraService 类,再看下 BnCameraService 的定义:

1 class BnCameraService: public BnInterface
2 {3 //...4 };

再跟下 public BnInterface<ICameraService> 的东西:

1 template
2 class BnInterface : public INTERFACE, public BBinder3 {4 //...5 };

到了这里,当我们使用 ICameraService 替换掉 INTERFACE 后,一切的远亲关系就明了了。也就无需赘言了。

就这样,最终来到了 CameraService 的connect()成员函数里了。
现在,就把对象从client转换成server吧:

在 frameworks/av/services/camera/libcameraservice/CameraService.cpp 文件中:

1 status_t CameraService::connect( 2         const sp
& cameraClient, 3 int cameraId, 4 const String16& clientPackageName, 5 int clientUid, 6 /*out*/ 7 sp
& device) { 8 9 //...10 11 sp
client;12 {13 //...14 status = connectHelperLocked(/*out*/client,15 cameraClient,16 cameraId,17 clientPackageName,18 clientUid,19 callingPid);20 }21 // important: release the mutex here so the client can call back22 // into the service from its destructor (can be at the end of the call)23 24 device = client; //通过指针(引用)方式,将获取到的Camera对象,返回到client那边去,然后再逐一返回到java层。当然,这种说通过指针的方式,仅是一种粗暴简单的说法。25 return OK;26 }

这里面的 connectHelperLocked()很重要,它将是整个Camera框架中,获取一个Camera client对象的终点:

1 status_t CameraService::connectHelperLocked( 2         /*out*/ 3         sp
& client, 4 /*in*/ 5 const sp
& cameraClient, 6 int cameraId, 7 const String16& clientPackageName, 8 int clientUid, 9 int callingPid,10 int halVersion,11 bool legacyMode) {12 13 //... 14 client = new CameraClient(this, cameraClient,15 clientPackageName, cameraId,16 facing, callingPid, clientUid, getpid(), legacyMode);17 18 //... 19 status_t status = connectFinishUnsafe(client, client->getRemote());20 21 //...22 mClient[cameraId] = client;23 24 //...25 return OK;26 }

好! 这里会new 一个camera client,看下 CameraClient的定义,在 frameworks/av/services/camera/libcameraservice/api1/CameraClient.h 文件中:

1 class CameraClient : public CameraService::Client 2 { 3 public: 4     // ICamera interface (see ICamera for details) 5     virtual void            disconnect(); 6     virtual status_t        connect(const sp
& client); 7 virtual status_t lock(); 8 virtual status_t unlock(); 9 virtual status_t setPreviewTarget(const sp
& bufferProducer);10 virtual void setPreviewCallbackFlag(int flag);11 virtual status_t setPreviewCallbackTarget(12 const sp
& callbackProducer);13 virtual status_t startPreview();14 virtual void stopPreview();15 virtual bool previewEnabled();16 virtual status_t storeMetaDataInBuffers(bool enabled);17 virtual status_t startRecording();18 virtual void stopRecording();19 virtual bool recordingEnabled();20 virtual void releaseRecordingFrame(const sp
& mem);21 virtual status_t autoFocus();22 virtual status_t cancelAutoFocus();23 virtual status_t takePicture(int msgType);24 virtual status_t setParameters(const String8& params);25 virtual String8 getParameters() const;26 virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);27 28 // Interface used by CameraService29 CameraClient(const sp
& cameraService,30 const sp
& cameraClient,31 const String16& clientPackageName,32 int cameraId,33 int cameraFacing,34 int clientPid,35 int clientUid,36 int servicePid,37 bool legacyMode = false);38 ~CameraClient();39 40 status_t initialize(camera_module_t *module);41 //...42 43 private:44 45 //...46 };

从定义可以知道,CameraClient 是来自 CameraService::Client 这个内部类的。

而 CameraService::Client 这个内部类,可以世俗的认为,是 CameraService 专为 Client 在心中留下的位置。
所谓的Client的远端调用,最终都会落实到 CameraService::Client 这个里面去做,再通过继承的关系,就顺利成章的把这一切任务交给了 CameraClient 的实例.
其实,到了这里,还不能完全说,真正的camera client对象已经被new出来了。因为Camera最终会和具体的设备相关。在new了一个 CameraClient 后,还需要考虑设备上的一些问题。
这里需要关注下下面这行代码的处理,因为它会告诉上层一个 CameraClient 是否构造成功的标志:

1 status_t status = connectFinishUnsafe(client, client->getRemote());
1 status_t CameraService::connectFinishUnsafe(const sp
& client, 2 const sp
& remoteCallback) { 3 status_t status = client->initialize(mModule); 4 5 if (status != OK) { 6 ALOGE("%s: Could not initialize client from HAL module.", __FUNCTION__); 7 return status; 8 } 9 if (remoteCallback != NULL) {10 remoteCallback->linkToDeath(this);11 }12 13 return OK;14 }

看下 client->initialize 的实现, 在 frameworks/av/services/camera/libcameraservice/api1/CameraClient.cpp 文件中:

1 status_t CameraClient::initialize(camera_module_t *module) { 2     int callingPid = getCallingPid(); 3     status_t res; 4  5     // Verify ops permissions 6     res = startCameraOps(); 7     if (res != OK) { 8         return res; 9     }10 11     char camera_device_name[10];12     snprintf(camera_device_name, sizeof(camera_device_name), "%d", mCameraId);13 14     mHardware = new CameraHardwareInterface(camera_device_name);15     res = mHardware->initialize(&module->common);16     if (res != OK) {17         ALOGE("%s: Camera %d: unable to initialize device: %s (%d)",18                 __FUNCTION__, mCameraId, strerror(-res), res);19         mHardware.clear();20         return res;21     }22 23     //设置HAL层的回掉函数24     mHardware->setCallbacks(notifyCallback,25             dataCallback,26             dataCallbackTimestamp,27             (void *)(uintptr_t)mCameraId);28 29     // Enable zoom, error, focus, and metadata messages by default30     enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |31                   CAMERA_MSG_PREVIEW_METADATA | CAMERA_MSG_FOCUS_MOVE);32 33     LOG1("CameraClient::initialize X (pid %d, id %d)", callingPid, mCameraId);34     return OK;35 }

看下 mHardware->initialize 的实现, 在文件 frameworks/av/services/camera/libcameraservice/device1/CameraHardwareInterface.h 中:

1 class CameraHardwareInterface : public virtual RefBase {2 public:3     status_t initialize(hw_module_t *module)4     {5         camera_module_t *cameraModule = reinterpret_cast
(module);6 //....7 }8 };

在这里,出现了 hw_module_t 这个HAL层特有的数据结构---也即是说,这里就开始涉及到了 HAL层。

那么,当一个 CameraClient 被new 后,initialize会去HAL层处理相关事务,如果没有意外,那这个 CameraClient 对象就真正的new 成功了。然后根据状态标志,将一路返回,直到App那里。

而App可能将开始打开摄像头的下一步动作:预览。

但这已经不再本篇 Camera对象的分析范围内了。

当摄像头client对象被建立(打开)后,下面的预览、拍照等等一切操作,将依赖刚才那个返回的 CameraClient 对象引用。在文件 android_hardware_Camera.cpp中:

1 sp
get_native_camera(JNIEnv *env, jobject thiz, JNICameraContext** pContext) 2 { 3 sp
camera; 4 Mutex::Autolock _l(sLock); 5 JNICameraContext* context = reinterpret_cast
(env->GetLongField(thiz, fields.context)); 6 if (context != NULL) { 7 camera = context->getCamera(); 8 } 9 ALOGI("get_native_camera: context=%p, camera=%p", context, camera.get());10 if (camera == 0) {11 jniThrowRuntimeException(env,12 "Camera is being used after Camera.release() was called");13 }14 15 if (pContext != NULL) *pContext = context;16 return camera;17 }

get_native_camera会去获取已经创建好了的 CameraClient 对象。比如拍照:

1 static void android_hardware_Camera_takePicture(JNIEnv *env, jobject thiz, jint msgType)2 {3     //...4     sp
camera = get_native_camera(env, thiz, &context);5 //...6 }

比如预览:

1 static void android_hardware_Camera_startPreview(JNIEnv *env, jobject thiz)2 {3     ALOGV("startPreview");4     sp
camera = get_native_camera(env, thiz, NULL);5 if (camera == 0) return;6 //...7 }

等等一系列动作,将依赖那个返回的 CameraClient 对象引用。直到 release 动作的发生。

(over)
2016-01-1

 

转载于:https://www.cnblogs.com/chineseboy/p/5142954.html

你可能感兴趣的文章
keil中的存储模式
查看>>
jQuery EasyUI API 中文文档 - Panel面板
查看>>
egrep 查找IP
查看>>
从子集和问题的动态规划解看判断问题与优化问题的区别与联系
查看>>
Effective C++:条款28:避免返回 handles 指向对象内部成员
查看>>
gulp-notify处理报错----gulp系列(二)
查看>>
浅谈OCR之Onenote 2010
查看>>
Android SDK打包
查看>>
yii url美化 urlManager组件
查看>>
数据库(表)的逻辑备份与恢复
查看>>
SQL SERVER 2005允许自定义聚合函数-表中字符串分组连接
查看>>
linux內核輸出soft lockup
查看>>
Android -- Annotation
查看>>
第3章 结构之法——重建二叉树
查看>>
struts2基本介绍
查看>>
celery最佳实践
查看>>
Ubuntu的LTS版本
查看>>
(剑指Offer)面试题51:数组中重复的数字
查看>>
第二十七篇:SOUI中控件属性查询方法
查看>>
HttpComponents 也就是以前的httpclient项目
查看>>