camera_client: refactor Camera/ProCamera commonalities into BasicCamera

Change-Id: Ie10a4094522d49683657665fe94ab0b7ccd280e9
diff --git a/include/camera/Camera.h b/include/camera/Camera.h
index be2b7f4..71c66ce 100644
--- a/include/camera/Camera.h
+++ b/include/camera/Camera.h
@@ -23,35 +23,13 @@
 #include <camera/ICameraClient.h>
 #include <camera/ICameraRecordingProxy.h>
 #include <camera/ICameraRecordingProxyListener.h>
+#include <camera/ICameraService.h>
+#include <camera/ICamera.h>
+#include <camera/CameraBase.h>
 
 namespace android {
 
-struct CameraInfo {
-    /**
-     * The direction that the camera faces to. It should be CAMERA_FACING_BACK
-     * or CAMERA_FACING_FRONT.
-     */
-    int facing;
-
-    /**
-     * The orientation of the camera image. The value is the angle that the
-     * camera image needs to be rotated clockwise so it shows correctly on the
-     * display in its natural orientation. It should be 0, 90, 180, or 270.
-     *
-     * For example, suppose a device has a naturally tall screen. The
-     * back-facing camera sensor is mounted in landscape. You are looking at
-     * the screen. If the top side of the camera sensor is aligned with the
-     * right edge of the screen in natural orientation, the value should be
-     * 90. If the top side of a front-facing camera sensor is aligned with the
-     * right of the screen, the value should be 270.
-     */
-    int orientation;
-};
-
-class ICameraService;
-class ICamera;
 class Surface;
-class Mutex;
 class String8;
 class String16;
 
@@ -65,32 +43,37 @@
     virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) = 0;
 };
 
-class Camera : public BnCameraClient, public IBinder::DeathRecipient
+class Camera;
+
+template <>
+struct CameraTraits<Camera>
+{
+    typedef CameraListener        TCamListener;
+    typedef ICamera               TCamUser;
+    typedef ICameraClient         TCamCallbacks;
+};
+
+class Camera :
+    public CameraBase<Camera>,
+    public BnCameraClient
 {
 public:
     enum {
-        USE_CALLING_UID = -1
+        USE_CALLING_UID = ICameraService::USE_CALLING_UID
     };
 
             // construct a camera client from an existing remote
     static  sp<Camera>  create(const sp<ICamera>& camera);
-    static  int32_t     getNumberOfCameras();
-    static  status_t    getCameraInfo(int cameraId,
-                                      struct CameraInfo* cameraInfo);
     static  sp<Camera>  connect(int cameraId,
                                 const String16& clientPackageName,
                                 int clientUid);
 
             virtual     ~Camera();
-            void        init();
 
             status_t    reconnect();
-            void        disconnect();
             status_t    lock();
             status_t    unlock();
 
-            status_t    getStatus() { return mStatus; }
-
             // pass the buffered Surface to the camera service
             status_t    setPreviewDisplay(const sp<Surface>& surface);
 
@@ -151,8 +134,6 @@
                                      camera_frame_metadata_t *metadata);
     virtual void        dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
 
-    sp<ICamera>         remote();
-
     class RecordingProxy : public BnCameraRecordingProxy
     {
     public:
@@ -168,35 +149,13 @@
     };
 
 protected:
-                        Camera();
+                        Camera(int cameraId);
                         Camera(const Camera&);
                         Camera& operator=(const Camera);
-                        virtual void binderDied(const wp<IBinder>& who);
 
-            class DeathNotifier: public IBinder::DeathRecipient
-            {
-            public:
-                DeathNotifier() {
-                }
+    sp<ICameraRecordingProxyListener>  mRecordingProxyListener;
 
-                virtual void binderDied(const wp<IBinder>& who);
-            };
-
-            static sp<DeathNotifier> mDeathNotifier;
-
-            // helper function to obtain camera service handle
-            static const sp<ICameraService>& getCameraService();
-
-            sp<ICamera>         mCamera;
-            status_t            mStatus;
-
-            sp<CameraListener>  mListener;
-            sp<ICameraRecordingProxyListener>  mRecordingProxyListener;
-
-            friend class DeathNotifier;
-
-            static  Mutex               mLock;
-            static  sp<ICameraService>  mCameraService;
+    friend class        CameraBase;
 };
 
 }; // namespace android
