Camera3: Add shutter notification

Mandatory now due to fragmented process_capture_result calls.

Bug: 8565103
Change-Id: I4e815e99a5220cc61650157894869189ceaf883d
diff --git a/camera/EmulatedFakeCamera3.cpp b/camera/EmulatedFakeCamera3.cpp
index 87a0a3c..d4c51e4 100644
--- a/camera/EmulatedFakeCamera3.cpp
+++ b/camera/EmulatedFakeCamera3.cpp
@@ -120,7 +120,7 @@
         struct hw_module_t* module) :
         EmulatedCamera3(cameraId, module),
         mFacingBack(facingBack) {
-    ALOGD("Constructing emulated fake camera 3 facing %s",
+    ALOGI("Constructing emulated fake camera 3 facing %s",
             facingBack ? "back" : "front");
 
     for (size_t i = 0; i < CAMERA3_TEMPLATE_COUNT; i++) {
@@ -166,6 +166,7 @@
     }
 
     mSensor = new Sensor();
+    mSensor->setSensorListener(this);
 
     res = mSensor->startUp();
     if (res != NO_ERROR) return res;
@@ -906,6 +907,7 @@
     mSensor->setFrameDuration(frameDuration);
     mSensor->setSensitivity(sensitivity);
     mSensor->setDestinationBuffers(sensorBuffers);
+    mSensor->setFrameNumber(request->frame_number);
 
     ReadoutThread::Request r;
     r.frameNumber = request->frame_number;
@@ -914,6 +916,7 @@
     r.buffers = buffers;
 
     mReadoutThread->queueCaptureRequest(r);
+    ALOGVV("%s: Queued frame %d", __FUNCTION__, request->frame_number);
 
     // Cache the settings for next time
     mPrevSettings.acquire(settings);
@@ -1730,6 +1733,27 @@
     }
 }
 
+void EmulatedFakeCamera3::onSensorEvent(uint32_t frameNumber, Event e,
+        nsecs_t timestamp) {
+    switch(e) {
+        case Sensor::SensorListener::EXPOSURE_START: {
+            ALOGVV("%s: Frame %d: Sensor started exposure at %lld",
+                    __FUNCTION__, frameNumber, timestamp);
+            // Trigger shutter notify to framework
+            camera3_notify_msg_t msg;
+            msg.type = CAMERA3_MSG_SHUTTER;
+            msg.message.shutter.frame_number = frameNumber;
+            msg.message.shutter.timestamp = timestamp;
+            sendNotify(&msg);
+            break;
+        }
+        default:
+            ALOGW("%s: Unexpected sensor event %d at %lld", __FUNCTION__,
+                    e, timestamp);
+            break;
+    }
+}
+
 EmulatedFakeCamera3::ReadoutThread::ReadoutThread(EmulatedFakeCamera3 *parent) :
         mParent(parent) {
 }
@@ -1799,6 +1823,8 @@
         mInFlightQueue.erase(mInFlightQueue.begin());
         mInFlightSignal.signal();
         mThreadActive = true;
+        ALOGVV("Beginning readout of frame %d", __FUNCTION__,
+                mCurrentRequest.frameNumber);
     }
 
     // Then wait for it to be delivered from the sensor
@@ -1808,6 +1834,8 @@
             mParent->mSensor->waitForNewFrame(kWaitPerLoop, &captureTime);
     if (!gotFrame) return true;
 
