am 65b35c04: am 48697f6d: Fix HWC documentation.

* commit '65b35c047433a413617a877d9785d36c9da4b612':
  Fix HWC documentation.
diff --git a/include/hardware/audio_effect.h b/include/hardware/audio_effect.h
index 46e323d..2c8f2e3 100644
--- a/include/hardware/audio_effect.h
+++ b/include/hardware/audio_effect.h
@@ -873,8 +873,10 @@
 //      Effect library interface
 /////////////////////////////////////////////////
 
-// Effect library interface version 2.0
-#define EFFECT_LIBRARY_API_VERSION EFFECT_MAKE_API_VERSION(2,0)
+// Effect library interface version 3.0
+// Note that EffectsFactory.c only checks the major version component, so changes to the minor
+// number can only be used for fully backwards compatible changes
+#define EFFECT_LIBRARY_API_VERSION EFFECT_MAKE_API_VERSION(3,0)
 
 #define AUDIO_EFFECT_LIBRARY_TAG ((('A') << 24) | (('E') << 16) | (('L') << 8) | ('T'))
 
@@ -893,57 +895,6 @@
 
     ////////////////////////////////////////////////////////////////////////////////
     //
-    //    Function:        query_num_effects
-    //
-    //    Description:    Returns the number of different effects exposed by the
-    //          library. Each effect must have a unique effect uuid (see
-    //          effect_descriptor_t). This function together with EffectQueryEffect()
-    //          is used to enumerate all effects present in the library.
-    //
-    //    Input/Output:
-    //          pNumEffects:    address where the number of effects should be returned.
-    //
-    //    Output:
-    //        returned value:    0          successful operation.
-    //                          -ENODEV     library failed to initialize
-    //                          -EINVAL     invalid pNumEffects
-    //        *pNumEffects:     updated with number of effects in library
-    //
-    ////////////////////////////////////////////////////////////////////////////////
-    int32_t (*query_num_effects)(uint32_t *pNumEffects);
-
-    ////////////////////////////////////////////////////////////////////////////////
-    //
-    //    Function:        query_effect
-    //
-    //    Description:    Returns the descriptor of the effect engine which index is
-    //          given as argument.
-    //          See effect_descriptor_t for details on effect descriptors.
-    //          This function together with EffectQueryNumberEffects() is used to enumerate all
-    //          effects present in the library. The enumeration sequence is:
-    //              EffectQueryNumberEffects(&num_effects);
-    //              for (i = 0; i < num_effects; i++)
-    //                  EffectQueryEffect(i,...);
-    //
-    //    Input/Output:
-    //          index:          index of the effect
-    //          pDescriptor:    address where to return the effect descriptor.
-    //
-    //    Output:
-    //        returned value:    0          successful operation.
-    //                          -ENODEV     library failed to initialize
-    //                          -EINVAL     invalid pDescriptor or index
-    //                          -ENOSYS     effect list has changed since last execution of
-    //                                      EffectQueryNumberEffects()
-    //                          -ENOENT     no more effect available
-    //        *pDescriptor:     updated with the effect descriptor.
-    //
-    ////////////////////////////////////////////////////////////////////////////////
-    int32_t (*query_effect)(uint32_t index,
-                            effect_descriptor_t *pDescriptor);
-
-    ////////////////////////////////////////////////////////////////////////////////
-    //
     //    Function:        create_effect
     //
     //    Description:    Creates an effect engine of the specified implementation uuid and
diff --git a/include/hardware/sensors.h b/include/hardware/sensors.h
index af6bced..e0ed8a9 100644
--- a/include/hardware/sensors.h
+++ b/include/hardware/sensors.h
@@ -26,6 +26,12 @@
 
 __BEGIN_DECLS
 
+/*****************************************************************************/
+
+#define SENSORS_HEADER_VERSION          1
+#define SENSORS_MODULE_API_VERSION_0_1  HARDWARE_MODULE_API_VERSION(0, 1)
+#define SENSORS_DEVICE_API_VERSION_0_1  HARDWARE_DEVICE_API_VERSION_2(0, 1, SENSORS_HEADER_VERSION)
+
 /**
  * The id of this module
  */