diff --git a/include/camera/CameraBase.h b/include/camera/CameraBase.h
new file mode 100644
index 0000000..fed28ea
--- /dev/null
+++ b/include/camera/CameraBase.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_CAMERA_BASE_H
+#define ANDROID_HARDWARE_CAMERA_BASE_H
+
+#include <utils/Mutex.h>
+#include <camera/ICameraService.h>
+
+struct camera_frame_metadata;
+
+namespace android {
+
+struct CameraInfo {
+    /**
+     * The direction that the camera faces to. It should be CAMERA_FACING_BACK
+     * or CAMERA_FACING_FRONT.
+     */
+    int facing;
+
+    /**
+     * The orientation of the camera image. The value is the angle that the
+     * camera image needs to be rotated clockwise so it shows correctly on the
+     * display in its natural orientation. It should be 0, 90, 180, or 270.
+     *
+     * For example, suppose a device has a naturally tall screen. The
+     * back-facing camera sensor is mounted in landscape. You are looking at
+     * the screen. If the top side of the camera sensor is aligned with the
+     * right edge of the screen in natural orientation, the value should be
+     * 90. If the top side of a front-facing camera sensor is aligned with the
+     * right of the screen, the value should be 270.
+     */
+    int orientation;
+};
+
+template <typename TCam>
+struct CameraTraits {
+};
+
+template <typename TCam, typename TCamTraits = CameraTraits<TCam> >
+class CameraBase : public IBinder::DeathRecipient
+{
+public:
+    typedef typename TCamTraits::TCamListener    TCamListener;
+    typedef typename TCamTraits::TCamUser        TCamUser;
+    typedef typename TCamTraits::TCamCallbacks   TCamCallbacks;
+
+    static sp<TCam>      connect(int cameraId,
+                                 const String16& clientPackageName,
+                                 int clientUid);
+    virtual void         disconnect();
+
+    void                 setListener(const sp<TCamListener>& listener);
+
+    static int           getNumberOfCameras();
+
+    static status_t      getCameraInfo(int cameraId,
+                                       /*out*/
+                                       struct CameraInfo* cameraInfo);
+
+    sp<TCamUser>         remote();
+
+    // Status is set to 'UNKNOWN_ERROR' after successful (re)connection
+    status_t             getStatus();
+
+protected:
+    CameraBase(int cameraId);
+    virtual              ~CameraBase();
+
+    ////////////////////////////////////////////////////////
+    // TCamCallbacks implementation
+    ////////////////////////////////////////////////////////
+    virtual void         notifyCallback(int32_t msgType, int32_t ext,
+                                        int32_t ext2);
+    virtual void         dataCallback(int32_t msgType,
+                                      const sp<IMemory>& dataPtr,
+                                      camera_frame_metadata *metadata);
+    bool                 dataCallbackTimestamp(nsecs_t timestamp,
+                                               int32_t msgType,
+                                               const sp<IMemory>& dataPtr);
+
+    ////////////////////////////////////////////////////////
+    // Common instance variables
+    ////////////////////////////////////////////////////////
+    Mutex                            mLock;
+
+    virtual void                     binderDied(const wp<IBinder>& who);
+
+    // helper function to obtain camera service handle
+    static const sp<ICameraService>& getCameraService();
+
+    sp<TCamUser>                     mCamera;
+    status_t                         mStatus;
+
+    sp<TCamListener>                 mListener;
+
+    const int                        mCameraId;
+
+    typedef CameraBase<TCam>        CameraBaseT;
+};
+
+}; // namespace android
+
+#endif
diff --git a/include/camera/ICameraService.h b/include/camera/ICameraService.h
index aa64243..ef2b685 100644
--- a/include/camera/ICameraService.h
+++ b/include/camera/ICameraService.h
@@ -21,12 +21,13 @@
 #include <binder/IInterface.h>
 #include <binder/Parcel.h>
 
-#include <camera/ICameraClient.h>
-#include <camera/ICamera.h>
-#include <camera/IProCameraUser.h>
-
 namespace android {
 
+class ICamera;
+class ICameraClient;
+class IProCameraUser;
+class IProCameraCallbacks;
+
 class ICameraService : public IInterface
 {
 public:
@@ -58,7 +59,9 @@
             int clientUid) = 0;
 
     virtual sp<IProCameraUser> connect(const sp<IProCameraCallbacks>& cameraCb,
-            int cameraId) = 0;
+            int cameraId,
+            const String16& clientPackageName,
+            int clientUid) = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/camera/ProCamera.h b/include/camera/ProCamera.h
index cd2772c..b228145 100644
--- a/include/camera/ProCamera.h
+++ b/include/camera/ProCamera.h
@@ -27,9 +27,13 @@
 #include <camera/CameraMetadata.h>
 #include <gui/CpuConsumer.h>
 
