(Camera)FrameProcessor: Refactor to share code with ProFrameProcessor

Change-Id: Ie8cd0df7caf83f9d0134f560ae31ab72f2f7d1fc
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp
index eb7a8d8..eb94d9f 100644
--- a/services/camera/libcameraservice/Camera2Client.cpp
+++ b/services/camera/libcameraservice/Camera2Client.cpp
@@ -115,7 +115,7 @@
 
     mStreamingProcessor = new StreamingProcessor(this);
 
-    mFrameProcessor = new FrameProcessor(this);
+    mFrameProcessor = new FrameProcessor(mDevice, this);
     threadName = String8::format("C2-%d-FrameProc",
             mCameraId);
     mFrameProcessor->run(threadName.string());
diff --git a/services/camera/libcameraservice/Camera2Device.cpp b/services/camera/libcameraservice/Camera2Device.cpp
index 81e58ca..37ba5ae 100644
--- a/services/camera/libcameraservice/Camera2Device.cpp
+++ b/services/camera/libcameraservice/Camera2Device.cpp
@@ -47,6 +47,10 @@
     disconnect();
 }
 
+int Camera2Device::getId() const {
+    return mId;
+}
+
 status_t Camera2Device::initialize(camera_module_t *module)
 {
     ATRACE_CALL();
diff --git a/services/camera/libcameraservice/Camera2Device.h b/services/camera/libcameraservice/Camera2Device.h
index 1adb7a9..3034a1d 100644
--- a/services/camera/libcameraservice/Camera2Device.h
+++ b/services/camera/libcameraservice/Camera2Device.h
@@ -38,6 +38,7 @@
     /**
      * CameraDevice interface
      */
+    virtual int      getId() const;
     virtual status_t initialize(camera_module_t *module);
     virtual status_t disconnect();
     virtual status_t dump(int fd, const Vector<String16>& args);
diff --git a/services/camera/libcameraservice/Camera3Device.cpp b/services/camera/libcameraservice/Camera3Device.cpp
index 2a1be09..04a6e6a 100644
--- a/services/camera/libcameraservice/Camera3Device.cpp
+++ b/services/camera/libcameraservice/Camera3Device.cpp
@@ -50,6 +50,10 @@
     disconnect();
 }
 