@@ -48,49 +54,7 @@
 
 
 /**
- * Sensor types
- */
-#define SENSOR_TYPE_ACCELEROMETER       1
-#define SENSOR_TYPE_MAGNETIC_FIELD      2
-#define SENSOR_TYPE_ORIENTATION         3
-#define SENSOR_TYPE_GYROSCOPE           4
-#define SENSOR_TYPE_LIGHT               5
-#define SENSOR_TYPE_PRESSURE            6
-#define SENSOR_TYPE_TEMPERATURE         7   // deprecated
-#define SENSOR_TYPE_PROXIMITY           8
-#define SENSOR_TYPE_GRAVITY             9
-#define SENSOR_TYPE_LINEAR_ACCELERATION 10
-#define SENSOR_TYPE_ROTATION_VECTOR     11
-#define SENSOR_TYPE_RELATIVE_HUMIDITY   12
-#define SENSOR_TYPE_AMBIENT_TEMPERATURE 13
-
-/**
- * Values returned by the accelerometer in various locations in the universe.
- * all values are in SI units (m/s^2)
- */
-
-#define GRAVITY_SUN             (275.0f)
-#define GRAVITY_EARTH           (9.80665f)
-
-/** Maximum magnetic field on Earth's surface */
-#define MAGNETIC_FIELD_EARTH_MAX    (60.0f)
-
-/** Minimum magnetic field on Earth's surface */
-#define MAGNETIC_FIELD_EARTH_MIN    (30.0f)
-
-
-/**
- * status of each sensor
- */
-
-#define SENSOR_STATUS_UNRELIABLE        0
-#define SENSOR_STATUS_ACCURACY_LOW      1
-#define SENSOR_STATUS_ACCURACY_MEDIUM   2
-#define SENSOR_STATUS_ACCURACY_HIGH     3
-
-/**
- * Definition of the axis
- * ----------------------
+ * Definition of the axis used by the sensor HAL API
  *
  * This API is relative to the screen of the device in its default orientation,
  * that is, if the device can be used in portrait or landscape, this API
@@ -117,9 +81,60 @@
  *
  *    O: Origin (x=0,y=0,z=0)
  *
+ */
+
+
+/*
+ * SENSOR_TYPE_ACCELEROMETER
  *
+ *  All values are in SI units (m/s^2) and measure the acceleration of the
+ *  device minus the force of gravity.
+ *
+ *  Acceleration sensors return sensor events for all 3 axes at a constant
+ *  rate defined by setDelay().
+ *
+ *  x: Acceleration on the x-axis
+ *  y: Acceleration on the y-axis
+ *  z: Acceleration on the z-axis
+ *
+ * Note that the readings from the accelerometer include the acceleration
+ * due to gravity (which is opposite to the direction of the gravity vector).
+ *
+ *  Examples:
+ *    The norm of <x, y, z>  should be close to 0 when in free fall.
+ *
+ *    When the device lies flat on a table and is pushed on its left side
+ *    toward the right, the x acceleration value is positive.
+ *
+ *    When the device lies flat on a table, the acceleration value is +9.81,
+ *    which correspond to the acceleration of the device (0 m/s^2) minus the
+ *    force of gravity (-9.81 m/s^2).
+ *
+ *    When the device lies flat on a table and is pushed toward the sky, the
+ *    acceleration value is greater than +9.81, which correspond to the
+ *    acceleration of the device (+A m/s^2) minus the force of
+ *    gravity (-9.81 m/s^2).
+ */
+#define SENSOR_TYPE_ACCELEROMETER                    (1)
+
+/*
+ * SENSOR_TYPE_GEOMAGNETIC_FIELD
+ *
+ *  All values are in micro-Tesla (uT) and measure the geomagnetic
+ *  field in the X, Y and Z axis.
+ *
+ *  Returned values include calibration mechanisms such that the vector is
+ *  aligned with the magnetic declination and heading of the earth's
+ *  geomagnetic field.
+ *
+ *  Magnetic Field sensors return sensor events for all 3 axes at a constant
+ *  rate defined by setDelay().
+ */
+#define SENSOR_TYPE_GEOMAGNETIC_FIELD                (2)
+#define SENSOR_TYPE_MAGNETIC_FIELD  SENSOR_TYPE_GEOMAGNETIC_FIELD
+
+/*
  * SENSOR_TYPE_ORIENTATION
- * -----------------------
  * 
  * All values are angles in degrees.
  * 
@@ -153,46 +168,11 @@
  *
  * Note: This definition is different from yaw, pitch and roll used in aviation
  *  where the X axis is along the long side of the plane (tail to nose).
- *  
- *  
- * SENSOR_TYPE_ACCELEROMETER
- * -------------------------
- *
- *  All values are in SI units (m/s^2) and measure the acceleration of the
- *  device minus the force of gravity.
- *  
- *  Acceleration sensors return sensor events for all 3 axes at a constant
- *  rate defined by setDelay().
- *
- *  x: Acceleration minus Gx on the x-axis 
- *  y: Acceleration minus Gy on the y-axis 
- *  z: Acceleration minus Gz on the z-axis
- *  
- *  Examples:
- *    When the device lies flat on a table and is pushed on its left side
- *    toward the right, the x acceleration value is positive.
- *    
- *    When the device lies flat on a table, the acceleration value is +9.81,
- *    which correspond to the acceleration of the device (0 m/s^2) minus the
- *    force of gravity (-9.81 m/s^2).
- *    
- *    When the device lies flat on a table and is pushed toward the sky, the
- *    acceleration value is greater than +9.81, which correspond to the
- *    acceleration of the device (+A m/s^2) minus the force of 
- *    gravity (-9.81 m/s^2).
- *    
- *    
- * SENSOR_TYPE_MAGNETIC_FIELD
- * --------------------------
- * 
- *  All values are in micro-Tesla (uT) and measure the ambient magnetic
- *  field in the X, Y and Z axis.
- *
- *  Magnetic Field sensors return sensor events for all 3 axes at a constant
- *  rate defined by setDelay().
- *
+ */
+#define SENSOR_TYPE_ORIENTATION                      (3)
+
+/*
  * SENSOR_TYPE_GYROSCOPE
- * ---------------------
  *
  *  All values are in radians/second and measure the rate of rotation
  *  around the X, Y and Z axis.  The coordinate system is the same as is
@@ -205,8 +185,34 @@
  *  with the definition of roll given earlier.
  *  The range should at least be 17.45 rad/s (ie: ~1000 deg/s).
  *
+ *  automatic gyro-drift compensation is allowed but not required.
+ */
+#define SENSOR_TYPE_GYROSCOPE                        (4)
+
+/*
+ * SENSOR_TYPE_LIGHT
+ *
+ * The light sensor value is returned in SI lux units.
+ *
+ * Light sensors report a value only when it changes and each time the
+ * sensor is enabled.
+ */
+#define SENSOR_TYPE_LIGHT                            (5)
+
+/*
+ * SENSOR_TYPE_PRESSURE
+ *
+ * The pressure sensor return the athmospheric pressure in hectopascal (hPa)
+ *
+ * Pressure sensors report events at a constant rate defined by setDelay().
+ */
+#define SENSOR_TYPE_PRESSURE                         (6)
+
+/* SENSOR_TYPE_TEMPERATURE is deprecated in the HAL */
+#define SENSOR_TYPE_TEMPERATURE                      (7)
+
+/*
  * SENSOR_TYPE_PROXIMITY
- * ----------------------
  *
  * The distance value is measured in centimeters.  Note that some proximity
  * sensors only support a binary "close" or "far" measurement.  In this case,
@@ -215,42 +221,38 @@
  *
  * Proximity sensors report a value only when it changes and each time the
  * sensor is enabled.
- *
- * SENSOR_TYPE_LIGHT
- * -----------------
- *
- * The light sensor value is returned in SI lux units.
- *
- * Light sensors report a value only when it changes and each time the
- * sensor is enabled.
- *
- * SENSOR_TYPE_PRESSURE
- * --------------------
- *
- * The pressure sensor return the athmospheric pressure in hectopascal (hPa)
- *
- * Pressure sensors report events at a constant rate defined by setDelay().
- *
+ */
+#define SENSOR_TYPE_PROXIMITY                        (8)
+
+/*
  * SENSOR_TYPE_GRAVITY
- * -------------------
  *
  * A gravity output indicates the direction of and magnitude of gravity in
  * the devices's coordinates.  On Earth, the magnitude is 9.8 m/s^2.
  * Units are m/s^2.  The coordinate system is the same as is used for the
  * acceleration sensor. When the device is at rest, the output of the
  * gravity sensor should be identical to that of the accelerometer.
- *
+ */
+#define SENSOR_TYPE_GRAVITY                          (9)
+
+/*
  * SENSOR_TYPE_LINEAR_ACCELERATION
- * --------------------------------
  *
  * Indicates the linear acceleration of the device in device coordinates,
  * not including gravity.
- * This output is essentially Acceleration - Gravity.  Units are m/s^2.
+ *
+ * The output is conceptually:
+ *    output of TYPE_ACCELERATION - output of TYPE_GRAVITY
+ *
+ * Readings on all axes should be close to 0 when device lies on a table.
+ * Units are m/s^2.
  * The coordinate system is the same as is used for the acceleration sensor.
- *
- *
+ */
+#define SENSOR_TYPE_LINEAR_ACCELERATION             (10)
+
+
+/*
  * SENSOR_TYPE_ROTATION_VECTOR
- * ---------------------------
  *
  * A rotation vector represents the orientation of the device as a combination
  * of an angle and an axis, in which the device has rotated through an angle
@@ -281,28 +283,110 @@
  *   sensors_event_t.data[1] = y*sin(theta/2)
  *   sensors_event_t.data[2] = z*sin(theta/2)
  *   sensors_event_t.data[3] =   cos(theta/2)
- *
- *
+ */
+#define SENSOR_TYPE_ROTATION_VECTOR                 (11)
+
+/*
  * SENSOR_TYPE_RELATIVE_HUMIDITY
- * ------------------------------
  *
  * A relative humidity sensor measures relative ambient air humidity and
  * returns a value in percent.
  *
  * Relative humidity sensors report a value only when it changes and each
  * time the sensor is enabled.
- *
- *
+ */
+#define SENSOR_TYPE_RELATIVE_HUMIDITY               (12)
+
+/*
  * SENSOR_TYPE_AMBIENT_TEMPERATURE
- * -------------------------------
  *
  * The ambient (room) temperature in degree Celsius.
  *
  * Temperature sensors report a value only when it changes and each time the
  * sensor is enabled.
+ */
+#define SENSOR_TYPE_AMBIENT_TEMPERATURE             (13)
+
+/*
+ * SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED
  *
+ *  All values are in micro-Tesla (uT) and measure the ambient magnetic
+ *  field in the X, Y and Z axis.
+ *
+ *  No periodic calibration is performed (ie: there are no discontinuities
+ *  in the data stream while using this sensor). Assumptions that the the
+ *  magnetic field is due to the Earth's poles should be avoided.
+ *
+ *  Factory calibration and temperature compensation should still be applied.
+ *
+ *  Magnetic Field sensors return sensor events for all 3 axes at a constant
+ *  rate defined by setDelay().
+ */
+#define SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED     (14)
+
+/*
+ * SENSOR_TYPE_GAME_ROTATION_VECTOR
+ *
+ * SENSOR_TYPE_GAME_ROTATION_VECTOR is identical to SENSOR_TYPE_ROTATION_VECTOR,
+ * except that it doesn't use the geomagnetic field. Therefore the Y axis doesn't
+ * point north, but instead to some other reference, that reference is allowed
+ * to drift by the same order of magnitude than the gyroscope drift around
+ * the Z axis.
+ *
+ * In the ideal case, a phone rotated and returning to the same real-world
+ * orientation should report the same game rotation vector
+ * (without using the earth's geomagnetic field).
+ *
+ * see SENSOR_TYPE_ROTATION_VECTOR for more details
+ */
+#define SENSOR_TYPE_GAME_ROTATION_VECTOR            (15)
+
+/*
+ * SENSOR_TYPE_GYROSCOPE_UNCALIBRATED
+ *
+ *  All values are in radians/second and measure the rate of rotation
+ *  around the X, Y and Z axis.  The coordinate system is the same as is
+ *  used for the acceleration sensor. Rotation is positive in the
+ *  counter-clockwise direction (right-hand rule). That is, an observer
+ *  looking from some positive location on the x, y or z axis at a device
+ *  positioned on the origin would report positive rotation if the device
+ *  appeared to be rotating counter clockwise. Note that this is the
+ *  standard mathematical definition of positive rotation and does not agree
+ *  with the definition of roll given earlier.
+ *  The range should at least be 17.45 rad/s (ie: ~1000 deg/s).
+ *
+ *  No gyro-drift compensation shall be performed.
+ *  Factory calibration and temperature compensation should still be applied.
+ */
+#define SENSOR_TYPE_GYROSCOPE_UNCALIBRATED          (16)
+
+/**
+ * Values returned by the accelerometer in various locations in the universe.
+ * all values are in SI units (m/s^2)
+ */
+#define GRAVITY_SUN             (275.0f)
+#define GRAVITY_EARTH           (9.80665f)
+
+/** Maximum magnetic field on Earth's surface */
+#define MAGNETIC_FIELD_EARTH_MAX    (60.0f)
+
+/** Minimum magnetic field on Earth's surface */
+#define MAGNETIC_FIELD_EARTH_MIN    (30.0f)
+
+
+/**
+ * status of orientation sensor
  */
 
