您的位置:首页 > 移动开发 > Android开发

sc7731 Android 5.1 Camera 学习之一Camera 两个对象

2016-04-08 10:12 676 查看
http://www.bubuko.com/infodetail-1323339.html

众所周知,在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 };


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 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

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: