Camera: Combine handling of deferred surface and shared surface

- Refactor the OutputConfiguration to contain isDeferred and isShared
  flag, and not contain NULL surface.
- Unify the handling of deferred surface and shared surface.

Test: Camera CTS, and manual testing of GoogleCamera use cases
Bug: 33777818
Change-Id: I5dd3472f0f2133699b0e9fbdd8ba456956222746
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 1675584..977e7a8 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -1292,7 +1292,7 @@
 status_t Camera3Device::createStream(sp<Surface> consumer,
             uint32_t width, uint32_t height, int format,
             android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
-            int streamSetId, uint32_t consumerUsage) {
+            int streamSetId, bool isShared, uint32_t consumerUsage) {
     ATRACE_CALL();
 
     if (consumer == nullptr) {
@@ -1304,19 +1304,19 @@
     consumers.push_back(consumer);
 
     return createStream(consumers, /*hasDeferredConsumer*/ false, width, height,
-            format, dataSpace, rotation, id, streamSetId, consumerUsage);
+            format, dataSpace, rotation, id, streamSetId, isShared, consumerUsage);
 }
 
 status_t Camera3Device::createStream(const std::vector<sp<Surface>>& consumers,
         bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
         android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
-        int streamSetId, uint32_t consumerUsage) {
+        int streamSetId, bool isShared, uint32_t consumerUsage) {
     ATRACE_CALL();
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
     ALOGV("Camera %s: Creating new stream %d: %d x %d, format %d, dataspace %d rotation %d"
-            " consumer usage 0x%x", mId.string(), mNextStreamId, width, height, format, dataSpace, rotation,
-            consumerUsage);
+            " consumer usage 0x%x, isShared %d", mId.string(), mNextStreamId, width, height, format,
+            dataSpace, rotation, consumerUsage, isShared);
 
     status_t res;
     bool wasActive = false;
@@ -1370,8 +1370,6 @@
         return BAD_VALUE;
     }
 
-    bool streamSharing  = consumers.size() > 1 || (consumers.size()  > 0 && hasDeferredConsumer);
-
     // Use legacy dataspace values for older HALs
     if (mDeviceVersion <= CAMERA_DEVICE_API_VERSION_3_3) {
         dataSpace = mapToLegacyDataspace(dataSpace);
@@ -1403,14 +1401,14 @@
         newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
                 width, height, rawOpaqueBufferSize, format, dataSpace, rotation,
                 mTimestampOffset, streamSetId);
+    } else if (isShared) {
+        newStream = new Camera3SharedOutputStream(mNextStreamId, consumers,
+                width, height, format, consumerUsage, dataSpace, rotation,
+                mTimestampOffset, streamSetId);
     } else if (consumers.size() == 0 && hasDeferredConsumer) {
         newStream = new Camera3OutputStream(mNextStreamId,
                 width, height, format, consumerUsage, dataSpace, rotation,
                 mTimestampOffset, streamSetId);
-    } else if (streamSharing) {
-        newStream = new Camera3SharedOutputStream(mNextStreamId, consumers,
-                hasDeferredConsumer, width, height, format, consumerUsage,
-                dataSpace, rotation, mTimestampOffset, streamSetId);
     } else {
         newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
                 width, height, format, dataSpace, rotation,
@@ -2067,14 +2065,16 @@
     }
 }
 