+#define SENSOR_STATUS_UNRELIABLE        0
+#define SENSOR_STATUS_ACCURACY_LOW      1
+#define SENSOR_STATUS_ACCURACY_MEDIUM   2
+#define SENSOR_STATUS_ACCURACY_HIGH     3
+
+
+/**
+ * sensor event data
+ */
 typedef struct {
     union {
         float v[3];
diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp
index 3756274..e9759e5 100755
--- a/modules/audio_remote_submix/audio_hw.cpp
+++ b/modules/audio_remote_submix/audio_hw.cpp
@@ -571,8 +571,7 @@
     // initialize pipe
     {
         ALOGV("  initializing pipe");
-        const NBAIO_Format format =
-                config->sample_rate == 48000 ? Format_SR48_C2_I16 : Format_SR44_1_C2_I16;
+        const NBAIO_Format format = Format_from_SR_C(config->sample_rate, 2);
         const NBAIO_Format offers[1] = {format};
         size_t numCounterOffers = 0;
         // creating a MonoPipe with optional blocking set to true.
diff --git a/tests/camera2/Android.mk b/tests/camera2/Android.mk
index c378e12..e9a8ebc 100644
--- a/tests/camera2/Android.mk
+++ b/tests/camera2/Android.mk
@@ -3,20 +3,27 @@
 
 LOCAL_SRC_FILES:= \
 	camera2.cpp \
-	camera2_utils.cpp
+	camera2_utils.cpp \
+	main.cpp \
+	CameraMetadataTests.cpp \
+	CameraModuleTests.cpp \
+	CameraStreamTests.cpp \
+	CameraFrameTests.cpp \
 
 LOCAL_SHARED_LIBRARIES := \
 	libutils \
+	libcutils \
 	libstlport \
 	libhardware \
 	libcamera_metadata \
+	libcameraservice \
 	libgui \
 	libsync \
-	libui
+	libui \
+	libdl
 
 LOCAL_STATIC_LIBRARIES := \
-	libgtest \
-	libgtest_main
+	libgtest
 
 LOCAL_C_INCLUDES += \
 	bionic \
@@ -24,6 +31,8 @@
 	external/gtest/include \
 	external/stlport/stlport \
 	system/media/camera/include \
+	frameworks/av/services/camera/libcameraservice \
+	frameworks/native/include \
 
 LOCAL_MODULE:= camera2_test
 LOCAL_MODULE_TAGS := tests
diff --git a/tests/camera2/CameraFrameTests.cpp b/tests/camera2/CameraFrameTests.cpp
new file mode 100644
index 0000000..9e3482c
--- /dev/null
+++ b/tests/camera2/CameraFrameTests.cpp
@@ -0,0 +1,128 @@
+/*
+ * 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 "Camera2Device.h"
+#include "utils/StrongPointer.h"
+
+#include <gui/CpuConsumer.h>
+#include <gui/SurfaceTextureClient.h>
+
+#include <unistd.h>
+
+#include "CameraStreamFixture.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 = {
+    /*mCameraId*/   0,
+    /*mFormat*/     HAL_PIXEL_FORMAT_YCrCb_420_SP,
+    /*mHeapCount*/  CAMERA_HEAP_COUNT
+};
+
+class CameraFrameTest
+    : public ::testing::TestWithParam<int>,
+      public CameraStreamFixture {
+
+public:
+    CameraFrameTest() : CameraStreamFixture(STREAM_PARAMETERS) {
+        if (!HasFatalFailure()) {
+            CreateStream();
+        }
+    }
+
+    ~CameraFrameTest() {
+        if (mDevice.get()) {
+            mDevice->waitUntilDrained();
+        }
+        DeleteStream();
+    }
+
+    virtual void SetUp() {
+    }
+    virtual void TearDown() {
+    }
+
+protected:
+
+};
+
+TEST_P(CameraFrameTest, GetFrame) {
+
+    if (HasFatalFailure()) {
+        return;
+    }
+
+    /* 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<uint8_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");
+        CameraMetadata tmpRequest = previewRequest;
+        ASSERT_EQ(OK, mDevice->capture(tmpRequest));
+    }
+
+    for (int i = 0; i < GetParam(); ++i) {
+        ASSERT_EQ(OK, mDevice->waitForNextFrame(CAMERA_FRAME_TIMEOUT));
+        CameraMetadata frameMetadata;
+        ASSERT_EQ(OK, mDevice->getNextFrame(&frameMetadata));
+    }
+
+}
+
+//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
new file mode 100644
index 0000000..739eba6
--- /dev/null
+++ b/tests/camera2/CameraMetadataTests.cpp
@@ -0,0 +1,126 @@
+/*
+ * 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 "Camera2Device.h"
+#include "utils/StrongPointer.h"
+
+#include <gui/CpuConsumer.h>
+#include <gui/SurfaceTextureClient.h>
+
+#include <string>
+#include "CameraStreamFixture.h"
+
+namespace android {
+namespace camera2 {
+namespace tests {
+
+//FIXME: dont hardcode
+static CameraStreamParams METADATA_STREAM_PARAMETERS = {
+    /*mCameraId*/   0,
+    /*mFormat*/     HAL_PIXEL_FORMAT_YCrCb_420_SP,
+    /*mHeapCount*/  2
+};
+
+class DISABLED_CameraMetadataTest
+    : public ::testing::Test,
+      public CameraStreamFixture {
+
+public:
+    DISABLED_CameraMetadataTest()
+    : CameraStreamFixture(METADATA_STREAM_PARAMETERS) {
+    }
+
+    ~DISABLED_CameraMetadataTest() {
+    }
+
+    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;
+    }
+
+    static void SetUpTestCase() {
+    }
+
+    static void TearDownTestCase()
+    {
+    }
+
+protected:
+
+};
+
+TEST_F(DISABLED_CameraMetadataTest, types) {
+
+    if (HasFatalFailure()) {
+        return;
+    }
+
+    //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);
+    }
+}
+
+}
+}
+}
diff --git a/tests/camera2/CameraModuleFixture.h b/tests/camera2/CameraModuleFixture.h
new file mode 100644
index 0000000..f000fdf
--- /dev/null
+++ b/tests/camera2/CameraModuleFixture.h
@@ -0,0 +1,107 @@
+/*
+ * 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 "hardware/hardware.h"
+#include "hardware/camera2.h"
+
+#include "Camera2Device.h"
+#include "camera2_utils.h"
+
+namespace android {
+namespace camera2 {
+namespace tests {
+
+template <bool InfoQuirk = false>
+struct CameraModuleFixture {
+
+    CameraModuleFixture(int CameraID = -1) {
+        mCameraID = CameraID;
+
+        SetUp();
+    }
+
+    ~CameraModuleFixture() {
+        TearDown();
+    }
+
+private:
+
+    void SetUp() {
+        ASSERT_LE(0, hw_get_module(CAMERA_HARDWARE_MODULE_ID,
+            (const hw_module_t **)&mModule)) << "Could not load camera module";
+        ASSERT_NE((void*)0, mModule);
+
+        mNumberOfCameras = mModule->get_number_of_cameras();
+        ASSERT_LE(0, mNumberOfCameras);
+
+        ASSERT_EQ(
+            CAMERA_MODULE_API_VERSION_2_0, mModule->common.module_api_version)
+            << "Wrong module API version";
+
+        /* For using this fixture in other tests only */
+        SetUpMixin();
+    }
+
+    void TearDown() {
+        TearDownMixin();
+
+        /* important: device must be destructed before closing module,
+           since it calls back into HAL */
+        mDevice.clear();
+
+        ASSERT_EQ(0, HWModuleHelpers::closeModule(&mModule->common))
+            << "Failed to close camera HAL module";
+    }
+
+    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 trying to initialize
+               before calling get_camera_info */
+            if (InfoQuirk) {
+                struct camera_info info;
+                ASSERT_EQ(OK, mModule->get_camera_info(mCameraID, &info));
+            }
+
+            mDevice = new Camera2Device(mCameraID);
+            ASSERT_EQ(OK, mDevice->initialize(mModule))
+                << "Failed to initialize device " << mCameraID;
+        }
+    }
+
+    void TearDownMixin() {
+
+    }
+
+protected:
+    int mNumberOfCameras;
+    camera_module_t *mModule;
+    sp<Camera2Device> mDevice;
+
+private:
+    int mCameraID;
+};
+
+
+}
+}
+}
+
diff --git a/tests/camera2/CameraModuleTests.cpp b/tests/camera2/CameraModuleTests.cpp
new file mode 100644
index 0000000..2bfdb88
--- /dev/null
+++ b/tests/camera2/CameraModuleTests.cpp
@@ -0,0 +1,120 @@
+/*
+ * 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 "DISABLED_CameraModuleTest"
+#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include "hardware/hardware.h"
+#include "hardware/camera2.h"
+
+#include "Camera2Device.h"
+#include "utils/StrongPointer.h"
+#include "CameraModuleFixture.h"
+
+namespace android {
+namespace camera2 {
+namespace tests {
+
+class DISABLED_CameraModuleTest : public ::testing::Test,
+                                  public CameraModuleFixture<> {
+
+    virtual void SetUp() {
+        //CameraModuleFixture::SetUp();
+    }
+
+    virtual void TearDown() {
+        //CameraModuleFixture::TearDown();
+    }
+};
+
+TEST_F(DISABLED_CameraModuleTest, LoadModule) {
+
+    if (HasFatalFailure()) {
+        return;
+    }
+
+    for (int i = 0; i < mNumberOfCameras; ++i) {
+        mDevice = new Camera2Device(i);
+        ASSERT_EQ(OK, mDevice->initialize(mModule))
+            << "Failed to initialize device " << i;
+        mDevice.clear();
+    }
+
+}
+
+TEST_F(DISABLED_CameraModuleTest, LoadModuleBadIndices) {
+
+    if (HasFatalFailure()) {
+        return;
+    }
+
+    int idx[] = { -1, mNumberOfCameras, mNumberOfCameras + 1 };
+
+    for (unsigned i = 0; i < sizeof(idx)/sizeof(idx[0]); ++i) {
+        mDevice = new Camera2Device(idx[i]);
+        status_t deviceInitializeCode = mDevice->initialize(mModule);
+        EXPECT_NE(OK, deviceInitializeCode);
+        EXPECT_EQ(-ENODEV, deviceInitializeCode)
+            << "Incorrect error code when trying to initialize invalid index "
+            << idx[i];
+        mDevice.clear();
+    }
+}
+
+TEST_F(DISABLED_CameraModuleTest, GetCameraInfo) {
+
+    if (HasFatalFailure()) {
+        return;
+    }
+
+    for (int i = 0; i < mNumberOfCameras; ++i) {
+        struct camera_info info;
+        ASSERT_EQ(OK, mModule->get_camera_info(i, &info));
+    }
+
+}
+
+TEST_F(DISABLED_CameraModuleTest, GetCameraInfoBadIndices) {
+
+    if (HasFatalFailure()) {
+        return;
+    }
+
+    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->get_camera_info(idx[i], &info));
+        EXPECT_EQ(-ENODEV, mModule->get_camera_info(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)
+ */
+
+
+
+
+}
+}
+}
+
diff --git a/tests/camera2/CameraStreamFixture.h b/tests/camera2/CameraStreamFixture.h
new file mode 100644
index 0000000..4bd8ac1
--- /dev/null
+++ b/tests/camera2/CameraStreamFixture.h
@@ -0,0 +1,119 @@
+/*
+ * 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 <gui/CpuConsumer.h>
+#include <gui/SurfaceTextureClient.h>
+
+#include "CameraModuleFixture.h"
+
+namespace android {
+namespace camera2 {
+namespace tests {
+
+struct CameraStreamParams {
+    int mCameraId;
+    int mFormat;
+    int mHeapCount;
+};
+
+class CameraStreamFixture
+    : public CameraModuleFixture</*InfoQuirk*/true> {
+
+public:
+    CameraStreamFixture(CameraStreamParams p)
+    : CameraModuleFixture(p.mCameraId) {
+        mParam = p;
+
+        SetUp();
+    }
+
+    ~CameraStreamFixture() {
+        TearDown();
+    }
+
+private:
+
+    void SetUp() {
+        CameraStreamParams p = mParam;
+        sp<Camera2Device> device = mDevice;
+
+        /* use an arbitrary w,h */
+        {
+            const int tag = ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES;
+
+            const android::camera2::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];
+        }
+    }
+    void TearDown() {
+    }
+
+protected:
+
+    void CreateStream() {
+        sp<Camera2Device> device = mDevice;
+        CameraStreamParams p = mParam;
+
+        mCpuConsumer = new CpuConsumer(p.mHeapCount);
+        mCpuConsumer->setName(String8("CameraStreamTest::mCpuConsumer"));
+
+        mNativeWindow = new SurfaceTextureClient(
+            mCpuConsumer->getProducerInterface());
+
+        ASSERT_EQ(OK,
+            device->createStream(mNativeWindow,
+                mWidth, mHeight, p.mFormat, /*size (for jpegs)*/0,
+                &mStreamId));
+
+        ASSERT_NE(-1, mStreamId);
+    }
+
+    void DeleteStream() {
+        ASSERT_EQ(OK, mDevice->deleteStream(mStreamId));
+    }
+
+    /* consider factoring out this common code into
+      a CameraStreamFixture<T>, e.g.
+      class CameraStreamTest : TestWithParam<CameraStreamParameters>,
+                               CameraStreamFixture<CameraStreamParameters>
+       to make it easier for other classes to not duplicate the params
+      */
+
+    int mWidth;
+    int mHeight;
+
+    int mStreamId;
+    android::sp<CpuConsumer>         mCpuConsumer;
+    android::sp<ANativeWindow>       mNativeWindow;
+
+private:
+    CameraStreamParams mParam;
+};
+
+}
+}
+}
+
diff --git a/tests/camera2/CameraStreamTests.cpp b/tests/camera2/CameraStreamTests.cpp
new file mode 100644
index 0000000..e06e4e9
--- /dev/null
+++ b/tests/camera2/CameraStreamTests.cpp
@@ -0,0 +1,148 @@
+/*
+ * 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 "DISABLED_CameraStreamTest"
+#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include "hardware/hardware.h"
+#include "hardware/camera2.h"
+
+#include "Camera2Device.h"
+#include "utils/StrongPointer.h"
+
+#include <gui/CpuConsumer.h>
+#include <gui/SurfaceTextureClient.h>
+
+#include "CameraStreamFixture.h"
+
+
+using namespace android;
+using namespace android::camera2;
+
+namespace android {
+namespace camera2 {
+namespace tests {
+
+class DISABLED_CameraStreamTest
+    : public ::testing::TestWithParam<CameraStreamParams>,
+      public CameraStreamFixture {
+
+public:
+    DISABLED_CameraStreamTest() : CameraStreamFixture(GetParam()) {
+    }
+
+    ~DISABLED_CameraStreamTest() {
+    }
+
+    virtual void SetUp() {
+    }
+    virtual void TearDown() {
+    }
+
+protected:
+
+};
+
+TEST_P(DISABLED_CameraStreamTest, CreateStream) {
+
+    if (HasFatalFailure()) {
+        return;
+    }
+
+    CreateStream();
+
+    if (HasFatalFailure()) {
+        return;
+    }
+
+    DeleteStream();
+}
+
+//TODO: use a combinatoric generator
+static CameraStreamParams TestParameters[] = {
+    {
+        /*cameraId*/   0,
+        /*mFormat*/    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
+        /*mHeapCount*/ 1
+    },
+    {
+        /*cameraId*/   0,
+        /*mFormat*/    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
+        /*mHeapCount*/ 2
+    },
+    {
+        /*cameraId*/   0,
+        /*mFormat*/    HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
+        /*mHeapCount*/ 3
+    },
+    {
+        /*cameraId*/   0,
+        /*mFormat*/    HAL_PIXEL_FORMAT_YCrCb_420_SP, // NV21
+        /*mHeapCount*/ 1
+    },
+    {
+        /*cameraId*/   0,
+        /*mFormat*/    HAL_PIXEL_FORMAT_YCrCb_420_SP,
+        /*mHeapCount*/ 2
+    },
+    {
+        /*cameraId*/   0,
+        /*mFormat*/    HAL_PIXEL_FORMAT_YCrCb_420_SP,
+        /*mHeapCount*/ 3
+    },
+    {
+        /*cameraId*/   0,
+        /*mFormat*/    HAL_PIXEL_FORMAT_YV12,
+        /*mHeapCount*/ 1
+    },
+    {
+        /*cameraId*/   0,
+        /*mFormat*/    HAL_PIXEL_FORMAT_YV12,
+        /*mHeapCount*/ 2
+    },
+    {
+        /*cameraId*/   0,
+        /*mFormat*/    HAL_PIXEL_FORMAT_YV12,
+        /*mHeapCount*/ 3
+    },
+    {
+        /*cameraId*/   0,
+        /*mFormat*/    HAL_PIXEL_FORMAT_RAW_SENSOR,
+        /*mHeapCount*/ 1
+    },
+    {
+        /*cameraId*/   0,
+        /*mFormat*/    HAL_PIXEL_FORMAT_RAW_SENSOR,
+        /*mHeapCount*/ 2
+    },
+    {
+        /*cameraId*/   0,
+        /*mFormat*/    HAL_PIXEL_FORMAT_RAW_SENSOR,
+        /*mHeapCount*/ 3
+    },
+};
+
+INSTANTIATE_TEST_CASE_P(StreamParameterCombinations, DISABLED_CameraStreamTest,
+    testing::ValuesIn(TestParameters));
+
+
+}
+}
+}
+
diff --git a/tests/camera2/camera2.cpp b/tests/camera2/camera2.cpp
index f43513e..b3bbc95 100644
--- a/tests/camera2/camera2.cpp
+++ b/tests/camera2/camera2.cpp
@@ -30,6 +30,8 @@
 #include "camera2_utils.h"
 
 namespace android {
+namespace camera2 {
+namespace tests {
 
 class Camera2Test: public testing::Test {
   public:
@@ -103,6 +105,11 @@
         }
     }
 
+    static void TearDownTestCase() {
+        hw_module_t *module = reinterpret_cast<hw_module_t*>(sCameraModule);
+        ASSERT_EQ(0, HWModuleHelpers::closeModule(module));
+    }
+
     static const camera_module_t *getCameraModule() {
         return sCameraModule;
     }
@@ -606,7 +613,7 @@
     }
 }
 
