Correctly process streams

The reference implementation stream validation/setting
was all out of whack, particularly the handling of "reuse"
streams. This CL does away with that, and plugs in the
static_properties/request_tracker validation/tracking of
configured streams.

Implementation specific features, such as gralloc flags,
are moved down into the V4L2Camera class out of the Camera class.

BUG: https://b/33057320, https://b/31044638
TEST: unit tests pass, some previously failing CTS tests are passing
(and no regressions), simple test camera preview app runs.

Change-Id: Ie8568239a1348dac45bf829ef928e500e01fdcda
diff --git a/modules/camera/3_4/Android.mk b/modules/camera/3_4/Android.mk
index 8e3c85a..592aa2f 100644
--- a/modules/camera/3_4/Android.mk
+++ b/modules/camera/3_4/Android.mk
@@ -46,7 +46,6 @@
   metadata/metadata_reader.cpp \
   request_tracker.cpp \
   static_properties.cpp \
-  stream.cpp \
   stream_format.cpp \
   v4l2_camera.cpp \
   v4l2_camera_hal.cpp \
diff --git a/modules/camera/3_4/camera.cpp b/modules/camera/3_4/camera.cpp
index 5a89e3e..30035bd 100644
--- a/modules/camera/3_4/camera.cpp
+++ b/modules/camera/3_4/camera.cpp
@@ -27,7 +27,6 @@
 #include <utils/Mutex.h>
 
 #include "metadata/metadata_common.h"
-#include "stream.h"
 
 //#define LOG_NDEBUG 0
 #define LOG_TAG "Camera"
@@ -57,8 +56,6 @@
     mSettingsSet(false),
     mBusy(false),
     mCallbackOps(NULL),