+    ALOGVV("Sensor done with readout for frame %d, captured at %lld ",
+            mCurrentRequest.frameNumber, captureTime);
     // Check if we need to JPEG encode a buffer
 
     for (size_t i = 0; i < mCurrentRequest.buffers->size(); i++) {
diff --git a/camera/EmulatedFakeCamera3.h b/camera/EmulatedFakeCamera3.h
index dd9e6a1..d65e6a0 100644
--- a/camera/EmulatedFakeCamera3.h
+++ b/camera/EmulatedFakeCamera3.h
@@ -42,7 +42,8 @@
  * connectDevice(), and closeCamera() methods of this class that are invoked in
  * response to hw_module_methods_t::open, and camera_device::close callbacks.
  */
-class EmulatedFakeCamera3 : public EmulatedCamera3 {
+class EmulatedFakeCamera3 : public EmulatedCamera3,
+        private Sensor::SensorListener {
 public:
 
     EmulatedFakeCamera3(int cameraId, bool facingBack,
@@ -118,6 +119,9 @@
     /** Signal from readout thread that it doesn't have anything to do */
     void     signalReadoutIdle();
 
+    /** Handle interrupt events from the sensor */
+    void     onSensorEvent(uint32_t frameNumber, Event e, nsecs_t timestamp);
+
     /****************************************************************************
      * Static configuration information
      ***************************************************************************/
diff --git a/camera/fake-pipeline2/Sensor.cpp b/camera/fake-pipeline2/Sensor.cpp
index 0c12f6f..3f9f318 100644
--- a/camera/fake-pipeline2/Sensor.cpp
+++ b/camera/fake-pipeline2/Sensor.cpp
@@ -107,7 +107,9 @@
         mFrameDuration(kFrameDurationRange[0]),
         mGainFactor(kDefaultSensitivity),
         mNextBuffers(NULL),
+        mFrameNumber(0),
         mCapturedBuffers(NULL),
+        mListener(NULL),
         mScene(kResolution[0], kResolution[1], kElectronsPerLuxSecond)
 {
 
@@ -169,6 +171,11 @@
     mNextBuffers = buffers;
 }
 
+void Sensor::setFrameNumber(uint32_t frameNumber) {
+    Mutex::Autolock lock(mControlMutex);
+    mFrameNumber = frameNumber;
+}
+
 bool Sensor::waitForVSync(nsecs_t reltime) {
     int res;
     Mutex::Autolock lock(mControlMutex);
@@ -204,6 +211,14 @@
     return true;
 }
 
+Sensor::SensorListener::~SensorListener() {
+}
+
+void Sensor::setSensorListener(SensorListener *listener) {
+    Mutex::Autolock lock(mControlMutex);
+    mListener = listener;
+}
+
 status_t Sensor::readyToRun() {
     ALOGV("Starting up sensor thread");
     mStartupTime = systemTime();
@@ -227,12 +242,16 @@
     uint64_t frameDuration;
     uint32_t gain;
     Buffers *nextBuffers;
+    uint32_t frameNumber;
+    SensorListener *listener = NULL;
     {
         Mutex::Autolock lock(mControlMutex);
         exposureDuration = mExposureTime;
         frameDuration    = mFrameDuration;
         gain             = mGainFactor;
         nextBuffers      = mNextBuffers;
+        frameNumber      = mFrameNumber;
+        listener         = mListener;
         // Don't reuse a buffer set
         mNextBuffers = NULL;
 
@@ -284,11 +303,14 @@
     /**
      * Stage 2: Capture new image
      */
-
     mNextCaptureTime = simulatedTime;
     mNextCapturedBuffers = nextBuffers;
 
     if (mNextCapturedBuffers != NULL) {
+        if (listener != NULL) {
+            listener->onSensorEvent(frameNumber, SensorListener::EXPOSURE_START,
+                    mNextCaptureTime);
+        }
         ALOGVV("Starting next capture: Exposure: %f ms, gain: %d",
                 (float)exposureDuration/1e6, gain);
         mScene.setExposureDuration((float)exposureDuration/1e9);
diff --git a/camera/fake-pipeline2/Sensor.h b/camera/fake-pipeline2/Sensor.h
index 72128c5..8e2ffe8 100644
--- a/camera/fake-pipeline2/Sensor.h
+++ b/camera/fake-pipeline2/Sensor.h
@@ -111,6 +111,8 @@
     void setSensitivity(uint32_t gain);
     // Buffer must be at least stride*height*2 bytes in size
     void setDestinationBuffers(Buffers *buffers);
+    // To simplify tracking sensor's current frame
+    void setFrameNumber(uint32_t frameNumber);
 
     /*
      * Controls that cause reconfiguration delay
@@ -134,6 +136,22 @@
     bool waitForNewFrame(nsecs_t reltime,
             nsecs_t *captureTime);
 
+    /*
+     * Interrupt event servicing from the sensor. Only triggers for sensor
+     * cycles that have valid buffers to write to.
+     */
+    struct SensorListener {
+        enum Event {
+            EXPOSURE_START, // Start of exposure
+        };
+
+        virtual void onSensorEvent(uint32_t frameNumber, Event e,
+                nsecs_t timestamp) = 0;
+        virtual ~SensorListener();
+    };
+
+    void setSensorListener(SensorListener *listener);
+
     /**
      * Static sensor characteristics
      */
@@ -180,6 +198,7 @@
     uint64_t  mFrameDuration;
     uint32_t  mGainFactor;
     Buffers  *mNextBuffers;
+    uint32_t  mFrameNumber;
 
     // End of control parameters
 
@@ -189,6 +208,7 @@
     Condition mReadoutComplete;
     Buffers  *mCapturedBuffers;
     nsecs_t   mCaptureTime;
+    SensorListener *mListener;
     // End of readout variables
 
     // Time of sensor startup, used for simulation zero-time point