+int Camera3Device::getId() const {
+    return mId;
+}
+
 status_t Camera3Device::initialize(camera_module_t *module)
 {
     ATRACE_CALL();
diff --git a/services/camera/libcameraservice/Camera3Device.h b/services/camera/libcameraservice/Camera3Device.h
index 2bc7cf0..df7352c 100644
--- a/services/camera/libcameraservice/Camera3Device.h
+++ b/services/camera/libcameraservice/Camera3Device.h
@@ -57,6 +57,7 @@
     /**
      * CameraDevice interface
      */
+    virtual int      getId() const;
     virtual status_t initialize(camera_module_t *module);
     virtual status_t disconnect();
     virtual status_t dump(int fd, const Vector<String16> &args);
diff --git a/services/camera/libcameraservice/CameraDeviceBase.h b/services/camera/libcameraservice/CameraDeviceBase.h
index 8252af7..8c457d9 100644
--- a/services/camera/libcameraservice/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/CameraDeviceBase.h
@@ -36,6 +36,11 @@
   public:
     virtual ~CameraDeviceBase();
 
+    /**
+     * The device's camera ID
+     */
+    virtual int      getId() const = 0;
+
     virtual status_t initialize(camera_module_t *module) = 0;
     virtual status_t disconnect() = 0;
 
diff --git a/services/camera/libcameraservice/ProCamera2Client.cpp b/services/camera/libcameraservice/ProCamera2Client.cpp
index 4a5a3d5..1270751 100644
--- a/services/camera/libcameraservice/ProCamera2Client.cpp
+++ b/services/camera/libcameraservice/ProCamera2Client.cpp
@@ -27,6 +27,7 @@
 #include "camera2/Parameters.h"
 #include "ProCamera2Client.h"
 #include "camera2/ProFrameProcessor.h"
+#include "CameraDeviceBase.h"
 
 namespace android {
 using namespace camera2;
@@ -61,7 +62,7 @@
     }
 
     String8 threadName;
-    mFrameProcessor = new ProFrameProcessor(this);
+    mFrameProcessor = new ProFrameProcessor(mDevice);
     threadName = String8::format("PC2-%d-FrameProc", mCameraId);
     mFrameProcessor->run(threadName.string());
 
diff --git a/services/camera/libcameraservice/camera2/FrameProcessor.cpp b/services/camera/libcameraservice/camera2/FrameProcessor.cpp
index 09b4b27..d13d398 100644
--- a/services/camera/libcameraservice/camera2/FrameProcessor.cpp
+++ b/services/camera/libcameraservice/camera2/FrameProcessor.cpp
@@ -28,146 +28,37 @@
 namespace android {
 namespace camera2 {
 
-FrameProcessor::FrameProcessor(wp<Camera2Client> client):
-        Thread(false), mClient(client), mLastFrameNumberOfFaces(0) {
+FrameProcessor::FrameProcessor(wp<CameraDeviceBase> device,
+                               wp<Camera2Client> client) :
+    ProFrameProcessor(device),
+    mClient(client),
+    mLastFrameNumberOfFaces(0) {
 }
 
 FrameProcessor::~FrameProcessor() {
-    ALOGV("%s: Exit", __FUNCTION__);
 }
 
-status_t FrameProcessor::registerListener(int32_t minId,
-        int32_t maxId, wp<FilteredListener> listener) {
-    Mutex::Autolock l(mInputMutex);
-    ALOGV("%s: Registering listener for frame id range %d - %d",
-            __FUNCTION__, minId, maxId);
-    RangeListener rListener = { minId, maxId, listener };
-    mRangeListeners.push_back(rListener);
-    return OK;
-}
+bool FrameProcessor::processSingleFrame(CameraMetadata &frame,
+                                        const sp<CameraDeviceBase> &device) {
 
-status_t FrameProcessor::removeListener(int32_t minId,
-        int32_t maxId, wp<FilteredListener> listener) {
-    Mutex::Autolock l(mInputMutex);
-    List<RangeListener>::iterator item = mRangeListeners.begin();
-    while (item != mRangeListeners.end()) {
-        if (item->minId == minId &&
-                item->maxId == maxId &&
-                item->listener == listener) {
-            item = mRangeListeners.erase(item);
-        } else {
-            item++;
-        }
-    }
-    return OK;
-}
-
-void FrameProcessor::dump(int fd, const Vector<String16>& /*args*/) {
-    String8 result("    Latest received frame:\n");
-    write(fd, result.string(), result.size());
-    mLastFrame.dump(fd, 2, 6);
-}
-
-bool FrameProcessor::threadLoop() {
-    status_t res;
-
-    sp<CameraDeviceBase> device;
-    {
-        sp<Camera2Client> client = mClient.promote();
-        if (client == 0) return false;
-        device = client->getCameraDevice();
-        if (device == 0) return false;
+    sp<Camera2Client> client = mClient.promote();
+    if (!client.get()) {
+        return false;
     }
 
-    res = device->waitForNextFrame(kWaitDuration);
-    if (res == OK) {
-        sp<Camera2Client> client = mClient.promote();
-        if (client == 0) return false;
-        processNewFrames(client);
-    } else if (res != TIMED_OUT) {
-        ALOGE("Camera2Client::FrameProcessor: Error waiting for new "
-                "frames: %s (%d)", strerror(-res), res);
+    if (processFaceDetect(frame, client) != OK) {
+        return false;
+    }
+
+    if (!ProFrameProcessor::processSingleFrame(frame, device)) {
+        return false;
     }
 
     return true;
 }
 
-void FrameProcessor::processNewFrames(sp<Camera2Client> &client) {
-    status_t res;
-    ATRACE_CALL();
-    CameraMetadata frame;
-    while ( (res = client->getCameraDevice()->getNextFrame(&frame)) == OK) {
-        camera_metadata_entry_t entry;
-
-        entry = frame.find(ANDROID_REQUEST_FRAME_COUNT);
-        if (entry.count == 0) {
-            ALOGE("%s: Camera %d: Error reading frame number",
-                    __FUNCTION__, client->getCameraId());
-            break;
-        }
-        ATRACE_INT("cam2_frame", entry.data.i32[0]);
-
-        res = processFaceDetect(frame, client);
-        if (res != OK) break;
-
-        res = processListeners(frame, client);
-        if (res != OK) break;
-
-        if (!frame.isEmpty()) {
-            mLastFrame.acquire(frame);
-        }
-    }
-    if (res != NOT_ENOUGH_DATA) {
-        ALOGE("%s: Camera %d: Error getting next frame: %s (%d)",
-                __FUNCTION__, client->getCameraId(), strerror(-res), res);
-        return;
-    }
-
-    return;
-}
-
-status_t FrameProcessor::processListeners(const CameraMetadata &frame,
-        sp<Camera2Client> &client) {
-    ATRACE_CALL();
-    camera_metadata_ro_entry_t entry;
-
-    entry = frame.find(ANDROID_REQUEST_ID);
-    if (entry.count == 0) {
-        ALOGE("%s: Camera %d: Error reading frame id",
-                __FUNCTION__, client->getCameraId());
-        return BAD_VALUE;
-    }
-    int32_t frameId = entry.data.i32[0];
-
-    List<sp<FilteredListener> > listeners;
-    {
-        Mutex::Autolock l(mInputMutex);
-
-        List<RangeListener>::iterator item = mRangeListeners.begin();
-        while (item != mRangeListeners.end()) {
-            if (frameId >= item->minId &&
-                    frameId < item->maxId) {
-                sp<FilteredListener> listener = item->listener.promote();
-                if (listener == 0) {
-                    item = mRangeListeners.erase(item);
-                    continue;
-                } else {
-                    listeners.push_back(listener);
-                }
-            }
-            item++;
-        }
-    }
-    ALOGV("Got %d range listeners out of %d", listeners.size(), mRangeListeners.size());
-    List<sp<FilteredListener> >::iterator item = listeners.begin();
-    for (; item != listeners.end(); item++) {
-        (*item)->onFrameAvailable(frameId, frame);
-    }
-    return OK;
-}
-
 status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame,
-        sp<Camera2Client> &client) {
+        const sp<Camera2Client> &client) {
     status_t res = BAD_VALUE;
     ATRACE_CALL();
     camera_metadata_ro_entry_t entry;
@@ -190,7 +81,9 @@
     Vector<camera_face_t> faces;
     metadata.number_of_faces = 0;
 
-    if (enableFaceDetect && faceDetectMode != ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) {
+    if (enableFaceDetect &&
+        faceDetectMode != ANDROID_STATISTICS_FACE_DETECT_MODE_OFF) {
+
         SharedParameters::Lock l(client->getParameters());
         entry = frame.find(ANDROID_STATISTICS_FACE_RECTANGLES);
         if (entry.count == 0) {
@@ -263,17 +156,17 @@
             if (faceDetectMode == ANDROID_STATISTICS_FACE_DETECT_MODE_FULL) {
                 face.id = faceIds[i];
                 face.left_eye[0] =
-                        l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 0]);
+                    l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 0]);
                 face.left_eye[1] =
-                        l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 1]);
+                    l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 1]);
                 face.right_eye[0] =
-                        l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 2]);
+                    l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 2]);
                 face.right_eye[1] =
