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


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

  • 相关阅读:
    python两个装饰器的运算顺序
    python中私有属性的访问
    python中的方法使用
    创业,宁愿单兵作战也不要参在拙劣的团队里继续寻觅队友
    项目经理问:为什么总是只有我在加班 – 挂包袱现象
    我该怎么安排下属的工作-项目经理如何分配任务
    项目经理自己要写代码吗?
    管理系统书籍《从程序员到项目经理》 从程序员到项目经理(一)
    宗宁:赚快钱的那些坑。。(转载)
    java 实现二分法
  • 原文地址:https://www.cnblogs.com/chineseboy/p/5142954.html
Copyright © 2020-2023  润新知