-TEST_F(Camera2Test, Capture1Jpeg) {
+TEST_F(Camera2Test, DISABLED_Capture1Jpeg) {
     status_t res;
 
     for (int id = 0; id < getNumCameras(); id++) {
@@ -720,5 +727,6 @@
     }
 }
 
-
+} // namespace tests
+} // namespace camera2
 } // namespace android
diff --git a/tests/camera2/camera2_utils.cpp b/tests/camera2/camera2_utils.cpp
index cefe29a..166ac52 100644
--- a/tests/camera2/camera2_utils.cpp
+++ b/tests/camera2/camera2_utils.cpp
@@ -21,8 +21,11 @@
 
 #include "utils/Log.h"
 #include "camera2_utils.h"
+#include <dlfcn.h>
 
 namespace android {
+namespace camera2 {
+namespace tests {
 
 /**
  * MetadataQueue
@@ -578,4 +581,22 @@
     mCondition.signal();
 }
 
+int HWModuleHelpers::closeModule(hw_module_t* module) {
+    int status;
+
+    if (!module) {
+        return -EINVAL;
+    }
+
+    status = dlclose(module->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
index 7822f5b..c938ee7 100644
--- a/tests/camera2/camera2_utils.h
+++ b/tests/camera2/camera2_utils.h
@@ -27,6 +27,8 @@
 #include <utils/Condition.h>
 
 namespace android {
+namespace camera2 {
+namespace tests {
 
 /**
  * Queue class for both sending requests to a camera2 device, and for receiving
@@ -233,4 +235,11 @@
     Condition mCondition;
 };
 
+struct HWModuleHelpers {
+    /* attempt to unload the library with dlclose */
+    static int closeModule(hw_module_t* module);
+};
+
+}
+}
 }
diff --git a/tests/camera2/main.cpp b/tests/camera2/main.cpp
new file mode 100644
index 0000000..40b9872
--- /dev/null
+++ b/tests/camera2/main.cpp
@@ -0,0 +1,26 @@
+/*
+ * 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>
+
+int main(int argc, char **argv) {
+
+    ::testing::InitGoogleTest(&argc, argv);
+
+    int ret = RUN_ALL_TESTS();
+
+    return ret;
+}