diff --git a/tests/camera2/Android.mk b/tests/camera2/Android.mk
deleted file mode 100644
index e4f9640..0000000
--- a/tests/camera2/Android.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-	camera2_utils.cpp \
-	main.cpp \
-	CameraMetadataTests.cpp \
-	CameraModuleTests.cpp \
-	CameraStreamTests.cpp \
-	CameraFrameTests.cpp \
-	CameraBurstTests.cpp \
-	CameraMultiStreamTests.cpp\
-	ForkedTests.cpp \
-	TestForkerEventListener.cpp \
-	TestSettings.cpp \
-
-LOCAL_SHARED_LIBRARIES := \
-	liblog \
-	libutils \
-	libcutils \
-	libhardware \
-	libcamera_metadata \
-	libcameraservice \
-	libcamera_client \
-	libgui \
-	libsync \
-	libui \
-	libdl \
-	android.hardware.camera.device@3.2
-
-LOCAL_C_INCLUDES += \
-	system/media/camera/include \
-	system/media/private/camera/include \
-	frameworks/av/include/ \
-	frameworks/av/services/camera/libcameraservice \
-	frameworks/native/include \
-
-LOCAL_CFLAGS += -Wall -Wextra
-LOCAL_MODULE:= camera2_test
-LOCAL_MODULE_STEM_32 := camera2_test
-LOCAL_MODULE_STEM_64 := camera2_test64
-LOCAL_MULTILIB := both
-LOCAL_MODULE_TAGS := tests
-
-include $(BUILD_NATIVE_TEST)
diff --git a/tests/camera2/CameraBurstTests.cpp b/tests/camera2/CameraBurstTests.cpp
deleted file mode 100644
index 198c0c1..0000000
--- a/tests/camera2/CameraBurstTests.cpp
+++ /dev/null
@@ -1,731 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#include <gtest/gtest.h>
-#include <inttypes.h>
-
-#define LOG_TAG "CameraBurstTest"
-//#define LOG_NDEBUG 0
-#include <utils/Log.h>
-#include <utils/Timers.h>
-
-#include <cmath>
-
-#include "CameraStreamFixture.h"
-#include "TestExtensions.h"
-
-#define CAMERA_FRAME_TIMEOUT    1000000000LL //nsecs (1 secs)
-#define CAMERA_HEAP_COUNT       2 //HALBUG: 1 means registerBuffers fails
-#define CAMERA_BURST_DEBUGGING  0
-#define CAMERA_FRAME_BURST_COUNT 10
-
-/* constants for the exposure test */
-#define CAMERA_EXPOSURE_DOUBLE  2
-#define CAMERA_EXPOSURE_DOUBLING_THRESHOLD 1.0f
-#define CAMERA_EXPOSURE_DOUBLING_COUNT 4
-#define CAMERA_EXPOSURE_FORMAT CAMERA_STREAM_AUTO_CPU_FORMAT
-#define CAMERA_EXPOSURE_STARTING 100000 // 1/10ms, up to 51.2ms with 10 steps
-
-#define USEC 1000LL        // in ns
-#define MSEC 1000000LL     // in ns
-#define SEC  1000000000LL  // in ns
-
-#if CAMERA_BURST_DEBUGGING
-#define dout std::cout
-#else
-#define dout if (0) std::cout
-#endif
-
-#define WARN_UNLESS(condition) if(!(condition)) std::cerr << "Warning: "
-#define WARN_LE(exp, act) WARN_UNLESS((exp) <= (act))
-#define WARN_LT(exp, act) WARN_UNLESS((exp) < (act))
-#define WARN_GT(exp, act) WARN_UNLESS((exp) > (act))
-
-using namespace android;
-using namespace android::camera2;
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-static CameraStreamParams STREAM_PARAMETERS = {
-    /*mFormat*/     CAMERA_EXPOSURE_FORMAT,
-    /*mHeapCount*/  CAMERA_HEAP_COUNT
-};
-
-class CameraBurstTest
-    : public ::testing::Test,
-      public CameraStreamFixture {
-
-public:
-    CameraBurstTest() : CameraStreamFixture(STREAM_PARAMETERS) {
-        TEST_EXTENSION_FORKING_CONSTRUCTOR;
-
-        if (HasFatalFailure()) {
-            return;
-        }
-
-        CreateStream();
-    }
-
-    ~CameraBurstTest() {
-        TEST_EXTENSION_FORKING_DESTRUCTOR;
-
-        if (mDevice.get()) {
-            mDevice->waitUntilDrained();
-        }
-        DeleteStream();
-    }
-
-    virtual void SetUp() {
-        TEST_EXTENSION_FORKING_SET_UP;
-    }
-    virtual void TearDown() {
-        TEST_EXTENSION_FORKING_TEAR_DOWN;
-    }
-
-    /* this assumes the format is YUV420sp or flexible YUV */
-    long long TotalBrightness(const CpuConsumer::LockedBuffer& imgBuffer,
-                              int *underexposed,
-                              int *overexposed) const {
-
-        const uint8_t* buf = imgBuffer.data;
-        size_t stride = imgBuffer.stride;
-
-        /* iterate over the Y plane only */
-        long long acc = 0;
-
-        *underexposed = 0;
-        *overexposed = 0;
-
-        for (size_t y = 0; y < imgBuffer.height; ++y) {
-            for (size_t x = 0; x < imgBuffer.width; ++x) {
-                const uint8_t p = buf[y * stride + x];
-
-                if (p == 0) {
-                    if (underexposed) {
-                        ++*underexposed;
-                    }
-                    continue;
-                } else if (p == 255) {
-                    if (overexposed) {
-                        ++*overexposed;
-                    }
-                    continue;
-                }
-
-                acc += p;
-            }
-        }
-
-        return acc;
-    }
-
-    // Parses a comma-separated string list into a Vector
-    template<typename T>
-    void ParseList(const char *src, Vector<T> &list) {
-        std::istringstream s(src);
-        while (!s.eof()) {
-            char c = s.peek();
-            if (c == ',' || c == ' ') {
-                s.ignore(1, EOF);
-                continue;
-            }
-            T val;
-            s >> val;
-            list.push_back(val);
-        }
-    }
-
-};
-
-TEST_F(CameraBurstTest, ManualExposureControl) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    // Range of valid exposure times, in nanoseconds
-    int64_t minExp, maxExp;
-    {
-        camera_metadata_ro_entry exposureTimeRange =
-            GetStaticEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE);
-
-        ASSERT_EQ(2u, exposureTimeRange.count);
-        minExp = exposureTimeRange.data.i64[0];
-        maxExp = exposureTimeRange.data.i64[1];
-    }
-
-    dout << "Min exposure is " << minExp;
-    dout << " max exposure is " << maxExp << std::endl;
-
-    // Calculate some set of valid exposure times for each request
-    int64_t exposures[CAMERA_FRAME_BURST_COUNT];
-    exposures[0] = CAMERA_EXPOSURE_STARTING;
-    for (int i = 1; i < CAMERA_FRAME_BURST_COUNT; ++i) {
-        exposures[i] = exposures[i-1] * CAMERA_EXPOSURE_DOUBLE;
-    }
-    // Our calculated exposure times should be in [minExp, maxExp]
-    EXPECT_LE(minExp, exposures[0])
-        << "Minimum exposure range is too high, wanted at most "
-        << exposures[0] << "ns";
-    EXPECT_GE(maxExp, exposures[CAMERA_FRAME_BURST_COUNT-1])
-        << "Maximum exposure range is too low, wanted at least "
-        << exposures[CAMERA_FRAME_BURST_COUNT-1] << "ns";
-
-    // Create a preview request, turning off all 3A
-    CameraMetadata previewRequest;
-    ASSERT_EQ(OK, mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
-                                                &previewRequest));
-    {
-        Vector<int32_t> outputStreamIds;
-        outputStreamIds.push(mStreamId);
-        ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
-                                            outputStreamIds));
-
-        // Disable all 3A routines
-        uint8_t cmOff = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
-        ASSERT_EQ(OK, previewRequest.update(ANDROID_CONTROL_MODE,
-                                            &cmOff, 1));
-
-        int requestId = 1;
-        ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_ID,
-                                            &requestId, 1));
-
-        if (CAMERA_BURST_DEBUGGING) {
-            int frameCount = 0;
-            ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_FRAME_COUNT,
-                                                &frameCount, 1));
-        }
-    }
-
-    if (CAMERA_BURST_DEBUGGING) {
-        previewRequest.dump(STDOUT_FILENO);
-    }
-
-    // Submit capture requests
-    for (int i = 0; i < CAMERA_FRAME_BURST_COUNT; ++i) {
-        CameraMetadata tmpRequest = previewRequest;
-        ASSERT_EQ(OK, tmpRequest.update(ANDROID_SENSOR_EXPOSURE_TIME,
-                                        &exposures[i], 1));
-        ALOGV("Submitting capture request %d with exposure %" PRId64, i,
-            exposures[i]);
-        dout << "Capture request " << i << " exposure is "
-             << (exposures[i]/1e6f) << std::endl;
-        ASSERT_EQ(OK, mDevice->capture(tmpRequest));
-    }
-
-    dout << "Buffer dimensions " << mWidth << "x" << mHeight << std::endl;
-
-    float brightnesses[CAMERA_FRAME_BURST_COUNT];
-    // Get each frame (metadata) and then the buffer. Calculate brightness.
-    for (int i = 0; i < CAMERA_FRAME_BURST_COUNT; ++i) {
-        ALOGV("Reading capture request %d with exposure %" PRId64, i, exposures[i]);
-        ASSERT_EQ(OK, mDevice->waitForNextFrame(CAMERA_FRAME_TIMEOUT));
-        ALOGV("Reading capture request-1 %d", i);
-        CaptureResult result;
-        ASSERT_EQ(OK, mDevice->getNextResult(&result));
-        ALOGV("Reading capture request-2 %d", i);
-
-        ASSERT_EQ(OK, mFrameListener->waitForFrame(CAMERA_FRAME_TIMEOUT));
-        ALOGV("We got the frame now");
-
-        CpuConsumer::LockedBuffer imgBuffer;
-        ASSERT_EQ(OK, mCpuConsumer->lockNextBuffer(&imgBuffer));
-
-        int underexposed, overexposed;
-        long long brightness = TotalBrightness(imgBuffer, &underexposed,
-                                               &overexposed);
-        float avgBrightness = brightness * 1.0f /
-                              (mWidth * mHeight - (underexposed + overexposed));
-        ALOGV("Total brightness for frame %d was %lld (underexposed %d, "
-              "overexposed %d), avg %f", i, brightness, underexposed,
-              overexposed, avgBrightness);
-        dout << "Average brightness (frame " << i << ") was " << avgBrightness
-             << " (underexposed " << underexposed << ", overexposed "
-             << overexposed << ")" << std::endl;
-
-        ASSERT_EQ(OK, mCpuConsumer->unlockBuffer(imgBuffer));
-
-        brightnesses[i] = avgBrightness;
-    }
-
-    // Calculate max consecutive frame exposure doubling
-    float prev = brightnesses[0];
-    int doubling_count = 1;
-    int max_doubling_count = 0;
-    for (int i = 1; i < CAMERA_FRAME_BURST_COUNT; ++i) {
-        if (fabs(brightnesses[i] - prev*CAMERA_EXPOSURE_DOUBLE)
-            <= CAMERA_EXPOSURE_DOUBLING_THRESHOLD) {
-            doubling_count++;
-        }
-        else {
-            max_doubling_count = std::max(max_doubling_count, doubling_count);
-            doubling_count = 1;
-        }
-        prev = brightnesses[i];
-    }
-
-    dout << "max doubling count: " << max_doubling_count << std::endl;
-
-    /**
-     * Make this check warning only, since the brightness calculation is not reliable
-     * and we have separate test to cover this case. Plus it is pretty subtle to make
-     * it right without complicating the test too much.
-     */
-    WARN_LE(CAMERA_EXPOSURE_DOUBLING_COUNT, max_doubling_count)
-            << "average brightness should double at least "
-            << CAMERA_EXPOSURE_DOUBLING_COUNT
-            << " times over each consecutive frame as the exposure is doubled"
-            << std::endl;
-}
-
-/**
- * This test varies exposure time, frame duration, and sensitivity for a
- * burst of captures. It picks values by default, but the selection can be
- * overridden with the environment variables
- *   CAMERA2_TEST_VARIABLE_BURST_EXPOSURE_TIMES
- *   CAMERA2_TEST_VARIABLE_BURST_FRAME_DURATIONS
- *   CAMERA2_TEST_VARIABLE_BURST_SENSITIVITIES
- * which must all be a list of comma-separated values, and each list must be
- * the same length.  In addition, if the environment variable
- *   CAMERA2_TEST_VARIABLE_BURST_DUMP_FRAMES
- * is set to 1, then the YUV buffers are dumped into files named
- *   "camera2_test_variable_burst_frame_NNN.yuv"
- *
- * For example:
- *   $ setenv CAMERA2_TEST_VARIABLE_BURST_EXPOSURE_TIMES 10000000,20000000
- *   $ setenv CAMERA2_TEST_VARIABLE_BURST_FRAME_DURATIONS 40000000,40000000
- *   $ setenv CAMERA2_TEST_VARIABLE_BURST_SENSITIVITIES 200,100
- *   $ setenv CAMERA2_TEST_VARIABLE_BURST_DUMP_FRAMES 1
- *   $ /data/nativetest/camera2_test/camera2_test --gtest_filter="*VariableBurst"
- */
-TEST_F(CameraBurstTest, VariableBurst) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    // Bounds for checking frame duration is within range
-    const nsecs_t DURATION_UPPER_BOUND = 10 * MSEC;
-    const nsecs_t DURATION_LOWER_BOUND = 20 * MSEC;
-
-    // Threshold for considering two captures to have equivalent exposure value,
-    // as a ratio of the smaller EV to the larger EV.
-    const float   EV_MATCH_BOUND = 0.95;
-    // Bound for two captures with equivalent exp values to have the same
-    // measured brightness, in 0-255 luminance.
-    const float   BRIGHTNESS_MATCH_BOUND = 5;
-
-    // Environment variables to look for to override test settings
-    const char *expEnv         = "CAMERA2_TEST_VARIABLE_BURST_EXPOSURE_TIMES";
-    const char *durationEnv    = "CAMERA2_TEST_VARIABLE_BURST_FRAME_DURATIONS";
-    const char *sensitivityEnv = "CAMERA2_TEST_VARIABLE_BURST_SENSITIVITIES";
-    const char *dumpFrameEnv   = "CAMERA2_TEST_VARIABLE_BURST_DUMP_FRAMES";
-
-    // Range of valid exposure times, in nanoseconds
-    int64_t minExp = 0, maxExp = 0;
-    // List of valid sensor sensitivities
-    Vector<int32_t> sensitivities;
-    // Range of valid frame durations, in nanoseconds
-    int64_t minDuration = 0, maxDuration = 0;
-
-    {
-        camera_metadata_ro_entry exposureTimeRange =
-            GetStaticEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE);
-
-        EXPECT_EQ(2u, exposureTimeRange.count) << "Bad exposure time range tag."
-                "Using default values";
-        if (exposureTimeRange.count == 2) {
-            minExp = exposureTimeRange.data.i64[0];
-            maxExp = exposureTimeRange.data.i64[1];
-        }
-
-        EXPECT_LT(0, minExp) << "Minimum exposure time is 0";
-        EXPECT_LT(0, maxExp) << "Maximum exposure time is 0";
-        EXPECT_LE(minExp, maxExp) << "Minimum exposure is greater than maximum";
-
-        if (minExp == 0) {
-            minExp = 1 * MSEC; // Fallback minimum exposure time
-        }
-
-        if (maxExp == 0) {
-            maxExp = 10 * SEC; // Fallback maximum exposure time
-        }
-    }
-
-    camera_metadata_ro_entry hardwareLevel =
-        GetStaticEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL);
-    ASSERT_EQ(1u, hardwareLevel.count);
-    uint8_t level = hardwareLevel.data.u8[0];
-    ASSERT_GE(level, ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED);
-    ASSERT_LE(level, ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL);
-    if (level == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED) {
-        const ::testing::TestInfo* const test_info =
-            ::testing::UnitTest::GetInstance()->current_test_info();
-        std::cerr << "Skipping test "
-                  << test_info->test_case_name() << "."
-                  << test_info->name()
-                  << " because HAL hardware supported level is limited "
-                  << std::endl;
-        return;
-    }
-
-    dout << "Stream size is " << mWidth << " x " << mHeight << std::endl;
-    dout << "Valid exposure range is: " <<
-            minExp << " - " << maxExp << " ns " << std::endl;
-
-    {
-        camera_metadata_ro_entry sensivityRange =
-            GetStaticEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE);
-        EXPECT_EQ(2u, sensivityRange.count) << "No sensitivity range listed."
-                "Falling back to default set.";
-        int32_t minSensitivity = 100;
-        int32_t maxSensitivity = 800;
-        if (sensivityRange.count == 2) {
-            ASSERT_GT(sensivityRange.data.i32[0], 0);
-            ASSERT_GT(sensivityRange.data.i32[1], 0);
-            minSensitivity = sensivityRange.data.i32[0];
-            maxSensitivity = sensivityRange.data.i32[1];
-        }
-        int32_t count = (maxSensitivity - minSensitivity + 99) / 100;
-        sensitivities.push_back(minSensitivity);
-        for (int i = 1; i < count; i++) {
-            sensitivities.push_back(minSensitivity + i * 100);
-        }
-        sensitivities.push_back(maxSensitivity);
-    }
-
-    dout << "Available sensitivities: ";
-    for (size_t i = 0; i < sensitivities.size(); i++) {
-        dout << sensitivities[i] << " ";
-    }
-    dout << std::endl;
-
-    {
-        if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
-            camera_metadata_ro_entry availableProcessedSizes =
-                    GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
-
-            camera_metadata_ro_entry availableProcessedMinFrameDurations =
-                    GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS);
-
-            EXPECT_EQ(availableProcessedSizes.count,
-                    availableProcessedMinFrameDurations.count * 2) <<
-                    "The number of minimum frame durations doesn't match the number of "
-                    "available sizes. Using fallback values";
-
-            if (availableProcessedSizes.count ==
-                    availableProcessedMinFrameDurations.count * 2) {
-                bool gotSize = false;
-                for (size_t i = 0; i < availableProcessedSizes.count; i += 2) {
-                    if (availableProcessedSizes.data.i32[i] == mWidth &&
-                            availableProcessedSizes.data.i32[i+1] == mHeight) {
-                        gotSize = true;
-                        minDuration = availableProcessedMinFrameDurations.data.i64[i/2];
-                    }
-                }
-                EXPECT_TRUE(gotSize) << "Can't find stream size in list of "
-                        "available sizes: " << mWidth << ", " << mHeight;
-            }
-            if (minDuration == 0) {
-                minDuration = 1 * SEC / 30; // Fall back to 30 fps as minimum duration
-            }
-        } else {
-            minDuration = getMinFrameDurationFor(
-                    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, mWidth, mHeight);
-        }
-        ASSERT_LT(0, minDuration);
-
-        camera_metadata_ro_entry maxFrameDuration =
-                GetStaticEntry(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION);
-
-        EXPECT_EQ(1u, maxFrameDuration.count) << "No valid maximum frame duration";
-
-        if (maxFrameDuration.count == 1) {
-            maxDuration = maxFrameDuration.data.i64[0];
-        }
-
-        EXPECT_GT(maxDuration, 0) << "Max duration is 0 or not given, using fallback";
-
-        if (maxDuration == 0) {
-            maxDuration = 10 * SEC; // Fall back to 10 seconds as max duration
-        }
-
-    }
-    dout << "Available frame duration range for configured stream size: "
-         << minDuration << " - " << maxDuration << " ns" << std::endl;
-
-    // Get environment variables if set
-    const char *expVal = getenv(expEnv);
-    const char *durationVal = getenv(durationEnv);
-    const char *sensitivityVal = getenv(sensitivityEnv);
-
-    bool gotExp = (expVal != NULL);
-    bool gotDuration = (durationVal != NULL);
-    bool gotSensitivity = (sensitivityVal != NULL);
-
-    // All or none must be provided if using override envs
-    ASSERT_TRUE( (gotDuration && gotExp && gotSensitivity) ||
-            (!gotDuration && !gotExp && !gotSensitivity) ) <<
-            "Incomplete set of environment variable overrides provided";
-
-    Vector<int64_t> expList, durationList;
-    Vector<int32_t> sensitivityList;
-    if (gotExp) {
-        ParseList(expVal, expList);
-        ParseList(durationVal, durationList);
-        ParseList(sensitivityVal, sensitivityList);
-
-        ASSERT_TRUE(
-            (expList.size() == durationList.size()) &&
-            (durationList.size() == sensitivityList.size())) <<
-                "Mismatched sizes in env lists, or parse error";
-
-        dout << "Using burst list from environment with " << expList.size() <<
-                " captures" << std::endl;
-    } else {
-        // Create a default set of controls based on the available ranges
-
-        int64_t e;
-        int64_t d;
-        int32_t s;
-
-        // Exposure ramp
-
-        e = minExp;
-        d = minDuration;
-        s = sensitivities[0];
-        while (e < maxExp) {
-            expList.push_back(e);
-            durationList.push_back(d);
-            sensitivityList.push_back(s);
-            e = e * 2;
-        }
-        e = maxExp;
-        expList.push_back(e);
-        durationList.push_back(d);
-        sensitivityList.push_back(s);
-
-        // Duration ramp
-
-        e = 30 * MSEC;
-        d = minDuration;
-        s = sensitivities[0];
-        while (d < maxDuration) {
-            // make sure exposure <= frame duration
-            expList.push_back(e > d ? d : e);
-            durationList.push_back(d);
-            sensitivityList.push_back(s);
-            d = d * 2;
-        }
-
-        // Sensitivity ramp
-
-        e = 30 * MSEC;
-        d = 30 * MSEC;
-        d = d > minDuration ? d : minDuration;
-        for (size_t i = 0; i < sensitivities.size(); i++) {
-            expList.push_back(e);
-            durationList.push_back(d);
-            sensitivityList.push_back(sensitivities[i]);
-        }
-
-        // Constant-EV ramp, duration == exposure
-
-        e = 30 * MSEC; // at ISO 100
-        for (size_t i = 0; i < sensitivities.size(); i++) {
-            int64_t e_adj = e * 100 / sensitivities[i];
-            expList.push_back(e_adj);
-            durationList.push_back(e_adj > minDuration ? e_adj : minDuration);
-            sensitivityList.push_back(sensitivities[i]);
-        }
-
-        dout << "Default burst sequence created with " << expList.size() <<
-                " entries" << std::endl;
-    }
-
-    // Validate the list, but warn only
-    for (size_t i = 0; i < expList.size(); i++) {
-        EXPECT_GE(maxExp, expList[i])
-                << "Capture " << i << " exposure too long: " << expList[i];
-        EXPECT_LE(minExp, expList[i])
-                << "Capture " << i << " exposure too short: " << expList[i];
-        EXPECT_GE(maxDuration, durationList[i])
-                << "Capture " << i << " duration too long: " << durationList[i];
-        EXPECT_LE(minDuration, durationList[i])
-                 << "Capture " << i << " duration too short: "  << durationList[i];
-        bool validSensitivity = false;
-        for (size_t j = 0; j < sensitivities.size(); j++) {
-            if (sensitivityList[i] == sensitivities[j]) {
-                validSensitivity = true;
-                break;
-            }
-        }
-        EXPECT_TRUE(validSensitivity)
-                << "Capture " << i << " sensitivity not in list: " << sensitivityList[i];
-    }
-
-    // Check if debug yuv dumps are requested
-
-    bool dumpFrames = false;
-    {
-        const char *frameDumpVal = getenv(dumpFrameEnv);
-        if (frameDumpVal != NULL) {
-            if (frameDumpVal[0] == '1') dumpFrames = true;
-        }
-    }
-
-    dout << "Dumping YUV frames " <<
-            (dumpFrames ? "enabled, not checking timing" : "disabled") << std::endl;
-
-    // Create a base preview request, turning off all 3A
-    CameraMetadata previewRequest;
-    ASSERT_EQ(OK, mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
-                                                &previewRequest));
-    {
-        Vector<int32_t> outputStreamIds;
-        outputStreamIds.push(mStreamId);
-        ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
-                                            outputStreamIds));
-
-        // Disable all 3A routines
-        uint8_t cmOff = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
-        ASSERT_EQ(OK, previewRequest.update(ANDROID_CONTROL_MODE,
-                                            &cmOff, 1));
-
-        int requestId = 1;
-        ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_ID,
-                                            &requestId, 1));
-    }
-
-    // Submit capture requests
-
-    for (size_t i = 0; i < expList.size(); ++i) {
-        CameraMetadata tmpRequest = previewRequest;
-        ASSERT_EQ(OK, tmpRequest.update(ANDROID_SENSOR_EXPOSURE_TIME,
-                                        &expList[i], 1));
-        ASSERT_EQ(OK, tmpRequest.update(ANDROID_SENSOR_FRAME_DURATION,
-                                        &durationList[i], 1));
-        ASSERT_EQ(OK, tmpRequest.update(ANDROID_SENSOR_SENSITIVITY,
-                                        &sensitivityList[i], 1));
-        ALOGV("Submitting capture %zu with exposure %" PRId64 ", frame duration %" PRId64 ", sensitivity %d",
-                i, expList[i], durationList[i], sensitivityList[i]);
-        dout << "Capture request " << i <<
-                ": exposure is " << (expList[i]/1e6f) << " ms" <<
-                ", frame duration is " << (durationList[i]/1e6f) << " ms" <<
-                ", sensitivity is " << sensitivityList[i] <<
-                std::endl;
-        ASSERT_EQ(OK, mDevice->capture(tmpRequest));
-    }
-
-    Vector<float> brightnesses;
-    Vector<nsecs_t> captureTimes;
-    brightnesses.setCapacity(expList.size());
-    captureTimes.setCapacity(expList.size());
-
-    // Get each frame (metadata) and then the buffer. Calculate brightness.
-    for (size_t i = 0; i < expList.size(); ++i) {
-
-        ALOGV("Reading request %zu", i);
-        dout << "Waiting for capture " << i << ": " <<
-                " exposure " << (expList[i]/1e6f) << " ms," <<
-                " frame duration " << (durationList[i]/1e6f) << " ms," <<
-                " sensitivity " << sensitivityList[i] <<
-                std::endl;
-
-        // Set wait limit based on expected frame duration, or minimum timeout
-        int64_t waitLimit = CAMERA_FRAME_TIMEOUT;
-        if (expList[i] * 2 > waitLimit) waitLimit = expList[i] * 2;
-        if (durationList[i] * 2 > waitLimit) waitLimit = durationList[i] * 2;
-
-        ASSERT_EQ(OK, mDevice->waitForNextFrame(waitLimit));
-        ALOGV("Reading capture request-1 %zu", i);
-        CaptureResult result;
-        ASSERT_EQ(OK, mDevice->getNextResult(&result));
-        ALOGV("Reading capture request-2 %zu", i);
-
-        ASSERT_EQ(OK, mFrameListener->waitForFrame(CAMERA_FRAME_TIMEOUT));
-        ALOGV("We got the frame now");
-
-        captureTimes.push_back(systemTime());
-
-        CpuConsumer::LockedBuffer imgBuffer;
-        ASSERT_EQ(OK, mCpuConsumer->lockNextBuffer(&imgBuffer));
-
-        int underexposed, overexposed;
-        float avgBrightness = 0;
-        long long brightness = TotalBrightness(imgBuffer, &underexposed,
-                                               &overexposed);
-        int numValidPixels = mWidth * mHeight - (underexposed + overexposed);
-        if (numValidPixels != 0) {
-            avgBrightness = brightness * 1.0f / numValidPixels;
-        } else if (underexposed < overexposed) {
-            avgBrightness = 255;
-        }
-
-        ALOGV("Total brightness for frame %zu was %lld (underexposed %d, "
-              "overexposed %d), avg %f", i, brightness, underexposed,
-              overexposed, avgBrightness);
-        dout << "Average brightness (frame " << i << ") was " << avgBrightness
-             << " (underexposed " << underexposed << ", overexposed "
-             << overexposed << ")" << std::endl;
-        brightnesses.push_back(avgBrightness);
-
-        if (i != 0) {
-            float prevEv = static_cast<float>(expList[i - 1]) * sensitivityList[i - 1];
-            float currentEv = static_cast<float>(expList[i]) * sensitivityList[i];
-            float evRatio = (prevEv > currentEv) ? (currentEv / prevEv) :
-                    (prevEv / currentEv);
-            if ( evRatio > EV_MATCH_BOUND ) {
-                WARN_LT(fabs(brightnesses[i] - brightnesses[i - 1]),
-                        BRIGHTNESS_MATCH_BOUND) <<
-                        "Capture brightness different from previous, even though "
-                        "they have the same EV value. Ev now: " << currentEv <<
-                        ", previous: " << prevEv << ". Brightness now: " <<
-                        brightnesses[i] << ", previous: " << brightnesses[i-1] <<
-                        std::endl;
-            }
-            // Only check timing if not saving to disk, since that slows things
-            // down substantially
-            if (!dumpFrames) {
-                nsecs_t timeDelta = captureTimes[i] - captureTimes[i-1];
-                nsecs_t expectedDelta = expList[i] > durationList[i] ?
-                        expList[i] : durationList[i];
-                WARN_LT(timeDelta, expectedDelta + DURATION_UPPER_BOUND) <<
-                        "Capture took " << timeDelta << " ns to receive, but expected"
-                        " frame duration was " << expectedDelta << " ns." <<
-                        std::endl;
-                WARN_GT(timeDelta, expectedDelta - DURATION_LOWER_BOUND) <<
-                        "Capture took " << timeDelta << " ns to receive, but expected"
-                        " frame duration was " << expectedDelta << " ns." <<
-                        std::endl;
-                dout << "Time delta from previous frame: " << timeDelta / 1e6 <<
-                        " ms.  Expected " << expectedDelta / 1e6 << " ms" << std::endl;
-            }
-        }
-
-        if (dumpFrames) {
-            String8 dumpName =
-                    String8::format("/data/local/tmp/camera2_test_variable_burst_frame_%03zu.yuv", i);
-            dout << "  Writing YUV dump to " << dumpName << std::endl;
-            DumpYuvToFile(dumpName, imgBuffer);
-        }
-
-        ASSERT_EQ(OK, mCpuConsumer->unlockBuffer(imgBuffer));
-    }
-
-}
-
-}
-}
-}
diff --git a/tests/camera2/CameraFrameTests.cpp b/tests/camera2/CameraFrameTests.cpp
deleted file mode 100644
index 3c5abf7..0000000
--- a/tests/camera2/CameraFrameTests.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#include <gtest/gtest.h>
-
-#define LOG_TAG "CameraFrameTest"
-//#define LOG_NDEBUG 0
-#include <utils/Log.h>
-
-#include "hardware/hardware.h"
-#include "hardware/camera2.h"
-
-#include <common/CameraDeviceBase.h>
-#include <utils/StrongPointer.h>
-#include <gui/CpuConsumer.h>
-#include <gui/Surface.h>
-
-#include <unistd.h>
-
-#include "CameraStreamFixture.h"
-#include "TestExtensions.h"
-
-#define CAMERA_FRAME_TIMEOUT    1000000000 //nsecs (1 secs)
-#define CAMERA_HEAP_COUNT       2 //HALBUG: 1 means registerBuffers fails
-#define CAMERA_FRAME_DEBUGGING  0
-
-using namespace android;
-using namespace android::camera2;
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-static CameraStreamParams STREAM_PARAMETERS = {
-    /*mFormat*/     CAMERA_STREAM_AUTO_CPU_FORMAT,
-    /*mHeapCount*/  CAMERA_HEAP_COUNT
-};
-
-class CameraFrameTest
-    : public ::testing::TestWithParam<int>,
-      public CameraStreamFixture {
-
-public:
-    CameraFrameTest() : CameraStreamFixture(STREAM_PARAMETERS) {
-        TEST_EXTENSION_FORKING_CONSTRUCTOR;
-
-        if (!HasFatalFailure()) {
-            CreateStream();
-        }
-    }
-
-    ~CameraFrameTest() {
-        TEST_EXTENSION_FORKING_DESTRUCTOR;
-
-        if (mDevice.get()) {
-            mDevice->waitUntilDrained();
-        }
-    }
-
-    virtual void SetUp() {
-        TEST_EXTENSION_FORKING_SET_UP;
-    }
-    virtual void TearDown() {
-        TEST_EXTENSION_FORKING_TEAR_DOWN;
-    }
-
-protected:
-
-};
-
-TEST_P(CameraFrameTest, GetFrame) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    /* Submit a PREVIEW type request, then wait until we get the frame back */
-    CameraMetadata previewRequest;
-    ASSERT_EQ(OK, mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
-                                                &previewRequest));
-    {
-        Vector<int32_t> outputStreamIds;
-        outputStreamIds.push(mStreamId);
-        ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
-                                            outputStreamIds));
-        if (CAMERA_FRAME_DEBUGGING) {
-            int frameCount = 0;
-            ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_FRAME_COUNT,
-                                                &frameCount, 1));
-        }
-    }
-
-    if (CAMERA_FRAME_DEBUGGING) {
-        previewRequest.dump(STDOUT_FILENO);
-    }
-
-    for (int i = 0; i < GetParam(); ++i) {
-        ALOGV("Submitting capture request %d", i);
-        CameraMetadata tmpRequest = previewRequest;
-        ASSERT_EQ(OK, mDevice->capture(tmpRequest));
-    }
-
-    for (int i = 0; i < GetParam(); ++i) {
-        ALOGV("Reading capture request %d", i);
-        ASSERT_EQ(OK, mDevice->waitForNextFrame(CAMERA_FRAME_TIMEOUT));
-
-        CaptureResult result;
-        ASSERT_EQ(OK, mDevice->getNextResult(&result));
-
-        // wait for buffer to be available
-        ASSERT_EQ(OK, mFrameListener->waitForFrame(CAMERA_FRAME_TIMEOUT));
-        ALOGV("We got the frame now");
-
-        // mark buffer consumed so producer can re-dequeue it
-        CpuConsumer::LockedBuffer imgBuffer;
-        ASSERT_EQ(OK, mCpuConsumer->lockNextBuffer(&imgBuffer));
-        ASSERT_EQ(OK, mCpuConsumer->unlockBuffer(imgBuffer));
-    }
-
-}
-
-//FIXME: dont hardcode stream params, and also test multistream
-INSTANTIATE_TEST_CASE_P(FrameParameterCombinations, CameraFrameTest,
-    testing::Range(1, 10));
-
-
-}
-}
-}
diff --git a/tests/camera2/CameraMetadataTests.cpp b/tests/camera2/CameraMetadataTests.cpp
deleted file mode 100644
index da5b748..0000000
--- a/tests/camera2/CameraMetadataTests.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#define LOG_NDEBUG 0
-#define LOG_TAG "CameraMetadataTestFunctional"
-#include "cutils/log.h"
-#include "cutils/properties.h"
-#include "utils/Errors.h"
-
-#include "gtest/gtest.h"
-#include "system/camera_metadata.h"
-#include "hardware/hardware.h"
-#include "hardware/camera2.h"
-
-#include "common/CameraDeviceBase.h"
-#include "utils/StrongPointer.h"
-
-#include <gui/CpuConsumer.h>
-#include <gui/Surface.h>
-
-#include <string>
-
-#include "CameraStreamFixture.h"
-#include "TestExtensions.h"
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-//FIXME: dont hardcode
-static CameraStreamParams METADATA_STREAM_PARAMETERS = {
-    /*mFormat*/     HAL_PIXEL_FORMAT_YCrCb_420_SP,
-    /*mHeapCount*/  2
-};
-
-class CameraMetadataTest
-    : public ::testing::Test,
-      public CameraStreamFixture {
-
-public:
-    CameraMetadataTest()
-    : CameraStreamFixture(METADATA_STREAM_PARAMETERS) {
-        TEST_EXTENSION_FORKING_CONSTRUCTOR;
-    }
-
-    ~CameraMetadataTest() {
-        TEST_EXTENSION_FORKING_DESTRUCTOR;
-    }
-
-    int GetTypeFromTag(uint32_t tag) const {
-        return get_camera_metadata_tag_type(tag);
-    }
-
-    int GetTypeFromStaticTag(uint32_t tag) const {
-        const CameraMetadata& staticInfo = mDevice->info();
-        camera_metadata_ro_entry entry = staticInfo.find(tag);
-        return entry.type;
-    }
-
-    int GetEntryCountFromStaticTag(uint32_t tag) const {
-        const CameraMetadata& staticInfo = mDevice->info();
-        camera_metadata_ro_entry entry = staticInfo.find(tag);
-        return entry.count;
-    }
-
-    bool HasElementInArrayFromStaticTag(uint32_t tag, int32_t element) const {
-        const CameraMetadata& staticInfo = mDevice->info();
-        camera_metadata_ro_entry entry = staticInfo.find(tag);
-        for (size_t i = 0; i < entry.count; ++i) {
-            if (entry.data.i32[i] == element)
-                return true;
-        }
-        return false;
-    }
-
-protected:
-
-};
-
-TEST_F(CameraMetadataTest, types) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    //FIXME: set this up in an external file of some sort (xml?)
-    {
-        char value[PROPERTY_VALUE_MAX];
-        property_get("ro.build.id", value, "");
-        std::string str_value(value);
-
-        if (str_value == "manta")
-        {
-            EXPECT_EQ(TYPE_BYTE,
-                GetTypeFromStaticTag(ANDROID_QUIRKS_TRIGGER_AF_WITH_AUTO));
-            EXPECT_EQ(TYPE_BYTE,
-                GetTypeFromStaticTag(ANDROID_QUIRKS_USE_ZSL_FORMAT));
-            EXPECT_EQ(TYPE_BYTE,
-                GetTypeFromStaticTag(ANDROID_QUIRKS_METERING_CROP_REGION));
-        }
-    }
-
-    /*
-    TODO:
-    go through all static metadata and make sure all fields we expect
-    that are there, ARE there.
-
-    dont worry about the type as its enforced by the metadata api
-    we can probably check the range validity though
-    */
-
-    if (0) {
-        camera_metadata_ro_entry entry;
-        EXPECT_EQ(TYPE_BYTE,     entry.type);
-        EXPECT_EQ(TYPE_INT32,    entry.type);
-        EXPECT_EQ(TYPE_FLOAT,    entry.type);
-        EXPECT_EQ(TYPE_INT64,    entry.type);
-        EXPECT_EQ(TYPE_DOUBLE,   entry.type);
-        EXPECT_EQ(TYPE_RATIONAL, entry.type);
-    }
-}
-
-TEST_F(CameraMetadataTest, RequiredFormats) {
-    TEST_EXTENSION_FORKING_INIT;
-
-    EXPECT_TRUE(
-        HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
-                                       HAL_PIXEL_FORMAT_BLOB)); // JPEG
-
-    if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_0) {
-        // HAL2 can support either flexible YUV or YV12 + NV21
-        if (!HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
-                        HAL_PIXEL_FORMAT_YCbCr_420_888)) {
-
-            EXPECT_TRUE(
-                HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
-                        HAL_PIXEL_FORMAT_YCrCb_420_SP)); // NV21
-
-            EXPECT_TRUE(
-                HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
-                        HAL_PIXEL_FORMAT_YV12));
-        }
-    } else {
-        // HAL3 must support flexible YUV
-        EXPECT_TRUE(HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
-                        HAL_PIXEL_FORMAT_YCbCr_420_888));
-    }
-
-}
-
-TEST_F(CameraMetadataTest, SaneResolutions) {
-    TEST_EXTENSION_FORKING_INIT;
-
-    if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
-        // Iff there are listed raw resolutions, the format should be available
-        int rawResolutionsCount =
-                GetEntryCountFromStaticTag(ANDROID_SCALER_AVAILABLE_RAW_SIZES);
-        if (rawResolutionsCount > 0) {
-            EXPECT_TRUE(
-                HasElementInArrayFromStaticTag(ANDROID_SCALER_AVAILABLE_FORMATS,
-                        HAL_PIXEL_FORMAT_RAW16));
-        }
-
-        // Required processed sizes.
-        int processedSizeCount =
-               GetEntryCountFromStaticTag(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
-        EXPECT_NE(0, processedSizeCount);
-        EXPECT_EQ(0, processedSizeCount % 2); // multiple of 2 (w,h)
-
-        // Required JPEG sizes
-        int jpegSizeCount =
-                GetEntryCountFromStaticTag(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
-        EXPECT_NE(0, jpegSizeCount);
-        EXPECT_EQ(0, jpegSizeCount % 2); // multiple of 2 (w,h)
-    } else {
-        int strmConfigCount =
-                GetEntryCountFromStaticTag(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
-        EXPECT_NE(0, strmConfigCount);
-        EXPECT_EQ(0, strmConfigCount % 4); // multiple of 4 (format,w,h,output?)
-    }
-
-}
-
-}
-}
-}
diff --git a/tests/camera2/CameraModuleFixture.h b/tests/camera2/CameraModuleFixture.h
deleted file mode 100644
index b0d49e2..0000000
--- a/tests/camera2/CameraModuleFixture.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2012 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_HAL_CAMERA2_TESTS_MODULE_FIXTURE__
-#define __ANDROID_HAL_CAMERA2_TESTS_MODULE_FIXTURE__
-
-#include <gtest/gtest.h>
-
-#include "hardware/hardware.h"
-#include "hardware/camera2.h"
-
-#include <common/CameraModule.h>
-#include <device3/Camera3Device.h>
-
-#include "camera2_utils.h"
-#include "TestExtensions.h"
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-template <bool InfoQuirk = false>
-struct CameraModuleFixture {
-
-    explicit CameraModuleFixture(int CameraID = -1) {
-        TEST_EXTENSION_FORKING_CONSTRUCTOR;
-
-        mCameraID = CameraID;
-    }
-
-    ~CameraModuleFixture() {
-        TEST_EXTENSION_FORKING_DESTRUCTOR;
-    }
-
-    camera_metadata_ro_entry GetStaticEntry(uint32_t tag) const {
-        const CameraMetadata& staticInfo = mDevice->info();
-        camera_metadata_ro_entry entry = staticInfo.find(tag);
-        return entry;
-    }
-
-    void SetUp() {
-        TEST_EXTENSION_FORKING_SET_UP;
-
-        camera_module_t *rawModule;
-        ASSERT_LE(0, hw_get_module(CAMERA_HARDWARE_MODULE_ID,
-            (const hw_module_t **)&rawModule)) << "Could not load camera module";
-        ASSERT_NE((void*)0, rawModule);
-        mModule = new CameraModule(rawModule);
-
-        mNumberOfCameras = mModule->getNumberOfCameras();
-        ASSERT_LE(0, mNumberOfCameras);
-
-        ASSERT_LE(
-            CAMERA_MODULE_API_VERSION_2_0, mModule->getModuleApiVersion())
-            << "Wrong module API version";
-
-        /* For using this fixture in other tests only */
-        SetUpMixin();
-    }
-
-    void TearDown() {
-        TEST_EXTENSION_FORKING_TEAR_DOWN;
-
-        TearDownMixin();
-
-        /* important: device must be destructed before closing module,
-           since it calls back into HAL */
-        mDevice.clear();
-
-        if (!TEST_EXTENSION_FORKING_ENABLED) {
-            ASSERT_EQ(0, HWModuleHelpers::closeModule(mModule->getDso()))
-                << "Failed to close camera HAL module";
-        }
-        delete mModule;
-    }
-
-    void CreateCamera(int cameraID, /*out*/ sp<CameraDeviceBase> *device) {
-        struct camera_info info;
-        ASSERT_EQ(OK, mModule->getCameraInfo(cameraID, &info));
-
-        ASSERT_GE((int)info.device_version, CAMERA_DEVICE_API_VERSION_3_0) <<
-                "Device version too old for camera " << cameraID << ". Version: " <<
-                info.device_version;
-        switch(info.device_version) {
-            case CAMERA_DEVICE_API_VERSION_3_0:
-            case CAMERA_DEVICE_API_VERSION_3_1:
-            case CAMERA_DEVICE_API_VERSION_3_2:
-                *device = new Camera3Device(String8::format("%d", cameraID));
-                break;
-            default:
-                device->clear();
-                FAIL() << "Device version unknown for camera " << cameraID << ". Version: " <<
-                       info.device_version;
-        }
-
-    }
-
-    int getDeviceVersion() {
-        return getDeviceVersion(mCameraID);
-    }
-
-    int getDeviceVersion(int cameraId, status_t* status = NULL) {
-        camera_info info;
-        status_t res;
-        res = mModule->getCameraInfo(cameraId, &info);
-        if (status != NULL) *status = res;
-
-        return info.device_version;
-    }
-
-private:
-
-    void SetUpMixin() {
-        /* For using this fixture in other tests only */
-        if (mCameraID != -1) {
-            EXPECT_LE(0, mCameraID);
-            EXPECT_LT(mCameraID, mNumberOfCameras);
-
-            /* HALBUG (Exynos5); crashes if we skip calling get_camera_info
-               before initializing. Need info anyway now. */
-
-            CreateCamera(mCameraID, &mDevice);
-
-            ASSERT_TRUE(mDevice != NULL) << "Failed to open device " << mCameraID;
-            ASSERT_EQ(OK, mDevice->initialize(mModule))
-                << "Failed to initialize device " << mCameraID;
-        }
-    }
-
-    void TearDownMixin() {
-
-    }
-
-protected:
-    int mNumberOfCameras;
-    CameraModule *mModule;
-    sp<CameraDeviceBase> mDevice;
-
-private:
-    int mCameraID;
-};
-
-
-}
-}
-}
-
-#endif
diff --git a/tests/camera2/CameraModuleTests.cpp b/tests/camera2/CameraModuleTests.cpp
deleted file mode 100644
index 2b6c757..0000000
--- a/tests/camera2/CameraModuleTests.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#include <gtest/gtest.h>
-
-#define LOG_TAG "CameraModuleTest"
-#define LOG_NDEBUG 0
-#include <utils/Log.h>
-#include <utils/StrongPointer.h>
-#include <common/CameraDeviceBase.h>
-
-#include "hardware/hardware.h"
-#include "hardware/camera2.h"
-
-#include "CameraModuleFixture.h"
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-class CameraModuleTest : public ::testing::Test,
-                                  public CameraModuleFixture<> {
-
-public:
-    CameraModuleTest() {
-        CameraModuleFixture::SetUp();
-    }
-
-    ~CameraModuleTest() {
-        CameraModuleFixture::TearDown();
-    }
-
-    status_t initializeDevice(int cameraId) {
-
-        // ignore HAL1s. count as test pass
-        status_t stat;
-        if (isDeviceVersionHal2(cameraId, &stat) && stat == OK) {
-            stat = mDevice->initialize(mModule);
-        }
-
-        return stat;
-    }
-
-    bool isDeviceVersionHal2(int cameraId, status_t* status) {
-        return getDeviceVersion(cameraId, status)
-               >= CAMERA_DEVICE_API_VERSION_2_0;
-    }
-};
-
-TEST_F(CameraModuleTest, LoadModule) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    status_t stat;
-    for (int i = 0; i < mNumberOfCameras; ++i) {
-        if (isDeviceVersionHal2(i, &stat) && stat == OK) {
-            CreateCamera(i, &mDevice);
-            ASSERT_EQ(OK, initializeDevice(i))
-                << "Failed to initialize device " << i;
-            mDevice.clear();
-        } else {
-            const ::testing::TestInfo* const test_info =
-                ::testing::UnitTest::GetInstance()->current_test_info();
-            std::cerr << "Skipping test "
-                      << test_info->test_case_name() << "."
-                      << test_info->name()
-                      << " because HAL device version is V1"
-                      << std::endl;
-        }
-    }
-
-}
-
-TEST_F(CameraModuleTest, LoadModuleBadIndices) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    int idx[] = { -1, mNumberOfCameras, mNumberOfCameras + 1 };
-    hw_device_t *device = NULL;
-
-    for (unsigned i = 0; i < sizeof(idx)/sizeof(idx[0]); ++i) {
-        String8 deviceName = String8::format("%d", idx[i]);
-        status_t res = mModule->open(deviceName, &device);
-        EXPECT_NE(OK, res);
-        EXPECT_EQ(-ENODEV, res)
-            << "Incorrect error code when trying to open camera with invalid id "
-            << deviceName;
-    }
-}
-
-TEST_F(CameraModuleTest, GetCameraInfo) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    for (int i = 0; i < mNumberOfCameras; ++i) {
-        struct camera_info info;
-        ASSERT_EQ(OK, mModule->getCameraInfo(i, &info));
-    }
-
-}
-
-TEST_F(CameraModuleTest, GetCameraInfoBadIndices) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    int idx[] = { -1, mNumberOfCameras, mNumberOfCameras + 1 };
-    for (unsigned i = 0; i < sizeof(idx)/sizeof(idx[0]); ++i) {
-        struct camera_info info;
-        EXPECT_NE(OK, mModule->getCameraInfo(idx[i], &info));
-        EXPECT_EQ(-EINVAL, mModule->getCameraInfo(idx[i], &info))
-            << "Incorrect error code for get_camera_info idx= "
-            << idx[i];
-    }
-}
-
-/**
- * TODO: Additional test to add: open two cameras at once.
- *       (is allowed to fail, at least for now, but should not blow up)
- *     - open same device multiple times
- *     - close same device multiple times
- */
-
-
-
-
-}
-}
-}
diff --git a/tests/camera2/CameraMultiStreamTests.cpp b/tests/camera2/CameraMultiStreamTests.cpp
deleted file mode 100644
index f4aeab7..0000000
--- a/tests/camera2/CameraMultiStreamTests.cpp
+++ /dev/null
@@ -1,713 +0,0 @@
-/*
- * 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.
- */
-
-#include <inttypes.h>
-#define LOG_TAG "CameraMultiStreamTest"
-//#define LOG_NDEBUG 0
-#include "CameraStreamFixture.h"
-#include "TestExtensions.h"
-
-#include <gtest/gtest.h>
-#include <utils/Log.h>
-#include <utils/StrongPointer.h>
-#include <common/CameraDeviceBase.h>
-#include <hardware/hardware.h>
-#include <hardware/camera2.h>
-#include <gui/SurfaceComposerClient.h>
-#include <gui/Surface.h>
-
-#define DEFAULT_FRAME_DURATION 33000000LL // 33ms
-#define CAMERA_HEAP_COUNT       1
-#define CAMERA_EXPOSURE_FORMAT CAMERA_STREAM_AUTO_CPU_FORMAT
-#define CAMERA_DISPLAY_FORMAT HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED
-#define CAMERA_MULTI_STREAM_DEBUGGING  0
-#define CAMERA_FRAME_TIMEOUT    1000000000LL // nsecs (1 secs)
-#define PREVIEW_RENDERING_TIME_INTERVAL 200000 // in unit of us, 200ms
-// 1% tolerance margin for exposure sanity check against metadata
-#define TOLERANCE_MARGIN_METADATA 0.01
-// 5% tolerance margin for exposure sanity check against capture times
-#define TOLERANCE_MARGIN_CAPTURE 0.05
-/* constants for display */
-#define DISPLAY_BUFFER_HEIGHT 1024
-#define DISPLAY_BUFFER_WIDTH 1024
-#define DISPLAY_BUFFER_FORMAT PIXEL_FORMAT_RGB_888
-
-// This test intends to test large preview size but less than 1080p.
-#define PREVIEW_WIDTH_CAP   1920
-#define PREVIEW_HEIGHT_CAP  1080
-// This test intends to test small metering burst size that is less than 640x480
-#define METERING_WIDTH_CAP  640
-#define METERING_HEIGHT_CAP 480
-
-#define EXP_WAIT_MULTIPLIER 2
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-static const CameraStreamParams DEFAULT_STREAM_PARAMETERS = {
-    /*mFormat*/     CAMERA_EXPOSURE_FORMAT,
-    /*mHeapCount*/  CAMERA_HEAP_COUNT
-};
-
-static const CameraStreamParams DISPLAY_STREAM_PARAMETERS = {
-    /*mFormat*/     CAMERA_DISPLAY_FORMAT,
-    /*mHeapCount*/  CAMERA_HEAP_COUNT
-};
-
-class CameraMultiStreamTest
-    : public ::testing::Test,
-      public CameraStreamFixture {
-
-public:
-    CameraMultiStreamTest() : CameraStreamFixture(DEFAULT_STREAM_PARAMETERS) {
-        TEST_EXTENSION_FORKING_CONSTRUCTOR;
-
-        if (HasFatalFailure()) {
-            return;
-        }
-        /**
-         * Don't create default stream, each test is in charge of creating
-         * its own streams.
-         */
-    }
-
-    ~CameraMultiStreamTest() {
-        TEST_EXTENSION_FORKING_DESTRUCTOR;
-    }
-
-    sp<SurfaceComposerClient> mComposerClient;
-    sp<SurfaceControl> mSurfaceControl;
-
-    void CreateOnScreenSurface(sp<Surface>& surface) {
-        mComposerClient = new SurfaceComposerClient;
-        ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
-
-        mSurfaceControl = mComposerClient->createSurface(
-                String8("CameraMultiStreamTest StreamingImage Surface"),
-                DISPLAY_BUFFER_HEIGHT, DISPLAY_BUFFER_WIDTH,
-                DISPLAY_BUFFER_FORMAT, 0);
-
-        ASSERT_NE((void*)NULL, mSurfaceControl.get());
-        ASSERT_TRUE(mSurfaceControl->isValid());
-
-        SurfaceComposerClient::openGlobalTransaction();
-        ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
-        ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
-        SurfaceComposerClient::closeGlobalTransaction();
-
-        surface = mSurfaceControl->getSurface();
-
-        ASSERT_NE((void*)NULL, surface.get());
-    }
-
-    struct Size {
-        int32_t width;
-        int32_t height;
-    };
-
-    // Select minimal size by number of pixels.
-    void GetMinSize(const int32_t* data, size_t count,
-            Size* min, int32_t* idx) {
-        ASSERT_NE((int32_t*)NULL, data);
-        int32_t minIdx = 0;
-        int32_t minSize = INT_MAX, tempSize;
-        for (size_t i = 0; i < count; i+=2) {
-            tempSize = data[i] * data[i+1];
-            if (minSize > tempSize) {
-                minSize = tempSize;
-                minIdx = i;
-            }
-        }
-        min->width = data[minIdx];
-        min->height = data[minIdx + 1];
-        *idx = minIdx;
-    }
-
-    // Select maximal size by number of pixels.
-    void GetMaxSize(const int32_t* data, size_t count,
-            Size* max, int32_t* idx) {
-        ASSERT_NE((int32_t*)NULL, data);
-        int32_t maxIdx = 0;
-        int32_t maxSize = INT_MIN, tempSize;
-        for (size_t i = 0; i < count; i+=2) {
-            tempSize = data[i] * data[i+1];
-            if (maxSize < tempSize) {
-                maxSize = tempSize;
-                maxIdx = i;
-            }
-        }
-        max->width = data[maxIdx];
-        max->height = data[maxIdx + 1];
-        *idx = maxIdx;
-    }
-
-    // Cap size by number of pixels.
-    Size CapSize(Size cap, Size input) {
-        if (input.width * input.height > cap.width * cap.height) {
-            return cap;
-        }
-        return input;
-    }
-
-    struct CameraStream : public RefBase {
-
-    public:
-        /**
-         * Only initialize the variables here, do the ASSERT check in
-         * SetUp function. To make this stream useful, the SetUp must
-         * be called before using it.
-         */
-        CameraStream(
-                int width,
-                int height,
-                const sp<CameraDeviceBase>& device,
-                CameraStreamParams param, sp<Surface> surface,
-                bool useCpuConsumer)
-            : mDevice(device),
-              mWidth(width),
-              mHeight(height) {
-            mFormat = param.mFormat;
-            if (useCpuConsumer) {
-                sp<IGraphicBufferProducer> producer;
-                sp<IGraphicBufferConsumer> consumer;
-                BufferQueue::createBufferQueue(&producer, &consumer);
-                mCpuConsumer = new CpuConsumer(consumer, param.mHeapCount);
-                mCpuConsumer->setName(String8(
-                        "CameraMultiStreamTest::mCpuConsumer"));
-                mSurface = new Surface(producer);
-            } else {
-                // Render the stream to screen.
-                mCpuConsumer = NULL;
-                mSurface = surface;
-            }
-
-            mFrameListener = new FrameListener();
-            if (mCpuConsumer != 0) {
-                mCpuConsumer->setFrameAvailableListener(mFrameListener);
-            }
-        }
-
-        /**
-         * Finally create camera stream, and do the ASSERT check, since we
-         * can not do it in ctor.
-         */
-        void SetUp() {
-            ASSERT_EQ(OK,
-                mDevice->createStream(mSurface,
-                    mWidth, mHeight, mFormat, HAL_DATASPACE_UNKNOWN,
-                    CAMERA3_STREAM_ROTATION_0, &mStreamId));
-
-            ASSERT_NE(-1, mStreamId);
-        }
-
-        int GetStreamId() { return mStreamId; }
-        sp<CpuConsumer> GetConsumer() { return mCpuConsumer; }
-        sp<FrameListener> GetFrameListener() { return mFrameListener; }
-
-    protected:
-        ~CameraStream() {
-            if (mDevice.get()) {
-                mDevice->waitUntilDrained();
-                mDevice->deleteStream(mStreamId);
-            }
-            // Clear producer before consumer.
-            mSurface.clear();
-            mCpuConsumer.clear();
-        }
-
-    private:
-        sp<FrameListener>       mFrameListener;
-        sp<CpuConsumer>         mCpuConsumer;
-        sp<Surface>             mSurface;
-        sp<CameraDeviceBase>    mDevice;
-        int                     mStreamId;
-        int                     mWidth;
-        int                     mHeight;
-        int                     mFormat;
-    };
-
-    int64_t GetExposureValue(const CameraMetadata& metaData) {
-        camera_metadata_ro_entry_t entry =
-                metaData.find(ANDROID_SENSOR_EXPOSURE_TIME);
-        EXPECT_EQ(1u, entry.count);
-        if (entry.count == 1) {
-            return entry.data.i64[0];
-        }
-        return -1;
-    }
-
-    int32_t GetSensitivity(const CameraMetadata& metaData) {
-        camera_metadata_ro_entry_t entry =
-                metaData.find(ANDROID_SENSOR_SENSITIVITY);
-        EXPECT_EQ(1u, entry.count);
-        if (entry.count == 1) {
-            return entry.data.i32[0];
-        }
-        return -1;
-    }
-
-    int64_t GetFrameDuration(const CameraMetadata& metaData) {
-        camera_metadata_ro_entry_t entry =
-                metaData.find(ANDROID_SENSOR_FRAME_DURATION);
-        EXPECT_EQ(1u, entry.count);
-        if (entry.count == 1) {
-            return entry.data.i64[0];
-        }
-        return -1;
-    }
-
-    void CreateRequests(CameraMetadata& previewRequest,
-            CameraMetadata& meteringRequest,
-            CameraMetadata& captureRequest,
-            int previewStreamId,
-            int meteringStreamId,
-            int captureStreamId) {
-        int32_t requestId = 0;
-        Vector<int32_t> previewStreamIds;
-        previewStreamIds.push(previewStreamId);
-        ASSERT_EQ(OK, mDevice->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
-                &previewRequest));
-        ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_OUTPUT_STREAMS,
-                previewStreamIds));
-        ASSERT_EQ(OK, previewRequest.update(ANDROID_REQUEST_ID,
-                &requestId, 1));
-
-        // Create metering request, manual settings
-        // Manual control: Disable 3A, noise reduction, edge sharping
-        uint8_t cmOff = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
-        uint8_t nrOff = static_cast<uint8_t>(ANDROID_NOISE_REDUCTION_MODE_OFF);
-        uint8_t sharpOff = static_cast<uint8_t>(ANDROID_EDGE_MODE_OFF);
-        Vector<int32_t> meteringStreamIds;
-        meteringStreamIds.push(meteringStreamId);
-        ASSERT_EQ(OK, mDevice->createDefaultRequest(
-                CAMERA2_TEMPLATE_PREVIEW,
-                &meteringRequest));
-        ASSERT_EQ(OK, meteringRequest.update(
-                ANDROID_REQUEST_OUTPUT_STREAMS,
-                meteringStreamIds));
-        ASSERT_EQ(OK, meteringRequest.update(
-                ANDROID_CONTROL_MODE,
-                &cmOff, 1));
-        ASSERT_EQ(OK, meteringRequest.update(
-                ANDROID_NOISE_REDUCTION_MODE,
-                &nrOff, 1));
-        ASSERT_EQ(OK, meteringRequest.update(
-                ANDROID_EDGE_MODE,
-                &sharpOff, 1));
-
-        // Create capture request, manual settings
-        Vector<int32_t> captureStreamIds;
-        captureStreamIds.push(captureStreamId);
-        ASSERT_EQ(OK, mDevice->createDefaultRequest(
-                CAMERA2_TEMPLATE_PREVIEW,
-                &captureRequest));
-        ASSERT_EQ(OK, captureRequest.update(
-                ANDROID_REQUEST_OUTPUT_STREAMS,
-                captureStreamIds));
-        ASSERT_EQ(OK, captureRequest.update(
-                ANDROID_CONTROL_MODE,
-                &cmOff, 1));
-        ASSERT_EQ(OK, captureRequest.update(
-                ANDROID_NOISE_REDUCTION_MODE,
-                &nrOff, 1));
-        ASSERT_EQ(OK, captureRequest.update(
-                ANDROID_EDGE_MODE,
-                &sharpOff, 1));
-    }
-
-    sp<CameraStream> CreateStream(
-            int width,
-            int height,
-            const sp<CameraDeviceBase>& device,
-            CameraStreamParams param = DEFAULT_STREAM_PARAMETERS,
-            const sp<Surface>& surface = NULL,
-            bool useCpuConsumer = true) {
-        param.mFormat = MapAutoFormat(param.mFormat);
-        return new CameraStream(width, height, device,
-                param, surface, useCpuConsumer);
-    }
-
-    void CaptureBurst(CameraMetadata& request, size_t requestCount,
-            const Vector<int64_t>& exposures,
-            const Vector<int32_t>& sensitivities,
-            const sp<CameraStream>& stream,
-            int64_t minFrameDuration,
-            int32_t* requestIdStart) {
-        ASSERT_EQ(OK, request.update(ANDROID_SENSOR_FRAME_DURATION,
-                &minFrameDuration, 1));
-        // Submit a series of requests with the specified exposure/gain values.
-        int32_t targetRequestId = *requestIdStart;
-        for (size_t i = 0; i < requestCount; i++) {
-            ASSERT_EQ(OK, request.update(ANDROID_REQUEST_ID, requestIdStart, 1));
-            ASSERT_EQ(OK, request.update(ANDROID_SENSOR_EXPOSURE_TIME, &exposures[i], 1));
-            ASSERT_EQ(OK, request.update(ANDROID_SENSOR_SENSITIVITY, &sensitivities[i], 1));
-            ASSERT_EQ(OK, mDevice->capture(request));
-            ALOGV("Submitting request with: id %d with exposure %" PRId64 ", sensitivity %d",
-                    *requestIdStart, exposures[i], sensitivities[i]);
-            if (CAMERA_MULTI_STREAM_DEBUGGING) {
-                request.dump(STDOUT_FILENO);
-            }
-            (*requestIdStart)++;
-        }
-        // Get capture burst results.
-        Vector<nsecs_t> captureBurstTimes;
-        sp<CpuConsumer> consumer = stream->GetConsumer();
-        sp<FrameListener> listener = stream->GetFrameListener();
-
-        // Set wait limit based on expected frame duration.
-        int64_t waitLimit = CAMERA_FRAME_TIMEOUT;
-        for (size_t i = 0; i < requestCount; i++) {
-            ALOGV("Reading request result %zu", i);
-
-            /**
-             * Raise the timeout to be at least twice as long as the exposure
-             * time. to avoid a false positive when the timeout is too short.
-             */
-            if ((exposures[i] * EXP_WAIT_MULTIPLIER) > waitLimit) {
-                waitLimit = exposures[i] * EXP_WAIT_MULTIPLIER;
-            }
-
-            CaptureResult result;
-            CameraMetadata frameMetadata;
-            int32_t resultRequestId;
-            do {
-                ASSERT_EQ(OK, mDevice->waitForNextFrame(waitLimit));
-                ASSERT_EQ(OK, mDevice->getNextResult(&result));
-                frameMetadata = result.mMetadata;
-
-                camera_metadata_entry_t resultEntry = frameMetadata.find(ANDROID_REQUEST_ID);
-                ASSERT_EQ(1u, resultEntry.count);
-                resultRequestId = resultEntry.data.i32[0];
-                if (CAMERA_MULTI_STREAM_DEBUGGING) {
-                    std::cout << "capture result req id: " << resultRequestId << std::endl;
-                }
-            } while (resultRequestId != targetRequestId);
-            targetRequestId++;
-            ALOGV("Got capture burst result for request %zu", i);
-
-            // Validate capture result
-            if (CAMERA_MULTI_STREAM_DEBUGGING) {
-                frameMetadata.dump(STDOUT_FILENO);
-            }
-
-            // TODO: Need revisit it to figure out an accurate margin.
-            int64_t resultExposure = GetExposureValue(frameMetadata);
-            int32_t resultSensitivity = GetSensitivity(frameMetadata);
-            EXPECT_LE(sensitivities[i] * (1.0 - TOLERANCE_MARGIN_METADATA), resultSensitivity);
-            EXPECT_GE(sensitivities[i] * (1.0 + TOLERANCE_MARGIN_METADATA), resultSensitivity);
-            EXPECT_LE(exposures[i] * (1.0 - TOLERANCE_MARGIN_METADATA), resultExposure);
-            EXPECT_GE(exposures[i] * (1.0 + TOLERANCE_MARGIN_METADATA), resultExposure);
-
-            ASSERT_EQ(OK, listener->waitForFrame(waitLimit));
-            captureBurstTimes.push_back(systemTime());
-            CpuConsumer::LockedBuffer imgBuffer;
-            ASSERT_EQ(OK, consumer->lockNextBuffer(&imgBuffer));
-            ALOGV("Got capture buffer for request %zu", i);
-
-            /**
-             * TODO: Validate capture buffer. Current brightness calculation
-             * is too slow, it also doesn't account for saturation effects,
-             * which is quite common since we are going over a significant
-             * range of EVs. we need figure out some reliable way to validate
-             * buffer data.
-             */
-
-            ASSERT_EQ(OK, consumer->unlockBuffer(imgBuffer));
-            if (i > 0) {
-                nsecs_t timeDelta =
-                        captureBurstTimes[i] - captureBurstTimes[i-1];
-                EXPECT_GE(timeDelta * ( 1 + TOLERANCE_MARGIN_CAPTURE), exposures[i]);
-            }
-        }
-    }
-
-    /**
-     * Intentionally shadow default CreateStream function from base class,
-     * because we don't want any test in this class to use the default
-     * stream creation function.
-     */
-    void CreateStream() {
-    }
-};
-
-/**
- * This test adds multiple stream use case test, basically, test 3
- * streams:
- *
- * 1. Preview stream, with large size that is no bigger than 1080p
- * we render this stream to display and vary the exposure time for
- * for certain amount of time for visualization purpose.
- *
- * 2. Metering stream, with small size that is no bigger than VGA size.
- * a burst is issued for different exposure times and analog gains
- * (or analog gain implemented sensitivities) then check if the capture
- * result metadata matches the request.
- *
- * 3. Capture stream, this is basically similar as meterting stream, but
- * has large size, which is the largest supported JPEG capture size.
- *
- * This multiple stream test is to test if HAL supports:
- *
- * 1. Multiple streams like above, HAL should support at least 3 streams
- * concurrently: one preview stream, 2 other YUV stream.
- *
- * 2. Manual control(gain/exposure) of mutiple burst capture.
- */
-// Disable this test for now, as we need cleanup the usage of the deprecated tag quite a bit.
-TEST_F(CameraMultiStreamTest, DISABLED_MultiBurst) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    const int32_t* implDefData;
-    size_t implDefCount;
-    const int32_t* jpegData;
-    size_t jpegCount;
-    if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
-        camera_metadata_ro_entry availableProcessedSizes =
-            GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES);
-        ASSERT_EQ(0u, availableProcessedSizes.count % 2);
-        ASSERT_GE(availableProcessedSizes.count, 2u);
-        camera_metadata_ro_entry availableProcessedMinFrameDurations =
-            GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS);
-        EXPECT_EQ(availableProcessedSizes.count,
-            availableProcessedMinFrameDurations.count * 2);
-
-        camera_metadata_ro_entry availableJpegSizes =
-            GetStaticEntry(ANDROID_SCALER_AVAILABLE_JPEG_SIZES);
-        ASSERT_EQ(0u, availableJpegSizes.count % 2);
-        ASSERT_GE(availableJpegSizes.count, 2u);
-        implDefData = availableProcessedSizes.data.i32;
-        implDefCount = availableProcessedSizes.count;
-        jpegData = availableJpegSizes.data.i32;
-        jpegCount = availableJpegSizes.count;
-    } else {
-        getResolutionList(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, &implDefData, &implDefCount);
-        ASSERT_NE(0u, implDefCount)
-            << "Missing implementation defined sizes";
-        ASSERT_EQ(0u, implDefCount % 2);
-        ASSERT_GE(implDefCount, 2u);
-
-        getResolutionList(HAL_PIXEL_FORMAT_BLOB, &jpegData, &jpegCount);
-        ASSERT_EQ(0u, jpegCount % 2);
-        ASSERT_GE(jpegCount, 2u);
-    }
-
-    camera_metadata_ro_entry hardwareLevel =
-        GetStaticEntry(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL);
-    ASSERT_EQ(1u, hardwareLevel.count);
-    uint8_t level = hardwareLevel.data.u8[0];
-    ASSERT_GE(level, ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED);
-    ASSERT_LE(level, ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL);
-    if (level == ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED) {
-        const ::testing::TestInfo* const test_info =
-            ::testing::UnitTest::GetInstance()->current_test_info();
-        std::cerr << "Skipping test "
-                  << test_info->test_case_name() << "."
-                  << test_info->name()
-                  << " because HAL hardware supported level is limited "
-                  << std::endl;
-        return;
-    }
-
-    // Find the right sizes for preview, metering, and capture streams
-    int64_t minFrameDuration = DEFAULT_FRAME_DURATION;
-    Size processedMinSize = {0, 0}, processedMaxSize = {0, 0};
-    Size jpegMaxSize = {0, 0};
-
-    int32_t minIdx, maxIdx;
-    GetMinSize(implDefData, implDefCount, &processedMinSize, &minIdx);
-    GetMaxSize(implDefData, implDefCount, &processedMaxSize, &maxIdx);
-    ALOGV("Found processed max size: %dx%d, min size = %dx%d",
-            processedMaxSize.width, processedMaxSize.height,
-            processedMinSize.width, processedMinSize.height);
-
-    if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
-        camera_metadata_ro_entry availableProcessedMinFrameDurations =
-            GetStaticEntry(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS);
-        minFrameDuration =
-            availableProcessedMinFrameDurations.data.i64[maxIdx / 2];
-    } else {
-        minFrameDuration = getMinFrameDurationFor(
-                HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
-                processedMaxSize.width, processedMaxSize.height);
-    }
-
-    EXPECT_GT(minFrameDuration, 0);
-
-    if (minFrameDuration <= 0) {
-        minFrameDuration = DEFAULT_FRAME_DURATION;
-    }
-
-    ALOGV("targeted minimal frame duration is: %" PRId64 "ns", minFrameDuration);
-
-    GetMaxSize(jpegData, jpegCount, &jpegMaxSize, &maxIdx);
-    ALOGV("Found Jpeg size max idx = %d", maxIdx);
-
-    // Max Jpeg size should be available in processed sizes. Use it for
-    // YUV capture anyway.
-    EXPECT_EQ(processedMaxSize.width, jpegMaxSize.width);
-    EXPECT_EQ(processedMaxSize.height, jpegMaxSize.height);
-
-    // Cap preview size.
-    Size previewLimit = { PREVIEW_WIDTH_CAP, PREVIEW_HEIGHT_CAP };
-    // FIXME: need make sure the previewLimit is supported by HAL.
-    Size previewSize = CapSize(previewLimit, processedMaxSize);
-    // Cap Metering size.
-    Size meteringLimit = { METERING_WIDTH_CAP, METERING_HEIGHT_CAP };
-    // Cap metering size to VGA (VGA is mandatory by CDD)
-    Size meteringSize = CapSize(meteringLimit, processedMinSize);
-    // Capture stream should be the max size of jpeg sizes.
-    ALOGV("preview size: %dx%d, metering size: %dx%d, capture size: %dx%d",
-            previewSize.width, previewSize.height,
-            meteringSize.width, meteringSize.height,
-            jpegMaxSize.width, jpegMaxSize.height);
-
-    // Create streams
-    // Preview stream: small resolution, render on the screen.
-    sp<CameraStream> previewStream;
-    {
-        sp<Surface> surface;
-        ASSERT_NO_FATAL_FAILURE(CreateOnScreenSurface(/*out*/surface));
-        previewStream = CreateStream(
-                previewSize.width,
-                previewSize.height,
-                mDevice,
-                DISPLAY_STREAM_PARAMETERS,
-                surface,
-                false);
-        ASSERT_NE((void*)NULL, previewStream.get());
-        ASSERT_NO_FATAL_FAILURE(previewStream->SetUp());
-    }
-    // Metering burst stream: small resolution yuv stream
-    sp<CameraStream> meteringStream =
-            CreateStream(
-                    meteringSize.width,
-                    meteringSize.height,
-                    mDevice);
-    ASSERT_NE((void*)NULL, meteringStream.get());
-    ASSERT_NO_FATAL_FAILURE(meteringStream->SetUp());
-    // Capture burst stream: full resolution yuv stream
-    sp<CameraStream> captureStream =
-            CreateStream(
-                    jpegMaxSize.width,
-                    jpegMaxSize.height,
-                    mDevice);
-    ASSERT_NE((void*)NULL, captureStream.get());
-    ASSERT_NO_FATAL_FAILURE(captureStream->SetUp());
-
-    // Create Preview request.
-    CameraMetadata previewRequest, meteringRequest, captureRequest;
-    ASSERT_NO_FATAL_FAILURE(CreateRequests(previewRequest, meteringRequest,
-            captureRequest, previewStream->GetStreamId(),
-            meteringStream->GetStreamId(), captureStream->GetStreamId()));
-
-    // Start preview
-    if (CAMERA_MULTI_STREAM_DEBUGGING) {
-        previewRequest.dump(STDOUT_FILENO);
-    }
-
-    // Generate exposure and sensitivity lists
-    camera_metadata_ro_entry exposureTimeRange =
-        GetStaticEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE);
-    ASSERT_EQ(exposureTimeRange.count, 2u);
-    int64_t minExp = exposureTimeRange.data.i64[0];
-    int64_t maxExp = exposureTimeRange.data.i64[1];
-    ASSERT_GT(maxExp, minExp);
-
-    camera_metadata_ro_entry sensivityRange =
-        GetStaticEntry(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE);
-    ASSERT_EQ(2u, sensivityRange.count);
-    int32_t minSensitivity = sensivityRange.data.i32[0];
-    int32_t maxSensitivity = sensivityRange.data.i32[1];
-    camera_metadata_ro_entry maxAnalogSenEntry =
-            GetStaticEntry(ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY);
-    EXPECT_EQ(1u, maxAnalogSenEntry.count);
-    int32_t maxAnalogSensitivity = maxAnalogSenEntry.data.i32[0];
-    EXPECT_LE(maxAnalogSensitivity, maxSensitivity);
-    // Only test the sensitivity implemented by analog gain.
-    if (maxAnalogSensitivity > maxSensitivity) {
-        // Fallback to maxSensitity
-        maxAnalogSensitivity = maxSensitivity;
-    }
-
-    // sensitivity list, only include the sensitivities that are implemented
-    // purely by analog gain if possible.
-    Vector<int32_t> sensitivities;
-    Vector<int64_t> exposures;
-    size_t count = (maxAnalogSensitivity - minSensitivity + 99) / 100;
-    sensitivities.push_back(minSensitivity);
-    for (size_t i = 1; i < count; i++) {
-        sensitivities.push_back(minSensitivity + i * 100);
-    }
-    sensitivities.push_back(maxAnalogSensitivity);
-    ALOGV("Sensitivity Range: min=%d, max=%d", minSensitivity,
-            maxAnalogSensitivity);
-    int64_t exp = minExp;
-    while (exp < maxExp) {
-        exposures.push_back(exp);
-        exp *= 2;
-    }
-    // Sweep the exposure value for preview, just for visual inspection purpose.
-    uint8_t cmOff = static_cast<uint8_t>(ANDROID_CONTROL_MODE_OFF);
-    for (size_t i = 0; i < exposures.size(); i++) {
-        ASSERT_EQ(OK, previewRequest.update(
-                ANDROID_CONTROL_MODE,
-                &cmOff, 1));
-        ASSERT_EQ(OK, previewRequest.update(
-                ANDROID_SENSOR_EXPOSURE_TIME,
-                &exposures[i], 1));
-        ALOGV("Submitting preview request %zu with exposure %" PRId64,
-                i, exposures[i]);
-
-        ASSERT_EQ(OK, mDevice->setStreamingRequest(previewRequest));
-
-        // Let preview run 200ms on screen for each exposure time.
-        usleep(PREVIEW_RENDERING_TIME_INTERVAL);
-    }
-
-    size_t requestCount = sensitivities.size();
-    if (requestCount > exposures.size()) {
-        requestCount = exposures.size();
-    }
-
-    // To maintain the request id uniqueness (preview request id is 0), make burst capture start
-    // request id 1 here.
-    int32_t requestIdStart = 1;
-    /**
-     * Submit metering request, set default frame duration to minimal possible
-     * value, we want the capture to run as fast as possible. HAL should adjust
-     * the frame duration to minimal necessary value to support the requested
-     * exposure value if exposure is larger than frame duration.
-     */
-    CaptureBurst(meteringRequest, requestCount, exposures, sensitivities,
-            meteringStream, minFrameDuration, &requestIdStart);
-
-    /**
-     * Submit capture request, set default frame duration to minimal possible
-     * value, we want the capture to run as fast as possible. HAL should adjust
-     * the frame duration to minimal necessary value to support the requested
-     * exposure value if exposure is larger than frame duration.
-     */
-    CaptureBurst(captureRequest, requestCount, exposures, sensitivities,
-            captureStream, minFrameDuration, &requestIdStart);
-
-    ASSERT_EQ(OK, mDevice->clearStreamingRequest());
-}
-
-}
-}
-}
diff --git a/tests/camera2/CameraStreamFixture.h b/tests/camera2/CameraStreamFixture.h
deleted file mode 100644
index 92ff05b..0000000
--- a/tests/camera2/CameraStreamFixture.h
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2012 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_HAL_CAMERA2_TESTS_STREAM_FIXTURE__
-#define __ANDROID_HAL_CAMERA2_TESTS_STREAM_FIXTURE__
-
-#include <gtest/gtest.h>
-#include <iostream>
-#include <fstream>
-
-#include <gui/CpuConsumer.h>
-#include <gui/Surface.h>
-#include <utils/Condition.h>
-#include <utils/Mutex.h>
-#include <system/camera_metadata.h>
-
-#include "CameraModuleFixture.h"
-#include "TestExtensions.h"
-
-#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-// Format specifier for picking the best format for CPU reading the given device
-// version
-#define CAMERA_STREAM_AUTO_CPU_FORMAT (-1)
-
-struct CameraStreamParams;
-
-void PrintTo(const CameraStreamParams& p, ::std::ostream* os);
-
-struct CameraStreamParams {
-    int mFormat;
-    int mHeapCount;
-
-};
-
-inline ::std::ostream& operator<<(::std::ostream& os, const CameraStreamParams &p) {
-    PrintTo(p, &os);
-    return os;
-}
-
-inline void PrintTo(const CameraStreamParams& p, ::std::ostream* os) {
-    char fmt[100];
-    camera_metadata_enum_snprint(
-        ANDROID_SCALER_AVAILABLE_FORMATS, p.mFormat, fmt, sizeof(fmt));
-
-    *os <<  "{ ";
-    *os <<  "Format: 0x"  << std::hex << p.mFormat    << ", ";
-    *os <<  "Format name: " << fmt << ", ";
-    *os <<  "HeapCount: " <<             p.mHeapCount;
-    *os << " }";
-}
-
-class CameraStreamFixture
-    : public CameraModuleFixture</*InfoQuirk*/true> {
-
-public:
-    explicit CameraStreamFixture(CameraStreamParams p)
-    : CameraModuleFixture(TestSettings::DeviceId()) {
-        TEST_EXTENSION_FORKING_CONSTRUCTOR;
-
-        mParam = p;
-
-        SetUp();
-    }
-
-    ~CameraStreamFixture() {
-        TEST_EXTENSION_FORKING_DESTRUCTOR;
-
-        TearDown();
-    }
-
-private:
-
-    void SetUp() {
-        TEST_EXTENSION_FORKING_SET_UP;
-
-        CameraModuleFixture::SetUp();
-
-        sp<CameraDeviceBase> device = mDevice;
-
-        /* use an arbitrary w,h */
-        if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
-            const int tag = ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES;
-
-            const CameraMetadata& staticInfo = device->info();
-            camera_metadata_ro_entry entry = staticInfo.find(tag);
-            ASSERT_NE(0u, entry.count)
-                << "Missing tag android.scaler.availableProcessedSizes";
-
-            ASSERT_LE(2u, entry.count);
-            /* this seems like it would always be the smallest w,h
-               but we actually make no contract that it's sorted asc */
-            mWidth = entry.data.i32[0];
-            mHeight = entry.data.i32[1];
-        } else {
-            buildOutputResolutions();
-            const int32_t *implDefResolutions = NULL;
-            size_t   implDefResolutionsCount;
-
-            int format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
-
-            getResolutionList(format,
-                    &implDefResolutions, &implDefResolutionsCount);
-            ASSERT_NE(0u, implDefResolutionsCount)
-                << "Missing implementation defined sizes";
-            mWidth = implDefResolutions[0];
-            mHeight = implDefResolutions[1];
-        }
-    }
-    void TearDown() {
-        TEST_EXTENSION_FORKING_TEAR_DOWN;
-
-        // important: shut down HAL before releasing streams
-        CameraModuleFixture::TearDown();
-
-        deleteOutputResolutions();
-        mSurface.clear();
-        mCpuConsumer.clear();
-        mFrameListener.clear();
-    }
-
-protected:
-
-    int64_t getMinFrameDurationFor(int32_t format, int32_t width, int32_t height) {
-        int64_t minFrameDuration = -1L;
-        const int tag = ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS;
-        sp<CameraDeviceBase> device = mDevice;
-        const CameraMetadata& staticInfo = device->info();
-        camera_metadata_ro_entry_t availableMinDurations = staticInfo.find(tag);
-        for (uint32_t i = 0; i < availableMinDurations.count; i += 4) {
-            if (format == availableMinDurations.data.i64[i] &&
-                    width == availableMinDurations.data.i64[i + 1] &&
-                    height == availableMinDurations.data.i64[i + 2]) {
-                minFrameDuration = availableMinDurations.data.i64[i + 3];
-                break;
-            }
-        }
-        return minFrameDuration;
-    }
-
-    void buildOutputResolutions() {
-        if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
-            return;
-        }
-        if (mOutputResolutions.isEmpty()) {
-            const int tag = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS;
-            const CameraMetadata& staticInfo = mDevice->info();
-            camera_metadata_ro_entry_t availableStrmConfigs = staticInfo.find(tag);
-            ASSERT_EQ(0u, availableStrmConfigs.count % 4);
-            for (uint32_t i = 0; i < availableStrmConfigs.count; i += 4) {
-                int32_t format = availableStrmConfigs.data.i32[i];
-                int32_t width = availableStrmConfigs.data.i32[i + 1];
-                int32_t height = availableStrmConfigs.data.i32[i + 2];
-                int32_t inOrOut = availableStrmConfigs.data.i32[i + 3];
-                if (inOrOut == ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT) {
-                    int index = mOutputResolutions.indexOfKey(format);
-                    if (index < 0) {
-                        index = mOutputResolutions.add(format, new Vector<int32_t>());
-                        ASSERT_TRUE(index >= 0);
-                    }
-                    Vector<int32_t> *resolutions = mOutputResolutions.editValueAt(index);
-                    resolutions->add(width);
-                    resolutions->add(height);
-                }
-            }
-        }
-    }
-
-    void getResolutionList(int32_t format,
-            const int32_t **list,
-            size_t *count) {
-        ALOGV("Getting resolutions for format %x", format);
-        if (getDeviceVersion() < CAMERA_DEVICE_API_VERSION_3_2) {
-            return;
-        }
-        int index = mOutputResolutions.indexOfKey(format);
-        ASSERT_TRUE(index >= 0);
-        Vector<int32_t>* resolutions = mOutputResolutions.valueAt(index);
-        *list = resolutions->array();
-        *count = resolutions->size();
-    }
-
-    void deleteOutputResolutions() {
-        for (uint32_t i = 0; i < mOutputResolutions.size(); i++) {
-            Vector<int32_t>* resolutions = mOutputResolutions.editValueAt(i);
-            delete resolutions;
-        }
-        mOutputResolutions.clear();
-    }
-
-    struct FrameListener : public ConsumerBase::FrameAvailableListener {
-
-        FrameListener() {
-            mPendingFrames = 0;
-        }
-
-        // CpuConsumer::FrameAvailableListener implementation
-        virtual void onFrameAvailable(const BufferItem& /* item */) {
-            ALOGV("Frame now available (start)");
-
-            Mutex::Autolock lock(mMutex);
-            mPendingFrames++;
-            mCondition.signal();
-
-            ALOGV("Frame now available (end)");
-        }
-
-        status_t waitForFrame(nsecs_t timeout) {
-            status_t res;
-            Mutex::Autolock lock(mMutex);
-            while (mPendingFrames == 0) {
-                res = mCondition.waitRelative(mMutex, timeout);
-                if (res != OK) return res;
-            }
-            mPendingFrames--;
-            return OK;
-        }
-
-    private:
-        Mutex mMutex;
-        Condition mCondition;
-        int mPendingFrames;
-    };
-
-    void CreateStream() {
-        sp<CameraDeviceBase> device = mDevice;
-        CameraStreamParams p = mParam;
-
-        sp<IGraphicBufferProducer> producer;
-        sp<IGraphicBufferConsumer> consumer;
-        BufferQueue::createBufferQueue(&producer, &consumer);
-        mCpuConsumer = new CpuConsumer(consumer, p.mHeapCount);
-        mCpuConsumer->setName(String8("CameraStreamTest::mCpuConsumer"));
-
-        mSurface = new Surface(producer);
-
-        int format = MapAutoFormat(p.mFormat);
-
-        ASSERT_EQ(OK,
-            device->createStream(mSurface,
-                mWidth, mHeight, format,
-                HAL_DATASPACE_UNKNOWN,
-                CAMERA3_STREAM_ROTATION_0,
-                &mStreamId));
-
-        ASSERT_NE(-1, mStreamId);
-
-        // do not make 'this' a FrameListener or the lifetime policy will clash
-        mFrameListener = new FrameListener();
-        mCpuConsumer->setFrameAvailableListener(mFrameListener);
-    }
-
-    void DeleteStream() {
-        ASSERT_EQ(OK, mDevice->deleteStream(mStreamId));
-    }
-
-    int MapAutoFormat(int format) {
-        if (format == CAMERA_STREAM_AUTO_CPU_FORMAT) {
-            if (getDeviceVersion() >= CAMERA_DEVICE_API_VERSION_3_0) {
-                format = HAL_PIXEL_FORMAT_YCbCr_420_888;
-            } else {
-                format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
-            }
-        }
-        return format;
-    }
-
-    void DumpYuvToFile(const String8 &fileName, const CpuConsumer::LockedBuffer &img) {
-        uint8_t *dataCb, *dataCr;
-        uint32_t stride;
-        uint32_t chromaStride;
-        uint32_t chromaStep;
-
-        switch (img.format) {
-            case HAL_PIXEL_FORMAT_YCbCr_420_888:
-                stride = img.stride;
-                chromaStride = img.chromaStride;
-                chromaStep = img.chromaStep;
-                dataCb = img.dataCb;
-                dataCr = img.dataCr;
-                break;
-            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-                stride = img.width;
-                chromaStride = img.width;
-                chromaStep = 2;
-                dataCr = img.data + img.width * img.height;
-                dataCb = dataCr + 1;
-                break;
-            case HAL_PIXEL_FORMAT_YV12:
-                stride = img.stride;
-                chromaStride = ALIGN(img.width / 2, 16);
-                chromaStep = 1;
-                dataCr = img.data + img.stride * img.height;
-                dataCb = dataCr + chromaStride * img.height/2;
-                break;
-            default:
-                ALOGE("Unknown format %d, not dumping", img.format);
-                return;
-        }
-
-        // Write Y
-        FILE *yuvFile = fopen(fileName.string(), "w");
-
-        size_t bytes;
-
-        for (size_t y = 0; y < img.height; ++y) {
-            bytes = fwrite(
-                reinterpret_cast<const char*>(img.data + stride * y),
-                1, img.width, yuvFile);
-            if (bytes != img.width) {
-                ALOGE("Unable to write to file %s", fileName.string());
-                fclose(yuvFile);
-                return;
-            }
-        }
-
-        // Write Cb/Cr
-        uint8_t *src = dataCb;
-        for (int c = 0; c < 2; ++c) {
-            for (size_t y = 0; y < img.height / 2; ++y) {
-                uint8_t *px = src + y * chromaStride;
-                if (chromaStep != 1) {
-                    for (size_t x = 0; x < img.width / 2; ++x) {
-                        fputc(*px, yuvFile);
-                        px += chromaStep;
-                    }
-                } else {
-                    bytes = fwrite(reinterpret_cast<const char*>(px),
-                            1, img.width / 2, yuvFile);
-                    if (bytes != img.width / 2) {
-                        ALOGE("Unable to write to file %s", fileName.string());
-                        fclose(yuvFile);
-                        return;
-                    }
-                }
-            }
-            src = dataCr;
-        }
-        fclose(yuvFile);
-    }
-
-    int mWidth;
-    int mHeight;
-
-    int mStreamId;
-
-    android::sp<FrameListener>       mFrameListener;
-    android::sp<CpuConsumer>         mCpuConsumer;
-    android::sp<Surface>             mSurface;
-    KeyedVector<int32_t, Vector<int32_t>* > mOutputResolutions;
-
-private:
-    CameraStreamParams mParam;
-};
-
-}
-}
-}
-
-#endif
diff --git a/tests/camera2/CameraStreamTests.cpp b/tests/camera2/CameraStreamTests.cpp
deleted file mode 100644
index de9ae8a..0000000
--- a/tests/camera2/CameraStreamTests.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#include <iostream>
-#include <iomanip>
-#include <gtest/gtest.h>
-
-#define LOG_TAG "CameraStreamTest"
-#define LOG_NDEBUG 0
-#include <utils/Log.h>
-
-#include "hardware/hardware.h"
-#include "hardware/camera2.h"
-
-#include <utils/StrongPointer.h>
-#include <gui/CpuConsumer.h>
-#include <gui/Surface.h>
-
-#include "CameraStreamFixture.h"
-#include "TestExtensions.h"
-
-using namespace android;
-using namespace android::camera2;
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-class CameraStreamTest
-    : public ::testing::TestWithParam<CameraStreamParams>,
-      public CameraStreamFixture {
-
-public:
-    CameraStreamTest() : CameraStreamFixture(GetParam()) {
-        TEST_EXTENSION_FORKING_CONSTRUCTOR;
-    }
-
-    ~CameraStreamTest() {
-        TEST_EXTENSION_FORKING_DESTRUCTOR;
-    }
-
-    virtual void SetUp() {
-        TEST_EXTENSION_FORKING_SET_UP;
-    }
-    virtual void TearDown() {
-        TEST_EXTENSION_FORKING_TEAR_DOWN;
-    }
-
-protected:
-
-};
-
-TEST_P(CameraStreamTest, CreateStream) {
-
-    TEST_EXTENSION_FORKING_INIT;
-
-    /** Make sure the format requested is supported. PASS this test if it's not
-      * not supported.
-      *
-      * TODO: would be nice of not running this test in the first place
-      *       somehow.
-      */
-    {
-        camera_metadata_ro_entry availableFormats =
-            GetStaticEntry(ANDROID_SCALER_AVAILABLE_FORMATS);
-
-        bool hasFormat = false;
-        for (size_t i = 0; i < availableFormats.count; ++i) {
-            if (availableFormats.data.i32[i] == GetParam().mFormat) {
-                hasFormat = true;
-                break;
-            }
-        }
-
-        if (!hasFormat) {
-            const ::testing::TestInfo* const test_info =
-                ::testing::UnitTest::GetInstance()->current_test_info();
-            std::cerr << "Skipping test "
-                      << test_info->test_case_name() << "."
-                      << test_info->name()
-                      << " because the format was not available: "
-                      << GetParam() << std::endl;
-            return;
-        }
-    }
-
-    ASSERT_NO_FATAL_FAILURE(CreateStream());
-    ASSERT_NO_FATAL_FAILURE(DeleteStream());
-}
-
-//TODO: use a combinatoric generator
-static CameraStreamParams TestParameters[] = {
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
-        /*mHeapCount*/ 1
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
-        /*mHeapCount*/ 2
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
-        /*mHeapCount*/ 3
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_YCrCb_420_SP, // NV21
-        /*mHeapCount*/ 1
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_YCrCb_420_SP,
-        /*mHeapCount*/ 2
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_YCrCb_420_SP,
-        /*mHeapCount*/ 3
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_YV12,
-        /*mHeapCount*/ 1
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_YV12,
-        /*mHeapCount*/ 2
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_YV12,
-        /*mHeapCount*/ 3
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_Y8,
-        /*mHeapCount*/ 1
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_Y8,
-        /*mHeapCount*/ 2
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_Y8,
-        /*mHeapCount*/ 3
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_Y16,
-        /*mHeapCount*/ 1
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_Y16,
-        /*mHeapCount*/ 2
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_Y16,
-        /*mHeapCount*/ 3
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_RAW16,
-        /*mHeapCount*/ 1
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_RAW16,
-        /*mHeapCount*/ 2
-    },
-    {
-        /*mFormat*/    HAL_PIXEL_FORMAT_RAW16,
-        /*mHeapCount*/ 3
-    },
-};
-
-INSTANTIATE_TEST_CASE_P(StreamParameterCombinations, CameraStreamTest,
-    testing::ValuesIn(TestParameters));
-
-
-}
-}
-}
diff --git a/tests/camera2/ForkedTests.cpp b/tests/camera2/ForkedTests.cpp
deleted file mode 100644
index 39599da..0000000
--- a/tests/camera2/ForkedTests.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#include <gtest/gtest.h>
-
-#include <stdlib.h>
-
-#include "TestExtensions.h"
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-// Intentionally disabled since 2 of these tests are supposed to fail
-class DISABLED_ForkedTest : public ::testing::Test {
-
-    virtual void SetUp() {
-        TEST_EXTENSION_FORKING_SET_UP;
-    }
-
-    virtual void TearDown() {
-        TEST_EXTENSION_FORKING_TEAR_DOWN;
-    }
-};
-
-// intentionally fail
-TEST_F(DISABLED_ForkedTest, FailCrash) {
-    TEST_EXTENSION_FORKING_INIT;
-    abort();
-}
-
-TEST_F(DISABLED_ForkedTest, SucceedNormal) {
-    TEST_EXTENSION_FORKING_INIT;
-
-    EXPECT_TRUE(true);
-}
-
-// intentionally fail
-TEST_F(DISABLED_ForkedTest, FailNormal) {
-    TEST_EXTENSION_FORKING_INIT;
-
-    EXPECT_TRUE(false);
-}
-
-}
-}
-}
-
diff --git a/tests/camera2/TestExtensions.h b/tests/camera2/TestExtensions.h
deleted file mode 100644
index 2af587d..0000000
--- a/tests/camera2/TestExtensions.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2012 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_HAL_CAMERA2_TESTS_EXTENSIONS__
-#define __ANDROID_HAL_CAMERA2_TESTS_EXTENSIONS__
-
-#include "TestForkerEventListener.h"
-#include "TestSettings.h"
-
-// Use at the beginning of each Test::SetUp() impl
-#define TEST_EXTENSION_FORKING_SET_UP                                       \
-    do {                                                                    \
-        if (TEST_EXTENSION_FORKING_ENABLED) {                               \
-            if (!TestForkerEventListener::mIsForked) {                      \
-                return;                                                     \
-            }                                                               \
-        }                                                                   \
-    } while (false)                                                         \
-
-// Use at the beginning of each Test::TearDown() impl
-#define TEST_EXTENSION_FORKING_TEAR_DOWN   TEST_EXTENSION_FORKING_SET_UP
-
-// Use at the beginning of each Test::Test constructor
-#define TEST_EXTENSION_FORKING_CONSTRUCTOR TEST_EXTENSION_FORKING_SET_UP
-
-// Use at the beginning of each Test::~Test destructor
-#define TEST_EXTENSION_FORKING_DESTRUCTOR  TEST_EXTENSION_FORKING_TEAR_DOWN
-
-// Use at the beginning of each test body, e.g. TEST(x,y), TEST_F(x,y), etc
-#define TEST_EXTENSION_FORKING_INIT                                         \
-    do {                                                                    \
-        TEST_EXTENSION_FORKING_SET_UP;                                      \
-        if (HasFatalFailure()) return;                                      \
-    } while(false)                                                          \
-
-// Are we running each test by forking it?
-#define TEST_EXTENSION_FORKING_ENABLED                                      \
-    (android::camera2::tests::TestSettings::ForkingEnabled())
-
-
-
-#endif
-
diff --git a/tests/camera2/TestForkerEventListener.cpp b/tests/camera2/TestForkerEventListener.cpp
deleted file mode 100644
index 9416db2..0000000
--- a/tests/camera2/TestForkerEventListener.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <string.h>
-
-#include <gtest/gtest.h>
-
-#include "TestForkerEventListener.h"
-#include "TestExtensions.h"
-
-#define DEBUG_TEST_FORKER_EVENT_LISTENER 0
-
-#define RETURN_CODE_PASSED 0
-#define RETURN_CODE_FAILED 1
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-bool TestForkerEventListener::mIsForked         = false;
-
-TestForkerEventListener::TestForkerEventListener() {
-    mIsForked = false;
-    mHasSucceeded = true;
-    mTermSignal = 0;
-}
-
-// Called before a test starts.
-void TestForkerEventListener::OnTestStart(const ::testing::TestInfo&) {
-
-    if (!TEST_EXTENSION_FORKING_ENABLED) {
-        return;
-    }
-
-    pid_t childPid = fork();
-    if (childPid != 0) {
-        int status;
-        waitpid(childPid, &status, /*options*/0);
-
-        // terminated normally?
-        mHasSucceeded = WIFEXITED(status);
-        // terminate with return code 0 = test passed, 1 = test failed
-        if (mHasSucceeded) {
-          mHasSucceeded = WEXITSTATUS(status) == RETURN_CODE_PASSED;
-        } else if (WIFSIGNALED(status)) {
-          mTermSignal = WTERMSIG(status);
-        }
-
-        /* the test is then skipped by inserting the various
-        TEST_EXTENSION_ macros in TestExtensions.h */
-
-    } else {
-        mIsForked = true;
-    }
-}
-
-// Called after a failed assertion or a SUCCEED() invocation.
-void TestForkerEventListener::OnTestPartResult(
-    const ::testing::TestPartResult& test_part_result) {
-
-    if (DEBUG_TEST_FORKER_EVENT_LISTENER) {
-        printf("%s in %s:%d\n%s\n",
-             test_part_result.failed() ? "*** Failure" : "Success",
-             test_part_result.file_name(),
-             test_part_result.line_number(),
-             test_part_result.summary());
-    }
-}
-
-// Called after a test ends.
-void TestForkerEventListener::OnTestEnd(const ::testing::TestInfo& test_info) {
-
-    if (!TEST_EXTENSION_FORKING_ENABLED) {
-        return;
-    }
-
-    if (mIsForked) {
-        exit(test_info.result()->Passed()
-            ? RETURN_CODE_PASSED : RETURN_CODE_FAILED);
-    } else if (!mHasSucceeded && mTermSignal != 0) {
-
-      printf("*** Test %s.%s crashed with signal = %s\n",
-             test_info.test_case_name(), test_info.name(),
-             strsignal(mTermSignal));
-    }
-
-    //TODO: overload the default event listener to suppress this message
-    // dynamically (e.g. by skipping OnTestPartResult after OnTestEnd )
-
-    // trigger a test failure if the child has failed
-    if (!mHasSucceeded) {
-        ADD_FAILURE();
-    }
-    mTermSignal = 0;
-}
-
-
-}
-}
-}
-
diff --git a/tests/camera2/TestForkerEventListener.h b/tests/camera2/TestForkerEventListener.h
deleted file mode 100644
index 347a06b..0000000
--- a/tests/camera2/TestForkerEventListener.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2012 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_HAL_CAMERA2_TESTS_FORKER_EVENT_LISTENER__
-#define __ANDROID_HAL_CAMERA2_TESTS_FORKER_EVENT_LISTENER__
-
-#include <gtest/gtest.h>
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-// Fork before each test runs.
-class TestForkerEventListener : public ::testing::EmptyTestEventListener {
-
-public:
-
-    TestForkerEventListener();
-
-private:
-
-    // Called before a test starts.
-    virtual void OnTestStart(const ::testing::TestInfo& test_info);
-
-    // Called after a failed assertion or a SUCCEED() invocation.
-    virtual void OnTestPartResult(
-        const ::testing::TestPartResult& test_part_result);
-
-    // Called after a test ends.
-    virtual void OnTestEnd(const ::testing::TestInfo& test_info);
-
-    bool mHasSucceeded;
-    int mTermSignal;
-
-public:
-    // do not read directly. use TEST_EXTENSION macros instead
-    static bool mIsForked;
-};
-
-}
-}
-}
-
-#endif
diff --git a/tests/camera2/TestSettings.cpp b/tests/camera2/TestSettings.cpp
deleted file mode 100644
index f07adc8..0000000
--- a/tests/camera2/TestSettings.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#include <cstdlib>
-#include <getopt.h>
-#include <cstring>
-#include <iostream>
-
-#include "TestSettings.h"
-
-#include "TestForkerEventListener.h"
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-bool TestSettings::mForkingDisabled     = false;
-int  TestSettings::mDeviceId            = 0;
-char* const* TestSettings::mArgv;
-
-// --forking-disabled, false by default
-bool TestSettings::ForkingDisabled() {
-    return mForkingDisabled;
-}
-
-// reverse of --forking-disabled (not a flag), true by default
-bool TestSettings::ForkingEnabled() {
-    return !ForkingDisabled();
-}
-
-// --device-id, 0 by default
-int TestSettings::DeviceId() {
-    return mDeviceId;
-}
-
-// returns false if usage should be printed and we should exit early
-bool TestSettings::ParseArgs(int argc, char* const argv[])
-{
-    {
-        char *env = getenv("CAMERA2_TEST_FORKING_DISABLED");
-        if (env) {
-            mForkingDisabled = atoi(env);
-        }
-
-        env = getenv("CAMERA2_TEST_DEVICE_ID");
-        if (env) {
-            mDeviceId = atoi(env);
-        }
-    }
-
-    bool printHelp = false;
-    bool unknownArgs = false;
-
-    opterr = 0; // do not print errors for unknown arguments
-    while (true) {
-        int c;
-        int option_index = 0;
-
-        static struct option long_options[] = {
-            /* name              has_arg          flag val */
-            {"forking-disabled", optional_argument, 0,  0  },
-            {"device-id",        required_argument, 0,  0  },
-            {"help",             no_argument,       0, 'h' },
-            {0,                  0,                 0,  0  }
-        };
-
-        // Note: '+' in optstring means do not mutate argv
-        c = getopt_long(argc, argv, "+h", long_options, &option_index);
-
-        if (c == -1) { // All arguments exhausted
-            break;
-        }
-        if (c == '?') { // Argument not in option lists
-            const char *arg = argv[optind-1];
-            // Anything beginning with gtest_ will get handled by gtest
-            if (strstr(arg, "--gtest_") != arg) {
-                std::cerr << "Unknown argument: " << arg << std::endl;
-                unknownArgs = true;
-            }
-            continue;
-        }
-
-        switch (c) {
-        case 0: // long option
-            switch (option_index) {
-            case 0: {
-                const char *arg = optarg ?: "1";
-                mForkingDisabled = atoi(arg);
-                break;
-            }
-            case 1: {
-                mDeviceId = atoi(optarg);
-                break;
-            }
-            default:
-                std::cerr << "Unknown long option: " << option_index << std::endl;
-                break;
-            }
-            break; // case 0
-        case 'h': // help
-            printHelp = true;
-            break;
-        default: // case '?'
-            std::cerr << "Unknown option: " << optarg << std::endl;
-        }
-    }
-
-    if (unknownArgs) {
-        std::cerr << std::endl;
-    }
-
-    mArgv = argv;
-
-    if (printHelp || unknownArgs) {
-        return false;
-    }
-
-    std::cerr << "Forking Disabled: "
-              << (mForkingDisabled ? "yes" : "no") << std::endl;
-
-    std::cerr << "Device ID: " << mDeviceId << std::endl;
-
-    return true;
-}
-
-// print usage/help list of commands (non-gtest)
-void TestSettings::PrintUsage() {
-    std::cerr << "Usage: " << mArgv[0] << " [OPTIONS]" << std::endl;
-    std::cerr << std::endl;
-
-    std::cerr << "Main modes of operation:"
-              << std::endl;
-    std::cerr << "   --forking-disabled[=1]  don't fork process before "
-              << std::endl
-              << "                           running a new test."
-              << std::endl
-              << "                           (default enabled)"
-              << std::endl;
-    std::cerr << "   --device-id=ID          specify a different camera ID"
-              << std::endl
-              << "                           (default 0)"
-              << std::endl;
-
-    std::cerr << "   -h, --help              print this help listing"
-              << std::endl;
-
-
-    std::cerr << std::endl;
-}
-
-}
-}
-}
-
diff --git a/tests/camera2/TestSettings.h b/tests/camera2/TestSettings.h
deleted file mode 100644
index 6164de5..0000000
--- a/tests/camera2/TestSettings.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-:qa
- * Copyright (C) 2012 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_HAL_CAMERA2_TESTS_SETTINGS__
-#define __ANDROID_HAL_CAMERA2_TESTS_SETTINGS__
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-class TestSettings {
-
-public:
-    // --forking-disabled, false by default
-    static bool ForkingDisabled();
-
-    // reverse of --forking-disabled (not a flag), true by default
-    static bool ForkingEnabled();
-
-    // --device-id, 0 by default
-    static int DeviceId();
-
-    // returns false if usage should be printed and we should exit early
-    static bool ParseArgs(int argc, char* const argv[]);
-
-    // print usage/help list of commands (non-gtest)
-    static void PrintUsage();
-
-private:
-    TestSettings();
-    ~TestSettings();
-
-    static bool mForkingDisabled;
-    static int  mDeviceId;
-    static char* const* mArgv;
-};
-
-}
-}
-}
-
-#endif
diff --git a/tests/camera2/camera2_utils.cpp b/tests/camera2/camera2_utils.cpp
deleted file mode 100644
index dab0ae9..0000000
--- a/tests/camera2/camera2_utils.cpp
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-// Utility classes for camera2 HAL testing
-
-#define LOG_TAG "Camera2_test_utils"
-#define LOG_NDEBUG 0
-
-#include "utils/Log.h"
-#include "camera2_utils.h"
-#include <dlfcn.h>
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-/**
- * MetadataQueue
- */
-
-MetadataQueue::MetadataQueue():
-            mDevice(NULL),
-            mFrameCount(0),
-            mCount(0),
-            mStreamSlotCount(0),
-            mSignalConsumer(true)
-{
-    camera2_request_queue_src_ops::dequeue_request = consumer_dequeue;
-    camera2_request_queue_src_ops::request_count = consumer_buffer_count;
-    camera2_request_queue_src_ops::free_request = consumer_free;
-
-    camera2_frame_queue_dst_ops::dequeue_frame = producer_dequeue;
-    camera2_frame_queue_dst_ops::cancel_frame = producer_cancel;
-    camera2_frame_queue_dst_ops::enqueue_frame = producer_enqueue;
-}
-
-MetadataQueue::~MetadataQueue() {
-    freeBuffers(mEntries.begin(), mEntries.end());
-    freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
-}
-
-// Interface to camera2 HAL as consumer (input requests/reprocessing)
-const camera2_request_queue_src_ops_t* MetadataQueue::getToConsumerInterface() {
-    return static_cast<camera2_request_queue_src_ops_t*>(this);
-}
-
-void MetadataQueue::setFromConsumerInterface(camera2_device_t *d) {
-    mDevice = d;
-}
-
-const camera2_frame_queue_dst_ops_t* MetadataQueue::getToProducerInterface() {
-    return static_cast<camera2_frame_queue_dst_ops_t*>(this);
-}
-
-// Real interfaces
-status_t MetadataQueue::enqueue(camera_metadata_t *buf) {
-    Mutex::Autolock l(mMutex);
-
-    mCount++;
-    mEntries.push_back(buf);
-    notEmpty.signal();
-
-    if (mSignalConsumer && mDevice != NULL) {
-        mSignalConsumer = false;
-
-        mMutex.unlock();
-        ALOGV("%s: Signaling consumer", __FUNCTION__);
-        mDevice->ops->notify_request_queue_not_empty(mDevice);
-        mMutex.lock();
-    }
-    return OK;
-}
-
-int MetadataQueue::getBufferCount() {
-    Mutex::Autolock l(mMutex);
-    if (mStreamSlotCount > 0) {
-        return CAMERA2_REQUEST_QUEUE_IS_BOTTOMLESS;
-    }
-    return mCount;
-}
-
-status_t MetadataQueue::dequeue(camera_metadata_t **buf, bool incrementCount) {
-    Mutex::Autolock l(mMutex);
-
-    if (mCount == 0) {
-        if (mStreamSlotCount == 0) {
-            ALOGV("%s: Empty", __FUNCTION__);
-            *buf = NULL;
-            mSignalConsumer = true;
-            return OK;
-        }
-        ALOGV("%s: Streaming %d frames to queue", __FUNCTION__,
-              mStreamSlotCount);
-
-        for (List<camera_metadata_t*>::iterator slotEntry = mStreamSlot.begin();
-                slotEntry != mStreamSlot.end();
-                slotEntry++ ) {
-            size_t entries = get_camera_metadata_entry_count(*slotEntry);
-            size_t dataBytes = get_camera_metadata_data_count(*slotEntry);
-
-            camera_metadata_t *copy = allocate_camera_metadata(entries, dataBytes);
-            append_camera_metadata(copy, *slotEntry);
-            mEntries.push_back(copy);
-        }
-        mCount = mStreamSlotCount;
-    }
-    ALOGV("MetadataQueue: deque (%d buffers)", mCount);
-    camera_metadata_t *b = *(mEntries.begin());
-    mEntries.erase(mEntries.begin());
-
-    if (incrementCount) {
-        add_camera_metadata_entry(b,
-                ANDROID_REQUEST_FRAME_COUNT,
-                (void**)&mFrameCount, 1);
-        mFrameCount++;
-    }
-
-    *buf = b;
-    mCount--;
-
-    return OK;
-}
-
-status_t MetadataQueue::waitForBuffer(nsecs_t timeout) {
-    Mutex::Autolock l(mMutex);
-    status_t res;
-    while (mCount == 0) {
-        res = notEmpty.waitRelative(mMutex,timeout);
-        if (res != OK) return res;
-    }
-    return OK;
-}
-
-status_t MetadataQueue::setStreamSlot(camera_metadata_t *buf) {
-    if (buf == NULL) {
-        freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
-        mStreamSlotCount = 0;
-        return OK;
-    }
-    if (mStreamSlotCount > 1) {
-        List<camera_metadata_t*>::iterator deleter = ++mStreamSlot.begin();
-        freeBuffers(++mStreamSlot.begin(), mStreamSlot.end());
-        mStreamSlotCount = 1;
-    }
-    if (mStreamSlotCount == 1) {
-        free_camera_metadata( *(mStreamSlot.begin()) );
-        *(mStreamSlot.begin()) = buf;
-    } else {
-        mStreamSlot.push_front(buf);
-        mStreamSlotCount = 1;
-    }
-    return OK;
-}
-
-status_t MetadataQueue::setStreamSlot(const List<camera_metadata_t*> &bufs) {
-    if (mStreamSlotCount > 0) {
-        freeBuffers(mStreamSlot.begin(), mStreamSlot.end());
-    }
-    mStreamSlot = bufs;
-    mStreamSlotCount = mStreamSlot.size();
-
-    return OK;
-}
-
-status_t MetadataQueue::freeBuffers(List<camera_metadata_t*>::iterator start,
-                                    const List<camera_metadata_t*>::iterator& end) {
-    while (start != end) {
-        free_camera_metadata(*start);
-        start = mStreamSlot.erase(start);
-    }
-    return OK;
-}
-
-MetadataQueue* MetadataQueue::getInstance(
-        const camera2_request_queue_src_ops_t *q) {
-    const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
-    return const_cast<MetadataQueue*>(cmq);
-}
-
-MetadataQueue* MetadataQueue::getInstance(
-        const camera2_frame_queue_dst_ops_t *q) {
-    const MetadataQueue* cmq = static_cast<const MetadataQueue*>(q);
-    return const_cast<MetadataQueue*>(cmq);
-}
-
-int MetadataQueue::consumer_buffer_count(
-        const camera2_request_queue_src_ops_t *q) {
-    MetadataQueue *queue = getInstance(q);
-    return queue->getBufferCount();
-}
-
-int MetadataQueue::consumer_dequeue(const camera2_request_queue_src_ops_t *q,
-        camera_metadata_t **buffer) {
-    MetadataQueue *queue = getInstance(q);
-    return queue->dequeue(buffer, true);
-}
-
-int MetadataQueue::consumer_free(const camera2_request_queue_src_ops_t * /* q */,
-        camera_metadata_t *old_buffer) {
-    free_camera_metadata(old_buffer);
-    return OK;
-}
-
-int MetadataQueue::producer_dequeue(const camera2_frame_queue_dst_ops_t * /* q */,
-        size_t entries, size_t bytes,
-        camera_metadata_t **buffer) {
-    camera_metadata_t *new_buffer =
-            allocate_camera_metadata(entries, bytes);
-    if (new_buffer == NULL) return NO_MEMORY;
-    *buffer = new_buffer;
-        return OK;
-}
-
-int MetadataQueue::producer_cancel(const camera2_frame_queue_dst_ops_t * /* q */,
-        camera_metadata_t *old_buffer) {
-    free_camera_metadata(old_buffer);
-    return OK;
-}
-
-int MetadataQueue::producer_enqueue(const camera2_frame_queue_dst_ops_t *q,
-        camera_metadata_t *filled_buffer) {
-    MetadataQueue *queue = getInstance(q);
-    return queue->enqueue(filled_buffer);
-}
-
-/**
- * NotifierListener
- */
-
-NotifierListener::NotifierListener() {
-}
-
-status_t NotifierListener::getNotificationsFrom(camera2_device *dev) {
-    if (!dev) return BAD_VALUE;
-    status_t err;
-    err = dev->ops->set_notify_callback(dev,
-            notify_callback_dispatch,
-            (void*)this);
-    return err;
-}
-
-status_t NotifierListener::getNextNotification(int32_t *msg_type,
-        int32_t *ext1,
-        int32_t *ext2,
-        int32_t *ext3) {
-    Mutex::Autolock l(mMutex);
-    if (mNotifications.size() == 0) return BAD_VALUE;
-    return getNextNotificationLocked(msg_type, ext1, ext2, ext3);
-}
-
-status_t NotifierListener::waitForNotification(int32_t *msg_type,
-        int32_t *ext1,
-        int32_t *ext2,
-        int32_t *ext3) {
-    Mutex::Autolock l(mMutex);
-    while (mNotifications.size() == 0) {
-        mNewNotification.wait(mMutex);
-    }
-    return getNextNotificationLocked(msg_type, ext1, ext2, ext3);
-}
-
-int NotifierListener::numNotifications() {
-    Mutex::Autolock l(mMutex);
-    return mNotifications.size();
-}
-
-status_t NotifierListener::getNextNotificationLocked(int32_t *msg_type,
-        int32_t *ext1,
-        int32_t *ext2,
-        int32_t *ext3) {
-    *msg_type = mNotifications.begin()->msg_type;
-    *ext1 = mNotifications.begin()->ext1;
-    *ext2 = mNotifications.begin()->ext2;
-    *ext3 = mNotifications.begin()->ext3;
-    mNotifications.erase(mNotifications.begin());
-    return OK;
-}
-
-void NotifierListener::onNotify(int32_t msg_type,
-        int32_t ext1,
-        int32_t ext2,
-        int32_t ext3) {
-    Mutex::Autolock l(mMutex);
-    mNotifications.push_back(Notification(msg_type, ext1, ext2, ext3));
-    mNewNotification.signal();
-}
-
-void NotifierListener::notify_callback_dispatch(int32_t msg_type,
-        int32_t ext1,
-        int32_t ext2,
-        int32_t ext3,
-        void *user) {
-    NotifierListener *me = reinterpret_cast<NotifierListener*>(user);
-    me->onNotify(msg_type, ext1, ext2, ext3);
-}
-
-/**
- * StreamAdapter
- */
-
-#ifndef container_of
-#define container_of(ptr, type, member) \
-    (type *)((char*)(ptr) - offsetof(type, member))
-#endif
-
-StreamAdapter::StreamAdapter(sp<IGraphicBufferProducer> consumer):
-        mState(UNINITIALIZED), mDevice(NULL),
-        mId(-1),
-        mWidth(0), mHeight(0), mFormat(0)
-{
-    mConsumerInterface = new Surface(consumer);
-    camera2_stream_ops::dequeue_buffer = dequeue_buffer;
-    camera2_stream_ops::enqueue_buffer = enqueue_buffer;
-    camera2_stream_ops::cancel_buffer = cancel_buffer;
-    camera2_stream_ops::set_crop = set_crop;
-}
-
-StreamAdapter::~StreamAdapter() {
-    disconnect();
-}
-
-status_t StreamAdapter::connectToDevice(camera2_device_t *d,
-        uint32_t width, uint32_t height, int format) {
-    if (mState != UNINITIALIZED) return INVALID_OPERATION;
-    if (d == NULL) {
-        ALOGE("%s: Null device passed to stream adapter", __FUNCTION__);
-        return BAD_VALUE;
-    }
-
-    status_t res;
-
-    mWidth = width;
-    mHeight = height;
-    mFormat = format;
-
-    // Allocate device-side stream interface
-
-    uint32_t id;
-    uint32_t formatActual; // ignored
-    uint32_t usage;
-    uint32_t maxBuffers = 2;
-    res = d->ops->allocate_stream(d,
-            mWidth, mHeight, mFormat, getStreamOps(),
-            &id, &formatActual, &usage, &maxBuffers);
-    if (res != OK) {
-        ALOGE("%s: Device stream allocation failed: %s (%d)",
-                __FUNCTION__, strerror(-res), res);
-        mState = UNINITIALIZED;
-        return res;
-    }
-    mDevice = d;
-
-    mId = id;
-    mUsage = usage;
-    mMaxProducerBuffers = maxBuffers;
-
-    // Configure consumer-side ANativeWindow interface
-
-    res = native_window_api_connect(mConsumerInterface.get(),
-            NATIVE_WINDOW_API_CAMERA);
-    if (res != OK) {
-        ALOGE("%s: Unable to connect to native window for stream %d",
-                __FUNCTION__, mId);
-        mState = ALLOCATED;
-        return res;
-    }
-
-    res = native_window_set_usage(mConsumerInterface.get(), mUsage);
-    if (res != OK) {
-        ALOGE("%s: Unable to configure usage %08x for stream %d",
-                __FUNCTION__, mUsage, mId);
-        mState = CONNECTED;
-        return res;
-    }
-
-    res = native_window_set_buffers_dimensions(mConsumerInterface.get(),
-            mWidth, mHeight);
-    if (res != OK) {
-        ALOGE("%s: Unable to configure buffer dimensions"
-                " %d x %d for stream %d",
-                __FUNCTION__, mWidth, mHeight, mId);
-        mState = CONNECTED;
-        return res;
-    }
-    res = native_window_set_buffers_format(mConsumerInterface.get(),
-            mFormat);
-    if (res != OK) {
-        ALOGE("%s: Unable to configure buffer format"
-                " 0x%x for stream %d",
-                __FUNCTION__, mFormat, mId);
-        mState = CONNECTED;
-        return res;
-    }
-
-    int maxConsumerBuffers;
-    res = mConsumerInterface->query(mConsumerInterface.get(),
-            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
-    if (res != OK) {
-        ALOGE("%s: Unable to query consumer undequeued"
-                " buffer count for stream %d", __FUNCTION__, mId);
-        mState = CONNECTED;
-        return res;
-    }
-    mMaxConsumerBuffers = maxConsumerBuffers;
-
-    ALOGV("%s: Producer wants %d buffers, consumer wants %d", __FUNCTION__,
-            mMaxProducerBuffers, mMaxConsumerBuffers);
-
-    int totalBuffers = mMaxConsumerBuffers + mMaxProducerBuffers;
-
-    res = native_window_set_buffer_count(mConsumerInterface.get(),
-            totalBuffers);
-    if (res != OK) {
-        ALOGE("%s: Unable to set buffer count for stream %d",
-                __FUNCTION__, mId);
-        mState = CONNECTED;
-        return res;
-    }
-
-    // Register allocated buffers with HAL device
-    buffer_handle_t *buffers = new buffer_handle_t[totalBuffers];
-    ANativeWindowBuffer **anwBuffers = new ANativeWindowBuffer*[totalBuffers];
-    int bufferIdx = 0;
-    for (; bufferIdx < totalBuffers; bufferIdx++) {
-        res = native_window_dequeue_buffer_and_wait(mConsumerInterface.get(),
-                &anwBuffers[bufferIdx]);
-        if (res != OK) {
-            ALOGE("%s: Unable to dequeue buffer %d for initial registration for"
-                    "stream %d", __FUNCTION__, bufferIdx, mId);
-            mState = CONNECTED;
-            goto cleanUpBuffers;
-        }
-        buffers[bufferIdx] = anwBuffers[bufferIdx]->handle;
-    }
-
-    res = mDevice->ops->register_stream_buffers(mDevice,
-            mId,
-            totalBuffers,
-            buffers);
-    if (res != OK) {
-        ALOGE("%s: Unable to register buffers with HAL device for stream %d",
-                __FUNCTION__, mId);
-        mState = CONNECTED;
-    } else {
-        mState = ACTIVE;
-    }
-
-cleanUpBuffers:
-    for (int i = 0; i < bufferIdx; i++) {
-        res = mConsumerInterface->cancelBuffer(mConsumerInterface.get(),
-                anwBuffers[i], -1);
-    }
-    delete[] anwBuffers;
-    delete[] buffers;
-
-    return res;
-}
-
-status_t StreamAdapter::disconnect() {
-    status_t res;
-    if (mState >= ALLOCATED) {
-        res = mDevice->ops->release_stream(mDevice, mId);
-        if (res != OK) {
-            ALOGE("%s: Unable to release stream %d",
-                    __FUNCTION__, mId);
-            return res;
-        }
-    }
-    if (mState >= CONNECTED) {
-        res = native_window_api_disconnect(mConsumerInterface.get(),
-                NATIVE_WINDOW_API_CAMERA);
-        if (res != OK) {
-            ALOGE("%s: Unable to disconnect stream %d from native window",
-                    __FUNCTION__, mId);
-            return res;
-        }
-    }
-    mId = -1;
-    mState = DISCONNECTED;
-    return OK;
-}
-
-int StreamAdapter::getId() {
-    return mId;
-}
-
-const camera2_stream_ops *StreamAdapter::getStreamOps() {
-    return static_cast<camera2_stream_ops *>(this);
-}
-
-ANativeWindow* StreamAdapter::toANW(const camera2_stream_ops_t *w) {
-    return static_cast<const StreamAdapter*>(w)->mConsumerInterface.get();
-}
-
-int StreamAdapter::dequeue_buffer(const camera2_stream_ops_t *w,
-        buffer_handle_t** buffer) {
-    int res;
-    int state = static_cast<const StreamAdapter*>(w)->mState;
-    if (state != ACTIVE) {
-        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
-        return INVALID_OPERATION;
-    }
-
-    ANativeWindow *a = toANW(w);
-    ANativeWindowBuffer* anb;
-    res = native_window_dequeue_buffer_and_wait(a, &anb);
-    if (res != OK) return res;
-
-    *buffer = &(anb->handle);
-
-    return res;
-}
-
-int StreamAdapter::enqueue_buffer(const camera2_stream_ops_t* w,
-        int64_t timestamp,
-        buffer_handle_t* buffer) {
-    int state = static_cast<const StreamAdapter*>(w)->mState;
-    if (state != ACTIVE) {
-        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
-        return INVALID_OPERATION;
-    }
-    ANativeWindow *a = toANW(w);
-    status_t err;
-    err = native_window_set_buffers_timestamp(a, timestamp);
-    if (err != OK) return err;
-    return a->queueBuffer(a,
-            container_of(buffer, ANativeWindowBuffer, handle), -1);
-}
-
-int StreamAdapter::cancel_buffer(const camera2_stream_ops_t* w,
-        buffer_handle_t* buffer) {
-    int state = static_cast<const StreamAdapter*>(w)->mState;
-    if (state != ACTIVE) {
-        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
-        return INVALID_OPERATION;
-    }
-    ANativeWindow *a = toANW(w);
-    return a->cancelBuffer(a,
-            container_of(buffer, ANativeWindowBuffer, handle), -1);
-}
-
-int StreamAdapter::set_crop(const camera2_stream_ops_t* w,
-        int left, int top, int right, int bottom) {
-    int state = static_cast<const StreamAdapter*>(w)->mState;
-    if (state != ACTIVE) {
-        ALOGE("%s: Called when in bad state: %d", __FUNCTION__, state);
-        return INVALID_OPERATION;
-    }
-    ANativeWindow *a = toANW(w);
-    android_native_rect_t crop = { left, top, right, bottom };
-    return native_window_set_crop(a, &crop);
-}
-
-/**
- * FrameWaiter
- */
-
-FrameWaiter::FrameWaiter():
-        mPendingFrames(0) {
-}
-
-status_t FrameWaiter::waitForFrame(nsecs_t timeout) {
-    status_t res;
-    Mutex::Autolock lock(mMutex);
-    while (mPendingFrames == 0) {
-        res = mCondition.waitRelative(mMutex, timeout);
-        if (res != OK) return res;
-    }
-    mPendingFrames--;
-    return OK;
-}
-
-void FrameWaiter::onFrameAvailable(const BufferItem& /* item */) {
-    Mutex::Autolock lock(mMutex);
-    mPendingFrames++;
-    mCondition.signal();
-}
-
-int HWModuleHelpers::closeModule(void *dso) {
-    int status;
-    if (!dso) {
-        return -EINVAL;
-    }
-
-    status = dlclose(dso);
-    if (status != 0) {
-        char const *err_str = dlerror();
-        ALOGE("%s dlclose failed, error: %s", __func__, err_str ?: "unknown");
-    }
-
-    return status;
-}
-
-} // namespace tests
-} // namespace camera2
-} // namespace android
diff --git a/tests/camera2/camera2_utils.h b/tests/camera2/camera2_utils.h
deleted file mode 100644
index 274ee76..0000000
--- a/tests/camera2/camera2_utils.h
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright (C) 2012 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_HAL_CAMERA2_TESTS_UTILS__
-#define __ANDROID_HAL_CAMERA2_TESTS_UTILS__
-
-// Utility classes for camera2 HAL testing
-
-#include <system/camera_metadata.h>
-#include <hardware/camera2.h>
-
-#include <gui/Surface.h>
-#include <gui/CpuConsumer.h>
-
-#include <utils/List.h>
-#include <utils/Mutex.h>
-#include <utils/Condition.h>
-
-namespace android {
-namespace camera2 {
-namespace tests {
-
-/**
- * Queue class for both sending requests to a camera2 device, and for receiving
- * frames from a camera2 device.
- */
-class MetadataQueue: public camera2_request_queue_src_ops_t,
-                    public camera2_frame_queue_dst_ops_t {
-  public:
-    MetadataQueue();
-    ~MetadataQueue();
-
-    // Interface to camera2 HAL device, either for requests (device is consumer)
-    // or for frames (device is producer)
-    const camera2_request_queue_src_ops_t*   getToConsumerInterface();
-    void setFromConsumerInterface(camera2_device_t *d);
-
-    const camera2_frame_queue_dst_ops_t* getToProducerInterface();
-
-    // Real interfaces. On enqueue, queue takes ownership of buffer pointer
-    // On dequeue, user takes ownership of buffer pointer.
-    status_t enqueue(camera_metadata_t *buf);
-    status_t dequeue(camera_metadata_t **buf, bool incrementCount = true);
-    int      getBufferCount();
-    status_t waitForBuffer(nsecs_t timeout);
-
-    // Set repeating buffer(s); if the queue is empty on a dequeue call, the
-    // queue copies the contents of the stream slot into the queue, and then
-    // dequeues the first new entry.
-    status_t setStreamSlot(camera_metadata_t *buf);
-    status_t setStreamSlot(const List<camera_metadata_t*> &bufs);
-
-  private:
-    status_t freeBuffers(List<camera_metadata_t*>::iterator start,
-                         const List<camera_metadata_t*>::iterator& end);
-
-    camera2_device_t *mDevice;
-
-    Mutex mMutex;
-    Condition notEmpty;
-
-    int mFrameCount;
-
-    int mCount;
-    List<camera_metadata_t*> mEntries;
-    int mStreamSlotCount;
-    List<camera_metadata_t*> mStreamSlot;
-
-    bool mSignalConsumer;
-
-    static MetadataQueue* getInstance(const camera2_frame_queue_dst_ops_t *q);
-    static MetadataQueue* getInstance(const camera2_request_queue_src_ops_t *q);
-
-    static int consumer_buffer_count(const camera2_request_queue_src_ops_t *q);
-
-    static int consumer_dequeue(const camera2_request_queue_src_ops_t *q,
-            camera_metadata_t **buffer);
-
-    static int consumer_free(const camera2_request_queue_src_ops_t *q,
-            camera_metadata_t *old_buffer);
-
-    static int producer_dequeue(const camera2_frame_queue_dst_ops_t *q,
-            size_t entries, size_t bytes,
-            camera_metadata_t **buffer);
-
-    static int producer_cancel(const camera2_frame_queue_dst_ops_t *q,
-            camera_metadata_t *old_buffer);
-
-    static int producer_enqueue(const camera2_frame_queue_dst_ops_t *q,
-            camera_metadata_t *filled_buffer);
-
-};
-
-/**
- * Basic class to receive and queue up notifications from the camera device
- */
-
-class NotifierListener {
-  public:
-
-    NotifierListener();
-
-    status_t getNotificationsFrom(camera2_device *dev);
-
-    status_t getNextNotification(int32_t *msg_type, int32_t *ext1,
-            int32_t *ext2, int32_t *ext3);
-
-    status_t waitForNotification(int32_t *msg_type, int32_t *ext1,
-            int32_t *ext2, int32_t *ext3);
-
-    int numNotifications();
-
-  private:
-
-    status_t getNextNotificationLocked(int32_t *msg_type,
-            int32_t *ext1, int32_t *ext2, int32_t *ext3);
-
-    struct Notification {
-        Notification(int32_t type, int32_t e1, int32_t e2, int32_t e3):
-                msg_type(type),
-                ext1(e1),
-                ext2(e2),
-                ext3(e3)
-        {}
-
-        int32_t msg_type;
-        int32_t ext1;
-        int32_t ext2;
-        int32_t ext3;
-    };
-
-    List<Notification> mNotifications;
-
-    Mutex mMutex;
-    Condition mNewNotification;
-
-    void onNotify(int32_t msg_type,
-            int32_t ext1,
-            int32_t ext2,
-            int32_t ext3);
-
-    static void notify_callback_dispatch(int32_t msg_type,
-            int32_t ext1,
-            int32_t ext2,
-            int32_t ext3,
-            void *user);
-
-};
-
-/**
- * Adapter from an IGraphicBufferProducer interface to camera2 device stream ops.
- * Also takes care of allocating/deallocating stream in device interface
- */
-class StreamAdapter: public camera2_stream_ops {
-  public:
-    explicit StreamAdapter(sp<IGraphicBufferProducer> consumer);
-
-    ~StreamAdapter();
-
-    status_t connectToDevice(camera2_device_t *d,
-            uint32_t width, uint32_t height, int format);
-
-    status_t disconnect();
-
-    // Get stream ID. Only valid after a successful connectToDevice call.
-    int      getId();
-
-  private:
-    enum {
-        ERROR = -1,
-        DISCONNECTED = 0,
-        UNINITIALIZED,
-        ALLOCATED,
-        CONNECTED,
-        ACTIVE
-    } mState;
-
-    sp<ANativeWindow> mConsumerInterface;
-    camera2_device_t *mDevice;
-
-    uint32_t mId;
-    uint32_t mWidth;
-    uint32_t mHeight;
-    uint32_t mFormat;
-    uint32_t mUsage;
-    uint32_t mMaxProducerBuffers;
-    uint32_t mMaxConsumerBuffers;
-
-    const camera2_stream_ops *getStreamOps();
-
-    static ANativeWindow* toANW(const camera2_stream_ops_t *w);
-
-    static int dequeue_buffer(const camera2_stream_ops_t *w,
-            buffer_handle_t** buffer);
-
-    static int enqueue_buffer(const camera2_stream_ops_t* w,
-            int64_t timestamp,
-            buffer_handle_t* buffer);
-
-    static int cancel_buffer(const camera2_stream_ops_t* w,
-            buffer_handle_t* buffer);
-
-    static int set_crop(const camera2_stream_ops_t* w,
-            int left, int top, int right, int bottom);
-
-};
-
-/**
- * Simple class to wait on the CpuConsumer to have a frame available
- */
-class FrameWaiter : public CpuConsumer::FrameAvailableListener {
-  public:
-    FrameWaiter();
-
-    /**
-     * Wait for max timeout nanoseconds for a new frame. Returns
-     * OK if a frame is available, TIMED_OUT if the timeout was reached.
-     */
-    status_t waitForFrame(nsecs_t timeout);
-
-    virtual void onFrameAvailable(const BufferItem& item);
-
-    int mPendingFrames;
-    Mutex mMutex;
-    Condition mCondition;
-};
-
-struct HWModuleHelpers {
-    /* attempt to unload the library with dlclose */
-    static int closeModule(void* dso);
-};
-
-}
-}
-}
-
-#endif
diff --git a/tests/camera2/main.cpp b/tests/camera2/main.cpp
deleted file mode 100644
index e0ebbe9..0000000
--- a/tests/camera2/main.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#include <gtest/gtest.h>
-#include "TestForkerEventListener.h"
-#include "TestSettings.h"
-
-using android::camera2::tests::TestForkerEventListener;
-using android::camera2::tests::TestSettings;
-
-int main(int argc, char **argv) {
-
-    bool printUsage = !TestSettings::ParseArgs(argc, argv);
-
-    ::testing::InitGoogleTest(&argc, argv);
-
-    if (printUsage) {
-        TestSettings::PrintUsage();
-        return 0;
-    }
-
-    // Gets hold of the event listener list.
-    ::testing::TestEventListeners& listeners =
-        ::testing::UnitTest::GetInstance()->listeners();
-    // Adds a listener to the end.  Google Test takes the ownership.
-    listeners.Append(new TestForkerEventListener());
-
-    int ret = RUN_ALL_TESTS();
-
-    return ret;
-}