-                        l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 3]);
+                    l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 3]);
                 face.mouth[0] =
-                        l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 4]);
+                    l.mParameters.arrayXToNormalized(faceLandmarks[i*6 + 4]);
                 face.mouth[1] =
-                        l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 5]);
+                    l.mParameters.arrayYToNormalized(faceLandmarks[i*6 + 5]);
             } else {
                 face.id = 0;
                 face.left_eye[0] = face.left_eye[1] = -2000;
@@ -293,14 +186,24 @@
 }
 
 void FrameProcessor::callbackFaceDetection(sp<Camera2Client> client,
-                               /*in*/camera_frame_metadata &metadata) {
+                                     const camera_frame_metadata &metadata) {
 
-    /* Filter out repeated 0-face callbacks, but not when the last frame was >0 */
-    if (metadata.number_of_faces != 0 || mLastFrameNumberOfFaces != metadata.number_of_faces) {
-        Camera2Client::SharedCameraCallbacks::Lock l(client->mSharedCameraCallbacks);
+    camera_frame_metadata *metadata_ptr =
+        const_cast<camera_frame_metadata*>(&metadata);
+
+    /**
+     * Filter out repeated 0-face callbacks,
+     * but not when the last frame was >0
+     */
+    if (metadata.number_of_faces != 0 ||
+        mLastFrameNumberOfFaces != metadata.number_of_faces) {
+
+        Camera2Client::SharedCameraCallbacks::Lock
+            l(client->mSharedCameraCallbacks);
         if (l.mRemoteCallback != NULL) {
             l.mRemoteCallback->dataCallback(CAMERA_MSG_PREVIEW_METADATA,
-                    NULL, &metadata);
+                                            NULL,
+                                            metadata_ptr);
         }
     }
 
diff --git a/services/camera/libcameraservice/camera2/FrameProcessor.h b/services/camera/libcameraservice/camera2/FrameProcessor.h
index 66e3cda..27ed8f6 100644
--- a/services/camera/libcameraservice/camera2/FrameProcessor.h
+++ b/services/camera/libcameraservice/camera2/FrameProcessor.h
@@ -22,7 +22,9 @@
 #include <utils/Vector.h>
 #include <utils/KeyedVector.h>
 #include <utils/List.h>
-#include "camera/CameraMetadata.h"
+#include <camera/CameraMetadata.h>
+
+#include "ProFrameProcessor.h"
 
 struct camera_frame_metadata;
 
@@ -35,51 +37,26 @@
 /* Output frame metadata processing thread.  This thread waits for new
  * frames from the device, and analyzes them as necessary.
  */
-class FrameProcessor: public Thread {
+class FrameProcessor : public ProFrameProcessor {
   public:
-    FrameProcessor(wp<Camera2Client> client);
+    FrameProcessor(wp<CameraDeviceBase> device, wp<Camera2Client> client);
     ~FrameProcessor();
 
-    struct FilteredListener: virtual public RefBase {
-        virtual void onFrameAvailable(int32_t frameId,
-                const CameraMetadata &frame) = 0;
-    };
-
-    // Register a listener for a range of IDs [minId, maxId). Multiple listeners
-    // can be listening to the same range
-    status_t registerListener(int32_t minId, int32_t maxId, wp<FilteredListener> listener);
-    status_t removeListener(int32_t minId, int32_t maxId, wp<FilteredListener> listener);
-
-    void dump(int fd, const Vector<String16>& args);
   private:
-    static const nsecs_t kWaitDuration = 10000000; // 10 ms
     wp<Camera2Client> mClient;
+    int mLastFrameNumberOfFaces;
 
-    virtual bool threadLoop();
+    void processNewFrames(const sp<Camera2Client> &client);
 
-    Mutex mInputMutex;
-
-    struct RangeListener {
-        int32_t minId;
-        int32_t maxId;
-        wp<FilteredListener> listener;
-    };
-    List<RangeListener> mRangeListeners;
-
-    void processNewFrames(sp<Camera2Client> &client);
+    virtual bool processSingleFrame(CameraMetadata &frame,
+                                    const sp<CameraDeviceBase> &device);
 
     status_t processFaceDetect(const CameraMetadata &frame,
-            sp<Camera2Client> &client);
-
-    status_t processListeners(const CameraMetadata &frame,
-            sp<Camera2Client> &client);
-
-    CameraMetadata mLastFrame;
-    int mLastFrameNumberOfFaces;
+            const sp<Camera2Client> &client);
 
     // Emit FaceDetection event to java if faces changed
     void callbackFaceDetection(sp<Camera2Client> client,
-                               camera_frame_metadata &metadata);
+                               const camera_frame_metadata &metadata);
 };
 
 
