众所周知,在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多行,简化吧)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 class CameraService : 2 public BinderService<CameraService>, 3 public BnCameraService, 4 public IBinder::DeathRecipient, 5 public camera_module_callbacks_t 6 { 7 // Implementation of BinderService<T> 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<VendorTagDescriptor>& desc); 32 33 virtual status_t connect(const sp<ICameraClient>& cameraClient, int cameraId, 34 const String16& clientPackageName, int clientUid, 35 /*out*/ 36 sp<ICamera>& device); 37 38 virtual status_t connectLegacy(const sp<ICameraClient>& cameraClient, int cameraId, 39 int halVersion, const String16& clientPackageName, int clientUid, 40 /*out*/ 41 sp<ICamera>& device); 42 43 virtual status_t connectPro(const sp<IProCameraCallbacks>& cameraCb, 44 int cameraId, const String16& clientPackageName, int clientUid, 45 /*out*/ 46 sp<IProCameraUser>& device); 47 48 virtual status_t connectDevice( 49 const sp<ICameraDeviceCallbacks>& cameraCb, 50 int cameraId, 51 const String16& clientPackageName, 52 int clientUid, 53 /*out*/ 54 sp<ICameraDeviceUser>& device); 55 56 virtual status_t addListener(const sp<ICameraServiceListener>& listener); 57 virtual status_t removeListener( 58 const sp<ICameraServiceListener>& 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<ICameraClient>& client) = 0; 93 virtual status_t lock() = 0; 94 virtual status_t unlock() = 0; 95 virtual status_t setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer)=0; 96 virtual void setPreviewCallbackFlag(int flag) = 0; 97 virtual status_t setPreviewCallbackTarget( 98 const sp<IGraphicBufferProducer>& 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<IMemory>& 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 CameraService 115 Client(const sp<CameraService>& cameraService, 116 const sp<ICameraClient>& 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 client 126 const sp<ICameraClient>& getRemoteCallback() { 127 return mRemoteCallback; 128 } 129 130 virtual sp<IBinder> 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 constructor 143 144 // - The app-side Binder interface to receive callbacks from us 145 sp<ICameraClient> mRemoteCallback; 146 147 }; // class Client 148 149 class ProClient : public BnProCameraUser, public BasicClient { //...}; 150 151 private: 152 153 // Delay-load the Camera HAL module 154 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<IBinder>& remoteCallback, 165 /*out*/ 166 sp<BasicClient> &client); 167 168 // When connection is successful, initialize client and track its death 169 status_t connectFinishUnsafe(const sp<BasicClient>& client, 170 const sp<IBinder>& remoteCallback); 171 172 virtual sp<BasicClient> getClientByRemote(const wp<IBinder>& cameraClient); 173 174 //.... 175 176 camera_module_t *mModule; 177 //... 178 179 };
这个类定义的东西太多了,300多行的东西。其实,简而言之,它分为这几个部分:
(1). 和binder通信有关的东西,比如:
static char const* getServiceName() { return "media.camera"; }
(2). 和client有关的东西:
在CameraService 的内部,定义了一个Client类。当远端Client对server进行调用操作的时候,其最终会把该动作落实到 在CameraService 内部的这个Client 类实例化上来.
1 class Client : public BnCamera, public BasicClient 2 { 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<typename SERVICE> class BinderService { public: static status_t publish(bool allowIsolated = false) { sp<IServiceManager> 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<CameraService>, 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<Camera>, 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<Camera> create(const sp<ICamera>& camera); 12 static sp<Camera> 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>& 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<IGraphicBufferProducer>& 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<IMemory>& 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<CameraListener>& listener); 72 void setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& 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<IGraphicBufferProducer>& callbackProducer); 82 83 sp<ICameraRecordingProxy> 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<IMemory>& dataPtr, 88 camera_frame_metadata_t *metadata); 89 virtual void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr); 90 91 class RecordingProxy : public BnCameraRecordingProxy 92 { 93 public: 94 RecordingProxy(const sp<Camera>& camera); 95 96 // ICameraRecordingProxy interface 97 virtual status_t startRecording(const sp<ICameraRecordingProxyListener>& listener); 98 virtual void stopRecording(); 99 virtual void releaseRecordingFrame(const sp<IMemory>& mem); 100 101 private: 102 sp<Camera> mCamera; 103 }; 104 105 protected: 106 Camera(int cameraId); 107 Camera(const Camera&); 108 Camera& operator=(const Camera); 109 110 sp<ICameraRecordingProxyListener> 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<Camera>(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> 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<JNICameraContext> 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 field 20 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> 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 <typename TCam, typename TCamTraits> 2 sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId, 3 const String16& clientPackageName, 4 int clientUid) 5 { 6 sp<TCam> c = new TCam(cameraId); 7 8 //通过SM获取CameraService在本地的一个引用。调用connect函数后最终调用CameraService侧的connect()函数 9 const sp<ICameraService>& 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 <typename TCam, typename TCamTraits = CameraTraits<TCam> > 2 class CameraBase : public IBinder::DeathRecipient 3 { 4 //... 5 };
在CameraBase模板定义的时候,可以看到了 typename TCamTraits = CameraTraits<TCam> 简而言之,就是TCamTraits使用默认的CameraTraits<TCam>的来代替就行了。
而CameraTraits<TCam>中的 TCam 再次使用 Camera 来代替,那就形成了这个格式:
1 TCamConnectService fnConnectService = TCamTraits::fnConnectService; => TCamConnectService fnConnectService = CameraTraits<Camera>::fnConnectService;
而 CameraTraits<Camera>::fnConnectService 在 frameworks/av/camera/Camera.cpp 文件中有明确的表示:
1 CameraTraits<Camera>::TCamConnectService CameraTraits<Camera>::fnConnectService = 2 &ICameraService::connect;
于是,这样,就把client端的connect交换到了 ICameraService 的名录下了。而这个ICameraService 与 server是有着远亲继承关系的:
可以回头看下 CameraService 的继承关系:
1 class CameraService : 2 public BinderService<CameraService>, 3 public BnCameraService, 4 public IBinder::DeathRecipient, 5 public camera_module_callbacks_t 6 { 7 //... 8 };
这里有继承 BnCameraService 类,再看下 BnCameraService 的定义:
1 class BnCameraService: public BnInterface<ICameraService> 2 { 3 //... 4 };
再跟下 public BnInterface<ICameraService> 的东西:
1 template<typename INTERFACE> 2 class BnInterface : public INTERFACE, public BBinder 3 { 4 //... 5 };
到了这里,当我们使用 ICameraService 替换掉 INTERFACE 后,一切的远亲关系就明了了。也就无需赘言了。
就这样,最终来到了 CameraService 的connect()成员函数里了。
现在,就把对象从client转换成server吧:
在 frameworks/av/services/camera/libcameraservice/CameraService.cpp 文件中:
1 status_t CameraService::connect( 2 const sp<ICameraClient>& cameraClient, 3 int cameraId, 4 const String16& clientPackageName, 5 int clientUid, 6 /*out*/ 7 sp<ICamera>& device) { 8 9 //... 10 11 sp<Client> 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 back 22 // 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>& client, 4 /*in*/ 5 const sp<ICameraClient>& 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<ICameraClient>& client); 7 virtual status_t lock(); 8 virtual status_t unlock(); 9 virtual status_t setPreviewTarget(const sp<IGraphicBufferProducer>& bufferProducer); 10 virtual void setPreviewCallbackFlag(int flag); 11 virtual status_t setPreviewCallbackTarget( 12 const sp<IGraphicBufferProducer>& 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<IMemory>& 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 CameraService 29 CameraClient(const sp<CameraService>& cameraService, 30 const sp<ICameraClient>& 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<BasicClient>& client, 2 const sp<IBinder>& 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 default 30 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<camera_module_t *>(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<Camera> get_native_camera(JNIEnv *env, jobject thiz, JNICameraContext** pContext) 2 { 3 sp<Camera> camera; 4 Mutex::Autolock _l(sLock); 5 JNICameraContext* context = reinterpret_cast<JNICameraContext*>(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> 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> camera = get_native_camera(env, thiz, NULL); 5 if (camera == 0) return; 6 //... 7 }
等等一系列动作,将依赖那个返回的 CameraClient 对象引用。直到 release 动作的发生。
(over)
2016-01-1