+#include <gui/Surface.h>
+
 #include <utils/Condition.h>
 #include <utils/Mutex.h>
 
+#include <camera/CameraBase.h>
+
 struct camera_metadata;
 
 namespace android {
@@ -53,6 +57,8 @@
     // OnBufferReceived and OnRequestReceived can come in with any order,
     // use android.sensor.timestamp and LockedBuffer.timestamp to correlate them
 
+    // TODO: remove onBufferReceived
+
     // A new frame buffer has been received for this stream.
     // -- This callback only fires for createStreamCpu streams
     // -- Use buf.timestamp to correlate with metadata's
@@ -67,22 +73,36 @@
       */
     virtual void onResultReceived(int32_t frameId, camera_metadata* result) = 0;
 
+    // TODO: make onFrameAvailable pure virtual
 
     // A new frame buffer has been received for this stream.
     // -- This callback only fires for createStreamCpu streams
     // -- Use buf.timestamp to correlate with metadata's android.sensor.timestamp
     // -- The buffer should be accessed with CpuConsumer::lockNextBuffer
     //      and CpuConsumer::unlockBuffer
-    virtual void onFrameAvailable(int streamId,
-                                  const sp<CpuConsumer>& cpuConsumer) {
+    virtual void onFrameAvailable(int /*streamId*/,
+                                  const sp<CpuConsumer>& /*cpuConsumer*/) {
     }
 
+    // TODO: Remove useOnFrameAvailable
     virtual bool useOnFrameAvailable() {
         return false;
     }
 };
 
-class ProCamera : public BnProCameraCallbacks, public IBinder::DeathRecipient
+class ProCamera;
+
+template <>
+struct CameraTraits<ProCamera>
+{
+    typedef ProCameraListener     TCamListener;
+    typedef IProCameraUser        TCamUser;
+    typedef IProCameraCallbacks   TCamCallbacks;
+};
+
+class ProCamera :
+    public CameraBase<ProCamera>,
+    public BnProCameraCallbacks
 {
 public:
     /**
@@ -91,11 +111,8 @@
      * to be acquired with exclusive[Try]Lock.
      */
     static sp<ProCamera> connect(int cameraId);
-    virtual void disconnect();
     virtual ~ProCamera();
 
-    void setListener(const sp<ProCameraListener>& listener);
-
     /**
      * Exclusive Locks:
      * - We may request exclusive access to a camera if no other
@@ -187,9 +204,6 @@
                                  /*out*/
                                   camera_metadata** request) const;
 
-    // Get number of cameras
-    static int getNumberOfCameras();
-
     // Get static camera metadata
     camera_metadata* getCameraInfo(int cameraId);
 
@@ -222,8 +236,6 @@
     //   BAD_VALUE - invalid streamId or count passed
     int dropFrameBuffer(int streamId, int count);
 
-    sp<IProCameraUser>         remote();
-
 protected:
     ////////////////////////////////////////////////////////
     // IProCameraCallbacks implementation
@@ -241,35 +253,8 @@
 
     virtual void        onResultReceived(int32_t frameId,
                                          camera_metadata* result);
-
-    class DeathNotifier: public IBinder::DeathRecipient
-    {
-    public:
-        DeathNotifier() {
-        }
-
-        virtual void binderDied(const wp<IBinder>& who);
-    };
-
 private:
-    ProCamera();
-
-    virtual void binderDied(const wp<IBinder>& who);
-
-    // helper function to obtain camera service handle
-    static const sp<ICameraService>& getCameraService();
-
-    static sp<DeathNotifier> mDeathNotifier;
-
-    sp<IProCameraUser>  mCamera;
-    status_t            mStatus;
-
-    sp<ProCameraListener>  mListener;
-
-    friend class DeathNotifier;
-
-    static  Mutex               mLock;
-    static  sp<ICameraService>  mCameraService;
+    ProCamera(int cameraId);
 
     class ProFrameListener : public CpuConsumer::FrameAvailableListener {
     public:
@@ -324,7 +309,7 @@
 
     StreamInfo& getStreamInfo(int streamId);
 
-
+    friend class CameraBase;
 };
 
 }; // namespace android