diff --git a/services/camera/libcameraservice/camera2/ProFrameProcessor.cpp b/services/camera/libcameraservice/camera2/ProFrameProcessor.cpp
index 742577a..257a45f 100644
--- a/services/camera/libcameraservice/camera2/ProFrameProcessor.cpp
+++ b/services/camera/libcameraservice/camera2/ProFrameProcessor.cpp
@@ -23,13 +23,13 @@
 
 #include "ProFrameProcessor.h"
 #include "../CameraDeviceBase.h"
-#include "../ProCamera2Client.h"
 
 namespace android {
 namespace camera2 {
 
-ProFrameProcessor::ProFrameProcessor(wp<ProCamera2Client> client):
-        Thread(false), mClient(client) {
+ProFrameProcessor::ProFrameProcessor(wp<CameraDeviceBase> device) :
+    Thread(/*canCallJava*/false),
+    mDevice(device) {
 }
 
 ProFrameProcessor::~ProFrameProcessor() {
@@ -47,7 +47,8 @@
 }
 
 status_t ProFrameProcessor::removeListener(int32_t minId,
-        int32_t maxId, wp<FilteredListener> listener) {
+                                           int32_t maxId,
+                                           wp<FilteredListener> listener) {
     Mutex::Autolock l(mInputMutex);
     List<RangeListener>::iterator item = mRangeListeners.begin();
     while (item != mRangeListeners.end()) {
@@ -73,42 +74,40 @@
 
     sp<CameraDeviceBase> device;
     {
-        sp<ProCamera2Client> client = mClient.promote();
-        if (client == 0) return false;
-        device = client->getCameraDevice();
+        device = mDevice.promote();
         if (device == 0) return false;
     }
 
     res = device->waitForNextFrame(kWaitDuration);
     if (res == OK) {
-        sp<ProCamera2Client> client = mClient.promote();
-        if (client == 0) return false;
-        processNewFrames(client);
+        processNewFrames(device);
     } else if (res != TIMED_OUT) {
-        ALOGE("ProCamera2Client::ProFrameProcessor: Error waiting for new "
+        ALOGE("ProFrameProcessor: Error waiting for new "
                 "frames: %s (%d)", strerror(-res), res);
     }
 
     return true;
 }
 
-void ProFrameProcessor::processNewFrames(sp<ProCamera2Client> &client) {
+void ProFrameProcessor::processNewFrames(const sp<CameraDeviceBase> &device) {
     status_t res;
     ATRACE_CALL();
     CameraMetadata frame;
-    while ( (res = client->getCameraDevice()->getNextFrame(&frame)) == OK) {
+    while ( (res = device->getNextFrame(&frame)) == OK) {
+
         camera_metadata_entry_t entry;
 
         entry = frame.find(ANDROID_REQUEST_FRAME_COUNT);
         if (entry.count == 0) {
             ALOGE("%s: Camera %d: Error reading frame number",
-                    __FUNCTION__, client->getCameraId());
+                    __FUNCTION__, device->getId());
             break;
         }
         ATRACE_INT("cam2_frame", entry.data.i32[0]);
 
-        res = processListeners(frame, client);
-        if (res != OK) break;
+        if (!processSingleFrame(frame, device)) {
+            break;
+        }
 
         if (!frame.isEmpty()) {
             mLastFrame.acquire(frame);
@@ -116,22 +115,27 @@
     }
     if (res != NOT_ENOUGH_DATA) {
         ALOGE("%s: Camera %d: Error getting next frame: %s (%d)",
-                __FUNCTION__, client->getCameraId(), strerror(-res), res);
+                __FUNCTION__, device->getId(), strerror(-res), res);
         return;
     }
 
     return;
 }
 
+bool ProFrameProcessor::processSingleFrame(CameraMetadata &frame,
+                                           const sp<CameraDeviceBase> &device) {
+    return processListeners(frame, device) == OK;
+}
+
 status_t ProFrameProcessor::processListeners(const CameraMetadata &frame,
-        sp<ProCamera2Client> &client) {
+        const sp<CameraDeviceBase> &device) {
     ATRACE_CALL();
     camera_metadata_ro_entry_t entry;
 
     entry = frame.find(ANDROID_REQUEST_ID);
     if (entry.count == 0) {
         ALOGE("%s: Camera %d: Error reading frame id",
-                __FUNCTION__, client->getCameraId());
+                __FUNCTION__, device->getId());
         return BAD_VALUE;
     }
     int32_t frameId = entry.data.i32[0];
diff --git a/services/camera/libcameraservice/camera2/ProFrameProcessor.h b/services/camera/libcameraservice/camera2/ProFrameProcessor.h
index e4094a6..b82942c 100644
--- a/services/camera/libcameraservice/camera2/ProFrameProcessor.h
+++ b/services/camera/libcameraservice/camera2/ProFrameProcessor.h
@@ -24,11 +24,9 @@
 #include <utils/List.h>
 #include <camera/CameraMetadata.h>
 
-struct camera_frame_metadata;
-
 namespace android {
 
-class ProCamera2Client;
+class CameraDeviceBase;
 
 namespace camera2 {
 
@@ -37,23 +35,25 @@
  */
 class ProFrameProcessor: public Thread {
   public:
-    ProFrameProcessor(wp<ProCamera2Client> client);
-    ~ProFrameProcessor();
+    ProFrameProcessor(wp<CameraDeviceBase> device);
+    virtual ~ProFrameProcessor();
 
     struct FilteredListener: virtual public RefBase {
         virtual void onFrameAvailable(int32_t frameId,
-                const CameraMetadata &frame) = 0;
+                                      const CameraMetadata &frame) = 0;
     };
 
     // Register a listener for a range of IDs [minId, maxId). Multiple listeners
     // can be listening to the same range
-    status_t registerListener(int32_t minId, int32_t maxId, wp<FilteredListener> listener);
-    status_t removeListener(int32_t minId, int32_t maxId, wp<FilteredListener> listener);
+    status_t registerListener(int32_t minId, int32_t maxId,
+                              wp<FilteredListener> listener);
+    status_t removeListener(int32_t minId, int32_t maxId,
+                            wp<FilteredListener> listener);
 
     void dump(int fd, const Vector<String16>& args);
-  private:
+  protected:
     static const nsecs_t kWaitDuration = 10000000; // 10 ms
-    wp<ProCamera2Client> mClient;
+    wp<CameraDeviceBase> mDevice;
 
     virtual bool threadLoop();
 
@@ -66,10 +66,13 @@
     };
     List<RangeListener> mRangeListeners;
 
-    void processNewFrames(sp<ProCamera2Client> &client);
+    void processNewFrames(const sp<CameraDeviceBase> &device);
+
+    virtual bool processSingleFrame(CameraMetadata &frame,
+                                    const sp<CameraDeviceBase> &device);
 
     status_t processListeners(const CameraMetadata &frame,
-            sp<ProCamera2Client> &client);
+                              const sp<CameraDeviceBase> &device);
 
     CameraMetadata mLastFrame;
 };