-status_t Camera3Device::setConsumerSurface(int streamId, sp<Surface> consumer) {
+status_t Camera3Device::setConsumerSurfaces(int streamId,
+        const std::vector<sp<Surface>>& consumers) {
     ATRACE_CALL();
-    ALOGV("%s: Camera %s: set consumer surface for stream %d", __FUNCTION__, mId.string(), streamId);
+    ALOGV("%s: Camera %s: set consumer surface for stream %d",
+            __FUNCTION__, mId.string(), streamId);
     Mutex::Autolock il(mInterfaceLock);
     Mutex::Autolock l(mLock);
 
-    if (consumer == nullptr) {
-        CLOGE("Null consumer is passed!");
+    if (consumers.size() == 0) {
+        CLOGE("No consumer is passed!");
         return BAD_VALUE;
     }
 
@@ -2084,7 +2084,7 @@
         return idx;
     }
     sp<Camera3OutputStreamInterface> stream = mOutputStreams[idx];
-    status_t res = stream->setConsumer(consumer);
+    status_t res = stream->setConsumers(consumers);
     if (res != OK) {
         CLOGE("Stream %d set consumer failed (error %d %s) ", streamId, res, strerror(-res));
         return res;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 9b869a9..91d682e 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -109,18 +109,18 @@
     // Actual stream creation/deletion is delayed until first request is submitted
     // If adding streams while actively capturing, will pause device before adding
     // stream, reconfiguring device, and unpausing. If the client create a stream
-    // with nullptr consumer surface, the client must then call setConsumer()
+    // with nullptr consumer surface, the client must then call setConsumers()
     // and finish the stream configuration before starting output streaming.
     status_t createStream(sp<Surface> consumer,
             uint32_t width, uint32_t height, int format,
             android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
             int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
-            uint32_t consumerUsage = 0) override;
+            bool isShared = false, uint32_t consumerUsage = 0) override;
     status_t createStream(const std::vector<sp<Surface>>& consumers,
             bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
             android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id,
             int streamSetId = camera3::CAMERA3_STREAM_SET_ID_INVALID,
-            uint32_t consumerUsage = 0) override;
+            bool isShared = false, uint32_t consumerUsage = 0) override;
 
     status_t createInputStream(
             uint32_t width, uint32_t height, int format,
@@ -183,10 +183,10 @@
     void             notifyStatus(bool idle); // updates from StatusTracker
 
     /**
-     * Set the deferred consumer surface to the output stream and finish the deferred
+     * Set the deferred consumer surfaces to the output stream and finish the deferred
      * consumer configuration.
      */
-    status_t setConsumerSurface(int streamId, sp<Surface> consumer) override;
+    status_t setConsumerSurfaces(int streamId, const std::vector<sp<Surface>>& consumers) override;
 
   private:
     static const size_t        kDumpLockAttempts  = 10;
diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
index 7f61c7a..1a730d6 100644
--- a/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3DummyStream.cpp
@@ -115,9 +115,9 @@
     return false;
 }
 
-status_t Camera3DummyStream::setConsumer(sp<Surface> consumer) {
-    ALOGE("%s: Stream %d: Dummy stream doesn't support set consumer surface %p!",
-            __FUNCTION__, mId, consumer.get());
+status_t Camera3DummyStream::setConsumers(const std::vector<sp<Surface>>& /*consumers*/) {
+    ALOGE("%s: Stream %d: Dummy stream doesn't support set consumer surface!",
+            __FUNCTION__, mId);
     return INVALID_OPERATION;
 }
 }; // namespace camera3
diff --git a/services/camera/libcameraservice/device3/Camera3DummyStream.h b/services/camera/libcameraservice/device3/Camera3DummyStream.h
index 37efbbb..b6ec99c 100644
--- a/services/camera/libcameraservice/device3/Camera3DummyStream.h
+++ b/services/camera/libcameraservice/device3/Camera3DummyStream.h
@@ -70,9 +70,9 @@
     virtual bool isConsumerConfigurationDeferred(size_t surface_id) const;
 
     /**
-     * Set the consumer surface to the output stream.
+     * Set the consumer surfaces to the output stream.
      */
-    virtual status_t setConsumer(sp<Surface> consumer);
+    virtual status_t setConsumers(const std::vector<sp<Surface>>& consumers);
 
   protected:
 
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 1e76a27..b5883e3 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -710,14 +710,19 @@
     Mutex::Autolock l(mLock);
 
     if (surface_id != 0) {
-        ALOGE("%s: surface_id for Camera3OutputStream should be 0!", __FUNCTION__);
+        ALOGE("%s: surface_id %zu for Camera3OutputStream should be 0!", __FUNCTION__, surface_id);
     }
     return mConsumer == nullptr;
 }
 