-    mStreams(NULL),
-    mNumStreams(0),
     mInFlightTracker(new RequestTracker)
 {
     memset(&mTemplates, 0, sizeof(mTemplates));
@@ -175,176 +172,86 @@
 
 int Camera::configureStreams(camera3_stream_configuration_t *stream_config)
 {
-    camera3_stream_t *astream;
-    Stream **newStreams = NULL;
-    int res = 0;
-
-    // Must provide new settings after configureStreams.
-    mSettingsSet = false;
+    android::Mutex::Autolock al(mDeviceLock);
 
     ALOGV("%s:%d: stream_config=%p", __func__, mId, stream_config);
     ATRACE_CALL();
-    android::Mutex::Autolock al(mDeviceLock);
 
-    if (stream_config == NULL) {
-        ALOGE("%s:%d: NULL stream configuration array", __func__, mId);
-        return -EINVAL;
-    }
-    if (stream_config->num_streams == 0) {
-        ALOGE("%s:%d: Empty stream configuration array", __func__, mId);
+    // Check that there are no in-flight requests.
+    if (!mInFlightTracker->Empty()) {
+        ALOGE("%s:%d: Can't configure streams while frames are in flight.",
+              __func__, mId);
         return -EINVAL;
     }
 
-    // Create new stream array
-    newStreams = new Stream*[stream_config->num_streams];
-    ALOGV("%s:%d: Number of Streams: %d", __func__, mId,
-            stream_config->num_streams);
-
-    // Mark all current streams unused for now
-    for (int i = 0; i < mNumStreams; i++)
-        mStreams[i]->mReuse = false;
-    // Fill new stream array with reused streams and new streams
-    for (unsigned int i = 0; i < stream_config->num_streams; i++) {
-        astream = stream_config->streams[i];
-        if (astream->max_buffers > 0) {
-            ALOGV("%s:%d: Reusing stream %d", __func__, mId, i);
-            newStreams[i] = reuseStream(astream);
-        } else {
-            ALOGV("%s:%d: Creating new stream %d", __func__, mId, i);
-            newStreams[i] = new Stream(mId, astream);
-        }
-
-        if (newStreams[i] == NULL) {
-            ALOGE("%s:%d: Error processing stream %d", __func__, mId, i);
-            goto err_out;
-        }
-        astream->priv = newStreams[i];
-    }
-
-    // Verify the set of streams in aggregate
-    if (!isValidStreamSet(newStreams, stream_config->num_streams,
-                          stream_config->operation_mode)) {
-        ALOGE("%s:%d: Invalid stream set", __func__, mId);
-        goto err_out;
-    }
-
-    // Set up all streams (calculate usage/max_buffers for each,
-    // do any device-specific initialization)
-    res = setupStreams(newStreams, stream_config->num_streams);
+    // Verify the set of streams in aggregate, and perform configuration if valid.
+    int res = validateStreamConfiguration(stream_config);
     if (res) {
-        ALOGE("%s:%d: Failed to setup stream set", __func__, mId);
-        goto err_out;
+        ALOGE("%s:%d: Failed to validate stream set", __func__, mId);
+    } else {
+        // Set up all streams. Since they've been validated,
+        // this should only result in fatal (-ENODEV) errors.
+        // This occurs after validation to ensure that if there
+        // is a non-fatal error, the stream configuration doesn't change states.
+        res = setupStreams(stream_config);
+        if (res) {
+            ALOGE("%s:%d: Failed to setup stream set", __func__, mId);
+        }
     }
 
-    // Destroy all old streams and replace stream array with new one
-    destroyStreams(mStreams, mNumStreams);
-    mStreams = newStreams;
-    mNumStreams = stream_config->num_streams;
-
-    // Update the request tracker.
-    mInFlightTracker->SetStreamConfiguration(*stream_config);
-
-    return 0;
-
-err_out:
-    // Clean up temporary streams, preserve existing mStreams/mNumStreams
-    destroyStreams(newStreams, stream_config->num_streams);
-    // Set error if it wasn't specified.
+    // Set trackers based on result.
     if (!res) {
-        res = -EINVAL;
+        // Success, set up the in-flight trackers for the new streams.
+        mInFlightTracker->SetStreamConfiguration(*stream_config);
+        // Must provide new settings for the new configuration.
+        mSettingsSet = false;
     } else if (res != -EINVAL) {
-        // Fatal error, clear stream configuration.
+        // Fatal error, the old configuration is invalid.
         mInFlightTracker->ClearStreamConfiguration();
     }
+    // On a non-fatal error the old configuration, if any, remains valid.
     return res;
 }
 
-void Camera::destroyStreams(Stream **streams, int count)
+int Camera::validateStreamConfiguration(
+    const camera3_stream_configuration_t* stream_config)
 {
-    if (streams == NULL)
-        return;
-    for (int i = 0; i < count; i++) {
-        // Only destroy streams that weren't reused
-        if (streams[i] != NULL && !streams[i]->mReuse)
-            delete streams[i];
-    }
-    delete [] streams;
-}
-
-Stream *Camera::reuseStream(camera3_stream_t *astream)
-{
-    Stream *priv = reinterpret_cast<Stream*>(astream->priv);
-    // Verify the re-used stream's parameters match
-    if (!priv->isValidReuseStream(mId, astream)) {
-        ALOGE("%s:%d: Mismatched parameter in reused stream", __func__, mId);
-        return NULL;
-    }
-    // Mark stream to be reused
-    priv->mReuse = true;
-    return priv;
-}
-
-bool Camera::isValidStreamSet(Stream **streams, int count, uint32_t mode)
-{
-    int inputs = 0;
-    int outputs = 0;
-
-    if (streams == NULL) {
+    // Check that the configuration is well-formed.
+    if (stream_config == nullptr) {
+        ALOGE("%s:%d: NULL stream configuration array", __func__, mId);
+        return -EINVAL;
+    } else if (stream_config->num_streams == 0) {
+        ALOGE("%s:%d: Empty stream configuration array", __func__, mId);
+        return -EINVAL;
+    } else if (stream_config->streams == nullptr) {
         ALOGE("%s:%d: NULL stream configuration streams", __func__, mId);
-        return false;
-    }
-    if (count == 0) {
-        ALOGE("%s:%d: Zero count stream configuration streams", __func__, mId);
-        return false;
-    }
-    // Validate there is at most one input stream and at least one output stream
-    for (int i = 0; i < count; i++) {
-        // A stream may be both input and output (bidirectional)
-        if (streams[i]->isInputType())
-            inputs++;
-        if (streams[i]->isOutputType())
-            outputs++;
-    }
-    ALOGV("%s:%d: Configuring %d output streams and %d input streams",
-            __func__, mId, outputs, inputs);
-    if (outputs < 1) {
-        ALOGE("%s:%d: Stream config must have >= 1 output", __func__, mId);
-        return false;
-    }
-    if (inputs > 1) {
-        ALOGE("%s:%d: Stream config must have <= 1 input", __func__, mId);
-        return false;
+        return -EINVAL;
     }
 
-    // check for correct number of Bayer/YUV/JPEG/Encoder streams
-    return isSupportedStreamSet(streams, count, mode);
-}
-
-int Camera::setupStreams(Stream **streams, int count)
-{
-    /*
-     * This is where the HAL has to decide internally how to handle all of the
-     * streams, and then produce usage and max_buffer values for each stream.
-     * Note, the stream array has been checked before this point for ALL invalid
-     * conditions, so it must find a successful configuration for this stream
-     * array. The only errors should be from individual streams requesting
-     * unsupported features (such as data_space or rotation).
-     */
-    for (int i = 0; i < count; i++) {
-        uint32_t usage = 0;
-        if (streams[i]->isOutputType())
-            usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
-        if (streams[i]->isInputType())
-            usage |= GRALLOC_USAGE_SW_READ_OFTEN;
-        streams[i]->setUsage(usage);
-
-        uint32_t max_buffers;
-        int res = setupStream(streams[i], &max_buffers);
+    // Check that the configuration is supported.
+    // Make sure static info has been initialized before trying to use it.
+    if (!mStaticInfo) {
+        int res = loadStaticInfo();
         if (res) {
-          return res;
+            return res;
         }
-        streams[i]->setMaxBuffers(max_buffers);
     }
+    if (!mStaticInfo->StreamConfigurationSupported(stream_config)) {
+        ALOGE("%s:%d: Stream configuration does not match static "
+              "metadata restrictions.", __func__, mId);
+        return -EINVAL;
+    }
+
+    // Dataspace support is poorly documented - unclear if the expectation
+    // is that a device supports ALL dataspaces that could match a given
+    // format. For now, defer to child class implementation.
+    // Rotation support isn't described by metadata, so must defer to device.
+    if (!validateDataspacesAndRotations(stream_config)) {
+        ALOGE("%s:%d: Device can not handle configuration "
+              "dataspaces or rotations.", __func__, mId);
+        return -EINVAL;
+    }
+
     return 0;
 }
 
@@ -409,6 +316,12 @@
 
     ALOGV("%s:%d: frame: %d", __func__, mId, request->frame_number);
 
+    if (!mInFlightTracker->CanAddRequest(*request)) {
+        // Streams are full or frame number is not unique.
+        ALOGE("%s:%d: Can not add request.", __func__, mId);
+        return -EINVAL;
+    }
+
     // Null/Empty indicates use last settings
     if (request->settings.isEmpty() && !mSettingsSet) {
         ALOGE("%s:%d: NULL settings without previous set Frame:%d",
@@ -423,14 +336,10 @@
         ALOGV("%s:%d: Capturing new frame.", __func__, mId);
     }
 
-    if (!isValidRequest(*request)) {
-        ALOGE("%s:%d: Invalid request.", __func__, mId);
+    if (!isValidRequestSettings(request->settings)) {
+        ALOGE("%s:%d: Invalid request settings.", __func__, mId);
         return -EINVAL;
     }
-    // Valid settings have been provided (mSettingsSet is a misnomer;
-    // all that matters is that a previous request with valid settings
-    // has been passed to the device, not that they've been set).
-    mSettingsSet = true;
 
     // Pre-process output buffers.
     if (request->output_buffers.size() <= 0) {
@@ -451,6 +360,11 @@
         return -ENODEV;
     }
 
+    // Valid settings have been provided (mSettingsSet is a misnomer;
+    // all that matters is that a previous request with valid settings
+    // has been passed to the device, not that they've been set).
+    mSettingsSet = true;
+
     // Send the request off to the device for completion.
     enqueueRequest(request);
 
@@ -603,12 +517,6 @@
     dprintf(fd, "Camera ID: %d (Busy: %d)\n", mId, mBusy);
 
     // TODO: dump all settings
-
-    dprintf(fd, "Number of streams: %d\n", mNumStreams);
-    for (int i = 0; i < mNumStreams; i++) {
-        dprintf(fd, "Stream %d/%d:\n", i, mNumStreams);
-        mStreams[i]->dump(fd);
-    }
 }
 
 const char* Camera::templateToString(int type)
diff --git a/modules/camera/3_4/camera.h b/modules/camera/3_4/camera.h
index 2685fd1..687c733 100644
--- a/modules/camera/3_4/camera.h
+++ b/modules/camera/3_4/camera.h
@@ -28,7 +28,6 @@
 #include "metadata/metadata.h"
 #include "request_tracker.h"
 #include "static_properties.h"
-#include "stream.h"
 
 namespace default_camera_hal {
 // Camera represents a physical camera on a device.
@@ -70,16 +69,17 @@
         // Initialize device info: resource cost and conflicting devices
         // (/conflicting devices length)
         virtual void initDeviceInfo(struct camera_info *info) = 0;
-        // Verify stream configuration is device-compatible
-        virtual bool isSupportedStreamSet(Stream** streams, int count,
-                                          uint32_t mode) = 0;
-        // Set up the device for a stream, and get the maximum number of
-        // buffers that stream can handle (max_buffers is an output parameter)
-        virtual int setupStream(Stream* stream, uint32_t* max_buffers) = 0;
-        // Verify settings are valid for a capture or reprocessing
-        virtual bool isValidRequest(const CaptureRequest& request) = 0;
         // Separate initialization method for individual devices when opened
         virtual int initDevice() = 0;
+        // Verify stream configuration dataspaces and rotation values
+        virtual bool validateDataspacesAndRotations(
+            const camera3_stream_configuration_t* stream_config) = 0;
+        // Set up the streams, including seting usage & max_buffers
+        virtual int setupStreams(
+            camera3_stream_configuration_t* stream_config) = 0;
+        // Verify settings are valid for a capture or reprocessing
+        virtual bool isValidRequestSettings(
+            const android::CameraMetadata& settings) = 0;
         // Enqueue a request to receive data from the camera
         virtual int enqueueRequest(
             std::shared_ptr<CaptureRequest> request) = 0;
@@ -100,14 +100,9 @@
         camera3_device_t mDevice;
         // Get static info from the device and store it in mStaticInfo.
         int loadStaticInfo();
-        // Reuse a stream already created by this device
-        Stream *reuseStream(camera3_stream_t *astream);
-        // Destroy all streams in a stream array, and the array itself
-        void destroyStreams(Stream **array, int count);
-        // Verify a set of streams is valid in aggregate
-        bool isValidStreamSet(Stream **array, int count, uint32_t mode);
-        // Calculate usage and max_bufs of each stream
-        int setupStreams(Stream **array, int count);
+        // Confirm that a stream configuration is valid.
+        int validateStreamConfiguration(
+            const camera3_stream_configuration_t* stream_config);
         // Verify settings are valid for reprocessing an input buffer
         bool isValidReprocessSettings(const camera_metadata_t *settings);
         // Pre-process an output buffer
@@ -140,10 +135,6 @@
         // be accessed without the camera device open
         android::Mutex mStaticInfoLock;
         android::Mutex mFlushLock;
-        // Array of handles to streams currently in use by the device
-        Stream **mStreams;
-        // Number of streams in mStreams
-        int mNumStreams;
         // Standard camera settings templates
         std::unique_ptr<const android::CameraMetadata> mTemplates[CAMERA3_TEMPLATE_COUNT];
         // Track in flight requests.
diff --git a/modules/camera/3_4/static_properties.cpp b/modules/camera/3_4/static_properties.cpp
index b075e6e..5be9dcd 100644
--- a/modules/camera/3_4/static_properties.cpp
+++ b/modules/camera/3_4/static_properties.cpp
@@ -294,8 +294,8 @@
 bool StaticProperties::InputStreamsSupported(
     const camera3_stream_configuration_t* stream_config) {
   // Find the input stream(s).
-  size_t num_input_streams;
-  int input_format;
+  size_t num_input_streams = 0;
+  int input_format = -1;
   for (size_t i = 0; i < stream_config->num_streams; ++i) {
     const camera3_stream_t* stream = stream_config->streams[i];
     if (IsInputType(stream->stream_type)) {
diff --git a/modules/camera/3_4/stream.cpp b/modules/camera/3_4/stream.cpp
deleted file mode 100644
index 97d8634..0000000
--- a/modules/camera/3_4/stream.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-// Modified from hardware/libhardware/modules/camera/Stream.cpp
-
-#include <stdio.h>
-#include <hardware/camera3.h>
-#include <hardware/gralloc.h>
-#include <system/graphics.h>
-#include <utils/Mutex.h>
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "Stream"
-#include <cutils/log.h>
-
-#define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
-#include <utils/Trace.h>
-
-#include "stream.h"
-
-namespace default_camera_hal {
-
-Stream::Stream(int id, camera3_stream_t *s)
-  : mReuse(false),
-    mId(id),
-    mStream(s),
-    mType(s->stream_type),
-    mWidth(s->width),
-    mHeight(s->height),
-    mFormat(s->format),
-    mUsage(0),
-    mRotation(s->rotation),
-    mDataSpace(s->data_space),
-    mMaxBuffers(0)
-{
-}
-
-Stream::~Stream()
-{
-}
-
-void Stream::setUsage(uint32_t usage)
-{
-    android::Mutex::Autolock al(mLock);
-    if (usage != mUsage) {
-        mUsage = usage;
-        mStream->usage = usage;
-    }
-}
-
-void Stream::setMaxBuffers(uint32_t max_buffers)
-{
-    android::Mutex::Autolock al(mLock);
-    if (max_buffers != mMaxBuffers) {
-        mMaxBuffers = max_buffers;
-        mStream->max_buffers = max_buffers;
-    }
-}
-
-void Stream::setDataSpace(android_dataspace_t data_space)
-{
-    android::Mutex::Autolock al(mLock);
-    if (data_space != mDataSpace) {
-        mDataSpace = data_space;
-        mStream->data_space = data_space;
-    }
-}
-
-bool Stream::isInputType() const
-{
-    return mType == CAMERA3_STREAM_INPUT ||
-        mType == CAMERA3_STREAM_BIDIRECTIONAL;
-}
-
-bool Stream::isOutputType() const
-{
-    return mType == CAMERA3_STREAM_OUTPUT ||
-        mType == CAMERA3_STREAM_BIDIRECTIONAL;
-}
-
-const char* Stream::typeToString(int type)
-{
-    switch (type) {
-    case CAMERA3_STREAM_INPUT:
-        return "CAMERA3_STREAM_INPUT";
-    case CAMERA3_STREAM_OUTPUT:
-        return "CAMERA3_STREAM_OUTPUT";
-    case CAMERA3_STREAM_BIDIRECTIONAL:
-        return "CAMERA3_STREAM_BIDIRECTIONAL";
-    }
-    return "Invalid stream type!";
-}
-
-const char* Stream::formatToString(int format)
-{
-    // See <system/graphics.h> for full list
-    switch (format) {
-    case HAL_PIXEL_FORMAT_BGRA_8888:
-        return "BGRA 8888";
-    case HAL_PIXEL_FORMAT_RGBA_8888:
-        return "RGBA 8888";
-    case HAL_PIXEL_FORMAT_RGBX_8888:
-        return "RGBX 8888";
-    case HAL_PIXEL_FORMAT_RGB_888:
-        return "RGB 888";
-    case HAL_PIXEL_FORMAT_RGB_565:
-        return "RGB 565";
-    case HAL_PIXEL_FORMAT_Y8:
-        return "Y8";
-    case HAL_PIXEL_FORMAT_Y16:
-        return "Y16";
-    case HAL_PIXEL_FORMAT_YV12:
-        return "YV12";
-    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-        return "NV16";
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-        return "NV21";
-    case HAL_PIXEL_FORMAT_YCbCr_422_I:
-        return "YUY2";
-    case HAL_PIXEL_FORMAT_RAW10:
-        return "RAW10";
-    case HAL_PIXEL_FORMAT_RAW16:
-        return "RAW16";
-    case HAL_PIXEL_FORMAT_BLOB:
-        return "BLOB";
-    case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
-        return "IMPLEMENTATION DEFINED";
-    case HAL_PIXEL_FORMAT_YCbCr_420_888:
-        return "FLEXIBLE YCbCr 420 888";
-    }
-    return "Invalid stream format!";
-}
-
-bool Stream::isValidReuseStream(int id, camera3_stream_t *s)
-{
-    if (id != mId) {
-        ALOGE("%s:%d: Invalid camera id for reuse. Got %d expect %d",
-                __func__, mId, id, mId);
-        return false;
-    }
-    if (s != mStream) {
-        ALOGE("%s:%d: Invalid stream handle for reuse. Got %p expect %p",
-                __func__, mId, s, mStream);
-        return false;
-    }
-    if (s->stream_type != mType) {
-        ALOGE("%s:%d: Mismatched type in reused stream. Got %s(%d) "
-                "expect %s(%d)", __func__, mId, typeToString(s->stream_type),
-                s->stream_type, typeToString(mType), mType);
-        return false;
-    }
-    if (s->format != mFormat) {
-        ALOGE("%s:%d: Mismatched format in reused stream. Got %s(%d) "
-                "expect %s(%d)", __func__, mId, formatToString(s->format),
-                s->format, formatToString(mFormat), mFormat);
-        return false;
-    }
-    if (s->width != mWidth) {
-        ALOGE("%s:%d: Mismatched width in reused stream. Got %d expect %d",
-                __func__, mId, s->width, mWidth);
-        return false;
-    }
-    if (s->height != mHeight) {
-        ALOGE("%s:%d: Mismatched height in reused stream. Got %d expect %d",
-                __func__, mId, s->height, mHeight);
-        return false;
-    }
-    return true;
-}
-
-void Stream::dump(int fd)
-{
-    android::Mutex::Autolock al(mLock);
-
-    dprintf(fd, "Stream ID: %d (%p)\n", mId, mStream);
-    dprintf(fd, "Stream Type: %s (%d)\n", typeToString(mType), mType);
-    dprintf(fd, "Width: %" PRIu32 " Height: %" PRIu32 "\n", mWidth, mHeight);
-    dprintf(fd, "Stream Format: %s (%d)", formatToString(mFormat), mFormat);
-    // ToDo: prettyprint usage mask flags
-    dprintf(fd, "Gralloc Usage Mask: %#" PRIx32 "\n", mUsage);
-    dprintf(fd, "Stream Rotation: %d\n", mRotation);
-    dprintf(fd, "Stream Dataspace: 0x%x\n", mDataSpace);
-    dprintf(fd, "Max Buffer Count: %" PRIu32 "\n", mMaxBuffers);
-}
-
-}  // namespace default_camera_hal
diff --git a/modules/camera/3_4/stream.h b/modules/camera/3_4/stream.h
deleted file mode 100644
index 781f946..0000000
--- a/modules/camera/3_4/stream.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-// Modified from hardware/libhardware/modules/camera/Stream.h
-
-#ifndef DEFAULT_CAMERA_HAL_STREAM_H_
-#define DEFAULT_CAMERA_HAL_STREAM_H_
-
-#include <hardware/camera3.h>
-#include <hardware/gralloc.h>
-#include <system/graphics.h>
-#include <utils/Mutex.h>
-
-namespace default_camera_hal {
-// Stream represents a single input or output stream for a camera device.
-class Stream {
-    public:
-        Stream(int id, camera3_stream_t *s);
-        ~Stream();
-
-        // validate that astream's parameters match this stream's parameters
-        bool isValidReuseStream(int id, camera3_stream_t *s);
-
-        void setUsage(uint32_t usage);
-        void setMaxBuffers(uint32_t max_buffers);
-        void setDataSpace(android_dataspace_t data_space);
-
-        inline int getFormat() const { return mFormat; };
-        inline int getType() const { return mType; };
-        inline uint32_t getWidth() const { return mWidth; };
-        inline uint32_t getHeight() const { return mHeight; };
-        inline int getRotation() const { return mRotation; };
-
-        bool isInputType() const;
-        bool isOutputType() const;
-        const char* typeToString(int type);
-        const char* formatToString(int format);
-        void dump(int fd);
-
-        // This stream is being reused. Used in stream configuration passes
-        bool mReuse;
-
-    private:
-
-        // The camera device id this stream belongs to
-        const int mId;
-        // Handle to framework's stream, used as a cookie for buffers
-        camera3_stream_t *mStream;
-        // Stream type: CAMERA3_STREAM_* (see <hardware/camera3.h>)
-        const int mType;
-        // Width in pixels of the buffers in this stream
-        const uint32_t mWidth;
-        // Height in pixels of the buffers in this stream
-        const uint32_t mHeight;
-        // Gralloc format: HAL_PIXEL_FORMAT_* (see <system/graphics.h>)
-        const int mFormat;
-        // Gralloc usage mask : GRALLOC_USAGE_* (see <hardware/gralloc.h>)
-        uint32_t mUsage;
-        // Output rotation this stream should undergo
-        const int mRotation;
-        // Color space of image data.
-        android_dataspace_t mDataSpace;
-        // Max simultaneous in-flight buffers for this stream
-        uint32_t mMaxBuffers;
-        // Lock protecting the Stream object for modifications
-        android::Mutex mLock;
-};
-}  // namespace default_camera_hal
-
-#endif  // DEFAULT_CAMERA_HAL_STREAM_H_
diff --git a/modules/camera/3_4/stream_format.cpp b/modules/camera/3_4/stream_format.cpp
index 2abfdb0..c85c26b 100644
--- a/modules/camera/3_4/stream_format.cpp
+++ b/modules/camera/3_4/stream_format.cpp
@@ -18,18 +18,18 @@
 
 #include <linux/videodev2.h>
 
+#include <system/graphics.h>
+
 #include "common.h"
-#include "stream.h"
 
 namespace v4l2_camera_hal {
 
-StreamFormat::StreamFormat(const default_camera_hal::Stream& stream)
+StreamFormat::StreamFormat(int format, uint32_t width, uint32_t height)
     // TODO(b/30000211): multiplanar support.
     : type_(V4L2_BUF_TYPE_VIDEO_CAPTURE),
-      v4l2_pixel_format_(
-          StreamFormat::HalToV4L2PixelFormat(stream.getFormat())),
-      width_(stream.getWidth()),
-      height_(stream.getHeight()),
+      v4l2_pixel_format_(StreamFormat::HalToV4L2PixelFormat(format)),
+      width_(width),
+      height_(height),
       bytes_per_line_(0),
       min_buffer_size_(0) {}
 
diff --git a/modules/camera/3_4/stream_format.h b/modules/camera/3_4/stream_format.h
index 9358d3d..66c5965 100644
--- a/modules/camera/3_4/stream_format.h
+++ b/modules/camera/3_4/stream_format.h
@@ -17,10 +17,11 @@
 #ifndef V4L2_CAMERA_HAL_STREAM_FORMAT_H_
 #define V4L2_CAMERA_HAL_STREAM_FORMAT_H_
 
+#include <string.h>
+
 #include <linux/videodev2.h>
 
 #include "common.h"
-#include "stream.h"
 
 namespace v4l2_camera_hal {
 
@@ -33,7 +34,7 @@
 
 class StreamFormat {
  public:
-  StreamFormat(const default_camera_hal::Stream& stream);
+  StreamFormat(int format, uint32_t width, uint32_t height);
   StreamFormat(const v4l2_format& format);
   virtual ~StreamFormat() = default;
   // Only uint32_t members, use default generated copy and assign.
diff --git a/modules/camera/3_4/v4l2_camera.cpp b/modules/camera/3_4/v4l2_camera.cpp
index 3383645..3e5b859 100644
--- a/modules/camera/3_4/v4l2_camera.cpp
+++ b/modules/camera/3_4/v4l2_camera.cpp
@@ -325,117 +325,25 @@
   return true;
 }
 
-bool V4L2Camera::isSupportedStreamSet(default_camera_hal::Stream** streams,
-                                      int count,
-                                      uint32_t mode) {
+bool V4L2Camera::validateDataspacesAndRotations(
+    const camera3_stream_configuration_t* stream_config) {
   HAL_LOG_ENTER();
 
-  if (mode != CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE) {
-    HAL_LOGE("Unsupported stream configuration mode: %d", mode);
-    return false;
-  }
-
-  // This should be checked by the caller, but put here as a sanity check.
-  if (count < 1) {
-    HAL_LOGE("Must request at least 1 stream");
-    return false;
-  }
-
-  // Count the number of streams of each type.
-  int32_t num_input = 0;
-  int32_t num_raw = 0;
-  int32_t num_stalling = 0;
-  int32_t num_non_stalling = 0;
-  for (int i = 0; i < count; ++i) {
-    default_camera_hal::Stream* stream = streams[i];
-
-    if (stream->isInputType()) {
-      ++num_input;
-    }
-
-    if (stream->isOutputType()) {
-      StreamFormat format(*stream);
-      switch (format.Category()) {
-        case kFormatCategoryRaw:
-          ++num_raw;
-        case kFormatCategoryStalling:
-          ++num_stalling;
-          break;
-        case kFormatCategoryNonStalling:
-          ++num_non_stalling;
-          break;
-        case kFormatCategoryUnknown:  // Fall through.
-        default:
-          HAL_LOGE(
-              "Unsupported format for stream %d: %d", i, stream->getFormat());
-          return false;
-      }
-    }
-  }
-
-  if (num_input > max_input_streams_ || num_raw > max_output_streams_[0] ||
-      num_non_stalling > max_output_streams_[1] ||
-      num_stalling > max_output_streams_[2]) {
-    HAL_LOGE(
-        "Invalid stream configuration: %d input, %d RAW, %d non-stalling, "
-        "%d stalling (max supported: %d input, %d RAW, %d non-stalling, "
-        "%d stalling)",
-        max_input_streams_,
-        max_output_streams_[0],
-        max_output_streams_[1],
-        max_output_streams_[2],
-        num_input,
-        num_raw,
-        num_non_stalling,
-        num_stalling);
-    return false;
-  }
-
-  // TODO(b/29939583): The above logic should be all that's necessary,
-  // but V4L2 doesn't actually support more than 1 stream at a time. So for now,
-  // if not all streams are the same format and size, error. Note that this
-  // means the HAL is not spec-compliant; the requested streams are technically
-  // valid and it is not technically allowed to error once it has reached this
-  // point.
-  int format = streams[0]->getFormat();
-  uint32_t width = streams[0]->getWidth();
-  uint32_t height = streams[0]->getHeight();
-  for (int i = 1; i < count; ++i) {
-    const default_camera_hal::Stream* stream = streams[i];
-    if (stream->getFormat() != format || stream->getWidth() != width ||
-        stream->getHeight() != height) {
-      HAL_LOGE(
-          "V4L2 only supports 1 stream configuration at a time "
-          "(stream 0 is format %d, width %u, height %u, "
-          "stream %d is format %d, width %u, height %u).",
-          format,
-          width,
-          height,
-          i,
-          stream->getFormat(),
-          stream->getWidth(),
-          stream->getHeight());
+  for (uint32_t i = 0; i < stream_config->num_streams; ++i) {
+    if (stream_config->streams[i]->rotation != CAMERA3_STREAM_ROTATION_0) {
+      HAL_LOGV("Rotation %d for stream %d not supported",
+               stream_config->streams[i]->rotation,
+               i);
       return false;
     }
+    // Accept all dataspaces, as it will just be overwritten below anyways.
   }
-
   return true;
 }
 
-int V4L2Camera::setupStream(default_camera_hal::Stream* stream,
-                            uint32_t* max_buffers) {
+int V4L2Camera::setupStreams(camera3_stream_configuration_t* stream_config) {
   HAL_LOG_ENTER();
 
-  if (stream->getRotation() != CAMERA3_STREAM_ROTATION_0) {
-    HAL_LOGE("Rotation %d not supported", stream->getRotation());
-    return -EINVAL;
-  }
-
-  // Doesn't matter what was requested, we always use dataspace V0_JFIF.
-  // Note: according to camera3.h, this isn't allowed, but etalvala@google.com
-  // claims it's underdocumented; the implementation lets the HAL overwrite it.
-  stream->setDataSpace(HAL_DATASPACE_V0_JFIF);
-
   std::lock_guard<std::mutex> guard(in_flight_lock_);
   // The framework should be enforcing this, but doesn't hurt to be safe.
   if (!in_flight_.empty()) {
@@ -443,44 +351,100 @@
     return -EINVAL;
   }
 
+  // stream_config should have been validated; assume at least 1 stream.
+  camera3_stream_t* stream = stream_config->streams[0];
+  int format = stream->format;
+  uint32_t width = stream->width;
+  uint32_t height = stream->height;
+
+  if (stream_config->num_streams > 1) {
+    // TODO(b/29939583):  V4L2 doesn't actually support more than 1
+    // stream at a time. If not all streams are the same format
+    // and size, error. Note that this means the HAL is not spec-compliant.
+    // Technically, this error should be thrown during validation, but
+    // since it isn't a spec-valid error validation isn't set up to check it.
+    for (uint32_t i = 1; i < stream_config->num_streams; ++i) {
+      stream = stream_config->streams[i];
+      if (stream->format != format || stream->width != width ||
+          stream->height != height) {
+        HAL_LOGE(
+            "V4L2 only supports 1 stream configuration at a time "
+            "(stream 0 is format %d, width %u, height %u, "
+            "stream %d is format %d, width %u, height %u).",
+            format,
+            width,
+            height,
+            i,
+            stream->format,
+            stream->width,
+            stream->height);
+        return -EINVAL;
+      }
+    }
+  }
+
   // Ensure the stream is off.
   int res = device_->StreamOff();
   if (res) {
-    HAL_LOGE("Device failed to turn off stream for reconfiguration.");
+    HAL_LOGE("Device failed to turn off stream for reconfiguration: %d.", res);
     return -ENODEV;
   }
 
-  res = device_->SetFormat(*stream, max_buffers);
+  StreamFormat stream_format(format, width, height);
+  uint32_t max_buffers = 0;
+  res = device_->SetFormat(stream_format, &max_buffers);
   if (res) {
-    HAL_LOGE("Failed to set device to correct format for stream.");
-    return res;
+    HAL_LOGE("Failed to set device to correct format for stream: %d.", res);
+    return -ENODEV;
   }
 
   // Sanity check.
-  if (*max_buffers < 1) {
+  if (max_buffers < 1) {
     HAL_LOGE("Setting format resulted in an invalid maximum of %u buffers.",
-             *max_buffers);
+             max_buffers);
     return -ENODEV;
   }
 
+  // Set all the streams dataspaces, usages, and max buffers.
+  for (uint32_t i = 0; i < stream_config->num_streams; ++i) {
+    stream = stream_config->streams[i];
+
+    // Max buffers as reported by the device.
+    stream->max_buffers = max_buffers;
+
+    // Usage: currently using sw graphics.
+    switch (stream->stream_type) {
+      case CAMERA3_STREAM_INPUT:
+        stream->usage = GRALLOC_USAGE_SW_READ_OFTEN;
+        break;
+      case CAMERA3_STREAM_OUTPUT:
+        stream->usage = GRALLOC_USAGE_SW_WRITE_OFTEN;
+        break;
+      case CAMERA3_STREAM_BIDIRECTIONAL:
+        stream->usage =
+            GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;
+        break;
+      default:
+        // nothing to do.
+        break;
+    }
+
+    // Doesn't matter what was requested, we always use dataspace V0_JFIF.
+    // Note: according to camera3.h, this isn't allowed, but the camera
+    // framework team claims it's underdocumented; the implementation lets the
+    // HAL overwrite it. If this is changed, change the validation above.
+    stream->data_space = HAL_DATASPACE_V0_JFIF;
+  }
+
   return 0;
 }
 
-bool V4L2Camera::isValidRequest(
-    const default_camera_hal::CaptureRequest& request) {
-  HAL_LOG_ENTER();
-
-  if (request.input_buffer != nullptr) {
-    HAL_LOGE("Input buffer reprocessing not implemented.");
-    return false;
-  } else if (request.output_buffers.size() > 1) {
-    HAL_LOGE("Only 1 output buffer allowed per request.");
-    return false;
-  } else if (!metadata_->IsValidRequest(request.settings)) {
+bool V4L2Camera::isValidRequestSettings(
+    const android::CameraMetadata& settings) {
+  if (!metadata_->IsValidRequest(settings)) {
     HAL_LOGE("Invalid request settings.");
     return false;
   }
-
   return true;
 }
 
diff --git a/modules/camera/3_4/v4l2_camera.h b/modules/camera/3_4/v4l2_camera.h
index 3dae649..1db8d40 100644
--- a/modules/camera/3_4/v4l2_camera.h
+++ b/modules/camera/3_4/v4l2_camera.h
@@ -67,17 +67,13 @@
   void initDeviceInfo(camera_info_t* info) override;
   // Extra initialization of device when opened.
   int initDevice() override;
-  // Verify stream configuration is device-compatible.
-  bool isSupportedStreamSet(default_camera_hal::Stream** streams,
-                            int count,
-                            uint32_t mode) override;
-  // Set up the device for a stream, and get the maximum number of
-  // buffers that stream can handle (max_buffers is an output parameter).
-  int setupStream(default_camera_hal::Stream* stream,
-                  uint32_t* max_buffers) override;
+  // Verify stream configuration dataspaces and rotation values
+  bool validateDataspacesAndRotations(
+      const camera3_stream_configuration_t* stream_config) override;
+  // Set up the streams, including seting usage & max_buffers
+  int setupStreams(camera3_stream_configuration_t* stream_config) override;
   // Verify settings are valid for a capture or reprocessing.
-  bool isValidRequest(
-      const default_camera_hal::CaptureRequest& request) override;
+  bool isValidRequestSettings(const android::CameraMetadata& settings) override;
   // Enqueue a request to receive data from the camera.
   int enqueueRequest(
       std::shared_ptr<default_camera_hal::CaptureRequest> request) override;
diff --git a/modules/camera/3_4/v4l2_wrapper.cpp b/modules/camera/3_4/v4l2_wrapper.cpp
index fd4f169..b24535c 100644
--- a/modules/camera/3_4/v4l2_wrapper.cpp
+++ b/modules/camera/3_4/v4l2_wrapper.cpp
@@ -31,7 +31,6 @@
 #include <nativehelper/ScopedFd.h>
 
 #include "common.h"
-#include "stream.h"
 #include "stream_format.h"
 #include "v4l2_gralloc.h"
 
@@ -440,17 +439,10 @@
   return 0;
 }
 
-int V4L2Wrapper::SetFormat(const default_camera_hal::Stream& stream,
+int V4L2Wrapper::SetFormat(const StreamFormat& desired_format,
                            uint32_t* result_max_buffers) {
   HAL_LOG_ENTER();
 
-  // Should be checked earlier; sanity check.
-  if (stream.isInputType()) {
-    HAL_LOGE("Input streams not supported.");
-    return -EINVAL;
-  }
-
-  StreamFormat desired_format(stream);
   if (format_ && desired_format == *format_) {
     HAL_LOGV("Already in correct format, skipping format setting.");
     *result_max_buffers = buffers_.size();
diff --git a/modules/camera/3_4/v4l2_wrapper.h b/modules/camera/3_4/v4l2_wrapper.h
index 8c10d4b..eb41239 100644
--- a/modules/camera/3_4/v4l2_wrapper.h
+++ b/modules/camera/3_4/v4l2_wrapper.h
@@ -27,7 +27,6 @@
 #include <nativehelper/ScopedFd.h>
 
 #include "common.h"
-#include "stream.h"
 #include "stream_format.h"
 #include "v4l2_gralloc.h"
 
@@ -75,7 +74,7 @@
       uint32_t v4l2_format,
       const std::array<int32_t, 2>& size,
       std::array<int64_t, 2>* duration_range);
-  virtual int SetFormat(const default_camera_hal::Stream& stream,
+  virtual int SetFormat(const StreamFormat& desired_format,
                         uint32_t* result_max_buffers);
   // Manage buffers.
   virtual int EnqueueBuffer(const camera3_stream_buffer_t* camera_buffer,
diff --git a/modules/camera/3_4/v4l2_wrapper_mock.h b/modules/camera/3_4/v4l2_wrapper_mock.h
index 5f8fc4a..d423cc5 100644
--- a/modules/camera/3_4/v4l2_wrapper_mock.h
+++ b/modules/camera/3_4/v4l2_wrapper_mock.h
@@ -42,8 +42,10 @@
                int(uint32_t,
                    const std::array<int32_t, 2>&,
                    std::array<int64_t, 2>*));
-  MOCK_METHOD2(SetFormat,
-               int(const default_camera_hal::Stream& stream,
+  MOCK_METHOD4(SetFormat,
+               int(int format,
+                   uint32_t width,
+                   uint32_t height,
                    uint32_t* result_max_buffers));
   MOCK_METHOD2(EnqueueBuffer,
                int(const camera3_stream_buffer_t* camera_buffer,