眾所周知,在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<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