-status_t Camera3OutputStream::setConsumer(sp<Surface> consumer) {
-    if (consumer == nullptr) {
-        ALOGE("%s: it's illegal to set a null consumer surface!", __FUNCTION__);
+status_t Camera3OutputStream::setConsumers(const std::vector<sp<Surface>>& consumers) {
+    if (consumers.size() != 1) {
+        ALOGE("%s: it's illegal to set %zu consumer surfaces!",
+                  __FUNCTION__, consumers.size());
+        return INVALID_OPERATION;
+    }
+    if (consumers[0] == nullptr) {
+        ALOGE("%s: it's illegal to set null consumer surface!", __FUNCTION__);
         return INVALID_OPERATION;
     }
 
@@ -726,7 +731,7 @@
         return INVALID_OPERATION;
     }
 
-    mConsumer = consumer;
+    mConsumer = consumers[0];
     return OK;
 }
 
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index 26ea63f..080c721 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -138,9 +138,9 @@
     virtual bool isConsumerConfigurationDeferred(size_t surface_id) const;
 
     /**
-     * Set the consumer surface to the output stream.
+     * Set the consumer surfaces to the output stream.
      */
-    virtual status_t setConsumer(sp<Surface> consumer);
+    virtual status_t setConsumers(const std::vector<sp<Surface>>& consumers);
 
     class BufferReleasedListener : public BnProducerListener {
         public:
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
index 6a911c6..11868e7 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStreamInterface.h
@@ -46,9 +46,9 @@
     virtual bool isConsumerConfigurationDeferred(size_t surface_id = 0) const = 0;
 
     /**
-     * Set the consumer surface to the output stream.
+     * Set the consumer surfaces to the output stream.
      */
-    virtual status_t setConsumer(sp<Surface> consumer) = 0;
+    virtual status_t setConsumers(const std::vector<sp<Surface>>& consumers) = 0;
 
     /**
      * Detach an unused buffer from the stream.
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
index b419e06..0d6a96c 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
@@ -22,7 +22,6 @@
 
 Camera3SharedOutputStream::Camera3SharedOutputStream(int id,
         const std::vector<sp<Surface>>& surfaces,
-        bool hasDeferredSurface,
         uint32_t width, uint32_t height, int format,
         uint32_t consumerUsage, android_dataspace dataSpace,
         camera3_stream_rotation_t rotation,
@@ -30,8 +29,7 @@
         Camera3OutputStream(id, CAMERA3_STREAM_OUTPUT, width, height,
                             format, dataSpace, rotation, consumerUsage,
                             timestampOffset, setId),
-        mSurfaces(surfaces),
-        mDeferred(hasDeferredSurface) {
+        mSurfaces(surfaces) {
 }
 
 Camera3SharedOutputStream::~Camera3SharedOutputStream() {
@@ -70,23 +68,35 @@
 
 bool Camera3SharedOutputStream::isConsumerConfigurationDeferred(size_t surface_id) const {
     Mutex::Autolock l(mLock);
-    return (mDeferred && surface_id >= mSurfaces.size());
+    return (surface_id >= mSurfaces.size());
 }
 
-status_t Camera3SharedOutputStream::setConsumer(sp<Surface> surface) {
-    if (surface == nullptr) {
-        ALOGE("%s: it's illegal to set a null consumer surface!", __FUNCTION__);
+status_t Camera3SharedOutputStream::setConsumers(const std::vector<sp<Surface>>& surfaces) {
+    if (surfaces.size() == 0) {
+        ALOGE("%s: it's illegal to set zero consumer surfaces!", __FUNCTION__);
         return INVALID_OPERATION;
     }
 
-    if (!mDeferred) {
-        ALOGE("%s: Current stream isn't deferred!", __FUNCTION__);
-        return INVALID_OPERATION;
+    status_t ret = OK;
+    for (auto& surface : surfaces) {
+        if (surface == nullptr) {
+            ALOGE("%s: it's illegal to set a null consumer surface!", __FUNCTION__);
+            return INVALID_OPERATION;
+        }
+
+        mSurfaces.push_back(surface);
+
+        // Only call addOutput if the splitter has been connected.
+        if (mStreamSplitter != nullptr) {
+            ret = mStreamSplitter->addOutput(surface, camera3_stream::max_buffers);
+            if (ret != OK) {
+                ALOGE("%s: addOutput failed with error code %d", __FUNCTION__, ret);
+                return ret;
+
+            }
+        }
     }
-
-    mSurfaces.push_back(surface);
-
-    return mStreamSplitter->addOutput(surface, camera3_stream::max_buffers);
+    return ret;
 }
 
 status_t Camera3SharedOutputStream::configureQueueLocked() {
@@ -124,7 +134,7 @@
 
 status_t Camera3SharedOutputStream::getEndpointUsage(uint32_t *usage) const {
 
-    status_t res;
+    status_t res = OK;
     uint32_t u = 0;
 
     if (mConsumer == nullptr) {
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
index 1b37d7c..cc96076 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.h
@@ -33,7 +33,7 @@
      * sharing between multiple streams.
      */
     Camera3SharedOutputStream(int id, const std::vector<sp<Surface>>& surfaces,
-            bool hasDeferredSurface, uint32_t width, uint32_t height, int format,
+            uint32_t width, uint32_t height, int format,
             uint32_t consumerUsage, android_dataspace dataSpace,
             camera3_stream_rotation_t rotation, nsecs_t timestampOffset,
             int setId = CAMERA3_STREAM_SET_ID_INVALID);
@@ -45,7 +45,7 @@
 
     virtual bool isConsumerConfigurationDeferred(size_t surface_id) const;
 
-    virtual status_t setConsumer(sp<Surface> consumer);
+    virtual status_t setConsumers(const std::vector<sp<Surface>>& consumers);
 
 private:
     // Surfaces passed in constructor from app
@@ -68,8 +68,6 @@
 
     virtual status_t getEndpointUsage(uint32_t *usage) const;
 
-    bool mDeferred;
-
 }; // class Camera3SharedOutputStream
 
 } // namespace camera3
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
index b935141..07f9491 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.cpp
@@ -55,14 +55,15 @@
     // Add output surfaces. This has to be before creating internal buffer queue
     // in order to get max consumer side buffers.
     for (size_t i = 0; i < surfaces.size(); i++) {
-        if (surfaces[i] != nullptr) {
-            res = addOutputLocked(surfaces[i], hal_max_buffers,
-                    OutputType::NonDeferred);
-            if (res != OK) {
-                ALOGE("%s: Failed to add output surface: %s(%d)",
-                        __FUNCTION__, strerror(-res), res);
-                return res;
-            }
+        if (surfaces[i] == nullptr) {
+            ALOGE("%s: Fatal: surface is NULL", __FUNCTION__);
+            return BAD_VALUE;
+        }
+        res = addOutputLocked(surfaces[i], hal_max_buffers, OutputType::NonDeferred);
+        if (res != OK) {
+            ALOGE("%s: Failed to add output surface: %s(%d)",
+                    __FUNCTION__, strerror(-res), res);
+            return res;
         }
     }
 
@@ -110,7 +111,7 @@
 }
 
 status_t Camera3StreamSplitter::addOutput(
-        sp<Surface>& outputQueue, size_t hal_max_buffers) {
+        const sp<Surface>& outputQueue, size_t hal_max_buffers) {
     Mutex::Autolock lock(mMutex);
     return addOutputLocked(outputQueue, hal_max_buffers, OutputType::Deferred);
 }
diff --git a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
index 5a25712..32ae073 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamSplitter.h
@@ -61,7 +61,7 @@
     // outputQueue has not been added to the splitter. BAD_VALUE is returned if
     // outputQueue is NULL. See IGraphicBufferProducer::connect for explanations
     // of other error codes.
-    status_t addOutput(sp<Surface>& outputQueue, size_t hal_max_buffers);
+    status_t addOutput(const sp<Surface>& outputQueue, size_t hal_max_buffers);
 
     // Request surfaces for a particular frame number. The requested surfaces
     // are stored in a FIFO queue. And when the buffer becomes available from the