diff --git a/include/hardware/ble_advertiser.h b/include/hardware/ble_advertiser.h
index 8abca00..02d553f 100644
--- a/include/hardware/ble_advertiser.h
+++ b/include/hardware/ble_advertiser.h
@@ -57,6 +57,9 @@
   /** Registers an advertiser with the stack */
   virtual void RegisterAdvertiser(IdStatusCallback) = 0;
 
+  using GetAddressCallback = base::Callback<void(uint8_t /* address_type*/, bt_bdaddr_t /*address*/)>;
+  virtual void GetOwnAddress(uint8_t advertiser_id, GetAddressCallback cb) = 0;
+
   /* Set the parameters as per spec, user manual specified values */
   virtual void SetParameters(uint8_t advertiser_id, AdvertiseParameters params,
                              ParametersCallback cb) = 0;
diff --git a/include/hardware/bt_gatt_client.h b/include/hardware/bt_gatt_client.h
index ec8dd16..33a6825 100644
--- a/include/hardware/bt_gatt_client.h
+++ b/include/hardware/bt_gatt_client.h
@@ -224,8 +224,13 @@
     bt_status_t (*search_service)(int conn_id, bt_uuid_t *filter_uuid );
 
     /** Read a characteristic on a remote device */
-    bt_status_t (*read_characteristic)( int conn_id, uint16_t handle,
-                    int auth_req );
+    bt_status_t (*read_characteristic)(int conn_id, uint16_t handle,
+                                       int auth_req);
+
+    /** Read a characteristic on a remote device */
+    bt_status_t (*read_using_characteristic_uuid)(
+        int conn_id, bt_uuid_t *uuid, uint16_t s_handle,
+        uint16_t e_handle, int auth_req);
 
     /** Write a remote characteristic */
     bt_status_t (*write_characteristic)(int conn_id, uint16_t handle,
diff --git a/modules/sensors/dynamic_sensor/ConnectionDetector.cpp b/modules/sensors/dynamic_sensor/ConnectionDetector.cpp
index 67a6f27..c51e912 100644
--- a/modules/sensors/dynamic_sensor/ConnectionDetector.cpp
+++ b/modules/sensors/dynamic_sensor/ConnectionDetector.cpp
@@ -105,30 +105,35 @@
 // FileConnectionDetector functions
 FileConnectionDetector::FileConnectionDetector (
         BaseDynamicSensorDaemon *d, const std::string &path, const std::string &regex)
-            : ConnectionDetector(d), Thread(false /*callCallJava*/), mPath(path), mRegex(regex) {
+            : ConnectionDetector(d), Thread(false /*callCallJava*/), mPath(path), mRegex(regex),
+              mLooper(new Looper(true /*allowNonCallback*/)), mInotifyFd(-1) {
+    if (mLooper == nullptr) {
+        return;
+    }
+
     mInotifyFd = ::inotify_init1(IN_NONBLOCK);
     if (mInotifyFd < 0) {
         ALOGE("Cannot init inotify");
         return;
     }
 
-    int wd = ::inotify_add_watch(mInotifyFd, path.c_str(), IN_CREATE | IN_DELETE | IN_MOVED_FROM);
-    if (wd < 0) {
+    int wd = ::inotify_add_watch(mInotifyFd, path.c_str(), IN_CREATE | IN_DELETE);
+    if (wd < 0 || !mLooper->addFd(mInotifyFd, POLL_IDENT, Looper::EVENT_INPUT, nullptr, nullptr)) {
         ::close(mInotifyFd);
         mInotifyFd = -1;
         ALOGE("Cannot setup watch on dir %s", path.c_str());
         return;
     }
 
-    mPollFd.fd = wd;
-    mPollFd.events = POLLIN;
-
+    // mLooper != null && mInotifyFd added to looper
     run("ddad_file");
 }
 
 FileConnectionDetector::~FileConnectionDetector() {
-    if (mInotifyFd) {
-        requestExitAndWait();
+    if (mInotifyFd > 0) {
+        requestExit();
+        mLooper->wake();
+        join();
         ::close(mInotifyFd);
     }
 }
@@ -153,63 +158,81 @@
     ::closedir(dirp);
 }
 
-bool FileConnectionDetector::threadLoop() {
-    struct {
-        struct inotify_event e;
-        uint8_t padding[NAME_MAX + 1];
-    } ev;
+void FileConnectionDetector::handleInotifyData(ssize_t len, const char *data) {
+    const char *dataEnd = data + len;
+    const struct inotify_event *ev;
 
-    processExistingFiles();
-
-    while (!Thread::exitPending()) {
-        int pollNum = ::poll(&mPollFd, 1, -1);
-        if (pollNum == -1) {
-           if (errno == EINTR)
-               continue;
-           ALOGE("inotify poll error: %s", ::strerror(errno));
+    // inotify adds paddings to guarantee the next read is aligned
+    for (; data < dataEnd; data += sizeof(struct inotify_event) + ev->len) {
+        ev = reinterpret_cast<const struct inotify_event*>(data);
+        if (ev->mask & IN_ISDIR) {
+            continue;
         }
 
-        if (pollNum > 0) {
-            if (! (mPollFd.revents & POLLIN)) {
-                continue;
+        const std::string name(ev->name);
+        if (matches(name)) {
+            if (ev->mask & IN_CREATE) {
+                mDaemon->onConnectionChange(getFullName(name), true /*connected*/);
             }
+            if (ev->mask & IN_DELETE) {
+                mDaemon->onConnectionChange(getFullName(name), false /*connected*/);
+            }
+        }
+    }
+}
 
-            /* Inotify events are available */
-            while (true) {
-                /* Read some events. */
-                ssize_t len = ::read(mInotifyFd, &ev, sizeof ev);
-                if (len == -1 && errno != EAGAIN) {
-                    ALOGE("read error: %s", ::strerror(errno));
-                    requestExit();
-                    break;
-                }
+bool FileConnectionDetector::readInotifyData() {
+    struct {
+        struct inotify_event ev;
+        char padding[NAME_MAX + 1];
+    } buffer;
 
-                /* If the nonblocking read() found no events to read, then
-                   it returns -1 with errno set to EAGAIN. In that case,
-                   we exit the loop. */
-                if (len <= 0) {
-                    break;
-                }
+    bool ret = true;
+    while (true) {
+        ssize_t len = ::read(mInotifyFd, &buffer, sizeof(buffer));
+        if (len == -1 && errno == EAGAIN) {
+            // no more data
+            break;
+        } else if (len > static_cast<ssize_t>(sizeof(struct inotify_event))) {
+            handleInotifyData(len, reinterpret_cast<char*>(&buffer));
+        } else if (len < 0) {
+            ALOGE("read error: %s", ::strerror(errno));
+            ret = false;
+            break;
+        } else {
+            // 0 <= len <= sizeof(struct inotify_event)
+            ALOGE("read return %zd, shorter than inotify_event size %zu",
+                  len, sizeof(struct inotify_event));
+            ret = false;
+            break;
+        }
+    }
+    return ret;
+}
 
-                if (ev.e.len && !(ev.e.mask & IN_ISDIR)) {
-                    const std::string name(ev.e.name);
-                    ALOGV("device %s state changed", name.c_str());
-                    if (matches(name)) {
-                        if (ev.e.mask & IN_CREATE) {
-                            mDaemon->onConnectionChange(getFullName(name), true /* connected*/);
-                        }
+bool FileConnectionDetector::threadLoop() {
+    Looper::setForThread(mLooper);
+    processExistingFiles();
+    while(!Thread::exitPending()) {
+        int ret = mLooper->pollOnce(-1);
 
-                        if (ev.e.mask & IN_DELETE || ev.e.mask & IN_MOVED_FROM) {
-                            mDaemon->onConnectionChange(getFullName(name), false /* connected*/);
-                        }
-                    }
-                }
+        if (ret != Looper::POLL_WAKE && ret != POLL_IDENT) {
+            ALOGE("Unexpected value %d from pollOnce, quit", ret);
+            requestExit();
+            break;
+        }
+
+        if (ret == POLL_IDENT) {
+            if (!readInotifyData()) {
+                requestExit();
             }
         }
     }
 
+    mLooper->removeFd(mInotifyFd);
     ALOGD("FileConnectionDetection thread exited");
     return false;
 }
+
 } // namespace SensorHalExt
 } // namespace android
diff --git a/modules/sensors/dynamic_sensor/ConnectionDetector.h b/modules/sensors/dynamic_sensor/ConnectionDetector.h
index 712d832..0ee1df2 100644
--- a/modules/sensors/dynamic_sensor/ConnectionDetector.h
+++ b/modules/sensors/dynamic_sensor/ConnectionDetector.h
@@ -19,6 +19,7 @@
 
 #include "BaseDynamicSensorDaemon.h"
 #include <utils/Thread.h>
+#include <utils/Looper.h>
 
 #include <regex>
 
@@ -62,17 +63,20 @@
             BaseDynamicSensorDaemon *d, const std::string &path, const std::string &regex);
     virtual ~FileConnectionDetector();
 private:
+    static constexpr int POLL_IDENT = 1;
     // implement virtual of Thread
     virtual bool threadLoop();
 
     bool matches(const std::string &name) const;
     void processExistingFiles() const;
+    void handleInotifyData(ssize_t len, const char *data);
+    bool readInotifyData();
     std::string getFullName(const std::string name) const;
 
     std::string mPath;
     std::regex mRegex;
+    sp<Looper> mLooper;
     int mInotifyFd;
-    struct pollfd mPollFd;
 };
 
 } // namespace SensorHalExt
diff --git a/modules/sensors/dynamic_sensor/HidRawSensorDevice.cpp b/modules/sensors/dynamic_sensor/HidRawSensorDevice.cpp
index 16e9060..8aa4cf9 100644
--- a/modules/sensors/dynamic_sensor/HidRawSensorDevice.cpp
+++ b/modules/sensors/dynamic_sensor/HidRawSensorDevice.cpp
@@ -37,7 +37,7 @@
 
 sp<HidRawSensorDevice> HidRawSensorDevice::create(const std::string &devName) {
     sp<HidRawSensorDevice> device(new HidRawSensorDevice(devName));
-    // remove +1 strong count added by constructor
+    // offset +1 strong count added by constructor
     device->decStrong(device.get());
 
     if (device->mValid) {
@@ -50,13 +50,15 @@
 HidRawSensorDevice::HidRawSensorDevice(const std::string &devName)
         : RefBase(), HidRawDevice(devName, sInterested),
           Thread(false /*canCallJava*/), mValid(false) {
-    if (!HidRawDevice::isValid()) {
-        return;
-    }
     // create HidRawSensor objects from digest
     // HidRawSensor object will take sp<HidRawSensorDevice> as parameter, so increment strong count
     // to prevent "this" being destructed.
     this->incStrong(this);
+
+    if (!HidRawDevice::isValid()) {
+        return;
+    }
+
     for (const auto &digest : mDigestVector) { // for each usage - vec<ReportPacket> pair
         uint32_t usage = static_cast<uint32_t>(digest.fullUsage);
         sp<HidRawSensor> s(new HidRawSensor(this, usage, digest.packets));
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;
-}
