Merge "add AMediaCodec_releaseName in libmediandk.map.txt" into pi-dev
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index a1a8cd6..c59d0e7 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -221,7 +221,7 @@
     mCallbacks.erase(cb);
 }
 
-void CameraManagerGlobal::getCameraIdList(std::vector<String8> *cameraIds) {
+void CameraManagerGlobal::getCameraIdList(std::vector<String8>* cameraIds) {
     // Ensure that we have initialized/refreshed the list of available devices
     auto cs = getCameraService();
     Mutex::Autolock _l(mLock);
diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h
index 4a172f3..cc42f77 100644
--- a/camera/ndk/impl/ACameraManager.h
+++ b/camera/ndk/impl/ACameraManager.h
@@ -19,6 +19,7 @@
 
 #include <camera/NdkCameraManager.h>
 
+#include <android-base/parseint.h>
 #include <android/hardware/ICameraService.h>
 #include <android/hardware/BnCameraServiceListener.h>
 #include <camera/CameraMetadata.h>
@@ -140,8 +141,29 @@
     static bool validStatus(int32_t status);
     static bool isStatusAvailable(int32_t status);
 
+    // The sort logic must match the logic in
+    // libcameraservice/common/CameraProviderManager.cpp::getAPI1CompatibleCameraDeviceIds
+    struct CameraIdComparator {
+        bool operator()(const String8& a, const String8& b) const {
+            uint32_t aUint = 0, bUint = 0;
+            bool aIsUint = base::ParseUint(a.c_str(), &aUint);
+            bool bIsUint = base::ParseUint(b.c_str(), &bUint);
+
+            // Uint device IDs first
+            if (aIsUint && bIsUint) {
+                return aUint < bUint;
+            } else if (aIsUint) {
+                return true;
+            } else if (bIsUint) {
+                return false;
+            }
+            // Simple string compare if both id are not uint
+            return a < b;
+        }
+    };
+
     // Map camera_id -> status
-    std::map<String8, int32_t> mDeviceStatusMap;
+    std::map<String8, int32_t, CameraIdComparator> mDeviceStatusMap;
 
     // For the singleton instance
     static Mutex sLock;
diff --git a/camera/ndk/impl/ACameraMetadata.cpp b/camera/ndk/impl/ACameraMetadata.cpp
index 62b0ec9..fc00a2d 100644
--- a/camera/ndk/impl/ACameraMetadata.cpp
+++ b/camera/ndk/impl/ACameraMetadata.cpp
@@ -313,6 +313,7 @@
         case ACAMERA_TONEMAP_GAMMA:
         case ACAMERA_TONEMAP_PRESET_CURVE:
         case ACAMERA_BLACK_LEVEL_LOCK:
+        case ACAMERA_DISTORTION_CORRECTION_MODE:
             return true;
         default:
             return false;
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 346761c..c7d2545 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -70,6 +70,7 @@
     ACAMERA_REPROCESS,
     ACAMERA_DEPTH,
     ACAMERA_LOGICAL_MULTI_CAMERA,
+    ACAMERA_DISTORTION_CORRECTION,
     ACAMERA_SECTION_COUNT,
 
     ACAMERA_VENDOR = 0x8000
@@ -108,6 +109,9 @@
     ACAMERA_LOGICAL_MULTI_CAMERA_START
                                    = ACAMERA_LOGICAL_MULTI_CAMERA
                                                                 << 16,
+    ACAMERA_DISTORTION_CORRECTION_START
+                                   = ACAMERA_DISTORTION_CORRECTION
+                                                                << 16,
     ACAMERA_VENDOR_START           = ACAMERA_VENDOR            << 16
 } acamera_metadata_section_start_t;
 
@@ -1909,8 +1913,8 @@
      * the thumbnail data will also be rotated.</p>
      * <p>Note that this orientation is relative to the orientation of the camera sensor, given
      * by ACAMERA_SENSOR_ORIENTATION.</p>
-     * <p>To translate from the device orientation given by the Android sensor APIs, the following
-     * sample code may be used:</p>
+     * <p>To translate from the device orientation given by the Android sensor APIs for camera
+     * sensors which are not EXTERNAL, the following sample code may be used:</p>
      * <pre><code>private int getJpegOrientation(CameraCharacteristics c, int deviceOrientation) {
      *     if (deviceOrientation == android.view.OrientationEventListener.ORIENTATION_UNKNOWN) return 0;
      *     int sensorOrientation = c.get(CameraCharacteristics.SENSOR_ORIENTATION);
@@ -1929,6 +1933,8 @@
      *     return jpegOrientation;
      * }
      * </code></pre>
+     * <p>For EXTERNAL cameras the sensor orientation will always be set to 0 and the facing will
+     * also be set to EXTERNAL. The above code is not relevant in such case.</p>
      *
      * @see ACAMERA_SENSOR_ORIENTATION
      */
@@ -4803,6 +4809,8 @@
      * of points can be less than max (that is, the request doesn't have to
      * always provide a curve with number of points equivalent to
      * ACAMERA_TONEMAP_MAX_CURVE_POINTS).</p>
+     * <p>For devices with MONOCHROME capability, only red channel is used. Green and blue channels
+     * are ignored.</p>
      * <p>A few examples, and their corresponding graphical mappings; these
      * only specify the red channel and the precision is limited to 4
      * digits, for conciseness.</p>
@@ -5285,6 +5293,63 @@
             ACAMERA_LOGICAL_MULTI_CAMERA_START + 1,
     ACAMERA_LOGICAL_MULTI_CAMERA_END,
 
+    /**
+     * <p>Mode of operation for the lens distortion correction block.</p>
+     *
+     * <p>Type: byte (acamera_metadata_enum_android_distortion_correction_mode_t)</p>
+     *
+     * <p>This tag may appear in:
+     * <ul>
+     *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
+     *   <li>ACaptureRequest</li>
+     * </ul></p>
+     *
+     * <p>The lens distortion correction block attempts to improve image quality by fixing
+     * radial, tangential, or other geometric aberrations in the camera device's optics.  If
+     * available, the ACAMERA_LENS_DISTORTION field documents the lens's distortion parameters.</p>
+     * <p>OFF means no distortion correction is done.</p>
+     * <p>FAST/HIGH_QUALITY both mean camera device determined distortion correction will be
+     * applied. HIGH_QUALITY mode indicates that the camera device will use the highest-quality
+     * correction algorithms, even if it slows down capture rate. FAST means the camera device
+     * will not slow down capture rate when applying correction. FAST may be the same as OFF if
+     * any correction at all would slow down capture rate.  Every output stream will have a
+     * similar amount of enhancement applied.</p>
+     * <p>The correction only applies to processed outputs such as YUV, JPEG, or DEPTH16; it is not
+     * applied to any RAW output.  Metadata coordinates such as face rectangles or metering
+     * regions are also not affected by correction.</p>
+     * <p>Applications enabling distortion correction need to pay extra attention when converting
+     * image coordinates between corrected output buffers and the sensor array. For example, if
+     * the app supports tap-to-focus and enables correction, it then has to apply the distortion
+     * model described in ACAMERA_LENS_DISTORTION to the image buffer tap coordinates to properly
+     * calculate the tap position on the sensor active array to be used with
+     * ACAMERA_CONTROL_AF_REGIONS. The same applies in reverse to detected face rectangles if
+     * they need to be drawn on top of the corrected output buffers.</p>
+     *
+     * @see ACAMERA_CONTROL_AF_REGIONS
+     * @see ACAMERA_LENS_DISTORTION
+     */
+    ACAMERA_DISTORTION_CORRECTION_MODE =                        // byte (acamera_metadata_enum_android_distortion_correction_mode_t)
+            ACAMERA_DISTORTION_CORRECTION_START,
+    /**
+     * <p>List of distortion correction modes for ACAMERA_DISTORTION_CORRECTION_MODE that are
+     * supported by this camera device.</p>
+     *
+     * @see ACAMERA_DISTORTION_CORRECTION_MODE
+     *
+     * <p>Type: byte[n]</p>
+     *
+     * <p>This tag may appear in:
+     * <ul>
+     *   <li>ACameraMetadata from ACameraManager_getCameraCharacteristics</li>
+     * </ul></p>
+     *
+     * <p>No device is required to support this API; such devices will always list only 'OFF'.
+     * All devices that support this API will list both FAST and HIGH_QUALITY.</p>
+     */
+    ACAMERA_DISTORTION_CORRECTION_AVAILABLE_MODES =             // byte[n]
+            ACAMERA_DISTORTION_CORRECTION_START + 1,
+    ACAMERA_DISTORTION_CORRECTION_END,
+
 } acamera_metadata_tag_t;
 
 /**
@@ -7033,6 +7098,12 @@
      */
     ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA      = 11,
 
+    /**
+     * <p>The camera device is a monochrome camera that doesn't contain a color filter array,
+     * and the pixel values on U and Y planes are all 128.</p>
+     */
+    ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME                = 12,
+
 } acamera_metadata_enum_android_request_available_capabilities_t;
 
 
@@ -7682,6 +7753,29 @@
 } acamera_metadata_enum_android_logical_multi_camera_sensor_sync_type_t;
 
 
+// ACAMERA_DISTORTION_CORRECTION_MODE
+typedef enum acamera_metadata_enum_acamera_distortion_correction_mode {
+    /**
+     * <p>No distortion correction is applied.</p>
+     */
+    ACAMERA_DISTORTION_CORRECTION_MODE_OFF                           = 0,
+
+    /**
+     * <p>Lens distortion correction is applied without reducing frame rate
+     * relative to sensor output. It may be the same as OFF if distortion correction would
+     * reduce frame rate relative to sensor.</p>
+     */
+    ACAMERA_DISTORTION_CORRECTION_MODE_FAST                          = 1,
+
+    /**
+     * <p>High-quality distortion correction is applied, at the cost of
+     * possibly reduced frame rate relative to sensor output.</p>
+     */
+    ACAMERA_DISTORTION_CORRECTION_MODE_HIGH_QUALITY                  = 2,
+
+} acamera_metadata_enum_android_distortion_correction_mode_t;
+
+
 #endif /* __ANDROID_API__ >= 24 */
 
 __END_DECLS
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 66e4400..4991e50 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -54,17 +54,18 @@
 
     proto: {
         export_proto_headers: true,
-	type: "lite",
+        type: "lite",
     },
     shared_libs: [
         "android.hardware.drm@1.0",
         "android.hardware.drm@1.1",
         "libbase",
         "libbinder",
-	"libhidlbase",
+        "libhidlbase",
         "liblog",
         "libmediametrics",
         "libprotobuf-cpp-lite",
+        "libstagefright_foundation",
         "libutils",
     ],
     cflags: [
@@ -86,24 +87,25 @@
 
     proto: {
         export_proto_headers: true,
-	type: "full",
+        type: "full",
     },
     shared_libs: [
         "android.hardware.drm@1.0",
         "android.hardware.drm@1.1",
         "libbase",
         "libbinder",
-	"libhidlbase",
+        "libhidlbase",
         "liblog",
         "libmediametrics",
         "libprotobuf-cpp-full",
+        "libstagefright_foundation",
         "libutils",
     ],
     cflags: [
         // Suppress unused parameter and no error options. These cause problems
-	// when using the map type in a proto definition.
-	"-Wno-unused-parameter",
-	"-Wno-error",
+        // when using the map type in a proto definition.
+        "-Wno-unused-parameter",
+        "-Wno-error",
     ],
 }
 
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index 5d97188..4e8ad52 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -32,6 +32,7 @@
 #include <media/drm/DrmAPI.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AString.h>
+#include <media/stagefright/foundation/base64.h>
 #include <media/stagefright/foundation/hexdump.h>
 #include <media/stagefright/MediaErrors.h>
 #include <mediadrm/DrmHal.h>
@@ -63,9 +64,27 @@
 // This constant corresponds to the PROPERTY_DEVICE_UNIQUE_ID constant
 // in the MediaDrm API.
 constexpr char kPropertyDeviceUniqueId[] = "deviceUniqueId";
+constexpr char kEqualsSign[] = "=";
 
+template<typename T>
+std::string toBase64StringNoPad(const T* data, size_t size) {
+    if (size == 0) {
+      return "";
+    }
+    CHECK(sizeof(data[0] == 1));
+
+    android::AString outputString;
+    encodeBase64(data, size, &outputString);
+    // Remove trailing equals padding if it exists.
+    while (outputString.size() > 0 && outputString.endsWith(kEqualsSign)) {
+        outputString.erase(outputString.size() - 1, 1);
+    }
+
+    return std::string(outputString.c_str(), outputString.size());
 }
 
+}  // anonymous namespace
+
 namespace android {
 
 #define INIT_CHECK() {if (mInitCheck != OK) return mInitCheck;}
@@ -101,15 +120,6 @@
     return hidl_string(string.string());
 }
 
-std::string toHexString(const std::string& str) {
-  std::ostringstream out;
-  out << std::hex << std::setfill('0');
-  for (size_t i = 0; i < str.size(); i++) {
-    out << std::setw(2) << (int)(str[i]);
-  }
-  return out.str();
-}
-
 static DrmPlugin::SecurityLevel toSecurityLevel(SecurityLevel level) {
     switch(level) {
     case SecurityLevel::SW_SECURE_CRYPTO:
@@ -340,6 +350,7 @@
 
 sp<IDrmPlugin> DrmHal::makeDrmPlugin(const sp<IDrmFactory>& factory,
         const uint8_t uuid[16], const String8& appPackageName) {
+    mAppPackageName = appPackageName;
     mMetrics.SetAppPackageName(appPackageName);
 
     sp<IDrmPlugin> plugin;
@@ -1353,9 +1364,10 @@
     if (result != OK) {
         ALOGE("Failed to serialize framework metrics: %d", result);
     }
-    serializedMetrics = toHexString(serializedMetrics);
-    if (!serializedMetrics.empty()) {
-        item.setCString("serialized_metrics", serializedMetrics.c_str());
+    std::string b64EncodedMetrics = toBase64StringNoPad(serializedMetrics.data(),
+                                                        serializedMetrics.size());
+    if (!b64EncodedMetrics.empty()) {
+        item.setCString("serialized_metrics", b64EncodedMetrics.c_str());
     }
     if (!item.selfrecord()) {
         ALOGE("Failed to self record framework metrics");
@@ -1364,14 +1376,16 @@
 
 void DrmHal::reportPluginMetrics() const
 {
-    Vector<uint8_t> metrics;
+    Vector<uint8_t> metricsVector;
     String8 vendor;
     String8 description;
     if (getPropertyStringInternal(String8("vendor"), vendor) == OK &&
             getPropertyStringInternal(String8("description"), description) == OK &&
-            getPropertyByteArrayInternal(String8("metrics"), metrics) == OK) {
-        status_t res = android::reportDrmPluginMetrics(
-                metrics, vendor, description);
+            getPropertyByteArrayInternal(String8("metrics"), metricsVector) == OK) {
+        std::string metricsString = toBase64StringNoPad(metricsVector.array(),
+                                                        metricsVector.size());
+        status_t res = android::reportDrmPluginMetrics(metricsString, vendor,
+                                                       description, mAppPackageName);
         if (res != OK) {
             ALOGE("Metrics were retrieved but could not be reported: %d", res);
         }
diff --git a/drm/libmediadrm/ICrypto.cpp b/drm/libmediadrm/ICrypto.cpp
index 40aeb9f..73ecda1 100644
--- a/drm/libmediadrm/ICrypto.cpp
+++ b/drm/libmediadrm/ICrypto.cpp
@@ -341,10 +341,10 @@
                 return OK;
             }
 
-            CryptoPlugin::SubSample *subSamples =
-                    new CryptoPlugin::SubSample[numSubSamples];
+            std::unique_ptr<CryptoPlugin::SubSample[]> subSamples =
+                    std::make_unique<CryptoPlugin::SubSample[]>(numSubSamples);
 
-            data.read(subSamples,
+            data.read(subSamples.get(),
                     sizeof(CryptoPlugin::SubSample) * numSubSamples);
 
             DestinationBuffer destination;
@@ -402,7 +402,7 @@
                 result = -EINVAL;
             } else {
                 result = decrypt(key, iv, mode, pattern, source, offset,
-                        subSamples, numSubSamples, destination, &errorDetailMsg);
+                        subSamples.get(), numSubSamples, destination, &errorDetailMsg);
             }
 
             reply->writeInt32(result);
@@ -421,9 +421,7 @@
                 }
             }
 
-            delete[] subSamples;
-            subSamples = NULL;
-
+            subSamples.reset();
             return OK;
         }
 
diff --git a/drm/libmediadrm/PluginMetricsReporting.cpp b/drm/libmediadrm/PluginMetricsReporting.cpp
index 6c97f2b..5cb48bf 100644
--- a/drm/libmediadrm/PluginMetricsReporting.cpp
+++ b/drm/libmediadrm/PluginMetricsReporting.cpp
@@ -16,80 +16,35 @@
 
 //#define LOG_NDEBUG 0
 #define LOG_TAG "PluginMetricsReporting"
-#include <utils/Log.h>
-#include <inttypes.h>
 
 #include <media/PluginMetricsReporting.h>
 
-#include <media/MediaAnalyticsItem.h>
+#include <inttypes.h>
 
-#include "protos/metrics.pb.h"
+#include <media/MediaAnalyticsItem.h>
+#include <utils/Log.h>
+
 
 namespace android {
 
 namespace {
 
-using android::drm_metrics::MetricsGroup;
-using android::drm_metrics::MetricsGroup_Metric;
-using android::drm_metrics::MetricsGroup_Metric_MetricValue;
+constexpr char kSerializedMetricsField[] = "serialized_metrics";
 
-const char* const kParentAttribute = "/parent/external";
-
-status_t reportMetricsGroup(const MetricsGroup& metricsGroup,
-                            const String8& batchName,
-                            const int64_t* parentId) {
-    MediaAnalyticsItem analyticsItem(batchName.c_str());
+status_t reportVendorMetrics(const std::string& metrics,
+                             const String8& name,
+                             const String8& appPackageName) {
+    MediaAnalyticsItem analyticsItem(name.c_str());
     analyticsItem.generateSessionID();
-    int64_t sessionId = analyticsItem.getSessionID();
-    if (parentId != NULL) {
-        analyticsItem.setInt64(kParentAttribute, *parentId);
-    }
 
-    // Report the package name.
-    if (metricsGroup.has_app_package_name()) {
-        std::string app_package_name(metricsGroup.app_package_name().c_str(),
-                               metricsGroup.app_package_name().size());
-      analyticsItem.setPkgName(app_package_name);
-    }
-
-    for (int i = 0; i < metricsGroup.metric_size(); ++i) {
-        const MetricsGroup_Metric& metric = metricsGroup.metric(i);
-        if (!metric.has_name()) {
-            ALOGE("Metric with no name.");
-            return BAD_VALUE;
-        }
-
-        if (!metric.has_value()) {
-            ALOGE("Metric with no value.");
-            return BAD_VALUE;
-        }
-
-        const MetricsGroup_Metric_MetricValue& value = metric.value();
-        if (value.has_int_value()) {
-            analyticsItem.setInt64(metric.name().c_str(),
-                                   value.int_value());
-        } else if (value.has_double_value()) {
-            analyticsItem.setDouble(metric.name().c_str(),
-                                    value.double_value());
-        } else if (value.has_string_value()) {
-            analyticsItem.setCString(metric.name().c_str(),
-                                     value.string_value().c_str());
-        } else {
-            ALOGE("Metric Value with no actual value.");
-            return BAD_VALUE;
-        }
+    std::string app_package_name(appPackageName.c_str(), appPackageName.size());
+    analyticsItem.setPkgName(app_package_name);
+    if (metrics.size() > 0) {
+        analyticsItem.setCString(kSerializedMetricsField, metrics.c_str());
     }
 
     if (!analyticsItem.selfrecord()) {
-      ALOGE("selfrecord() returned false. sessioId %" PRId64, sessionId);
-    }
-
-    for (int i = 0; i < metricsGroup.metric_sub_group_size(); ++i) {
-        const MetricsGroup& subGroup = metricsGroup.metric_sub_group(i);
-        status_t res = reportMetricsGroup(subGroup, batchName, &sessionId);
-        if (res != OK) {
-            return res;
-        }
+      ALOGE("selfrecord() returned false. sessioId %" PRId64, analyticsItem.getSessionID());
     }
 
     return OK;
@@ -111,21 +66,16 @@
 
 }  // namespace
 
-status_t reportDrmPluginMetrics(const Vector<uint8_t>& serializedMetrics,
+status_t reportDrmPluginMetrics(const std::string& b64EncodedMetrics,
                                 const String8& vendor,
-                                const String8& description) {
-    MetricsGroup root_metrics_group;
-    if (!root_metrics_group.ParseFromArray(serializedMetrics.array(),
-                                           serializedMetrics.size())) {
-        ALOGE("Failure to parse.");
-        return BAD_VALUE;
-    }
+                                const String8& description,
+                                const String8& appPackageName) {
 
     String8 name = String8::format("drm.vendor.%s.%s",
                                    sanitize(vendor).c_str(),
                                    sanitize(description).c_str());
 
-    return reportMetricsGroup(root_metrics_group, name, NULL);
+    return reportVendorMetrics(b64EncodedMetrics, name, appPackageName);
 }
 
 }  // namespace android
diff --git a/drm/libmediadrm/protos/metrics.proto b/drm/libmediadrm/protos/metrics.proto
index aa26f5f..6160e6f 100644
--- a/drm/libmediadrm/protos/metrics.proto
+++ b/drm/libmediadrm/protos/metrics.proto
@@ -18,33 +18,6 @@
 
 package android.drm_metrics;
 
-// The MetricsGroup is a collection of metric name/value pair instances
-// that can be serialized and provided to a caller.
-message MetricsGroup {
-  message Metric {
-    message MetricValue {
-      // Exactly one of the following values must be set.
-      optional int64 int_value = 1;
-      optional double double_value = 2;
-      optional string string_value = 3;
-    }
-
-    // The name of the metric. Must be valid UTF-8. Required.
-    optional string name = 1;
-
-    // The value of the metric. Required.
-    optional MetricValue value = 2;
-  }
-
-  // The list of name/value pairs of metrics.
-  repeated Metric metric = 1;
-
-  // Allow multiple sub groups of metrics.
-  repeated MetricsGroup metric_sub_group = 2;
-
-  // Name of the application package associated with the metrics.
-  optional string app_package_name = 3;
-}
 
 // This message contains the specific metrics captured by DrmMetrics. It is
 // used for serializing and logging metrics.
@@ -72,7 +45,7 @@
   // The Counter message is used to store a count value with an associated
   // Attribute.
   message Counter {
-    optional int64 count = 1;
+    optional uint64 count = 1;
     // Represents the attributes associated with this counter instance.
     optional Attributes attributes = 2;
   }
@@ -80,11 +53,11 @@
   // The DistributionMetric is meant to capture the moments of a normally
   // distributed (or approximately normal) value.
   message DistributionMetric {
-    optional double min = 1;
-    optional double max = 2;
-    optional double mean = 3;
+    optional float min = 1;
+    optional float max = 2;
+    optional float mean = 3;
     optional double variance = 4;
-    optional double operation_count = 5;
+    optional uint64 operation_count = 5;
 
     // Represents the attributes assocated with this distribution metric
     // instance.
@@ -93,9 +66,9 @@
 
   message SessionLifetime {
     // Start time of the session in milliseconds since epoch.
-    optional int64 start_time_ms = 1;
+    optional uint64 start_time_ms = 1;
     // End time of the session in milliseconds since epoch.
-    optional int64 end_time_ms = 2;
+    optional uint64 end_time_ms = 2;
   }
 
   // The count of open session operations. Each instance has a specific error
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
index ed9534f..73ed8c3 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
@@ -55,7 +55,7 @@
 
 status_t ClearKeyCasFactory::createPlugin(
         int32_t CA_system_id,
-        uint64_t appData,
+        void *appData,
         CasPluginCallback callback,
         CasPlugin **plugin) {
     if (!isSystemIdSupported(CA_system_id)) {
@@ -83,7 +83,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 ClearKeyCasPlugin::ClearKeyCasPlugin(
-        uint64_t appData, CasPluginCallback callback)
+        void *appData, CasPluginCallback callback)
     : mCallback(callback), mAppData(appData) {
     ALOGV("CTOR");
 }
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
index b7134e4..42cfb8f 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
@@ -44,7 +44,7 @@
             std::vector<CasPluginDescriptor> *descriptors) const override;
     virtual status_t createPlugin(
             int32_t CA_system_id,
-            uint64_t appData,
+            void *appData,
             CasPluginCallback callback,
             CasPlugin **plugin) override;
 };
@@ -62,7 +62,7 @@
 
 class ClearKeyCasPlugin : public CasPlugin {
 public:
-    ClearKeyCasPlugin(uint64_t appData, CasPluginCallback callback);
+    ClearKeyCasPlugin(void *appData, CasPluginCallback callback);
     virtual ~ClearKeyCasPlugin();
 
     virtual status_t setPrivateData(
@@ -94,7 +94,7 @@
     Mutex mKeyFetcherLock;
     std::unique_ptr<KeyFetcher> mKeyFetcher;
     CasPluginCallback mCallback;
-    uint64_t mAppData;
+    void* mAppData;
 };
 
 class ClearKeyDescramblerPlugin : public DescramblerPlugin {
diff --git a/drm/mediacas/plugins/mock/MockCasPlugin.cpp b/drm/mediacas/plugins/mock/MockCasPlugin.cpp
index 06516b5..8404a83 100644
--- a/drm/mediacas/plugins/mock/MockCasPlugin.cpp
+++ b/drm/mediacas/plugins/mock/MockCasPlugin.cpp
@@ -49,7 +49,7 @@
 
 status_t MockCasFactory::createPlugin(
         int32_t CA_system_id,
-        uint64_t /*appData*/,
+        void* /*appData*/,
         CasPluginCallback /*callback*/,
         CasPlugin **plugin) {
     if (!isSystemIdSupported(CA_system_id)) {
diff --git a/drm/mediacas/plugins/mock/MockCasPlugin.h b/drm/mediacas/plugins/mock/MockCasPlugin.h
index 9632492..8106990 100644
--- a/drm/mediacas/plugins/mock/MockCasPlugin.h
+++ b/drm/mediacas/plugins/mock/MockCasPlugin.h
@@ -39,7 +39,7 @@
             std::vector<CasPluginDescriptor> *descriptors) const override;
     virtual status_t createPlugin(
             int32_t CA_system_id,
-            uint64_t appData,
+            void *appData,
             CasPluginCallback callback,
             CasPlugin **plugin) override;
 };
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
index 300c688..d51e29d 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp
@@ -400,7 +400,7 @@
 
     if (level > SecurityLevel::SW_SECURE_CRYPTO) {
         ALOGE("Cannot set security level > max");
-        return Status::BAD_VALUE;
+        return Status::ERROR_DRM_CANNOT_HANDLE;
     }
 
     std::vector<uint8_t> sid = toVector(sessionId);
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index b4fa3c5..ca119d5 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -60,6 +60,8 @@
     volatile int32_t mRear;     // written by producer (output: client, input: server)
     volatile int32_t mFlush;    // incremented by client to indicate a request to flush;
                                 // server notices and discards all data between mFront and mRear
+    volatile int32_t mStop;     // set by client to indicate a stop frame position; server
+                                // will not read beyond this position until start is called.
     volatile uint32_t mUnderrunFrames; // server increments for each unavailable but desired frame
     volatile uint32_t mUnderrunCount;  // server increments for each underrun occurrence
 };
@@ -335,6 +337,8 @@
         mTimestamp.clear();
     }
 
+    virtual void stop() { }; // called by client in AudioTrack::stop()
+
 private:
     // This is a copy of mCblk->mBufferSizeInFrames
     uint32_t   mBufferSizeInFrames;  // effective size of the buffer
@@ -383,8 +387,14 @@
         mPlaybackRateMutator.push(playbackRate);
     }
 
+    // Sends flush and stop position information from the client to the server,
+    // used by streaming AudioTrack flush() or stop().
+    void sendStreamingFlushStop(bool flush);
+
     virtual void flush();
 
+            void stop() override;
+
     virtual uint32_t    getUnderrunFrames() const {
         return mCblk->u.mStreaming.mUnderrunFrames;
     }
@@ -410,6 +420,8 @@
 
     virtual void    flush();
 
+    void stop() override;
+
 #define MIN_LOOP    16  // minimum length of each loop iteration in frames
 
             // setLoop(), setBufferPosition(), and setBufferPositionAndLoop() set the
@@ -532,6 +544,10 @@
     //   client will be notified via Futex
     virtual void    flushBufferIfNeeded();
 
+    // Returns the rear position of the AudioTrack shared ring buffer, limited by
+    // the stop frame position level.
+    virtual int32_t getRear() const = 0;
+
     // Total count of the number of flushed frames since creation (never reset).
     virtual int64_t     framesFlushed() const { return mFlushed; }
 
@@ -607,10 +623,18 @@
         return mDrained.load();
     }
 
+    int32_t             getRear() const override;
+
+    // Called on server side track start().
+    virtual void        start();
+
 private:
     AudioPlaybackRate             mPlaybackRate;  // last observed playback rate
     PlaybackRateQueue::Observer   mPlaybackRateObserver;
 
+    // Last client stop-at position when start() was called. Used for streaming AudioTracks.
+    std::atomic<int32_t>          mStopLast{0};
+
     // The server keeps a copy here where it is safe from the client.
     uint32_t                      mUnderrunCount; // echoed to mCblk
     bool                          mUnderrunning;  // used to detect edge of underrun
@@ -634,6 +658,10 @@
     virtual void        tallyUnderrunFrames(uint32_t frameCount);
     virtual uint32_t    getUnderrunFrames() const { return 0; }
 
+    int32_t getRear() const override;
+
+    void start() override { } // ignore for static tracks
+
 private:
     status_t            updateStateWithLoop(StaticAudioTrackState *localState,
                                             const StaticAudioTrackState &update) const;
@@ -661,6 +689,10 @@
             size_t frameSize, bool clientInServer)
         : ServerProxy(cblk, buffers, frameCount, frameSize, false /*isOut*/, clientInServer) { }
 
+    int32_t getRear() const override {
+        return mCblk->u.mStreaming.mRear; // For completeness only; mRear written by server.
+    }
+
 protected:
     virtual ~AudioRecordServerProxy() { }
 };
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 07ef0e3..99f32d5 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -1123,19 +1123,33 @@
 
         case FOURCC('t', 'r', 'e', 'f'):
         {
-            *offset += chunk_size;
-
-            if (mLastTrack == NULL) {
+            off64_t stop_offset = *offset + chunk_size;
+            *offset = data_offset;
+            while (*offset < stop_offset) {
+                status_t err = parseChunk(offset, depth + 1);
+                if (err != OK) {
+                    return err;
+                }
+            }
+            if (*offset != stop_offset) {
                 return ERROR_MALFORMED;
             }
+            break;
+        }
 
-            // Skip thumbnail track for now since we don't have an
-            // API to retrieve it yet.
-            // The thumbnail track can't be accessed by negative index or time,
-            // because each timed sample has its own corresponding thumbnail
-            // in the thumbnail track. We'll need a dedicated API to retrieve
-            // thumbnail at time instead.
-            mLastTrack->skipTrack = true;
+        case FOURCC('t', 'h', 'm', 'b'):
+        {
+            *offset += chunk_size;
+
+            if (mLastTrack != NULL) {
+                // Skip thumbnail track for now since we don't have an
+                // API to retrieve it yet.
+                // The thumbnail track can't be accessed by negative index or time,
+                // because each timed sample has its own corresponding thumbnail
+                // in the thumbnail track. We'll need a dedicated API to retrieve
+                // thumbnail at time instead.
+                mLastTrack->skipTrack = true;
+            }
 
             break;
         }
@@ -2353,7 +2367,9 @@
                     // This means that the file should have moov box.
                     // It could be any iso files (mp4, heifs, etc.)
                     mHasMoovBox = true;
-                    ALOGV("identified HEIF image with other tracks");
+                    if (mIsHeif) {
+                        ALOGV("identified HEIF image with other tracks");
+                    }
                 }
             }
 
diff --git a/media/img_utils/src/DngUtils.cpp b/media/img_utils/src/DngUtils.cpp
index 9dc5f05..67ec244 100644
--- a/media/img_utils/src/DngUtils.cpp
+++ b/media/img_utils/src/DngUtils.cpp
@@ -18,6 +18,7 @@
 
 #include <inttypes.h>
 
+#include <algorithm>
 #include <vector>
 #include <math.h>
 
@@ -61,8 +62,8 @@
                                                    const float* lensShadingMap) {
     uint32_t activeAreaWidth = activeAreaRight - activeAreaLeft;
     uint32_t activeAreaHeight = activeAreaBottom - activeAreaTop;
-    double spacingV = 1.0 / lsmHeight;
-    double spacingH = 1.0 / lsmWidth;
+    double spacingV = 1.0 / std::max(1u, lsmHeight - 1);
+    double spacingH = 1.0 / std::max(1u, lsmWidth - 1);
 
     std::vector<float> redMapVector(lsmWidth * lsmHeight);
     float *redMap = redMapVector.data();
diff --git a/media/libaaudio/examples/input_monitor/src/input_monitor.cpp b/media/libaaudio/examples/input_monitor/src/input_monitor.cpp
index e5ad2d9..c1ff34b 100644
--- a/media/libaaudio/examples/input_monitor/src/input_monitor.cpp
+++ b/media/libaaudio/examples/input_monitor/src/input_monitor.cpp
@@ -26,23 +26,22 @@
 #include "AAudioExampleUtils.h"
 #include "AAudioSimpleRecorder.h"
 
-// TODO support FLOAT
-#define REQUIRED_FORMAT    AAUDIO_FORMAT_PCM_I16
 #define MIN_FRAMES_TO_READ 48  /* arbitrary, 1 msec at 48000 Hz */
 
 static const int FRAMES_PER_LINE = 20000;
 
 int main(int argc, const char **argv)
 {
-    AAudioArgsParser   argParser;
-    aaudio_result_t result;
-    AAudioSimpleRecorder recorder;
-    int actualSamplesPerFrame;
-    int actualSampleRate;
-    aaudio_format_t       actualDataFormat;
+    AAudioArgsParser      argParser;
+    AAudioSimpleRecorder  recorder;
+    AAudioStream         *aaudioStream = nullptr;
 
-    AAudioStream *aaudioStream = nullptr;
+    aaudio_result_t       result;
+    aaudio_format_t       actualDataFormat;
     aaudio_stream_state_t state;
+
+    int32_t actualSamplesPerFrame;
+    int32_t actualSampleRate;
     int32_t framesPerBurst = 0;
     int32_t framesPerRead = 0;
     int32_t framesToRecord = 0;
@@ -50,18 +49,18 @@
     int32_t nextFrameCount = 0;
     int32_t frameCount = 0;
     int32_t xRunCount = 0;
-    int64_t previousFramePosition = -1;
-    int16_t *data = nullptr;
-    float peakLevel = 0.0;
     int32_t deviceId;
 
+    int16_t *shortData = nullptr;
+    float   *floatData = nullptr;
+    float    peakLevel = 0.0;
+
     // Make printf print immediately so that debug info is not stuck
     // in a buffer if we hang or crash.
     setvbuf(stdout, nullptr, _IONBF, (size_t) 0);
 
-    printf("%s - Monitor input level using AAudio read, V0.1.2\n", argv[0]);
+    printf("%s - Monitor input level using AAudio read, V0.1.3\n", argv[0]);
 
-    argParser.setFormat(REQUIRED_FORMAT);
     if (argParser.parseArgs(argc, argv)) {
         return EXIT_FAILURE;
     }
@@ -69,6 +68,7 @@
     result = recorder.open(argParser);
     if (result != AAUDIO_OK) {
         fprintf(stderr, "ERROR -  recorder.open() returned %d\n", result);
+        printf("IMPORTANT - Did you remember to enter:   adb root\n");
         goto finish;
     }
     aaudioStream = recorder.getStream();
@@ -96,17 +96,18 @@
     printf("DataFormat: framesPerRead  = %d\n",framesPerRead);
 
     actualDataFormat = AAudioStream_getFormat(aaudioStream);
-    printf("DataFormat: requested      = %d, actual = %d\n",
-           REQUIRED_FORMAT, actualDataFormat);
-    // TODO handle other data formats
-    assert(actualDataFormat == REQUIRED_FORMAT);
 
     // Allocate a buffer for the PCM_16 audio data.
-    data = new(std::nothrow) int16_t[framesPerRead * actualSamplesPerFrame];
-    if (data == nullptr) {
-        fprintf(stderr, "ERROR - could not allocate data buffer\n");
-        result = AAUDIO_ERROR_NO_MEMORY;
-        goto finish;
+    switch (actualDataFormat) {
+        case AAUDIO_FORMAT_PCM_I16:
+            shortData = new int16_t[framesPerRead * actualSamplesPerFrame];
+            break;
+        case AAUDIO_FORMAT_PCM_FLOAT:
+            floatData = new float[framesPerRead * actualSamplesPerFrame];
+            break;
+        default:
+            fprintf(stderr, "UNEXPECTED FORMAT! %d", actualDataFormat);
+            goto finish;
     }
 
     // Start the stream.
@@ -126,7 +127,12 @@
         // Read audio data from the stream.
         const int64_t timeoutNanos = 1000 * NANOS_PER_MILLISECOND;
         int minFrames = (framesToRecord < framesPerRead) ? framesToRecord : framesPerRead;
-        int actual = AAudioStream_read(aaudioStream, data, minFrames, timeoutNanos);
+        int actual = 0;
+        if (actualDataFormat == AAUDIO_FORMAT_PCM_I16) {
+            actual = AAudioStream_read(aaudioStream, shortData, minFrames, timeoutNanos);
+        } else if (actualDataFormat == AAUDIO_FORMAT_PCM_FLOAT) {
+            actual = AAudioStream_read(aaudioStream, floatData, minFrames, timeoutNanos);
+        }
         if (actual < 0) {
             fprintf(stderr, "ERROR - AAudioStream_read() returned %d\n", actual);
             result = actual;
@@ -140,7 +146,12 @@
 
         // Peak finder.
         for (int frameIndex = 0; frameIndex < actual; frameIndex++) {
-            float sample = data[frameIndex * actualSamplesPerFrame] * (1.0/32768);
+            float sample = 0.0f;
+            if (actualDataFormat == AAUDIO_FORMAT_PCM_I16) {
+                sample = shortData[frameIndex * actualSamplesPerFrame] * (1.0/32768);
+            } else if (actualDataFormat == AAUDIO_FORMAT_PCM_FLOAT) {
+                sample = floatData[frameIndex * actualSamplesPerFrame];
+            }
             if (sample > peakLevel) {
                 peakLevel = sample;
             }
@@ -151,17 +162,15 @@
             displayPeakLevel(peakLevel);
             peakLevel = 0.0;
             nextFrameCount += FRAMES_PER_LINE;
-        }
 
-        // Print timestamps.
-        int64_t framePosition = 0;
-        int64_t frameTime = 0;
-        aaudio_result_t timeResult;
-        timeResult = AAudioStream_getTimestamp(aaudioStream, CLOCK_MONOTONIC,
-                                               &framePosition, &frameTime);
+            // Print timestamps.
+            int64_t framePosition = 0;
+            int64_t frameTime = 0;
+            aaudio_result_t timeResult;
+            timeResult = AAudioStream_getTimestamp(aaudioStream, CLOCK_MONOTONIC,
+                                                   &framePosition, &frameTime);
 
-        if (timeResult == AAUDIO_OK) {
-            if (framePosition > (previousFramePosition + FRAMES_PER_LINE)) {
+            if (timeResult == AAUDIO_OK) {
                 int64_t realTime = getNanoseconds();
                 int64_t framesRead = AAudioStream_getFramesRead(aaudioStream);
 
@@ -175,11 +184,15 @@
                        (long long) framePosition,
                        (long long) frameTime,
                        latencyMillis);
-                previousFramePosition = framePosition;
+            } else {
+                printf("WARNING - AAudioStream_getTimestamp() returned %d\n", timeResult);
             }
         }
     }
 
+    state = AAudioStream_getState(aaudioStream);
+    printf("after loop, state = %s\n", AAudio_convertStreamStateToText(state));
+
     xRunCount = AAudioStream_getXRunCount(aaudioStream);
     printf("AAudioStream_getXRunCount %d\n", xRunCount);
 
@@ -192,7 +205,8 @@
 
 finish:
     recorder.close();
-    delete[] data;
+    delete[] shortData;
+    delete[] floatData;
     printf("exiting - AAudio result = %d = %s\n", result, AAudio_convertResultToText(result));
     return (result != AAUDIO_OK) ? EXIT_FAILURE : EXIT_SUCCESS;
 }
diff --git a/media/libaaudio/examples/input_monitor/src/input_monitor_callback.cpp b/media/libaaudio/examples/input_monitor/src/input_monitor_callback.cpp
index 893795b..986158f 100644
--- a/media/libaaudio/examples/input_monitor/src/input_monitor_callback.cpp
+++ b/media/libaaudio/examples/input_monitor/src/input_monitor_callback.cpp
@@ -47,6 +47,7 @@
                        SimpleRecorderDataCallbackProc, SimpleRecorderErrorCallbackProc, &myData);
     if (result != AAUDIO_OK) {
         fprintf(stderr, "ERROR -  recorder.open() returned %d\n", result);
+        printf("IMPORTANT - Did you remember to enter:   adb root\n");
         goto error;
     }
     printf("recorder.getFramesPerSecond() = %d\n", recorder.getFramesPerSecond());
diff --git a/media/libaaudio/examples/loopback/src/loopback.cpp b/media/libaaudio/examples/loopback/src/loopback.cpp
index 39d079e..026ff0f 100644
--- a/media/libaaudio/examples/loopback/src/loopback.cpp
+++ b/media/libaaudio/examples/loopback/src/loopback.cpp
@@ -151,8 +151,7 @@
 static void MyErrorCallbackProc(
         AAudioStream *stream __unused,
         void *userData __unused,
-        aaudio_result_t error)
-{
+        aaudio_result_t error) {
     printf("Error Callback, error: %d\n",(int)error);
     LoopbackData *myData = (LoopbackData *) userData;
     myData->outputError = error;
diff --git a/media/libaaudio/examples/utils/AAudioArgsParser.h b/media/libaaudio/examples/utils/AAudioArgsParser.h
index eb6925a..88d7401 100644
--- a/media/libaaudio/examples/utils/AAudioArgsParser.h
+++ b/media/libaaudio/examples/utils/AAudioArgsParser.h
@@ -87,7 +87,6 @@
     return;
 }
 
-// TODO use this as a base class within AAudio
 class AAudioParameters {
 public:
 
@@ -262,6 +261,9 @@
                 case 'd':
                     setDeviceId(atoi(&arg[2]));
                     break;
+                case 'f':
+                    setFormat(atoi(&arg[2]));
+                    break;
                 case 'i':
                     setInputPreset(atoi(&arg[2]));
                     break;
@@ -326,6 +328,10 @@
         printf("      -b{bufferCapacity} frames\n");
         printf("      -c{channels} for example 2 for stereo\n");
         printf("      -d{deviceId} default is %d\n", AAUDIO_UNSPECIFIED);
+        printf("      -f{0|1|2} set format\n");
+        printf("          0 = UNSPECIFIED\n");
+        printf("          1 = PCM_I16\n");
+        printf("          2 = FLOAT\n");
         printf("      -i{inputPreset} eg. 5 for AAUDIO_INPUT_PRESET_CAMCORDER\n");
         printf("      -m{0|1|2|3} set MMAP policy\n");
         printf("          0 = _UNSPECIFIED, use aaudio.mmap_policy system property, default\n");
diff --git a/media/libaaudio/examples/write_sine/src/write_sine.cpp b/media/libaaudio/examples/write_sine/src/write_sine.cpp
index 38e1e4c..8e33a31 100644
--- a/media/libaaudio/examples/write_sine/src/write_sine.cpp
+++ b/media/libaaudio/examples/write_sine/src/write_sine.cpp
@@ -57,7 +57,7 @@
     // in a buffer if we hang or crash.
     setvbuf(stdout, nullptr, _IONBF, (size_t) 0);
 
-    printf("%s - Play a sine wave using AAudio V0.1.2\n", argv[0]);
+    printf("%s - Play a sine wave using AAudio V0.1.3\n", argv[0]);
 
     if (argParser.parseArgs(argc, argv)) {
         return EXIT_FAILURE;
diff --git a/media/libaaudio/examples/write_sine/src/write_sine_callback.cpp b/media/libaaudio/examples/write_sine/src/write_sine_callback.cpp
index e167773..e33e9f8 100644
--- a/media/libaaudio/examples/write_sine/src/write_sine_callback.cpp
+++ b/media/libaaudio/examples/write_sine/src/write_sine_callback.cpp
@@ -204,7 +204,7 @@
     AAudioArgsParser::usage();
     printf("      -l{count} loopCount start/stop, every other one is silent\n");
     printf("      -t{msec}  play a high pitched tone at the beginning\n");
-    printf("      -f        force periodic underruns by sleeping in callback\n");
+    printf("      -z        force periodic underruns by sleeping in callback\n");
 }
 
 int main(int argc, const char **argv)
@@ -219,7 +219,7 @@
     // in a buffer if we hang or crash.
     setvbuf(stdout, nullptr, _IONBF, (size_t) 0);
 
-    printf("%s - Play a sine sweep using an AAudio callback V0.1.3\n", argv[0]);
+    printf("%s - Play a sine sweep using an AAudio callback V0.1.4\n", argv[0]);
 
     for (int i = 1; i < argc; i++) {
         const char *arg = argv[i];
@@ -234,8 +234,8 @@
                     case 't':
                         prefixToneMsec = atoi(&arg[2]);
                         break;
-                    case 'f':
-                        forceUnderruns = true;
+                    case 'z':
+                        forceUnderruns = true;  // Zzzzzzz
                         break;
                     default:
                         usage();
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index e40a6cd..2207cb8c 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -146,6 +146,8 @@
  * to make more refined volume or routing decisions.
  *
  * Note that these match the equivalent values in AudioAttributes in the Android Java API.
+ *
+ * Added in API level 28.
  */
 enum {
     /**
@@ -220,6 +222,8 @@
  * enforce audio focus.
  *
  * Note that these match the equivalent values in AudioAttributes in the Android Java API.
+ *
+ * Added in API level 28.
  */
 enum {
 
@@ -252,6 +256,8 @@
  * configuration.
  *
  * Note that these match the equivalent values in MediaRecorder.AudioSource in the Android Java API.
+ *
+ * Added in API level 28.
  */
 enum {
     /**
@@ -288,6 +294,8 @@
      * Do not allocate a session ID.
      * Effects cannot be used with this stream.
      * Default.
+     *
+     * Added in API level 28.
      */
     AAUDIO_SESSION_ID_NONE = -1,
 
@@ -297,6 +305,8 @@
      * Note that the use of this flag may result in higher latency.
      *
      * Note that this matches the value of AudioManager.AUDIO_SESSION_ID_GENERATE.
+     *
+     * Added in API level 28.
      */
     AAUDIO_SESSION_ID_ALLOCATE = 0,
 };
@@ -481,6 +491,8 @@
  *
  * The default, if you do not call this function, is AAUDIO_USAGE_MEDIA.
  *
+ * Added in API level 28.
+ *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param usage the desired usage, eg. AAUDIO_USAGE_GAME
  */
@@ -496,6 +508,8 @@
  *
  * The default, if you do not call this function, is AAUDIO_CONTENT_TYPE_MUSIC.
  *
+ * Added in API level 28.
+ *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param contentType the type of audio data, eg. AAUDIO_CONTENT_TYPE_SPEECH
  */
@@ -514,6 +528,8 @@
  * That is because VOICE_RECOGNITION is the preset with the lowest latency
  * on many platforms.
  *
+ * Added in API level 28.
+ *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param inputPreset the desired configuration for recording
  */
@@ -540,6 +556,8 @@
  *
  * Allocated session IDs will always be positive and nonzero.
  *
+ * Added in API level 28.
+ *
  * @param builder reference provided by AAudio_createStreamBuilder()
  * @param sessionId an allocated sessionID or AAUDIO_SESSION_ID_ALLOCATE
  */
@@ -1059,6 +1077,8 @@
  *
  * The sessionID for a stream should not change once the stream has been opened.
  *
+ * Added in API level 28.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return session ID or AAUDIO_SESSION_ID_NONE
  */
@@ -1094,6 +1114,8 @@
 /**
  * Return the use case for the stream.
  *
+ * Added in API level 28.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return frames read
  */
@@ -1102,6 +1124,8 @@
 /**
  * Return the content type for the stream.
  *
+ * Added in API level 28.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return content type, for example AAUDIO_CONTENT_TYPE_MUSIC
  */
@@ -1110,6 +1134,8 @@
 /**
  * Return the input preset for the stream.
  *
+ * Added in API level 28.
+ *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
  * @return input preset, for example AAUDIO_INPUT_PRESET_CAMCORDER
  */
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 6b25302..2a3e668 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -67,8 +67,6 @@
         , mWakeupDelayNanos(AAudioProperty_getWakeupDelayMicros() * AAUDIO_NANOS_PER_MICROSECOND)
         , mMinimumSleepNanos(AAudioProperty_getMinimumSleepMicros() * AAUDIO_NANOS_PER_MICROSECOND)
         {
-    ALOGD("%s - mWakeupDelayNanos = %d, mMinimumSleepNanos = %d",
-          __func__, mWakeupDelayNanos, mMinimumSleepNanos);
 }
 
 AudioStreamInternal::~AudioStreamInternal() {
@@ -231,8 +229,7 @@
 
 aaudio_result_t AudioStreamInternal::close() {
     aaudio_result_t result = AAUDIO_OK;
-    ALOGD("close(): mServiceStreamHandle = 0x%08X",
-             mServiceStreamHandle);
+    ALOGD("%s(): mServiceStreamHandle = 0x%08X", __func__, mServiceStreamHandle);
     if (mServiceStreamHandle != AAUDIO_HANDLE_INVALID) {
         // Don't close a stream while it is running.
         aaudio_stream_state_t currentState = getState();
@@ -243,8 +240,8 @@
             result = waitForStateChange(currentState, &nextState,
                                                        timeoutNanoseconds);
             if (result != AAUDIO_OK) {
-                ALOGE("close() waitForStateChange() returned %d %s",
-                result, AAudio_convertResultToText(result));
+                ALOGE("%s() waitForStateChange() returned %d %s",
+                __func__, result, AAudio_convertResultToText(result));
             }
         }
         setState(AAUDIO_STREAM_STATE_CLOSING);
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
index 11b43c3..0c3b1fa 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
@@ -57,8 +57,7 @@
         return result;
     }
     if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
-        ALOGE("requestPauseInternal() mServiceStreamHandle invalid = 0x%08X",
-              mServiceStreamHandle);
+        ALOGE("%s() mServiceStreamHandle invalid", __func__);
         return AAUDIO_ERROR_INVALID_STATE;
     }
 
@@ -70,8 +69,7 @@
 
 aaudio_result_t AudioStreamInternalPlay::requestFlush() {
     if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
-        ALOGE("AudioStreamInternal::requestFlush() mServiceStreamHandle invalid = 0x%08X",
-              mServiceStreamHandle);
+        ALOGE("%s() mServiceStreamHandle invalid", __func__);
         return AAUDIO_ERROR_INVALID_STATE;
     }
 
@@ -86,7 +84,7 @@
     // Bump offset so caller does not see the retrograde motion in getFramesRead().
     int64_t offset = writeCounter - readCounter;
     mFramesOffsetFromService += offset;
-    ALOGD("advanceClientToMatchServerPosition() readN = %lld, writeN = %lld, offset = %lld",
+    ALOGV("%s() readN = %lld, writeN = %lld, offset = %lld", __func__,
           (long long)readCounter, (long long)writeCounter, (long long)mFramesOffsetFromService);
 
     // Force writeCounter to match readCounter.
@@ -100,9 +98,7 @@
 
 // Write the data, block if needed and timeoutMillis > 0
 aaudio_result_t AudioStreamInternalPlay::write(const void *buffer, int32_t numFrames,
-                                           int64_t timeoutNanoseconds)
-
-{
+                                               int64_t timeoutNanoseconds) {
     return processData((void *)buffer, numFrames, timeoutNanoseconds);
 }
 
@@ -121,7 +117,7 @@
         // Still haven't got any timestamps from server.
         // Keep waiting until we get some valid timestamps then start writing to the
         // current buffer position.
-        ALOGD("processDataNow() wait for valid timestamps");
+        ALOGD("%s() wait for valid timestamps", __func__);
         // Sleep very briefly and hope we get a timestamp soon.
         *wakeTimePtr = currentNanoTime + (2000 * AAUDIO_NANOS_PER_MICROSECOND);
         ATRACE_END();
@@ -203,8 +199,6 @@
 
 aaudio_result_t AudioStreamInternalPlay::writeNowWithConversion(const void *buffer,
                                                             int32_t numFrames) {
-    // ALOGD("AudioStreamInternal::writeNowWithConversion(%p, %d)",
-    //              buffer, numFrames);
     WrappingBuffer wrappingBuffer;
     uint8_t *byteBuffer = (uint8_t *) buffer;
     int32_t framesLeft = numFrames;
@@ -249,7 +243,6 @@
     int32_t framesWritten = numFrames - framesLeft;
     mAudioEndpoint.advanceWriteIndex(framesWritten);
 
-    // ALOGD("AudioStreamInternal::writeNowWithConversion() returns %d", framesWritten);
     return framesWritten;
 }
 
@@ -268,7 +261,6 @@
     } else {
         mLastFramesRead = framesRead;
     }
-    //ALOGD("AudioStreamInternalPlay::getFramesRead() returns %lld", (long long)framesRead);
     return framesRead;
 }
 
@@ -276,13 +268,13 @@
 {
     int64_t framesWritten = mAudioEndpoint.getDataWriteCounter()
                                + mFramesOffsetFromService;
-    //ALOGD("AudioStreamInternalPlay::getFramesWritten() returns %lld", (long long)framesWritten);
     return framesWritten;
 }
 
 
 // Render audio in the application callback and then write the data to the stream.
 void *AudioStreamInternalPlay::callbackLoop() {
+    ALOGD("%s() entering >>>>>>>>>>>>>>>", __func__);
     aaudio_result_t result = AAUDIO_OK;
     aaudio_data_callback_result_t callbackResult = AAUDIO_CALLBACK_RESULT_CONTINUE;
     if (!isDataCallbackSet()) return NULL;
@@ -297,7 +289,6 @@
             // Write audio data to stream. This is a BLOCKING WRITE!
             result = write(mCallbackBuffer, mCallbackFrames, timeoutNanos);
             if ((result != mCallbackFrames)) {
-                ALOGE("AudioStreamInternalPlay(): callbackLoop: write() returned %d", result);
                 if (result >= 0) {
                     // Only wrote some of the frames requested. Must have timed out.
                     result = AAUDIO_ERROR_TIMEOUT;
@@ -306,13 +297,13 @@
                 break;
             }
         } else if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
-            ALOGD("AudioStreamInternalPlay(): callback returned AAUDIO_CALLBACK_RESULT_STOP");
+            ALOGV("%s(): callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
             break;
         }
     }
 
-    ALOGD("AudioStreamInternalPlay(): callbackLoop() exiting, result = %d, isActive() = %d",
-          result, (int) isActive());
+    ALOGD("%s() exiting, result = %d, isActive() = %d <<<<<<<<<<<<<<",
+          __func__, result, (int) isActive());
     return NULL;
 }
 
diff --git a/media/libaaudio/src/core/AudioStream.cpp b/media/libaaudio/src/core/AudioStream.cpp
index c4465fd..61e03db 100644
--- a/media/libaaudio/src/core/AudioStream.cpp
+++ b/media/libaaudio/src/core/AudioStream.cpp
@@ -104,17 +104,17 @@
     mErrorCallbackUserData = builder.getErrorCallbackUserData();
 
     // This is very helpful for debugging in the future. Please leave it in.
-    ALOGI("open() rate = %d, channels = %d, format = %d, sharing = %s, dir = %s",
+    ALOGI("open() rate   = %d, channels    = %d, format   = %d, sharing = %s, dir = %s",
           mSampleRate, mSamplesPerFrame, mFormat,
           AudioStream_convertSharingModeToShortText(mSharingMode),
           (getDirection() == AAUDIO_DIRECTION_OUTPUT) ? "OUTPUT" : "INPUT");
-    ALOGI("open() device = %d, sessionId = %d, perfMode = %d, callback: %s with frames = %d",
+    ALOGI("open() device = %d, sessionId   = %d, perfMode = %d, callback: %s with frames = %d",
           mDeviceId,
           mSessionId,
           mPerformanceMode,
           (isDataCallbackSet() ? "ON" : "OFF"),
           mFramesPerDataCallback);
-    ALOGI("open() usage = %d, contentType = %d, inputPreset = %d",
+    ALOGI("open() usage  = %d, contentType = %d, inputPreset = %d",
           mUsage, mContentType, mInputPreset);
 
     return AAUDIO_OK;
@@ -242,6 +242,22 @@
     return close();
 }
 
+void AudioStream::setState(aaudio_stream_state_t state) {
+    ALOGV("%s(%p) from %d to %d", __func__, this, mState, state);
+    // CLOSED is a final state
+    if (mState == AAUDIO_STREAM_STATE_CLOSED) {
+        ALOGE("%s(%p) tried to set to %d but already CLOSED", __func__, this, state);
+
+    // Once DISCONNECTED, we can only move to CLOSED state.
+    } else if (mState == AAUDIO_STREAM_STATE_DISCONNECTED
+               && state != AAUDIO_STREAM_STATE_CLOSED) {
+        ALOGE("%s(%p) tried to set to %d but already DISCONNECTED", __func__, this, state);
+
+    } else {
+        mState = state;
+    }
+}
+
 aaudio_result_t AudioStream::waitForStateChange(aaudio_stream_state_t currentState,
                                                 aaudio_stream_state_t *nextState,
                                                 int64_t timeoutNanoseconds)
@@ -313,7 +329,9 @@
     setPeriodNanoseconds(periodNanoseconds);
     int err = pthread_create(&mThread, nullptr, AudioStream_internalThreadProc, this);
     if (err != 0) {
-        return AAudioConvert_androidToAAudioResult(-errno);
+        android::status_t status = -errno;
+        ALOGE("createThread() - pthread_create() failed, %d", status);
+        return AAudioConvert_androidToAAudioResult(status);
     } else {
         // TODO Use AAudioThread or maybe AndroidThread
         // Name the thread with an increasing index, "AAudio_#", for debugging.
diff --git a/media/libaaudio/src/core/AudioStream.h b/media/libaaudio/src/core/AudioStream.h
index c0db0f9..5273e36 100644
--- a/media/libaaudio/src/core/AudioStream.h
+++ b/media/libaaudio/src/core/AudioStream.h
@@ -471,16 +471,7 @@
         mFormat = format;
     }
 
-    void setState(aaudio_stream_state_t state) {
-        if (mState == AAUDIO_STREAM_STATE_CLOSED) {
-            ; // CLOSED is a final state
-        } else if (mState == AAUDIO_STREAM_STATE_DISCONNECTED
-                && state != AAUDIO_STREAM_STATE_CLOSED) {
-            ; // Once DISCONNECTED, we can only move to CLOSED state.
-        } else {
-            mState = state;
-        }
-    }
+    void setState(aaudio_stream_state_t state);
 
     void setDeviceId(int32_t deviceId) {
         mDeviceId = deviceId;
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 50c1295..86791c2 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -770,6 +770,7 @@
         mReleased = 0;
     }
 
+    mProxy->stop(); // notify server not to read beyond current client position until start().
     mProxy->interrupt();
     mAudioTrack->stop();
 
@@ -2248,6 +2249,16 @@
         staticPosition = mStaticProxy->getPosition().unsignedValue();
     }
 
+    // See b/74409267. Connecting to a BT A2DP device supporting multiple codecs
+    // causes a lot of churn on the service side, and it can reject starting
+    // playback of a previously created track. May also apply to other cases.
+    const int INITIAL_RETRIES = 3;
+    int retries = INITIAL_RETRIES;
+retry:
+    if (retries < INITIAL_RETRIES) {
+        // See the comment for clearAudioConfigCache at the start of the function.
+        AudioSystem::clearAudioConfigCache();
+    }
     mFlags = mOrigFlags;
 
     // If a new IAudioTrack is successfully created, createTrack_l() will modify the
@@ -2256,7 +2267,10 @@
     // If a new IAudioTrack cannot be created, the previous (dead) instance will be left intact.
     status_t result = createTrack_l();
 
-    if (result == NO_ERROR) {
+    if (result != NO_ERROR) {
+        ALOGW("%s(): createTrack_l failed, do not retry", __func__);
+        retries = 0;
+    } else {
         // take the frames that will be lost by track recreation into account in saved position
         // For streaming tracks, this is the amount we obtained from the user/client
         // (not the number actually consumed at the server - those are already lost).
@@ -2301,7 +2315,10 @@
         mFramesWrittenAtRestore = mFramesWrittenServerOffset;
     }
     if (result != NO_ERROR) {
-        ALOGW("restoreTrack_l() failed status %d", result);
+        ALOGW("%s() failed status %d, retries %d", __func__, result, retries);
+        if (--retries > 0) {
+            goto retry;
+        }
         mState = STATE_STOPPED;
         mReleased = 0;
     }
diff --git a/media/libaudioclient/AudioTrackShared.cpp b/media/libaudioclient/AudioTrackShared.cpp
index 7bf4f99..b4c179d 100644
--- a/media/libaudioclient/AudioTrackShared.cpp
+++ b/media/libaudioclient/AudioTrackShared.cpp
@@ -393,19 +393,50 @@
 
 // ---------------------------------------------------------------------------
 
-__attribute__((no_sanitize("integer")))
 void AudioTrackClientProxy::flush()
 {
+    sendStreamingFlushStop(true /* flush */);
+}
+
+void AudioTrackClientProxy::stop()
+{
+    sendStreamingFlushStop(false /* flush */);
+}
+
+// Sets the client-written mFlush and mStop positions, which control server behavior.
+//
+// @param flush indicates whether the operation is a flush or stop.
+// A client stop sets mStop to the current write position;
+// the server will not read past this point until start() or subsequent flush().
+// A client flush sets both mStop and mFlush to the current write position.
+// This advances the server read limit (if previously set) and on the next
+// server read advances the server read position to this limit.
+//
+void AudioTrackClientProxy::sendStreamingFlushStop(bool flush)
+{
+    // TODO: Replace this by 64 bit counters - avoids wrap complication.
     // This works for mFrameCountP2 <= 2^30
-    size_t increment = mFrameCountP2 << 1;
-    size_t mask = increment - 1;
-    audio_track_cblk_t* cblk = mCblk;
     // mFlush is 32 bits concatenated as [ flush_counter ] [ newfront_offset ]
     // Should newFlush = cblk->u.mStreaming.mRear?  Only problem is
     // if you want to flush twice to the same rear location after a 32 bit wrap.
-    int32_t newFlush = (cblk->u.mStreaming.mRear & mask) |
-                        ((cblk->u.mStreaming.mFlush & ~mask) + increment);
-    android_atomic_release_store(newFlush, &cblk->u.mStreaming.mFlush);
+
+    const size_t increment = mFrameCountP2 << 1;
+    const size_t mask = increment - 1;
+    // No need for client atomic synchronization on mRear, mStop, mFlush
+    // as AudioTrack client only read/writes to them under client lock. Server only reads.
+    const int32_t rearMasked = mCblk->u.mStreaming.mRear & mask;
+
+    // update stop before flush so that the server front
+    // never advances beyond a (potential) previous stop's rear limit.
+    int32_t stopBits; // the following add can overflow
+    __builtin_add_overflow(mCblk->u.mStreaming.mStop & ~mask, increment, &stopBits);
+    android_atomic_release_store(rearMasked | stopBits, &mCblk->u.mStreaming.mStop);
+
+    if (flush) {
+        int32_t flushBits; // the following add can overflow
+        __builtin_add_overflow(mCblk->u.mStreaming.mFlush & ~mask, increment, &flushBits);
+        android_atomic_release_store(rearMasked | flushBits, &mCblk->u.mStreaming.mFlush);
+    }
 }
 
 bool AudioTrackClientProxy::clearStreamEndDone() {
@@ -540,6 +571,11 @@
     LOG_ALWAYS_FATAL("static flush");
 }
 
+void StaticAudioTrackClientProxy::stop()
+{
+    ; // no special handling required for static tracks.
+}
+
 void StaticAudioTrackClientProxy::setLoop(size_t loopStart, size_t loopEnd, int loopCount)
 {
     // This can only happen on a 64-bit client
@@ -638,6 +674,7 @@
     if (flush != mFlush) {
         ALOGV("ServerProxy::flushBufferIfNeeded() mStreaming.mFlush = 0x%x, mFlush = 0x%0x",
                 flush, mFlush);
+        // shouldn't matter, but for range safety use mRear instead of getRear().
         int32_t rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear);
         int32_t front = cblk->u.mStreaming.mFront;
 
@@ -677,6 +714,45 @@
 }
 
 __attribute__((no_sanitize("integer")))
+int32_t AudioTrackServerProxy::getRear() const
+{
+    const int32_t stop = android_atomic_acquire_load(&mCblk->u.mStreaming.mStop);
+    const int32_t rear = android_atomic_acquire_load(&mCblk->u.mStreaming.mRear);
+    const int32_t stopLast = mStopLast.load(std::memory_order_acquire);
+    if (stop != stopLast) {
+        const int32_t front = mCblk->u.mStreaming.mFront;
+        const size_t overflowBit = mFrameCountP2 << 1;
+        const size_t mask = overflowBit - 1;
+        int32_t newRear = (rear & ~mask) | (stop & mask);
+        ssize_t filled = newRear - front;
+        if (filled < 0) {
+            // front and rear offsets span the overflow bit of the p2 mask
+            // so rebasing newrear.
+            ALOGV("stop wrap: filled %zx >= overflowBit %zx", filled, overflowBit);
+            newRear += overflowBit;
+            filled += overflowBit;
+        }
+        if (0 <= filled && (size_t) filled <= mFrameCount) {
+            // we're stopped, return the stop level as newRear
+            return newRear;
+        }
+
+        // A corrupt stop. Log error and ignore.
+        ALOGE("mStopLast %#x -> stop %#x, front %#x, rear %#x, mask %#x, newRear %#x, "
+                "filled %zd=%#x",
+                stopLast, stop, front, rear,
+                (unsigned)mask, newRear, filled, (unsigned)filled);
+        // Don't reset mStopLast as this is const.
+    }
+    return rear;
+}
+
+void AudioTrackServerProxy::start()
+{
+    mStopLast = android_atomic_acquire_load(&mCblk->u.mStreaming.mStop);
+}
+
+__attribute__((no_sanitize("integer")))
 status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush)
 {
     LOG_ALWAYS_FATAL_IF(buffer == NULL || buffer->mFrameCount == 0,
@@ -693,7 +769,7 @@
     // See notes on barriers at ClientProxy::obtainBuffer()
     if (mIsOut) {
         flushBufferIfNeeded(); // might modify mFront
-        rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear);
+        rear = getRear();
         front = cblk->u.mStreaming.mFront;
     } else {
         front = android_atomic_acquire_load(&cblk->u.mStreaming.mFront);
@@ -825,8 +901,7 @@
         // FIXME should return an accurate value, but over-estimate is better than under-estimate
         return mFrameCount;
     }
-    // the acquire might not be necessary since not doing a subsequent read
-    int32_t rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear);
+    const int32_t rear = getRear();
     ssize_t filled = rear - cblk->u.mStreaming.mFront;
     // pipe should not already be overfull
     if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
@@ -852,7 +927,7 @@
     if (flush != mFlush) {
         return mFrameCount;
     }
-    const int32_t rear = android_atomic_acquire_load(&cblk->u.mStreaming.mRear);
+    const int32_t rear = getRear();
     const ssize_t filled = rear - cblk->u.mStreaming.mFront;
     if (!(0 <= filled && (size_t) filled <= mFrameCount)) {
         return 0; // error condition, silently return 0.
@@ -1149,6 +1224,12 @@
     }
 }
 
+int32_t StaticAudioTrackServerProxy::getRear() const
+{
+    LOG_ALWAYS_FATAL("getRear() not permitted for static tracks");
+    return 0;
+}
+
 // ---------------------------------------------------------------------------
 
 }   // namespace android
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 873d836..77cfe4d 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -87,7 +87,7 @@
     GET_AUDIO_HW_SYNC_FOR_SESSION,
     SYSTEM_READY,
     FRAME_COUNT_HAL,
-    LIST_MICROPHONES,
+    GET_MICROPHONES,
 };
 
 #define MAX_ITEMS_PER_LIST 1024
@@ -849,7 +849,7 @@
     {
         Parcel data, reply;
         data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
-        status_t status = remote()->transact(LIST_MICROPHONES, data, &reply);
+        status_t status = remote()->transact(GET_MICROPHONES, data, &reply);
         if (status != NO_ERROR ||
                 (status = (status_t)reply.readInt32()) != NO_ERROR) {
             return status;
@@ -903,13 +903,15 @@
         case SET_MODE:
         case SET_MIC_MUTE:
         case SET_LOW_RAM_DEVICE:
-        case SYSTEM_READY:
-            if (IPCThreadState::self()->getCallingUid() >= AID_APP_START) {
+        case SYSTEM_READY: {
+            uid_t multiUserClientUid = IPCThreadState::self()->getCallingUid() % AID_USER_OFFSET;
+            if (multiUserClientUid >= AID_APP_START) {
                 ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
                       __func__, code, IPCThreadState::self()->getCallingPid(),
                       IPCThreadState::self()->getCallingUid());
                 return INVALID_OPERATION;
             }
+        } break;
         default:
             break;
     }
@@ -1442,7 +1444,7 @@
             reply->writeInt64( frameCountHAL((audio_io_handle_t) data.readInt32()) );
             return NO_ERROR;
         } break;
-        case LIST_MICROPHONES: {
+        case GET_MICROPHONES: {
             CHECK_INTERFACE(IAudioFlinger, data, reply);
             std::vector<media::MicrophoneInfo> microphones;
             status_t status = getMicrophones(&microphones);
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 0b98502..a49b2cb 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -872,18 +872,33 @@
         case INIT_STREAM_VOLUME:
         case SET_STREAM_VOLUME:
         case REGISTER_POLICY_MIXES:
-        case SET_MASTER_MONO:
-            if (IPCThreadState::self()->getCallingUid() >= AID_APP_START) {
+        case SET_MASTER_MONO: {
+            uid_t multiUserClientUid = IPCThreadState::self()->getCallingUid() % AID_USER_OFFSET;
+            if (multiUserClientUid >= AID_APP_START) {
                 ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
                       __func__, code, IPCThreadState::self()->getCallingPid(),
                       IPCThreadState::self()->getCallingUid());
                 return INVALID_OPERATION;
             }
+        } break;
         default:
             break;
     }
 
-    TimeCheck check("IAudioPolicyService");
+    // FIXME: extend timeout for SET_DEVICE_CONNECTION_STATE and HANDLE_DEVICE_CONFIG_CHANGE
+    // while we investigate why BT A2DP device connection/disconnection can sometimes
+    // take more than 5 seconds
+    uint32_t timeoutMs = TimeCheck::kDefaultTimeOutMs;
+    switch (code) {
+        case SET_DEVICE_CONNECTION_STATE:
+        case HANDLE_DEVICE_CONFIG_CHANGE:
+            timeoutMs *= 2;
+            break;
+        default:
+            break;
+    }
+
+    TimeCheck check("IAudioPolicyService", timeoutMs);
 
     switch (code) {
         case SET_DEVICE_CONNECTION_STATE: {
diff --git a/media/libaudiohal/2.0/DeviceHalHidl.cpp b/media/libaudiohal/2.0/DeviceHalHidl.cpp
index 0d9c6c4..5b99d70 100644
--- a/media/libaudiohal/2.0/DeviceHalHidl.cpp
+++ b/media/libaudiohal/2.0/DeviceHalHidl.cpp
@@ -53,7 +53,7 @@
         audio_devices_t device, const char* halAddress, DeviceAddress* address) {
     address->device = AudioDevice(device);
 
-    if (address == nullptr || strnlen(halAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
+    if (halAddress == nullptr || strnlen(halAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
         return OK;
     }
     const bool isInput = (device & AUDIO_DEVICE_BIT_IN) != 0;
@@ -346,6 +346,12 @@
     return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
 }
 
+status_t DeviceHalHidl::getMicrophones(
+        std::vector<media::MicrophoneInfo> *microphonesInfo __unused) {
+    if (mDevice == 0) return NO_INIT;
+    return INVALID_OPERATION;
+}
+
 status_t DeviceHalHidl::dump(int fd) {
     if (mDevice == 0) return NO_INIT;
     native_handle_t* hidlHandle = native_handle_create(1, 0);
diff --git a/media/libaudiohal/2.0/DeviceHalHidl.h b/media/libaudiohal/2.0/DeviceHalHidl.h
index 8651b51..3c1cb59 100644
--- a/media/libaudiohal/2.0/DeviceHalHidl.h
+++ b/media/libaudiohal/2.0/DeviceHalHidl.h
@@ -107,6 +107,9 @@
     // Set audio port configuration.
     virtual status_t setAudioPortConfig(const struct audio_port_config *config);
 
+    // List microphones
+    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
     virtual status_t dump(int fd);
 
   private:
diff --git a/media/libaudiohal/2.0/DeviceHalLocal.cpp b/media/libaudiohal/2.0/DeviceHalLocal.cpp
index fc098f5..ec3bf78 100644
--- a/media/libaudiohal/2.0/DeviceHalLocal.cpp
+++ b/media/libaudiohal/2.0/DeviceHalLocal.cpp
@@ -184,6 +184,11 @@
         return INVALID_OPERATION;
 }
 
+status_t DeviceHalLocal::getMicrophones(
+        std::vector<media::MicrophoneInfo> *microphones __unused) {
+    return INVALID_OPERATION;
+}
+
 status_t DeviceHalLocal::dump(int fd) {
     return mDev->dump(mDev, fd);
 }
diff --git a/media/libaudiohal/2.0/DeviceHalLocal.h b/media/libaudiohal/2.0/DeviceHalLocal.h
index 865f296..aec201a 100644
--- a/media/libaudiohal/2.0/DeviceHalLocal.h
+++ b/media/libaudiohal/2.0/DeviceHalLocal.h
@@ -100,6 +100,9 @@
     // Set audio port configuration.
     virtual status_t setAudioPortConfig(const struct audio_port_config *config);
 
+    // List microphones
+    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
     virtual status_t dump(int fd);
 
     void closeOutputStream(struct audio_stream_out *stream_out);
diff --git a/media/libaudiohal/2.0/StreamHalHidl.cpp b/media/libaudiohal/2.0/StreamHalHidl.cpp
index 0cafa36..9869cd2 100644
--- a/media/libaudiohal/2.0/StreamHalHidl.cpp
+++ b/media/libaudiohal/2.0/StreamHalHidl.cpp
@@ -555,6 +555,11 @@
     }
 }
 
+status_t StreamOutHalHidl::updateSourceMetadata(const SourceMetadata& /* sourceMetadata */) {
+    // Audio HAL V2.0 does not support propagating source metadata
+    return INVALID_OPERATION;
+}
+
 void StreamOutHalHidl::onWriteReady() {
     sp<StreamOutHalInterfaceCallback> callback = mCallback.promote();
     if (callback == 0) return;
@@ -749,4 +754,15 @@
     }
 }
 
+status_t StreamInHalHidl::getActiveMicrophones(
+        std::vector<media::MicrophoneInfo> *microphones __unused) {
+    if (mStream == 0) return NO_INIT;
+    return INVALID_OPERATION;
+}
+
+status_t StreamInHalHidl::updateSinkMetadata(const SinkMetadata& /* sinkMetadata */) {
+    // Audio HAL V2.0 does not support propagating sink metadata
+    return INVALID_OPERATION;
+}
+
 } // namespace android
diff --git a/media/libaudiohal/2.0/StreamHalHidl.h b/media/libaudiohal/2.0/StreamHalHidl.h
index d4ab943..ebad8ae 100644
--- a/media/libaudiohal/2.0/StreamHalHidl.h
+++ b/media/libaudiohal/2.0/StreamHalHidl.h
@@ -161,6 +161,9 @@
     // Return a recent count of the number of audio frames presented to an external observer.
     virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp);
 
+    // Called when the metadata of the stream's source has been changed.
+    status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;
+
     // Methods used by StreamOutCallback (HIDL).
     void onWriteReady();
     void onDrainReady();
@@ -210,6 +213,12 @@
     // the clock time associated with that frame count.
     virtual status_t getCapturePosition(int64_t *frames, int64_t *time);
 
+    // Get active microphones
+    virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
+    // Called when the metadata of the stream's sink has been changed.
+    status_t updateSinkMetadata(const SinkMetadata& sinkMetadata) override;
+
   private:
     friend class DeviceHalHidl;
     typedef MessageQueue<ReadParameters, hardware::kSynchronizedReadWrite> CommandMQ;
diff --git a/media/libaudiohal/2.0/StreamHalLocal.cpp b/media/libaudiohal/2.0/StreamHalLocal.cpp
index 8d61e24..98107e5 100644
--- a/media/libaudiohal/2.0/StreamHalLocal.cpp
+++ b/media/libaudiohal/2.0/StreamHalLocal.cpp
@@ -231,6 +231,19 @@
     return mStream->get_presentation_position(mStream, frames, timestamp);
 }
 
+status_t StreamOutHalLocal::updateSourceMetadata(const SourceMetadata& sourceMetadata) {
+    if (mStream->update_source_metadata == nullptr) {
+        return INVALID_OPERATION;
+    }
+    const source_metadata_t metadata {
+        .track_count = sourceMetadata.tracks.size(),
+        // const cast is fine as it is in a const structure
+        .tracks = const_cast<playback_track_metadata*>(sourceMetadata.tracks.data()),
+    };
+    mStream->update_source_metadata(mStream, &metadata);
+    return OK;
+}
+
 status_t StreamOutHalLocal::start() {
     if (mStream->start == NULL) return INVALID_OPERATION;
     return mStream->start(mStream);
@@ -292,6 +305,19 @@
     return mStream->get_capture_position(mStream, frames, time);
 }
 
+status_t StreamInHalLocal::updateSinkMetadata(const SinkMetadata& sinkMetadata) {
+    if (mStream->update_sink_metadata == nullptr) {
+        return INVALID_OPERATION;
+    }
+    const sink_metadata_t metadata {
+        .track_count = sinkMetadata.tracks.size(),
+        // const cast is fine as it is in a const structure
+        .tracks = const_cast<record_track_metadata*>(sinkMetadata.tracks.data()),
+    };
+    mStream->update_sink_metadata(mStream, &metadata);
+    return OK;
+}
+
 status_t StreamInHalLocal::start() {
     if (mStream->start == NULL) return INVALID_OPERATION;
     return mStream->start(mStream);
@@ -313,4 +339,9 @@
     return mStream->get_mmap_position(mStream, position);
 }
 
+status_t StreamInHalLocal::getActiveMicrophones(
+        std::vector<media::MicrophoneInfo> *microphones __unused) {
+    return INVALID_OPERATION;
+}
+
 } // namespace android
diff --git a/media/libaudiohal/2.0/StreamHalLocal.h b/media/libaudiohal/2.0/StreamHalLocal.h
index c7136df..cda8d0c 100644
--- a/media/libaudiohal/2.0/StreamHalLocal.h
+++ b/media/libaudiohal/2.0/StreamHalLocal.h
@@ -149,6 +149,9 @@
     // Get current read/write position in the mmap buffer
     virtual status_t getMmapPosition(struct audio_mmap_position *position);
 
+    // Called when the metadata of the stream's source has been changed.
+    status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;
+
   private:
     audio_stream_out_t *mStream;
     wp<StreamOutHalInterfaceCallback> mCallback;
@@ -194,6 +197,12 @@
     // Get current read/write position in the mmap buffer
     virtual status_t getMmapPosition(struct audio_mmap_position *position);
 
+    // Get active microphones
+    virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
+    // Called when the metadata of the stream's sink has been changed.
+    status_t updateSinkMetadata(const SinkMetadata& sinkMetadata) override;
+
   private:
     audio_stream_in_t *mStream;
 
diff --git a/media/libaudiohal/4.0/Android.bp b/media/libaudiohal/4.0/Android.bp
index 3d104ab..833defa 100644
--- a/media/libaudiohal/4.0/Android.bp
+++ b/media/libaudiohal/4.0/Android.bp
@@ -26,6 +26,7 @@
     shared_libs: [
         "libaudiohal_deathhandler",
         "libaudioutils",
+        "libbinder",
         "libcutils",
         "liblog",
         "libutils",
diff --git a/media/libaudiohal/4.0/ConversionHelperHidl.cpp b/media/libaudiohal/4.0/ConversionHelperHidl.cpp
index a3cc28f..fe27504 100644
--- a/media/libaudiohal/4.0/ConversionHelperHidl.cpp
+++ b/media/libaudiohal/4.0/ConversionHelperHidl.cpp
@@ -22,6 +22,11 @@
 
 #include "ConversionHelperHidl.h"
 
+using ::android::hardware::audio::V4_0::AudioMicrophoneChannelMapping;
+using ::android::hardware::audio::V4_0::AudioMicrophoneDirectionality;
+using ::android::hardware::audio::V4_0::AudioMicrophoneLocation;
+using ::android::hardware::audio::V4_0::DeviceAddress;
+using ::android::hardware::audio::V4_0::MicrophoneInfo;
 using ::android::hardware::audio::V4_0::Result;
 
 namespace android {
@@ -101,5 +106,132 @@
     ALOGE("%s %p %s: %s (from rpc)", mClassName, this, funcName, description);
 }
 
+// TODO: Use the same implementation in the hal when it moves to a util library.
+std::string deviceAddressToHal(const DeviceAddress& address) {
+    // HAL assumes that the address is NUL-terminated.
+    char halAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN];
+    memset(halAddress, 0, sizeof(halAddress));
+    audio_devices_t halDevice = static_cast<audio_devices_t>(address.device);
+    const bool isInput = (halDevice & AUDIO_DEVICE_BIT_IN) != 0;
+    if (isInput) halDevice &= ~AUDIO_DEVICE_BIT_IN;
+    if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) ||
+        (isInput && (halDevice & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
+        snprintf(halAddress, sizeof(halAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
+                 address.address.mac[0], address.address.mac[1], address.address.mac[2],
+                 address.address.mac[3], address.address.mac[4], address.address.mac[5]);
+    } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_IP) != 0) ||
+               (isInput && (halDevice & AUDIO_DEVICE_IN_IP) != 0)) {
+        snprintf(halAddress, sizeof(halAddress), "%d.%d.%d.%d", address.address.ipv4[0],
+                 address.address.ipv4[1], address.address.ipv4[2], address.address.ipv4[3]);
+    } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_USB) != 0) ||
+               (isInput && (halDevice & AUDIO_DEVICE_IN_ALL_USB) != 0)) {
+        snprintf(halAddress, sizeof(halAddress), "card=%d;device=%d", address.address.alsa.card,
+                 address.address.alsa.device);
+    } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_BUS) != 0) ||
+               (isInput && (halDevice & AUDIO_DEVICE_IN_BUS) != 0)) {
+        snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
+    } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0 ||
+               (isInput && (halDevice & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
+        snprintf(halAddress, sizeof(halAddress), "%s", address.rSubmixAddress.c_str());
+    } else {
+        snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
+    }
+    return halAddress;
+}
+
+//local conversion helpers
+
+audio_microphone_channel_mapping_t  channelMappingToHal(AudioMicrophoneChannelMapping mapping) {
+    switch (mapping) {
+        case AudioMicrophoneChannelMapping::UNUSED:
+            return AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
+        case AudioMicrophoneChannelMapping::DIRECT:
+            return AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT;
+        case AudioMicrophoneChannelMapping::PROCESSED:
+            return AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED;
+        default:
+            LOG_ALWAYS_FATAL("Unknown channelMappingToHal conversion %d", mapping);
+    }
+}
+
+audio_microphone_location_t locationToHal(AudioMicrophoneLocation location) {
+    switch (location) {
+        case AudioMicrophoneLocation::UNKNOWN:
+            return AUDIO_MICROPHONE_LOCATION_UNKNOWN;
+        case AudioMicrophoneLocation::MAINBODY:
+            return AUDIO_MICROPHONE_LOCATION_MAINBODY;
+        case AudioMicrophoneLocation::MAINBODY_MOVABLE:
+            return AUDIO_MICROPHONE_LOCATION_MAINBODY_MOVABLE;
+        case AudioMicrophoneLocation::PERIPHERAL:
+            return AUDIO_MICROPHONE_LOCATION_PERIPHERAL;
+        default:
+            LOG_ALWAYS_FATAL("Unknown locationToHal conversion %d", location);
+    }
+}
+audio_microphone_directionality_t directionalityToHal(AudioMicrophoneDirectionality dir) {
+    switch (dir) {
+        case AudioMicrophoneDirectionality::UNKNOWN:
+            return AUDIO_MICROPHONE_DIRECTIONALITY_UNKNOWN;
+        case AudioMicrophoneDirectionality::OMNI:
+            return AUDIO_MICROPHONE_DIRECTIONALITY_OMNI;
+        case AudioMicrophoneDirectionality::BI_DIRECTIONAL:
+            return AUDIO_MICROPHONE_DIRECTIONALITY_BI_DIRECTIONAL;
+        case AudioMicrophoneDirectionality::CARDIOID:
+            return AUDIO_MICROPHONE_DIRECTIONALITY_CARDIOID;
+        case AudioMicrophoneDirectionality::HYPER_CARDIOID:
+            return AUDIO_MICROPHONE_DIRECTIONALITY_HYPER_CARDIOID;
+        case AudioMicrophoneDirectionality::SUPER_CARDIOID:
+            return AUDIO_MICROPHONE_DIRECTIONALITY_SUPER_CARDIOID;
+        default:
+            LOG_ALWAYS_FATAL("Unknown directionalityToHal conversion %d", dir);
+    }
+}
+
+// static
+void ConversionHelperHidl::microphoneInfoToHal(const MicrophoneInfo& src,
+                                                     audio_microphone_characteristic_t *pDst) {
+    if (pDst != NULL) {
+        snprintf(pDst->device_id, sizeof(pDst->device_id),
+                 "%s", src.deviceId.c_str());
+        pDst->device = static_cast<audio_devices_t>(src.deviceAddress.device);
+        snprintf(pDst->address, sizeof(pDst->address),
+                 "%s", deviceAddressToHal(src.deviceAddress).c_str());
+        if (src.channelMapping.size() > AUDIO_CHANNEL_COUNT_MAX) {
+            ALOGW("microphoneInfoToStruct found %zu channelMapping elements. Max expected is %d",
+                  src.channelMapping.size(), AUDIO_CHANNEL_COUNT_MAX);
+        }
+        size_t ch;
+        for (ch = 0; ch < src.channelMapping.size() && ch < AUDIO_CHANNEL_COUNT_MAX; ch++) {
+            pDst->channel_mapping[ch] = channelMappingToHal(src.channelMapping[ch]);
+        }
+        for (; ch < AUDIO_CHANNEL_COUNT_MAX; ch++) {
+            pDst->channel_mapping[ch] = AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
+        }
+        pDst->location = locationToHal(src.location);
+        pDst->group = (audio_microphone_group_t)src.group;
+        pDst->index_in_the_group = (unsigned int)src.indexInTheGroup;
+        pDst->sensitivity = src.sensitivity;
+        pDst->max_spl = src.maxSpl;
+        pDst->min_spl = src.minSpl;
+        pDst->directionality = directionalityToHal(src.directionality);
+        pDst->num_frequency_responses = (unsigned int)src.frequencyResponse.size();
+        if (pDst->num_frequency_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
+            ALOGW("microphoneInfoToStruct found %d frequency responses. Max expected is %d",
+                  pDst->num_frequency_responses, AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES);
+            pDst->num_frequency_responses = AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES;
+        }
+        for (size_t k = 0; k < pDst->num_frequency_responses; k++) {
+            pDst->frequency_responses[0][k] = src.frequencyResponse[k].frequency;
+            pDst->frequency_responses[1][k] = src.frequencyResponse[k].level;
+        }
+        pDst->geometric_location.x = src.position.x;
+        pDst->geometric_location.y = src.position.y;
+        pDst->geometric_location.z = src.position.z;
+        pDst->orientation.x = src.orientation.x;
+        pDst->orientation.y = src.orientation.y;
+        pDst->orientation.z = src.orientation.z;
+    }
+}
+
 }  // namespace V4_0
 }  // namespace android
diff --git a/media/libaudiohal/4.0/ConversionHelperHidl.h b/media/libaudiohal/4.0/ConversionHelperHidl.h
index ddc8569..8823a8d 100644
--- a/media/libaudiohal/4.0/ConversionHelperHidl.h
+++ b/media/libaudiohal/4.0/ConversionHelperHidl.h
@@ -19,9 +19,11 @@
 
 #include <android/hardware/audio/4.0/types.h>
 #include <hidl/HidlSupport.h>
+#include <system/audio.h>
 #include <utils/String8.h>
 
 using ::android::hardware::audio::V4_0::ParameterValue;
+using ::android::hardware::audio::V4_0::MicrophoneInfo;
 using ::android::hardware::Return;
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
@@ -34,6 +36,8 @@
     static status_t keysFromHal(const String8& keys, hidl_vec<hidl_string> *hidlKeys);
     static status_t parametersFromHal(const String8& kvPairs, hidl_vec<ParameterValue> *hidlParams);
     static void parametersToHal(const hidl_vec<ParameterValue>& parameters, String8 *values);
+    static void microphoneInfoToHal(const MicrophoneInfo& src,
+                                    audio_microphone_characteristic_t *pDst);
 
     ConversionHelperHidl(const char* className);
 
diff --git a/media/libaudiohal/4.0/DeviceHalHidl.cpp b/media/libaudiohal/4.0/DeviceHalHidl.cpp
index 8da1051..6facca9 100644
--- a/media/libaudiohal/4.0/DeviceHalHidl.cpp
+++ b/media/libaudiohal/4.0/DeviceHalHidl.cpp
@@ -59,7 +59,7 @@
         audio_devices_t device, const char* halAddress, DeviceAddress* address) {
     address->device = AudioDevice(device);
 
-    if (address == nullptr || strnlen(halAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
+    if (halAddress == nullptr || strnlen(halAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
         return OK;
     }
     const bool isInput = (device & AUDIO_DEVICE_BIT_IN) != 0;
@@ -359,6 +359,23 @@
     return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
 }
 
+status_t DeviceHalHidl::getMicrophones(std::vector<media::MicrophoneInfo> *microphonesInfo) {
+    if (mDevice == 0) return NO_INIT;
+    Result retval;
+    Return<void> ret = mDevice->getMicrophones(
+            [&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
+        retval = r;
+        for (size_t k = 0; k < micArrayHal.size(); k++) {
+            audio_microphone_characteristic_t dst;
+            //convert
+            microphoneInfoToHal(micArrayHal[k], &dst);
+            media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
+            microphonesInfo->push_back(microphone);
+        }
+    });
+    return processReturn("getMicrophones", ret, retval);
+}
+
 status_t DeviceHalHidl::dump(int fd) {
     if (mDevice == 0) return NO_INIT;
     native_handle_t* hidlHandle = native_handle_create(1, 0);
diff --git a/media/libaudiohal/4.0/DeviceHalHidl.h b/media/libaudiohal/4.0/DeviceHalHidl.h
index f460add..0bd2175 100644
--- a/media/libaudiohal/4.0/DeviceHalHidl.h
+++ b/media/libaudiohal/4.0/DeviceHalHidl.h
@@ -108,6 +108,9 @@
     // Set audio port configuration.
     virtual status_t setAudioPortConfig(const struct audio_port_config *config);
 
+    // List microphones
+    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
     virtual status_t dump(int fd);
 
   private:
diff --git a/media/libaudiohal/4.0/DeviceHalLocal.cpp b/media/libaudiohal/4.0/DeviceHalLocal.cpp
index e64eee1..a245dd9 100644
--- a/media/libaudiohal/4.0/DeviceHalLocal.cpp
+++ b/media/libaudiohal/4.0/DeviceHalLocal.cpp
@@ -185,6 +185,18 @@
         return INVALID_OPERATION;
 }
 
+status_t DeviceHalLocal::getMicrophones(std::vector<media::MicrophoneInfo> *microphones) {
+    if (mDev->get_microphones == NULL) return INVALID_OPERATION;
+    size_t actual_mics = AUDIO_MICROPHONE_MAX_COUNT;
+    audio_microphone_characteristic_t mic_array[AUDIO_MICROPHONE_MAX_COUNT];
+    status_t status = mDev->get_microphones(mDev, &mic_array[0], &actual_mics);
+    for (size_t i = 0; i < actual_mics; i++) {
+        media::MicrophoneInfo microphoneInfo = media::MicrophoneInfo(mic_array[i]);
+        microphones->push_back(microphoneInfo);
+    }
+    return status;
+}
+
 status_t DeviceHalLocal::dump(int fd) {
     return mDev->dump(mDev, fd);
 }
diff --git a/media/libaudiohal/4.0/DeviceHalLocal.h b/media/libaudiohal/4.0/DeviceHalLocal.h
index daafdc7..08341a4 100644
--- a/media/libaudiohal/4.0/DeviceHalLocal.h
+++ b/media/libaudiohal/4.0/DeviceHalLocal.h
@@ -101,6 +101,9 @@
     // Set audio port configuration.
     virtual status_t setAudioPortConfig(const struct audio_port_config *config);
 
+    // List microphones
+    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
     virtual status_t dump(int fd);
 
     void closeOutputStream(struct audio_stream_out *stream_out);
diff --git a/media/libaudiohal/4.0/StreamHalHidl.cpp b/media/libaudiohal/4.0/StreamHalHidl.cpp
index de16e98..1c2fdb0 100644
--- a/media/libaudiohal/4.0/StreamHalHidl.cpp
+++ b/media/libaudiohal/4.0/StreamHalHidl.cpp
@@ -28,14 +28,20 @@
 #include "VersionUtils.h"
 
 using ::android::hardware::audio::common::V4_0::AudioChannelMask;
+using ::android::hardware::audio::common::V4_0::AudioContentType;
 using ::android::hardware::audio::common::V4_0::AudioFormat;
+using ::android::hardware::audio::common::V4_0::AudioSource;
+using ::android::hardware::audio::common::V4_0::AudioUsage;
 using ::android::hardware::audio::common::V4_0::ThreadInfo;
 using ::android::hardware::audio::V4_0::AudioDrain;
 using ::android::hardware::audio::V4_0::IStreamOutCallback;
 using ::android::hardware::audio::V4_0::MessageQueueFlagBits;
+using ::android::hardware::audio::V4_0::MicrophoneInfo;
 using ::android::hardware::audio::V4_0::MmapBufferInfo;
 using ::android::hardware::audio::V4_0::MmapPosition;
 using ::android::hardware::audio::V4_0::ParameterValue;
+using ::android::hardware::audio::V4_0::PlaybackTrackMetadata;
+using ::android::hardware::audio::V4_0::RecordTrackMetadata;
 using ::android::hardware::audio::V4_0::Result;
 using ::android::hardware::audio::V4_0::TimeSpec;
 using ::android::hardware::MQDescriptorSync;
@@ -560,6 +566,28 @@
     }
 }
 
+/** Transform a standard collection to an HIDL vector. */
+template <class Values, class ElementConverter>
+static auto transformToHidlVec(const Values& values, ElementConverter converter) {
+    hidl_vec<decltype(converter(*values.begin()))> result{values.size()};
+    using namespace std;
+    transform(begin(values), end(values), begin(result), converter);
+    return result;
+}
+
+status_t StreamOutHalHidl::updateSourceMetadata(const SourceMetadata& sourceMetadata) {
+    hardware::audio::V4_0::SourceMetadata halMetadata = {
+        .tracks = transformToHidlVec(sourceMetadata.tracks,
+              [](const playback_track_metadata& metadata) -> PlaybackTrackMetadata {
+                  return {
+                    .usage=static_cast<AudioUsage>(metadata.usage),
+                    .contentType=static_cast<AudioContentType>(metadata.content_type),
+                    .gain=metadata.gain,
+                  };
+              })};
+    return processReturn("updateSourceMetadata", mStream->updateSourceMetadata(halMetadata));
+}
+
 void StreamOutHalHidl::onWriteReady() {
     sp<StreamOutHalInterfaceCallback> callback = mCallback.promote();
     if (callback == 0) return;
@@ -754,5 +782,36 @@
     }
 }
 
+
+status_t StreamInHalHidl::getActiveMicrophones(
+        std::vector<media::MicrophoneInfo> *microphonesInfo) {
+    if (!mStream) return NO_INIT;
+    Result retval;
+    Return<void> ret = mStream->getActiveMicrophones(
+            [&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
+        retval = r;
+        for (size_t k = 0; k < micArrayHal.size(); k++) {
+            audio_microphone_characteristic_t dst;
+            // convert
+            microphoneInfoToHal(micArrayHal[k], &dst);
+            media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
+            microphonesInfo->push_back(microphone);
+        }
+    });
+    return processReturn("getActiveMicrophones", ret, retval);
+}
+
+status_t StreamInHalHidl::updateSinkMetadata(const SinkMetadata& sinkMetadata) {
+    hardware::audio::V4_0::SinkMetadata halMetadata = {
+        .tracks = transformToHidlVec(sinkMetadata.tracks,
+              [](const record_track_metadata& metadata) -> RecordTrackMetadata {
+                  return {
+                    .source=static_cast<AudioSource>(metadata.source),
+                    .gain=metadata.gain,
+                  };
+              })};
+    return processReturn("updateSinkMetadata", mStream->updateSinkMetadata(halMetadata));
+}
+
 } // namespace V4_0
 } // namespace android
diff --git a/media/libaudiohal/4.0/StreamHalHidl.h b/media/libaudiohal/4.0/StreamHalHidl.h
index 8d4dc8c..2dda0f8 100644
--- a/media/libaudiohal/4.0/StreamHalHidl.h
+++ b/media/libaudiohal/4.0/StreamHalHidl.h
@@ -162,6 +162,9 @@
     // Return a recent count of the number of audio frames presented to an external observer.
     virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp);
 
+    // Called when the metadata of the stream's source has been changed.
+    status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;
+
     // Methods used by StreamOutCallback (HIDL).
     void onWriteReady();
     void onDrainReady();
@@ -211,6 +214,12 @@
     // the clock time associated with that frame count.
     virtual status_t getCapturePosition(int64_t *frames, int64_t *time);
 
+    // Get active microphones
+    virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
+    // Called when the metadata of the stream's sink has been changed.
+    status_t updateSinkMetadata(const SinkMetadata& sinkMetadata) override;
+
   private:
     friend class DeviceHalHidl;
     typedef MessageQueue<ReadParameters, hardware::kSynchronizedReadWrite> CommandMQ;
diff --git a/media/libaudiohal/4.0/StreamHalLocal.cpp b/media/libaudiohal/4.0/StreamHalLocal.cpp
index 592a931..e9d96bf 100644
--- a/media/libaudiohal/4.0/StreamHalLocal.cpp
+++ b/media/libaudiohal/4.0/StreamHalLocal.cpp
@@ -233,6 +233,19 @@
     return mStream->get_presentation_position(mStream, frames, timestamp);
 }
 
+status_t StreamOutHalLocal::updateSourceMetadata(const SourceMetadata& sourceMetadata) {
+    if (mStream->update_source_metadata == nullptr) {
+        return INVALID_OPERATION;
+    }
+    const source_metadata_t metadata {
+        .track_count = sourceMetadata.tracks.size(),
+        // const cast is fine as it is in a const structure
+        .tracks = const_cast<playback_track_metadata*>(sourceMetadata.tracks.data()),
+    };
+    mStream->update_source_metadata(mStream, &metadata);
+    return OK;
+}
+
 status_t StreamOutHalLocal::start() {
     if (mStream->start == NULL) return INVALID_OPERATION;
     return mStream->start(mStream);
@@ -294,6 +307,19 @@
     return mStream->get_capture_position(mStream, frames, time);
 }
 
+status_t StreamInHalLocal::updateSinkMetadata(const SinkMetadata& sinkMetadata) {
+    if (mStream->update_sink_metadata == nullptr) {
+        return INVALID_OPERATION;
+    }
+    const sink_metadata_t metadata {
+        .track_count = sinkMetadata.tracks.size(),
+        // const cast is fine as it is in a const structure
+        .tracks = const_cast<record_track_metadata*>(sinkMetadata.tracks.data()),
+    };
+    mStream->update_sink_metadata(mStream, &metadata);
+    return OK;
+}
+
 status_t StreamInHalLocal::start() {
     if (mStream->start == NULL) return INVALID_OPERATION;
     return mStream->start(mStream);
@@ -315,5 +341,17 @@
     return mStream->get_mmap_position(mStream, position);
 }
 
+status_t StreamInHalLocal::getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones) {
+    if (mStream->get_active_microphones == NULL) return INVALID_OPERATION;
+    size_t actual_mics = AUDIO_MICROPHONE_MAX_COUNT;
+    audio_microphone_characteristic_t mic_array[AUDIO_MICROPHONE_MAX_COUNT];
+    status_t status = mStream->get_active_microphones(mStream, &mic_array[0], &actual_mics);
+    for (size_t i = 0; i < actual_mics; i++) {
+        media::MicrophoneInfo microphoneInfo = media::MicrophoneInfo(mic_array[i]);
+        microphones->push_back(microphoneInfo);
+    }
+    return status;
+}
+
 } // namespace V4_0
 } // namespace android
diff --git a/media/libaudiohal/4.0/StreamHalLocal.h b/media/libaudiohal/4.0/StreamHalLocal.h
index 076bc4c..7237509 100644
--- a/media/libaudiohal/4.0/StreamHalLocal.h
+++ b/media/libaudiohal/4.0/StreamHalLocal.h
@@ -150,6 +150,9 @@
     // Get current read/write position in the mmap buffer
     virtual status_t getMmapPosition(struct audio_mmap_position *position);
 
+    // Called when the metadata of the stream's source has been changed.
+    status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;
+
   private:
     audio_stream_out_t *mStream;
     wp<StreamOutHalInterfaceCallback> mCallback;
@@ -195,6 +198,12 @@
     // Get current read/write position in the mmap buffer
     virtual status_t getMmapPosition(struct audio_mmap_position *position);
 
+    // Get active microphones
+    virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+
+    // Called when the metadata of the stream's sink has been changed.
+    status_t updateSinkMetadata(const SinkMetadata& sinkMetadata) override;
+
   private:
     audio_stream_in_t *mStream;
 
diff --git a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
index caf01be..7de8eb3 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -17,6 +17,7 @@
 #ifndef ANDROID_HARDWARE_DEVICE_HAL_INTERFACE_H
 #define ANDROID_HARDWARE_DEVICE_HAL_INTERFACE_H
 
+#include <media/MicrophoneInfo.h>
 #include <system/audio.h>
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
@@ -105,6 +106,9 @@
     // Set audio port configuration.
     virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0;
 
+    // List microphones
+    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones) = 0;
+
     virtual status_t dump(int fd) = 0;
 
   protected:
diff --git a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
index 7419c34..c969e28 100644
--- a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
@@ -17,7 +17,10 @@
 #ifndef ANDROID_HARDWARE_STREAM_HAL_INTERFACE_H
 #define ANDROID_HARDWARE_STREAM_HAL_INTERFACE_H
 
+#include <vector>
+
 #include <media/audiohal/EffectHalInterface.h>
+#include <media/MicrophoneInfo.h>
 #include <system/audio.h>
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
@@ -142,6 +145,15 @@
     // Return a recent count of the number of audio frames presented to an external observer.
     virtual status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp) = 0;
 
+    struct SourceMetadata {
+        std::vector<playback_track_metadata_t> tracks;
+    };
+    /**
+     * Called when the metadata of the stream's source has been changed.
+     * @param sourceMetadata Description of the audio that is played by the clients.
+     */
+    virtual status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) = 0;
+
   protected:
     virtual ~StreamOutHalInterface() {}
 };
@@ -161,6 +173,18 @@
     // the clock time associated with that frame count.
     virtual status_t getCapturePosition(int64_t *frames, int64_t *time) = 0;
 
+    // Get active microphones
+    virtual status_t getActiveMicrophones(std::vector<media::MicrophoneInfo> *microphones) = 0;
+
+    struct SinkMetadata {
+        std::vector<record_track_metadata_t> tracks;
+    };
+    /**
+     * Called when the metadata of the stream's sink has been changed.
+     * @param sinkMetadata Description of the audio that is suggested by the clients.
+     */
+    virtual status_t updateSinkMetadata(const SinkMetadata& sinkMetadata) = 0;
+
   protected:
     virtual ~StreamInHalInterface() {}
 };
diff --git a/media/libeffects/config/src/EffectsConfig.cpp b/media/libeffects/config/src/EffectsConfig.cpp
index 4ed3ba8..d79501f 100644
--- a/media/libeffects/config/src/EffectsConfig.cpp
+++ b/media/libeffects/config/src/EffectsConfig.cpp
@@ -203,7 +203,7 @@
         auto parseProxy = [&xmlEffect, &parseImpl](const char* tag, EffectImpl& proxyLib) {
             auto* xmlProxyLib = xmlEffect.FirstChildElement(tag);
             if (xmlProxyLib == nullptr) {
-                ALOGE("effectProxy must contain a <%s>: %s", tag, dump(*xmlProxyLib));
+                ALOGE("effectProxy must contain a <%s>: %s", tag, dump(xmlEffect));
                 return false;
             }
             return parseImpl(*xmlProxyLib, proxyLib);
diff --git a/media/libeffects/data/audio_effects.conf b/media/libeffects/data/audio_effects.conf
index 14a171b..dd729c5 100644
--- a/media/libeffects/data/audio_effects.conf
+++ b/media/libeffects/data/audio_effects.conf
@@ -38,6 +38,9 @@
   loudness_enhancer {
     path /vendor/lib/soundfx/libldnhncr.so
   }
+  dynamics_processing {
+    path /vendor/lib/soundfx/libdynproc.so
+  }
 }
 
 # Default pre-processing library. Add to audio_effect.conf "libraries" section if
@@ -129,6 +132,10 @@
     library loudness_enhancer
     uuid fa415329-2034-4bea-b5dc-5b381c8d1e2c
   }
+  dynamics_processing {
+    library dynamics_processing
+    uuid e0e6539b-1781-7261-676f-6d7573696340
+  }
 }
 
 # Default pre-processing effects. Add to audio_effect.conf "effects" section if
diff --git a/media/libeffects/dynamicsproc/Android.mk b/media/libeffects/dynamicsproc/Android.mk
new file mode 100644
index 0000000..7be0c49
--- /dev/null
+++ b/media/libeffects/dynamicsproc/Android.mk
@@ -0,0 +1,43 @@
+# Copyright (C) 2018 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+# DynamicsProcessing library
+include $(CLEAR_VARS)
+
+LOCAL_VENDOR_MODULE := true
+
+EIGEN_PATH := external/eigen
+LOCAL_C_INCLUDES += $(EIGEN_PATH)
+
+LOCAL_SRC_FILES:= \
+    EffectDynamicsProcessing.cpp \
+    dsp/DPBase.cpp \
+    dsp/DPFrequency.cpp
+
+LOCAL_CFLAGS+= -O2 -fvisibility=hidden
+LOCAL_CFLAGS += -Wall -Werror
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    liblog \
+
+LOCAL_MODULE_RELATIVE_PATH := soundfx
+LOCAL_MODULE:= libdynproc
+
+LOCAL_HEADER_LIBRARIES := \
+    libaudioeffects
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libeffects/dynamicsproc/EffectDynamicsProcessing.cpp b/media/libeffects/dynamicsproc/EffectDynamicsProcessing.cpp
new file mode 100644
index 0000000..55383eb
--- /dev/null
+++ b/media/libeffects/dynamicsproc/EffectDynamicsProcessing.cpp
@@ -0,0 +1,1259 @@
+/*
+ * Copyright (C) 2018 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_TAG "EffectDP"
+//#define LOG_NDEBUG 0
+
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <new>
+
+#include <log/log.h>
+
+#include <audio_effects/effect_dynamicsprocessing.h>
+#include <dsp/DPBase.h>
+#include <dsp/DPFrequency.h>
+
+//#define VERY_VERY_VERBOSE_LOGGING
+#ifdef VERY_VERY_VERBOSE_LOGGING
+#define ALOGVV ALOGV
+#else
+#define ALOGVV(a...) do { } while (false)
+#endif
+
+// union to hold command values
+using value_t = union {
+    int32_t i;
+    float f;
+};
+
+// effect_handle_t interface implementation for DP effect
+extern const struct effect_interface_s gDPInterface;
+
+// AOSP Dynamics Processing UUID: e0e6539b-1781-7261-676f-6d7573696340
+const effect_descriptor_t gDPDescriptor = {
+        {0x7261676f, 0x6d75, 0x7369, 0x6364, {0x28, 0xe2, 0xfd, 0x3a, 0xc3, 0x9e}}, // type
+        {0xe0e6539b, 0x1781, 0x7261, 0x676f, {0x6d, 0x75, 0x73, 0x69, 0x63, 0x40}}, // uuid
+        EFFECT_CONTROL_API_VERSION,
+        (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST),
+        0, // TODO
+        1,
+        "Dynamics Processing",
+        "The Android Open Source Project",
+};
+
+enum dp_state_e {
+    DYNAMICS_PROCESSING_STATE_UNINITIALIZED,
+    DYNAMICS_PROCESSING_STATE_INITIALIZED,
+    DYNAMICS_PROCESSING_STATE_ACTIVE,
+};
+
+struct DynamicsProcessingContext {
+    const struct effect_interface_s *mItfe;
+    effect_config_t mConfig;
+    uint8_t mState;
+
+    dp_fx::DPBase * mPDynamics; //the effect (or current effect)
+    int32_t mCurrentVariant;
+    float mPreferredFrameDuration;
+};
+
+// The value offset of an effect parameter is computed by rounding up
+// the parameter size to the next 32 bit alignment.
+static inline uint32_t computeParamVOffset(const effect_param_t *p) {
+    return ((p->psize + sizeof(int32_t) - 1) / sizeof(int32_t)) *
+            sizeof(int32_t);
+}
+
+//--- local function prototypes
+int DP_setParameter(DynamicsProcessingContext *pContext,
+        uint32_t paramSize,
+        void *pParam,
+        uint32_t valueSize,
+        void *pValue);
+int DP_getParameter(DynamicsProcessingContext *pContext,
+        uint32_t paramSize,
+        void *pParam,
+        uint32_t *pValueSize,
+        void *pValue);
+int DP_getParameterCmdSize(uint32_t paramSize,
+        void *pParam);
+void DP_expectedParamValueSizes(uint32_t paramSize,
+        void *pParam,
+        bool isSet,
+        uint32_t *pCmdSize,
+        uint32_t *pValueSize);
+//
+//--- Local functions (not directly used by effect interface)
+//
+
+void DP_reset(DynamicsProcessingContext *pContext)
+{
+    ALOGV("> DP_reset(%p)", pContext);
+    if (pContext->mPDynamics != NULL) {
+        pContext->mPDynamics->reset();
+    } else {
+        ALOGE("DP_reset(%p): null DynamicsProcessing", pContext);
+    }
+}
+
+//----------------------------------------------------------------------------
+// DP_setConfig()
+//----------------------------------------------------------------------------
+// Purpose: Set input and output audio configuration.
+//
+// Inputs:
+//  pContext:   effect engine context
+//  pConfig:    pointer to effect_config_t structure holding input and output
+//      configuration parameters
+//
+// Outputs:
+//
+//----------------------------------------------------------------------------
+
+int DP_setConfig(DynamicsProcessingContext *pContext, effect_config_t *pConfig)
+{
+    ALOGV("DP_setConfig(%p)", pContext);
+
+    if (pConfig->inputCfg.samplingRate != pConfig->outputCfg.samplingRate) return -EINVAL;
+    if (pConfig->inputCfg.channels != pConfig->outputCfg.channels) return -EINVAL;
+    if (pConfig->inputCfg.format != pConfig->outputCfg.format) return -EINVAL;
+    if (pConfig->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_WRITE &&
+            pConfig->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_ACCUMULATE) return -EINVAL;
+    if (pConfig->inputCfg.format != AUDIO_FORMAT_PCM_FLOAT) return -EINVAL;
+
+    pContext->mConfig = *pConfig;
+
+    DP_reset(pContext);
+
+    return 0;
+}
+
+//----------------------------------------------------------------------------
+// DP_getConfig()
+//----------------------------------------------------------------------------
+// Purpose: Get input and output audio configuration.
+//
+// Inputs:
+//  pContext:   effect engine context
+//  pConfig:    pointer to effect_config_t structure holding input and output
+//      configuration parameters
+//
+// Outputs:
+//
+//----------------------------------------------------------------------------
+
+void DP_getConfig(DynamicsProcessingContext *pContext, effect_config_t *pConfig)
+{
+    *pConfig = pContext->mConfig;
+}
+
+//----------------------------------------------------------------------------
+// DP_init()
+//----------------------------------------------------------------------------
+// Purpose: Initialize engine with default configuration.
+//
+// Inputs:
+//  pContext:   effect engine context
+//
+// Outputs:
+//
+//----------------------------------------------------------------------------
+
+int DP_init(DynamicsProcessingContext *pContext)
+{
+    ALOGV("DP_init(%p)", pContext);
+
+    pContext->mItfe = &gDPInterface;
+    pContext->mPDynamics = NULL;
+    pContext->mState = DYNAMICS_PROCESSING_STATE_UNINITIALIZED;
+
+    pContext->mConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
+    pContext->mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+    pContext->mConfig.inputCfg.format = AUDIO_FORMAT_PCM_FLOAT;
+    pContext->mConfig.inputCfg.samplingRate = 48000;
+    pContext->mConfig.inputCfg.bufferProvider.getBuffer = NULL;
+    pContext->mConfig.inputCfg.bufferProvider.releaseBuffer = NULL;
+    pContext->mConfig.inputCfg.bufferProvider.cookie = NULL;
+    pContext->mConfig.inputCfg.mask = EFFECT_CONFIG_ALL;
+    pContext->mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
+    pContext->mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+    pContext->mConfig.outputCfg.format = AUDIO_FORMAT_PCM_FLOAT;
+    pContext->mConfig.outputCfg.samplingRate = 48000;
+    pContext->mConfig.outputCfg.bufferProvider.getBuffer = NULL;
+    pContext->mConfig.outputCfg.bufferProvider.releaseBuffer = NULL;
+    pContext->mConfig.outputCfg.bufferProvider.cookie = NULL;
+    pContext->mConfig.outputCfg.mask = EFFECT_CONFIG_ALL;
+
+    pContext->mCurrentVariant = -1; //none
+    pContext->mPreferredFrameDuration = 0; //none
+
+    DP_setConfig(pContext, &pContext->mConfig);
+    pContext->mState = DYNAMICS_PROCESSING_STATE_INITIALIZED;
+    return 0;
+}
+
+void DP_changeVariant(DynamicsProcessingContext *pContext, int newVariant) {
+    ALOGV("DP_changeVariant from %d to %d", pContext->mCurrentVariant, newVariant);
+    switch(newVariant) {
+    case VARIANT_FAVOR_FREQUENCY_RESOLUTION: {
+        pContext->mCurrentVariant = VARIANT_FAVOR_FREQUENCY_RESOLUTION;
+        delete pContext->mPDynamics;
+        pContext->mPDynamics = new dp_fx::DPFrequency();
+        break;
+    }
+    default: {
+        ALOGW("DynamicsProcessing variant %d not available for creation", newVariant);
+        break;
+    }
+    } //switch
+}
+
+static inline bool isPowerOf2(unsigned long n) {
+    return (n & (n - 1)) == 0;
+}
+
+void DP_configureVariant(DynamicsProcessingContext *pContext, int newVariant) {
+    ALOGV("DP_configureVariant %d", newVariant);
+    switch(newVariant) {
+    case VARIANT_FAVOR_FREQUENCY_RESOLUTION: {
+        int32_t minBlockSize = (int32_t)dp_fx::DPFrequency::getMinBockSize();
+        int32_t desiredBlock = pContext->mPreferredFrameDuration *
+                pContext->mConfig.inputCfg.samplingRate / 1000.0f;
+        int32_t currentBlock = desiredBlock;
+        ALOGV(" sampling rate: %d, desiredBlock size %0.2f (%d) samples",
+                pContext->mConfig.inputCfg.samplingRate, pContext->mPreferredFrameDuration,
+                desiredBlock);
+        if (desiredBlock < minBlockSize) {
+            currentBlock = minBlockSize;
+        } else if (!isPowerOf2(desiredBlock)) {
+            //find next highest power of 2.
+            currentBlock = 1 << (32 - __builtin_clz(desiredBlock));
+        }
+        ((dp_fx::DPFrequency*)pContext->mPDynamics)->configure(currentBlock,
+                currentBlock/2,
+                pContext->mConfig.inputCfg.samplingRate);
+        break;
+    }
+    default: {
+        ALOGE("DynamicsProcessing variant %d not available to configure", newVariant);
+        break;
+    }
+    }
+}
+
+//
+//--- Effect Library Interface Implementation
+//
+
+int DPLib_Release(effect_handle_t handle) {
+    DynamicsProcessingContext * pContext = (DynamicsProcessingContext *)handle;
+
+    ALOGV("DPLib_Release %p", handle);
+    if (pContext == NULL) {
+        return -EINVAL;
+    }
+    delete pContext->mPDynamics;
+    delete pContext;
+
+    return 0;
+}
+
+int DPLib_Create(const effect_uuid_t *uuid,
+                         int32_t sessionId __unused,
+                         int32_t ioId __unused,
+                         effect_handle_t *pHandle) {
+    ALOGV("DPLib_Create()");
+
+    if (pHandle == NULL || uuid == NULL) {
+        return -EINVAL;
+    }
+
+    if (memcmp(uuid, &gDPDescriptor.uuid, sizeof(*uuid)) != 0) {
+        return -EINVAL;
+    }
+
+    DynamicsProcessingContext *pContext = new DynamicsProcessingContext;
+    *pHandle = (effect_handle_t)pContext;
+    int ret = DP_init(pContext);
+    if (ret < 0) {
+        ALOGW("DPLib_Create() init failed");
+        DPLib_Release(*pHandle);
+        return ret;
+    }
+
+    ALOGV("DPLib_Create context is %p", pContext);
+    return 0;
+}
+
+int DPLib_GetDescriptor(const effect_uuid_t *uuid,
+                                effect_descriptor_t *pDescriptor) {
+
+    if (pDescriptor == NULL || uuid == NULL){
+        ALOGE("DPLib_GetDescriptor() called with NULL pointer");
+        return -EINVAL;
+    }
+
+    if (memcmp(uuid, &gDPDescriptor.uuid, sizeof(*uuid)) == 0) {
+        *pDescriptor = gDPDescriptor;
+        return 0;
+    }
+
+    return -EINVAL;
+} /* end DPLib_GetDescriptor */
+
+//
+//--- Effect Control Interface Implementation
+//
+int DP_process(effect_handle_t self, audio_buffer_t *inBuffer,
+        audio_buffer_t *outBuffer) {
+    DynamicsProcessingContext * pContext = (DynamicsProcessingContext *)self;
+
+    if (pContext == NULL) {
+        ALOGE("DP_process() called with NULL context");
+        return -EINVAL;
+    }
+
+    if (inBuffer == NULL || inBuffer->raw == NULL ||
+        outBuffer == NULL || outBuffer->raw == NULL ||
+        inBuffer->frameCount != outBuffer->frameCount ||
+        inBuffer->frameCount == 0) {
+        ALOGE("inBuffer or outBuffer are NULL or have problems with frame count");
+        return -EINVAL;
+    }
+    if (pContext->mState != DYNAMICS_PROCESSING_STATE_ACTIVE) {
+        ALOGE("mState is not DYNAMICS_PROCESSING_STATE_ACTIVE. Current mState %d",
+                pContext->mState);
+        return -ENODATA;
+    }
+    //if dynamics exist...
+    if (pContext->mPDynamics != NULL) {
+        int32_t channelCount = (int32_t)audio_channel_count_from_out_mask(
+                        pContext->mConfig.inputCfg.channels);
+        pContext->mPDynamics->processSamples(inBuffer->f32, inBuffer->f32,
+                inBuffer->frameCount * channelCount);
+
+        if (inBuffer->raw != outBuffer->raw) {
+            if (pContext->mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
+                for (size_t i = 0; i < outBuffer->frameCount * channelCount; i++) {
+                    outBuffer->f32[i] += inBuffer->f32[i];
+                }
+            } else {
+                memcpy(outBuffer->raw, inBuffer->raw,
+                        outBuffer->frameCount * channelCount * sizeof(float));
+            }
+        }
+    } else {
+        //do nothing. no effect created yet. warning.
+        ALOGW("Warning: no DynamicsProcessing engine available");
+        return -EINVAL;
+    }
+    return 0;
+}
+
+int DP_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
+        void *pCmdData, uint32_t *replySize, void *pReplyData) {
+
+    DynamicsProcessingContext * pContext = (DynamicsProcessingContext *)self;
+
+    if (pContext == NULL || pContext->mState == DYNAMICS_PROCESSING_STATE_UNINITIALIZED) {
+        ALOGE("DP_command() called with NULL context or uninitialized state.");
+        return -EINVAL;
+    }
+
+    ALOGV("DP_command command %d cmdSize %d",cmdCode, cmdSize);
+    switch (cmdCode) {
+    case EFFECT_CMD_INIT:
+        if (pReplyData == NULL || *replySize != sizeof(int)) {
+            ALOGE("EFFECT_CMD_INIT wrong replyData or repySize");
+            return -EINVAL;
+        }
+        *(int *) pReplyData = DP_init(pContext);
+        break;
+    case EFFECT_CMD_SET_CONFIG:
+        if (pCmdData == NULL || cmdSize != sizeof(effect_config_t)
+                || pReplyData == NULL || replySize == NULL || *replySize != sizeof(int)) {
+            ALOGE("EFFECT_CMD_SET_CONFIG error with pCmdData, cmdSize, pReplyData or replySize");
+            return -EINVAL;
+        }
+        *(int *) pReplyData = DP_setConfig(pContext,
+                (effect_config_t *) pCmdData);
+        break;
+    case EFFECT_CMD_GET_CONFIG:
+        if (pReplyData == NULL ||
+            *replySize != sizeof(effect_config_t)) {
+            ALOGE("EFFECT_CMD_GET_CONFIG wrong replyData or repySize");
+            return -EINVAL;
+        }
+        DP_getConfig(pContext, (effect_config_t *)pReplyData);
+        break;
+    case EFFECT_CMD_RESET:
+        DP_reset(pContext);
+        break;
+    case EFFECT_CMD_ENABLE:
+        if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int)) {
+            ALOGE("EFFECT_CMD_ENABLE wrong replyData or repySize");
+            return -EINVAL;
+        }
+        if (pContext->mState != DYNAMICS_PROCESSING_STATE_INITIALIZED) {
+            ALOGE("EFFECT_CMD_ENABLE state not initialized");
+            *(int *)pReplyData = -ENOSYS;
+        } else {
+            pContext->mState = DYNAMICS_PROCESSING_STATE_ACTIVE;
+            ALOGV("EFFECT_CMD_ENABLE() OK");
+            *(int *)pReplyData = 0;
+        }
+        break;
+    case EFFECT_CMD_DISABLE:
+        if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int)) {
+            ALOGE("EFFECT_CMD_DISABLE wrong replyData or repySize");
+            return -EINVAL;
+        }
+        if (pContext->mState != DYNAMICS_PROCESSING_STATE_ACTIVE) {
+            ALOGE("EFFECT_CMD_DISABLE state not active");
+            *(int *)pReplyData = -ENOSYS;
+        } else {
+            pContext->mState = DYNAMICS_PROCESSING_STATE_INITIALIZED;
+            ALOGV("EFFECT_CMD_DISABLE() OK");
+            *(int *)pReplyData = 0;
+        }
+        break;
+    case EFFECT_CMD_GET_PARAM: {
+        if (pCmdData == NULL || pReplyData == NULL || replySize == NULL) {
+            ALOGE("null pCmdData or pReplyData or replySize");
+            return -EINVAL;
+        }
+        effect_param_t *pEffectParam = (effect_param_t *) pCmdData;
+        uint32_t expectedCmdSize = DP_getParameterCmdSize(pEffectParam->psize,
+                pEffectParam->data);
+        if (cmdSize != expectedCmdSize || *replySize < expectedCmdSize) {
+            ALOGE("error cmdSize: %d, expetedCmdSize: %d, replySize: %d",
+                    cmdSize, expectedCmdSize, *replySize);
+            return -EINVAL;
+        }
+
+        ALOGVV("DP_command expectedCmdSize: %d", expectedCmdSize);
+        memcpy(pReplyData, pCmdData, expectedCmdSize);
+        effect_param_t *p = (effect_param_t *)pReplyData;
+
+        uint32_t voffset = computeParamVOffset(p);
+
+        p->status = DP_getParameter(pContext,
+                p->psize,
+                p->data,
+                &p->vsize,
+                p->data + voffset);
+        *replySize = sizeof(effect_param_t) + voffset + p->vsize;
+
+        ALOGVV("DP_command replysize %u, status %d" , *replySize, p->status);
+        break;
+    }
+    case EFFECT_CMD_SET_PARAM: {
+        if (pCmdData == NULL ||
+                cmdSize < (sizeof(effect_param_t) + sizeof(int32_t) + sizeof(int32_t)) ||
+                pReplyData == NULL || replySize == NULL || *replySize != sizeof(int32_t)) {
+            ALOGE("\tLVM_ERROR : DynamicsProcessing cmdCode Case: "
+                    "EFFECT_CMD_SET_PARAM: ERROR");
+            return -EINVAL;
+        }
+
+        effect_param_t * const p = (effect_param_t *) pCmdData;
+        const uint32_t voffset = computeParamVOffset(p);
+
+        *(int *)pReplyData = DP_setParameter(pContext,
+                p->psize,
+                (void *)p->data,
+                p->vsize,
+                p->data + voffset);
+        break;
+    }
+    case EFFECT_CMD_SET_DEVICE:
+    case EFFECT_CMD_SET_VOLUME:
+    case EFFECT_CMD_SET_AUDIO_MODE:
+        break;
+
+    default:
+        ALOGW("DP_command invalid command %d",cmdCode);
+        return -EINVAL;
+    }
+
+    return 0;
+}
+
+//register expected cmd size
+int DP_getParameterCmdSize(uint32_t paramSize,
+        void *pParam) {
+    if (paramSize < sizeof(int32_t)) {
+        return 0;
+    }
+    int32_t param = *(int32_t*)pParam;
+    switch(param) {
+    case DP_PARAM_GET_CHANNEL_COUNT: //paramcmd
+    case DP_PARAM_ENGINE_ARCHITECTURE:
+        //effect + param
+        return (int)(sizeof(effect_param_t) + sizeof(uint32_t));
+    case DP_PARAM_INPUT_GAIN: //paramcmd + param
+    case DP_PARAM_LIMITER:
+    case DP_PARAM_PRE_EQ:
+    case DP_PARAM_POST_EQ:
+    case DP_PARAM_MBC:
+        //effect + param
+        return (int)(sizeof(effect_param_t) + 2 * sizeof(uint32_t));
+    case DP_PARAM_PRE_EQ_BAND:
+    case DP_PARAM_POST_EQ_BAND:
+    case DP_PARAM_MBC_BAND:
+        return (int)(sizeof(effect_param_t) + 3 * sizeof(uint32_t));
+    }
+    return 0;
+}
+
+//helper function
+bool DP_checkSizesInt(uint32_t paramSize, uint32_t valueSize, uint32_t expectedParams,
+        uint32_t expectedValues) {
+    if (paramSize < expectedParams * sizeof(int32_t)) {
+        ALOGE("Invalid paramSize: %u expected %u", paramSize,
+                (uint32_t) (expectedParams * sizeof(int32_t)));
+        return false;
+    }
+    if (valueSize < expectedValues * sizeof(int32_t)) {
+        ALOGE("Invalid valueSize %u expected %u", valueSize,
+                (uint32_t)(expectedValues * sizeof(int32_t)));
+        return false;
+    }
+    return true;
+}
+
+static dp_fx::DPChannel* DP_getChannel(DynamicsProcessingContext *pContext,
+        int32_t channel) {
+    if (pContext->mPDynamics == NULL) {
+        return NULL;
+    }
+    dp_fx::DPChannel *pChannel = pContext->mPDynamics->getChannel(channel);
+    ALOGE_IF(pChannel == NULL, "DPChannel NULL. invalid channel %d", channel);
+    return pChannel;
+}
+
+static dp_fx::DPEq* DP_getEq(DynamicsProcessingContext *pContext, int32_t channel,
+        int32_t eqType) {
+    dp_fx::DPChannel * pChannel = DP_getChannel(pContext, channel);
+    if (pChannel == NULL) {
+        return NULL;
+    }
+    dp_fx::DPEq *pEq = (eqType == DP_PARAM_PRE_EQ ? pChannel->getPreEq() :
+            (eqType == DP_PARAM_POST_EQ ? pChannel->getPostEq() : NULL));
+    ALOGE_IF(pEq == NULL,"DPEq NULL invalid eq");
+    return pEq;
+}
+
+static dp_fx::DPEqBand* DP_getEqBand(DynamicsProcessingContext *pContext, int32_t channel,
+        int32_t eqType, int32_t band) {
+    dp_fx::DPEq *pEq = DP_getEq(pContext, channel, eqType);
+    if (pEq == NULL) {
+        return NULL;
+    }
+    dp_fx::DPEqBand *pEqBand = pEq->getBand(band);
+    ALOGE_IF(pEqBand == NULL, "DPEqBand NULL. invalid band %d", band);
+    return pEqBand;
+}
+
+static dp_fx::DPMbc* DP_getMbc(DynamicsProcessingContext *pContext, int32_t channel) {
+    dp_fx::DPChannel * pChannel = DP_getChannel(pContext, channel);
+    if (pChannel == NULL) {
+        return NULL;
+    }
+    dp_fx::DPMbc *pMbc = pChannel->getMbc();
+    ALOGE_IF(pMbc == NULL, "DPMbc NULL invalid MBC");
+    return pMbc;
+}
+
+static dp_fx::DPMbcBand* DP_getMbcBand(DynamicsProcessingContext *pContext, int32_t channel,
+        int32_t band) {
+    dp_fx::DPMbc *pMbc = DP_getMbc(pContext, channel);
+    if (pMbc == NULL) {
+        return NULL;
+    }
+    dp_fx::DPMbcBand *pMbcBand = pMbc->getBand(band);
+    ALOGE_IF(pMbcBand == NULL, "pMbcBand NULL. invalid band %d", band);
+    return pMbcBand;
+}
+
+int DP_getParameter(DynamicsProcessingContext *pContext,
+                           uint32_t paramSize,
+                           void *pParam,
+                           uint32_t *pValueSize,
+                           void *pValue) {
+    int status = 0;
+    int32_t *params = (int32_t *)pParam;
+    static_assert(sizeof(float) == sizeof(int32_t) && sizeof(float) == sizeof(value_t) &&
+            alignof(float) == alignof(int32_t) && alignof(float) == alignof(value_t),
+            "Size/alignment mismatch for float/int32_t/value_t");
+    value_t *values = reinterpret_cast<value_t*>(pValue);
+
+    ALOGVV("%s start", __func__);
+#ifdef VERY_VERY_VERBOSE_LOGGING
+    for (size_t i = 0; i < paramSize/sizeof(int32_t); i++) {
+        ALOGVV("Param[%zu] %d", i, params[i]);
+    }
+#endif
+    if (paramSize < sizeof(int32_t)) {
+        ALOGE("%s invalid paramSize: %u", __func__, paramSize);
+        return -EINVAL;
+    }
+    const int32_t command = params[0];
+    switch (command) {
+    case DP_PARAM_GET_CHANNEL_COUNT: {
+        if (!DP_checkSizesInt(paramSize,*pValueSize, 1 /*params*/, 1 /*values*/)) {
+            ALOGE("%s DP_PARAM_GET_CHANNEL_COUNT (cmd %d) invalid sizes.", __func__, command);
+            status = -EINVAL;
+            break;
+        }
+        *pValueSize = sizeof(uint32_t);
+        *(uint32_t *)pValue = (uint32_t)audio_channel_count_from_out_mask(
+                pContext->mConfig.inputCfg.channels);
+        ALOGVV("%s DP_PARAM_GET_CHANNEL_COUNT channels %d", __func__, *(int32_t *)pValue);
+        break;
+    }
+    case DP_PARAM_ENGINE_ARCHITECTURE: {
+        ALOGVV("engine architecture paramsize: %d valuesize %d",paramSize, *pValueSize);
+        if (!DP_checkSizesInt(paramSize, *pValueSize, 1 /*params*/, 9 /*values*/)) {
+            ALOGE("%s DP_PARAM_ENGINE_ARCHITECTURE (cmd %d) invalid sizes.", __func__, command);
+            status = -EINVAL;
+            break;
+        }
+//        Number[] params = { PARAM_ENGINE_ARCHITECTURE };
+//        Number[] values = { 0 /*0 variant */,
+//                0.0f /* 1 preferredFrameDuration */,
+//                0 /*2 preEqInUse */,
+//                0 /*3 preEqBandCount */,
+//                0 /*4 mbcInUse */,
+//                0 /*5 mbcBandCount*/,
+//                0 /*6 postEqInUse */,
+//                0 /*7 postEqBandCount */,
+//                0 /*8 limiterInUse */};
+        if (pContext->mPDynamics == NULL) {
+            ALOGE("%s DP_PARAM_ENGINE_ARCHITECTURE error mPDynamics is NULL", __func__);
+            status = -EINVAL;
+            break;
+        }
+        values[0].i = pContext->mCurrentVariant;
+        values[1].f = pContext->mPreferredFrameDuration;
+        values[2].i = pContext->mPDynamics->isPreEQInUse();
+        values[3].i = pContext->mPDynamics->getPreEqBandCount();
+        values[4].i = pContext->mPDynamics->isMbcInUse();
+        values[5].i = pContext->mPDynamics->getMbcBandCount();
+        values[6].i = pContext->mPDynamics->isPostEqInUse();
+        values[7].i = pContext->mPDynamics->getPostEqBandCount();
+        values[8].i = pContext->mPDynamics->isLimiterInUse();
+
+        *pValueSize = sizeof(value_t) * 9;
+
+        ALOGVV(" variant %d, preferredFrameDuration: %f, preEqInuse %d, bands %d, mbcinuse %d,"
+                "mbcbands %d, posteqInUse %d, bands %d, limiterinuse %d",
+                values[0].i, values[1].f, values[2].i, values[3].i, values[4].i, values[5].i,
+                values[6].i, values[7].i, values[8].i);
+        break;
+    }
+    case DP_PARAM_INPUT_GAIN: {
+        ALOGVV("engine get PARAM_INPUT_GAIN paramsize: %d valuesize %d",paramSize, *pValueSize);
+        if (!DP_checkSizesInt(paramSize, *pValueSize, 2 /*params*/, 1 /*values*/)) {
+            ALOGE("%s get PARAM_INPUT_GAIN invalid sizes.", __func__);
+            status = -EINVAL;
+            break;
+        }
+
+        const int32_t channel = params[1];
+        dp_fx::DPChannel * pChannel = DP_getChannel(pContext, channel);
+        if (pChannel == NULL) {
+            ALOGE("%s get PARAM_INPUT_GAIN invalid channel %d", __func__, channel);
+            status = -EINVAL;
+            break;
+        }
+        values[0].f = pChannel->getInputGain();
+        *pValueSize = sizeof(value_t) * 1;
+
+        ALOGVV(" channel: %d, input gain %f\n", channel, values[0].f);
+        break;
+    }
+    case DP_PARAM_PRE_EQ:
+    case DP_PARAM_POST_EQ: {
+        ALOGVV("engine get PARAM_*_EQ paramsize: %d valuesize %d",paramSize, *pValueSize);
+        if (!DP_checkSizesInt(paramSize, *pValueSize, 2 /*params*/, 3 /*values*/)) {
+            ALOGE("%s get PARAM_*_EQ (cmd %d) invalid sizes.", __func__, command);
+            status = -EINVAL;
+            break;
+        }
+//        Number[] params = {paramSet == PARAM_PRE_EQ ? PARAM_PRE_EQ : PARAM_POST_EQ,
+//                       channelIndex};
+//               Number[] values = {0 /*0 in use */,
+//                                   0 /*1 enabled*/,
+//                                   0 /*2 band count */};
+        const int32_t channel = params[1];
+
+        dp_fx::DPEq *pEq = DP_getEq(pContext, channel, command);
+        if (pEq == NULL) {
+            ALOGE("%s get PARAM_*_EQ invalid eq", __func__);
+            status = -EINVAL;
+            break;
+        }
+        values[0].i = pEq->isInUse();
+        values[1].i = pEq->isEnabled();
+        values[2].i = pEq->getBandCount();
+        *pValueSize = sizeof(value_t) * 3;
+
+        ALOGVV(" %s channel: %d, inUse::%d, enabled:%d, bandCount:%d\n",
+                (command == DP_PARAM_PRE_EQ ? "preEq" : "postEq"), channel,
+                values[0].i, values[1].i, values[2].i);
+        break;
+    }
+    case DP_PARAM_PRE_EQ_BAND:
+    case DP_PARAM_POST_EQ_BAND: {
+        ALOGVV("engine get PARAM_*_EQ_BAND paramsize: %d valuesize %d",paramSize, *pValueSize);
+        if (!DP_checkSizesInt(paramSize, *pValueSize, 3 /*params*/, 3 /*values*/)) {
+            ALOGE("%s get PARAM_*_EQ_BAND (cmd %d) invalid sizes.", __func__, command);
+            status = -EINVAL;
+            break;
+        }
+//        Number[] params = {paramSet,
+//                channelIndex,
+//                bandIndex};
+//        Number[] values = {(eqBand.isEnabled() ? 1 : 0),
+//              eqBand.getCutoffFrequency(),
+//              eqBand.getGain()};
+        const int32_t channel = params[1];
+        const int32_t band = params[2];
+        int eqCommand = (command == DP_PARAM_PRE_EQ_BAND ? DP_PARAM_PRE_EQ :
+                (command == DP_PARAM_POST_EQ_BAND ? DP_PARAM_POST_EQ : -1));
+
+        dp_fx::DPEqBand *pEqBand = DP_getEqBand(pContext, channel, eqCommand, band);
+        if (pEqBand == NULL) {
+            ALOGE("%s get PARAM_*_EQ_BAND invalid channel %d or band %d", __func__, channel, band);
+            status = -EINVAL;
+            break;
+        }
+
+        values[0].i = pEqBand->isEnabled();
+        values[1].f = pEqBand->getCutoffFrequency();
+        values[2].f = pEqBand->getGain();
+        *pValueSize = sizeof(value_t) * 3;
+
+        ALOGVV("%s channel: %d, band::%d, enabled:%d, cutoffFrequency:%f, gain%f\n",
+                (command == DP_PARAM_PRE_EQ_BAND ? "preEqBand" : "postEqBand"), channel, band,
+                values[0].i, values[1].f, values[2].f);
+        break;
+    }
+    case DP_PARAM_MBC: {
+        ALOGVV("engine get PDP_PARAM_MBC paramsize: %d valuesize %d",paramSize, *pValueSize);
+        if (!DP_checkSizesInt(paramSize, *pValueSize, 2 /*params*/, 3 /*values*/)) {
+            ALOGE("%s get PDP_PARAM_MBC (cmd %d) invalid sizes.", __func__, command);
+            status = -EINVAL;
+            break;
+        }
+
+//           Number[] params = {PARAM_MBC,
+//                    channelIndex};
+//            Number[] values = {0 /*0 in use */,
+//                                0 /*1 enabled*/,
+//                                0 /*2 band count */};
+
+        const int32_t channel = params[1];
+
+        dp_fx::DPMbc *pMbc = DP_getMbc(pContext, channel);
+        if (pMbc == NULL) {
+            ALOGE("%s get PDP_PARAM_MBC invalid MBC", __func__);
+            status = -EINVAL;
+            break;
+        }
+
+        values[0].i = pMbc->isInUse();
+        values[1].i = pMbc->isEnabled();
+        values[2].i = pMbc->getBandCount();
+        *pValueSize = sizeof(value_t) * 3;
+
+        ALOGVV("DP_PARAM_MBC channel: %d, inUse::%d, enabled:%d, bandCount:%d\n", channel,
+                values[0].i, values[1].i, values[2].i);
+        break;
+    }
+    case DP_PARAM_MBC_BAND: {
+        ALOGVV("engine get DP_PARAM_MBC_BAND paramsize: %d valuesize %d",paramSize, *pValueSize);
+        if (!DP_checkSizesInt(paramSize, *pValueSize, 3 /*params*/, 11 /*values*/)) {
+            ALOGE("%s get DP_PARAM_MBC_BAND (cmd %d) invalid sizes.", __func__, command);
+            status = -EINVAL;
+            break;
+        }
+//        Number[] params = {PARAM_MBC_BAND,
+//                        channelIndex,
+//                        bandIndex};
+//                Number[] values = {0 /*0 enabled */,
+//                        0.0f /*1 cutoffFrequency */,
+//                        0.0f /*2 AttackTime */,
+//                        0.0f /*3 ReleaseTime */,
+//                        0.0f /*4 Ratio */,
+//                        0.0f /*5 Threshold */,
+//                        0.0f /*6 KneeWidth */,
+//                        0.0f /*7 NoiseGateThreshold */,
+//                        0.0f /*8 ExpanderRatio */,
+//                        0.0f /*9 PreGain */,
+//                        0.0f /*10 PostGain*/};
+
+        const int32_t channel = params[1];
+        const int32_t band = params[2];
+
+        dp_fx::DPMbcBand *pMbcBand = DP_getMbcBand(pContext, channel, band);
+        if (pMbcBand == NULL) {
+            ALOGE("%s get PARAM_MBC_BAND invalid channel %d or band %d", __func__, channel, band);
+            status = -EINVAL;
+            break;
+        }
+
+        values[0].i = pMbcBand->isEnabled();
+        values[1].f = pMbcBand->getCutoffFrequency();
+        values[2].f = pMbcBand->getAttackTime();
+        values[3].f = pMbcBand->getReleaseTime();
+        values[4].f = pMbcBand->getRatio();
+        values[5].f = pMbcBand->getThreshold();
+        values[6].f = pMbcBand->getKneeWidth();
+        values[7].f = pMbcBand->getNoiseGateThreshold();
+        values[8].f = pMbcBand->getExpanderRatio();
+        values[9].f = pMbcBand->getPreGain();
+        values[10].f = pMbcBand->getPostGain();
+
+        *pValueSize = sizeof(value_t) * 11;
+        ALOGVV(" mbcBand channel: %d, band::%d, enabled:%d, cutoffFrequency:%f, attackTime:%f,"
+                "releaseTime:%f, ratio:%f, threshold:%f, kneeWidth:%f, noiseGateThreshold:%f,"
+                "expanderRatio:%f, preGain:%f, postGain:%f\n", channel, band, values[0].i,
+                values[1].f, values[2].f, values[3].f, values[4].f, values[5].f, values[6].f,
+                values[7].f, values[8].f, values[9].f, values[10].f);
+        break;
+    }
+    case DP_PARAM_LIMITER: {
+        ALOGVV("engine get DP_PARAM_LIMITER paramsize: %d valuesize %d",paramSize, *pValueSize);
+        if (!DP_checkSizesInt(paramSize, *pValueSize, 2 /*params*/, 8 /*values*/)) {
+            ALOGE("%s DP_PARAM_LIMITER (cmd %d) invalid sizes.", __func__, command);
+            status = -EINVAL;
+            break;
+        }
+
+        int32_t channel = params[1];
+//      Number[] values = {0 /*0 in use (int)*/,
+//              0 /*1 enabled (int)*/,
+//              0 /*2 link group (int)*/,
+//              0.0f /*3 attack time (float)*/,
+//              0.0f /*4 release time (float)*/,
+//              0.0f /*5 ratio (float)*/,
+//              0.0f /*6 threshold (float)*/,
+//              0.0f /*7 post gain(float)*/};
+        dp_fx::DPChannel * pChannel = DP_getChannel(pContext, channel);
+        if (pChannel == NULL) {
+            ALOGE("%s DP_PARAM_LIMITER invalid channel %d", __func__, channel);
+            status = -EINVAL;
+            break;
+        }
+        dp_fx::DPLimiter *pLimiter = pChannel->getLimiter();
+        if (pLimiter == NULL) {
+            ALOGE("%s DP_PARAM_LIMITER null LIMITER", __func__);
+            status = -EINVAL;
+            break;
+        }
+        values[0].i = pLimiter->isInUse();
+        values[1].i = pLimiter->isEnabled();
+        values[2].i = pLimiter->getLinkGroup();
+        values[3].f = pLimiter->getAttackTime();
+        values[4].f = pLimiter->getReleaseTime();
+        values[5].f = pLimiter->getRatio();
+        values[6].f = pLimiter->getThreshold();
+        values[7].f = pLimiter->getPostGain();
+
+        *pValueSize = sizeof(value_t) * 8;
+
+        ALOGVV(" Limiter channel: %d, inUse::%d, enabled:%d, linkgroup:%d attackTime:%f,"
+                "releaseTime:%f, ratio:%f, threshold:%f, postGain:%f\n",
+                channel, values[0].i/*inUse*/, values[1].i/*enabled*/, values[2].i/*linkGroup*/,
+                values[3].f/*attackTime*/, values[4].f/*releaseTime*/,
+                values[5].f/*ratio*/, values[6].f/*threshold*/,
+                values[7].f/*postGain*/);
+        break;
+    }
+    default:
+        ALOGE("%s invalid param %d", __func__, params[0]);
+        status = -EINVAL;
+        break;
+    }
+
+    ALOGVV("%s end param: %d, status: %d", __func__, params[0], status);
+    return status;
+} /* end DP_getParameter */
+
+int DP_setParameter(DynamicsProcessingContext *pContext,
+                           uint32_t paramSize,
+                           void *pParam,
+                           uint32_t valueSize,
+                           void *pValue) {
+    int status = 0;
+    int32_t *params = (int32_t *)pParam;
+    static_assert(sizeof(float) == sizeof(int32_t) && sizeof(float) == sizeof(value_t) &&
+            alignof(float) == alignof(int32_t) && alignof(float) == alignof(value_t),
+            "Size/alignment mismatch for float/int32_t/value_t");
+    value_t *values = reinterpret_cast<value_t*>(pValue);
+
+    ALOGVV("%s start", __func__);
+    if (paramSize < sizeof(int32_t)) {
+        ALOGE("%s invalid paramSize: %u", __func__, paramSize);
+        return -EINVAL;
+    }
+    const int32_t command = params[0];
+    switch (command) {
+    case DP_PARAM_ENGINE_ARCHITECTURE: {
+        ALOGVV("engine architecture paramsize: %d valuesize %d",paramSize, valueSize);
+        if (!DP_checkSizesInt(paramSize, valueSize, 1 /*params*/, 9 /*values*/)) {
+            ALOGE("%s DP_PARAM_ENGINE_ARCHITECTURE (cmd %d) invalid sizes.", __func__, command);
+            status = -EINVAL;
+            break;
+        }
+//        Number[] params = { PARAM_ENGINE_ARCHITECTURE };
+//        Number[] values = { variant /* variant */,
+//                preferredFrameDuration,
+//                (preEqInUse ? 1 : 0),
+//                preEqBandCount,
+//                (mbcInUse ? 1 : 0),
+//                mbcBandCount,
+//                (postEqInUse ? 1 : 0),
+//                postEqBandCount,
+//                (limiterInUse ? 1 : 0)};
+        const int32_t variant = values[0].i;
+        const float preferredFrameDuration = values[1].f;
+        const int32_t preEqInUse = values[2].i;
+        const int32_t preEqBandCount = values[3].i;
+        const int32_t mbcInUse = values[4].i;
+        const int32_t mbcBandCount = values[5].i;
+        const int32_t postEqInUse = values[6].i;
+        const int32_t postEqBandCount = values[7].i;
+        const int32_t limiterInUse = values[8].i;
+        ALOGVV("variant %d, preEqInuse %d, bands %d, mbcinuse %d, mbcbands %d, posteqInUse %d,"
+                "bands %d, limiterinuse %d", variant, preEqInUse, preEqBandCount, mbcInUse,
+                mbcBandCount, postEqInUse, postEqBandCount, limiterInUse);
+
+        //set variant (instantiate effect)
+        //initArchitecture for effect
+        DP_changeVariant(pContext, variant);
+        if (pContext->mPDynamics == NULL) {
+            ALOGE("%s DP_PARAM_ENGINE_ARCHITECTURE error setting variant %d", __func__, variant);
+            status = -EINVAL;
+            break;
+        }
+        pContext->mPreferredFrameDuration = preferredFrameDuration;
+        pContext->mPDynamics->init((uint32_t)audio_channel_count_from_out_mask(
+                pContext->mConfig.inputCfg.channels),
+                preEqInUse != 0, (uint32_t)preEqBandCount,
+                mbcInUse != 0, (uint32_t)mbcBandCount,
+                postEqInUse != 0, (uint32_t)postEqBandCount,
+                limiterInUse != 0);
+
+        DP_configureVariant(pContext, variant);
+        break;
+    }
+    case DP_PARAM_INPUT_GAIN: {
+        ALOGVV("engine DP_PARAM_INPUT_GAIN paramsize: %d valuesize %d",paramSize, valueSize);
+        if (!DP_checkSizesInt(paramSize, valueSize, 2 /*params*/, 1 /*values*/)) {
+            ALOGE("%s DP_PARAM_INPUT_GAIN invalid sizes.", __func__);
+            status = -EINVAL;
+            break;
+        }
+
+        const int32_t channel = params[1];
+        dp_fx::DPChannel * pChannel = DP_getChannel(pContext, channel);
+        if (pChannel == NULL) {
+            ALOGE("%s DP_PARAM_INPUT_GAIN invalid channel %d", __func__, channel);
+            status = -EINVAL;
+            break;
+        }
+        const float gain = values[0].f;
+        ALOGVV("%s DP_PARAM_INPUT_GAIN channel %d, level %f", __func__, channel, gain);
+        pChannel->setInputGain(gain);
+        break;
+    }
+    case DP_PARAM_PRE_EQ:
+    case DP_PARAM_POST_EQ: {
+        ALOGVV("engine DP_PARAM_*_EQ paramsize: %d valuesize %d",paramSize, valueSize);
+        if (!DP_checkSizesInt(paramSize, valueSize, 2 /*params*/, 3 /*values*/)) {
+            ALOGE("%s DP_PARAM_*_EQ (cmd %d) invalid sizes.", __func__, command);
+            status = -EINVAL;
+            break;
+        }
+//        Number[] params = {paramSet,
+//                channelIndex};
+//        Number[] values = { (eq.isInUse() ? 1 : 0),
+//                (eq.isEnabled() ? 1 : 0),
+//                bandCount};
+        const int32_t channel = params[1];
+
+        const int32_t enabled = values[1].i;
+        const int32_t bandCount = values[2].i;
+        ALOGVV(" %s channel: %d, inUse::%d, enabled:%d, bandCount:%d\n",
+                (command == DP_PARAM_PRE_EQ ? "preEq" : "postEq"), channel, values[0].i,
+                values[2].i, bandCount);
+
+        dp_fx::DPEq *pEq = DP_getEq(pContext, channel, command);
+        if (pEq == NULL) {
+            ALOGE("%s set PARAM_*_EQ invalid channel %d or command %d", __func__, channel,
+                    command);
+            status = -EINVAL;
+            break;
+        }
+
+        pEq->setEnabled(enabled != 0);
+        //fail if bandcountis different? maybe.
+        if ((int32_t)pEq->getBandCount() != bandCount) {
+            ALOGW("%s warning, trying to set different bandcount from %d to %d", __func__,
+                    pEq->getBandCount(), bandCount);
+        }
+        break;
+    }
+    case DP_PARAM_PRE_EQ_BAND:
+    case DP_PARAM_POST_EQ_BAND: {
+        ALOGVV("engine set PARAM_*_EQ_BAND paramsize: %d valuesize %d",paramSize, valueSize);
+        if (!DP_checkSizesInt(paramSize, valueSize, 3 /*params*/, 3 /*values*/)) {
+            ALOGE("%s PARAM_*_EQ_BAND (cmd %d) invalid sizes.", __func__, command);
+            status = -EINVAL;
+            break;
+        }
+//        Number[] values = { channelIndex,
+//                bandIndex,
+//                (eqBand.isEnabled() ? 1 : 0),
+//                eqBand.getCutoffFrequency(),
+//                eqBand.getGain()};
+
+//        Number[] params = {paramSet,
+//                channelIndex,
+//                bandIndex};
+//        Number[] values = {(eqBand.isEnabled() ? 1 : 0),
+//              eqBand.getCutoffFrequency(),
+//              eqBand.getGain()};
+
+        const int32_t channel = params[1];
+        const int32_t band = params[2];
+
+        const int32_t enabled = values[0].i;
+        const float cutoffFrequency = values[1].f;
+        const float gain = values[2].f;
+
+
+        ALOGVV(" %s channel: %d, band::%d, enabled:%d, cutoffFrequency:%f, gain%f\n",
+                (command == DP_PARAM_PRE_EQ_BAND ? "preEqBand" : "postEqBand"), channel, band,
+                enabled, cutoffFrequency, gain);
+
+        int eqCommand = (command == DP_PARAM_PRE_EQ_BAND ? DP_PARAM_PRE_EQ :
+                (command == DP_PARAM_POST_EQ_BAND ? DP_PARAM_POST_EQ : -1));
+        dp_fx::DPEq *pEq = DP_getEq(pContext, channel, eqCommand);
+        if (pEq == NULL) {
+            ALOGE("%s set PARAM_*_EQ_BAND invalid channel %d or command %d", __func__, channel,
+                    command);
+            status = -EINVAL;
+            break;
+        }
+
+        dp_fx::DPEqBand eqBand;
+        eqBand.init(enabled != 0, cutoffFrequency, gain);
+        pEq->setBand(band, eqBand);
+        break;
+    }
+    case DP_PARAM_MBC: {
+        ALOGVV("engine DP_PARAM_MBC paramsize: %d valuesize %d",paramSize, valueSize);
+        if (!DP_checkSizesInt(paramSize, valueSize, 2 /*params*/, 3 /*values*/)) {
+            ALOGE("%s DP_PARAM_MBC (cmd %d) invalid sizes.", __func__, command);
+            status = -EINVAL;
+            break;
+        }
+//            Number[] params = { PARAM_MBC,
+//                    channelIndex};
+//            Number[] values = {(mbc.isInUse() ? 1 : 0),
+//                    (mbc.isEnabled() ? 1 : 0),
+//                    bandCount};
+        const int32_t channel = params[1];
+
+        const int32_t enabled = values[1].i;
+        const int32_t bandCount = values[2].i;
+        ALOGVV("MBC channel: %d, inUse::%d, enabled:%d, bandCount:%d\n", channel, values[0].i,
+                enabled, bandCount);
+
+        dp_fx::DPMbc *pMbc = DP_getMbc(pContext, channel);
+        if (pMbc == NULL) {
+            ALOGE("%s set DP_PARAM_MBC invalid channel %d ", __func__, channel);
+            status = -EINVAL;
+            break;
+        }
+
+        pMbc->setEnabled(enabled != 0);
+        //fail if bandcountis different? maybe.
+        if ((int32_t)pMbc->getBandCount() != bandCount) {
+            ALOGW("%s warning, trying to set different bandcount from %d to %d", __func__,
+                    pMbc->getBandCount(), bandCount);
+        }
+        break;
+    }
+    case DP_PARAM_MBC_BAND: {
+        ALOGVV("engine set DP_PARAM_MBC_BAND paramsize: %d valuesize %d ",paramSize, valueSize);
+        if (!DP_checkSizesInt(paramSize, valueSize, 3 /*params*/, 11 /*values*/)) {
+            ALOGE("%s DP_PARAM_MBC_BAND: (cmd %d) invalid sizes.", __func__, command);
+            status = -EINVAL;
+            break;
+        }
+//        Number[] params = { PARAM_MBC_BAND,
+//                channelIndex,
+//                bandIndex};
+//        Number[] values = {(mbcBand.isEnabled() ? 1 : 0),
+//                mbcBand.getCutoffFrequency(),
+//                mbcBand.getAttackTime(),
+//                mbcBand.getReleaseTime(),
+//                mbcBand.getRatio(),
+//                mbcBand.getThreshold(),
+//                mbcBand.getKneeWidth(),
+//                mbcBand.getNoiseGateThreshold(),
+//                mbcBand.getExpanderRatio(),
+//                mbcBand.getPreGain(),
+//                mbcBand.getPostGain()};
+
+        const int32_t channel = params[1];
+        const int32_t band = params[2];
+
+        const int32_t enabled = values[0].i;
+        const float cutoffFrequency = values[1].f;
+        const float attackTime = values[2].f;
+        const float releaseTime = values[3].f;
+        const float ratio = values[4].f;
+        const float threshold = values[5].f;
+        const float kneeWidth = values[6].f;
+        const float noiseGateThreshold = values[7].f;
+        const float expanderRatio = values[8].f;
+        const float preGain = values[9].f;
+        const float postGain = values[10].f;
+
+        ALOGVV(" mbcBand channel: %d, band::%d, enabled:%d, cutoffFrequency:%f, attackTime:%f,"
+                "releaseTime:%f, ratio:%f, threshold:%f, kneeWidth:%f, noiseGateThreshold:%f,"
+                "expanderRatio:%f, preGain:%f, postGain:%f\n",
+                channel, band, enabled, cutoffFrequency, attackTime, releaseTime, ratio,
+                threshold, kneeWidth, noiseGateThreshold, expanderRatio, preGain, postGain);
+
+        dp_fx::DPMbc *pMbc = DP_getMbc(pContext, channel);
+        if (pMbc == NULL) {
+            ALOGE("%s set DP_PARAM_MBC_BAND invalid channel %d", __func__, channel);
+            status = -EINVAL;
+            break;
+        }
+
+        dp_fx::DPMbcBand mbcBand;
+        mbcBand.init(enabled != 0, cutoffFrequency, attackTime, releaseTime, ratio, threshold,
+                kneeWidth, noiseGateThreshold, expanderRatio, preGain, postGain);
+        pMbc->setBand(band, mbcBand);
+        break;
+    }
+    case DP_PARAM_LIMITER: {
+        ALOGVV("engine DP_PARAM_LIMITER paramsize: %d valuesize %d",paramSize, valueSize);
+        if (!DP_checkSizesInt(paramSize, valueSize, 2 /*params*/, 8 /*values*/)) {
+            ALOGE("%s DP_PARAM_LIMITER (cmd %d) invalid sizes.", __func__, command);
+            status = -EINVAL;
+            break;
+        }
+//            Number[] params = { PARAM_LIMITER,
+//                             channelIndex};
+//                     Number[] values = {(limiter.isInUse() ? 1 : 0),
+//                             (limiter.isEnabled() ? 1 : 0),
+//                             limiter.getLinkGroup(),
+//                             limiter.getAttackTime(),
+//                             limiter.getReleaseTime(),
+//                             limiter.getRatio(),
+//                             limiter.getThreshold(),
+//                             limiter.getPostGain()};
+
+        const int32_t channel = params[1];
+
+        const int32_t inUse = values[0].i;
+        const int32_t enabled = values[1].i;
+        const int32_t linkGroup = values[2].i;
+        const float attackTime = values[3].f;
+        const float releaseTime = values[4].f;
+        const float ratio = values[5].f;
+        const float threshold = values[6].f;
+        const float postGain = values[7].f;
+
+        ALOGVV(" Limiter channel: %d, inUse::%d, enabled:%d, linkgroup:%d attackTime:%f,"
+                "releaseTime:%f, ratio:%f, threshold:%f, postGain:%f\n", channel, inUse,
+                enabled, linkGroup, attackTime, releaseTime, ratio, threshold, postGain);
+
+        dp_fx::DPChannel * pChannel = DP_getChannel(pContext, channel);
+        if (pChannel == NULL) {
+            ALOGE("%s DP_PARAM_LIMITER invalid channel %d", __func__, channel);
+            status = -EINVAL;
+            break;
+        }
+        dp_fx::DPLimiter limiter;
+        limiter.init(inUse != 0, enabled != 0, linkGroup, attackTime, releaseTime, ratio,
+                threshold, postGain);
+        pChannel->setLimiter(limiter);
+        break;
+    }
+    default:
+        ALOGE("%s invalid param %d", __func__, params[0]);
+        status = -EINVAL;
+        break;
+    }
+
+    ALOGVV("%s end param: %d, status: %d", __func__, params[0], status);
+    return status;
+} /* end DP_setParameter */
+
+/* Effect Control Interface Implementation: get_descriptor */
+int DP_getDescriptor(effect_handle_t self,
+        effect_descriptor_t *pDescriptor)
+{
+    DynamicsProcessingContext * pContext = (DynamicsProcessingContext *) self;
+
+    if (pContext == NULL || pDescriptor == NULL) {
+        ALOGE("DP_getDescriptor() invalid param");
+        return -EINVAL;
+    }
+
+    *pDescriptor = gDPDescriptor;
+
+    return 0;
+} /* end DP_getDescriptor */
+
+
+// effect_handle_t interface implementation for Dynamics Processing effect
+const struct effect_interface_s gDPInterface = {
+        DP_process,
+        DP_command,
+        DP_getDescriptor,
+        NULL,
+};
+
+extern "C" {
+// This is the only symbol that needs to be exported
+__attribute__ ((visibility ("default")))
+audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
+    .tag = AUDIO_EFFECT_LIBRARY_TAG,
+    .version = EFFECT_LIBRARY_API_VERSION,
+    .name = "Dynamics Processing Library",
+    .implementor = "The Android Open Source Project",
+    .create_effect = DPLib_Create,
+    .release_effect = DPLib_Release,
+    .get_descriptor = DPLib_GetDescriptor,
+};
+
+}; // extern "C"
+
diff --git a/media/libeffects/dynamicsproc/MODULE_LICENSE_APACHE2 b/media/libeffects/dynamicsproc/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/media/libeffects/dynamicsproc/MODULE_LICENSE_APACHE2
diff --git a/media/libeffects/dynamicsproc/NOTICE b/media/libeffects/dynamicsproc/NOTICE
new file mode 100644
index 0000000..31cc6e9
--- /dev/null
+++ b/media/libeffects/dynamicsproc/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-2018, 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.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/media/libeffects/dynamicsproc/dsp/DPBase.cpp b/media/libeffects/dynamicsproc/dsp/DPBase.cpp
new file mode 100644
index 0000000..8b79991
--- /dev/null
+++ b/media/libeffects/dynamicsproc/dsp/DPBase.cpp
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2018 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_TAG "DPBase"
+//#define LOG_NDEBUG 0
+
+#include <log/log.h>
+#include "DPBase.h"
+#include "DPFrequency.h"
+
+namespace dp_fx {
+
+DPStage::DPStage() : mInUse(DP_DEFAULT_STAGE_INUSE),
+        mEnabled(DP_DEFAULT_STAGE_ENABLED) {
+}
+
+void DPStage::init(bool inUse, bool enabled) {
+    mInUse = inUse;
+    mEnabled = enabled;
+}
+
+//----
+DPBandStage::DPBandStage() : mBandCount(0) {
+}
+
+void DPBandStage::init(bool inUse, bool enabled, int bandCount) {
+    DPStage::init(inUse, enabled);
+    mBandCount = inUse ? bandCount : 0;
+}
+
+//---
+DPBandBase::DPBandBase() {
+    init(DP_DEFAULT_BAND_ENABLED,
+            DP_DEFAULT_BAND_CUTOFF_FREQUENCY_HZ);
+}
+
+void DPBandBase::init(bool enabled, float cutoffFrequency){
+    mEnabled = enabled;
+    mCutoofFrequencyHz = cutoffFrequency;
+}
+
+//-----
+DPEqBand::DPEqBand() {
+    init(DP_DEFAULT_BAND_ENABLED,
+            DP_DEFAULT_BAND_CUTOFF_FREQUENCY_HZ,
+            DP_DEFAULT_GAIN_DB);
+}
+
+void DPEqBand::init(bool enabled, float cutoffFrequency, float gain) {
+    DPBandBase::init(enabled, cutoffFrequency);
+    setGain(gain);
+}
+
+float DPEqBand::getGain() const{
+    return mGainDb;
+}
+
+void DPEqBand::setGain(float gain) {
+    mGainDb = gain;
+}
+
+//------
+DPMbcBand::DPMbcBand() {
+    init(DP_DEFAULT_BAND_ENABLED,
+            DP_DEFAULT_BAND_CUTOFF_FREQUENCY_HZ,
+            DP_DEFAULT_ATTACK_TIME_MS,
+            DP_DEFAULT_RELEASE_TIME_MS,
+            DP_DEFAULT_RATIO,
+            DP_DEFAULT_THRESHOLD_DB,
+            DP_DEFAULT_KNEE_WIDTH_DB,
+            DP_DEFAULT_NOISE_GATE_THRESHOLD_DB,
+            DP_DEFAULT_EXPANDER_RATIO,
+            DP_DEFAULT_GAIN_DB,
+            DP_DEFAULT_GAIN_DB);
+}
+
+void DPMbcBand::init(bool enabled, float cutoffFrequency, float attackTime, float releaseTime,
+        float ratio, float threshold, float kneeWidth, float noiseGateThreshold,
+        float expanderRatio, float preGain, float postGain) {
+    DPBandBase::init(enabled, cutoffFrequency);
+    setAttackTime(attackTime);
+    setReleaseTime(releaseTime);
+    setRatio(ratio);
+    setThreshold(threshold);
+    setKneeWidth(kneeWidth);
+    setNoiseGateThreshold(noiseGateThreshold);
+    setExpanderRatio(expanderRatio);
+    setPreGain(preGain);
+    setPostGain(postGain);
+}
+
+//------
+DPEq::DPEq() {
+}
+
+void DPEq::init(bool inUse, bool enabled, uint32_t bandCount) {
+    DPBandStage::init(inUse, enabled, bandCount);
+    mBands.resize(getBandCount());
+}
+
+DPEqBand * DPEq::getBand(uint32_t band) {
+    if (band < getBandCount()) {
+        return &mBands[band];
+    }
+    return NULL;
+}
+
+void DPEq::setBand(uint32_t band, DPEqBand &src) {
+    if (band < getBandCount()) {
+        mBands[band] = src;
+    }
+}
+
+//------
+DPMbc::DPMbc() {
+}
+
+void DPMbc::init(bool inUse, bool enabled, uint32_t bandCount) {
+    DPBandStage::init(inUse, enabled, bandCount);
+    if (isInUse()) {
+        mBands.resize(bandCount);
+    } else {
+        mBands.resize(0);
+    }
+}
+
+DPMbcBand * DPMbc::getBand(uint32_t band) {
+    if (band < getBandCount()) {
+        return &mBands[band];
+    }
+    return NULL;
+}
+
+void DPMbc::setBand(uint32_t band, DPMbcBand &src) {
+    if (band < getBandCount()) {
+        mBands[band] = src;
+    }
+}
+
+//------
+DPLimiter::DPLimiter() {
+    init(DP_DEFAULT_STAGE_INUSE,
+            DP_DEFAULT_STAGE_ENABLED,
+            DP_DEFAULT_LINK_GROUP,
+            DP_DEFAULT_ATTACK_TIME_MS,
+            DP_DEFAULT_RELEASE_TIME_MS,
+            DP_DEFAULT_RATIO,
+            DP_DEFAULT_THRESHOLD_DB,
+            DP_DEFAULT_GAIN_DB);
+}
+
+void DPLimiter::init(bool inUse, bool enabled, uint32_t linkGroup, float attackTime, float releaseTime,
+        float ratio, float threshold, float postGain) {
+    DPStage::init(inUse, enabled);
+    setLinkGroup(linkGroup);
+    setAttackTime(attackTime);
+    setReleaseTime(releaseTime);
+    setRatio(ratio);
+    setThreshold(threshold);
+    setPostGain(postGain);
+}
+
+//----
+DPChannel::DPChannel() : mInitialized(false), mInputGainDb(0), mPreEqInUse(false), mMbcInUse(false),
+        mPostEqInUse(false), mLimiterInUse(false) {
+}
+
+void DPChannel::init(float inputGain, bool preEqInUse, uint32_t preEqBandCount,
+        bool mbcInUse, uint32_t mbcBandCount, bool postEqInUse, uint32_t postEqBandCount,
+        bool limiterInUse) {
+    setInputGain(inputGain);
+    mPreEqInUse = preEqInUse;
+    mMbcInUse = mbcInUse;
+    mPostEqInUse = postEqInUse;
+    mLimiterInUse = limiterInUse;
+
+    mPreEq.init(mPreEqInUse, false, preEqBandCount);
+    mMbc.init(mMbcInUse, false, mbcBandCount);
+    mPostEq.init(mPostEqInUse, false, postEqBandCount);
+    mLimiter.init(mLimiterInUse, false, 0, 50, 120, 2, -30, 0);
+    mInitialized = true;
+}
+
+DPEq* DPChannel::getPreEq() {
+    if (!mInitialized) {
+        return NULL;
+    }
+    return &mPreEq;
+}
+
+DPMbc* DPChannel::getMbc() {
+    if (!mInitialized) {
+        return NULL;
+    }
+    return &mMbc;
+}
+
+DPEq* DPChannel::getPostEq() {
+    if (!mInitialized) {
+        return NULL;
+    }
+    return &mPostEq;
+}
+
+DPLimiter* DPChannel::getLimiter() {
+    if (!mInitialized) {
+        return NULL;
+    }
+    return &mLimiter;
+}
+
+void DPChannel::setLimiter(DPLimiter &limiter) {
+    if (!mInitialized) {
+        return;
+    }
+    mLimiter = limiter;
+}
+
+//----
+DPBase::DPBase() : mInitialized(false), mChannelCount(0), mPreEqInUse(false), mPreEqBandCount(0),
+        mMbcInUse(false), mMbcBandCount(0), mPostEqInUse(false), mPostEqBandCount(0),
+        mLimiterInUse(false) {
+}
+
+void DPBase::init(uint32_t channelCount, bool preEqInUse, uint32_t preEqBandCount,
+        bool mbcInUse, uint32_t mbcBandCount, bool postEqInUse, uint32_t postEqBandCount,
+        bool limiterInUse) {
+    ALOGV("DPBase::init");
+    mChannelCount = channelCount;
+    mPreEqInUse = preEqInUse;
+    mPreEqBandCount = preEqBandCount;
+    mMbcInUse = mbcInUse;
+    mMbcBandCount = mbcBandCount;
+    mPostEqInUse = postEqInUse;
+    mPostEqBandCount = postEqBandCount;
+    mLimiterInUse = limiterInUse;
+    mChannel.resize(mChannelCount);
+    for (size_t ch = 0; ch < mChannelCount; ch++) {
+        mChannel[ch].init(0, preEqInUse, preEqBandCount, mbcInUse, mbcBandCount,
+                postEqInUse, postEqBandCount, limiterInUse);
+    }
+    mInitialized = true;
+}
+
+DPChannel* DPBase::getChannel(uint32_t channelIndex) {
+    if (!mInitialized || channelIndex < 0 || channelIndex >= mChannel.size()) {
+        return NULL;
+    }
+    return & mChannel[channelIndex];
+}
+
+} //namespace dp_fx
diff --git a/media/libeffects/dynamicsproc/dsp/DPBase.h b/media/libeffects/dynamicsproc/dsp/DPBase.h
new file mode 100644
index 0000000..355f64b
--- /dev/null
+++ b/media/libeffects/dynamicsproc/dsp/DPBase.h
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2018 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 DPBASE_H_
+#define DPBASE_H_
+
+
+#include <stdint.h>
+#include <cmath>
+#include <vector>
+#include <android/log.h>
+
+namespace dp_fx {
+
+#define DP_DEFAULT_BAND_ENABLED false
+#define DP_DEFAULT_BAND_CUTOFF_FREQUENCY_HZ 1000
+#define DP_DEFAULT_ATTACK_TIME_MS 50
+#define DP_DEFAULT_RELEASE_TIME_MS 120
+#define DP_DEFAULT_RATIO 2
+#define DP_DEFAULT_THRESHOLD_DB -30
+#define DP_DEFAULT_KNEE_WIDTH_DB 0
+#define DP_DEFAULT_NOISE_GATE_THRESHOLD_DB -90
+#define DP_DEFAULT_EXPANDER_RATIO 1
+#define DP_DEFAULT_GAIN_DB 0
+#define DP_DEFAULT_STAGE_INUSE false
+#define DP_DEFAULT_STAGE_ENABLED false
+#define DP_DEFAULT_LINK_GROUP 0
+
+
+
+class DPStage {
+public:
+    DPStage();
+    ~DPStage() = default;
+    void init(bool inUse, bool enabled);
+    bool isInUse() const {
+        return mInUse;
+    }
+    bool isEnabled() const {
+        return mEnabled;
+    }
+    void setEnabled(bool enabled) {
+        mEnabled = enabled;
+    }
+private:
+    bool mInUse;
+    bool mEnabled;
+};
+
+class DPBandStage : public DPStage {
+public:
+    DPBandStage();
+    ~DPBandStage() = default;
+    void init(bool inUse, bool enabled, int bandCount);
+    uint32_t getBandCount() const {
+        return mBandCount;
+    }
+    void setBandCount(uint32_t bandCount) {
+        mBandCount = bandCount;
+    }
+private:
+    uint32_t mBandCount;
+};
+
+class DPBandBase {
+public:
+    DPBandBase();
+    ~DPBandBase() = default;
+    void init(bool enabled, float cutoffFrequency);
+    bool isEnabled() const {
+        return mEnabled;
+    }
+    void setEnabled(bool enabled) {
+        mEnabled = enabled;
+    }
+    float getCutoffFrequency() const {
+        return mCutoofFrequencyHz;
+    }
+    void setCutoffFrequency(float cutoffFrequency) {
+        mCutoofFrequencyHz = cutoffFrequency;
+    }
+private:
+    bool mEnabled;
+    float mCutoofFrequencyHz;
+};
+
+class DPEqBand : public DPBandBase {
+public:
+    DPEqBand();
+    ~DPEqBand() = default;
+    void init(bool enabled, float cutoffFrequency, float gain);
+    float getGain() const;
+    void setGain(float gain);
+private:
+    float mGainDb;
+};
+
+class DPMbcBand : public DPBandBase {
+public:
+    DPMbcBand();
+    ~DPMbcBand() = default;
+    void init(bool enabled, float cutoffFrequency, float attackTime, float releaseTime,
+            float ratio, float threshold, float kneeWidth, float noiseGateThreshold,
+            float expanderRatio, float preGain, float postGain);
+    float getAttackTime() const {
+        return mAttackTimeMs;
+    }
+    void setAttackTime(float attackTime) {
+        mAttackTimeMs = attackTime;
+    }
+    float getReleaseTime() const {
+        return mReleaseTimeMs;
+    }
+    void setReleaseTime(float releaseTime) {
+        mReleaseTimeMs = releaseTime;
+    }
+    float getRatio() const {
+        return mRatio;
+    }
+    void setRatio(float ratio) {
+        mRatio = ratio;
+    }
+    float getThreshold() const {
+        return mThresholdDb;
+    }
+    void setThreshold(float threshold) {
+        mThresholdDb = threshold;
+    }
+    float getKneeWidth() const {
+        return mKneeWidthDb;
+    }
+    void setKneeWidth(float kneeWidth) {
+        mKneeWidthDb = kneeWidth;
+    }
+    float getNoiseGateThreshold() const {
+        return mNoiseGateThresholdDb;
+    }
+    void setNoiseGateThreshold(float noiseGateThreshold) {
+        mNoiseGateThresholdDb = noiseGateThreshold;
+    }
+    float getExpanderRatio() const {
+        return mExpanderRatio;
+    }
+    void setExpanderRatio(float expanderRatio) {
+        mExpanderRatio = expanderRatio;
+    }
+    float getPreGain() const {
+        return mPreGainDb;
+    }
+    void setPreGain(float preGain) {
+        mPreGainDb = preGain;
+    }
+    float getPostGain() const {
+        return mPostGainDb;
+    }
+    void setPostGain(float postGain) {
+        mPostGainDb = postGain;
+    }
+private:
+    float mAttackTimeMs;
+    float mReleaseTimeMs;
+    float mRatio;
+    float mThresholdDb;
+    float mKneeWidthDb;
+    float mNoiseGateThresholdDb;
+    float mExpanderRatio;
+    float mPreGainDb;
+    float mPostGainDb;
+};
+
+class DPEq : public DPBandStage {
+public:
+    DPEq();
+    ~DPEq() = default;
+    void init(bool inUse, bool enabled, uint32_t bandCount);
+    DPEqBand * getBand(uint32_t band);
+    void setBand(uint32_t band, DPEqBand &src);
+private:
+    std::vector<DPEqBand> mBands;
+};
+
+class DPMbc : public DPBandStage {
+public:
+    DPMbc();
+    ~DPMbc() = default;
+    void init(bool inUse, bool enabled, uint32_t bandCount);
+    DPMbcBand * getBand(uint32_t band);
+    void setBand(uint32_t band, DPMbcBand &src);
+private:
+    std::vector<DPMbcBand> mBands;
+};
+
+class DPLimiter : public DPStage {
+public:
+    DPLimiter();
+    ~DPLimiter() = default;
+    void init(bool inUse, bool enabled, uint32_t linkGroup, float attackTime, float releaseTime,
+            float ratio, float threshold, float postGain);
+    uint32_t getLinkGroup() const {
+        return mLinkGroup;
+    }
+    void setLinkGroup(uint32_t linkGroup) {
+        mLinkGroup = linkGroup;
+    }
+    float getAttackTime() const {
+        return mAttackTimeMs;
+    }
+    void setAttackTime(float attackTime) {
+        mAttackTimeMs = attackTime;
+    }
+    float getReleaseTime() const {
+        return mReleaseTimeMs;
+    }
+    void setReleaseTime(float releaseTime) {
+        mReleaseTimeMs = releaseTime;
+    }
+    float getRatio() const {
+        return mRatio;
+    }
+    void setRatio(float ratio) {
+        mRatio = ratio;
+    }
+    float getThreshold() const {
+        return mThresholdDb;
+    }
+    void setThreshold(float threshold) {
+        mThresholdDb = threshold;
+    }
+    float getPostGain() const {
+        return mPostGainDb;
+    }
+    void setPostGain(float postGain) {
+        mPostGainDb = postGain;
+    }
+private:
+    uint32_t mLinkGroup;
+    float mAttackTimeMs;
+    float mReleaseTimeMs;
+    float mRatio;
+    float mThresholdDb;
+    float mPostGainDb;
+};
+
+class DPChannel {
+public:
+    DPChannel();
+    ~DPChannel() = default;
+    void init(float inputGain, bool preEqInUse, uint32_t preEqBandCount,
+            bool mbcInUse, uint32_t mbcBandCount, bool postEqInUse, uint32_t postEqBandCount,
+            bool limiterInUse);
+
+    float getInputGain() const {
+        if (!mInitialized) {
+            return 0;
+        }
+        return mInputGainDb;
+    }
+    void setInputGain(float gain) {
+        mInputGainDb = gain;
+    }
+
+    DPEq* getPreEq();
+    DPMbc* getMbc();
+    DPEq* getPostEq();
+    DPLimiter *getLimiter();
+    void setLimiter(DPLimiter &limiter);
+
+private:
+    bool mInitialized;
+    float mInputGainDb;
+
+    DPEq mPreEq;
+    DPMbc mMbc;
+    DPEq mPostEq;
+    DPLimiter mLimiter;
+
+    bool mPreEqInUse;
+    bool mMbcInUse;
+    bool mPostEqInUse;
+    bool mLimiterInUse;
+};
+
+class DPBase {
+public:
+    DPBase();
+    virtual ~DPBase() = default;
+
+    void init(uint32_t channelCount, bool preEqInUse, uint32_t preEqBandCount,
+            bool mbcInUse, uint32_t mbcBandCount, bool postEqInUse, uint32_t postEqBandCount,
+            bool limiterInUse);
+    virtual size_t processSamples(const float *in, float *out, size_t samples) = 0;
+    virtual void reset() = 0;
+
+    DPChannel* getChannel(uint32_t channelIndex);
+    uint32_t getChannelCount() const {
+        return mChannelCount;
+    }
+    uint32_t getPreEqBandCount() const {
+        return mPreEqBandCount;
+    }
+    uint32_t getMbcBandCount() const {
+        return mMbcBandCount;
+    }
+    uint32_t getPostEqBandCount() const {
+        return mPostEqBandCount;
+    }
+    bool isPreEQInUse() const {
+        return mPreEqInUse;
+    }
+    bool isMbcInUse() const {
+        return mMbcInUse;
+    }
+    bool isPostEqInUse() const {
+        return mPostEqInUse;
+    }
+    bool isLimiterInUse() const {
+        return mLimiterInUse;
+    }
+
+private:
+    bool mInitialized;
+    //general
+    uint32_t mChannelCount;
+    bool mPreEqInUse;
+    uint32_t mPreEqBandCount;
+    bool mMbcInUse;
+    uint32_t mMbcBandCount;
+    bool mPostEqInUse;
+    uint32_t mPostEqBandCount;
+    bool mLimiterInUse;
+
+    std::vector<DPChannel> mChannel;
+};
+
+} //namespace dp_fx
+
+
+#endif  // DPBASE_H_
diff --git a/media/libeffects/dynamicsproc/dsp/DPFrequency.cpp b/media/libeffects/dynamicsproc/dsp/DPFrequency.cpp
new file mode 100644
index 0000000..59195fc
--- /dev/null
+++ b/media/libeffects/dynamicsproc/dsp/DPFrequency.cpp
@@ -0,0 +1,518 @@
+/*
+ * Copyright (C) 2018 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_TAG "DPFrequency"
+//#define LOG_NDEBUG 0
+
+#include <log/log.h>
+#include "DPFrequency.h"
+#include <algorithm>
+
+namespace dp_fx {
+
+using Eigen::MatrixXd;
+#define MAX_BLOCKSIZE 16384 //For this implementation
+#define MIN_BLOCKSIZE 8
+
+#define CIRCULAR_BUFFER_UPSAMPLE 4  //4 times buffer size
+
+static constexpr float MIN_ENVELOPE = 0.000001f;
+//helper functionS
+static inline bool isPowerOf2(unsigned long n) {
+    return (n & (n - 1)) == 0;
+}
+static constexpr float EPSILON = 0.0000001f;
+
+static inline bool isZero(float f) {
+    return fabs(f) <= EPSILON;
+}
+
+template <class T>
+bool compareEquality(T a, T b) {
+    return (a == b);
+}
+
+template <> bool compareEquality<float>(float a, float b) {
+    return isZero(a - b);
+}
+
+//TODO: avoid using macro for estimating change and assignment.
+#define IS_CHANGED(c, a, b) { c |= !compareEquality(a,b); \
+    (a) = (b); }
+
+float dBtoLinear(float valueDb) {
+    return  pow (10, valueDb / 20.0);
+}
+
+float linearToDb(float value) {
+    return 20 * log10(value);
+}
+
+//ChannelBuffers helper
+void ChannelBuffer::initBuffers(unsigned int blockSize, unsigned int overlapSize,
+        unsigned int halfFftSize, unsigned int samplingRate, DPBase &dpBase) {
+    ALOGV("ChannelBuffer::initBuffers blockSize %d, overlap %d, halfFft %d",
+            blockSize, overlapSize, halfFftSize);
+
+    mSamplingRate = samplingRate;
+    mBlockSize = blockSize;
+
+    cBInput.resize(mBlockSize * CIRCULAR_BUFFER_UPSAMPLE);
+    cBOutput.resize(mBlockSize * CIRCULAR_BUFFER_UPSAMPLE);
+
+    //fill input with half block size...
+    for (unsigned int k = 0;  k < mBlockSize/2; k++) {
+        cBInput.write(0);
+    }
+
+    //temp vectors
+    input.resize(mBlockSize);
+    output.resize(mBlockSize);
+    outTail.resize(overlapSize);
+
+    //module vectors
+    mPreEqFactorVector.resize(halfFftSize, 1.0);
+    mPostEqFactorVector.resize(halfFftSize, 1.0);
+
+    mPreEqBands.resize(dpBase.getPreEqBandCount());
+    mMbcBands.resize(dpBase.getMbcBandCount());
+    mPostEqBands.resize(dpBase.getPostEqBandCount());
+    ALOGV("mPreEqBands %zu, mMbcBands %zu, mPostEqBands %zu",mPreEqBands.size(),
+            mMbcBands.size(), mPostEqBands.size());
+
+    DPChannel *pChannel = dpBase.getChannel(0);
+    if (pChannel != NULL) {
+        mPreEqInUse = pChannel->getPreEq()->isInUse();
+        mMbcInUse = pChannel->getMbc()->isInUse();
+        mPostEqInUse = pChannel->getPostEq()->isInUse();
+        mLimiterInUse = pChannel->getLimiter()->isInUse();
+    }
+}
+
+void ChannelBuffer::computeBinStartStop(BandParams &bp, size_t binStart) {
+
+    bp.binStart = binStart;
+    bp.binStop = (int)(0.5 + bp.freqCutoffHz * mBlockSize / mSamplingRate);
+}
+
+//== DPFrequency
+
+void DPFrequency::reset() {
+}
+
+size_t DPFrequency::getMinBockSize() {
+    return MIN_BLOCKSIZE;
+}
+
+size_t DPFrequency::getMaxBockSize() {
+    return MAX_BLOCKSIZE;
+}
+
+void DPFrequency::configure(size_t blockSize, size_t overlapSize,
+        size_t samplingRate) {
+    ALOGV("configure");
+    mBlockSize = blockSize;
+    if (mBlockSize > MAX_BLOCKSIZE) {
+        mBlockSize = MAX_BLOCKSIZE;
+    } else if (mBlockSize < MIN_BLOCKSIZE) {
+        mBlockSize = MIN_BLOCKSIZE;
+    } else {
+        if (!isPowerOf2(blockSize)) {
+            //find next highest power of 2.
+            mBlockSize = 1 << (32 - __builtin_clz(blockSize));
+        }
+    }
+
+    mHalfFFTSize = 1 + mBlockSize / 2; //including Nyquist bin
+    mOverlapSize = std::min(overlapSize, mBlockSize/2);
+
+    int channelcount = getChannelCount();
+    mSamplingRate = samplingRate;
+    mChannelBuffers.resize(channelcount);
+    for (int ch = 0; ch < channelcount; ch++) {
+        mChannelBuffers[ch].initBuffers(mBlockSize, mOverlapSize, mHalfFFTSize,
+                mSamplingRate, *this);
+    }
+
+    //dsp
+    fill_window(mVWindow, RDSP_WINDOW_HANNING_FLAT_TOP, mBlockSize, mOverlapSize);
+}
+
+void DPFrequency::updateParameters(ChannelBuffer &cb, int channelIndex) {
+    DPChannel *pChannel = getChannel(channelIndex);
+
+    if (pChannel == NULL) {
+        ALOGE("Error: updateParameters null DPChannel %d", channelIndex);
+        return;
+    }
+
+    //===Input Gain and preEq
+    {
+        bool changed = false;
+        IS_CHANGED(changed, cb.inputGainDb, pChannel->getInputGain());
+        //===EqPre
+        if (cb.mPreEqInUse) {
+            DPEq *pPreEq = pChannel->getPreEq();
+            if (pPreEq == NULL) {
+                ALOGE("Error: updateParameters null PreEq for channel: %d", channelIndex);
+                return;
+            }
+            IS_CHANGED(changed, cb.mPreEqEnabled, pPreEq->isEnabled());
+            if (cb.mPreEqEnabled) {
+                for (unsigned int b = 0; b < getPreEqBandCount(); b++) {
+                    DPEqBand *pEqBand = pPreEq->getBand(b);
+                    if (pEqBand == NULL) {
+                        ALOGE("Error: updateParameters null PreEqBand for band %d", b);
+                        return; //failed.
+                    }
+                    ChannelBuffer::EqBandParams *pEqBandParams = &cb.mPreEqBands[b];
+                    IS_CHANGED(changed, pEqBandParams->enabled, pEqBand->isEnabled());
+                    IS_CHANGED(changed, pEqBandParams->freqCutoffHz,
+                            pEqBand->getCutoffFrequency());
+                    IS_CHANGED(changed, pEqBandParams->gainDb, pEqBand->getGain());
+                }
+            }
+        }
+
+        if (changed) {
+            float inputGainFactor = dBtoLinear(cb.inputGainDb);
+            if (cb.mPreEqInUse && cb.mPreEqEnabled) {
+                ALOGV("preEq changed, recomputing! channel %d", channelIndex);
+                size_t binNext = 0;
+                for (unsigned int b = 0; b < getPreEqBandCount(); b++) {
+                    ChannelBuffer::EqBandParams *pEqBandParams = &cb.mPreEqBands[b];
+
+                    //frequency translation
+                    cb.computeBinStartStop(*pEqBandParams, binNext);
+                    binNext = pEqBandParams->binStop + 1;
+                    float factor = dBtoLinear(pEqBandParams->gainDb);
+                    if (!pEqBandParams->enabled) {
+                        factor = inputGainFactor;
+                    }
+                    for (size_t k = pEqBandParams->binStart;
+                            k <= pEqBandParams->binStop && k < mHalfFFTSize; k++) {
+                        cb.mPreEqFactorVector[k] = factor * inputGainFactor;
+                    }
+                }
+            } else {
+                ALOGV("only input gain changed, recomputing!");
+                //populate PreEq factor with input gain factor.
+                for (size_t k = 0; k < mHalfFFTSize; k++) {
+                    cb.mPreEqFactorVector[k] = inputGainFactor;
+                }
+            }
+        }
+    } //inputGain and preEq
+
+    //===EqPost
+    if (cb.mPostEqInUse) {
+        bool changed = false;
+
+        DPEq *pPostEq = pChannel->getPostEq();
+        if (pPostEq == NULL) {
+            ALOGE("Error: updateParameters null postEq for channel: %d", channelIndex);
+            return; //failed.
+        }
+        IS_CHANGED(changed, cb.mPostEqEnabled, pPostEq->isEnabled());
+        if (cb.mPostEqEnabled) {
+            for (unsigned int b = 0; b < getPostEqBandCount(); b++) {
+                DPEqBand *pEqBand = pPostEq->getBand(b);
+                if (pEqBand == NULL) {
+                    ALOGE("Error: updateParameters PostEqBand NULL for band %d", b);
+                    return; //failed.
+                }
+                ChannelBuffer::EqBandParams *pEqBandParams = &cb.mPostEqBands[b];
+                IS_CHANGED(changed, pEqBandParams->enabled, pEqBand->isEnabled());
+                IS_CHANGED(changed, pEqBandParams->freqCutoffHz,
+                        pEqBand->getCutoffFrequency());
+                IS_CHANGED(changed, pEqBandParams->gainDb, pEqBand->getGain());
+            }
+            if (changed) {
+                ALOGV("postEq changed, recomputing! channel %d", channelIndex);
+                size_t binNext = 0;
+                for (unsigned int b = 0; b < getPostEqBandCount(); b++) {
+                    ChannelBuffer::EqBandParams *pEqBandParams = &cb.mPostEqBands[b];
+
+                    //frequency translation
+                    cb.computeBinStartStop(*pEqBandParams, binNext);
+                    binNext = pEqBandParams->binStop + 1;
+                    float factor = dBtoLinear(pEqBandParams->gainDb);
+                    if (!pEqBandParams->enabled) {
+                        factor = 1.0;
+                    }
+                    for (size_t k = pEqBandParams->binStart;
+                            k <= pEqBandParams->binStop && k < mHalfFFTSize; k++) {
+                        cb.mPostEqFactorVector[k] = factor;
+                    }
+                }
+            }
+        } //enabled
+    }
+
+    //===MBC
+    if (cb.mMbcInUse) {
+        DPMbc *pMbc = pChannel->getMbc();
+        if (pMbc == NULL) {
+            ALOGE("Error: updateParameters Mbc NULL for channel: %d", channelIndex);
+            return;
+        }
+        cb.mMbcEnabled = pMbc->isEnabled();
+        if (cb.mMbcEnabled) {
+            bool changed = false;
+            for (unsigned int b = 0; b < getMbcBandCount(); b++) {
+                DPMbcBand *pMbcBand = pMbc->getBand(b);
+                if (pMbcBand == NULL) {
+                    ALOGE("Error: updateParameters MbcBand NULL for band %d", b);
+                    return; //failed.
+                }
+                ChannelBuffer::MbcBandParams *pMbcBandParams = &cb.mMbcBands[b];
+                pMbcBandParams->enabled = pMbcBand->isEnabled();
+                IS_CHANGED(changed, pMbcBandParams->freqCutoffHz,
+                        pMbcBand->getCutoffFrequency());
+
+                pMbcBandParams->gainPreDb = pMbcBand->getPreGain();
+                pMbcBandParams->gainPostDb = pMbcBand->getPostGain();
+                pMbcBandParams->attackTimeMs = pMbcBand->getAttackTime();
+                pMbcBandParams->releaseTimeMs = pMbcBand->getReleaseTime();
+                pMbcBandParams->ratio = pMbcBand->getRatio();
+                pMbcBandParams->thresholdDb = pMbcBand->getThreshold();
+                pMbcBandParams->kneeWidthDb = pMbcBand->getKneeWidth();
+                pMbcBandParams->noiseGateThresholdDb = pMbcBand->getNoiseGateThreshold();
+                pMbcBandParams->expanderRatio = pMbcBand->getExpanderRatio();
+
+            }
+
+            if (changed) {
+                ALOGV("mbc changed, recomputing! channel %d", channelIndex);
+                size_t binNext= 0;
+                for (unsigned int b = 0; b < getMbcBandCount(); b++) {
+                    ChannelBuffer::MbcBandParams *pMbcBandParams = &cb.mMbcBands[b];
+
+                    pMbcBandParams->previousEnvelope = 0;
+
+                    //frequency translation
+                    cb.computeBinStartStop(*pMbcBandParams, binNext);
+                    binNext = pMbcBandParams->binStop + 1;
+                }
+
+            }
+
+        }
+    }
+}
+
+size_t DPFrequency::processSamples(const float *in, float *out, size_t samples) {
+       const float *pIn = in;
+       float *pOut = out;
+
+       int channelCount = mChannelBuffers.size();
+       if (channelCount < 1) {
+           ALOGW("warning: no Channels ready for processing");
+           return 0;
+       }
+
+       //**Check if parameters have changed and update
+       for (int ch = 0; ch < channelCount; ch++) {
+           updateParameters(mChannelBuffers[ch], ch);
+       }
+
+       //**separate into channels
+       for (size_t k = 0; k < samples; k += channelCount) {
+           for (int ch = 0; ch < channelCount; ch++) {
+               mChannelBuffers[ch].cBInput.write(*pIn++);
+           }
+       }
+
+       //TODO: lookahead limiters
+       //TODO: apply linked limiters to all channels.
+       //**Process each Channel
+       for (int ch = 0; ch < channelCount; ch++) {
+           processMono(mChannelBuffers[ch]);
+       }
+
+       //** estimate how much data is available in ALL channels
+       size_t available = mChannelBuffers[0].cBOutput.availableToRead();
+       for (int ch = 1; ch < channelCount; ch++) {
+           available = std::min(available, mChannelBuffers[ch].cBOutput.availableToRead());
+       }
+
+       //** make sure to output just what the buffer can handle
+       if (available > samples/channelCount) {
+           available = samples/channelCount;
+       }
+
+       //**Prepend zeroes if necessary
+       size_t fill = samples - (channelCount * available);
+       for (size_t k = 0; k < fill; k++) {
+           *pOut++ = 0;
+       }
+
+       //**interleave channels
+       for (size_t k = 0; k < available; k++) {
+           for (int ch = 0; ch < channelCount; ch++) {
+               *pOut++ = mChannelBuffers[ch].cBOutput.read();
+           }
+       }
+
+       return samples;
+}
+
+size_t DPFrequency::processMono(ChannelBuffer &cb) {
+
+    size_t processedSamples = 0;
+
+    size_t available = cb.cBInput.availableToRead();
+    while (available >= mBlockSize - mOverlapSize) {
+
+        //move tail of previous
+        for (unsigned int k = 0; k < mOverlapSize; ++k) {
+            cb.input[k] = cb.input[mBlockSize - mOverlapSize + k];
+        }
+
+        //read new available data
+        for (unsigned int k = 0; k < mBlockSize - mOverlapSize; k++) {
+            cb.input[mOverlapSize + k] = cb.cBInput.read();
+        }
+
+        //## Actual process
+        processOneVector(cb.output, cb.input, cb);
+        //##End of Process
+
+        //mix tail (and capture new tail
+        for (unsigned int k = 0; k < mOverlapSize; k++) {
+            cb.output[k] += cb.outTail[k];
+            cb.outTail[k] = cb.output[mBlockSize - mOverlapSize + k]; //new tail
+        }
+
+        //output data
+        for (unsigned int k = 0; k < mBlockSize - mOverlapSize; k++) {
+            cb.cBOutput.write(cb.output[k]);
+        }
+
+        available = cb.cBInput.availableToRead();
+    }
+
+    return processedSamples;
+}
+
+size_t DPFrequency::processOneVector(FloatVec & output, FloatVec & input,
+        ChannelBuffer &cb) {
+
+    //##apply window
+    Eigen::Map<Eigen::VectorXf> eWindow(&mVWindow[0], mVWindow.size());
+    Eigen::Map<Eigen::VectorXf> eInput(&input[0], input.size());
+
+    Eigen::VectorXf eWin = eInput.cwiseProduct(eWindow); //apply window
+
+    //##fft //TODO: refactor frequency transformations away from other stages.
+    mFftServer.fwd(mComplexTemp, eWin);
+
+    size_t cSize = mComplexTemp.size();
+    size_t maxBin = std::min(cSize/2, mHalfFFTSize);
+
+    //== EqPre (always runs)
+    for (size_t k = 0; k < maxBin; k++) {
+        mComplexTemp[k] *= cb.mPreEqFactorVector[k];
+    }
+
+    //== MBC
+    if (cb.mMbcInUse && cb.mMbcEnabled) {
+        for (size_t band = 0; band < cb.mMbcBands.size(); band++) {
+            ChannelBuffer::MbcBandParams *pMbcBandParams = &cb.mMbcBands[band];
+            float fEnergySum = 0;
+
+            //apply pre gain.
+            float preGainFactor = dBtoLinear(pMbcBandParams->gainPreDb);
+            float preGainSquared = preGainFactor * preGainFactor;
+
+            for (size_t k = pMbcBandParams->binStart; k <= pMbcBandParams->binStop; k++) {
+                float fReal = mComplexTemp[k].real();
+                float fImag = mComplexTemp[k].imag();
+                float fSquare = (fReal * fReal + fImag * fImag) * preGainSquared;
+
+                fEnergySum += fSquare;
+            }
+
+            fEnergySum = sqrt(fEnergySum /2.0);
+            float fTheta = 0.0;
+            float fFAtt = pMbcBandParams->attackTimeMs;
+            float fFRel = pMbcBandParams->releaseTimeMs;
+
+            float fUpdatesPerSecond = 10; //TODO: compute from framerate
+
+
+            if (fEnergySum > pMbcBandParams->previousEnvelope) {
+                fTheta = exp(-1.0 / (fFAtt * fUpdatesPerSecond));
+            } else {
+                fTheta = exp(-1.0 / (fFRel * fUpdatesPerSecond));
+            }
+
+            float fEnv = (1.0 - fTheta) * fEnergySum + fTheta * pMbcBandParams->previousEnvelope;
+
+            //preserve for next iteration
+            pMbcBandParams->previousEnvelope = fEnv;
+
+            float fThreshold = dBtoLinear(pMbcBandParams->thresholdDb);
+            float fNoiseGateThreshold = dBtoLinear(pMbcBandParams->noiseGateThresholdDb);
+
+            float fNewFactor = 1.0;
+
+            if (fEnv > fThreshold) {
+                float fDbAbove = linearToDb(fThreshold / fEnv);
+                float fDbTarget = fDbAbove / pMbcBandParams->ratio;
+                float fDbChange = fDbAbove - fDbTarget;
+                fNewFactor = dBtoLinear(fDbChange);
+            } else if (fEnv < fNoiseGateThreshold) {
+                if (fEnv < MIN_ENVELOPE) {
+                    fEnv = MIN_ENVELOPE;
+                }
+                float fDbBelow = linearToDb(fNoiseGateThreshold / fEnv);
+                float fDbTarget = fDbBelow / pMbcBandParams->expanderRatio;
+                float fDbChange = fDbBelow - fDbTarget;
+                fNewFactor = dBtoLinear(fDbChange);
+            }
+
+            //apply post gain.
+            fNewFactor *= dBtoLinear(pMbcBandParams->gainPostDb);
+
+            if (fNewFactor < 0) {
+                fNewFactor = 0;
+            }
+
+            //apply to this band
+            for (size_t k = pMbcBandParams->binStart; k <= pMbcBandParams->binStop; k++) {
+                mComplexTemp[k] *= fNewFactor;
+            }
+
+        } //end per band process
+
+    } //end MBC
+
+    //== EqPost
+    if (cb.mPostEqInUse && cb.mPostEqEnabled) {
+        for (size_t k = 0; k < maxBin; k++) {
+            mComplexTemp[k] *= cb.mPostEqFactorVector[k];
+        }
+    }
+
+    //##ifft directly to output.
+    Eigen::Map<Eigen::VectorXf> eOutput(&output[0], output.size());
+    mFftServer.inv(eOutput, mComplexTemp);
+
+    return mBlockSize;
+}
+
+} //namespace dp_fx
diff --git a/media/libeffects/dynamicsproc/dsp/DPFrequency.h b/media/libeffects/dynamicsproc/dsp/DPFrequency.h
new file mode 100644
index 0000000..9919142
--- /dev/null
+++ b/media/libeffects/dynamicsproc/dsp/DPFrequency.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2018 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 DPFREQUENCY_H_
+#define DPFREQUENCY_H_
+
+#include <Eigen/Dense>
+#include <unsupported/Eigen/FFT>
+
+#include "RDsp.h"
+#include "SHCircularBuffer.h"
+
+#include "DPBase.h"
+
+
+namespace dp_fx {
+
+using FXBuffer = SHCircularBuffer<float>;
+
+class ChannelBuffer {
+public:
+    FXBuffer cBInput;   // Circular Buffer input
+    FXBuffer cBOutput;  // Circular Buffer output
+    FloatVec input;     // time domain temp vector for input
+    FloatVec output;    // time domain temp vector for output
+    FloatVec outTail;   // time domain temp vector for output tail (for overlap-add method)
+
+    //Current parameters
+    float inputGainDb;
+    struct BandParams {
+        bool enabled;
+        float freqCutoffHz;
+        size_t binStart;
+        size_t binStop;
+    };
+    struct EqBandParams : public BandParams {
+        float gainDb;
+    };
+    struct MbcBandParams : public BandParams {
+        float gainPreDb;
+        float gainPostDb;
+        float attackTimeMs;
+        float releaseTimeMs;
+        float ratio;
+        float thresholdDb;
+        float kneeWidthDb;
+        float noiseGateThresholdDb;
+        float expanderRatio;
+
+        //Historic values
+        float previousEnvelope;
+    };
+
+    bool mPreEqInUse;
+    bool mPreEqEnabled;
+    std::vector<EqBandParams> mPreEqBands;
+
+    bool mMbcInUse;
+    bool mMbcEnabled;
+    std::vector<MbcBandParams> mMbcBands;
+
+    bool mPostEqInUse;
+    bool mPostEqEnabled;
+    std::vector<EqBandParams> mPostEqBands;
+
+    bool mLimiterInUse;
+    bool mLimiterEnabled;
+    FloatVec mPreEqFactorVector; // temp pre-computed vector to shape spectrum at preEQ stage
+    FloatVec mPostEqFactorVector; // temp pre-computed vector to shape spectrum at postEQ stage
+
+    void initBuffers(unsigned int blockSize, unsigned int overlapSize, unsigned int halfFftSize,
+            unsigned int samplingRate, DPBase &dpBase);
+    void computeBinStartStop(BandParams &bp, size_t binStart);
+private:
+    unsigned int mSamplingRate;
+    unsigned int mBlockSize;
+
+};
+
+class DPFrequency : public DPBase {
+public:
+    virtual size_t processSamples(const float *in, float *out, size_t samples);
+    virtual void reset();
+    void configure(size_t blockSize, size_t overlapSize, size_t samplingRate);
+    static size_t getMinBockSize();
+    static size_t getMaxBockSize();
+
+private:
+    void updateParameters(ChannelBuffer &cb, int channelIndex);
+    size_t processMono(ChannelBuffer &cb);
+    size_t processOneVector(FloatVec &output, FloatVec &input, ChannelBuffer &cb);
+
+    size_t mBlockSize;
+    size_t mHalfFFTSize;
+    size_t mOverlapSize;
+    size_t mSamplingRate;
+
+    std::vector<ChannelBuffer> mChannelBuffers;
+
+    //dsp
+    FloatVec mVWindow;  //window class.
+    Eigen::VectorXcf mComplexTemp;
+    Eigen::FFT<float> mFftServer;
+};
+
+} //namespace dp_fx
+
+#endif  // DPFREQUENCY_H_
diff --git a/media/libeffects/dynamicsproc/dsp/RDsp.h b/media/libeffects/dynamicsproc/dsp/RDsp.h
new file mode 100644
index 0000000..1048442
--- /dev/null
+++ b/media/libeffects/dynamicsproc/dsp/RDsp.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2018 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 RDSP_H
+#define RDSP_H
+
+#include <complex>
+#include <log/log.h>
+#include <vector>
+using FloatVec = std::vector<float>;
+using ComplexVec  = std::vector<std::complex<float>>;
+
+// =======
+// DSP window creation
+// =======
+
+#define TWOPI (M_PI * 2)
+
+enum rdsp_window_type {
+    RDSP_WINDOW_RECTANGULAR,
+    RDSP_WINDOW_TRIANGULAR,
+    RDSP_WINDOW_TRIANGULAR_FLAT_TOP,
+    RDSP_WINDOW_HAMMING,
+    RDSP_WINDOW_HAMMING_FLAT_TOP,
+    RDSP_WINDOW_HANNING,
+    RDSP_WINDOW_HANNING_FLAT_TOP,
+};
+
+template <typename T>
+static void fillRectangular(T &v) {
+    const size_t size = v.size();
+    for (size_t i = 0; i < size; i++) {
+        v[i] = 1.0;
+    }
+} //rectangular
+
+template <typename T>
+static void fillTriangular(T &v, size_t overlap) {
+    const size_t size = v.size();
+    //ramp up
+    size_t i = 0;
+    if (overlap > 0) {
+        for (; i < overlap; i++) {
+            v[i] = (2.0 * i + 1) / (2 * overlap);
+        }
+    }
+
+    //flat top
+    for (; i < size - overlap; i++) {
+        v[i] = 1.0;
+    }
+
+    //ramp down
+    if (overlap > 0) {
+        for (; i < size; i++) {
+            v[i] = (2.0 * (size - i) - 1) / (2 * overlap);
+        }
+    }
+} //triangular
+
+template <typename T>
+static void fillHamming(T &v, size_t overlap) {
+    const size_t size = v.size();
+    const size_t twoOverlap = 2 * overlap;
+    size_t i = 0;
+    if (overlap > 0) {
+        for (; i < overlap; i++) {
+            v[i] = 0.54 - 0.46 * cos(TWOPI * i /(twoOverlap - 1));
+        }
+    }
+
+    //flat top
+    for (; i < size - overlap; i++) {
+        v[i] = 1.0;
+    }
+
+    //ramp down
+    if (overlap > 0) {
+        for (; i < size; i++) {
+            int k = i - ((int)size - 2 * overlap);
+            v[i] = 0.54 - 0.46 * cos(TWOPI * k / (twoOverlap - 1));
+        }
+    }
+} //hamming
+
+template <typename T>
+static void fillHanning(T &v, size_t overlap) {
+    const size_t size = v.size();
+    const size_t twoOverlap = 2 * overlap;
+    //ramp up
+    size_t i = 0;
+    if (overlap > 0) {
+        for (; i < overlap; i++) {
+            v[i] = 0.5 * (1.0 - cos(TWOPI * i / (twoOverlap - 1)));
+        }
+    }
+
+    //flat top
+    for (; i < size - overlap; i++) {
+        v[i] = 1.0;
+    }
+
+    //ramp down
+    if (overlap > 0) {
+        for (; i < size; i++) {
+            int k = i - ((int)size - 2 * overlap);
+            v[i] = 0.5 * (1.0 - cos(TWOPI * k / (twoOverlap - 1)));
+        }
+    }
+}
+
+template <typename T>
+static void fill_window(T &v, int type, size_t size, size_t overlap) {
+    if (overlap > size / 2) {
+        overlap = size / 2;
+    }
+    v.resize(size);
+
+    switch (type) {
+    case RDSP_WINDOW_RECTANGULAR:
+        fillRectangular(v);
+        break;
+    case RDSP_WINDOW_TRIANGULAR:
+        fillTriangular(v, size / 2);
+        break;
+    case RDSP_WINDOW_TRIANGULAR_FLAT_TOP:
+        fillTriangular(v, overlap);
+        break;
+    case RDSP_WINDOW_HAMMING:
+        fillHamming(v, size / 2);
+        break;
+    case RDSP_WINDOW_HAMMING_FLAT_TOP:
+        fillHamming(v, overlap);
+        break;
+    case RDSP_WINDOW_HANNING:
+        fillHanning(v, size / 2);
+        break;
+    case RDSP_WINDOW_HANNING_FLAT_TOP:
+        fillHanning(v, overlap);
+        break;
+    default:
+        ALOGE("Error: unknown window type %d", type);
+    }
+}
+
+//};
+#endif //RDSP_H
diff --git a/media/libeffects/dynamicsproc/dsp/SHCircularBuffer.h b/media/libeffects/dynamicsproc/dsp/SHCircularBuffer.h
new file mode 100644
index 0000000..c139cd8
--- /dev/null
+++ b/media/libeffects/dynamicsproc/dsp/SHCircularBuffer.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2018 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 SHCIRCULARBUFFER_H
+#define SHCIRCULARBUFFER_H
+
+#include <log/log.h>
+#include <vector>
+
+template <class T>
+class SHCircularBuffer {
+
+public:
+    SHCircularBuffer() : mReadIndex(0), mWriteIndex(0), mReadAvailable(0) {
+    }
+
+    explicit SHCircularBuffer(size_t maxSize) {
+        resize(maxSize);
+    }
+    void resize(size_t maxSize) {
+        mBuffer.resize(maxSize);
+        mReadIndex = 0;
+        mWriteIndex = 0;
+        mReadAvailable = 0;
+    }
+    inline void write(T value) {
+        if (availableToWrite()) {
+            mBuffer[mWriteIndex++] = value;
+            if (mWriteIndex >= getSize()) {
+                mWriteIndex = 0;
+            }
+            mReadAvailable++;
+        } else {
+            ALOGE("Error: SHCircularBuffer no space to write. allocated size %zu ", getSize());
+        }
+    }
+    inline T read() {
+        T value = T();
+        if (availableToRead()) {
+            value = mBuffer[mReadIndex++];
+            if (mReadIndex >= getSize()) {
+                mReadIndex = 0;
+            }
+            mReadAvailable--;
+        } else {
+            ALOGW("Warning: SHCircularBuffer no data available to read. Default value returned");
+        }
+        return value;
+    }
+    inline size_t availableToRead() const {
+        return mReadAvailable;
+    }
+    inline size_t availableToWrite() const {
+        return getSize() - mReadAvailable;
+    }
+    inline size_t getSize() const {
+        return mBuffer.size();
+    }
+
+private:
+    std::vector<T> mBuffer;
+    size_t mReadIndex;
+    size_t mWriteIndex;
+    size_t mReadAvailable;
+};
+
+
+#endif //SHCIRCULARBUFFER_H
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index 0630285..e1c03f9 100644
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -1966,7 +1966,8 @@
 
     if (pContext->bEnabled == LVM_FALSE) {
         if (pContext->SamplesToExitCount > 0) {
-            pContext->SamplesToExitCount -= outBuffer->frameCount;
+            // signed - unsigned will trigger integer overflow if result becomes negative.
+            pContext->SamplesToExitCount -= (ssize_t)outBuffer->frameCount;
         } else {
             status = -ENODATA;
         }
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 3990e69..9d9ac8c 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -3,10 +3,12 @@
     vendor_available: true,
     export_include_dirs: ["include"],
     header_libs:[
+        "libgui_headers",
         "libstagefright_headers",
         "media_plugin_headers",
     ],
     export_header_lib_headers: [
+        "libgui_headers",
         "libstagefright_headers",
         "media_plugin_headers",
     ],
@@ -192,6 +194,14 @@
         export_aidl_headers: true,
     },
 
+    header_libs: [
+        "libstagefright_headers",
+    ],
+
+    export_header_lib_headers: [
+        "libstagefright_headers",
+    ],
+
     shared_libs: [
         "liblog",
         "libcutils",
diff --git a/media/libmedia/TypeConverter.cpp b/media/libmedia/TypeConverter.cpp
index 03700bf..a3db754 100644
--- a/media/libmedia/TypeConverter.cpp
+++ b/media/libmedia/TypeConverter.cpp
@@ -333,6 +333,7 @@
     MAKE_STRING_FROM_ENUM(AUDIO_USAGE_ASSISTANCE_SONIFICATION),
     MAKE_STRING_FROM_ENUM(AUDIO_USAGE_GAME),
     MAKE_STRING_FROM_ENUM(AUDIO_USAGE_VIRTUAL_SOURCE),
+    MAKE_STRING_FROM_ENUM(AUDIO_USAGE_ASSISTANT),
     TERMINATOR
 };
 
diff --git a/media/libmedia/include/media/DrmHal.h b/media/libmedia/include/media/DrmHal.h
index b0e1cc8..f267f76 100644
--- a/media/libmedia/include/media/DrmHal.h
+++ b/media/libmedia/include/media/DrmHal.h
@@ -182,6 +182,7 @@
     const Vector<sp<IDrmFactory>> mFactories;
     sp<IDrmPlugin> mPlugin;
     sp<drm::V1_1::IDrmPlugin> mPluginV1_1;
+    String8 mAppPackageName;
 
     // Mutable to allow modification within GetPropertyByteArray.
     mutable MediaDrmMetrics mMetrics;
diff --git a/media/libmedia/include/media/PluginMetricsReporting.h b/media/libmedia/include/media/PluginMetricsReporting.h
index 4a5a363..e00bd43 100644
--- a/media/libmedia/include/media/PluginMetricsReporting.h
+++ b/media/libmedia/include/media/PluginMetricsReporting.h
@@ -20,13 +20,13 @@
 
 #include <utils/Errors.h>
 #include <utils/String8.h>
-#include <utils/Vector.h>
 
 namespace android {
 
-status_t reportDrmPluginMetrics(const Vector<uint8_t>& serializedMetrics,
+status_t reportDrmPluginMetrics(const std::string& b64EncodedMetrics,
                                 const String8& vendorName,
-                                const String8& description);
+                                const String8& description,
+                                const String8& appPackageName);
 
 }  // namespace android
 
diff --git a/media/libmedia/include/media/mediametadataretriever.h b/media/libmedia/include/media/mediametadataretriever.h
index 3511253..b41da80 100644
--- a/media/libmedia/include/media/mediametadataretriever.h
+++ b/media/libmedia/include/media/mediametadataretriever.h
@@ -66,6 +66,8 @@
     METADATA_KEY_IMAGE_HEIGHT    = 30,
     METADATA_KEY_IMAGE_ROTATION  = 31,
     METADATA_KEY_VIDEO_FRAME_COUNT  = 32,
+    METADATA_KEY_EXIF_OFFSET     = 33,
+    METADATA_KEY_EXIF_LENGTH     = 34,
 
     // Add more here...
 };
diff --git a/media/libmedia/include/media/mediaplayer.h b/media/libmedia/include/media/mediaplayer.h
index c4dbf42..2335c5a 100644
--- a/media/libmedia/include/media/mediaplayer.h
+++ b/media/libmedia/include/media/mediaplayer.h
@@ -59,6 +59,7 @@
     MEDIA_SUBTITLE_DATA     = 201,
     MEDIA_META_DATA         = 202,
     MEDIA_DRM_INFO          = 210,
+    MEDIA_TIME_DISCONTINUITY = 211,
     MEDIA_AUDIO_ROUTING_CHANGED = 10000,
 };
 
diff --git a/media/libmedia/include/media/omx/1.0/Conversion.h b/media/libmedia/include/media/omx/1.0/Conversion.h
index 94f2e8d..3700a23 100644
--- a/media/libmedia/include/media/omx/1.0/Conversion.h
+++ b/media/libmedia/include/media/omx/1.0/Conversion.h
@@ -20,6 +20,7 @@
 #include <vector>
 #include <list>
 
+#include <cinttypes>
 #include <unistd.h>
 
 #include <hidl/MQDescriptor.h>
@@ -34,6 +35,8 @@
 #include <media/OMXFenceParcelable.h>
 #include <media/OMXBuffer.h>
 #include <media/hardware/VideoAPI.h>
+#include <media/stagefright/MediaErrors.h>
+#include <gui/IGraphicBufferProducer.h>
 
 #include <android/hardware/media/omx/1.0/types.h>
 #include <android/hardware/media/omx/1.0/IOmx.h>
@@ -197,26 +200,6 @@
 }
 
 /**
- * \brief Convert `Return<Status>` to `status_t`. This is for legacy binder
- * calls.
- *
- * \param[in] t The source `Return<Status>`.
- * \return The corresponding `status_t`.
- *
- * This function first check if \p t has a transport error. If it does, then the
- * return value is the transport error code. Otherwise, the return value is
- * converted from `Status` contained inside \p t.
- *
- * Note:
- * - This `Status` is omx-specific. It is defined in `types.hal`.
- * - The name of this function is not `convert`.
- */
-// convert: Status -> status_t
-inline status_t toStatusT(Return<Status> const& t) {
-    return t.isOk() ? static_cast<status_t>(static_cast<Status>(t)) : UNKNOWN_ERROR;
-}
-
-/**
  * \brief Convert `Return<void>` to `status_t`. This is for legacy binder calls.
  *
  * \param[in] t The source `Return<void>`.
@@ -235,7 +218,47 @@
  */
 // convert: Status -> status_t
 inline status_t toStatusT(Status const& t) {
-    return static_cast<status_t>(t);
+    switch (t) {
+    case Status::NO_ERROR:
+    case Status::NAME_NOT_FOUND:
+    case Status::WOULD_BLOCK:
+    case Status::NO_MEMORY:
+    case Status::ALREADY_EXISTS:
+    case Status::NO_INIT:
+    case Status::BAD_VALUE:
+    case Status::DEAD_OBJECT:
+    case Status::INVALID_OPERATION:
+    case Status::TIMED_OUT:
+    case Status::ERROR_UNSUPPORTED:
+    case Status::UNKNOWN_ERROR:
+    case Status::RELEASE_ALL_BUFFERS:
+        return static_cast<status_t>(t);
+    case Status::BUFFER_NEEDS_REALLOCATION:
+        return NOT_ENOUGH_DATA;
+    default:
+        ALOGW("Unrecognized status value: %" PRId32, static_cast<int32_t>(t));
+        return static_cast<status_t>(t);
+    }
+}
+
+/**
+ * \brief Convert `Return<Status>` to `status_t`. This is for legacy binder
+ * calls.
+ *
+ * \param[in] t The source `Return<Status>`.
+ * \return The corresponding `status_t`.
+ *
+ * This function first check if \p t has a transport error. If it does, then the
+ * return value is the transport error code. Otherwise, the return value is
+ * converted from `Status` contained inside \p t.
+ *
+ * Note:
+ * - This `Status` is omx-specific. It is defined in `types.hal`.
+ * - The name of this function is not `convert`.
+ */
+// convert: Status -> status_t
+inline status_t toStatusT(Return<Status> const& t) {
+    return t.isOk() ? toStatusT(static_cast<Status>(t)) : UNKNOWN_ERROR;
 }
 
 /**
@@ -246,7 +269,28 @@
  */
 // convert: status_t -> Status
 inline Status toStatus(status_t l) {
-    return static_cast<Status>(l);
+    switch (l) {
+    case NO_ERROR:
+    case NAME_NOT_FOUND:
+    case WOULD_BLOCK:
+    case NO_MEMORY:
+    case ALREADY_EXISTS:
+    case NO_INIT:
+    case BAD_VALUE:
+    case DEAD_OBJECT:
+    case INVALID_OPERATION:
+    case TIMED_OUT:
+    case ERROR_UNSUPPORTED:
+    case UNKNOWN_ERROR:
+    case IGraphicBufferProducer::RELEASE_ALL_BUFFERS:
+    case IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION:
+        return static_cast<Status>(l);
+    case NOT_ENOUGH_DATA:
+        return Status::BUFFER_NEEDS_REALLOCATION;
+    default:
+        ALOGW("Unrecognized status value: %" PRId32, static_cast<int32_t>(l));
+        return static_cast<Status>(l);
+    }
 }
 
 /**
diff --git a/media/libmediaplayer2/mediaplayer2.cpp b/media/libmediaplayer2/mediaplayer2.cpp
index 9e96a2b..e5567dc 100644
--- a/media/libmediaplayer2/mediaplayer2.cpp
+++ b/media/libmediaplayer2/mediaplayer2.cpp
@@ -903,7 +903,6 @@
     if (mPlayer == 0) {
         return INVALID_OPERATION;
     }
-    return mPlayer->getPlaybackSettings(rate);
     status_t ret = mPlayer->getPlaybackSettings(rate);
     if (ret == NO_ERROR) {
         ALOGV("getPlaybackSettings(%f, %f, %d, %d)",
@@ -925,7 +924,9 @@
 status_t MediaPlayer2::getSyncSettings(
         AVSyncSettings* sync /* nonnull */, float* videoFps /* nonnull */) {
     Mutex::Autolock _l(mLock);
-    if (mPlayer == 0) return INVALID_OPERATION;
+    if (mPlayer == 0) {
+        return INVALID_OPERATION;
+    }
     status_t ret = mPlayer->getSyncSettings(sync, videoFps);
     if (ret == NO_ERROR) {
         ALOGV("getSyncSettings(%u, %u, %f, %f)",
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index bd83c6d..0a1bdfe 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -220,8 +220,11 @@
     mUID = uid;
 }
 
-void NuPlayer::setDriver(const wp<NuPlayerDriver> &driver) {
+void NuPlayer::init(const wp<NuPlayerDriver> &driver) {
     mDriver = driver;
+
+    sp<AMessage> notify = new AMessage(kWhatMediaClockNotify, this);
+    mMediaClock->setNotificationMessage(notify);
 }
 
 void NuPlayer::setDataSourceAsync(const sp<IStreamSource> &source) {
@@ -1286,7 +1289,8 @@
                 ALOGV("Tear down audio with reason %d.", reason);
                 if (reason == Renderer::kDueToTimeout && !(mPaused && mOffloadAudio)) {
                     // TimeoutWhenPaused is only for offload mode.
-                    ALOGW("Receive a stale message for teardown.");
+                    ALOGW("Received a stale message for teardown, mPaused(%d), mOffloadAudio(%d)",
+                          mPaused, mOffloadAudio);
                     break;
                 }
                 int64_t positionUs;
@@ -1425,6 +1429,24 @@
             break;
         }
 
+        case kWhatMediaClockNotify:
+        {
+            ALOGV("kWhatMediaClockNotify");
+            int64_t anchorMediaUs, anchorRealUs;
+            float playbackRate;
+            CHECK(msg->findInt64("anchor-media-us", &anchorMediaUs));
+            CHECK(msg->findInt64("anchor-real-us", &anchorRealUs));
+            CHECK(msg->findFloat("playback-rate", &playbackRate));
+
+            Parcel in;
+            in.writeInt64(anchorMediaUs);
+            in.writeInt64(anchorRealUs);
+            in.writeFloat(playbackRate);
+
+            notifyListener(MEDIA_TIME_DISCONTINUITY, 0, 0, &in);
+            break;
+        }
+
         default:
             TRESPASS();
             break;
@@ -1768,6 +1790,8 @@
 
 void NuPlayer::restartAudio(
         int64_t currentPositionUs, bool forceNonOffload, bool needsToCreateAudioDecoder) {
+    ALOGD("restartAudio timeUs(%lld), dontOffload(%d), createDecoder(%d)",
+          (long long)currentPositionUs, forceNonOffload, needsToCreateAudioDecoder);
     if (mAudioDecoder != NULL) {
         mAudioDecoder->pause();
         mAudioDecoder.clear();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 9481234..3a7ef4e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -39,7 +39,7 @@
 
     void setUID(uid_t uid);
 
-    void setDriver(const wp<NuPlayerDriver> &driver);
+    void init(const wp<NuPlayerDriver> &driver);
 
     void setDataSourceAsync(const sp<IStreamSource> &source);
 
@@ -158,6 +158,7 @@
         kWhatSetBufferingSettings       = 'sBuS',
         kWhatPrepareDrm                 = 'pDrm',
         kWhatReleaseDrm                 = 'rDrm',
+        kWhatMediaClockNotify           = 'mckN',
     };
 
     wp<NuPlayerDriver> mDriver;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 731fdba..63c887b 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -104,7 +104,7 @@
 
     mLooper->registerHandler(mPlayer);
 
-    mPlayer->setDriver(this);
+    mPlayer->init(this);
 }
 
 NuPlayerDriver::~NuPlayerDriver() {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index cc7f688..a762e76 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -1617,14 +1617,7 @@
             // internal buffer before resuming playback.
             // FIXME: this is ignored after flush().
             mAudioSink->stop();
-            if (mPaused) {
-                // Race condition: if renderer is paused and audio sink is stopped,
-                // we need to make sure that the audio track buffer fully drains
-                // before delivering data.
-                // FIXME: remove this if we can detect if stop() is complete.
-                const int delayUs = 2 * 50 * 1000; // (2 full mixer thread cycles at 50ms)
-                mPauseDrainAudioAllowedUs = ALooper::GetNowUs() + delayUs;
-            } else {
+            if (!mPaused) {
                 mAudioSink->start();
             }
             mNumFramesWritten = 0;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index a8c6d15..3bbba49 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -3291,6 +3291,22 @@
         return err;
     }
 
+    if (compressionFormat == OMX_VIDEO_CodingHEVC) {
+        int32_t profile;
+        if (msg->findInt32("profile", &profile)) {
+            // verify if Main10 profile is supported at all, and fail
+            // immediately if it's not supported.
+            if (profile == OMX_VIDEO_HEVCProfileMain10 ||
+                profile == OMX_VIDEO_HEVCProfileMain10HDR10) {
+                err = verifySupportForProfileAndLevel(
+                        kPortIndexInput, profile, 0);
+                if (err != OK) {
+                    return err;
+                }
+            }
+        }
+    }
+
     if (compressionFormat == OMX_VIDEO_CodingVP9) {
         OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
         InitOMXParams(&params);
@@ -4059,7 +4075,7 @@
             return INVALID_OPERATION;
         }
 
-        err = verifySupportForProfileAndLevel(profile, level);
+        err = verifySupportForProfileAndLevel(kPortIndexOutput, profile, level);
 
         if (err != OK) {
             return err;
@@ -4131,7 +4147,7 @@
             return INVALID_OPERATION;
         }
 
-        err = verifySupportForProfileAndLevel(profile, level);
+        err = verifySupportForProfileAndLevel(kPortIndexOutput, profile, level);
 
         if (err != OK) {
             return err;
@@ -4266,7 +4282,7 @@
             return INVALID_OPERATION;
         }
 
-        err = verifySupportForProfileAndLevel(profile, level);
+        err = verifySupportForProfileAndLevel(kPortIndexOutput, profile, level);
 
         if (err != OK) {
             return err;
@@ -4280,7 +4296,7 @@
         // Use largest supported profile for AVC recording if profile is not specified.
         for (OMX_VIDEO_AVCPROFILETYPE profile : {
                 OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCProfileMain }) {
-            if (verifySupportForProfileAndLevel(profile, 0) == OK) {
+            if (verifySupportForProfileAndLevel(kPortIndexOutput, profile, 0) == OK) {
                 h264type.eProfile = profile;
                 break;
             }
@@ -4457,7 +4473,7 @@
             return INVALID_OPERATION;
         }
 
-        err = verifySupportForProfileAndLevel(profile, level);
+        err = verifySupportForProfileAndLevel(kPortIndexOutput, profile, level);
         if (err != OK) {
             return err;
         }
@@ -4602,10 +4618,10 @@
 }
 
 status_t ACodec::verifySupportForProfileAndLevel(
-        int32_t profile, int32_t level) {
+        OMX_U32 portIndex, int32_t profile, int32_t level) {
     OMX_VIDEO_PARAM_PROFILELEVELTYPE params;
     InitOMXParams(&params);
-    params.nPortIndex = kPortIndexOutput;
+    params.nPortIndex = portIndex;
 
     for (OMX_U32 index = 0; index <= kMaxIndicesToCheck; ++index) {
         params.nProfileIndex = index;
@@ -4906,8 +4922,8 @@
                             rect.nHeight = videoDef->nFrameHeight;
                         }
 
-                        if (rect.nLeft < 0 ||
-                            rect.nTop < 0 ||
+                        if (rect.nLeft < 0 || rect.nTop < 0 ||
+                            rect.nWidth == 0 || rect.nHeight == 0 ||
                             rect.nLeft + rect.nWidth > videoDef->nFrameWidth ||
                             rect.nTop + rect.nHeight > videoDef->nFrameHeight) {
                             ALOGE("Wrong cropped rect (%d, %d, %u, %u) vs. frame (%u, %u)",
diff --git a/media/libstagefright/HevcUtils.cpp b/media/libstagefright/HevcUtils.cpp
index 91deca5..f152a38 100644
--- a/media/libstagefright/HevcUtils.cpp
+++ b/media/libstagefright/HevcUtils.cpp
@@ -162,6 +162,8 @@
     reader.skipBits(1);
     // Skip vps_max_layers_minus_1
     reader.skipBits(6);
+    // Skip vps_max_sub_layers_minus1
+    reader.skipBits(3);
     // Skip vps_temporal_id_nesting_flags
     reader.skipBits(1);
     // Skip reserved
@@ -422,7 +424,7 @@
 
     uint8_t *header = hvcc;
     header[0] = 1;
-    header[1] = (kGeneralProfileSpace << 6) | (kGeneralTierFlag << 5) | kGeneralProfileIdc;
+    header[1] = (generalProfileSpace << 6) | (generalTierFlag << 5) | generalProfileIdc;
     header[2] = (compatibilityFlags >> 24) & 0xff;
     header[3] = (compatibilityFlags >> 16) & 0xff;
     header[4] = (compatibilityFlags >> 8) & 0xff;
diff --git a/media/libstagefright/MediaClock.cpp b/media/libstagefright/MediaClock.cpp
index 15843a2..41dbfd4 100644
--- a/media/libstagefright/MediaClock.cpp
+++ b/media/libstagefright/MediaClock.cpp
@@ -70,11 +70,9 @@
         it->mNotify->post();
         it = mTimers.erase(it);
     }
-    mAnchorTimeMediaUs = -1;
-    mAnchorTimeRealUs = -1;
     mMaxTimeMediaUs = INT64_MAX;
     mStartingTimeMediaUs = -1;
-    mPlaybackRate = 1.0;
+    updateAnchorTimesAndPlaybackRate_l(-1, -1, 1.0);
     ++mGeneration;
 }
 
@@ -85,8 +83,7 @@
 
 void MediaClock::clearAnchor() {
     Mutex::Autolock autoLock(mLock);
-    mAnchorTimeMediaUs = -1;
-    mAnchorTimeRealUs = -1;
+    updateAnchorTimesAndPlaybackRate_l(-1, -1, mPlaybackRate);
 }
 
 void MediaClock::updateAnchor(
@@ -118,8 +115,7 @@
             return;
         }
     }
-    mAnchorTimeRealUs = nowUs;
-    mAnchorTimeMediaUs = nowMediaUs;
+    updateAnchorTimesAndPlaybackRate_l(nowMediaUs, nowUs, mPlaybackRate);
 
     ++mGeneration;
     processTimers_l();
@@ -139,13 +135,12 @@
     }
 
     int64_t nowUs = ALooper::GetNowUs();
-    mAnchorTimeMediaUs += (nowUs - mAnchorTimeRealUs) * (double)mPlaybackRate;
-    if (mAnchorTimeMediaUs < 0) {
+    int64_t nowMediaUs = mAnchorTimeMediaUs + (nowUs - mAnchorTimeRealUs) * (double)mPlaybackRate;
+    if (nowMediaUs < 0) {
         ALOGW("setRate: anchor time should not be negative, set to 0.");
-        mAnchorTimeMediaUs = 0;
+        nowMediaUs = 0;
     }
-    mAnchorTimeRealUs = nowUs;
-    mPlaybackRate = rate;
+    updateAnchorTimesAndPlaybackRate_l(nowMediaUs, nowUs, rate);
 
     if (rate > 0.0) {
         ++mGeneration;
@@ -313,4 +308,31 @@
     msg->post(nextLapseRealUs);
 }
 
+void MediaClock::updateAnchorTimesAndPlaybackRate_l(int64_t anchorTimeMediaUs,
+        int64_t anchorTimeRealUs, float playbackRate) {
+    if (mAnchorTimeMediaUs != anchorTimeMediaUs
+            || mAnchorTimeRealUs != anchorTimeRealUs
+            || mPlaybackRate != playbackRate) {
+        mAnchorTimeMediaUs = anchorTimeMediaUs;
+        mAnchorTimeRealUs = anchorTimeRealUs;
+        mPlaybackRate = playbackRate;
+        notifyDiscontinuity_l();
+    }
+}
+
+void MediaClock::setNotificationMessage(const sp<AMessage> &msg) {
+    Mutex::Autolock autoLock(mLock);
+    mNotify = msg;
+}
+
+void MediaClock::notifyDiscontinuity_l() {
+    if (mNotify != nullptr) {
+        sp<AMessage> msg = mNotify->dup();
+        msg->setInt64("anchor-media-us", mAnchorTimeMediaUs);
+        msg->setInt64("anchor-real-us", mAnchorTimeRealUs);
+        msg->setFloat("playback-rate", mPlaybackRate);
+        msg->post();
+    }
+}
+
 }  // namespace android
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 5ad4c01..f25d1f1 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -19,6 +19,7 @@
 #include <utils/Log.h>
 
 #include <inttypes.h>
+#include <stdlib.h>
 
 #include "include/SecureBuffer.h"
 #include "include/SharedMemoryBuffer.h"
@@ -81,13 +82,28 @@
 
 // NB: These are not yet exposed as public Java API constants.
 static const char *kCodecCrypto = "android.media.mediacodec.crypto";   /* 0,1 */
-static const char *kCodecBytesIn = "android.media.mediacodec.bytesin";  /* 0..n */
 static const char *kCodecProfile = "android.media.mediacodec.profile";  /* 0..n */
 static const char *kCodecLevel = "android.media.mediacodec.level";  /* 0..n */
 static const char *kCodecMaxWidth = "android.media.mediacodec.maxwidth";  /* 0..n */
 static const char *kCodecMaxHeight = "android.media.mediacodec.maxheight";  /* 0..n */
 static const char *kCodecError = "android.media.mediacodec.errcode";
 static const char *kCodecErrorState = "android.media.mediacodec.errstate";
+static const char *kCodecLatencyMax = "android.media.mediacodec.latency.max";   /* in us */
+static const char *kCodecLatencyMin = "android.media.mediacodec.latency.min";   /* in us */
+static const char *kCodecLatencyAvg = "android.media.mediacodec.latency.avg";   /* in us */
+static const char *kCodecLatencyCount = "android.media.mediacodec.latency.n";
+static const char *kCodecLatencyHist = "android.media.mediacodec.latency.hist"; /* in us */
+static const char *kCodecLatencyUnknown = "android.media.mediacodec.latency.unknown";
+
+// the kCodecRecent* fields appear only in getMetrics() results
+static const char *kCodecRecentLatencyMax = "android.media.mediacodec.recent.max";      /* in us */
+static const char *kCodecRecentLatencyMin = "android.media.mediacodec.recent.min";      /* in us */
+static const char *kCodecRecentLatencyAvg = "android.media.mediacodec.recent.avg";      /* in us */
+static const char *kCodecRecentLatencyCount = "android.media.mediacodec.recent.n";
+static const char *kCodecRecentLatencyHist = "android.media.mediacodec.recent.hist";    /* in us */
+
+// XXX suppress until we get our representation right
+static bool kEmitHistogram = false;
 
 
 static int64_t getId(const sp<IResourceManagerClient> &client) {
@@ -506,12 +522,14 @@
       mDequeueOutputTimeoutGeneration(0),
       mDequeueOutputReplyID(0),
       mHaveInputSurface(false),
-      mHavePendingInputBuffers(false) {
+      mHavePendingInputBuffers(false),
+      mLatencyUnknown(0) {
     if (uid == kNoUid) {
         mUid = IPCThreadState::self()->getCallingUid();
     } else {
         mUid = uid;
     }
+
     initAnalyticsItem();
 }
 
@@ -523,16 +541,90 @@
 }
 
 void MediaCodec::initAnalyticsItem() {
-    CHECK(mAnalyticsItem == NULL);
-    // set up our new record, get a sessionID, put it into the in-progress list
-    mAnalyticsItem = new MediaAnalyticsItem(kCodecKeyName);
-    if (mAnalyticsItem != NULL) {
-        // don't record it yet; only at the end, when we have decided that we have
-        // data worth writing (e.g. .count() > 0)
+    if (mAnalyticsItem == NULL) {
+        mAnalyticsItem = new MediaAnalyticsItem(kCodecKeyName);
+    }
+
+    mLatencyHist.setup(kLatencyHistBuckets, kLatencyHistWidth, kLatencyHistFloor);
+
+    {
+        Mutex::Autolock al(mRecentLock);
+        for (int i = 0; i<kRecentLatencyFrames; i++) {
+            mRecentSamples[i] = kRecentSampleInvalid;
+        }
+        mRecentHead = 0;
+    }
+}
+
+void MediaCodec::updateAnalyticsItem() {
+    ALOGV("MediaCodec::updateAnalyticsItem");
+    if (mAnalyticsItem == NULL) {
+        return;
+    }
+
+    if (mLatencyHist.getCount() != 0 ) {
+        mAnalyticsItem->setInt64(kCodecLatencyMax, mLatencyHist.getMax());
+        mAnalyticsItem->setInt64(kCodecLatencyMin, mLatencyHist.getMin());
+        mAnalyticsItem->setInt64(kCodecLatencyAvg, mLatencyHist.getAvg());
+        mAnalyticsItem->setInt64(kCodecLatencyCount, mLatencyHist.getCount());
+
+        if (kEmitHistogram) {
+            // and the histogram itself
+            std::string hist = mLatencyHist.emit();
+            mAnalyticsItem->setCString(kCodecLatencyHist, hist.c_str());
+        }
+    }
+    if (mLatencyUnknown > 0) {
+        mAnalyticsItem->setInt64(kCodecLatencyUnknown, mLatencyUnknown);
+    }
+
+#if 0
+    // enable for short term, only while debugging
+    updateEphemeralAnalytics(mAnalyticsItem);
+#endif
+}
+
+void MediaCodec::updateEphemeralAnalytics(MediaAnalyticsItem *item) {
+    ALOGD("MediaCodec::updateEphemeralAnalytics()");
+
+    if (item == NULL) {
+        return;
+    }
+
+    Histogram recentHist;
+
+    // build an empty histogram
+    recentHist.setup(kLatencyHistBuckets, kLatencyHistWidth, kLatencyHistFloor);
+
+    // stuff it with the samples in the ring buffer
+    {
+        Mutex::Autolock al(mRecentLock);
+
+        for (int i=0; i<kRecentLatencyFrames; i++) {
+            if (mRecentSamples[i] != kRecentSampleInvalid) {
+                recentHist.insert(mRecentSamples[i]);
+            }
+        }
+    }
+
+
+    // spit the data (if any) into the supplied analytics record
+    if (recentHist.getCount()!= 0 ) {
+        item->setInt64(kCodecRecentLatencyMax, recentHist.getMax());
+        item->setInt64(kCodecRecentLatencyMin, recentHist.getMin());
+        item->setInt64(kCodecRecentLatencyAvg, recentHist.getAvg());
+        item->setInt64(kCodecRecentLatencyCount, recentHist.getCount());
+
+        if (kEmitHistogram) {
+            // and the histogram itself
+            std::string hist = recentHist.emit();
+            item->setCString(kCodecRecentLatencyHist, hist.c_str());
+        }
     }
 }
 
 void MediaCodec::flushAnalyticsItem() {
+    updateAnalyticsItem();
     if (mAnalyticsItem != NULL) {
         // don't log empty records
         if (mAnalyticsItem->count() > 0) {
@@ -543,6 +635,190 @@
     }
 }
 
+bool MediaCodec::Histogram::setup(int nbuckets, int64_t width, int64_t floor)
+{
+    if (nbuckets <= 0 || width <= 0) {
+        return false;
+    }
+
+    // get histogram buckets
+    if (nbuckets == mBucketCount && mBuckets != NULL) {
+        // reuse our existing buffer
+        memset(mBuckets, 0, sizeof(*mBuckets) * mBucketCount);
+    } else {
+        // get a new pre-zeroed buffer
+        int64_t *newbuckets = (int64_t *)calloc(nbuckets, sizeof (*mBuckets));
+        if (newbuckets == NULL) {
+            goto bad;
+        }
+        if (mBuckets != NULL)
+            free(mBuckets);
+        mBuckets = newbuckets;
+    }
+
+    mWidth = width;
+    mFloor = floor;
+    mCeiling = floor + nbuckets * width;
+    mBucketCount = nbuckets;
+
+    mMin = INT64_MAX;
+    mMax = INT64_MIN;
+    mSum = 0;
+    mCount = 0;
+    mBelow = mAbove = 0;
+
+    return true;
+
+  bad:
+    if (mBuckets != NULL) {
+        free(mBuckets);
+        mBuckets = NULL;
+    }
+
+    return false;
+}
+
+void MediaCodec::Histogram::insert(int64_t sample)
+{
+    // histogram is not set up
+    if (mBuckets == NULL) {
+        return;
+    }
+
+    mCount++;
+    mSum += sample;
+    if (mMin > sample) mMin = sample;
+    if (mMax < sample) mMax = sample;
+
+    if (sample < mFloor) {
+        mBelow++;
+    } else if (sample >= mCeiling) {
+        mAbove++;
+    } else {
+        int64_t slot = (sample - mFloor) / mWidth;
+        CHECK(slot < mBucketCount);
+        mBuckets[slot]++;
+    }
+    return;
+}
+
+std::string MediaCodec::Histogram::emit()
+{
+    std::string value;
+    char buffer[64];
+
+    // emits:  width,Below{bucket0,bucket1,...., bucketN}above
+    // unconfigured will emit: 0,0{}0
+    // XXX: is this best representation?
+    snprintf(buffer, sizeof(buffer), "%" PRId64 ",%" PRId64 ",%" PRId64 "{",
+             mFloor, mWidth, mBelow);
+    value = buffer;
+    for (int i = 0; i < mBucketCount; i++) {
+        if (i != 0) {
+            value = value + ",";
+        }
+        snprintf(buffer, sizeof(buffer), "%" PRId64, mBuckets[i]);
+        value = value + buffer;
+    }
+    snprintf(buffer, sizeof(buffer), "}%" PRId64 , mAbove);
+    value = value + buffer;
+    return value;
+}
+
+// when we send a buffer to the codec;
+void MediaCodec::statsBufferSent(int64_t presentationUs) {
+
+    // only enqueue if we have a legitimate time
+    if (presentationUs <= 0) {
+        ALOGV("presentation time: %" PRId64, presentationUs);
+        return;
+    }
+
+    const int64_t nowNs = systemTime(SYSTEM_TIME_MONOTONIC);
+    BufferFlightTiming_t startdata = { presentationUs, nowNs };
+
+    {
+        // mutex access to mBuffersInFlight and other stats
+        Mutex::Autolock al(mLatencyLock);
+
+
+        // XXX: we *could* make sure that the time is later than the end of queue
+        // as part of a consistency check...
+        mBuffersInFlight.push_back(startdata);
+    }
+}
+
+// when we get a buffer back from the codec
+void MediaCodec::statsBufferReceived(int64_t presentationUs) {
+
+    CHECK_NE(mState, UNINITIALIZED);
+
+    // mutex access to mBuffersInFlight and other stats
+    Mutex::Autolock al(mLatencyLock);
+
+    // how long this buffer took for the round trip through the codec
+    // NB: pipelining can/will make these times larger. e.g., if each packet
+    // is always 2 msec and we have 3 in flight at any given time, we're going to
+    // see "6 msec" as an answer.
+
+    // ignore stuff with no presentation time
+    if (presentationUs <= 0) {
+        ALOGD("-- returned buffer has bad timestamp %" PRId64 ", ignore it", presentationUs);
+        mLatencyUnknown++;
+        return;
+    }
+
+    BufferFlightTiming_t startdata;
+    bool valid = false;
+    while (mBuffersInFlight.size() > 0) {
+        startdata = *mBuffersInFlight.begin();
+        ALOGV("-- Looking at startdata. presentation %" PRId64 ", start %" PRId64,
+              startdata.presentationUs, startdata.startedNs);
+        if (startdata.presentationUs == presentationUs) {
+            // a match
+            ALOGV("-- match entry for %" PRId64 ", hits our frame of %" PRId64,
+                  startdata.presentationUs, presentationUs);
+            mBuffersInFlight.pop_front();
+            valid = true;
+            break;
+        } else if (startdata.presentationUs < presentationUs) {
+            // we must have missed the match for this, drop it and keep looking
+            ALOGV("--  drop entry for %" PRId64 ", before our frame of %" PRId64,
+                  startdata.presentationUs, presentationUs);
+            mBuffersInFlight.pop_front();
+            continue;
+        } else {
+            // head is after, so we don't have a frame for ourselves
+            ALOGV("--  found entry for %" PRId64 ", AFTER our frame of %" PRId64
+                  " we have nothing to pair with",
+                  startdata.presentationUs, presentationUs);
+            mLatencyUnknown++;
+            return;
+        }
+    }
+    if (!valid) {
+        ALOGV("-- empty queue, so ignore that.");
+        mLatencyUnknown++;
+        return;
+    }
+
+    // nowNs start our calculations
+    const int64_t nowNs = systemTime(SYSTEM_TIME_MONOTONIC);
+    int64_t latencyUs = (nowNs - startdata.startedNs + 500) / 1000;
+
+    mLatencyHist.insert(latencyUs);
+
+    // push into the recent samples
+    {
+        Mutex::Autolock al(mRecentLock);
+
+        if (mRecentHead >= kRecentLatencyFrames) {
+            mRecentHead = 0;
+        }
+        mRecentSamples[mRecentHead++] = latencyUs;
+    }
+}
+
 // static
 status_t MediaCodec::PostAndAwaitResponse(
         const sp<AMessage> &msg, sp<AMessage> *response) {
@@ -778,7 +1054,6 @@
             msg->setPointer("descrambler", descrambler.get());
         }
         if (mAnalyticsItem != NULL) {
-            // XXX: save indication that it's crypto in some way...
             mAnalyticsItem->setInt32(kCodecCrypto, 1);
         }
     } else if (mFlags & kFlagIsSecure) {
@@ -1245,11 +1520,14 @@
         return UNKNOWN_ERROR;
     }
 
-    // XXX: go get current values for whatever in-flight data we want
+    // update any in-flight data that's not carried within the record
+    updateAnalyticsItem();
 
     // send it back to the caller.
     reply = mAnalyticsItem->dup();
 
+    updateEphemeralAnalytics(reply);
+
     return OK;
 }
 
@@ -1435,6 +1713,8 @@
         int64_t timeUs;
         CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
 
+        statsBufferReceived(timeUs);
+
         response->setInt64("timeUs", timeUs);
 
         int32_t flags;
@@ -2919,9 +3199,8 @@
         Mutex::Autolock al(mBufferLock);
         info->mOwnedByClient = false;
         info->mData.clear();
-        if (mAnalyticsItem != NULL) {
-            mAnalyticsItem->addInt64(kCodecBytesIn, size);
-        }
+
+        statsBufferSent(timeUs);
     }
 
     return err;
@@ -3138,6 +3417,8 @@
 
         msg->setInt64("timeUs", timeUs);
 
+        statsBufferReceived(timeUs);
+
         int32_t flags;
         CHECK(buffer->meta()->findInt32("flags", &flags));
 
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index 179e0e6..5ae5644 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -438,6 +438,15 @@
         mMetaData.add(METADATA_KEY_CAPTURE_FRAMERATE, String8(tmp));
     }
 
+    int64_t exifOffset, exifSize;
+    if (meta->findInt64(kKeyExifOffset, &exifOffset)
+     && meta->findInt64(kKeyExifSize, &exifSize)) {
+        sprintf(tmp, "%lld", (long long)exifOffset);
+        mMetaData.add(METADATA_KEY_EXIF_OFFSET, String8(tmp));
+        sprintf(tmp, "%lld", (long long)exifSize);
+        mMetaData.add(METADATA_KEY_EXIF_LENGTH, String8(tmp));
+    }
+
     bool hasAudio = false;
     bool hasVideo = false;
     int32_t videoWidth = -1;
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 0c6e988..c61f4b5 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -303,6 +303,8 @@
     const static ALookup<uint8_t, OMX_VIDEO_HEVCPROFILETYPE> profiles {
         { 1, OMX_VIDEO_HEVCProfileMain   },
         { 2, OMX_VIDEO_HEVCProfileMain10 },
+        // use Main for Main Still Picture decoding
+        { 3, OMX_VIDEO_HEVCProfileMain },
     };
 
     // set profile & level if they are recognized
@@ -310,6 +312,7 @@
     OMX_VIDEO_HEVCLEVELTYPE codecLevel;
     if (!profiles.map(profile, &codecProfile)) {
         if (ptr[2] & 0x40 /* general compatibility flag 1 */) {
+            // Note that this case covers Main Still Picture too
             codecProfile = OMX_VIDEO_HEVCProfileMain;
         } else if (ptr[2] & 0x20 /* general compatibility flag 2 */) {
             codecProfile = OMX_VIDEO_HEVCProfileMain10;
diff --git a/media/libstagefright/codec2/1.0/Android.bp b/media/libstagefright/codec2/1.0/Android.bp
deleted file mode 100644
index 84d301a..0000000
--- a/media/libstagefright/codec2/1.0/Android.bp
+++ /dev/null
@@ -1,43 +0,0 @@
-cc_library_shared {
-    name: "android.hardware.media.c2@1.0-service-impl",
-    // relative_install_path: "hw",
-    // TODO: vendor: true,
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
-
-    srcs: [
-        //"ComponentAuth.cpp",
-        //"Component.cpp",
-        //"ComponentListener.cpp",
-        //"ComponentStore.cpp",
-        //"Configurable.cpp",
-        "InputSurface.cpp",
-        "InputSurfaceConnection.cpp",
-        //"types.cpp",
-    ],
-
-    include_dirs: [
-        "frameworks/av/media/libstagefright/codec2/include",
-        "frameworks/av/media/libstagefright/codec2/vndk/internal",
-    ],
-
-    shared_libs: [
-        "libcutils",
-	"libgui",
-        "libhidlbase",
-        "libhidltransport",
-        "liblog",
-        "libnativewindow",
-        "libstagefright_bufferqueue_helper",
-        "libstagefright_codec2_vndk",
-        "libui",
-        "libutils",
-
-        //"android.hardware.media.c2@1.0",
-        "android.hardware.graphics.bufferqueue@1.0",
-        "android.hidl.token@1.0-utils",
-    ],
-}
-
diff --git a/media/libstagefright/codec2/1.0/InputSurface.cpp b/media/libstagefright/codec2/1.0/InputSurface.cpp
deleted file mode 100644
index 977d410..0000000
--- a/media/libstagefright/codec2/1.0/InputSurface.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2018, 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 "InputSurface"
-#include <utils/Log.h>
-
-#include <C2AllocatorGralloc.h>
-#include <C2PlatformSupport.h>
-
-#include <media/stagefright/bqhelper/GraphicBufferSource.h>
-#include <media/stagefright/codec2/1.0/InputSurface.h>
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace c2 {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::GraphicBufferSource;
-
-sp<InputSurface> InputSurface::Create() {
-    sp<GraphicBufferSource> source = new GraphicBufferSource;
-    if (source->initCheck() != OK) {
-        return nullptr;
-    }
-    return new InputSurface(source->getIGraphicBufferProducer(), source);
-}
-
-InputSurface::InputSurface(
-        const sp<BGraphicBufferProducer> &base, const sp<GraphicBufferSource> &source)
-    : InputSurfaceBase(base),
-      mSource(source) {
-}
-
-sp<InputSurfaceConnection> InputSurface::connectToComponent(
-        const std::shared_ptr<C2Component> &comp) {
-    sp<InputSurfaceConnection> conn = new InputSurfaceConnection(mSource, comp);
-    if (!conn->init()) {
-        return nullptr;
-    }
-    return conn;
-}
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace c2
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
diff --git a/media/libstagefright/codec2/1.0/InputSurfaceConnection.cpp b/media/libstagefright/codec2/1.0/InputSurfaceConnection.cpp
deleted file mode 100644
index 693eeea..0000000
--- a/media/libstagefright/codec2/1.0/InputSurfaceConnection.cpp
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright 2018, 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 "InputSurfaceConnection"
-#include <utils/Log.h>
-
-#include <C2AllocatorGralloc.h>
-#include <C2BlockInternal.h>
-#include <C2PlatformSupport.h>
-
-#include <media/stagefright/codec2/1.0/InputSurfaceConnection.h>
-#include <system/window.h>
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace c2 {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::status_t;
-
-namespace {
-
-class Buffer2D : public C2Buffer {
-public:
-    explicit Buffer2D(C2ConstGraphicBlock block) : C2Buffer({ block }) {}
-};
-
-}  // namespace
-
-constexpr int32_t kBufferCount = 16;
-
-class InputSurfaceConnection::Impl : public ComponentWrapper {
-public:
-    Impl(const sp<GraphicBufferSource> &source, const std::shared_ptr<C2Component> &comp)
-        : mSource(source), mComp(comp) {
-    }
-
-    virtual ~Impl() = default;
-
-    bool init() {
-        sp<GraphicBufferSource> source = mSource.promote();
-        if (source == nullptr) {
-            return false;
-        }
-        status_t err = source->initCheck();
-        if (err != OK) {
-            ALOGE("Impl::init: GBS init failed: %d", err);
-            return false;
-        }
-        // TODO: proper color aspect & dataspace
-        android_dataspace dataSpace = HAL_DATASPACE_BT709;
-        // TODO: read settings properly from the interface
-        err = source->configure(
-                this, dataSpace, kBufferCount, 1080, 1920, GRALLOC_USAGE_SW_READ_OFTEN);
-        if (err != OK) {
-            ALOGE("Impl::init: GBS configure failed: %d", err);
-            return false;
-        }
-        for (int32_t i = 0; i < kBufferCount; ++i) {
-            if (!source->onInputBufferAdded(i).isOk()) {
-                ALOGE("Impl::init: population GBS slots failed");
-                return false;
-            }
-        }
-        if (!source->start().isOk()) {
-            ALOGE("Impl::init: GBS start failed");
-            return false;
-        }
-        c2_status_t c2err = GetCodec2PlatformAllocatorStore()->fetchAllocator(
-                C2AllocatorStore::PLATFORM_START + 1,  // GRALLOC
-                &mAllocator);
-        if (c2err != OK) {
-            ALOGE("Impl::init: failed to fetch gralloc allocator: %d", c2err);
-            return false;
-        }
-        return true;
-    }
-
-    // From ComponentWrapper
-    status_t submitBuffer(
-            int32_t bufferId, const sp<GraphicBuffer> &buffer,
-            int64_t timestamp, int fenceFd) override {
-        ALOGV("Impl::submitBuffer bufferId = %d", bufferId);
-        // TODO: Use fd to construct fence
-        (void)fenceFd;
-
-        std::shared_ptr<C2Component> comp = mComp.lock();
-        if (!comp) {
-            return NO_INIT;
-        }
-
-        std::shared_ptr<C2GraphicAllocation> alloc;
-        C2Handle *handle = WrapNativeCodec2GrallocHandle(
-                buffer->handle, buffer->width, buffer->height,
-                buffer->format, buffer->usage, buffer->stride);
-        c2_status_t err = mAllocator->priorGraphicAllocation(handle, &alloc);
-        if (err != OK) {
-            return UNKNOWN_ERROR;
-        }
-        std::shared_ptr<C2GraphicBlock> block = _C2BlockFactory::CreateGraphicBlock(alloc);
-
-        std::unique_ptr<C2Work> work(new C2Work);
-        work->input.flags = (C2FrameData::flags_t)0;
-        work->input.ordinal.timestamp = timestamp;
-        work->input.ordinal.frameIndex = mFrameIndex++;
-        work->input.buffers.clear();
-        std::shared_ptr<C2Buffer> c2Buffer(
-                // TODO: fence
-                new Buffer2D(block->share(
-                        C2Rect(block->width(), block->height()), ::C2Fence())),
-                [handle, bufferId, src = mSource](C2Buffer *ptr) {
-                    delete ptr;
-                    native_handle_delete(handle);
-                    sp<GraphicBufferSource> source = src.promote();
-                    if (source != nullptr) {
-                        // TODO: fence
-                        (void)source->onInputBufferEmptied(bufferId, -1);
-                    }
-                });
-        work->input.buffers.push_back(c2Buffer);
-        work->worklets.clear();
-        work->worklets.emplace_back(new C2Worklet);
-        std::list<std::unique_ptr<C2Work>> items;
-        items.push_back(std::move(work));
-
-        err = comp->queue_nb(&items);
-        if (err != C2_OK) {
-            return UNKNOWN_ERROR;
-        }
-
-        mLastTimestamp = timestamp;
-
-        return OK;
-    }
-
-    status_t submitEos(int32_t) override {
-        std::shared_ptr<C2Component> comp = mComp.lock();
-        if (!comp) {
-            return NO_INIT;
-        }
-
-        std::unique_ptr<C2Work> work(new C2Work);
-        work->input.flags = C2FrameData::FLAG_END_OF_STREAM;
-        work->input.ordinal.timestamp = mLastTimestamp;
-        work->input.ordinal.frameIndex = mFrameIndex++;
-        work->input.buffers.clear();
-        work->worklets.clear();
-        work->worklets.emplace_back(new C2Worklet);
-        std::list<std::unique_ptr<C2Work>> items;
-        items.push_back(std::move(work));
-
-        c2_status_t err = comp->queue_nb(&items);
-        return (err == C2_OK) ? OK : UNKNOWN_ERROR;
-    }
-
-    void dispatchDataSpaceChanged(
-            int32_t dataSpace, int32_t aspects, int32_t pixelFormat) override {
-        // TODO
-        (void)dataSpace;
-        (void)aspects;
-        (void)pixelFormat;
-    }
-
-private:
-    wp<GraphicBufferSource> mSource;
-    std::weak_ptr<C2Component> mComp;
-
-    // Needed for ComponentWrapper implementation
-    int64_t mLastTimestamp;
-    std::shared_ptr<C2Allocator> mAllocator;
-    std::atomic_uint64_t mFrameIndex;
-};
-
-InputSurfaceConnection::InputSurfaceConnection(
-        const sp<GraphicBufferSource> &source,
-        const std::shared_ptr<C2Component> &comp)
-    : mSource(source),
-      mImpl(new Impl(source, comp)) {
-}
-
-InputSurfaceConnection::~InputSurfaceConnection() {
-    disconnect();
-}
-
-bool InputSurfaceConnection::init() {
-    if (mImpl == nullptr) {
-        return false;
-    }
-    return mImpl->init();
-}
-
-void InputSurfaceConnection::disconnect() {
-    ALOGV("disconnect");
-    if (mSource != nullptr) {
-        (void)mSource->stop();
-        (void)mSource->release();
-    }
-    mImpl.clear();
-    mSource.clear();
-    ALOGV("disconnected");
-}
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace c2
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
diff --git a/media/libstagefright/codec2/Android.bp b/media/libstagefright/codec2/Android.bp
deleted file mode 100644
index 1c32953..0000000
--- a/media/libstagefright/codec2/Android.bp
+++ /dev/null
@@ -1,93 +0,0 @@
-cc_library_shared {
-    name: "libstagefright_codec2",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
-
-    tags: [
-        "optional",
-    ],
-
-    srcs: ["C2.cpp"],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-    ],
-
-    include_dirs: [
-        "frameworks/av/media/libstagefright/codec2/include",
-        "frameworks/native/include/media/hardware",
-    ],
-
-    export_include_dirs: [
-        "include",
-    ],
-
-    header_libs: [
-        "libhardware_headers",
-        "libutils_headers",
-    ],
-
-    export_header_lib_headers: [
-        "libhardware_headers",
-        "libutils_headers",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-        cfi: false, // true,
-        diag: {
-            cfi: false, // true,
-        },
-    },
-
-    ldflags: ["-Wl,-Bsymbolic"],
-}
-
-cc_library_shared {
-    name: "libstagefright_simple_c2component",
-    vendor_available: true,
-
-    tags: [
-        "optional",
-    ],
-
-    srcs: [
-        "SimpleC2Component.cpp",
-        "SimpleC2Interface.cpp",
-    ],
-
-    include_dirs: [
-    ],
-
-    shared_libs: [
-        "liblog",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_foundation",
-	"libutils",
-    ],
-
-    sanitize: {
-        misc_undefined: [
-            "unsigned-integer-overflow",
-            "signed-integer-overflow",
-        ],
-        cfi: true,
-        diag: {
-            cfi: true,
-        },
-    },
-
-    ldflags: ["-Wl,-Bsymbolic"],
-}
-
-subdirs = [
-    "tests",
-    "vndk",
-]
diff --git a/media/libstagefright/codec2/Android.mk b/media/libstagefright/codec2/Android.mk
deleted file mode 100644
index 459608f..0000000
--- a/media/libstagefright/codec2/Android.mk
+++ /dev/null
@@ -1,42 +0,0 @@
-# =============================================================================
-# DOCUMENTATION GENERATION
-# =============================================================================
-C2_ROOT := $(call my-dir)
-
-C2_DOCS_ROOT := $(OUT_DIR)/target/common/docs/codec2
-
-C2_OUT_TEMP := $(PRODUCT_OUT)/gen/ETC/Codec2-docs_intermediates
-
-C2_DOXY := $(or $(shell command -v doxygen),\
-		$(shell command -v /Applications/Doxygen.app/Contents/Resources/doxygen))
-
-check-doxygen:
-ifndef C2_DOXY
-	$(error 'doxygen is not available')
-endif
-
-$(C2_OUT_TEMP)/doxy-api.config: $(C2_ROOT)/docs/doxygen.config
-	# only document include directory, no internal sections
-	sed 's/\(^INPUT *=.*\)/\1include\//; \
-	s/\(^INTERNAL_DOCS *= *\).*/\1NO/; \
-	s/\(^ENABLED_SECTIONS *=.*\)INTERNAL\(.*\).*/\1\2/; \
-	s:\(^OUTPUT_DIRECTORY *= \)out:\1'$(OUT_DIR)':;' \
-		$(C2_ROOT)/docs/doxygen.config > $@
-
-$(C2_OUT_TEMP)/doxy-internal.config: $(C2_ROOT)/docs/doxygen.config
-	sed 's:\(^OUTPUT_DIRECTORY *= \)out\(.*\)api:\1'$(OUT_DIR)'\2internal:;' \
-		$(C2_ROOT)/docs/doxygen.config > $@
-
-docs-api: $(C2_OUT_TEMP)/doxy-api.config check-doxygen
-	echo API docs are building in $(C2_DOCS_ROOT)/api
-	rm -rf $(C2_DOCS_ROOT)/api
-	mkdir -p $(C2_DOCS_ROOT)/api
-	$(C2_DOXY) $(C2_OUT_TEMP)/doxy-api.config
-
-docs-internal: $(C2_OUT_TEMP)/doxy-internal.config check-doxygen
-	echo Internal docs are building in $(C2_DOCS_ROOT)/internal
-	rm -rf $(C2_DOCS_ROOT)/internal
-	mkdir -p $(C2_DOCS_ROOT)/internal
-	$(C2_DOXY) $(C2_OUT_TEMP)/doxy-internal.config
-
-docs-all: docs-api docs-internal
\ No newline at end of file
diff --git a/media/libstagefright/codec2/C2.cpp b/media/libstagefright/codec2/C2.cpp
deleted file mode 100644
index 359d4e5..0000000
--- a/media/libstagefright/codec2/C2.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <C2.h>
-#include <C2Buffer.h>
-#include <C2Component.h>
-#include <C2Config.h>
-#include <C2Param.h>
-#include <C2ParamDef.h>
-#include <C2Work.h>
-
-/**
- * There is nothing here yet. This library is built to see what symbols and methods get
- * defined as part of the API include files.
- *
- * Going forward, the Codec2 library will contain utility methods that are useful for
- * Codec2 clients.
- */
-
-
diff --git a/media/libstagefright/codec2/SimpleC2Component.cpp b/media/libstagefright/codec2/SimpleC2Component.cpp
deleted file mode 100644
index f3d95f6..0000000
--- a/media/libstagefright/codec2/SimpleC2Component.cpp
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * Copyright (C) 2017 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 "SimpleC2Component"
-#include <media/stagefright/foundation/ADebug.h>
-
-#include <inttypes.h>
-
-#include <C2PlatformSupport.h>
-#include <SimpleC2Component.h>
-
-namespace android {
-
-std::unique_ptr<C2Work> SimpleC2Component::WorkQueue::pop_front() {
-    std::unique_ptr<C2Work> work = std::move(mQueue.front().work);
-    mQueue.pop_front();
-    return work;
-}
-
-void SimpleC2Component::WorkQueue::push_back(std::unique_ptr<C2Work> work) {
-    mQueue.push_back({ std::move(work), NO_DRAIN });
-}
-
-bool SimpleC2Component::WorkQueue::empty() const {
-    return mQueue.empty();
-}
-
-void SimpleC2Component::WorkQueue::clear() {
-    mQueue.clear();
-}
-
-uint32_t SimpleC2Component::WorkQueue::drainMode() const {
-    return mQueue.front().drainMode;
-}
-
-void SimpleC2Component::WorkQueue::markDrain(uint32_t drainMode) {
-    mQueue.push_back({ nullptr, drainMode });
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
-SimpleC2Component::SimpleC2Component(
-        const std::shared_ptr<C2ComponentInterface> &intf)
-    : mIntf(intf) {
-}
-
-c2_status_t SimpleC2Component::setListener_vb(
-        const std::shared_ptr<C2Component::Listener> &listener, c2_blocking_t mayBlock) {
-    Mutexed<ExecState>::Locked state(mExecState);
-    if (state->mState == RUNNING) {
-        if (listener) {
-            return C2_BAD_STATE;
-        } else if (!mayBlock) {
-            return C2_BLOCKING;
-        }
-    }
-    state->mListener = listener;
-    // TODO: wait for listener change to have taken place before returning
-    // (e.g. if there is an ongoing listener callback)
-    return C2_OK;
-}
-
-c2_status_t SimpleC2Component::queue_nb(std::list<std::unique_ptr<C2Work>> * const items) {
-    {
-        Mutexed<ExecState>::Locked state(mExecState);
-        if (state->mState != RUNNING) {
-            return C2_BAD_STATE;
-        }
-    }
-    {
-        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
-        while (!items->empty()) {
-            queue->push_back(std::move(items->front()));
-            items->pop_front();
-        }
-        queue->mCondition.broadcast();
-    }
-    return C2_OK;
-}
-
-c2_status_t SimpleC2Component::announce_nb(const std::vector<C2WorkOutline> &items) {
-    (void)items;
-    return C2_OMITTED;
-}
-
-c2_status_t SimpleC2Component::flush_sm(
-        flush_mode_t flushMode, std::list<std::unique_ptr<C2Work>>* const flushedWork) {
-    (void)flushMode;
-    {
-        Mutexed<ExecState>::Locked state(mExecState);
-        if (state->mState != RUNNING) {
-            return C2_BAD_STATE;
-        }
-    }
-    {
-        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
-        queue->incGeneration();
-        // TODO: queue->splicedBy(flushedWork, flushedWork->end());
-        while (!queue->empty()) {
-            std::unique_ptr<C2Work> work = queue->pop_front();
-            if (work) {
-                flushedWork->push_back(std::move(work));
-            }
-        }
-    }
-    {
-        Mutexed<PendingWork>::Locked pending(mPendingWork);
-        while (!pending->empty()) {
-            flushedWork->push_back(std::move(pending->begin()->second));
-            pending->erase(pending->begin());
-        }
-    }
-
-    return C2_OK;
-}
-
-c2_status_t SimpleC2Component::drain_nb(drain_mode_t drainMode) {
-    if (drainMode == DRAIN_CHAIN) {
-        return C2_OMITTED;
-    }
-    {
-        Mutexed<ExecState>::Locked state(mExecState);
-        if (state->mState != RUNNING) {
-            return C2_BAD_STATE;
-        }
-    }
-    {
-        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
-        queue->markDrain(drainMode);
-        queue->mCondition.broadcast();
-    }
-
-    return C2_OK;
-}
-
-c2_status_t SimpleC2Component::start() {
-    Mutexed<ExecState>::Locked state(mExecState);
-    if (state->mState == RUNNING) {
-        return C2_BAD_STATE;
-    }
-    bool needsInit = (state->mState == UNINITIALIZED);
-    if (needsInit) {
-        state.unlock();
-        c2_status_t err = onInit();
-        if (err != C2_OK) {
-            return err;
-        }
-        state.lock();
-    }
-    if (!state->mThread.joinable()) {
-        mExitRequested = false;
-        {
-            Mutexed<ExitMonitor>::Locked monitor(mExitMonitor);
-            monitor->mExited = false;
-        }
-        state->mThread = std::thread(
-                [](std::weak_ptr<SimpleC2Component> wp) {
-                    while (true) {
-                        std::shared_ptr<SimpleC2Component> thiz = wp.lock();
-                        if (!thiz) {
-                            return;
-                        }
-                        if (thiz->exitRequested()) {
-                            ALOGV("stop processing");
-                            thiz->signalExit();
-                            return;
-                        }
-                        thiz->processQueue();
-                    }
-                },
-                shared_from_this());
-    }
-    state->mState = RUNNING;
-    return C2_OK;
-}
-
-void SimpleC2Component::signalExit() {
-    Mutexed<ExitMonitor>::Locked monitor(mExitMonitor);
-    monitor->mExited = true;
-    monitor->mCondition.broadcast();
-}
-
-void SimpleC2Component::requestExitAndWait(std::function<void()> job) {
-    {
-        Mutexed<ExecState>::Locked state(mExecState);
-        if (!state->mThread.joinable()) {
-            return;
-        }
-    }
-    mExitRequested = true;
-    {
-        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
-        queue->mCondition.broadcast();
-    }
-    // TODO: timeout?
-    {
-        Mutexed<ExitMonitor>::Locked monitor(mExitMonitor);
-        while (!monitor->mExited) {
-            monitor.waitForCondition(monitor->mCondition);
-        }
-        job();
-    }
-    Mutexed<ExecState>::Locked state(mExecState);
-    if (state->mThread.joinable()) {
-        ALOGV("joining the processing thread");
-        state->mThread.join();
-        ALOGV("joined the processing thread");
-    }
-}
-
-c2_status_t SimpleC2Component::stop() {
-    ALOGV("stop");
-    {
-        Mutexed<ExecState>::Locked state(mExecState);
-        if (state->mState != RUNNING) {
-            return C2_BAD_STATE;
-        }
-        state->mState = STOPPED;
-    }
-    {
-        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
-        queue->clear();
-    }
-    {
-        Mutexed<PendingWork>::Locked pending(mPendingWork);
-        pending->clear();
-    }
-    c2_status_t err;
-    requestExitAndWait([this, &err]{ err = onStop(); });
-    if (err != C2_OK) {
-        return err;
-    }
-    return C2_OK;
-}
-
-c2_status_t SimpleC2Component::reset() {
-    ALOGV("reset");
-    {
-        Mutexed<ExecState>::Locked state(mExecState);
-        state->mState = UNINITIALIZED;
-    }
-    {
-        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
-        queue->clear();
-    }
-    {
-        Mutexed<PendingWork>::Locked pending(mPendingWork);
-        pending->clear();
-    }
-    requestExitAndWait([this]{ onReset(); });
-    return C2_OK;
-}
-
-c2_status_t SimpleC2Component::release() {
-    ALOGV("release");
-    requestExitAndWait([this]{ onRelease(); });
-    return C2_OK;
-}
-
-std::shared_ptr<C2ComponentInterface> SimpleC2Component::intf() {
-    return mIntf;
-}
-
-namespace {
-
-std::list<std::unique_ptr<C2Work>> vec(std::unique_ptr<C2Work> &work) {
-    std::list<std::unique_ptr<C2Work>> ret;
-    ret.push_back(std::move(work));
-    return ret;
-}
-
-}  // namespace
-
-void SimpleC2Component::finish(
-        uint64_t frameIndex, std::function<void(const std::unique_ptr<C2Work> &)> fillWork) {
-    std::unique_ptr<C2Work> work;
-    {
-        Mutexed<PendingWork>::Locked pending(mPendingWork);
-        if (pending->count(frameIndex) == 0) {
-            ALOGW("unknown frame index: %" PRIu64, frameIndex);
-            return;
-        }
-        work = std::move(pending->at(frameIndex));
-        pending->erase(frameIndex);
-    }
-    if (work) {
-        fillWork(work);
-        Mutexed<ExecState>::Locked state(mExecState);
-        state->mListener->onWorkDone_nb(shared_from_this(), vec(work));
-        ALOGV("returning pending work");
-    }
-}
-
-void SimpleC2Component::processQueue() {
-    std::unique_ptr<C2Work> work;
-    uint64_t generation;
-    int32_t drainMode;
-    bool isFlushPending = false;
-    {
-        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
-        nsecs_t deadline = systemTime() + ms2ns(250);
-        while (queue->empty()) {
-            if (exitRequested()) {
-                return;
-            }
-            nsecs_t now = systemTime();
-            if (now >= deadline) {
-                return;
-            }
-            status_t err = queue.waitForConditionRelative(queue->mCondition, deadline - now);
-            if (err == TIMED_OUT) {
-                return;
-            }
-        }
-
-        generation = queue->generation();
-        drainMode = queue->drainMode();
-        isFlushPending = queue->popPendingFlush();
-        work = queue->pop_front();
-    }
-    if (isFlushPending) {
-        ALOGV("processing pending flush");
-        c2_status_t err = onFlush_sm();
-        if (err != C2_OK) {
-            ALOGD("flush err: %d", err);
-            // TODO: error
-        }
-    }
-
-    if (!mOutputBlockPool) {
-        c2_status_t err = [this] {
-            // TODO: don't use query_vb
-            C2StreamFormatConfig::output outputFormat(0u);
-            c2_status_t err = intf()->query_vb(
-                    { &outputFormat },
-                    {},
-                    C2_DONT_BLOCK,
-                    nullptr);
-            if (err != C2_OK) {
-                return err;
-            }
-            if (outputFormat.value == C2FormatVideo) {
-                err = GetCodec2BlockPool(
-                        C2BlockPool::BASIC_GRAPHIC,
-                        shared_from_this(), &mOutputBlockPool);
-            } else {
-                err = CreateCodec2BlockPool(
-                        C2PlatformAllocatorStore::ION,
-                        shared_from_this(), &mOutputBlockPool);
-            }
-            if (err != C2_OK) {
-                return err;
-            }
-            return C2_OK;
-        }();
-        if (err != C2_OK) {
-            Mutexed<ExecState>::Locked state(mExecState);
-            state->mListener->onError_nb(shared_from_this(), err);
-            return;
-        }
-    }
-
-    if (!work) {
-        c2_status_t err = drain(drainMode, mOutputBlockPool);
-        if (err != C2_OK) {
-            Mutexed<ExecState>::Locked state(mExecState);
-            state->mListener->onError_nb(shared_from_this(), err);
-        }
-        return;
-    }
-
-    process(work, mOutputBlockPool);
-    ALOGV("processed frame #%" PRIu64, work->input.ordinal.frameIndex.peeku());
-    {
-        Mutexed<WorkQueue>::Locked queue(mWorkQueue);
-        if (queue->generation() != generation) {
-            ALOGD("work form old generation: was %" PRIu64 " now %" PRIu64,
-                    queue->generation(), generation);
-            work->result = C2_NOT_FOUND;
-            queue.unlock();
-            {
-                Mutexed<ExecState>::Locked state(mExecState);
-                state->mListener->onWorkDone_nb(shared_from_this(), vec(work));
-            }
-            queue.lock();
-            return;
-        }
-    }
-    if (work->workletsProcessed != 0u) {
-        Mutexed<ExecState>::Locked state(mExecState);
-        ALOGV("returning this work");
-        state->mListener->onWorkDone_nb(shared_from_this(), vec(work));
-    } else {
-        ALOGV("queue pending work");
-        std::unique_ptr<C2Work> unexpected;
-        {
-            Mutexed<PendingWork>::Locked pending(mPendingWork);
-            uint64_t frameIndex = work->input.ordinal.frameIndex.peeku();
-            if (pending->count(frameIndex) != 0) {
-                unexpected = std::move(pending->at(frameIndex));
-                pending->erase(frameIndex);
-            }
-            (void)pending->insert({ frameIndex, std::move(work) });
-        }
-        if (unexpected) {
-            ALOGD("unexpected pending work");
-            unexpected->result = C2_CORRUPTED;
-            Mutexed<ExecState>::Locked state(mExecState);
-            state->mListener->onWorkDone_nb(shared_from_this(), vec(unexpected));
-        }
-    }
-}
-
-std::shared_ptr<C2Buffer> SimpleC2Component::createLinearBuffer(
-        const std::shared_ptr<C2LinearBlock> &block) {
-    return createLinearBuffer(block, block->offset(), block->size());
-}
-
-std::shared_ptr<C2Buffer> SimpleC2Component::createLinearBuffer(
-        const std::shared_ptr<C2LinearBlock> &block, size_t offset, size_t size) {
-    return C2Buffer::CreateLinearBuffer(block->share(offset, size, ::C2Fence()));
-}
-
-std::shared_ptr<C2Buffer> SimpleC2Component::createGraphicBuffer(
-        const std::shared_ptr<C2GraphicBlock> &block) {
-    return createGraphicBuffer(block, C2Rect(0, 0, block->width(), block->height()));
-}
-
-std::shared_ptr<C2Buffer> SimpleC2Component::createGraphicBuffer(
-        const std::shared_ptr<C2GraphicBlock> &block, const C2Rect &crop) {
-    return C2Buffer::CreateGraphicBuffer(block->share(crop, ::C2Fence()));
-}
-
-} // namespace android
diff --git a/media/libstagefright/codec2/SimpleC2Interface.cpp b/media/libstagefright/codec2/SimpleC2Interface.cpp
deleted file mode 100644
index d159426..0000000
--- a/media/libstagefright/codec2/SimpleC2Interface.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2017 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 "SimpleC2Interface"
-#include <utils/Log.h>
-
-#include <SimpleC2Interface.h>
-
-namespace android {
-
-c2_status_t SimpleC2Interface::query_vb(
-        const std::vector<C2Param*> &stackParams,
-        const std::vector<C2Param::Index> &heapParamIndices,
-        c2_blocking_t mayBlock,
-        std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
-    (void)mayBlock;
-
-    for (C2Param* const param : stackParams) {
-        if (param->coreIndex() != C2StreamFormatConfig::CORE_INDEX
-                || !param->forStream()
-                || param->stream() != 0u) {
-            param->invalidate();
-            continue;
-        }
-        if (param->forInput()) {
-            param->updateFrom(mInputFormat);
-        } else {
-            param->updateFrom(mOutputFormat);
-        }
-    }
-    if (heapParams) {
-        heapParams->clear();
-        for (const auto &index : heapParamIndices) {
-            switch (index.type()) {
-                case C2StreamFormatConfig::input::PARAM_TYPE:
-                    if (index.stream() == 0u) {
-                        heapParams->push_back(C2Param::Copy(mInputFormat));
-                    } else {
-                        heapParams->push_back(nullptr);
-                    }
-                    break;
-                case C2StreamFormatConfig::output::PARAM_TYPE:
-                    if (index.stream() == 0u) {
-                        heapParams->push_back(C2Param::Copy(mOutputFormat));
-                    } else {
-                        heapParams->push_back(nullptr);
-                    }
-                    break;
-                case C2PortMimeConfig::input::PARAM_TYPE:
-                    if (mInputMediaType) {
-                        heapParams->push_back(C2Param::Copy(*mInputMediaType));
-                    } else {
-                        heapParams->push_back(nullptr);
-                    }
-                    break;
-                case C2PortMimeConfig::output::PARAM_TYPE:
-                    if (mOutputMediaType) {
-                        heapParams->push_back(C2Param::Copy(*mOutputMediaType));
-                    } else {
-                        heapParams->push_back(nullptr);
-                    }
-                    break;
-                default:
-                    heapParams->push_back(nullptr);
-                    break;
-            }
-        }
-    }
-
-    return C2_OK;
-}
-
-} // namespace android
diff --git a/media/libstagefright/codec2/client/Android.bp b/media/libstagefright/codec2/client/Android.bp
deleted file mode 100644
index 0129e15..0000000
--- a/media/libstagefright/codec2/client/Android.bp
+++ /dev/null
@@ -1,30 +0,0 @@
-cc_library {
-    name: "libstagefright_codec2_client",
-
-    srcs: [
-        "client.cpp",
-    ],
-
-    shared_libs: [
-        "android.hardware.media.bufferpool@1.0",
-        "libcutils",
-        "libhidlbase",
-        "libhidltransport",
-        "liblog",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libstagefright_codec2_hidl@1.0",
-        "libutils",
-        "vendor.google.media.c2@1.0",
-    ],
-
-    export_include_dirs: [
-        "include",
-    ],
-
-    export_shared_lib_headers: [
-        "libstagefright_codec2",
-    ],
-
-}
-
diff --git a/media/libstagefright/codec2/client/client.cpp b/media/libstagefright/codec2/client/client.cpp
deleted file mode 100644
index 5a176dc..0000000
--- a/media/libstagefright/codec2/client/client.cpp
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * Copyright (C) 2018 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 "Codec2Client-interfaces"
-#include <log/log.h>
-
-#include <media/stagefright/codec2/client.h>
-
-#include <codec2/hidl/1.0/types.h>
-
-#include <vendor/google/media/c2/1.0/IComponentListener.h>
-#include <vendor/google/media/c2/1.0/IConfigurable.h>
-#include <vendor/google/media/c2/1.0/IComponentInterface.h>
-#include <vendor/google/media/c2/1.0/IComponent.h>
-#include <vendor/google/media/c2/1.0/IComponentStore.h>
-
-#include <hidl/HidlSupport.h>
-
-#include <limits>
-#include <type_traits>
-
-namespace /* unnamed */ {
-
-// TODO: Find the appropriate error code for this
-constexpr c2_status_t C2_TRANSACTION_FAILED = C2_CORRUPTED;
-
-} // unnamed namespace
-
-namespace android {
-
-using ::android::hardware::hidl_vec;
-using ::android::hardware::hidl_string;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-
-using namespace ::vendor::google::media::c2::V1_0;
-using namespace ::vendor::google::media::c2::V1_0::implementation;
-
-// Codec2ConfigurableClient
-
-const C2String& Codec2ConfigurableClient::getName() const {
-    return mName;
-}
-
-Codec2ConfigurableClient::Base* Codec2ConfigurableClient::base() const {
-    return static_cast<Base*>(mBase.get());
-}
-
-Codec2ConfigurableClient::Codec2ConfigurableClient(
-        const sp<Codec2ConfigurableClient::Base>& base) : mBase(base) {
-    Return<void> transStatus = base->getName(
-            [this](const hidl_string& name) {
-                mName = name.c_str();
-            });
-    if (!transStatus.isOk()) {
-        ALOGE("Cannot obtain name from IConfigurable.");
-    }
-}
-
-c2_status_t Codec2ConfigurableClient::query(
-        const std::vector<C2Param::Index> &indices,
-        c2_blocking_t mayBlock,
-        std::vector<std::unique_ptr<C2Param>>* const params) const {
-    hidl_vec<ParamIndex> hidlIndices(indices.size());
-    size_t i = 0;
-    for (const C2Param::Index& index : indices) {
-        hidlIndices[i++] = static_cast<ParamIndex>(index.operator uint32_t());
-    }
-    c2_status_t status;
-    Return<void> transStatus = base()->query(
-            hidlIndices,
-            mayBlock == C2_MAY_BLOCK,
-            [&status, params](Status s, const Params& p) {
-                status = static_cast<c2_status_t>(s);
-                if (status != C2_OK) {
-                    return;
-                }
-                status = copyParamsFromBlob(params, p);
-            });
-    if (!transStatus.isOk()) {
-        ALOGE("query -- transaction failed.");
-        return C2_TRANSACTION_FAILED;
-    }
-    return status;
-}
-
-c2_status_t Codec2ConfigurableClient::config(
-        const std::vector<C2Param*> &params,
-        c2_blocking_t mayBlock,
-        std::vector<std::unique_ptr<C2SettingResult>>* const failures) {
-    Params hidlParams;
-    Status hidlStatus = createParamsBlob(&hidlParams, params);
-    if (hidlStatus != Status::OK) {
-        ALOGE("config -- bad input.");
-        return C2_TRANSACTION_FAILED;
-    }
-    c2_status_t status;
-    Return<void> transStatus = base()->config(
-            hidlParams,
-            mayBlock == C2_MAY_BLOCK,
-            [&status, &params, failures](
-                    Status s,
-                    const hidl_vec<SettingResult> f,
-                    const Params& o) {
-                status = static_cast<c2_status_t>(s);
-                if (status != C2_OK) {
-                    return;
-                }
-                failures->clear();
-                failures->resize(f.size());
-                size_t i = 0;
-                for (const SettingResult& sf : f) {
-                    status = objcpy(&(*failures)[i++], sf);
-                    if (status != C2_OK) {
-                        return;
-                    }
-                }
-                status = updateParamsFromBlob(params, o);
-            });
-    if (!transStatus.isOk()) {
-        ALOGE("config -- transaction failed.");
-        return C2_TRANSACTION_FAILED;
-    }
-    return status;
-}
-
-c2_status_t Codec2ConfigurableClient::querySupportedParams(
-        std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const {
-    // TODO: Cache and query properly!
-    c2_status_t status;
-    Return<void> transStatus = base()->querySupportedParams(
-            std::numeric_limits<uint32_t>::min(),
-            std::numeric_limits<uint32_t>::max(),
-            [&status, params](
-                    Status s,
-                    const hidl_vec<ParamDescriptor>& p) {
-                status = static_cast<c2_status_t>(s);
-                if (status != C2_OK) {
-                    return;
-                }
-                params->resize(p.size());
-                size_t i = 0;
-                for (const ParamDescriptor& sp : p) {
-                    status = objcpy(&(*params)[i++], sp);
-                    if (status != C2_OK) {
-                        return;
-                    }
-                }
-            });
-    if (!transStatus.isOk()) {
-        ALOGE("querySupportedParams -- transaction failed.");
-        return C2_TRANSACTION_FAILED;
-    }
-    return status;
-}
-
-c2_status_t Codec2ConfigurableClient::querySupportedValues(
-        std::vector<C2FieldSupportedValuesQuery>& fields,
-        c2_blocking_t mayBlock) const {
-    hidl_vec<FieldSupportedValuesQuery> inFields(fields.size());
-    for (size_t i = 0; i < fields.size(); ++i) {
-        Status hidlStatus = objcpy(&inFields[i], fields[i]);
-        if (hidlStatus != Status::OK) {
-            ALOGE("querySupportedValues -- bad input");
-            return C2_TRANSACTION_FAILED;
-        }
-    }
-
-    c2_status_t status;
-    Return<void> transStatus = base()->querySupportedValues(
-            inFields,
-            mayBlock == C2_MAY_BLOCK,
-            [&status, &inFields, &fields](
-                    Status s,
-                    const hidl_vec<FieldSupportedValuesQueryResult>& r) {
-                status = static_cast<c2_status_t>(s);
-                if (status != C2_OK) {
-                    return;
-                }
-                if (r.size() != fields.size()) {
-                    ALOGE("querySupportedValues -- input and output lists "
-                            "have different sizes.");
-                    status = C2_CORRUPTED;
-                    return;
-                }
-                for (size_t i = 0; i < fields.size(); ++i) {
-                    status = objcpy(&fields[i], inFields[i], r[i]);
-                    if (status != C2_OK) {
-                        return;
-                    }
-                }
-            });
-    if (!transStatus.isOk()) {
-        ALOGE("querySupportedValues -- transaction failed.");
-        return C2_TRANSACTION_FAILED;
-    }
-    return status;
-}
-
-// Codec2Client
-
-Codec2Client::Base* Codec2Client::base() const {
-    return static_cast<Base*>(mBase.get());
-}
-
-Codec2Client::Codec2Client(const sp<Codec2Client::Base>& base) :
-        Codec2ConfigurableClient(base), mListed(false) {
-}
-
-c2_status_t Codec2Client::createComponent(
-        const C2String& name,
-        const std::shared_ptr<Codec2Client::Listener>& listener,
-        std::shared_ptr<Codec2Client::Component>* const component) {
-
-    // TODO: Add support for Bufferpool
-
-    struct HidlListener : public IComponentListener {
-        std::shared_ptr<Codec2Client::Listener> base;
-        std::weak_ptr<Codec2Client::Component> component;
-
-        virtual Return<void> onWorkDone(const WorkBundle& workBundle) override {
-            std::list<std::unique_ptr<C2Work>> workItems;
-            c2_status_t status = objcpy(&workItems, workBundle);
-            if (status != C2_OK) {
-                ALOGE("onWorkDone -- received corrupted WorkBundle. "
-                        "Error code: %d", static_cast<int>(status));
-                return Void();
-            }
-            base->onWorkDone(component, workItems);
-            return Void();
-        }
-
-        virtual Return<void> onTripped(
-                const hidl_vec<SettingResult>& settingResults) override {
-            std::vector<std::shared_ptr<C2SettingResult>> c2SettingResults(
-                    settingResults.size());
-            c2_status_t status;
-            for (size_t i = 0; i < settingResults.size(); ++i) {
-                std::unique_ptr<C2SettingResult> c2SettingResult;
-                status = objcpy(&c2SettingResult, settingResults[i]);
-                if (status != C2_OK) {
-                    ALOGE("onTripped -- received corrupted SettingResult. "
-                            "Error code: %d", static_cast<int>(status));
-                    return Void();
-                }
-                c2SettingResults[i] = std::move(c2SettingResult);
-            }
-            base->onTripped(component, c2SettingResults);
-            return Void();
-        }
-
-        virtual Return<void> onError(Status s, uint32_t errorCode) override {
-            base->onError(component, s == Status::OK ?
-                    errorCode : static_cast<c2_status_t>(s));
-            return Void();
-        }
-    };
-
-    c2_status_t status;
-    sp<HidlListener> hidlListener = new HidlListener();
-    hidlListener->base = listener;
-    Return<void> transStatus = base()->createComponent(
-            name,
-            hidlListener,
-            nullptr,
-            [&status, component](
-                    Status s,
-                    const sp<IComponent>& c) {
-                status = static_cast<c2_status_t>(s);
-                if (status != C2_OK) {
-                    return;
-                }
-                *component = std::make_shared<Codec2Client::Component>(c);
-            });
-    if (!transStatus.isOk()) {
-        ALOGE("createComponent -- failed transaction.");
-        return C2_TRANSACTION_FAILED;
-    }
-    if (status != C2_OK) {
-        ALOGE("createComponent -- failed to create component.");
-        return status;
-    }
-    hidlListener->component = *component;
-    return status;
-}
-
-c2_status_t Codec2Client::createInterface(
-        const C2String& name,
-        std::shared_ptr<Codec2Client::Interface>* const interface) {
-    c2_status_t status;
-    Return<void> transStatus = base()->createInterface(
-            name,
-            [&status, interface](
-                    Status s,
-                    const sp<IComponentInterface>& i) {
-                status = static_cast<c2_status_t>(s);
-                if (status != C2_OK) {
-                    return;
-                }
-                *interface = std::make_shared<Codec2Client::Interface>(i);
-            });
-    if (!transStatus.isOk()) {
-        ALOGE("createInterface -- failed transaction.");
-        return C2_TRANSACTION_FAILED;
-    }
-    return status;
-}
-
-const std::vector<C2Component::Traits>& Codec2Client::listComponents()
-        const {
-    if (mListed) {
-        return mTraitsList;
-    }
-    Return<void> transStatus = base()->listComponents(
-            [this](const hidl_vec<IComponentStore::ComponentTraits>& t) {
-                mTraitsList.resize(t.size());
-                mAliasesBuffer.resize(t.size());
-                for (size_t i = 0; i < t.size(); ++i) {
-                    c2_status_t status = objcpy(
-                            &mTraitsList[i], &mAliasesBuffer[i], t[i]);
-                    if (status != C2_OK) {
-                        ALOGE("listComponents -- corrupted output.");
-                        return;
-                    }
-                }
-            });
-    if (!transStatus.isOk()) {
-        ALOGE("listComponents -- failed transaction.");
-    }
-    mListed = true;
-    return mTraitsList;
-}
-
-c2_status_t Codec2Client::copyBuffer(
-        const std::shared_ptr<C2Buffer>& src,
-        const std::shared_ptr<C2Buffer>& dst) {
-    // TODO: Implement?
-    (void)src;
-    (void)dst;
-    ALOGE("copyBuffer not implemented");
-    return C2_OMITTED;
-}
-
-std::shared_ptr<C2ParamReflector>
-        Codec2Client::getParamReflector() {
-    // TODO: Implement this once there is a way to construct C2StructDescriptor
-    // dynamically.
-    ALOGE("getParamReflector -- not implemented.");
-    return nullptr;
-}
-
-std::shared_ptr<Codec2Client> Codec2Client::CreateFromService(
-        const char* instanceName, bool waitForService) {
-    sp<Base> baseStore = waitForService ?
-            Base::getService(instanceName) :
-            Base::tryGetService(instanceName);
-    if (!baseStore) {
-        if (waitForService) {
-            ALOGE("Codec2.0 service inaccessible. Check the device manifest.");
-        } else {
-            ALOGW("Codec2.0 service not available right now. Try again later.");
-        }
-        return nullptr;
-    }
-    return std::make_shared<Codec2Client>(baseStore);
-}
-
-// Codec2Client::Listener
-
-Codec2Client::Listener::~Listener() {
-}
-
-// Codec2Client::Component
-
-Codec2Client::Component::Base* Codec2Client::Component::base() const {
-    return static_cast<Base*>(mBase.get());
-}
-
-Codec2Client::Component::Component(const sp<Codec2Client::Component::Base>& base) :
-        Codec2Client::Configurable(base) {
-}
-
-c2_status_t Codec2Client::Component::createBlockPool(
-        C2Allocator::id_t id,
-        C2BlockPool::local_id_t* localId,
-        std::shared_ptr<Codec2Client::Configurable>* configurable) {
-    c2_status_t status;
-    Return<void> transStatus = base()->createBlockPool(
-            static_cast<uint32_t>(id),
-            [&status, localId, configurable](
-                    Status s,
-                    uint64_t pId,
-                    const sp<IConfigurable>& c) {
-                status = static_cast<c2_status_t>(s);
-                if (status != C2_OK) {
-                    return;
-                }
-                *localId = static_cast<C2BlockPool::local_id_t>(pId);
-                *configurable = std::make_shared<Codec2Client::Configurable>(c);
-            });
-    if (!transStatus.isOk()) {
-        ALOGE("createBlockPool -- transaction failed.");
-        return C2_TRANSACTION_FAILED;
-    }
-    return status;
-}
-
-c2_status_t Codec2Client::Component::queue(
-        std::list<std::unique_ptr<C2Work>>* const items) {
-    WorkBundle workBundle;
-    Status hidlStatus = objcpy(&workBundle, *items);
-    if (hidlStatus != Status::OK) {
-        ALOGE("queue -- bad input.");
-        return C2_TRANSACTION_FAILED;
-    }
-    Return<Status> transStatus = base()->queue(workBundle);
-    if (!transStatus.isOk()) {
-        ALOGE("queue -- transaction failed.");
-        return C2_TRANSACTION_FAILED;
-    }
-    return static_cast<c2_status_t>(static_cast<Status>(transStatus));
-}
-
-c2_status_t Codec2Client::Component::flush(
-        C2Component::flush_mode_t mode,
-        std::list<std::unique_ptr<C2Work>>* const flushedWork) {
-    (void)mode; // Flush mode isn't supported in HIDL yet.
-    c2_status_t status;
-    Return<void> transStatus = base()->flush(
-            [&status, flushedWork](
-                    Status s, const WorkBundle& wb) {
-                status = static_cast<c2_status_t>(s);
-                if (status != C2_OK) {
-                    return;
-                }
-                status = objcpy(flushedWork, wb);
-            });
-    if (!transStatus.isOk()) {
-        ALOGE("flush -- transaction failed.");
-        return C2_TRANSACTION_FAILED;
-    }
-    return status;
-}
-
-c2_status_t Codec2Client::Component::drain(C2Component::drain_mode_t mode) {
-    Return<Status> transStatus = base()->drain(
-            mode == C2Component::DRAIN_COMPONENT_WITH_EOS);
-    if (!transStatus.isOk()) {
-        ALOGE("drain -- transaction failed.");
-        return C2_TRANSACTION_FAILED;
-    }
-    return static_cast<c2_status_t>(static_cast<Status>(transStatus));
-}
-
-c2_status_t Codec2Client::Component::start() {
-    Return<Status> transStatus = base()->start();
-    if (!transStatus.isOk()) {
-        ALOGE("start -- transaction failed.");
-        return C2_TRANSACTION_FAILED;
-    }
-    return static_cast<c2_status_t>(static_cast<Status>(transStatus));
-}
-
-c2_status_t Codec2Client::Component::stop() {
-    Return<Status> transStatus = base()->stop();
-    if (!transStatus.isOk()) {
-        ALOGE("stop -- transaction failed.");
-        return C2_TRANSACTION_FAILED;
-    }
-    return static_cast<c2_status_t>(static_cast<Status>(transStatus));
-}
-
-c2_status_t Codec2Client::Component::reset() {
-    Return<Status> transStatus = base()->reset();
-    if (!transStatus.isOk()) {
-        ALOGE("reset -- transaction failed.");
-        return C2_TRANSACTION_FAILED;
-    }
-    return static_cast<c2_status_t>(static_cast<Status>(transStatus));
-}
-
-c2_status_t Codec2Client::Component::release() {
-    Return<Status> transStatus = base()->release();
-    if (!transStatus.isOk()) {
-        ALOGE("release -- transaction failed.");
-        return C2_TRANSACTION_FAILED;
-    }
-    return static_cast<c2_status_t>(static_cast<Status>(transStatus));
-}
-
-
-
-
-}  // namespace android
-
diff --git a/media/libstagefright/codec2/client/include/media/stagefright/codec2/client.h b/media/libstagefright/codec2/client/include/media/stagefright/codec2/client.h
deleted file mode 100644
index 1bbf459..0000000
--- a/media/libstagefright/codec2/client/include/media/stagefright/codec2/client.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2018 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 CODEC2_CLIENT_INTERFACES_H_
-#define CODEC2_CLIENT_INTERFACES_H_
-
-#include <C2Component.h>
-#include <C2Buffer.h>
-#include <C2Param.h>
-#include <C2.h>
-
-#include <utils/StrongPointer.h>
-
-#include <memory>
-
-/**
- * This file contains minimal interfaces for the framework to access Codec2.0.
- *
- * Codec2Client is the main class that contains the following inner classes:
- * - Listener
- * - Configurable
- * - Interface
- * - Component
- *
- * Classes in Codec2Client, interfaces in Codec2.0, and  HIDL interfaces are
- * related as follows:
- * - Codec2Client <==> C2ComponentStore <==> IComponentStore
- * - Codec2Client::Listener <==> C2Component::Listener <==> IComponentListener
- * - Codec2Client::Configurable <==> [No equivalent] <==> IConfigurable
- * - Codec2Client::Interface <==> C2ComponentInterface <==> IComponentInterface
- * - Codec2Client::Component <==> C2Component <==> IComponent
- *
- * The entry point is Codec2Client::CreateFromService(), which creates a
- * Codec2Client object. From Codec2Client, Interface and Component objects can
- * be created by calling createComponent() and createInterface().
- *
- * createComponent() takes a Listener object, which must be implemented by the
- * user.
- *
- * At the present, createBlockPool() is the only method that yields a
- * Configurable object. Note, however, that Interface, Component and
- * Codec2Client are all subclasses of Configurable.
- */
-
-// Forward declaration of HIDL interfaces
-namespace vendor {
-namespace google {
-namespace media {
-namespace c2 {
-namespace V1_0 {
-struct IConfigurable;
-struct IComponentInterface;
-struct IComponent;
-struct IComponentStore;
-} // namespace V1_0
-} // namespace c2
-} // namespace media
-} // namespace google
-} // namespace vendor
-
-namespace android {
-
-// This class is supposed to be called Codec2Client::Configurable, but forward
-// declaration of an inner class is not possible.
-struct Codec2ConfigurableClient {
-
-    typedef ::vendor::google::media::c2::V1_0::IConfigurable Base;
-
-    const C2String& getName() const;
-
-    c2_status_t query(
-            const std::vector<C2Param::Index> &indices,
-            c2_blocking_t mayBlock,
-            std::vector<std::unique_ptr<C2Param>>* const params) const;
-
-    c2_status_t config(
-            const std::vector<C2Param*> &params,
-            c2_blocking_t mayBlock,
-            std::vector<std::unique_ptr<C2SettingResult>>* const failures
-            );
-
-    c2_status_t querySupportedParams(
-            std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
-            ) const;
-
-    c2_status_t querySupportedValues(
-            std::vector<C2FieldSupportedValuesQuery>& fields,
-            c2_blocking_t mayBlock) const;
-
-    // base cannot be null.
-    Codec2ConfigurableClient(const sp<Base>& base);
-
-protected:
-    C2String mName;
-    sp<Base> mBase;
-
-    Base* base() const;
-
-    friend struct Codec2Client;
-};
-
-struct Codec2Client : public Codec2ConfigurableClient {
-
-    typedef ::vendor::google::media::c2::V1_0::IComponentStore Base;
-
-    struct Listener;
-
-    typedef Codec2ConfigurableClient Configurable;
-
-    typedef Configurable Interface; // These two types may diverge in the future.
-
-    struct Component;
-
-    typedef Codec2Client Store;
-
-    c2_status_t createComponent(
-            const C2String& name,
-            const std::shared_ptr<Listener>& listener,
-            std::shared_ptr<Component>* const component);
-
-    c2_status_t createInterface(
-            const C2String& name,
-            std::shared_ptr<Interface>* const interface);
-
-    const std::vector<C2Component::Traits>&
-            listComponents() const;
-
-    c2_status_t copyBuffer(
-            const std::shared_ptr<C2Buffer>& src,
-            const std::shared_ptr<C2Buffer>& dst);
-
-    std::shared_ptr<C2ParamReflector> getParamReflector();
-
-    static std::shared_ptr<Codec2Client> CreateFromService(
-            const char* instanceName,
-            bool waitForService = true);
-
-    // base cannot be null.
-    Codec2Client(const sp<Base>& base);
-
-protected:
-    mutable bool mListed;
-    mutable std::vector<C2Component::Traits> mTraitsList;
-    mutable std::vector<std::unique_ptr<std::vector<std::string>>>
-            mAliasesBuffer;
-
-    Base* base() const;
-};
-
-struct Codec2Client::Listener {
-
-    virtual void onWorkDone(
-            const std::weak_ptr<Codec2Client::Component>& comp,
-            const std::list<std::unique_ptr<C2Work>>& workItems) = 0;
-
-    virtual void onTripped(
-            const std::weak_ptr<Codec2Client::Component>& comp,
-            const std::vector<std::shared_ptr<C2SettingResult>>& settingResults
-            ) = 0;
-
-    virtual void onError(
-            const std::weak_ptr<Codec2Client::Component>& comp,
-            uint32_t errorCode) = 0;
-
-    virtual ~Listener();
-
-};
-
-struct Codec2Client::Component : public Codec2Client::Configurable {
-
-    typedef ::vendor::google::media::c2::V1_0::IComponent Base;
-
-    c2_status_t createBlockPool(
-            C2Allocator::id_t id,
-            C2BlockPool::local_id_t* localId,
-            std::shared_ptr<Codec2Client::Configurable>* configurable);
-
-    c2_status_t queue(
-            std::list<std::unique_ptr<C2Work>>* const items);
-
-    c2_status_t flush(
-            C2Component::flush_mode_t mode,
-            std::list<std::unique_ptr<C2Work>>* const flushedWork);
-
-    c2_status_t drain(C2Component::drain_mode_t mode);
-
-    c2_status_t start();
-
-    c2_status_t stop();
-
-    c2_status_t reset();
-
-    c2_status_t release();
-
-    // base cannot be null.
-    Component(const sp<Base>& base);
-
-protected:
-    Base* base() const;
-
-    friend struct Codec2Client;
-};
-
-}  // namespace android
-
-#endif  // CODEC2_CLIENT_INTERFACES_H_
-
diff --git a/media/libstagefright/codec2/docs/doxyfilter.sh b/media/libstagefright/codec2/docs/doxyfilter.sh
deleted file mode 100755
index d813153..0000000
--- a/media/libstagefright/codec2/docs/doxyfilter.sh
+++ /dev/null
@@ -1,100 +0,0 @@
-#!/usr/bin/env python3
-import re, sys
-
-global in_comment, current, indent, hold
-in_comment, current, indent, hold = False, None, '', []
-
-class ChangeCStyleCommentsToDoxy:
-    def dump_hold():
-        global hold
-        for h in hold:
-            print(h, end='')
-        hold[:] = []
-
-    def doxy_hold():
-        global current, hold
-        if current == '//':
-            for h in hold:
-                print(re.sub(r'^( *//(?!/))', r'\1/', h), end='')
-        else:
-            first = True
-            for h in hold:
-                if first:
-                    h = re.sub(r'^( */[*](?![*]))', r'\1*', h)
-                    first = False
-                print(h, end='')
-        hold[:] = []
-
-    def process_comment(t, ind, line):
-        global current, indent, hold
-        if t != current or ind not in (indent, indent + ' '):
-            dump_hold()
-            current, indent = t, ind
-        hold.append(line)
-
-    def process_line(ind, line):
-        global current, indent
-        if ind in (indent, ''):
-            doxy_hold()
-        else:
-            dump_hold()
-        current, indent = None, None
-        print(line, end='')
-
-    def process(self, input, path):
-        for line in input:
-            ind = re.match(r'^( *)', line).group(1)
-            if in_comment:
-                # TODO: this is not quite right, but good enough
-                m = re.match(r'^ *[*]/', line)
-                if m:
-                    process_comment('/*', ind, line)
-                    in_comment = False
-                else:
-                    process_comment('/*', ind, line)
-                continue
-            m = re.match(r'^ *//', line)
-            if m:
-                # one-line comment
-                process_comment('//', ind, line)
-                continue
-            m = re.match(r'^ */[*]', line)
-            if m:
-                # multi-line comment
-                process_comment('/*', ind, line)
-                # TODO: this is not quite right, but good enough
-                in_comment = not re.match(r'^ *[*]/', line)
-                continue
-            process_line(ind, line)
-
-class AutoGroup:
-    def process(self, input, path):
-        if '/codec2/include/' in path:
-            group = 'API Codec2 API'
-        elif False:
-            return
-        elif '/codec2/vndk/' in path:
-            group = 'VNDK Platform provided glue'
-        elif '/codec2/tests/' in path:
-            group = 'Tests Unit tests'
-        else:
-            group = 'Random Misc. sandbox'
-
-        print('#undef __APPLE__')
-
-        for line in input:
-            if re.match(r'^namespace android {', line):
-                print(line, end='')
-                print()
-                print(r'/// \addtogroup {}'.format(group))
-                print(r'/// @{')
-                continue
-            elif re.match(r'^} +// +namespace', line):
-                print(r'/// @}')
-                print()
-            print(line, end='')
-
-P = AutoGroup()
-for path in sys.argv[1:]:
-    with open(path, 'rt') as input:
-        P.process(input, path)
diff --git a/media/libstagefright/codec2/docs/doxygen.config b/media/libstagefright/codec2/docs/doxygen.config
deleted file mode 100644
index 11a921f..0000000
--- a/media/libstagefright/codec2/docs/doxygen.config
+++ /dev/null
@@ -1,2446 +0,0 @@
-# Doxyfile 1.8.11
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project.
-#
-# All text after a double hash (##) is considered a comment and is placed in
-# front of the TAG it is preceding.
-#
-# All text after a single hash (#) is considered a comment and will be ignored.
-# The format is:
-# TAG = value [value, ...]
-# For lists, items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (\" \").
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# This tag specifies the encoding used for all characters in the config file
-# that follow. The default is UTF-8 which is also the encoding used for all text
-# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
-# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
-# for the list of possible encodings.
-# The default value is: UTF-8.
-
-DOXYFILE_ENCODING      = UTF-8
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
-# double-quotes, unless you are using Doxywizard) that should identify the
-# project for which the documentation is generated. This name is used in the
-# title of most generated pages and in a few other places.
-# The default value is: My Project.
-
-PROJECT_NAME           = Codec2
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
-# could be handy for archiving the generated documentation or if some version
-# control system is used.
-
-PROJECT_NUMBER         = 
-
-# Using the PROJECT_BRIEF tag one can provide an optional one line description
-# for a project that appears at the top of each page and should give viewer a
-# quick idea about the purpose of the project. Keep the description short.
-
-PROJECT_BRIEF          = 
-
-# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
-# in the documentation. The maximum height of the logo should not exceed 55
-# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
-# the logo to the output directory.
-
-PROJECT_LOGO           = 
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
-# into which the generated documentation will be written. If a relative path is
-# entered, it will be relative to the location where doxygen was started. If
-# left blank the current directory will be used.
-
-OUTPUT_DIRECTORY       = out/target/common/docs/codec2/api
-
-# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
-# directories (in 2 levels) under the output directory of each output format and
-# will distribute the generated files over these directories. Enabling this
-# option can be useful when feeding doxygen a huge amount of source files, where
-# putting all generated files in the same directory would otherwise causes
-# performance problems for the file system.
-# The default value is: NO.
-
-CREATE_SUBDIRS         = NO
-
-# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
-# characters to appear in the names of generated files. If set to NO, non-ASCII
-# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
-# U+3044.
-# The default value is: NO.
-
-ALLOW_UNICODE_NAMES    = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
-# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
-# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
-# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
-# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
-# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
-# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
-# Ukrainian and Vietnamese.
-# The default value is: English.
-
-OUTPUT_LANGUAGE        = English
-
-# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
-# descriptions after the members that are listed in the file and class
-# documentation (similar to Javadoc). Set to NO to disable this.
-# The default value is: YES.
-
-BRIEF_MEMBER_DESC      = YES
-
-# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
-# description of a member or function before the detailed description
-#
-# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-# The default value is: YES.
-
-REPEAT_BRIEF           = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator that is
-# used to form the text in various listings. Each string in this list, if found
-# as the leading text of the brief description, will be stripped from the text
-# and the result, after processing the whole list, is used as the annotated
-# text. Otherwise, the brief description is used as-is. If left blank, the
-# following values are used ($name is automatically replaced with the name of
-# the entity):The $name class, The $name widget, The $name file, is, provides,
-# specifies, contains, represents, a, an and the.
-
-ABBREVIATE_BRIEF       = "The $name class" \
-                         "The $name widget" \
-                         "The $name file" \
-                         is \
-                         provides \
-                         specifies \
-                         contains \
-                         represents \
-                         a \
-                         an \
-                         the
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# doxygen will generate a detailed section even if there is only a brief
-# description.
-# The default value is: NO.
-
-ALWAYS_DETAILED_SEC    = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-# The default value is: NO.
-
-INLINE_INHERITED_MEMB  = YES
-
-# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
-# before files name in the file list and in the header files. If set to NO the
-# shortest path that makes the file name unique will be used
-# The default value is: YES.
-
-FULL_PATH_NAMES        = YES
-
-# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
-# Stripping is only done if one of the specified strings matches the left-hand
-# part of the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the path to
-# strip.
-#
-# Note that you can specify absolute paths here, but also relative paths, which
-# will be relative from the directory where doxygen is started.
-# This tag requires that the tag FULL_PATH_NAMES is set to YES.
-
-STRIP_FROM_PATH        = frameworks/av/media/libstagefright/codec2
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
-# path mentioned in the documentation of a class, which tells the reader which
-# header file to include in order to use a class. If left blank only the name of
-# the header file containing the class definition is used. Otherwise one should
-# specify the list of include paths that are normally passed to the compiler
-# using the -I flag.
-
-STRIP_FROM_INC_PATH    = 
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
-# less readable) file names. This can be useful is your file systems doesn't
-# support long names like on DOS, Mac, or CD-ROM.
-# The default value is: NO.
-
-SHORT_NAMES            = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
-# first line (until the first dot) of a Javadoc-style comment as the brief
-# description. If set to NO, the Javadoc-style will behave just like regular Qt-
-# style comments (thus requiring an explicit @brief command for a brief
-# description.)
-# The default value is: NO.
-
-JAVADOC_AUTOBRIEF      = YES
-
-# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
-# line (until the first dot) of a Qt-style comment as the brief description. If
-# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
-# requiring an explicit \brief command for a brief description.)
-# The default value is: NO.
-
-QT_AUTOBRIEF           = YES
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
-# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
-# a brief description. This used to be the default behavior. The new default is
-# to treat a multi-line C++ comment block as a detailed description. Set this
-# tag to YES if you prefer the old behavior instead.
-#
-# Note that setting this tag to YES also means that rational rose comments are
-# not recognized any more.
-# The default value is: NO.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
-# documentation from any documented member that it re-implements.
-# The default value is: YES.
-
-INHERIT_DOCS           = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
-# page for each member. If set to NO, the documentation of a member will be part
-# of the file/class/namespace that contains it.
-# The default value is: NO.
-
-SEPARATE_MEMBER_PAGES  = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
-# uses this value to replace tabs by spaces in code fragments.
-# Minimum value: 1, maximum value: 16, default value: 4.
-
-TAB_SIZE               = 4
-
-# This tag can be used to specify a number of aliases that act as commands in
-# the documentation. An alias has the form:
-# name=value
-# For example adding
-# "sideeffect=@par Side Effects:\n"
-# will allow you to put the command \sideeffect (or @sideeffect) in the
-# documentation, which will result in a user-defined paragraph with heading
-# "Side Effects:". You can put \n's in the value part of an alias to insert
-# newlines.
-
-ALIASES                = 
-
-# This tag can be used to specify a number of word-keyword mappings (TCL only).
-# A mapping has the form "name=value". For example adding "class=itcl::class"
-# will allow you to use the command class in the itcl::class meaning.
-
-TCL_SUBST              = 
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
-# only. Doxygen will then generate output that is more tailored for C. For
-# instance, some of the names that are used will be different. The list of all
-# members will be omitted, etc.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_FOR_C  = NO
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
-# Python sources only. Doxygen will then generate output that is more tailored
-# for that language. For instance, namespaces will be presented as packages,
-# qualified scopes will look different, etc.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_JAVA   = NO
-
-# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
-# sources. Doxygen will then generate output that is tailored for Fortran.
-# The default value is: NO.
-
-OPTIMIZE_FOR_FORTRAN   = NO
-
-# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
-# sources. Doxygen will then generate output that is tailored for VHDL.
-# The default value is: NO.
-
-OPTIMIZE_OUTPUT_VHDL   = NO
-
-# Doxygen selects the parser to use depending on the extension of the files it
-# parses. With this tag you can assign which parser to use for a given
-# extension. Doxygen has a built-in mapping, but you can override or extend it
-# using this tag. The format is ext=language, where ext is a file extension, and
-# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
-# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
-# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
-# Fortran. In the later case the parser tries to guess whether the code is fixed
-# or free formatted code, this is the default for Fortran type files), VHDL. For
-# instance to make doxygen treat .inc files as Fortran files (default is PHP),
-# and .f files as C (default is Fortran), use: inc=Fortran f=C.
-#
-# Note: For files without extension you can use no_extension as a placeholder.
-#
-# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
-# the files are not read by doxygen.
-
-EXTENSION_MAPPING      = 
-
-# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
-# according to the Markdown format, which allows for more readable
-# documentation. See http://daringfireball.net/projects/markdown/ for details.
-# The output of markdown processing is further processed by doxygen, so you can
-# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
-# case of backward compatibilities issues.
-# The default value is: YES.
-
-MARKDOWN_SUPPORT       = YES
-
-# When enabled doxygen tries to link words that correspond to documented
-# classes, or namespaces to their corresponding documentation. Such a link can
-# be prevented in individual cases by putting a % sign in front of the word or
-# globally by setting AUTOLINK_SUPPORT to NO.
-# The default value is: YES.
-
-AUTOLINK_SUPPORT       = YES
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
-# to include (a tag file for) the STL sources as input, then you should set this
-# tag to YES in order to let doxygen match functions declarations and
-# definitions whose arguments contain STL classes (e.g. func(std::string);
-# versus func(std::string) {}). This also make the inheritance and collaboration
-# diagrams that involve STL classes more complete and accurate.
-# The default value is: NO.
-
-BUILTIN_STL_SUPPORT    = YES
-
-# If you use Microsoft's C++/CLI language, you should set this option to YES to
-# enable parsing support.
-# The default value is: NO.
-
-CPP_CLI_SUPPORT        = NO
-
-# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
-# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
-# will parse them like normal C++ but will assume all classes use public instead
-# of private inheritance when no explicit protection keyword is present.
-# The default value is: NO.
-
-SIP_SUPPORT            = NO
-
-# For Microsoft's IDL there are propget and propput attributes to indicate
-# getter and setter methods for a property. Setting this option to YES will make
-# doxygen to replace the get and set methods by a property in the documentation.
-# This will only work if the methods are indeed getting or setting a simple
-# type. If this is not the case, or you want to show the methods anyway, you
-# should set this option to NO.
-# The default value is: YES.
-
-IDL_PROPERTY_SUPPORT   = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-# The default value is: NO.
-
-DISTRIBUTE_GROUP_DOC   = NO
-
-# If one adds a struct or class to a group and this option is enabled, then also
-# any nested class or struct is added to the same group. By default this option
-# is disabled and one has to add nested compounds explicitly via \ingroup.
-# The default value is: NO.
-
-GROUP_NESTED_COMPOUNDS = NO
-
-# Set the SUBGROUPING tag to YES to allow class member groups of the same type
-# (for instance a group of public functions) to be put as a subgroup of that
-# type (e.g. under the Public Functions section). Set it to NO to prevent
-# subgrouping. Alternatively, this can be done per class using the
-# \nosubgrouping command.
-# The default value is: YES.
-
-SUBGROUPING            = YES
-
-# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
-# are shown inside the group in which they are included (e.g. using \ingroup)
-# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
-# and RTF).
-#
-# Note that this feature does not work in combination with
-# SEPARATE_MEMBER_PAGES.
-# The default value is: NO.
-
-INLINE_GROUPED_CLASSES = NO
-
-# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
-# with only public data fields or simple typedef fields will be shown inline in
-# the documentation of the scope in which they are defined (i.e. file,
-# namespace, or group documentation), provided this scope is documented. If set
-# to NO, structs, classes, and unions are shown on a separate page (for HTML and
-# Man pages) or section (for LaTeX and RTF).
-# The default value is: NO.
-
-INLINE_SIMPLE_STRUCTS  = NO
-
-# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
-# enum is documented as struct, union, or enum with the name of the typedef. So
-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
-# with name TypeT. When disabled the typedef will appear as a member of a file,
-# namespace, or class. And the struct will be named TypeS. This can typically be
-# useful for C code in case the coding convention dictates that all compound
-# types are typedef'ed and only the typedef is referenced, never the tag name.
-# The default value is: NO.
-
-TYPEDEF_HIDES_STRUCT   = YES
-
-# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
-# cache is used to resolve symbols given their name and scope. Since this can be
-# an expensive process and often the same symbol appears multiple times in the
-# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
-# doxygen will become slower. If the cache is too large, memory is wasted. The
-# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
-# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
-# symbols. At the end of a run doxygen will report the cache usage and suggest
-# the optimal cache size from a speed point of view.
-# Minimum value: 0, maximum value: 9, default value: 0.
-
-LOOKUP_CACHE_SIZE      = 0
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
-# documentation are documented, even if no documentation was available. Private
-# class members and static file members will be hidden unless the
-# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
-# Note: This will also disable the warnings about undocumented members that are
-# normally produced when WARNINGS is set to YES.
-# The default value is: NO.
-
-EXTRACT_ALL            = YES
-
-# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
-# be included in the documentation.
-# The default value is: NO.
-
-EXTRACT_PRIVATE        = NO
-
-# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
-# scope will be included in the documentation.
-# The default value is: NO.
-
-EXTRACT_PACKAGE        = NO
-
-# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
-# included in the documentation.
-# The default value is: NO.
-
-EXTRACT_STATIC         = NO
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
-# locally in source files will be included in the documentation. If set to NO,
-# only classes defined in header files are included. Does not have any effect
-# for Java sources.
-# The default value is: YES.
-
-EXTRACT_LOCAL_CLASSES  = YES
-
-# This flag is only useful for Objective-C code. If set to YES, local methods,
-# which are defined in the implementation section but not in the interface are
-# included in the documentation. If set to NO, only methods in the interface are
-# included.
-# The default value is: NO.
-
-EXTRACT_LOCAL_METHODS  = NO
-
-# If this flag is set to YES, the members of anonymous namespaces will be
-# extracted and appear in the documentation as a namespace called
-# 'anonymous_namespace{file}', where file will be replaced with the base name of
-# the file that contains the anonymous namespace. By default anonymous namespace
-# are hidden.
-# The default value is: NO.
-
-EXTRACT_ANON_NSPACES   = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
-# undocumented members inside documented classes or files. If set to NO these
-# members will be included in the various overviews, but no documentation
-# section is generated. This option has no effect if EXTRACT_ALL is enabled.
-# The default value is: NO.
-
-HIDE_UNDOC_MEMBERS     = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy. If set
-# to NO, these classes will be included in the various overviews. This option
-# has no effect if EXTRACT_ALL is enabled.
-# The default value is: NO.
-
-HIDE_UNDOC_CLASSES     = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
-# (class|struct|union) declarations. If set to NO, these declarations will be
-# included in the documentation.
-# The default value is: NO.
-
-HIDE_FRIEND_COMPOUNDS  = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
-# documentation blocks found inside the body of a function. If set to NO, these
-# blocks will be appended to the function's detailed documentation block.
-# The default value is: NO.
-
-HIDE_IN_BODY_DOCS      = NO
-
-# The INTERNAL_DOCS tag determines if documentation that is typed after a
-# \internal command is included. If the tag is set to NO then the documentation
-# will be excluded. Set it to YES to include the internal documentation.
-# The default value is: NO.
-
-INTERNAL_DOCS          = YES
-
-# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
-# names in lower-case letters. If set to YES, upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-# The default value is: system dependent.
-
-CASE_SENSE_NAMES       = NO
-
-# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
-# their full class and namespace scopes in the documentation. If set to YES, the
-# scope will be hidden.
-# The default value is: NO.
-
-HIDE_SCOPE_NAMES       = YES
-
-# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
-# append additional text to a page's title, such as Class Reference. If set to
-# YES the compound reference will be hidden.
-# The default value is: NO.
-
-HIDE_COMPOUND_REFERENCE= NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
-# the files that are included by a file in the documentation of that file.
-# The default value is: YES.
-
-SHOW_INCLUDE_FILES     = YES
-
-# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
-# grouped member an include statement to the documentation, telling the reader
-# which file to include in order to use the member.
-# The default value is: NO.
-
-SHOW_GROUPED_MEMB_INC  = NO
-
-# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
-# files with double quotes in the documentation rather than with sharp brackets.
-# The default value is: NO.
-
-FORCE_LOCAL_INCLUDES   = NO
-
-# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
-# documentation for inline members.
-# The default value is: YES.
-
-INLINE_INFO            = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
-# (detailed) documentation of file and class members alphabetically by member
-# name. If set to NO, the members will appear in declaration order.
-# The default value is: YES.
-
-SORT_MEMBER_DOCS       = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
-# descriptions of file, namespace and class members alphabetically by member
-# name. If set to NO, the members will appear in declaration order. Note that
-# this will also influence the order of the classes in the class list.
-# The default value is: NO.
-
-SORT_BRIEF_DOCS        = NO
-
-# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
-# (brief and detailed) documentation of class members so that constructors and
-# destructors are listed first. If set to NO the constructors will appear in the
-# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
-# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
-# member documentation.
-# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
-# detailed member documentation.
-# The default value is: NO.
-
-SORT_MEMBERS_CTORS_1ST = NO
-
-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
-# of group names into alphabetical order. If set to NO the group names will
-# appear in their defined order.
-# The default value is: NO.
-
-SORT_GROUP_NAMES       = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
-# fully-qualified names, including namespaces. If set to NO, the class list will
-# be sorted only by class name, not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the alphabetical
-# list.
-# The default value is: NO.
-
-SORT_BY_SCOPE_NAME     = NO
-
-# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
-# type resolution of all parameters of a function it will reject a match between
-# the prototype and the implementation of a member function even if there is
-# only one candidate or it is obvious which candidate to choose by doing a
-# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
-# accept a match between prototype and implementation in such cases.
-# The default value is: NO.
-
-STRICT_PROTO_MATCHING  = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
-# list. This list is created by putting \todo commands in the documentation.
-# The default value is: YES.
-
-GENERATE_TODOLIST      = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
-# list. This list is created by putting \test commands in the documentation.
-# The default value is: YES.
-
-GENERATE_TESTLIST      = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
-# list. This list is created by putting \bug commands in the documentation.
-# The default value is: YES.
-
-GENERATE_BUGLIST       = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
-# the deprecated list. This list is created by putting \deprecated commands in
-# the documentation.
-# The default value is: YES.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional documentation
-# sections, marked by \if <section_label> ... \endif and \cond <section_label>
-# ... \endcond blocks.
-
-ENABLED_SECTIONS       = INTERNAL
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
-# initial value of a variable or macro / define can have for it to appear in the
-# documentation. If the initializer consists of more lines than specified here
-# it will be hidden. Use a value of 0 to hide initializers completely. The
-# appearance of the value of individual variables and macros / defines can be
-# controlled using \showinitializer or \hideinitializer command in the
-# documentation regardless of this setting.
-# Minimum value: 0, maximum value: 10000, default value: 30.
-
-MAX_INITIALIZER_LINES  = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
-# the bottom of the documentation of classes and structs. If set to YES, the
-# list will mention the files that were used to generate the documentation.
-# The default value is: YES.
-
-SHOW_USED_FILES        = YES
-
-# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
-# will remove the Files entry from the Quick Index and from the Folder Tree View
-# (if specified).
-# The default value is: YES.
-
-SHOW_FILES             = YES
-
-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
-# page. This will remove the Namespaces entry from the Quick Index and from the
-# Folder Tree View (if specified).
-# The default value is: YES.
-
-SHOW_NAMESPACES        = YES
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from
-# the version control system). Doxygen will invoke the program by executing (via
-# popen()) the command command input-file, where command is the value of the
-# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
-# by doxygen. Whatever the program writes to standard output is used as the file
-# version. For an example see the documentation.
-
-FILE_VERSION_FILTER    = 
-
-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
-# by doxygen. The layout file controls the global structure of the generated
-# output files in an output format independent way. To create the layout file
-# that represents doxygen's defaults, run doxygen with the -l option. You can
-# optionally specify a file name after the option, if omitted DoxygenLayout.xml
-# will be used as the name of the layout file.
-#
-# Note that if you run doxygen from a directory containing a file called
-# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
-# tag is left empty.
-
-LAYOUT_FILE            = 
-
-# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
-# the reference definitions. This must be a list of .bib files. The .bib
-# extension is automatically appended if omitted. This requires the bibtex tool
-# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
-# For LaTeX the style of the bibliography can be controlled using
-# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
-# search path. See also \cite for info how to create references.
-
-CITE_BIB_FILES         = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated to
-# standard output by doxygen. If QUIET is set to YES this implies that the
-# messages are off.
-# The default value is: NO.
-
-QUIET                  = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
-# this implies that the warnings are on.
-#
-# Tip: Turn warnings on while writing the documentation.
-# The default value is: YES.
-
-WARNINGS               = YES
-
-# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
-# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
-# will automatically be disabled.
-# The default value is: YES.
-
-WARN_IF_UNDOCUMENTED   = YES
-
-# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some parameters
-# in a documented function, or documenting parameters that don't exist or using
-# markup commands wrongly.
-# The default value is: YES.
-
-WARN_IF_DOC_ERROR      = YES
-
-# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
-# are documented, but have no documentation for their parameters or return
-# value. If set to NO, doxygen will only warn about wrong or incomplete
-# parameter documentation, but not about the absence of documentation.
-# The default value is: NO.
-
-WARN_NO_PARAMDOC       = NO
-
-# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
-# a warning is encountered.
-# The default value is: NO.
-
-WARN_AS_ERROR          = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that doxygen
-# can produce. The string should contain the $file, $line, and $text tags, which
-# will be replaced by the file and line number from which the warning originated
-# and the warning text. Optionally the format may contain $version, which will
-# be replaced by the version of the file (if it could be obtained via
-# FILE_VERSION_FILTER)
-# The default value is: $file:$line: $text.
-
-WARN_FORMAT            = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning and error
-# messages should be written. If left blank the output is written to standard
-# error (stderr).
-
-WARN_LOGFILE           = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag is used to specify the files and/or directories that contain
-# documented source files. You may enter file names like myfile.cpp or
-# directories like /usr/src/myproject. Separate the files or directories with
-# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
-# Note: If this tag is empty the current directory is searched.
-
-INPUT                  = frameworks/av/media/libstagefright/codec2/
-
-# This tag can be used to specify the character encoding of the source files
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
-# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
-# documentation (see: http://www.gnu.org/software/libiconv) for the list of
-# possible encodings.
-# The default value is: UTF-8.
-
-INPUT_ENCODING         = UTF-8
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
-# *.h) to filter out the source-files in the directories.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# read by doxygen.
-#
-# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
-# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
-# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
-# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl,
-# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js.
-
-FILE_PATTERNS          = C2*.c \
-                         C2*.cpp \
-                         C2*.h
-
-# The RECURSIVE tag can be used to specify whether or not subdirectories should
-# be searched for input files as well.
-# The default value is: NO.
-
-RECURSIVE              = YES
-
-# The EXCLUDE tag can be used to specify files and/or directories that should be
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-#
-# Note that relative paths are relative to the directory from which doxygen is
-# run.
-
-EXCLUDE                = 
-
-# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
-# directories that are symbolic links (a Unix file system feature) are excluded
-# from the input.
-# The default value is: NO.
-
-EXCLUDE_SYMLINKS       = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories.
-#
-# Note that the wildcards are matched against the file with absolute path, so to
-# exclude all test directories for example use the pattern */test/*
-
-EXCLUDE_PATTERNS       = ._*
-
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
-# (namespaces, classes, functions, etc.) that should be excluded from the
-# output. The symbol name can be a fully qualified name, a word, or if the
-# wildcard * is used, a substring. Examples: ANamespace, AClass,
-# AClass::ANamespace, ANamespace::*Test
-#
-# Note that the wildcards are matched against the file with absolute path, so to
-# exclude all test directories use the pattern */test/*
-
-EXCLUDE_SYMBOLS        = 
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or directories
-# that contain example code fragments that are included (see the \include
-# command).
-
-EXAMPLE_PATH           = 
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
-# *.h) to filter out the source-files in the directories. If left blank all
-# files are included.
-
-EXAMPLE_PATTERNS       = *
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude commands
-# irrespective of the value of the RECURSIVE tag.
-# The default value is: NO.
-
-EXAMPLE_RECURSIVE      = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or directories
-# that contain images that are to be included in the documentation (see the
-# \image command).
-
-IMAGE_PATH             = 
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command:
-#
-# <filter> <input-file>
-#
-# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
-# name of an input file. Doxygen will then use the output that the filter
-# program writes to standard output. If FILTER_PATTERNS is specified, this tag
-# will be ignored.
-#
-# Note that the filter must not add or remove lines; it is applied before the
-# code is scanned, but not when the output code is generated. If lines are added
-# or removed, the anchors will not be placed correctly.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# properly processed by doxygen.
-
-INPUT_FILTER           = frameworks/av/media/libstagefright/codec2/docs/doxyfilter.sh
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis. Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match. The filters are a list of the form: pattern=filter
-# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
-# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
-# patterns match the file name, INPUT_FILTER is applied.
-#
-# Note that for custom extensions or not directly supported extensions you also
-# need to set EXTENSION_MAPPING for the extension otherwise the files are not
-# properly processed by doxygen.
-
-FILTER_PATTERNS        = 
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will also be used to filter the input files that are used for
-# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
-# The default value is: NO.
-
-FILTER_SOURCE_FILES    = YES
-
-# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
-# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
-# it is also possible to disable source filtering for a specific pattern using
-# *.ext= (so without naming a filter).
-# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
-
-FILTER_SOURCE_PATTERNS = 
-
-# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
-# is part of the input, its contents will be placed on the main page
-# (index.html). This can be useful if you have a project on for instance GitHub
-# and want to reuse the introduction page also for the doxygen output.
-
-USE_MDFILE_AS_MAINPAGE = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
-# generated. Documented entities will be cross-referenced with these sources.
-#
-# Note: To get rid of all source code in the generated output, make sure that
-# also VERBATIM_HEADERS is set to NO.
-# The default value is: NO.
-
-SOURCE_BROWSER         = YES
-
-# Setting the INLINE_SOURCES tag to YES will include the body of functions,
-# classes and enums directly into the documentation.
-# The default value is: NO.
-
-INLINE_SOURCES         = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
-# special comment blocks from generated source code fragments. Normal C, C++ and
-# Fortran comments will always remain visible.
-# The default value is: YES.
-
-STRIP_CODE_COMMENTS    = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
-# function all documented functions referencing it will be listed.
-# The default value is: NO.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES then for each documented function
-# all documented entities called/used by that function will be listed.
-# The default value is: NO.
-
-REFERENCES_RELATION    = YES
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
-# to YES then the hyperlinks from functions in REFERENCES_RELATION and
-# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
-# link to the documentation.
-# The default value is: YES.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
-# source code will show a tooltip with additional information such as prototype,
-# brief description and links to the definition and documentation. Since this
-# will make the HTML file larger and loading of large files a bit slower, you
-# can opt to disable this feature.
-# The default value is: YES.
-# This tag requires that the tag SOURCE_BROWSER is set to YES.
-
-SOURCE_TOOLTIPS        = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code will
-# point to the HTML generated by the htags(1) tool instead of doxygen built-in
-# source browser. The htags tool is part of GNU's global source tagging system
-# (see http://www.gnu.org/software/global/global.html). You will need version
-# 4.8.6 or higher.
-#
-# To use it do the following:
-# - Install the latest version of global
-# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
-# - Make sure the INPUT points to the root of the source tree
-# - Run doxygen as normal
-#
-# Doxygen will invoke htags (and that will in turn invoke gtags), so these
-# tools must be available from the command line (i.e. in the search path).
-#
-# The result: instead of the source browser generated by doxygen, the links to
-# source code will now point to the output of htags.
-# The default value is: NO.
-# This tag requires that the tag SOURCE_BROWSER is set to YES.
-
-USE_HTAGS              = NO
-
-# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
-# verbatim copy of the header file for each class for which an include is
-# specified. Set to NO to disable this.
-# See also: Section \class.
-# The default value is: YES.
-
-VERBATIM_HEADERS       = YES
-
-# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
-# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
-# cost of reduced performance. This can be particularly helpful with template
-# rich C++ code for which doxygen's built-in parser lacks the necessary type
-# information.
-# Note: The availability of this option depends on whether or not doxygen was
-# generated with the -Duse-libclang=ON option for CMake.
-# The default value is: NO.
-
-CLANG_ASSISTED_PARSING = YES
-
-# If clang assisted parsing is enabled you can provide the compiler with command
-# line options that you would normally use when invoking the compiler. Note that
-# the include paths will already be set by doxygen for the files and directories
-# specified with INPUT and INCLUDE_PATH.
-# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
-
-CLANG_OPTIONS          = -std=c++11
-
-#---------------------------------------------------------------------------
-# Configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
-# compounds will be generated. Enable this if the project contains a lot of
-# classes, structs, unions or interfaces.
-# The default value is: YES.
-
-ALPHABETICAL_INDEX     = YES
-
-# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
-# which the alphabetical index list will be split.
-# Minimum value: 1, maximum value: 20, default value: 5.
-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
-
-COLS_IN_ALPHA_INDEX    = 5
-
-# In case all classes in a project start with a common prefix, all classes will
-# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
-# can be used to specify a prefix (or a list of prefixes) that should be ignored
-# while generating the index headers.
-# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
-
-IGNORE_PREFIX          = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
-# The default value is: YES.
-
-GENERATE_HTML          = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: html.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_OUTPUT            = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
-# generated HTML page (for example: .htm, .php, .asp).
-# The default value is: .html.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_FILE_EXTENSION    = .html
-
-# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
-# each generated HTML page. If the tag is left blank doxygen will generate a
-# standard header.
-#
-# To get valid HTML the header file that includes any scripts and style sheets
-# that doxygen needs, which is dependent on the configuration options used (e.g.
-# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
-# default header using
-# doxygen -w html new_header.html new_footer.html new_stylesheet.css
-# YourConfigFile
-# and then modify the file new_header.html. See also section "Doxygen usage"
-# for information on how to generate the default header that doxygen normally
-# uses.
-# Note: The header is subject to change so you typically have to regenerate the
-# default header when upgrading to a newer version of doxygen. For a description
-# of the possible markers and block names see the documentation.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_HEADER            = 
-
-# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
-# generated HTML page. If the tag is left blank doxygen will generate a standard
-# footer. See HTML_HEADER for more information on how to generate a default
-# footer and what special commands can be used inside the footer. See also
-# section "Doxygen usage" for information on how to generate the default footer
-# that doxygen normally uses.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_FOOTER            = 
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
-# sheet that is used by each HTML page. It can be used to fine-tune the look of
-# the HTML output. If left blank doxygen will generate a default style sheet.
-# See also section "Doxygen usage" for information on how to generate the style
-# sheet that doxygen normally uses.
-# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
-# it is more robust and this tag (HTML_STYLESHEET) will in the future become
-# obsolete.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_STYLESHEET        = 
-
-# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
-# cascading style sheets that are included after the standard style sheets
-# created by doxygen. Using this option one can overrule certain style aspects.
-# This is preferred over using HTML_STYLESHEET since it does not replace the
-# standard style sheet and is therefore more robust against future updates.
-# Doxygen will copy the style sheet files to the output directory.
-# Note: The order of the extra style sheet files is of importance (e.g. the last
-# style sheet in the list overrules the setting of the previous ones in the
-# list). For an example see the documentation.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_EXTRA_STYLESHEET  = 
-
-# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the HTML output directory. Note
-# that these files will be copied to the base HTML output directory. Use the
-# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
-# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
-# files will be copied as-is; there are no commands or markers available.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_EXTRA_FILES       = 
-
-# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
-# will adjust the colors in the style sheet and background images according to
-# this color. Hue is specified as an angle on a colorwheel, see
-# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
-# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
-# purple, and 360 is red again.
-# Minimum value: 0, maximum value: 359, default value: 220.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_HUE    = 220
-
-# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
-# in the HTML output. For a value of 0 the output will use grayscales only. A
-# value of 255 will produce the most vivid colors.
-# Minimum value: 0, maximum value: 255, default value: 100.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_SAT    = 100
-
-# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
-# luminance component of the colors in the HTML output. Values below 100
-# gradually make the output lighter, whereas values above 100 make the output
-# darker. The value divided by 100 is the actual gamma applied, so 80 represents
-# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
-# change the gamma.
-# Minimum value: 40, maximum value: 240, default value: 80.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_COLORSTYLE_GAMMA  = 80
-
-# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
-# page will contain the date and time when the page was generated. Setting this
-# to YES can help to show when doxygen was last run and thus if the
-# documentation is up to date.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_TIMESTAMP         = NO
-
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
-# documentation will contain sections that can be hidden and shown after the
-# page has loaded.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_DYNAMIC_SECTIONS  = YES
-
-# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
-# shown in the various tree structured indices initially; the user can expand
-# and collapse entries dynamically later on. Doxygen will expand the tree to
-# such a level that at most the specified number of entries are visible (unless
-# a fully collapsed tree already exceeds this amount). So setting the number of
-# entries 1 will produce a full collapsed tree by default. 0 is a special value
-# representing an infinite number of entries and will result in a full expanded
-# tree by default.
-# Minimum value: 0, maximum value: 9999, default value: 100.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-HTML_INDEX_NUM_ENTRIES = 100
-
-# If the GENERATE_DOCSET tag is set to YES, additional index files will be
-# generated that can be used as input for Apple's Xcode 3 integrated development
-# environment (see: http://developer.apple.com/tools/xcode/), introduced with
-# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
-# Makefile in the HTML output directory. Running make will produce the docset in
-# that directory and running make install will install the docset in
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
-# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
-# for more information.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_DOCSET        = NO
-
-# This tag determines the name of the docset feed. A documentation feed provides
-# an umbrella under which multiple documentation sets from a single provider
-# (such as a company or product suite) can be grouped.
-# The default value is: Doxygen generated docs.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_FEEDNAME        = "Doxygen generated docs"
-
-# This tag specifies a string that should uniquely identify the documentation
-# set bundle. This should be a reverse domain-name style string, e.g.
-# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_BUNDLE_ID       = org.doxygen.Project
-
-# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
-# the documentation publisher. This should be a reverse domain-name style
-# string, e.g. com.mycompany.MyDocSet.documentation.
-# The default value is: org.doxygen.Publisher.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
-
-# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
-# The default value is: Publisher.
-# This tag requires that the tag GENERATE_DOCSET is set to YES.
-
-DOCSET_PUBLISHER_NAME  = Publisher
-
-# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
-# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
-# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
-# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
-# Windows.
-#
-# The HTML Help Workshop contains a compiler that can convert all HTML output
-# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
-# files are now used as the Windows 98 help format, and will replace the old
-# Windows help format (.hlp) on all Windows platforms in the future. Compressed
-# HTML files also contain an index, a table of contents, and you can search for
-# words in the documentation. The HTML workshop also contains a viewer for
-# compressed HTML files.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_HTMLHELP      = NO
-
-# The CHM_FILE tag can be used to specify the file name of the resulting .chm
-# file. You can add a path in front of the file if the result should not be
-# written to the html output directory.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-CHM_FILE               = 
-
-# The HHC_LOCATION tag can be used to specify the location (absolute path
-# including file name) of the HTML help compiler (hhc.exe). If non-empty,
-# doxygen will try to run the HTML help compiler on the generated index.hhp.
-# The file has to be specified with full path.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-HHC_LOCATION           = 
-
-# The GENERATE_CHI flag controls if a separate .chi index file is generated
-# (YES) or that it should be included in the master .chm file (NO).
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-GENERATE_CHI           = NO
-
-# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
-# and project file content.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-CHM_INDEX_ENCODING     = 
-
-# The BINARY_TOC flag controls whether a binary table of contents is generated
-# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
-# enables the Previous and Next buttons.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-BINARY_TOC             = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members to
-# the table of contents of the HTML help documentation and to the tree view.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
-
-TOC_EXPAND             = NO
-
-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
-# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
-# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
-# (.qch) of the generated HTML documentation.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_QHP           = NO
-
-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
-# the file name of the resulting .qch file. The path specified is relative to
-# the HTML output folder.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QCH_FILE               = 
-
-# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
-# Project output. For more information please see Qt Help Project / Namespace
-# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_NAMESPACE          = org.doxygen.Project
-
-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
-# Help Project output. For more information please see Qt Help Project / Virtual
-# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
-# folders).
-# The default value is: doc.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_VIRTUAL_FOLDER     = doc
-
-# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
-# filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
-# filters).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_CUST_FILTER_NAME   = 
-
-# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
-# custom filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
-# filters).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_CUST_FILTER_ATTRS  = 
-
-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
-# project's filter section matches. Qt Help Project / Filter Attributes (see:
-# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHP_SECT_FILTER_ATTRS  = 
-
-# The QHG_LOCATION tag can be used to specify the location of Qt's
-# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
-# generated .qhp file.
-# This tag requires that the tag GENERATE_QHP is set to YES.
-
-QHG_LOCATION           = 
-
-# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
-# generated, together with the HTML files, they form an Eclipse help plugin. To
-# install this plugin and make it available under the help contents menu in
-# Eclipse, the contents of the directory containing the HTML and XML files needs
-# to be copied into the plugins directory of eclipse. The name of the directory
-# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
-# After copying Eclipse needs to be restarted before the help appears.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_ECLIPSEHELP   = NO
-
-# A unique identifier for the Eclipse help plugin. When installing the plugin
-# the directory name containing the HTML and XML files should also have this
-# name. Each documentation set should have its own identifier.
-# The default value is: org.doxygen.Project.
-# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
-
-ECLIPSE_DOC_ID         = org.doxygen.Project
-
-# If you want full control over the layout of the generated HTML pages it might
-# be necessary to disable the index and replace it with your own. The
-# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
-# of each HTML page. A value of NO enables the index and the value YES disables
-# it. Since the tabs in the index contain the same information as the navigation
-# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-DISABLE_INDEX          = NO
-
-# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
-# structure should be generated to display hierarchical information. If the tag
-# value is set to YES, a side panel will be generated containing a tree-like
-# index structure (just like the one that is generated for HTML Help). For this
-# to work a browser that supports JavaScript, DHTML, CSS and frames is required
-# (i.e. any modern browser). Windows users are probably better off using the
-# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
-# further fine-tune the look of the index. As an example, the default style
-# sheet generated by doxygen has an example that shows how to put an image at
-# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
-# the same information as the tab index, you could consider setting
-# DISABLE_INDEX to YES when enabling this option.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-GENERATE_TREEVIEW      = YES
-
-# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
-# doxygen will group on one line in the generated HTML documentation.
-#
-# Note that a value of 0 will completely suppress the enum values from appearing
-# in the overview section.
-# Minimum value: 0, maximum value: 20, default value: 4.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-ENUM_VALUES_PER_LINE   = 4
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
-# to set the initial width (in pixels) of the frame in which the tree is shown.
-# Minimum value: 0, maximum value: 1500, default value: 250.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-TREEVIEW_WIDTH         = 250
-
-# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
-# external symbols imported via tag files in a separate window.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-EXT_LINKS_IN_WINDOW    = NO
-
-# Use this tag to change the font size of LaTeX formulas included as images in
-# the HTML documentation. When you change the font size after a successful
-# doxygen run you need to manually remove any form_*.png images from the HTML
-# output directory to force them to be regenerated.
-# Minimum value: 8, maximum value: 50, default value: 10.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-FORMULA_FONTSIZE       = 10
-
-# Use the FORMULA_TRANPARENT tag to determine whether or not the images
-# generated for formulas are transparent PNGs. Transparent PNGs are not
-# supported properly for IE 6.0, but are supported on all modern browsers.
-#
-# Note that when changing this option you need to delete any form_*.png files in
-# the HTML output directory before the changes have effect.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-FORMULA_TRANSPARENT    = YES
-
-# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
-# http://www.mathjax.org) which uses client side Javascript for the rendering
-# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
-# installed or if you want to formulas look prettier in the HTML output. When
-# enabled you may also need to install MathJax separately and configure the path
-# to it using the MATHJAX_RELPATH option.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-USE_MATHJAX            = NO
-
-# When MathJax is enabled you can set the default output format to be used for
-# the MathJax output. See the MathJax site (see:
-# http://docs.mathjax.org/en/latest/output.html) for more details.
-# Possible values are: HTML-CSS (which is slower, but has the best
-# compatibility), NativeMML (i.e. MathML) and SVG.
-# The default value is: HTML-CSS.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_FORMAT         = HTML-CSS
-
-# When MathJax is enabled you need to specify the location relative to the HTML
-# output directory using the MATHJAX_RELPATH option. The destination directory
-# should contain the MathJax.js script. For instance, if the mathjax directory
-# is located at the same level as the HTML output directory, then
-# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
-# Content Delivery Network so you can quickly see the result without installing
-# MathJax. However, it is strongly recommended to install a local copy of
-# MathJax from http://www.mathjax.org before deployment.
-# The default value is: http://cdn.mathjax.org/mathjax/latest.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
-
-# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
-# extension names that should be enabled during MathJax rendering. For example
-# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_EXTENSIONS     = 
-
-# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
-# of code that will be used on startup of the MathJax code. See the MathJax site
-# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
-# example see the documentation.
-# This tag requires that the tag USE_MATHJAX is set to YES.
-
-MATHJAX_CODEFILE       = 
-
-# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
-# the HTML output. The underlying search engine uses javascript and DHTML and
-# should work on any modern browser. Note that when using HTML help
-# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
-# there is already a search function so this one should typically be disabled.
-# For large projects the javascript based search engine can be slow, then
-# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
-# search using the keyboard; to jump to the search box use <access key> + S
-# (what the <access key> is depends on the OS and browser, but it is typically
-# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
-# key> to jump into the search results window, the results can be navigated
-# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
-# the search. The filter options can be selected when the cursor is inside the
-# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
-# to select a filter and <Enter> or <escape> to activate or cancel the filter
-# option.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_HTML is set to YES.
-
-SEARCHENGINE           = YES
-
-# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
-# implemented using a web server instead of a web client using Javascript. There
-# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
-# setting. When disabled, doxygen will generate a PHP script for searching and
-# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
-# and searching needs to be provided by external tools. See the section
-# "External Indexing and Searching" for details.
-# The default value is: NO.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SERVER_BASED_SEARCH    = NO
-
-# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
-# script for searching. Instead the search results are written to an XML file
-# which needs to be processed by an external indexer. Doxygen will invoke an
-# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
-# search results.
-#
-# Doxygen ships with an example indexer (doxyindexer) and search engine
-# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: http://xapian.org/).
-#
-# See the section "External Indexing and Searching" for details.
-# The default value is: NO.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTERNAL_SEARCH        = NO
-
-# The SEARCHENGINE_URL should point to a search engine hosted by a web server
-# which will return the search results when EXTERNAL_SEARCH is enabled.
-#
-# Doxygen ships with an example indexer (doxyindexer) and search engine
-# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: http://xapian.org/). See the section "External Indexing and
-# Searching" for details.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SEARCHENGINE_URL       = 
-
-# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
-# search data is written to a file for indexing by an external tool. With the
-# SEARCHDATA_FILE tag the name of this file can be specified.
-# The default file is: searchdata.xml.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-SEARCHDATA_FILE        = searchdata.xml
-
-# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
-# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
-# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
-# projects and redirect the results back to the right project.
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTERNAL_SEARCH_ID     = 
-
-# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
-# projects other than the one defined by this configuration file, but that are
-# all added to the same external search index. Each project needs to have a
-# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
-# to a relative location where the documentation can be found. The format is:
-# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
-# This tag requires that the tag SEARCHENGINE is set to YES.
-
-EXTRA_SEARCH_MAPPINGS  = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
-# The default value is: YES.
-
-GENERATE_LATEX         = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: latex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_OUTPUT           = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked.
-#
-# Note that when enabling USE_PDFLATEX this option is only used for generating
-# bitmaps for formulas in the HTML output, but not in the Makefile that is
-# written to the output directory.
-# The default file is: latex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_CMD_NAME         = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
-# index for LaTeX.
-# The default file is: makeindex.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-MAKEINDEX_CMD_NAME     = makeindex
-
-# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
-# documents. This may be useful for small projects and may help to save some
-# trees in general.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-COMPACT_LATEX          = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used by the
-# printer.
-# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
-# 14 inches) and executive (7.25 x 10.5 inches).
-# The default value is: a4.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-PAPER_TYPE             = a4
-
-# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
-# that should be included in the LaTeX output. The package can be specified just
-# by its name or with the correct syntax as to be used with the LaTeX
-# \usepackage command. To get the times font for instance you can specify :
-# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
-# To use the option intlimits with the amsmath package you can specify:
-# EXTRA_PACKAGES=[intlimits]{amsmath}
-# If left blank no extra packages will be included.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-EXTRA_PACKAGES         = 
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
-# generated LaTeX document. The header should contain everything until the first
-# chapter. If it is left blank doxygen will generate a standard header. See
-# section "Doxygen usage" for information on how to let doxygen write the
-# default header to a separate file.
-#
-# Note: Only use a user-defined header if you know what you are doing! The
-# following commands have a special meaning inside the header: $title,
-# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
-# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
-# string, for the replacement values of the other commands the user is referred
-# to HTML_HEADER.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_HEADER           = 
-
-# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
-# generated LaTeX document. The footer should contain everything after the last
-# chapter. If it is left blank doxygen will generate a standard footer. See
-# LATEX_HEADER for more information on how to generate a default footer and what
-# special commands can be used inside the footer.
-#
-# Note: Only use a user-defined footer if you know what you are doing!
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_FOOTER           = 
-
-# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
-# LaTeX style sheets that are included after the standard style sheets created
-# by doxygen. Using this option one can overrule certain style aspects. Doxygen
-# will copy the style sheet files to the output directory.
-# Note: The order of the extra style sheet files is of importance (e.g. the last
-# style sheet in the list overrules the setting of the previous ones in the
-# list).
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_EXTRA_STYLESHEET = 
-
-# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the LATEX_OUTPUT output
-# directory. Note that the files will be copied as-is; there are no commands or
-# markers available.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_EXTRA_FILES      = 
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
-# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
-# contain links (just like the HTML output) instead of page references. This
-# makes the output suitable for online browsing using a PDF viewer.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-PDF_HYPERLINKS         = YES
-
-# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
-# the PDF file directly from the LaTeX files. Set this option to YES, to get a
-# higher quality PDF documentation.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-USE_PDFLATEX           = YES
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
-# command to the generated LaTeX files. This will instruct LaTeX to keep running
-# if errors occur, instead of asking the user for help. This option is also used
-# when generating formulas in HTML.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_BATCHMODE        = NO
-
-# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
-# index chapters (such as File Index, Compound Index, etc.) in the output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_HIDE_INDICES     = NO
-
-# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
-# code with syntax highlighting in the LaTeX output.
-#
-# Note that which sources are shown also depends on other settings such as
-# SOURCE_BROWSER.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_SOURCE_CODE      = NO
-
-# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
-# bibliography, e.g. plainnat, or ieeetr. See
-# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
-# The default value is: plain.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_BIB_STYLE        = plain
-
-# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
-# page will contain the date and time when the page was generated. Setting this
-# to NO can help when comparing the output of multiple runs.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_LATEX is set to YES.
-
-LATEX_TIMESTAMP        = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
-# RTF output is optimized for Word 97 and may not look too pretty with other RTF
-# readers/editors.
-# The default value is: NO.
-
-GENERATE_RTF           = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: rtf.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_OUTPUT             = rtf
-
-# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
-# documents. This may be useful for small projects and may help to save some
-# trees in general.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-COMPACT_RTF            = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
-# contain hyperlink fields. The RTF file will contain links (just like the HTML
-# output) instead of page references. This makes the output suitable for online
-# browsing using Word or some other Word compatible readers that support those
-# fields.
-#
-# Note: WordPad (write) and others do not support links.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_HYPERLINKS         = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's config
-# file, i.e. a series of assignments. You only have to provide replacements,
-# missing definitions are set to their default value.
-#
-# See also section "Doxygen usage" for information on how to generate the
-# default style sheet that doxygen normally uses.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_STYLESHEET_FILE    = 
-
-# Set optional variables used in the generation of an RTF document. Syntax is
-# similar to doxygen's config file. A template extensions file can be generated
-# using doxygen -e rtf extensionFile.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_EXTENSIONS_FILE    = 
-
-# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
-# with syntax highlighting in the RTF output.
-#
-# Note that which sources are shown also depends on other settings such as
-# SOURCE_BROWSER.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_RTF is set to YES.
-
-RTF_SOURCE_CODE        = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
-# classes and files.
-# The default value is: NO.
-
-GENERATE_MAN           = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it. A directory man3 will be created inside the directory specified by
-# MAN_OUTPUT.
-# The default directory is: man.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_OUTPUT             = man
-
-# The MAN_EXTENSION tag determines the extension that is added to the generated
-# man pages. In case the manual section does not start with a number, the number
-# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
-# optional.
-# The default value is: .3.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_EXTENSION          = .3
-
-# The MAN_SUBDIR tag determines the name of the directory created within
-# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
-# MAN_EXTENSION with the initial . removed.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_SUBDIR             = 
-
-# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
-# will generate one additional man file for each entity documented in the real
-# man page(s). These additional files only source the real man page, but without
-# them the man command would be unable to find the correct page.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_MAN is set to YES.
-
-MAN_LINKS              = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
-# captures the structure of the code including all documentation.
-# The default value is: NO.
-
-GENERATE_XML           = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
-# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
-# it.
-# The default directory is: xml.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_OUTPUT             = xml
-
-# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
-# listings (including syntax highlighting and cross-referencing information) to
-# the XML output. Note that enabling this will significantly increase the size
-# of the XML output.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_XML is set to YES.
-
-XML_PROGRAMLISTING     = YES
-
-#---------------------------------------------------------------------------
-# Configuration options related to the DOCBOOK output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
-# that can be used to generate PDF.
-# The default value is: NO.
-
-GENERATE_DOCBOOK       = NO
-
-# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
-# front of it.
-# The default directory is: docbook.
-# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
-
-DOCBOOK_OUTPUT         = docbook
-
-# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
-# program listings (including syntax highlighting and cross-referencing
-# information) to the DOCBOOK output. Note that enabling this will significantly
-# increase the size of the DOCBOOK output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
-
-DOCBOOK_PROGRAMLISTING = NO
-
-#---------------------------------------------------------------------------
-# Configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
-# AutoGen Definitions (see http://autogen.sf.net) file that captures the
-# structure of the code including all documentation. Note that this feature is
-# still experimental and incomplete at the moment.
-# The default value is: NO.
-
-GENERATE_AUTOGEN_DEF   = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
-# file that captures the structure of the code including all documentation.
-#
-# Note that this feature is still experimental and incomplete at the moment.
-# The default value is: NO.
-
-GENERATE_PERLMOD       = NO
-
-# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
-# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
-# output from the Perl module output.
-# The default value is: NO.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_LATEX          = NO
-
-# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
-# formatted so it can be parsed by a human reader. This is useful if you want to
-# understand what is going on. On the other hand, if this tag is set to NO, the
-# size of the Perl module output will be much smaller and Perl will parse it
-# just the same.
-# The default value is: YES.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_PRETTY         = YES
-
-# The names of the make variables in the generated doxyrules.make file are
-# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
-# so different doxyrules.make files included by the same Makefile don't
-# overwrite each other's variables.
-# This tag requires that the tag GENERATE_PERLMOD is set to YES.
-
-PERLMOD_MAKEVAR_PREFIX = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
-# C-preprocessor directives found in the sources and include files.
-# The default value is: YES.
-
-ENABLE_PREPROCESSING   = YES
-
-# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
-# in the source code. If set to NO, only conditional compilation will be
-# performed. Macro expansion can be done in a controlled way by setting
-# EXPAND_ONLY_PREDEF to YES.
-# The default value is: NO.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-MACRO_EXPANSION        = YES
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
-# the macro expansion is limited to the macros specified with the PREDEFINED and
-# EXPAND_AS_DEFINED tags.
-# The default value is: NO.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-EXPAND_ONLY_PREDEF     = YES
-
-# If the SEARCH_INCLUDES tag is set to YES, the include files in the
-# INCLUDE_PATH will be searched if a #include is found.
-# The default value is: YES.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-SEARCH_INCLUDES        = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by the
-# preprocessor.
-# This tag requires that the tag SEARCH_INCLUDES is set to YES.
-
-INCLUDE_PATH           = /Volumes/A/aosp/prebuilts/clang/darwin-x86/host/3.6/lib/clang/3.6/include \
-                         /Volumes/A/aosp/external/libcxx/include \
-                         /Volumes/A/aosp/bionic/libc/include \
-                         /Volumes/A/aosp/bionic/libc/kernel/uapi \
-                         /Volumes/A/aosp/bionic/libc/kernel/uapi/asm-arm64 \
-                         /Volumes/A/aosp/external/gtest
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will be
-# used.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-INCLUDE_FILE_PATTERNS  = 
-
-# The PREDEFINED tag can be used to specify one or more macro names that are
-# defined before the preprocessor is started (similar to the -D option of e.g.
-# gcc). The argument of the tag is a list of macros of the form: name or
-# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
-# is assumed. To prevent a macro definition from being undefined via #undef or
-# recursively expanded use the := operator instead of the = operator.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-PREDEFINED             = __APPLE__= \
-                         __ANDROID__=1 \
-                         ANDROID:=1 \
-			 __unused=
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
-# tag can be used to specify a list of macro names that should be expanded. The
-# macro definition that is found in the sources will be used. Use the PREDEFINED
-# tag if you want to use a different macro definition that overrules the
-# definition found in the source code.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-EXPAND_AS_DEFINED      = DEFINE_FLEXIBLE_METHODS \
-                         DEFINE_CAST_OPERATORS
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
-# remove all references to function-like macros that are alone on a line, have
-# an all uppercase name, and do not end with a semicolon. Such function macros
-# are typically used for boiler-plate code, and will confuse the parser if not
-# removed.
-# The default value is: YES.
-# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
-
-SKIP_FUNCTION_MACROS   = YES
-
-#---------------------------------------------------------------------------
-# Configuration options related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES tag can be used to specify one or more tag files. For each tag
-# file the location of the external documentation should be added. The format of
-# a tag file without this location is as follows:
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where loc1 and loc2 can be relative or absolute paths or URLs. See the
-# section "Linking to external documentation" for more information about the use
-# of tag files.
-# Note: Each tag file must have a unique name (where the name does NOT include
-# the path). If a tag file is not located in the directory in which doxygen is
-# run, you must also specify the path to the tagfile here.
-
-TAGFILES               = 
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
-# tag file that is based on the input files it reads. See section "Linking to
-# external documentation" for more information about the usage of tag files.
-
-GENERATE_TAGFILE       = 
-
-# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
-# the class index. If set to NO, only the inherited external classes will be
-# listed.
-# The default value is: NO.
-
-ALLEXTERNALS           = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will be
-# listed.
-# The default value is: YES.
-
-EXTERNAL_GROUPS        = YES
-
-# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
-# the related pages index. If set to NO, only the current project's pages will
-# be listed.
-# The default value is: YES.
-
-EXTERNAL_PAGES         = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of 'which perl').
-# The default file (with absolute path) is: /usr/bin/perl.
-
-PERL_PATH              = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
-# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
-# NO turns the diagrams off. Note that this option also works with HAVE_DOT
-# disabled, but it is recommended to install and use dot, since it yields more
-# powerful graphs.
-# The default value is: YES.
-
-CLASS_DIAGRAMS         = YES
-
-# You can define message sequence charts within doxygen comments using the \msc
-# command. Doxygen will then run the mscgen tool (see:
-# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
-# documentation. The MSCGEN_PATH tag allows you to specify the directory where
-# the mscgen tool resides. If left empty the tool is assumed to be found in the
-# default search path.
-
-MSCGEN_PATH            = 
-
-# You can include diagrams made with dia in doxygen documentation. Doxygen will
-# then run dia to produce the diagram and insert it in the documentation. The
-# DIA_PATH tag allows you to specify the directory where the dia binary resides.
-# If left empty dia is assumed to be found in the default search path.
-
-DIA_PATH               = 
-
-# If set to YES the inheritance and collaboration graphs will hide inheritance
-# and usage relations if the target is undocumented or is not a class.
-# The default value is: YES.
-
-HIDE_UNDOC_RELATIONS   = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz (see:
-# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
-# Bell Labs. The other options in this section have no effect if this option is
-# set to NO
-# The default value is: NO.
-
-HAVE_DOT               = NO
-
-# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
-# to run in parallel. When set to 0 doxygen will base this on the number of
-# processors available in the system. You can set it explicitly to a value
-# larger than 0 to get control over the balance between CPU load and processing
-# speed.
-# Minimum value: 0, maximum value: 32, default value: 0.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_NUM_THREADS        = 0
-
-# When you want a differently looking font in the dot files that doxygen
-# generates you can specify the font name using DOT_FONTNAME. You need to make
-# sure dot is able to find the font, which can be done by putting it in a
-# standard location or by setting the DOTFONTPATH environment variable or by
-# setting DOT_FONTPATH to the directory containing the font.
-# The default value is: Helvetica.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTNAME           = Helvetica
-
-# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
-# dot graphs.
-# Minimum value: 4, maximum value: 24, default value: 10.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTSIZE           = 10
-
-# By default doxygen will tell dot to use the default font as specified with
-# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
-# the path where dot can find it using this tag.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_FONTPATH           = 
-
-# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
-# each documented class showing the direct and indirect inheritance relations.
-# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CLASS_GRAPH            = YES
-
-# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
-# graph for each documented class showing the direct and indirect implementation
-# dependencies (inheritance, containment, and class references variables) of the
-# class with other documented classes.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-COLLABORATION_GRAPH    = YES
-
-# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
-# groups, showing the direct groups dependencies.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GROUP_GRAPHS           = YES
-
-# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-UML_LOOK               = NO
-
-# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
-# class node. If there are many fields or methods and many nodes the graph may
-# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
-# number of items for each type to make the size more manageable. Set this to 0
-# for no limit. Note that the threshold may be exceeded by 50% before the limit
-# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
-# but if the number exceeds 15, the total amount of fields shown is limited to
-# 10.
-# Minimum value: 0, maximum value: 100, default value: 10.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-UML_LIMIT_NUM_FIELDS   = 10
-
-# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
-# collaboration graphs will show the relations between templates and their
-# instances.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-TEMPLATE_RELATIONS     = NO
-
-# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
-# YES then doxygen will generate a graph for each documented file showing the
-# direct and indirect include dependencies of the file with other documented
-# files.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INCLUDE_GRAPH          = YES
-
-# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
-# set to YES then doxygen will generate a graph for each documented file showing
-# the direct and indirect include dependencies of the file with other documented
-# files.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INCLUDED_BY_GRAPH      = YES
-
-# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
-# dependency graph for every global function or class method.
-#
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable call graphs for selected
-# functions only using the \callgraph command. Disabling a call graph can be
-# accomplished by means of the command \hidecallgraph.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CALL_GRAPH             = NO
-
-# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
-# dependency graph for every global function or class method.
-#
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable caller graphs for selected
-# functions only using the \callergraph command. Disabling a caller graph can be
-# accomplished by means of the command \hidecallergraph.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-CALLER_GRAPH           = NO
-
-# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
-# hierarchy of all classes instead of a textual one.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GRAPHICAL_HIERARCHY    = YES
-
-# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
-# dependencies a directory has on other directories in a graphical way. The
-# dependency relations are determined by the #include relations between the
-# files in the directories.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DIRECTORY_GRAPH        = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. For an explanation of the image formats see the section
-# output formats in the documentation of the dot tool (Graphviz (see:
-# http://www.graphviz.org/)).
-# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
-# to make the SVG files visible in IE 9+ (other browsers do not have this
-# requirement).
-# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
-# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
-# png:gdiplus:gdiplus.
-# The default value is: png.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_IMAGE_FORMAT       = png
-
-# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
-# enable generation of interactive SVG images that allow zooming and panning.
-#
-# Note that this requires a modern browser other than Internet Explorer. Tested
-# and working are Firefox, Chrome, Safari, and Opera.
-# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
-# the SVG files visible. Older versions of IE do not have SVG support.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-INTERACTIVE_SVG        = NO
-
-# The DOT_PATH tag can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_PATH               = 
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the \dotfile
-# command).
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOTFILE_DIRS           = 
-
-# The MSCFILE_DIRS tag can be used to specify one or more directories that
-# contain msc files that are included in the documentation (see the \mscfile
-# command).
-
-MSCFILE_DIRS           = 
-
-# The DIAFILE_DIRS tag can be used to specify one or more directories that
-# contain dia files that are included in the documentation (see the \diafile
-# command).
-
-DIAFILE_DIRS           = 
-
-# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
-# path where java can find the plantuml.jar file. If left blank, it is assumed
-# PlantUML is not used or called during a preprocessing step. Doxygen will
-# generate a warning when it encounters a \startuml command in this case and
-# will not generate output for the diagram.
-
-PLANTUML_JAR_PATH      = 
-
-# When using plantuml, the specified paths are searched for files specified by
-# the !include statement in a plantuml block.
-
-PLANTUML_INCLUDE_PATH  = 
-
-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
-# that will be shown in the graph. If the number of nodes in a graph becomes
-# larger than this value, doxygen will truncate the graph, which is visualized
-# by representing a node as a red box. Note that doxygen if the number of direct
-# children of the root node in a graph is already larger than
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
-# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
-# Minimum value: 0, maximum value: 10000, default value: 50.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_GRAPH_MAX_NODES    = 50
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
-# generated by dot. A depth value of 3 means that only nodes reachable from the
-# root by following a path via at most 3 edges will be shown. Nodes that lay
-# further from the root node will be omitted. Note that setting this option to 1
-# or 2 may greatly reduce the computation time needed for large code bases. Also
-# note that the size of a graph can be further restricted by
-# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
-# Minimum value: 0, maximum value: 1000, default value: 0.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-MAX_DOT_GRAPH_DEPTH    = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, because dot on Windows does not seem
-# to support this out of the box.
-#
-# Warning: Depending on the platform used, enabling this option may lead to
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
-# read).
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_TRANSPARENT        = NO
-
-# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10) support
-# this, this feature is disabled by default.
-# The default value is: NO.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_MULTI_TARGETS      = NO
-
-# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
-# explaining the meaning of the various boxes and arrows in the dot generated
-# graphs.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-GENERATE_LEGEND        = YES
-
-# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
-# files that are used to generate the various graphs.
-# The default value is: YES.
-# This tag requires that the tag HAVE_DOT is set to YES.
-
-DOT_CLEANUP            = YES
diff --git a/media/libstagefright/codec2/hidl/impl/1.0/Android.bp b/media/libstagefright/codec2/hidl/impl/1.0/Android.bp
deleted file mode 100644
index 3d930c6..0000000
--- a/media/libstagefright/codec2/hidl/impl/1.0/Android.bp
+++ /dev/null
@@ -1,42 +0,0 @@
-cc_library {
-    name: "libstagefright_codec2_hidl@1.0",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
-
-    defaults: ["hidl_defaults"],
-
-    srcs: [
-        "Component.cpp",
-        "ComponentStore.cpp",
-        "Configurable.cpp",
-        "types.cpp",
-    ],
-
-    shared_libs: [
-        "android.hardware.media.bufferpool@1.0",
-        "libcutils",
-        "libhidlbase",
-        "libhidltransport",
-        "liblog",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libutils",
-        "vendor.google.media.c2@1.0",
-    ],
-
-    export_include_dirs: [
-        "include",
-    ],
-
-    export_shared_lib_headers: [
-        "libstagefright_codec2",
-    ],
-
-    // Private include directories
-    header_libs: [
-        "libstagefright_codec2_internal",
-    ],
-}
-
diff --git a/media/libstagefright/codec2/hidl/impl/1.0/Component.cpp b/media/libstagefright/codec2/hidl/impl/1.0/Component.cpp
deleted file mode 100644
index 2b34fde..0000000
--- a/media/libstagefright/codec2/hidl/impl/1.0/Component.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (C) 2018 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 "Codec2-Component"
-#include <log/log.h>
-
-#include <codec2/hidl/1.0/Component.h>
-#include <codec2/hidl/1.0/types.h>
-
-namespace vendor {
-namespace google {
-namespace media {
-namespace c2 {
-namespace V1_0 {
-namespace implementation {
-
-using namespace ::android;
-
-// Implementation of ConfigurableC2Intf based on C2ComponentInterface
-struct CompIntf : public ConfigurableC2Intf {
-    CompIntf(const std::shared_ptr<C2ComponentInterface>& intf) :
-        ConfigurableC2Intf(intf->getName()),
-        mIntf(intf) {
-    }
-
-    virtual c2_status_t config(
-            const std::vector<C2Param*>& params,
-            c2_blocking_t mayBlock,
-            std::vector<std::unique_ptr<C2SettingResult>>* const failures
-            ) override {
-        return mIntf->config_vb(params, mayBlock, failures);
-    }
-
-    virtual c2_status_t query(
-            const std::vector<C2Param::Index>& indices,
-            c2_blocking_t mayBlock,
-            std::vector<std::unique_ptr<C2Param>>* const params) const override {
-        return mIntf->query_vb({}, indices, mayBlock, params);
-    }
-
-    virtual c2_status_t querySupportedParams(
-            std::vector<std::shared_ptr<C2ParamDescriptor>>* const params
-            ) const override {
-        return mIntf->querySupportedParams_nb(params);
-    }
-
-    virtual c2_status_t querySupportedValues(
-            std::vector<C2FieldSupportedValuesQuery>& fields,
-            c2_blocking_t mayBlock) const override {
-        return mIntf->querySupportedValues_vb(fields, mayBlock);
-    }
-
-protected:
-    std::shared_ptr<C2ComponentInterface> mIntf;
-};
-
-// ComponentInterface
-ComponentInterface::ComponentInterface(
-        const std::shared_ptr<C2ComponentInterface>& intf,
-        const sp<ComponentStore>& store) :
-    Configurable(new CachedConfigurable(std::make_unique<CompIntf>(intf))),
-    mInterface(intf) {
-    mInit = init(store.get());
-}
-
-c2_status_t ComponentInterface::status() const {
-    return mInit;
-}
-
-// ComponentListener wrapper
-struct Listener : public C2Component::Listener {
-    Listener(const wp<IComponentListener>& listener) : mListener(listener) {
-        // TODO: Should we track interface errors? We could reuse onError() or
-        // create our own error channel.
-    }
-
-    virtual void onError_nb(
-            std::weak_ptr<C2Component> /* c2component */,
-            uint32_t errorCode) override {
-        sp<IComponentListener> listener = mListener.promote();
-        if (listener) {
-            listener->onError(Status::OK, errorCode);
-        }
-    }
-
-    virtual void onTripped_nb(
-            std::weak_ptr<C2Component> /* c2component */,
-            std::vector<std::shared_ptr<C2SettingResult>> c2settingResult
-            ) override {
-        sp<IComponentListener> listener = mListener.promote();
-        if (listener) {
-            hidl_vec<SettingResult> settingResults(c2settingResult.size());
-            size_t ix = 0;
-            for (const std::shared_ptr<C2SettingResult> &c2result :
-                    c2settingResult) {
-                if (c2result) {
-                    if (objcpy(&settingResults[ix++], *c2result) != Status::OK) {
-                        break;
-                    }
-                }
-            }
-            settingResults.resize(ix);
-            listener->onTripped(settingResults);
-        }
-    }
-
-    virtual void onWorkDone_nb(
-            std::weak_ptr<C2Component> /* c2component */,
-            std::list<std::unique_ptr<C2Work>> c2workItems) override {
-        sp<IComponentListener> listener = mListener.promote();
-        if (listener) {
-            WorkBundle workBundle;
-
-            // TODO: Connect with bufferpool API to send Works & Buffers
-            if (objcpy(&workBundle, c2workItems) != Status::OK) {
-                ALOGE("onWorkDone() received corrupted work items.");
-                return;
-            }
-            listener->onWorkDone(workBundle);
-
-            // Finish buffer transfers: nothing else to do
-        }
-    }
-
-protected:
-    wp<IComponentListener> mListener;
-};
-
-// Component
-Component::Component(
-        const std::shared_ptr<C2Component>& component,
-        const sp<IComponentListener>& listener,
-        const sp<ComponentStore>& store) :
-    Configurable(new CachedConfigurable(
-            std::make_unique<CompIntf>(component->intf()))),
-    mComponent(component),
-    mInterface(component->intf()),
-    mListener(listener) /* , // TODO: Do we need store for anything?
-    mStore(store)*/ {
-    std::shared_ptr<C2Component::Listener> c2listener =
-            std::make_shared<Listener>(listener);
-    c2_status_t res = mComponent->setListener_vb(c2listener, C2_DONT_BLOCK);
-    // Retrieve supported parameters from store
-    // TODO: We could cache this per component/interface type
-    mInit = init(store.get());
-    mInit = mInit != C2_OK ? res : mInit;
-}
-
-// Methods from ::android::hardware::media::c2::V1_0::IComponent
-Return<Status> Component::queue(const WorkBundle& workBundle) {
-    std::list<std::unique_ptr<C2Work>> c2works;
-
-    // TODO: Connect with bufferpool API for buffer transfers
-    if (objcpy(&c2works, workBundle) != C2_OK) {
-        return Status::CORRUPTED;
-    }
-    return static_cast<Status>(mComponent->queue_nb(&c2works));
-}
-
-Return<void> Component::flush(flush_cb _hidl_cb) {
-    std::list<std::unique_ptr<C2Work>> c2flushedWorks;
-    c2_status_t c2res = mComponent->flush_sm(
-            C2Component::FLUSH_COMPONENT,
-            &c2flushedWorks);
-    WorkBundle flushedWorkBundle;
-
-    Status res = static_cast<Status>(c2res);
-    if (c2res == C2_OK) {
-        // TODO: Connect with bufferpool API for buffer transfers
-        res = objcpy(&flushedWorkBundle, c2flushedWorks);
-    }
-    _hidl_cb(res, flushedWorkBundle);
-    return Void();
-}
-
-Return<Status> Component::drain(bool withEos) {
-    return static_cast<Status>(mComponent->drain_nb(withEos ?
-            C2Component::DRAIN_COMPONENT_WITH_EOS :
-            C2Component::DRAIN_COMPONENT_NO_EOS));
-}
-
-Return<Status> Component::connectToInputSurface(const sp<IInputSurface>& surface) {
-    // TODO implement
-    (void)surface;
-    return Status::OK;
-}
-
-Return<Status> Component::connectToOmxInputSurface(
-        const sp<::android::hardware::graphics::bufferqueue::V1_0::
-        IGraphicBufferProducer>& producer,
-        const sp<::android::hardware::media::omx::V1_0::
-        IGraphicBufferSource>& source) {
-    // TODO implement
-    (void)producer;
-    (void)source;
-    return Status::OK;
-}
-
-Return<Status> Component::disconnectFromInputSurface() {
-    // TODO implement
-    return Status::OK;
-}
-
-Return<void> Component::createBlockPool(uint32_t allocatorId, createBlockPool_cb _hidl_cb) {
-    // TODO implement
-    (void)allocatorId;
-    _hidl_cb(Status::OK, 0 /* blockPoolId */, nullptr /* configurable */);
-    return Void();
-}
-
-Return<Status> Component::start() {
-    return static_cast<Status>(mComponent->start());
-}
-
-Return<Status> Component::stop() {
-    return static_cast<Status>(mComponent->stop());
-}
-
-Return<Status> Component::reset() {
-    return static_cast<Status>(mComponent->reset());
-}
-
-Return<Status> Component::release() {
-    return static_cast<Status>(mComponent->release());
-}
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace c2
-}  // namespace media
-}  // namespace google
-}  // namespace vendor
diff --git a/media/libstagefright/codec2/hidl/impl/1.0/ComponentStore.cpp b/media/libstagefright/codec2/hidl/impl/1.0/ComponentStore.cpp
deleted file mode 100644
index 4d51fba..0000000
--- a/media/libstagefright/codec2/hidl/impl/1.0/ComponentStore.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2018 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 "Codec2-ComponentStore"
-#include <log/log.h>
-
-#include <codec2/hidl/1.0/ComponentStore.h>
-#include <codec2/hidl/1.0/Component.h>
-#include <codec2/hidl/1.0/ConfigurableC2Intf.h>
-#include <codec2/hidl/1.0/types.h>
-
-namespace vendor {
-namespace google {
-namespace media {
-namespace c2 {
-namespace V1_0 {
-namespace implementation {
-
-using namespace ::android;
-
-struct StoreIntf : public ConfigurableC2Intf {
-    StoreIntf(const std::shared_ptr<C2ComponentStore>& store) :
-        ConfigurableC2Intf(store ? store->getName() : ""),
-        mStore(store) {
-    }
-
-    c2_status_t config(
-            const std::vector<C2Param*> &params,
-            c2_blocking_t mayBlock,
-            std::vector<std::unique_ptr<C2SettingResult>> *const failures
-            ) override {
-        // Assume all params are blocking
-        // TODO: Filter for supported params
-        if (mayBlock == C2_DONT_BLOCK && params.size() != 0) {
-            return C2_BLOCKING;
-        }
-        return mStore->config_sm(params, failures);
-    }
-
-    c2_status_t query(
-            const std::vector<C2Param::Index> &indices,
-            c2_blocking_t mayBlock,
-            std::vector<std::unique_ptr<C2Param>> *const params) const override {
-        // Assume all params are blocking
-        // TODO: Filter for supported params
-        if (mayBlock == C2_DONT_BLOCK && indices.size() != 0) {
-            return C2_BLOCKING;
-        }
-        return mStore->query_sm({}, indices, params);
-    }
-
-    c2_status_t querySupportedParams(
-            std::vector<std::shared_ptr<C2ParamDescriptor>> *const params
-            ) const override {
-        return mStore->querySupportedParams_nb(params);
-    }
-
-    c2_status_t querySupportedValues(
-            std::vector<C2FieldSupportedValuesQuery> &fields,
-            c2_blocking_t mayBlock) const override {
-        // Assume all params are blocking
-        // TODO: Filter for supported params
-        if (mayBlock == C2_DONT_BLOCK && fields.size() != 0) {
-            return C2_BLOCKING;
-        }
-        return mStore->querySupportedValues_sm(fields);
-    }
-
-protected:
-    std::shared_ptr<C2ComponentStore> mStore;
-};
-
-
-ComponentStore::ComponentStore(const std::shared_ptr<C2ComponentStore>& store) :
-    Configurable(new CachedConfigurable(std::make_unique<StoreIntf>(store))),
-    mStore(store) {
-    // Retrieve struct descriptors
-    mParamReflector = mStore->getParamReflector();
-
-    // Retrieve supported parameters from store
-    mInit = init(this);
-}
-
-c2_status_t ComponentStore::validateSupportedParams(
-        const std::vector<std::shared_ptr<C2ParamDescriptor>>& params) {
-    c2_status_t res = C2_OK;
-
-    for (const std::shared_ptr<C2ParamDescriptor> &desc : params) {
-        if (!desc) {
-            // All descriptors should be valid
-            res = res ? res : C2_BAD_VALUE;
-            continue;
-        }
-        C2Param::CoreIndex coreIndex = desc->index().coreIndex();
-        auto it = mStructDescriptors.find(coreIndex);
-        if (it == mStructDescriptors.end()) {
-            std::shared_ptr<C2StructDescriptor> structDesc =
-                    mParamReflector->describe(coreIndex);
-            if (!structDesc) {
-                // All supported params must be described
-                res = C2_BAD_INDEX;
-            }
-            mStructDescriptors.insert({ coreIndex, structDesc });
-        }
-    }
-    return res;
-}
-
-// Methods from ::android::hardware::media::c2::V1_0::IComponentStore
-Return<void> ComponentStore::createComponent(
-        const hidl_string& name,
-        const sp<IComponentListener>& listener,
-        // TODO: Return the pool if the component has it.
-        const sp<IClientManager>& /* pool */,
-        createComponent_cb _hidl_cb) {
-    std::shared_ptr<C2Component> c2component;
-    c2_status_t res = mStore->createComponent(name, &c2component);
-    sp<IComponent> component;
-    if (res == C2_OK) {
-        component = new Component(c2component, listener, this);
-    }
-    _hidl_cb((Status)res, component);
-    return Void();
-}
-
-Return<void> ComponentStore::createInterface(
-        const hidl_string& name,
-        createInterface_cb _hidl_cb) {
-    std::shared_ptr<C2ComponentInterface> c2interface;
-    c2_status_t res = mStore->createInterface(name, &c2interface);
-    sp<IComponentInterface> interface;
-    if (res == C2_OK) {
-        interface = new ComponentInterface(c2interface, this);
-    }
-    _hidl_cb((Status)res, interface);
-    return Void();
-}
-
-Return<void> ComponentStore::listComponents(listComponents_cb _hidl_cb) {
-    std::vector<std::shared_ptr<const C2Component::Traits>> c2traits =
-            mStore->listComponents();
-    hidl_vec<IComponentStore::ComponentTraits> traits(c2traits.size());
-    size_t ix = 0;
-    for (const std::shared_ptr<const C2Component::Traits> &c2trait : c2traits) {
-        if (c2trait) {
-            objcpy(&traits[ix++], *c2trait);
-        }
-    }
-    traits.resize(ix);
-    _hidl_cb(traits);
-    return Void();
-}
-
-Return<sp<IInputSurface>> ComponentStore::createInputSurface() {
-    // TODO implement
-    return sp<IInputSurface> {};
-}
-
-Return<void> ComponentStore::getStructDescriptors(
-        const hidl_vec<uint32_t>& indices,
-        getStructDescriptors_cb _hidl_cb) {
-    hidl_vec<StructDescriptor> descriptors(indices.size());
-    size_t dstIx = 0;
-    Status res;
-    for (size_t srcIx = 0; srcIx < indices.size(); ++srcIx) {
-        const auto item = mStructDescriptors.find(
-                C2Param::CoreIndex(indices[srcIx]).coreIndex());
-        if (item == mStructDescriptors.end()) {
-            res = Status::NOT_FOUND;
-        } else if (item->second) {
-            objcpy(&descriptors[dstIx++], *item->second);
-        } else {
-            res = Status::NO_MEMORY;
-        }
-    }
-    descriptors.resize(dstIx);
-    _hidl_cb(res, descriptors);
-    return Void();
-}
-
-Return<sp<IClientManager>> ComponentStore::getPoolClientManager() {
-    // TODO implement
-    return sp<IClientManager> {};
-}
-
-Return<Status> ComponentStore::copyBuffer(const Buffer& src, const Buffer& dst) {
-    // TODO implement
-    (void)src;
-    (void)dst;
-    return Status::OMITTED;
-}
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace c2
-}  // namespace media
-}  // namespace google
-}  // namespace vendor
diff --git a/media/libstagefright/codec2/hidl/impl/1.0/Configurable.cpp b/media/libstagefright/codec2/hidl/impl/1.0/Configurable.cpp
deleted file mode 100644
index 3f041a9..0000000
--- a/media/libstagefright/codec2/hidl/impl/1.0/Configurable.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (C) 2018 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 "Codec2-Configurable"
-#include <log/log.h>
-
-#include <codec2/hidl/1.0/Configurable.h>
-#include <codec2/hidl/1.0/ComponentStore.h>
-#include <codec2/hidl/1.0/types.h>
-#include <C2ParamInternal.h>
-
-namespace vendor {
-namespace google {
-namespace media {
-namespace c2 {
-namespace V1_0 {
-namespace implementation {
-
-using namespace ::android;
-
-CachedConfigurable::CachedConfigurable(
-        std::unique_ptr<ConfigurableC2Intf>&& intf) :
-    mIntf(std::move(intf)) {
-}
-
-c2_status_t CachedConfigurable::init(ComponentStore* store) {
-    // Retrieve supported parameters from store
-    c2_status_t init = mIntf->querySupportedParams(&mSupportedParams);
-    c2_status_t validate = store->validateSupportedParams(mSupportedParams);
-    return init == C2_OK ? C2_OK : validate;
-}
-
-// Methods from ::android::hardware::media::c2::V1_0::IConfigurable follow.
-Return<void> CachedConfigurable::getName(getName_cb _hidl_cb) {
-    _hidl_cb(mIntf->getName());
-    return Void();
-}
-
-Return<void> CachedConfigurable::query(
-        const hidl_vec<uint32_t>& indices,
-        bool mayBlock,
-        query_cb _hidl_cb) {
-    typedef C2Param::Index Index;
-    std::vector<Index> c2heapParamIndices(
-            (Index*)indices.data(),
-            (Index*)indices.data() + indices.size());
-    std::vector<std::unique_ptr<C2Param>> c2heapParams;
-    c2_status_t c2res = mIntf->query(
-            c2heapParamIndices,
-            mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK,
-            &c2heapParams);
-
-    hidl_vec<uint8_t> params;
-    createParamsBlob(&params, c2heapParams);
-    _hidl_cb(static_cast<Status>(c2res), params);
-
-    return Void();
-}
-
-Return<void> CachedConfigurable::config(
-        const hidl_vec<uint8_t>& inParams,
-        bool mayBlock,
-        config_cb _hidl_cb) {
-    std::vector<C2Param*> c2params;
-    if (parseParamsBlob(&c2params, inParams) != C2_OK) {
-        _hidl_cb(Status::CORRUPTED,
-                hidl_vec<SettingResult>(),
-                hidl_vec<uint8_t>());
-        return Void();
-    }
-    // TODO: check if blob was invalid
-    std::vector<std::unique_ptr<C2SettingResult>> c2failures;
-    c2_status_t c2res = mIntf->config(
-            c2params,
-            mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK,
-            &c2failures);
-    hidl_vec<SettingResult> failures(c2failures.size());
-    {
-        size_t ix = 0;
-        for (const std::unique_ptr<C2SettingResult>& c2result : c2failures) {
-            if (c2result) {
-                objcpy(&failures[ix++], *c2result);
-            }
-        }
-        failures.resize(ix);
-    }
-    hidl_vec<uint8_t> outParams;
-    createParamsBlob(&outParams, c2params);
-    _hidl_cb((Status)c2res, failures, outParams);
-    return Void();
-}
-
-Return<void> CachedConfigurable::querySupportedParams(
-        uint32_t start,
-        uint32_t count,
-        querySupportedParams_cb _hidl_cb) {
-    C2LinearRange request = C2LinearCapacity(mSupportedParams.size()).range(
-            start, count);
-    hidl_vec<ParamDescriptor> params(request.size());
-    Status res = Status::OK;
-    size_t dstIx = 0;
-    for (size_t srcIx = request.offset(); srcIx < request.endOffset(); ++srcIx) {
-        if (mSupportedParams[srcIx]) {
-            objcpy(&params[dstIx++], *mSupportedParams[srcIx]);
-        } else {
-            res = Status::CORRUPTED;
-        }
-    }
-    params.resize(dstIx);
-    _hidl_cb(res, params);
-    return Void();
-}
-
-Return<void> CachedConfigurable::querySupportedValues(
-        const hidl_vec<FieldSupportedValuesQuery>& inFields,
-        bool mayBlock,
-        querySupportedValues_cb _hidl_cb) {
-    std::vector<C2FieldSupportedValuesQuery> c2fields;
-    {
-        // C2FieldSupportedValuesQuery objects are restricted in that some
-        // members are const.
-        // C2ParamField - required for its constructor - has no constructors
-        // from fields. Use C2ParamInspector.
-        for (const FieldSupportedValuesQuery &query : inFields) {
-            c2fields.emplace_back(_C2ParamInspector::CreateParamField(
-                    query.field.index,
-                    query.field.fieldId.offset,
-                    query.field.fieldId.size),
-                    query.type == FieldSupportedValuesQuery::Type::POSSIBLE ?
-                    C2FieldSupportedValuesQuery::POSSIBLE :
-                    C2FieldSupportedValuesQuery::CURRENT);
-        }
-    }
-    c2_status_t c2res = mIntf->querySupportedValues(
-            c2fields,
-            mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK);
-    hidl_vec<FieldSupportedValuesQueryResult> outFields(inFields.size());
-    {
-        size_t ix = 0;
-        for (const C2FieldSupportedValuesQuery &result : c2fields) {
-            objcpy(&outFields[ix++], result);
-        }
-    }
-    _hidl_cb((Status)c2res, outFields);
-    return Void();
-}
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace c2
-}  // namespace media
-}  // namespace google
-}  // namespace vendor
diff --git a/media/libstagefright/codec2/hidl/impl/1.0/include/codec2/hidl/1.0/Component.h b/media/libstagefright/codec2/hidl/impl/1.0/include/codec2/hidl/1.0/Component.h
deleted file mode 100644
index 0308fe0..0000000
--- a/media/libstagefright/codec2/hidl/impl/1.0/include/codec2/hidl/1.0/Component.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef VENDOR_GOOGLE_MEDIA_C2_V1_0_COMPONENT_H
-#define VENDOR_GOOGLE_MEDIA_C2_V1_0_COMPONENT_H
-
-#include <codec2/hidl/1.0/Configurable.h>
-
-#include <vendor/google/media/c2/1.0/IComponentListener.h>
-#include <vendor/google/media/c2/1.0/IComponentStore.h>
-#include <vendor/google/media/c2/1.0/IComponent.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-
-#include <C2Component.h>
-#include <C2.h>
-
-namespace vendor {
-namespace google {
-namespace media {
-namespace c2 {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
-
-struct ComponentStore;
-
-struct ComponentInterface : public Configurable<IComponentInterface> {
-    ComponentInterface(
-            const std::shared_ptr<C2ComponentInterface>& interface,
-            const sp<ComponentStore>& store);
-    c2_status_t status() const;
-
-protected:
-    c2_status_t mInit;
-    std::shared_ptr<C2ComponentInterface> mInterface;
-    // sp<ComponentStore> mStore; // TODO needed?
-};
-
-struct Component : public Configurable<IComponent> {
-    Component(
-            const std::shared_ptr<C2Component>&,
-            const sp<IComponentListener>& listener,
-            const sp<ComponentStore>& store);
-
-    // Methods from gIComponent follow.
-    virtual Return<Status> queue(const WorkBundle& workBundle) override;
-    virtual Return<void> flush(flush_cb _hidl_cb) override;
-    virtual Return<Status> drain(bool withEos) override;
-    virtual Return<Status> connectToInputSurface(
-            const sp<IInputSurface>& surface) override;
-    virtual Return<Status> connectToOmxInputSurface(
-            const sp<::android::hardware::graphics::bufferqueue::V1_0::
-            IGraphicBufferProducer>& producer,
-            const sp<::android::hardware::media::omx::V1_0::
-            IGraphicBufferSource>& source) override;
-    virtual Return<Status> disconnectFromInputSurface() override;
-    virtual Return<void> createBlockPool(
-            uint32_t allocatorId,
-            createBlockPool_cb _hidl_cb) override;
-    virtual Return<Status> start() override;
-    virtual Return<Status> stop() override;
-    virtual Return<Status> reset() override;
-    virtual Return<Status> release() override;
-
-protected:
-    c2_status_t mInit;
-    std::shared_ptr<C2Component> mComponent;
-    std::shared_ptr<C2ComponentInterface> mInterface;
-    sp<IComponentListener> mListener;
-    // sp<ComponentStore> mStore; // TODO needed?
-};
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace c2
-}  // namespace media
-}  // namespace google
-}  // namespace vendor
-
-#endif  // VENDOR_GOOGLE_MEDIA_C2_V1_0_COMPONENT_H
diff --git a/media/libstagefright/codec2/hidl/impl/1.0/include/codec2/hidl/1.0/ComponentStore.h b/media/libstagefright/codec2/hidl/impl/1.0/include/codec2/hidl/1.0/ComponentStore.h
deleted file mode 100644
index c3f92a0..0000000
--- a/media/libstagefright/codec2/hidl/impl/1.0/include/codec2/hidl/1.0/ComponentStore.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2018 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 VENDOR_GOOGLE_MEDIA_C2_V1_0_COMPONENTSTORE_H
-#define VENDOR_GOOGLE_MEDIA_C2_V1_0_COMPONENTSTORE_H
-
-#include <codec2/hidl/1.0/Component.h>
-#include <codec2/hidl/1.0/Configurable.h>
-#include <C2Component.h>
-#include <C2Param.h>
-#include <C2.h>
-
-#include <vendor/google/media/c2/1.0/IComponentStore.h>
-#include <android/hardware/media/bufferpool/1.0/IClientManager.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-
-#include <vector>
-#include <map>
-#include <memory>
-
-namespace vendor {
-namespace google {
-namespace media {
-namespace c2 {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::hardware::media::bufferpool::V1_0::IClientManager;
-
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
-
-struct ComponentStore : public Configurable<IComponentStore> {
-    ComponentStore(const std::shared_ptr<C2ComponentStore>& store);
-    virtual ~ComponentStore() = default;
-
-    c2_status_t status() const {
-        return mInit;
-    }
-
-    c2_status_t validateSupportedParams(
-            const std::vector<std::shared_ptr<C2ParamDescriptor>>& params);
-
-    // Methods from ::android::hardware::media::c2::V1_0::IComponentStore
-    Return<void> createComponent(
-            const hidl_string& name,
-            const sp<IComponentListener>& listener,
-            const sp<IClientManager>& pool,
-            createComponent_cb _hidl_cb) override;
-    Return<void> createInterface(
-            const hidl_string& name,
-            createInterface_cb _hidl_cb) override;
-    Return<void> listComponents(listComponents_cb _hidl_cb) override;
-    Return<sp<IInputSurface>> createInputSurface() override;
-    Return<void> getStructDescriptors(
-            const hidl_vec<uint32_t>& indices,
-            getStructDescriptors_cb _hidl_cb) override;
-    Return<sp<IClientManager>> getPoolClientManager() override;
-    Return<Status> copyBuffer(
-            const Buffer& src,
-            const Buffer& dst) override;
-
-protected:
-    c2_status_t mInit;
-    std::shared_ptr<C2ComponentStore> mStore;
-    std::shared_ptr<C2ParamReflector> mParamReflector;
-    std::map<C2Param::CoreIndex, std::shared_ptr<C2StructDescriptor>>
-            mStructDescriptors;
-
-    sp<IClientManager> mPoolManager;
-};
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace c2
-}  // namespace media
-}  // namespace google
-}  // namespace vendor
-
-#endif  // VENDOR_GOOGLE_MEDIA_C2_V1_0_COMPONENTSTORE_H
diff --git a/media/libstagefright/codec2/hidl/impl/1.0/include/codec2/hidl/1.0/Configurable.h b/media/libstagefright/codec2/hidl/impl/1.0/include/codec2/hidl/1.0/Configurable.h
deleted file mode 100644
index 697d483..0000000
--- a/media/libstagefright/codec2/hidl/impl/1.0/include/codec2/hidl/1.0/Configurable.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2018 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 VENDOR_GOOGLE_MEDIA_C2_V1_0_CONFIGURABLE_H
-#define VENDOR_GOOGLE_MEDIA_C2_V1_0_CONFIGURABLE_H
-
-#include <codec2/hidl/1.0/ConfigurableC2Intf.h>
-
-#include <C2Component.h>
-#include <C2Param.h>
-#include <C2.h>
-
-#include <vendor/google/media/c2/1.0/IConfigurable.h>
-#include <hidl/Status.h>
-
-#include <memory>
-
-namespace vendor {
-namespace google {
-namespace media {
-namespace c2 {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
-
-struct ComponentStore;
-
-/**
- * Implementation of the IConfigurable interface that supports caching of
- * supported parameters from a supplied ComponentStore.
- *
- * This is mainly the same for all of the configurable C2 interfaces though
- * there are slight differences in the blocking behavior. This is handled in the
- * ConfigurableC2Intf implementations.
- */
-struct CachedConfigurable : public IConfigurable {
-    CachedConfigurable(std::unique_ptr<ConfigurableC2Intf>&& intf);
-
-    c2_status_t init(ComponentStore* store);
-
-    // Methods from ::android::hardware::media::c2::V1_0::IConfigurable
-
-    virtual Return<void> getName(getName_cb _hidl_cb) override;
-
-    virtual Return<void> query(
-            const hidl_vec<uint32_t>& indices,
-            bool mayBlock,
-            query_cb _hidl_cb) override;
-
-    virtual Return<void> config(
-            const hidl_vec<uint8_t>& inParams,
-            bool mayBlock,
-            config_cb _hidl_cb) override;
-
-    virtual Return<void> querySupportedParams(
-            uint32_t start,
-            uint32_t count,
-            querySupportedParams_cb _hidl_cb) override;
-
-    virtual Return<void> querySupportedValues(
-            const hidl_vec<FieldSupportedValuesQuery>& inFields,
-            bool mayBlock,
-            querySupportedValues_cb _hidl_cb) override;
-
-protected:
-    // Common Codec2.0 interface wrapper
-    std::unique_ptr<ConfigurableC2Intf> mIntf;
-
-    // Cached supported params
-    std::vector<std::shared_ptr<C2ParamDescriptor>> mSupportedParams;
-};
-
-/**
- * Template that implements the `IConfigurable` interface for an inherited
- * interface. Classes that implement a child interface `I` of `IConfigurable`
- * can derive from `Configurable<I>`.
- */
-template <typename I>
-struct Configurable : public I {
-    Configurable(const sp<CachedConfigurable>& intf): mIntf(intf) {
-    }
-
-    c2_status_t init(ComponentStore* store) {
-        return mIntf->init(store);
-    }
-
-    // Methods from ::android::hardware::media::c2::V1_0::IConfigurable
-
-    using getName_cb = typename I::getName_cb;
-    virtual Return<void> getName(getName_cb _hidl_cb) override {
-        return mIntf->getName(_hidl_cb);
-    }
-
-    using query_cb = typename I::query_cb;
-    virtual Return<void> query(
-            const hidl_vec<uint32_t>& indices,
-            bool mayBlock,
-            query_cb _hidl_cb) override {
-        return mIntf->query(indices, mayBlock, _hidl_cb);
-    }
-
-    using config_cb = typename I::config_cb;
-    virtual Return<void> config(
-            const hidl_vec<uint8_t>& inParams,
-            bool mayBlock,
-            config_cb _hidl_cb) override {
-        return mIntf->config(inParams, mayBlock, _hidl_cb);
-    }
-
-    using querySupportedParams_cb = typename I::querySupportedParams_cb;
-    virtual Return<void> querySupportedParams(
-            uint32_t start,
-            uint32_t count,
-            querySupportedParams_cb _hidl_cb) override {
-        return mIntf->querySupportedParams(start, count, _hidl_cb);
-    }
-
-    using querySupportedValues_cb = typename I::querySupportedValues_cb;
-    virtual Return<void> querySupportedValues(
-            const hidl_vec<FieldSupportedValuesQuery>& inFields,
-            bool mayBlock,
-            querySupportedValues_cb _hidl_cb) override {
-        return mIntf->querySupportedValues(inFields, mayBlock, _hidl_cb);
-    }
-
-protected:
-    sp<CachedConfigurable> mIntf;
-};
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace c2
-}  // namespace media
-}  // namespace google
-}  // namespace vendor
-
-#endif  // VENDOR_GOOGLE_MEDIA_C2_V1_0_CONFIGURABLE_H
diff --git a/media/libstagefright/codec2/hidl/impl/1.0/include/codec2/hidl/1.0/ConfigurableC2Intf.h b/media/libstagefright/codec2/hidl/impl/1.0/include/codec2/hidl/1.0/ConfigurableC2Intf.h
deleted file mode 100644
index da90996..0000000
--- a/media/libstagefright/codec2/hidl/impl/1.0/include/codec2/hidl/1.0/ConfigurableC2Intf.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2018 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 VENDOR_GOOGLE_MEDIA_C2_V1_0_CONFIGURABLEC2INTF_H
-#define VENDOR_GOOGLE_MEDIA_C2_V1_0_CONFIGURABLEC2INTF_H
-
-#include <C2Work.h>
-#include <C2Component.h>
-#include <C2Param.h>
-#include <C2.h>
-
-#include <hidl/HidlSupport.h>
-#include <utils/StrongPointer.h>
-#include <vector>
-#include <memory>
-
-namespace vendor {
-namespace google {
-namespace media {
-namespace c2 {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::sp;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-
-/**
- * Common Codec 2.0 interface wrapper.
- */
-struct ConfigurableC2Intf {
-    C2String getName() const { return mName; }
-    /** C2ComponentInterface::query_vb sans stack params */
-    virtual c2_status_t query(
-            const std::vector<C2Param::Index> &indices,
-            c2_blocking_t mayBlock,
-            std::vector<std::unique_ptr<C2Param>>* const params) const = 0;
-    /** C2ComponentInterface::config_vb */
-    virtual c2_status_t config(
-            const std::vector<C2Param*> &params,
-            c2_blocking_t mayBlock,
-            std::vector<std::unique_ptr<C2SettingResult>>* const failures) = 0;
-    /** C2ComponentInterface::querySupportedParams_nb */
-    virtual c2_status_t querySupportedParams(
-            std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const = 0;
-    /** C2ComponentInterface::querySupportedParams_nb */
-    virtual c2_status_t querySupportedValues(
-            std::vector<C2FieldSupportedValuesQuery>& fields, c2_blocking_t mayBlock) const = 0;
-
-    virtual ~ConfigurableC2Intf() = default;
-
-    ConfigurableC2Intf(const C2String& name) : mName(name) {}
-
-protected:
-    C2String mName; /* cache component name */
-};
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace c2
-}  // namespace media
-}  // namespace google
-}  // namespace vendor
-
-#endif  // VENDOR_GOOGLE_MEDIA_C2_V1_0_CONFIGURABLEC2INTF_H
diff --git a/media/libstagefright/codec2/hidl/impl/1.0/include/codec2/hidl/1.0/types.h b/media/libstagefright/codec2/hidl/impl/1.0/include/codec2/hidl/1.0/types.h
deleted file mode 100644
index 1eace56..0000000
--- a/media/libstagefright/codec2/hidl/impl/1.0/include/codec2/hidl/1.0/types.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2018 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 VENDOR_GOOGLE_MEDIA_C2_V1_0_TYPES_H
-#define VENDOR_GOOGLE_MEDIA_C2_V1_0_TYPES_H
-
-#include <vendor/google/media/c2/1.0/types.h>
-#include <vendor/google/media/c2/1.0/IComponentStore.h>
-
-#include <C2Param.h>
-#include <C2Component.h>
-#include <C2Work.h>
-
-namespace vendor {
-namespace google {
-namespace media {
-namespace c2 {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::hardware::hidl_bitfield;
-using ::android::hardware::hidl_handle;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::sp;
-
-// Types of metadata for Blocks.
-struct C2Hidl_Range {
-    uint32_t offset;
-    uint32_t length; // Do not use "size" because the name collides with C2Info::size().
-};
-typedef C2GlobalParam<C2Info, C2Hidl_Range, 0> C2Hidl_RangeInfo;
-
-struct C2Hidl_Rect {
-    uint32_t left;
-    uint32_t top;
-    uint32_t width;
-    uint32_t height;
-};
-typedef C2GlobalParam<C2Info, C2Hidl_Rect, 1> C2Hidl_RectInfo;
-
-// C2SettingResult -> SettingResult
-Status objcpy(
-        SettingResult* d,
-        const C2SettingResult& s);
-
-// SettingResult -> std::unique_ptr<C2SettingResult>
-c2_status_t objcpy(
-        std::unique_ptr<C2SettingResult>* d,
-        const SettingResult& s);
-
-// C2ParamDescriptor -> ParamDescriptor
-Status objcpy(
-        ParamDescriptor* d,
-        const C2ParamDescriptor& s);
-
-// ParamDescriptor -> std::shared_ptr<C2ParamDescriptor>
-c2_status_t objcpy(
-        std::shared_ptr<C2ParamDescriptor>* d,
-        const ParamDescriptor& s);
-
-// C2FieldSupportedValuesQuery -> FieldSupportedValuesQuery
-Status objcpy(
-        FieldSupportedValuesQuery* d,
-        const C2FieldSupportedValuesQuery& s);
-
-// FieldSupportedValuesQuery -> C2FieldSupportedValuesQuery
-c2_status_t objcpy(
-        C2FieldSupportedValuesQuery* d,
-        const FieldSupportedValuesQuery& s);
-
-// C2FieldSupportedValuesQuery -> FieldSupportedValuesQueryResult
-Status objcpy(
-        FieldSupportedValuesQueryResult* d,
-        const C2FieldSupportedValuesQuery& s);
-
-// FieldSupportedValuesQuery, FieldSupportedValuesQueryResult -> C2FieldSupportedValuesQuery
-c2_status_t objcpy(
-        C2FieldSupportedValuesQuery* d,
-        const FieldSupportedValuesQuery& sq,
-        const FieldSupportedValuesQueryResult& sr);
-
-// C2Component::Traits -> ComponentTraits
-Status objcpy(
-        IComponentStore::ComponentTraits* d,
-        const C2Component::Traits& s);
-
-// ComponentTraits -> C2Component::Traits, std::unique_ptr<std::vector<std::string>>
-// Note: The output d is only valid as long as aliasesBuffer remains alive.
-c2_status_t objcpy(
-        C2Component::Traits* d,
-        std::unique_ptr<std::vector<std::string>>* aliasesBuffer,
-        const IComponentStore::ComponentTraits& s);
-
-// C2StructDescriptor -> StructDescriptor
-Status objcpy(
-        StructDescriptor* d,
-        const C2StructDescriptor& s);
-
-// StructDescriptor -> C2StructDescriptor
-// TODO: This cannot be implemented yet because C2StructDescriptor does not
-// allow dynamic construction/modification.
-c2_status_t objcpy(
-        C2StructDescriptor* d,
-        const StructDescriptor& s);
-
-// std::list<std::unique_ptr<C2Work>> -> WorkBundle
-// TODO: Connect with Bufferpool
-Status objcpy(
-        WorkBundle* d,
-        const std::list<std::unique_ptr<C2Work>>& s);
-
-// WorkBundle -> std::list<std::unique_ptr<C2Work>>
-// TODO: Connect with Bufferpool
-c2_status_t objcpy(
-        std::list<std::unique_ptr<C2Work>>* d,
-        const WorkBundle& s);
-
-/**
- * Parses a params blob and returns C2Param pointers to its params.
- * \param[out] params target vector of C2Param pointers
- * \param[in] blob parameter blob to parse
- * \retval C2_OK if the full blob was parsed
- * \retval C2_BAD_VALUE otherwise
- */
-c2_status_t parseParamsBlob(
-        std::vector<C2Param*> *params,
-        const hidl_vec<uint8_t> &blob);
-
-/**
- * Concatenates a list of C2Params into a params blob.
- * \param[out] blob target blob
- * \param[in] params parameters to concatenate
- * \retval C2_OK if the blob was successfully created
- * \retval C2_BAD_VALUE if the blob was not successful (this only happens if the parameters were
- *         not const)
- */
-Status createParamsBlob(
-        hidl_vec<uint8_t> *blob,
-        const std::vector<C2Param*> &params);
-Status createParamsBlob(
-        hidl_vec<uint8_t> *blob,
-        const std::vector<std::unique_ptr<C2Param>> &params);
-Status createParamsBlob(
-        hidl_vec<uint8_t> *blob,
-        const std::vector<std::shared_ptr<const C2Info>> &params);
-Status createParamsBlob(
-        hidl_vec<uint8_t> *blob,
-        const std::vector<std::unique_ptr<C2Tuning>> &params);
-
-/**
- * Parses a params blob and create a vector of C2Params whose members are copies
- * of the params in the blob.
- * \param[out] params the resulting vector
- * \param[in] blob parameter blob to parse
- * \retval C2_OK if the full blob was parsed and params was constructed
- * \retval C2_BAD_VALUE otherwise
- */
-c2_status_t copyParamsFromBlob(
-        std::vector<std::unique_ptr<C2Param>>* params,
-        Params blob);
-
-/**
- * Parses a params blob and applies updates to params
- * \param[in,out] params params to be updated
- * \param[in] blob parameter blob containing updates
- * \retval C2_OK if the full blob was parsed and params was updated
- * \retval C2_BAD_VALUE otherwise
- */
-c2_status_t updateParamsFromBlob(
-        const std::vector<C2Param*>& params,
-        const Params& blob);
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace c2
-}  // namespace media
-}  // namespace google
-}  // namespace vendor
-
-#endif  // VENDOR_GOOGLE_MEDIA_C2_V1_0_TYPES_H
diff --git a/media/libstagefright/codec2/hidl/impl/1.0/types.cpp b/media/libstagefright/codec2/hidl/impl/1.0/types.cpp
deleted file mode 100644
index f14c21a..0000000
--- a/media/libstagefright/codec2/hidl/impl/1.0/types.cpp
+++ /dev/null
@@ -1,1265 +0,0 @@
-/*
- * Copyright (C) 2018 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 "Codec2-types"
-#include <log/log.h>
-
-#include <codec2/hidl/1.0/types.h>
-
-#include <C2AllocatorIon.h>
-#include <C2AllocatorGralloc.h>
-#include <C2PlatformSupport.h>
-#include <C2BlockInternal.h>
-#include <C2ParamInternal.h>
-#include <C2Param.h>
-#include <C2Buffer.h>
-#include <C2Work.h>
-#include <C2Component.h>
-#include <util/C2ParamUtils.h>
-
-#include <unordered_map>
-#include <algorithm>
-
-namespace vendor {
-namespace google {
-namespace media {
-namespace c2 {
-namespace V1_0 {
-namespace implementation {
-
-using namespace ::android;
-
-namespace /* unnamed */ {
-
-template <typename Common, typename DstVector, typename SrcVector>
-void copyVector(DstVector* d, const SrcVector& s) {
-    static_assert(sizeof(Common) == sizeof(decltype((*d)[0])),
-            "DstVector's component size does not match Common");
-    static_assert(sizeof(Common) == sizeof(decltype(s[0])),
-            "SrcVector's component size does not match Common");
-    d->resize(s.size());
-    std::copy(
-            reinterpret_cast<const Common*>(&s[0]),
-            reinterpret_cast<const Common*>(&s[0] + s.size()),
-            reinterpret_cast<Common*>(&(*d)[0]));
-}
-
-// C2ParamField -> ParamField
-void objcpy(ParamField *d, const C2ParamField &s) {
-    d->index = static_cast<ParamIndex>(_C2ParamInspector::GetIndex(s));
-    d->fieldId.offset = static_cast<uint32_t>(_C2ParamInspector::GetOffset(s));
-    d->fieldId.size = static_cast<uint32_t>(_C2ParamInspector::GetSize(s));
-}
-
-struct C2ParamFieldBuilder : public C2ParamField {
-    C2ParamFieldBuilder() : C2ParamField(
-            static_cast<C2Param::Index>(static_cast<uint32_t>(0)), 0, 0) {
-    }
-    // ParamField -> C2ParamField
-    C2ParamFieldBuilder(const ParamField& s) : C2ParamField(
-            static_cast<C2Param::Index>(static_cast<uint32_t>(s.index)),
-            static_cast<uint32_t>(s.fieldId.offset),
-            static_cast<uint32_t>(s.fieldId.size)) {
-    }
-};
-
-// C2WorkOrdinalStruct -> WorkOrdinal
-void objcpy(WorkOrdinal *d, const C2WorkOrdinalStruct &s) {
-    d->frameIndex = static_cast<uint64_t>(s.frameIndex.peeku());
-    d->timestampUs = static_cast<uint64_t>(s.timestamp.peeku());
-    d->customOrdinal = static_cast<uint64_t>(s.customOrdinal.peeku());
-}
-
-// WorkOrdinal -> C2WorkOrdinalStruct
-void objcpy(C2WorkOrdinalStruct *d, const WorkOrdinal &s) {
-    d->frameIndex = c2_cntr64_t(s.frameIndex);
-    d->timestamp = c2_cntr64_t(s.timestampUs);
-    d->customOrdinal = c2_cntr64_t(s.customOrdinal);
-}
-
-// C2FieldSupportedValues::range's type -> FieldSupportedValues::Range
-void objcpy(
-        FieldSupportedValues::Range* d,
-        const decltype(C2FieldSupportedValues::range)& s) {
-    d->min = static_cast<PrimitiveValue>(s.min.u64);
-    d->max = static_cast<PrimitiveValue>(s.max.u64);
-    d->step = static_cast<PrimitiveValue>(s.step.u64);
-    d->num = static_cast<PrimitiveValue>(s.num.u64);
-    d->denom = static_cast<PrimitiveValue>(s.denom.u64);
-}
-
-// C2FieldSupportedValues -> FieldSupportedValues
-Status objcpy(FieldSupportedValues *d, const C2FieldSupportedValues &s) {
-    d->typeOther = static_cast<int32_t>(s.type);
-    switch (s.type) {
-    case C2FieldSupportedValues::EMPTY:
-        d->type = FieldSupportedValues::Type::EMPTY;
-        d->values.resize(0);
-        return Status::OK;
-    case C2FieldSupportedValues::RANGE:
-        d->type = FieldSupportedValues::Type::RANGE;
-        objcpy(&d->range, s.range);
-        d->values.resize(0);
-        return Status::OK;
-    default:
-        switch (s.type) {
-        case C2FieldSupportedValues::VALUES:
-            d->type = FieldSupportedValues::Type::VALUES;
-            break;
-        case C2FieldSupportedValues::FLAGS:
-            d->type = FieldSupportedValues::Type::FLAGS;
-            break;
-        default:
-            d->type = FieldSupportedValues::Type::OTHER;
-            // Copy all fields in this case
-            objcpy(&d->range, s.range);
-        }
-        d->values.resize(s.values.size());
-        copyVector<uint64_t>(&d->values, s.values);
-        return Status::OK;
-    }
-}
-
-// FieldSupportedValues::Range -> C2FieldSupportedValues::range's type
-void objcpy(
-        decltype(C2FieldSupportedValues::range)* d,
-        const FieldSupportedValues::Range& s) {
-    d->min.u64 = static_cast<uint64_t>(s.min);
-    d->max.u64 = static_cast<uint64_t>(s.max);
-    d->step.u64 = static_cast<uint64_t>(s.step);
-    d->num.u64 = static_cast<uint64_t>(s.num);
-    d->denom.u64 = static_cast<uint64_t>(s.denom);
-}
-
-// FieldSupportedValues -> C2FieldSupportedValues
-c2_status_t objcpy(C2FieldSupportedValues *d, const FieldSupportedValues &s) {
-    switch (s.type) {
-    case FieldSupportedValues::Type::EMPTY:
-        d->type = C2FieldSupportedValues::EMPTY;
-        return C2_OK;
-    case FieldSupportedValues::Type::RANGE:
-        d->type = C2FieldSupportedValues::RANGE;
-        objcpy(&d->range, s.range);
-        d->values.resize(0);
-        return C2_OK;
-    default:
-        switch (s.type) {
-        case FieldSupportedValues::Type::VALUES:
-            d->type = C2FieldSupportedValues::VALUES;
-            break;
-        case FieldSupportedValues::Type::FLAGS:
-            d->type = C2FieldSupportedValues::FLAGS;
-            break;
-        default:
-            d->type = static_cast<C2FieldSupportedValues::type_t>(s.typeOther);
-            // Copy all fields in this case
-            objcpy(&d->range, s.range);
-        }
-        copyVector<uint64_t>(&d->values, s.values);
-        return C2_OK;
-    }
-}
-
-} // unnamed namespace
-
-// C2FieldSupportedValuesQuery -> FieldSupportedValuesQuery
-Status objcpy(
-        FieldSupportedValuesQuery* d,
-        const C2FieldSupportedValuesQuery& s) {
-    objcpy(&d->field, s.field());
-    switch (s.type()) {
-    case C2FieldSupportedValuesQuery::POSSIBLE:
-        d->type = FieldSupportedValuesQuery::Type::POSSIBLE;
-        break;
-    case C2FieldSupportedValuesQuery::CURRENT:
-        d->type = FieldSupportedValuesQuery::Type::CURRENT;
-        break;
-    default:
-        ALOGE("Unknown type of C2FieldSupportedValuesQuery: %u",
-                static_cast<unsigned>(s.type()));
-        return Status::BAD_VALUE;
-    }
-    return Status::OK;
-}
-
-// FieldSupportedValuesQuery -> C2FieldSupportedValuesQuery
-c2_status_t objcpy(
-        C2FieldSupportedValuesQuery* d,
-        const FieldSupportedValuesQuery& s) {
-    C2FieldSupportedValuesQuery::type_t dType;
-    switch (s.type) {
-    case FieldSupportedValuesQuery::Type::POSSIBLE:
-        dType = C2FieldSupportedValuesQuery::POSSIBLE;
-        break;
-    case FieldSupportedValuesQuery::Type::CURRENT:
-        dType = C2FieldSupportedValuesQuery::CURRENT;
-        break;
-    default:
-        ALOGE("Unknown type of FieldSupportedValuesQuery: %u",
-                static_cast<unsigned>(s.type));
-        return C2_BAD_VALUE;
-    }
-    *d = C2FieldSupportedValuesQuery(C2ParamFieldBuilder(s.field), dType);
-    return C2_OK;
-}
-
-// C2FieldSupportedValuesQuery -> FieldSupportedValuesQueryResult
-Status objcpy(
-        FieldSupportedValuesQueryResult* d,
-        const C2FieldSupportedValuesQuery& s) {
-    d->status = static_cast<Status>(s.status);
-    return objcpy(&d->values, s.values);
-}
-
-// FieldSupportedValuesQuery, FieldSupportedValuesQueryResult ->
-// C2FieldSupportedValuesQuery
-c2_status_t objcpy(
-        C2FieldSupportedValuesQuery* d,
-        const FieldSupportedValuesQuery& sq,
-        const FieldSupportedValuesQueryResult& sr) {
-    c2_status_t status = objcpy(d, sq);
-    if (status != C2_OK) {
-        return status;
-    }
-    d->status = static_cast<c2_status_t>(sr.status);
-    return objcpy(&d->values, sr.values);
-}
-
-// C2Component::Traits -> IComponentStore::ComponentTraits
-Status objcpy(
-        IComponentStore::ComponentTraits *d,
-        const C2Component::Traits &s) {
-    d->name = s.name;
-
-    // TODO: Currently, we do not have any domain values defined in Codec2.0.
-    d->domain = IComponentStore::ComponentTraits::Domain::OTHER;
-    d->domainOther = static_cast<uint32_t>(s.domain);
-
-    // TODO: Currently, we do not have any kind values defined in Codec2.0.
-    d->kind = IComponentStore::ComponentTraits::Kind::OTHER;
-    d->kindOther = static_cast<uint32_t>(s.kind);
-
-    d->rank = static_cast<uint32_t>(s.rank);
-
-    d->mediaType = s.mediaType;
-
-    d->aliases.resize(s.aliases.size());
-    for (size_t ix = s.aliases.size(); ix > 0; ) {
-        --ix;
-        d->aliases[ix] = s.aliases[ix];
-    }
-    return Status::OK;
-}
-
-// ComponentTraits -> C2Component::Traits, std::unique_ptr<std::vector<std::string>>
-c2_status_t objcpy(
-        C2Component::Traits* d,
-        std::unique_ptr<std::vector<std::string>>* aliasesBuffer,
-        const IComponentStore::ComponentTraits& s) {
-    d->name = s.name.c_str();
-    d->domain = static_cast<C2Component::domain_t>(s.domainOther);
-    d->kind = static_cast<C2Component::kind_t>(s.kindOther);
-    d->rank = static_cast<C2Component::rank_t>(s.rank);
-    d->mediaType = s.mediaType.c_str();
-
-    // aliasesBuffer must not be resized after this.
-    *aliasesBuffer = std::make_unique<std::vector<std::string>>(
-            s.aliases.size());
-    (*aliasesBuffer)->resize(s.aliases.size());
-    std::vector<C2StringLiteral> dAliases(s.aliases.size());
-    for (size_t i = 0; i < s.aliases.size(); ++i) {
-        (**aliasesBuffer)[i] = s.aliases[i].c_str();
-        d->aliases[i] = (**aliasesBuffer)[i].c_str();
-    }
-    return C2_OK;
-}
-
-namespace /* unnamed */ {
-
-// C2ParamFieldValues -> ParamFieldValues
-Status objcpy(ParamFieldValues *d, const C2ParamFieldValues &s) {
-    objcpy(&d->paramOrField, s.paramOrField);
-    if (s.values) {
-        d->values.resize(1);
-        return objcpy(&d->values[0], *s.values);
-    }
-    d->values.resize(0);
-    return Status::OK;
-}
-
-// ParamFieldValues -> C2ParamFieldValues
-c2_status_t objcpy(C2ParamFieldValues *d, const ParamFieldValues &s) {
-    d->paramOrField = C2ParamFieldBuilder(s.paramOrField);
-    if (s.values.size() == 1) {
-        d->values = std::make_unique<C2FieldSupportedValues>();
-        return objcpy(d->values.get(), s.values[0]);
-    } else if (s.values.size() == 0) {
-        d->values.reset();
-        return C2_OK;
-    }
-    ALOGE("Multiple FieldSupportedValues objects. "
-            "(Only one is allowed.)");
-    return C2_BAD_VALUE;
-}
-
-} // unnamed namespace
-
-// C2SettingResult -> SettingResult
-Status objcpy(SettingResult *d, const C2SettingResult &s) {
-    d->failureOther = static_cast<uint32_t>(s.failure);
-    switch (s.failure) {
-    case C2SettingResult::READ_ONLY:
-        d->failure = SettingResult::Failure::READ_ONLY;
-        break;
-    case C2SettingResult::MISMATCH:
-        d->failure = SettingResult::Failure::MISMATCH;
-        break;
-    case C2SettingResult::BAD_VALUE:
-        d->failure = SettingResult::Failure::BAD_VALUE;
-        break;
-    case C2SettingResult::BAD_TYPE:
-        d->failure = SettingResult::Failure::BAD_TYPE;
-        break;
-    case C2SettingResult::BAD_PORT:
-        d->failure = SettingResult::Failure::BAD_PORT;
-        break;
-    case C2SettingResult::BAD_INDEX:
-        d->failure = SettingResult::Failure::BAD_INDEX;
-        break;
-    case C2SettingResult::CONFLICT:
-        d->failure = SettingResult::Failure::CONFLICT;
-        break;
-    case C2SettingResult::UNSUPPORTED:
-        d->failure = SettingResult::Failure::UNSUPPORTED;
-        break;
-    case C2SettingResult::INFO_CONFLICT:
-        d->failure = SettingResult::Failure::INFO_CONFLICT;
-        break;
-    default:
-        d->failure = SettingResult::Failure::OTHER;
-    }
-    Status status = objcpy(&d->field, s.field);
-    if (status != Status::OK) {
-        return status;
-    }
-    d->conflicts.resize(s.conflicts.size());
-    size_t i = 0;
-    for (const C2ParamFieldValues& sConflict : s.conflicts) {
-        ParamFieldValues &dConflict = d->conflicts[i++];
-        status = objcpy(&dConflict, sConflict);
-        if (status != Status::OK) {
-            return status;
-        }
-    }
-    return Status::OK;
-}
-
-// SettingResult -> std::unique_ptr<C2SettingResult>
-c2_status_t objcpy(std::unique_ptr<C2SettingResult> *d, const SettingResult &s) {
-    *d = std::unique_ptr<C2SettingResult>(new C2SettingResult {
-            .field = C2ParamFieldValues(C2ParamFieldBuilder()) });
-    if (!*d) {
-        return C2_NO_MEMORY;
-    }
-
-    // failure
-    switch (s.failure) {
-    case SettingResult::Failure::READ_ONLY:
-        (*d)->failure = C2SettingResult::READ_ONLY;
-        break;
-    case SettingResult::Failure::MISMATCH:
-        (*d)->failure = C2SettingResult::MISMATCH;
-        break;
-    case SettingResult::Failure::BAD_VALUE:
-        (*d)->failure = C2SettingResult::BAD_VALUE;
-        break;
-    case SettingResult::Failure::BAD_TYPE:
-        (*d)->failure = C2SettingResult::BAD_TYPE;
-        break;
-    case SettingResult::Failure::BAD_PORT:
-        (*d)->failure = C2SettingResult::BAD_PORT;
-        break;
-    case SettingResult::Failure::BAD_INDEX:
-        (*d)->failure = C2SettingResult::BAD_INDEX;
-        break;
-    case SettingResult::Failure::CONFLICT:
-        (*d)->failure = C2SettingResult::CONFLICT;
-        break;
-    case SettingResult::Failure::UNSUPPORTED:
-        (*d)->failure = C2SettingResult::UNSUPPORTED;
-        break;
-    case SettingResult::Failure::INFO_CONFLICT:
-        (*d)->failure = C2SettingResult::INFO_CONFLICT;
-        break;
-    default:
-        (*d)->failure = static_cast<C2SettingResult::Failure>(s.failureOther);
-    }
-
-    // field
-    c2_status_t status = objcpy(&(*d)->field, s.field);
-    if (status != C2_OK) {
-        return status;
-    }
-
-    // conflicts
-    (*d)->conflicts.clear();
-    (*d)->conflicts.reserve(s.conflicts.size());
-    for (const ParamFieldValues& sConflict : s.conflicts) {
-        (*d)->conflicts.emplace_back(
-                C2ParamFieldValues{ C2ParamFieldBuilder(), nullptr });
-        status = objcpy(&(*d)->conflicts.back(), sConflict);
-        if (status != C2_OK) {
-            return status;
-        }
-    }
-    return C2_OK;
-}
-
-// C2ParamDescriptor -> ParamDescriptor
-Status objcpy(ParamDescriptor *d, const C2ParamDescriptor &s) {
-    d->index = static_cast<ParamIndex>(s.index());
-    d->attrib = static_cast<hidl_bitfield<ParamDescriptor::Attrib>>(
-            _C2ParamInspector::GetAttrib(s));
-    d->name = s.name();
-    copyVector<uint32_t>(&d->dependencies, s.dependencies());
-    return Status::OK;
-}
-
-// ParamDescriptor -> C2ParamDescriptor
-c2_status_t objcpy(std::shared_ptr<C2ParamDescriptor> *d, const ParamDescriptor &s) {
-    std::vector<C2Param::Index> dDependencies;
-    dDependencies.reserve(s.dependencies.size());
-    for (const ParamIndex& sDependency : s.dependencies) {
-        dDependencies.emplace_back(static_cast<uint32_t>(sDependency));
-    }
-    *d = std::make_shared<C2ParamDescriptor>(
-            C2Param::Index(static_cast<uint32_t>(s.index)),
-            static_cast<C2ParamDescriptor::attrib_t>(s.attrib),
-            C2String(s.name.c_str()),
-            std::move(dDependencies));
-    return C2_OK;
-}
-
-// C2StructDescriptor -> StructDescriptor
-Status objcpy(StructDescriptor *d, const C2StructDescriptor &s) {
-    d->type = static_cast<ParamIndex>(s.coreIndex().coreIndex());
-    d->fields.resize(s.numFields());
-    size_t i = 0;
-    for (const auto& sField : s) {
-        FieldDescriptor& dField = d->fields[i++];
-        dField.fieldId.offset = static_cast<uint32_t>(
-                _C2ParamInspector::GetOffset(sField));
-        dField.fieldId.size = static_cast<uint32_t>(
-                _C2ParamInspector::GetSize(sField));
-        dField.type = static_cast<hidl_bitfield<FieldDescriptor::Type>>(
-                sField.type());
-        dField.length = static_cast<uint32_t>(sField.extent());
-        dField.name = static_cast<hidl_string>(sField.name());
-        const auto& sNamedValues = sField.namedValues();
-        dField.namedValues.resize(sNamedValues.size());
-        size_t j = 0;
-        for (const auto& sNamedValue : sNamedValues) {
-            FieldDescriptor::NamedValue& dNamedValue = dField.namedValues[j++];
-            dNamedValue.name = static_cast<hidl_string>(sNamedValue.first);
-            dNamedValue.value = static_cast<PrimitiveValue>(
-                    sNamedValue.second.u64);
-        }
-    }
-    return Status::OK;
-}
-
-// StructDescriptor -> C2StructDescriptor
-c2_status_t objcpy(C2StructDescriptor *d, const StructDescriptor &s) {
-    // TODO: Implement this when C2StructDescriptor can be dynamically
-    // constructed.
-    (void)d;
-    (void)s;
-    ALOGE("Conversion StructDescriptor -> C2StructDescriptor "
-            "not implemented.");
-    return C2_OMITTED;
-}
-
-// Finds or adds a hidl BaseBlock object from a given C2Handle* to a list and an
-// associated map.
-// Note: Native handles are not duplicated. The original handles must not be
-// closed before the transaction is complete.
-namespace /* unnamed */ {
-
-Status addBaseBlock(uint32_t* index, const C2Handle* handle,
-        std::vector<BaseBlock>* baseBlocks,
-        std::map<const C2Handle*, uint32_t>* baseBlockIndices) {
-    if (handle == nullptr) {
-        return Status::BAD_VALUE;
-    }
-    auto it = baseBlockIndices->find(handle);
-    if (it != baseBlockIndices->end()) {
-        *index = it->second;
-    } else {
-        *index = baseBlocks->size();
-        BaseBlock dBaseBlock;
-        // TODO: Use BufferPool.
-        dBaseBlock.type = BaseBlock::Type::NATIVE;
-        // This does not clone the handle.
-        dBaseBlock.nativeBlock =
-                reinterpret_cast<const native_handle_t*>(handle);
-        baseBlocks->push_back(dBaseBlock);
-        baseBlockIndices->emplace(handle, *index);
-    }
-    return Status::OK;
-}
-
-// C2Fence -> hidl_handle
-// Note: File descriptors are not duplicated. The original file descriptor must
-// not be closed before the transaction is complete.
-Status objcpy(hidl_handle* d, const C2Fence& s) {
-    (void)s; // TODO: implement s.fd()
-    int fenceFd = -1;
-    d->setTo(nullptr);
-    if (fenceFd >= 0) {
-        native_handle_t *handle = native_handle_create(1, 0);
-        if (!handle) {
-            return Status::NO_MEMORY;
-        }
-        handle->data[0] = fenceFd;
-        d->setTo(handle, true /* owns */);
-    }
-    return Status::OK;
-}
-
-// C2ConstLinearBlock -> Block
-// Note: Native handles are not duplicated. The original handles must not be
-// closed before the transaction is complete.
-Status objcpy(Block* d, const C2ConstLinearBlock& s,
-        std::vector<BaseBlock>* baseBlocks,
-        std::map<const C2Handle*, uint32_t>* baseBlockIndices) {
-    // Find the BaseBlock index.
-    // TODO: Use BufferPool.
-    Status status = addBaseBlock(
-            &d->index, s.handle(), baseBlocks, baseBlockIndices);
-    if (status != Status::OK) {
-        return status;
-    }
-
-    // Create the metadata.
-    C2Hidl_RangeInfo dRangeInfo;
-    dRangeInfo.offset = static_cast<uint32_t>(s.offset());
-    dRangeInfo.length = static_cast<uint32_t>(s.size());
-    status = createParamsBlob(&d->meta,
-            std::vector<C2Param*>{ &dRangeInfo });
-    if (status != Status::OK) {
-        return Status::BAD_VALUE;
-    }
-
-    // Copy the fence
-    return objcpy(&d->fence, s.fence());
-}
-
-// C2ConstGraphicBlock -> Block
-// Note: Native handles are not duplicated. The original handles must not be
-// closed before the transaction is complete.
-Status objcpy(Block* d, const C2ConstGraphicBlock& s,
-        std::vector<BaseBlock>* baseBlocks,
-        std::map<const C2Handle*, uint32_t>* baseBlockIndices) {
-    // Find the BaseBlock index.
-    // TODO: Use BufferPool.
-    Status status = addBaseBlock(
-            &d->index, s.handle(), baseBlocks, baseBlockIndices);
-    if (status != Status::OK) {
-        return status;
-    }
-
-    // Create the metadata.
-    C2Hidl_RectInfo dRectInfo;
-    C2Rect sRect = s.crop();
-    dRectInfo.left = static_cast<uint32_t>(sRect.left);
-    dRectInfo.top = static_cast<uint32_t>(sRect.top);
-    dRectInfo.width = static_cast<uint32_t>(sRect.width);
-    dRectInfo.height = static_cast<uint32_t>(sRect.height);
-    status = createParamsBlob(&d->meta,
-            std::vector<C2Param*>{ &dRectInfo });
-    if (status != Status::OK) {
-        return Status::BAD_VALUE;
-    }
-
-    // Copy the fence
-    return objcpy(&d->fence, s.fence());
-}
-
-// C2BufferData -> Buffer
-// This function only fills in d->blocks.
-Status objcpy(Buffer* d, const C2BufferData& s,
-        std::vector<BaseBlock>* baseBlocks,
-        std::map<const C2Handle*, uint32_t>* baseBlockIndices) {
-    Status status;
-    d->blocks.resize(
-            s.linearBlocks().size() +
-            s.graphicBlocks().size());
-    size_t i = 0;
-    for (const C2ConstLinearBlock& linearBlock : s.linearBlocks()) {
-        Block& dBlock = d->blocks[i++];
-        status = objcpy(
-                &dBlock, linearBlock, baseBlocks, baseBlockIndices);
-        if (status != Status::OK) {
-            return status;
-        }
-    }
-    for (const C2ConstGraphicBlock& graphicBlock : s.graphicBlocks()) {
-        Block& dBlock = d->blocks[i++];
-        status = objcpy(
-                &dBlock, graphicBlock, baseBlocks, baseBlockIndices);
-        if (status != Status::OK) {
-            return status;
-        }
-    }
-    return Status::OK;
-}
-
-// C2Buffer -> Buffer
-Status objcpy(Buffer* d, const C2Buffer& s,
-        std::vector<BaseBlock>* baseBlocks,
-        std::map<const C2Handle*, uint32_t>* baseBlockIndices) {
-    Status status = createParamsBlob(&d->info, s.info());
-    if (status != Status::OK) {
-        return status;
-    }
-    return objcpy(d, s.data(), baseBlocks, baseBlockIndices);
-}
-
-// C2InfoBuffer -> InfoBuffer
-Status objcpy(InfoBuffer* d, const C2InfoBuffer& s,
-        std::vector<BaseBlock>* baseBlocks,
-        std::map<const C2Handle*, uint32_t>* baseBlockIndices) {
-    // TODO: C2InfoBuffer is not implemented.
-    (void)d;
-    (void)s;
-    (void)baseBlocks;
-    (void)baseBlockIndices;
-    return Status::OK;
-    /*
-    // Stub implementation that may work in the future.
-    d->index = static_cast<uint32_t>(s.index());
-    d->buffer.info.resize(0);
-    return objcpy(&d->buffer, s.data(), baseBlocks, baseBlockIndices);
-    */
-}
-
-// C2FrameData -> FrameData
-Status objcpy(FrameData* d, const C2FrameData& s,
-        std::vector<BaseBlock>* baseBlocks,
-        std::map<const C2Handle*, uint32_t>* baseBlockIndices) {
-    d->flags = static_cast<hidl_bitfield<FrameData::Flags>>(s.flags);
-    objcpy(&d->ordinal, s.ordinal);
-
-    Status status;
-    d->buffers.resize(s.buffers.size());
-    size_t i = 0;
-    for (const std::shared_ptr<C2Buffer>& sBuffer : s.buffers) {
-        Buffer& dBuffer = d->buffers[i++];
-        if (!sBuffer) {
-            ALOGE("Null C2Buffer");
-            return Status::BAD_VALUE;
-        }
-        status = objcpy(&dBuffer, *sBuffer, baseBlocks, baseBlockIndices);
-        if (status != Status::OK) {
-            return status;
-        }
-    }
-
-    status = createParamsBlob(&d->configUpdate, s.configUpdate);
-    if (status != Status::OK) {
-        return status;
-    }
-
-    d->infoBuffers.resize(s.infoBuffers.size());
-    i = 0;
-    for (const std::shared_ptr<C2InfoBuffer>& sInfoBuffer : s.infoBuffers) {
-        InfoBuffer& dInfoBuffer = d->infoBuffers[i++];
-        if (!sInfoBuffer) {
-            ALOGE("Null C2InfoBuffer");
-            return Status::BAD_VALUE;
-        }
-        status = objcpy(&dInfoBuffer, *sInfoBuffer, baseBlocks, baseBlockIndices);
-        if (status != Status::OK) {
-            return status;
-        }
-    }
-
-    return status;
-}
-
-} // unnamed namespace
-
-// std::list<std::unique_ptr<C2Work>> -> WorkBundle
-// TODO: Connect with Bufferpool
-Status objcpy(WorkBundle* d, const std::list<std::unique_ptr<C2Work>>& s) {
-    Status status = Status::OK;
-
-    std::vector<BaseBlock> baseBlocks;
-    std::map<const C2Handle*, uint32_t> baseBlockIndices;
-    d->works.resize(s.size());
-    size_t i = 0;
-    for (const std::unique_ptr<C2Work>& sWork : s) {
-        Work &dWork = d->works[i++];
-        if (!sWork) {
-            ALOGW("Null C2Work encountered.");
-            continue;
-        }
-        status = objcpy(&dWork.input, sWork->input,
-                &baseBlocks, &baseBlockIndices);
-        if (status != Status::OK) {
-            return status;
-        }
-        if (sWork->worklets.size() == 0) {
-            ALOGW("Work with no worklets.");
-        } else {
-            if (sWork->worklets.size() > 1) {
-                ALOGW("Work with multiple worklets. "
-                        "Only the first worklet will be marshalled.");
-            }
-            if (!sWork->worklets.front()) {
-                ALOGE("Null worklet encountered.");
-                return Status::BAD_VALUE;
-            }
-
-            // Parcel the first worklet.
-            const C2Worklet &sWorklet = *sWork->worklets.front();
-            Worklet &dWorklet = dWork.worklet;
-
-            dWorklet.tunings.resize(sWorklet.tunings.size());
-            size_t j = 0;
-            for (const std::unique_ptr<C2Tuning>& sTuning : sWorklet.tunings) {
-                status = createParamsBlob(
-                        &dWorklet.tunings[j++],
-                        std::vector<C2Param*>
-                        { reinterpret_cast<C2Param*>(sTuning.get()) });
-                if (status != Status::OK) {
-                    return status;
-                }
-            }
-
-            dWorklet.failures.resize(sWorklet.failures.size());
-            j = 0;
-            for (const std::unique_ptr<C2SettingResult>& sFailure :
-                    sWorklet.failures) {
-                if (!sFailure) {
-                    ALOGE("Null C2SettingResult");
-                    return Status::BAD_VALUE;
-                }
-                status = objcpy(&dWorklet.failures[j++], *sFailure);
-                if (status != Status::OK) {
-                    return status;
-                }
-            }
-
-            status = objcpy(&dWorklet.output, sWorklet.output,
-                    &baseBlocks, &baseBlockIndices);
-            if (status != Status::OK) {
-                return status;
-            }
-        }
-        dWork.workletProcessed = sWork->workletsProcessed > 0;
-        dWork.result = static_cast<Status>(sWork->result);
-    }
-
-    d->baseBlocks = baseBlocks;
-
-    return Status::OK;
-}
-
-namespace /* unnamed */ {
-
-// hidl_handle -> C2Fence
-// Note: File descriptors are not duplicated. The original file descriptor must
-// not be closed before the transaction is complete.
-c2_status_t objcpy(C2Fence* d, const hidl_handle& s) {
-    // TODO: Implement.
-    (void)s;
-    *d = C2Fence();
-    return C2_OK;
-}
-
-// Buffer -> C2Buffer
-// Note: The native handles will be cloned.
-c2_status_t objcpy(std::shared_ptr<C2Buffer>* d, const Buffer& s,
-        const hidl_vec<BaseBlock>& baseBlocks) {
-    c2_status_t status;
-
-    // First, construct C2Buffer with blocks from s.blocks.
-    *d = nullptr;
-
-    // TODO: Only buffers with 1 block are supported.
-    if (s.blocks.size() == 1) {
-        // Obtain the BaseBlock.
-        const Block &sBlock = s.blocks[0];
-        if (sBlock.index >= baseBlocks.size()) {
-            ALOGE("Index into baseBlocks is out of range.");
-            return C2_BAD_VALUE;
-        }
-        const BaseBlock &sBaseBlock = baseBlocks[sBlock.index];
-
-        // Parse meta.
-        std::vector<C2Param*> sBlockMeta;
-        status = parseParamsBlob(&sBlockMeta, sBlock.meta);
-        if (status != C2_OK) {
-            ALOGE("Invalid block params blob.");
-            return C2_BAD_VALUE;
-        }
-
-        // Copy fence.
-        C2Fence dFence;
-        status = objcpy(&dFence, sBlock.fence);
-
-        // Construct a block.
-        switch (sBaseBlock.type) {
-        case BaseBlock::Type::NATIVE: {
-            const native_handle_t* sHandle = sBaseBlock.nativeBlock;
-            if (sHandle == nullptr) {
-                ALOGE("Null native handle in a block.");
-                return C2_BAD_VALUE;
-            }
-            sHandle = native_handle_clone(sHandle);
-            if (sHandle == nullptr) {
-                ALOGE("Cannot clone native handle.");
-                return C2_NO_MEMORY;
-            }
-            const C2Handle *sC2Handle =
-                    reinterpret_cast<const C2Handle*>(sHandle);
-
-            // Currently, there are only 2 types of C2Allocation: ion and
-            // gralloc.
-            if (C2AllocatorIon::isValid(sC2Handle)) {
-                // Check the block meta. It should have exactly 1 C2Info:
-                // C2Hidl_RangeInfo.
-                if ((sBlockMeta.size() != 1) || !sBlockMeta[0]) {
-                    ALOGE("Invalid block metadata for ion block.");
-                    return C2_BAD_VALUE;
-                }
-                if (sBlockMeta[0]->size() != sizeof(C2Hidl_RangeInfo)) {
-                    ALOGE("Invalid block metadata for ion block: range.");
-                    return C2_BAD_VALUE;
-                }
-                C2Hidl_RangeInfo *rangeInfo =
-                        reinterpret_cast<C2Hidl_RangeInfo*>(sBlockMeta[0]);
-
-                std::shared_ptr<C2Allocator> allocator;
-                c2_status_t status = GetCodec2PlatformAllocatorStore(
-                        )->fetchAllocator(
-                        C2PlatformAllocatorStore::ION,
-                        &allocator);
-                if (status != C2_OK) {
-                    ALOGE("Cannot fetch platform linear allocator.");
-                    return status;
-                }
-                std::shared_ptr<C2LinearAllocation> allocation;
-                status = allocator->priorLinearAllocation(
-                        sC2Handle, &allocation);
-                if (status != C2_OK) {
-                    ALOGE("Error constructing linear allocation.");
-                    return status;
-                } else if (!allocation) {
-                    ALOGE("Null linear allocation.");
-                    return C2_BAD_VALUE;
-                }
-                std::shared_ptr<C2LinearBlock> block =
-                        _C2BlockFactory::CreateLinearBlock(allocation);
-                if (!block) {
-                    ALOGE("Cannot create a block.");
-                    return C2_BAD_VALUE;
-                }
-                *d = C2Buffer::CreateLinearBuffer(block->share(
-                        rangeInfo->offset, rangeInfo->length, dFence));
-                if (!(*d)) {
-                    ALOGE("Cannot create a linear buffer.");
-                    return C2_BAD_VALUE;
-                }
-            } else if (C2AllocatorGralloc::isValid(sC2Handle)) {
-                // Check the block meta. It should have exactly 1 C2Info:
-                // C2Hidl_RectInfo.
-                if ((sBlockMeta.size() != 1) || !sBlockMeta[0]) {
-                    ALOGE("Invalid block metadata for graphic block.");
-                    return C2_BAD_VALUE;
-                }
-                if (sBlockMeta[0]->size() != sizeof(C2Hidl_RectInfo)) {
-                    ALOGE("Invalid block metadata for graphic block: crop rect.");
-                    return C2_BAD_VALUE;
-                }
-                C2Hidl_RectInfo *rectInfo =
-                        reinterpret_cast<C2Hidl_RectInfo*>(sBlockMeta[0]);
-
-                std::shared_ptr<C2Allocator> allocator;
-                c2_status_t status = GetCodec2PlatformAllocatorStore(
-                        )->fetchAllocator(
-                        C2PlatformAllocatorStore::GRALLOC,
-                        &allocator);
-                if (status != C2_OK) {
-                    ALOGE("Cannot fetch platform graphic allocator.");
-                    return status;
-                }
-
-                std::shared_ptr<C2GraphicAllocation> allocation;
-                status = allocator->priorGraphicAllocation(
-                        sC2Handle, &allocation);
-                if (status != C2_OK) {
-                    ALOGE("Error constructing graphic allocation.");
-                    return status;
-                } else if (!allocation) {
-                    ALOGE("Null graphic allocation.");
-                    return C2_BAD_VALUE;
-                }
-                std::shared_ptr<C2GraphicBlock> block =
-                        _C2BlockFactory::CreateGraphicBlock(allocation);
-                if (!block) {
-                    ALOGE("Cannot create a block.");
-                    return C2_BAD_VALUE;
-                }
-                *d = C2Buffer::CreateGraphicBuffer(block->share(
-                        C2Rect(rectInfo->width, rectInfo->height,
-                               rectInfo->left, rectInfo->top),
-                        dFence));
-                if (!(*d)) {
-                    ALOGE("Cannot create a graphic buffer.");
-                    return C2_BAD_VALUE;
-                }
-            } else {
-                ALOGE("Unknown handle type.");
-                return C2_BAD_VALUE;
-            }
-            break;
-        }
-        case BaseBlock::Type::POOLED: {
-            // TODO: Implement. Use BufferPool.
-            return C2_OMITTED;
-        }
-        default:
-            ALOGE("Invalid BaseBlock type.");
-            return C2_BAD_VALUE;
-        }
-    } else {
-        ALOGE("Currently a buffer must contain exactly 1 block.");
-        return C2_BAD_VALUE;
-    }
-
-    // Parse info
-    std::vector<C2Param*> params;
-    status = parseParamsBlob(&params, s.info);
-    if (status != C2_OK) {
-        ALOGE("Invalid buffer params blob.");
-        return status;
-    }
-    for (C2Param* param : params) {
-        if (param == nullptr) {
-            ALOGE("Null buffer param encountered.");
-            return C2_BAD_VALUE;
-        }
-        std::shared_ptr<C2Param> c2param(
-                C2Param::Copy(*param).release());
-        if (!c2param) {
-            ALOGE("Invalid buffer param inside a blob.");
-            return C2_BAD_VALUE;
-        }
-        status = (*d)->setInfo(std::static_pointer_cast<C2Info>(c2param));
-        if (status != C2_OK) {
-            ALOGE("C2Buffer::setInfo failed().");
-            return C2_BAD_VALUE;
-        }
-    }
-
-    return C2_OK;
-}
-
-// FrameData -> C2FrameData
-c2_status_t objcpy(C2FrameData* d, const FrameData& s,
-        const hidl_vec<BaseBlock>& baseBlocks) {
-    c2_status_t status;
-    d->flags = static_cast<C2FrameData::flags_t>(s.flags);
-    objcpy(&d->ordinal, s.ordinal);
-    d->buffers.clear();
-    d->buffers.reserve(s.buffers.size());
-    for (const Buffer& sBuffer : s.buffers) {
-        std::shared_ptr<C2Buffer> dBuffer;
-        status = objcpy(&dBuffer, sBuffer, baseBlocks);
-        if (status != C2_OK) {
-            return status;
-        }
-        d->buffers.emplace_back(dBuffer);
-    }
-
-    std::vector<C2Param*> params;
-    status = parseParamsBlob(&params, s.configUpdate);
-    if (status != C2_OK) {
-        ALOGE("Failed to parse frame data params.");
-        return status;
-    }
-    d->configUpdate.clear();
-    for (C2Param* param : params) {
-        d->configUpdate.emplace_back(C2Param::Copy(*param));
-        if (!d->configUpdate.back()) {
-            ALOGE("Unexpected error while parsing frame data params.");
-            return C2_BAD_VALUE;
-        }
-    }
-
-    // TODO: Implement this once C2InfoBuffer has constructors.
-    d->infoBuffers.clear();
-    return C2_OK;
-}
-
-} // unnamed namespace
-
-// WorkBundle -> std::list<std::unique_ptr<C2Work>>
-// TODO: Connect with Bufferpool
-c2_status_t objcpy(std::list<std::unique_ptr<C2Work>>* d, const WorkBundle& s) {
-    c2_status_t status;
-    d->clear();
-    for (const Work& sWork : s.works) {
-        d->emplace_back(std::make_unique<C2Work>());
-        C2Work& dWork = *d->back();
-
-        // input
-        status = objcpy(&dWork.input, sWork.input, s.baseBlocks);
-        if (status != C2_OK) {
-            ALOGE("Error constructing C2Work's input.");
-            return C2_BAD_VALUE;
-        }
-
-        // worklet(s)
-        // TODO: Currently, tunneling is not supported.
-        if (sWork.workletProcessed) {
-            dWork.worklets.clear();
-            dWork.workletsProcessed = 1;
-
-            const Worklet &sWorklet = sWork.worklet;
-            std::unique_ptr<C2Worklet> dWorklet = std::make_unique<C2Worklet>();
-
-            // tunings
-            dWorklet->tunings.clear();
-            dWorklet->tunings.reserve(sWorklet.tunings.size());
-            for (const Params& sTuning : sWorklet.tunings) {
-                std::vector<C2Param*> dParams;
-                status = parseParamsBlob(&dParams, sTuning);
-                if (status != C2_OK) {
-                    ALOGE("Failed to parse C2Tuning in C2Worklet.");
-                    return C2_BAD_VALUE;
-                }
-                for (C2Param* param : dParams) {
-                    std::unique_ptr<C2Param> dParam = C2Param::Copy(*param);
-                    if (!dParam) {
-                        ALOGE("Null C2Tuning encountered while "
-                                "parsing C2Worklet.");
-                        return C2_BAD_VALUE;
-                    }
-                    dWorklet->tunings.emplace_back(
-                            std::unique_ptr<C2Tuning>(
-                            reinterpret_cast<C2Tuning*>(
-                            dParam.release())));
-                }
-            }
-            // failures
-            dWorklet->failures.clear();
-            dWorklet->failures.reserve(sWorklet.failures.size());
-            for (const SettingResult& sFailure : sWorklet.failures) {
-                std::unique_ptr<C2SettingResult> dFailure;
-                status = objcpy(&dFailure, sFailure);
-                if (status != C2_OK) {
-                    ALOGE("Failed to create C2SettingResult in C2Worklet.");
-                    return C2_BAD_VALUE;
-                }
-                dWorklet->failures.emplace_back(std::move(dFailure));
-            }
-            // output
-            status = objcpy(&dWorklet->output, sWorklet.output, s.baseBlocks);
-            if (status != C2_OK) {
-                ALOGE("Failed to create output C2FrameData.");
-                return C2_BAD_VALUE;
-            }
-            dWork.worklets.emplace_back(std::move(dWorklet));
-        } else {
-            dWork.worklets.clear();
-            dWork.workletsProcessed = 0;
-        }
-
-        // result
-        dWork.result = static_cast<c2_status_t>(sWork.result);
-    }
-
-    return C2_OK;
-}
-
-// Params -> std::vector<C2Param*>
-c2_status_t parseParamsBlob(std::vector<C2Param*> *params, const hidl_vec<uint8_t> &blob) {
-    // assuming blob is const here
-    size_t size = blob.size();
-    const uint8_t *data = blob.data();
-    C2Param *p = nullptr;
-
-    do {
-        p = C2ParamUtils::ParseFirst(data, size);
-        if (p) {
-            params->emplace_back(p);
-            size -= p->size();
-            data += p->size();
-        }
-    } while (p);
-
-    return size == 0 ? C2_OK : C2_BAD_VALUE;
-}
-
-namespace /* unnamed */ {
-
-/**
- * Concatenates a list of C2Params into a params blob.
- * \param[out] blob target blob
- * \param[in] params parameters to concatenate
- * \retval C2_OK if the blob was successfully created
- * \retval C2_BAD_VALUE if the blob was not successful (this only happens if the parameters were
- *         not const)
- */
-template<typename T>
-Status _createParamsBlob(hidl_vec<uint8_t> *blob, const T &params) {
-    // assuming the parameter values are const
-    size_t size = 0;
-    for (const auto &p : params) {
-        size += p->size();
-    }
-    blob->resize(size);
-    size_t ix = 0;
-    for (const auto &p : params) {
-        // NEVER overwrite even if param values (e.g. size) changed
-        size_t paramSize = std::min(p->size(), size - ix);
-//        memcpy(&blob[ix], &*p, paramSize);
-        std::copy(
-                reinterpret_cast<const uint8_t*>(&*p),
-                reinterpret_cast<const uint8_t*>(&*p) + paramSize,
-                &blob[ix]);
-        ix += paramSize;
-    }
-    blob->resize(ix);
-    return ix == size ? Status::OK : Status::CORRUPTED;
-}
-
-} // unnamed namespace
-
-// std::vector<const C2Param*> -> Params
-Status createParamsBlob(
-        hidl_vec<uint8_t> *blob,
-        const std::vector<const C2Param*> &params) {
-    return _createParamsBlob(blob, params);
-}
-
-// std::vector<C2Param*> -> Params
-Status createParamsBlob(
-        hidl_vec<uint8_t> *blob,
-        const std::vector<C2Param*> &params) {
-    return _createParamsBlob(blob, params);
-}
-
-// std::vector<std::unique_ptr<C2Param>> -> Params
-Status createParamsBlob(
-        hidl_vec<uint8_t> *blob,
-        const std::vector<std::unique_ptr<C2Param>> &params) {
-    return _createParamsBlob(blob, params);
-}
-
-// std::vector<std::unique_ptr<C2Tuning>> -> Params
-Status createParamsBlob(
-        hidl_vec<uint8_t> *blob,
-        const std::vector<std::unique_ptr<C2Tuning>> &params) {
-    return _createParamsBlob(blob, params);
-}
-
-// std::vector<std::shared_ptr<const C2Info>> -> Params
-Status createParamsBlob(
-        hidl_vec<uint8_t> *blob,
-        const std::vector<std::shared_ptr<const C2Info>> &params) {
-    return _createParamsBlob(blob, params);
-}
-
-// Params -> std::vector<std::unique_ptr<C2Param>>
-c2_status_t copyParamsFromBlob(
-        std::vector<std::unique_ptr<C2Param>>* params,
-        Params blob) {
-    std::vector<C2Param*> paramPointers;
-    c2_status_t status = parseParamsBlob(&paramPointers, blob);
-    if (status != C2_OK) {
-        ALOGE("copyParamsFromBlob -- blob parsing failed.");
-        return status;
-    }
-    params->resize(paramPointers.size());
-    size_t i = 0;
-    for (C2Param* const& paramPointer : paramPointers) {
-        if (!paramPointer) {
-            ALOGE("copyParamsFromBlob -- corrupted params blob.");
-            return C2_BAD_VALUE;
-        }
-        (*params)[i++] = C2Param::Copy(*paramPointer);
-    }
-    return C2_OK;
-}
-
-// Params -> update std::vector<std::unique_ptr<C2Param>>
-c2_status_t updateParamsFromBlob(
-        const std::vector<C2Param*>& params,
-        const Params& blob) {
-    std::unordered_map<uint32_t, C2Param*> index2param;
-    for (C2Param* const& param : params) {
-        if (!param) {
-            ALOGE("updateParamsFromBlob -- corrupted input params.");
-            return C2_BAD_VALUE;
-        }
-        if (index2param.find(param->index()) == index2param.end()) {
-            index2param.emplace(param->index(), param);
-        }
-    }
-
-    std::vector<C2Param*> paramPointers;
-    c2_status_t status = parseParamsBlob(&paramPointers, blob);
-    if (status != C2_OK) {
-        ALOGE("updateParamsFromBlob -- blob parsing failed.");
-        return status;
-    }
-
-    for (C2Param* const& paramPointer : paramPointers) {
-        if (!paramPointer) {
-            ALOGE("updateParamsFromBlob -- corrupted param in blob.");
-            return C2_BAD_VALUE;
-        }
-        decltype(index2param)::iterator i = index2param.find(
-                paramPointer->index());
-        if (i == index2param.end()) {
-            ALOGW("updateParamsFromBlob -- unseen param index.");
-            continue;
-        }
-        if (!i->second->updateFrom(*paramPointer)) {
-            ALOGE("updateParamsFromBlob -- mismatching sizes: "
-                    "%u vs %u (index = %u).",
-                    static_cast<unsigned>(params.size()),
-                    static_cast<unsigned>(paramPointer->size()),
-                    static_cast<unsigned>(i->first));
-            return C2_BAD_VALUE;
-        }
-    }
-    return C2_OK;
-}
-
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace c2
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
diff --git a/media/libstagefright/codec2/hidl/interfaces/1.0/Android.bp b/media/libstagefright/codec2/hidl/interfaces/1.0/Android.bp
deleted file mode 100644
index e75ef24..0000000
--- a/media/libstagefright/codec2/hidl/interfaces/1.0/Android.bp
+++ /dev/null
@@ -1,56 +0,0 @@
-// This file is autogenerated by hidl-gen -Landroidbp.
-
-hidl_package_root {
-    name: "vendor.google.media.c2",
-    path: "frameworks/av/media/libstagefright/codec2/hidl/interfaces",
-}
-
-hidl_interface {
-    name: "vendor.google.media.c2@1.0",
-    root: "vendor.google.media.c2",
-    vndk: {
-        enabled: true,
-    },
-    srcs: [
-        "types.hal",
-        "IComponent.hal",
-        "IComponentInterface.hal",
-        "IComponentListener.hal",
-        "IComponentStore.hal",
-        "IConfigurable.hal",
-        "IInputSurface.hal",
-        "IInputSurfaceConnection.hal",
-    ],
-    interfaces: [
-        "android.hardware.graphics.bufferqueue@1.0",
-        "android.hardware.graphics.common@1.0",
-        "android.hardware.media.bufferpool@1.0",
-        "android.hardware.media.omx@1.0",
-        "android.hardware.media@1.0",
-        "android.hidl.base@1.0",
-    ],
-    types: [
-        "Block",
-        "BlockId",
-        "Buffer",
-        "FieldDescriptor",
-        "FieldId",
-        "FieldSupportedValues",
-        "FieldSupportedValuesQuery",
-        "FieldSupportedValuesQueryResult",
-        "FieldType",
-        "FrameData",
-        "InfoBuffer",
-        "ParamDescriptor",
-        "ParamField",
-        "ParamFieldValues",
-        "SettingResult",
-        "Status",
-        "StructDescriptor",
-        "Work",
-        "WorkOrdinal",
-        "Worklet",
-    ],
-    gen_java: false,
-}
-
diff --git a/media/libstagefright/codec2/hidl/interfaces/1.0/IComponent.hal b/media/libstagefright/codec2/hidl/interfaces/1.0/IComponent.hal
deleted file mode 100644
index b1b4fc2..0000000
--- a/media/libstagefright/codec2/hidl/interfaces/1.0/IComponent.hal
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-package vendor.google.media.c2@1.0;
-
-import android.hardware.graphics.bufferqueue@1.0::IGraphicBufferProducer;
-import android.hardware.media.omx@1.0::IGraphicBufferSource;
-
-import IConfigurable;
-import IComponentInterface;
-import IComponentListener;
-import IInputSurface;
-
-/**
- * Interface for a Codec 2.0 component corresponding to API level 1.0 or
- * below. Components have two states: stopped and running. The running
- * state has three sub-states: executing, tripped and error.
- */
-interface IComponent extends IComponentInterface {
-
-    // METHODS AVAILABLE WHEN RUNNING
-    // =========================================================================
-
-    /**
-     * Queues up work for the component.
-     *
-     * This method must be supported in running (including tripped) states.
-     *
-     * This method must return within 1ms
-     *
-     * It is acceptable for this method to return OK and return an error value
-     * using the onWorkDone() callback.
-     *
-     * @param workBundle WorkBundle object containing Works to queue to the
-     * component.
-     * @return status Status of the call, which may be
-     *   - OK        - Works in \p workBundle were successfully queued.
-     *   - BAD_INDEX - Some component(s) in some Work do(es) not exist.
-     *   - CANNOT_DO - The components are not tunneled.
-     *   - NO_MEMORY - Not enough memory to queue \p workBundle.
-     *   - CORRUPTED - Some unknown error prevented queuing the Works.
-     *                 (unexpected).
-     */
-    queue(WorkBundle workBundle) generates (Status status);
-
-    /**
-     * Discards and abandons any pending work for the component.
-     *
-     * This method must be supported in running (including tripped) states.
-     *
-     * This method must return within 5ms.
-     *
-     * Work that could be immediately abandoned/discarded must be returned in
-     * \p flushedWorks; this can be done in an arbitrary order.
-     *
-     * Work that could not be abandoned or discarded immediately must be marked
-     * to be discarded at the earliest opportunity, and must be returned via
-     * the onWorkDone() callback. This must be completed within 500ms.
-     *
-     * @return status Status of the call, which may be
-     *   - OK        - The component has been successfully flushed.
-     *   - TIMED_OUT - The flush could not be completed within the time limit.
-     *                 (unexpected)
-     *   - CORRUPTED - Some unknown error prevented flushing from
-     *                 completion. (unexpected)
-     * @return flushedWorkBundle WorkBundle object containing flushed Works.
-     */
-    flush(
-        ) generates (
-            Status status,
-            WorkBundle flushedWorkBundle
-        );
-
-    /**
-     * Drains the component, and optionally downstream components. This is a
-     * signalling method; as such it does not wait for any work completion.
-     *
-     * Marks last work item as "drain-till-here", so component is notified not
-     * to wait for further work before it processes work already queued. This
-     * method can also be used to set the end-of-stream flag after work has been
-     * queued. Client can continue to queue further work immediately after this
-     * method returns.
-     *
-     * This method must be supported in running (including tripped) states.
-     *
-     * This method must return within 1ms.
-     *
-     * Work that is completed must be returned via the onWorkDone() callback.
-     *
-     * @param withEos Whether to drain the component with marking end-of-stream.
-     * @return status Status of the call, which may be
-     *   - OK        - The drain request has been successfully recorded.
-     *   - TIMED_OUT - The flush could not be completed within the time limit.
-     *                 (unexpected)
-     *   - CORRUPTED - Some unknown error prevented flushing from completion.
-     *                 (unexpected)
-     */
-    drain(bool withEos) generates (Status status);
-
-    /**
-     * Starts using a persistent input surface for a component.
-     *
-     * The component must be in running state.
-     *
-     * @param surface A persistent input surface to use for codec input.
-     * @return status Status of the call, which may be
-     *   - OK        - The operation completed successfully.
-     *   - CANNOT_DO - The component does not support an input surface.
-     *   - BAD_STATE - Component is not in running state.
-     *   - DUPLICATE - The component is already connected to an input surface.
-     *   - REFUSED   - The input surface is already in use.
-     *   - NO_MEMORY - Not enough memory to start the component.
-     *   - TIMED_OUT - The component could not be connected within the time
-     *                 limit. (unexpected)
-     *   - CORRUPTED - Some unknown error prevented connecting the component.
-     *                 (unexpected)
-     */
-    connectToInputSurface(IInputSurface surface) generates (Status status);
-
-    /**
-     * Starts using a persistent OMX input surface for a component.
-     *
-     * The component must be in running state.
-     *
-     * @param producer Producer component of an OMX persistent input surface.
-     * @param source Source component of an OMX persistent input surface.
-     * @return status Status of the call, which may be
-     *   - OK        - The operation completed successfully.
-     *   - CANNOT_DO - The component does not support an input surface.
-     *   - BAD_STATE - Component is not in running state.
-     *   - DUPLICATE - The component is already connected to an input surface.
-     *   - REFUSED   - The input surface is already in use.
-     *   - NO_MEMORY - Not enough memory to start the component.
-     *   - TIMED_OUT - The component could not be connected within the time
-     *                 limit. (unexpected)
-     *   - CORRUPTED - Some unknown error prevented connecting the component.
-     *                 (unexpected)
-     */
-    connectToOmxInputSurface(
-            IGraphicBufferProducer producer,
-            IGraphicBufferSource source
-        ) generates (Status status);
-
-    /**
-     * Stops using an input surface.
-     *
-     * This call is used for both Codec 2.0 and OMX input surfaces.
-     *
-     * The component must be in running state.
-     *
-     * @return status Status of the call, which may be
-     *   - OK        - The operation completed successfully.
-     *   - CANNOT_DO - The component does not support an input surface.
-     *   - BAD_STATE - Component is not in running state.
-     *   - NOT_FOUND - The component is not connected to an input surface.
-     *   - TIMED_OUT - The component could not be connected within the time
-     *                 limit. (unexpected)
-     *   - CORRUPTED - Some unknown error prevented connecting the component.
-     *                 (unexpected)
-     */
-    disconnectFromInputSurface() generates (Status Status);
-
-    /**
-     * Creates a local block pool backed by the given allocator and returns its
-     * identifier.
-     *
-     * This call must return within 100 msec.
-     *
-     * @param allocatorId The Codec 2.0 allocator ID
-     * @return status Status of the call, which may be
-     *   - OK        - The operation completed successfully.
-     *   - NO_MEMORY - Not enough memory to create the pool.
-     *   - BAD_VALUE - Invalid allocator.
-     *   - TIMED_OUT - The pool could not be created within the time
-     *                 limit. (unexpected)
-     *   - CORRUPTED - Some unknown error prevented creating the pool.
-     *                 (unexpected)
-     * @return blockPoolId The Codec 2.0 blockpool ID for the created pool.
-     * @return configurable Configuration interface for the created pool.
-     */
-    createBlockPool(uint32_t allocatorId) generates (
-        Status status,
-        uint64_t blockPoolId,
-        IConfigurable configurable
-    );
-
-    // STATE CHANGE METHODS
-    // =========================================================================
-
-    /**
-     * Starts the component.
-     *
-     * This method must be supported in stopped state as well as tripped state.
-     *
-     * If the return value is OK, the component must be in the running state.
-     * If the return value is BAD_STATE or DUPLICATE, no state change is
-     * expected as a response to this call.
-     * Otherwise, the component must be in the stopped state.
-     *
-     * If a component is in the tripped state and start() is called while the
-     * component configuration still results in a trip, start must succeed and
-     * a new onTripped callback must be used to communicate the configuration
-     * conflict that results in the new trip.
-     *
-     * This method must return within 500ms.
-     *
-     * @return status Status of the call, which may be
-     *   - OK        - The component has started successfully.
-     *   - BAD_STATE - Component is not in stopped or tripped state.
-     *   - DUPLICATE - When called during another start call from another
-     *                 thread.
-     *   - NO_MEMORY - Not enough memory to start the component.
-     *   - TIMED_OUT - The component could not be started within the time limit.
-     *                 (unexpected)
-     *   - CORRUPTED - Some unknown error prevented starting the component.
-     *                 (unexpected)
-     */
-    start() generates (Status status);
-
-    /**
-     * Stops the component.
-     *
-     * This method must be supported in running (including tripped) state.
-     *
-     * This method must return withing 500ms.
-     *
-     * Upon this call, all pending work must be abandoned.
-     * If the return value is BAD_STATE or DUPLICATE, no state change is
-     * expected as a response to this call.
-     * For all other return values, the component must be in the stopped state.
-     *
-     * This does not alter any settings and tunings that may have resulted in a
-     * tripped state.
-     *
-     * @return status Status of the call, which may be
-     *   - OK        - The component has stopped successfully.
-     *   - BAD_STATE - Component is not in running state.
-     *   - DUPLICATE - When called during another stop call from another thread.
-     *   - TIMED_OUT - The component could not be stopped within the time limit.
-     *                 (unexpected)
-     *   - CORRUPTED - Some unknown error prevented starting the component.
-     *                 (unexpected)
-     */
-    stop() generates (Status status);
-
-    /**
-     * Resets the component.
-     *
-     * This method must be supported in all (including tripped) states other
-     * than released.
-     *
-     * This method must be supported during any other blocking call.
-     *
-     * This method must return withing 500ms.
-     *
-     * After this call returns all work must have been abandoned, all references
-     * must have been released.
-     *
-     * If the return value is BAD_STATE or DUPLICATE, no state change is
-     * expected as a response to this call.
-     * For all other return values, the component shall be in the stopped state.
-     *
-     * This brings settings back to their default - "guaranteeing" no tripped
-     * state.
-     *
-     * @return status Status of the call, which may be
-     *   - OK        - The component has been reset.
-     *   - BAD_STATE - Component is in released state.
-     *   - DUPLICATE - When called during another reset call from another
-     *                 thread.
-     *   - TIMED_OUT - The component could not be reset within the time limit.
-     *                 (unexpected)
-     *   - CORRUPTED - Some unknown error prevented resetting the component.
-     *                 (unexpected)
-     */
-    reset() generates (Status status);
-
-    /**
-     * Releases the component.
-     *
-     * This method must be supported in stopped state.
-     *
-     * This method must return withing 500ms. Upon return all references must
-     * be abandoned.
-     *
-     * @return status Status of the call, which may be
-     *   - OK        - The component has been released.
-     *   - BAD_STATE - The component is running.
-     *   - DUPLICATE - The component is already released.
-     *   - TIMED_OUT - The component could not be released within the time
-     *                 limit. (unexpected)
-     *   - CORRUPTED - Some unknown error prevented releasing the component.
-     *                 (unexpected)
-     */
-    release() generates (Status status);
-
-};
-
diff --git a/media/libstagefright/codec2/hidl/interfaces/1.0/IComponentInterface.hal b/media/libstagefright/codec2/hidl/interfaces/1.0/IComponentInterface.hal
deleted file mode 100644
index 7014998..0000000
--- a/media/libstagefright/codec2/hidl/interfaces/1.0/IComponentInterface.hal
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-package vendor.google.media.c2@1.0;
-
-import IConfigurable;
-
-/**
- * Component interface object. This object contains all of the configuration of
- * a potential or actual component. It can be created and used independently of
- * an actual Codec 2.0 component instance to query support and parameters for
- * various component settings and configurations for a potential component.
- * Actual components also expose this interface.
- */
-interface IComponentInterface extends IConfigurable {
-    /*
-     * There are no additional methods to IConfigurable interface.
-     *
-     * Component interfaces have no states.
-     *
-     * The name of the component or component interface object is a unique name
-     * for that component or component interface 'class'; however, multiple
-     * instances of that component must have the same name.
-     */
-};
-
diff --git a/media/libstagefright/codec2/hidl/interfaces/1.0/IComponentListener.hal b/media/libstagefright/codec2/hidl/interfaces/1.0/IComponentListener.hal
deleted file mode 100644
index d1a681a..0000000
--- a/media/libstagefright/codec2/hidl/interfaces/1.0/IComponentListener.hal
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-package vendor.google.media.c2@1.0;
-
-/**
- * This callback interface is used for handling notifications from IComponent.
- */
-interface IComponentListener {
-
-    /**
-     * Notify the listener that some works have been completed.
-     */
-    oneway onWorkDone(WorkBundle workBundle);
-
-    /**
-     * Notify the listener that the component is tripped.
-     */
-    oneway onTripped(vec<SettingResult> settingResults);
-
-    /**
-     * Notify the listener of an error.
-     *
-     * @param status The error type. \p status may be `OK`, which means that an
-     *     error has occurred, but the error type is unknown.
-     * @param errorCode Additional error code. The framework may not recognize
-     *     this.
-     */
-    oneway onError(Status status, uint32_t errorCode);
-
-};
-
diff --git a/media/libstagefright/codec2/hidl/interfaces/1.0/IComponentStore.hal b/media/libstagefright/codec2/hidl/interfaces/1.0/IComponentStore.hal
deleted file mode 100644
index eae5b72..0000000
--- a/media/libstagefright/codec2/hidl/interfaces/1.0/IComponentStore.hal
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-package vendor.google.media.c2@1.0;
-
-import android.hardware.media.bufferpool@1.0::IClientManager;
-import IComponentInterface;
-import IComponentListener;
-import IComponent;
-import IConfigurable;
-import IInputSurface;
-
-interface IComponentStore extends IConfigurable {
-
-    /**
-     * Creates a component by name.
-     *
-     * This method must return within 100ms.
-     *
-     * @param name Name of the component to create. This should match one of the
-     *     names returned by listComponents().
-     * @param listener The component listener to use for the component.
-     * @param pool The buffer pool client manager of the component listener.
-     *     This must be null if the listener process does not own a buffer pool.
-     * @return status Status of the call, which may be
-     *   - OK        - The component was created successfully.
-     *   - NOT_FOUND - There is no component with the given name.
-     *   - NO_MEMORY - Not enough memory to create the component.
-     *   - TIMED_OUT - The component could not be created within the time limit.
-     *                 (unexpected)
-     *   - CORRUPTED - Some unknown error prevented the creation of the
-     *                 component. (unexpected)
-     * @return comp The created component if `Status = OK`.
-     */
-    createComponent(
-            string name,
-            IComponentListener listener,
-            IClientManager pool
-        ) generates (
-            Status status,
-            IComponent comp
-        );
-
-    /**
-     * Creates a component interface by name.
-     *
-     * This method must return within 100ms.
-     *
-     * @param name Name of the component interface to create. This should match
-     *     one of the names returned by listComponents().
-     * @return status Status of the call, which may be
-     *   - OK        - The component interface was created successfully.
-     *   - NOT_FOUND - There is no component interface with the given name.
-     *   - NO_MEMORY - Not enough memory to create the component interface.
-     *   - TIMED_OUT - The component interface could not be created within the
-     *                 time limit. (unexpected)
-     *   - CORRUPTED - Some unknown error prevented the creation of the
-     *                 component interface. (unexpected)
-     * @return compIntf The created component interface if `Status = OK`.
-     */
-    createInterface(
-            string name
-        ) generates (
-            Status status,
-            IComponentInterface compIntf
-        );
-
-    /**
-     * Component traits.
-     */
-    struct ComponentTraits {
-        /**
-         * Name of the component.
-         */
-        string name;
-
-        enum Domain : uint32_t {
-            AUDIO,
-            VIDEO,
-            OTHER = 0xffffffff,
-        };
-        /**
-         * Component domain. The framework may not recognize `OTHER`.
-         */
-        Domain domain;
-        /**
-         * If #domain is `OTHER`, #domainOther can be used to provide additional
-         * information. Otherwise, #domainOther is ignored. The framework may
-         * not inspect this value.
-         */
-        uint32_t domainOther;
-
-        enum Kind : uint32_t {
-            DECODER,
-            ENCODER,
-            OTHER = 0xffffffff,
-        };
-        /**
-         * Component kind. The framework may not recognize `OTHER`.
-         */
-        Kind kind;
-        /**
-         * If #kind is `OTHER`, #kindOther can be used to provide additional
-         * information. Otherwise, #kindOther is ignored. The framework may not
-         * inspect this value.
-         */
-        uint32_t kindOther;
-
-        /**
-         * Rank used by MediaCodecList to determine component ordering. Lower
-         * value means higher priority.
-         */
-        uint32_t rank;
-
-        /**
-         * Media type.
-         */
-        string mediaType;
-
-        /**
-         * Aliases for component name for backward compatibility.
-         *
-         * \note Multiple components can have the same alias (but not the same
-         * component name) as long as their media types differ.
-         */
-        vec<string> aliases;
-    };
-
-    /**
-     * Returns the list of components supported by this component store.
-     *
-     * This method must return within 500ms.
-     *
-     * @return traits List of component traits for all components supported by this store in no
-     * particular order.
-     */
-    listComponents() generates (vec<ComponentTraits> traits);
-
-    /**
-     * Creates a persistent input surface that can be used as an input surface
-     * for any IComponent instance
-     *
-     * This method must return within 100ms.
-     *
-     * @return surface A persistent input surface
-     */
-    createInputSurface() generates (IInputSurface surface);
-
-    /**
-     * Returns a list of StructDescriptor object for a set of requested
-     * structures that this store is aware of.
-     *
-     * This operation must be performed at best effort, e.g. the component
-     * store must simply ignore all struct indices that it is not aware of.
-     *
-     * @param indices struct indices to return des
-     * @return status Status of the call, which may be
-     *   - OK        - The operation completed successfully.
-     *   - NOT_FOUND - Some indices were not known.
-     *   - NO_MEMORY - Not enough memory to complete this method.
-     * @return structs List of StructDescriptor objects.
-     */
-    getStructDescriptors(
-            vec<ParamIndex> indices
-        ) generates (
-            Status status,
-            vec<StructDescriptor> structs
-        );
-
-    /**
-     * Returns information required for using BufferPool API in buffer passing.
-     * If the returned pool is not null, the client can call registerSender() to
-     * register its IAccessor instance, hence allowing the client to send
-     * buffers to components hosted by this process.
-     *
-     * @return pool If the component store supports receiving buffers via
-     *     BufferPool API, \p pool must be a valid `IClientManager` instance.
-     *     Otherwise, \p pool must be null.
-     */
-    getPoolClientManager(
-        ) generates (
-            IClientManager pool
-        );
-
-    /**
-     * The store must copy the contents of \p src into \p dst without changing
-     * the format of \p dst.
-     *
-     * @param src Source buffer.
-     * @param dst Destination buffer.
-     * @return status Status of the call, which may be
-     *   - OK        - The copy is successful.
-     *   - CANNOT_DO - \p src and \p dst are not compatible.
-     *   - REFUSED   - No permission to copy.
-     *   - CORRUPTED - The copy cannot be done. (unexpected)
-     */
-    copyBuffer(Buffer src, Buffer dst) generates (Status status);
-
-};
-
diff --git a/media/libstagefright/codec2/hidl/interfaces/1.0/IConfigurable.hal b/media/libstagefright/codec2/hidl/interfaces/1.0/IConfigurable.hal
deleted file mode 100644
index 83447ad..0000000
--- a/media/libstagefright/codec2/hidl/interfaces/1.0/IConfigurable.hal
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-package vendor.google.media.c2@1.0;
-
-/**
- * Generic configuration interface used by all configurable Codec 2.0
- * components.
- *
- * This interface must be supported in all states of the inheriting
- * object, and must not change the state of the inheriting object.
- */
-interface IConfigurable {
-    /**
-     * Returns the name of this object. This must match the name that was
-     * supplied during the creation of the object.
-     *
-     * @return name Name of this object.
-     */
-    getName() generates (string name);
-
-    /**
-     * Queries a set of parameters from the object. Querying is performed at
-     * best effort: the object must query all supported parameters and skip
-     * unsupported ones, or parameters that could not be allocated. Any errors
-     * are communicated in the return value.
-     *
-     * \note Parameter values do not depend on the order of query.
-     *
-     * This method must return within 1ms if \p mayBlock is DONT_BLOCK, and
-     * within 5ms otherwise.
-     *
-     * @param indices List of param indices for params to be queried.
-     * @param mayBlock Whether this call may block or not.
-     * @return status Status of the call, which may be
-     *   - OK        - All parameters could be queried.
-     *   - BAD_INDEX - All supported parameters could be queried, but some
-     *                 parameters were not supported.
-     *   - NO_MEMORY - Could not allocate memory for a supported parameter.
-     *   - BLOCKING  - Querying some parameters requires blocking.
-     *   - CORRUPTED - Some unknown error prevented the querying of the
-     *                 parameters. (unexpected)
-     * @return params List of params queried corresponding to \p indices.
-     */
-    query(
-            vec<ParamIndex> indices,
-            bool mayBlock
-        ) generates (
-            Status status,
-            Params params
-        );
-
-    /**
-     * Sets a set of parameters for the object. Tuning is performed at best
-     * effort: the object must update all supported configuration at best
-     * effort and skip unsupported parameters. Any errors are communicated in
-     * the return value and in \p failures.
-     *
-     * \note Parameter tuning DOES depend on the order of the tuning parameters.
-     * E.g. some parameter update may allow some subsequent parameter update.
-     *
-     * This method must return within 1ms if \p mayBlock is false, and within
-     * 5ms otherwise.
-     *
-     * @param inParams Requested parameter updates.
-     * @param mayBlock Whether this call may block or not.
-     * @return status Status of the call, which may be
-     *   - OK        - All parameters could be updated successfully.
-     *   - BAD_INDEX - All supported parameters could be updated successfully,
-     *                 but some parameters were not supported.
-     *   - NO_MEMORY - Some supported parameters could not be updated
-     *                 successfully because they contained unsupported values.
-     *                 These are returned in \p failures.
-     *   - BLOCKING  - Setting some parameters requires blocking.
-     *   - CORRUPTED - Some unknown error prevented the update of the
-     *                 parameters. (unexpected)
-     * @return failures List of parameter failures.
-     * @return outParams Resulting values for the configured parameters.
-     */
-    config(
-            Params inParams,
-            bool mayBlock
-        ) generates (
-            Status status,
-            vec<SettingResult> failures,
-            Params outParams
-        );
-
-    // REFLECTION MECHANISM
-    // =========================================================================
-
-    /**
-     * Returns a selected range of the set of supported parameters.
-     *
-     * The set of supported parameters are represented in a vector with a
-     * start index of 0, and the selected range are indices into this vector.
-     * Fewer than \p count parameters are returned if the selected range is
-     * not fully/not at all part of the available vector indices.
-     *
-     * This method must return within 1ms.
-     *
-     * @param start start index of selected range
-     * @param count size of the selected
-     * @return status Status of the call, which may be
-     *   - OK        - The operation completed successfully.
-     *   - NO_MEMORY - Not enough memory to complete this method.
-     * @return params Vector containing the selected range of supported
-     *     parameters.
-     */
-    querySupportedParams(
-            uint32_t start,
-            uint32_t count
-        ) generates (
-            Status status,
-            vec<ParamDescriptor> params
-        );
-
-    /**
-     * Retrieves the supported values for the queried fields.
-     *
-     * Upon return the object must fill in the supported
-     * values for the fields listed as well as a status for each field.
-     * Object shall process all fields queried even if some queries fail.
-     *
-     * This method must return within 1ms if \p mayBlock is false, and within
-     * 5ms otherwise.
-     *
-     * @param inFields Vector of field queries.
-     * @param mayBlock Whether this call may block or not.
-     * @return status Status of the call, which may be
-     *   - OK        - The operation completed successfully.
-     *   - BLOCKING  - Querying some parameters requires blocking.
-     *   - NO_MEMORY - Not enough memory to complete this method.
-     *   - BAD_INDEX - At least one field was not recognized as a component
-     *                 field.
-     * @return outFields Vector containing supported values and query result
-     *     for the selected fields.
-     */
-    querySupportedValues(
-            vec<FieldSupportedValuesQuery> inFields,
-            bool mayBlock
-        ) generates (
-            Status status,
-            vec<FieldSupportedValuesQueryResult> outFields
-        );
-
-};
-
diff --git a/media/libstagefright/codec2/hidl/interfaces/1.0/IInputSurface.hal b/media/libstagefright/codec2/hidl/interfaces/1.0/IInputSurface.hal
deleted file mode 100644
index 79dd65f..0000000
--- a/media/libstagefright/codec2/hidl/interfaces/1.0/IInputSurface.hal
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-package vendor.google.media.c2@1.0;
-
-import android.hardware.graphics.bufferqueue@1.0::IGraphicBufferProducer;
-
-import IConfigurable;
-import IInputSurfaceConnection;
-
-/**
- * Input surface that can be configured for the IComponent.
- */
-interface IInputSurface extends IGraphicBufferProducer {
-
-    /**
-     * Connects this input surface to a component.
-     *
-     * This call must return within 100 ms.
-     *
-     * @param component The component to connect to. This must have type
-     *     IComponent.
-     * @return status Status of the call, which may be
-     *   - OK        - The operation succeeded.
-     *   - BAD_STATE - The component is in running state.
-     *   - DUPLICATE - The surface is already connected to a component.
-     *   - NO_MEMORY - Could not allocate memory to connect to the component.
-     *   - CORRUPTED - Some unknown error prevented the connection. (unexpected)
-     * @return connection Connection object that is used to disconnect
-     *     from the component.
-     */
-    connectToComponent(
-            interface component
-        ) generates (
-            Status status,
-            IInputSurfaceConnection connection
-        );
-
-    /**
-     * Returns the Codec 2.0 configuration object for this surface.
-     *
-     * @return configurable The configuration object for this surface.
-     */
-    getConfigurable() generates (IConfigurable configurable);
-
-};
-
diff --git a/media/libstagefright/codec2/hidl/interfaces/1.0/IInputSurfaceConnection.hal b/media/libstagefright/codec2/hidl/interfaces/1.0/IInputSurfaceConnection.hal
deleted file mode 100644
index 4deabb9..0000000
--- a/media/libstagefright/codec2/hidl/interfaces/1.0/IInputSurfaceConnection.hal
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-package vendor.google.media.c2@1.0;
-
-interface IInputSurfaceConnection {
-
-    /**
-     * Disconnects this input surface from the component.
-     *
-     * This call must return within 100 ms.
-     *
-     * @return status Status of the call, which may be
-     *   - OK        - The operation succeeded.
-     *   - BAD_STATE - The component is not in running state.
-     *   - NOT_FOUND - The surface is not connected to a component.
-     *   - CORRUPTED - Some unknown error prevented the connection. (unexpected)
-     */
-    disconnect() generates (Status status);
-
-};
-
diff --git a/media/libstagefright/codec2/hidl/interfaces/1.0/types.hal b/media/libstagefright/codec2/hidl/interfaces/1.0/types.hal
deleted file mode 100644
index 65b7fec..0000000
--- a/media/libstagefright/codec2/hidl/interfaces/1.0/types.hal
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-package vendor.google.media.c2@1.0;
-
-import android.hardware.media.bufferpool@1.0::BufferStatusMessage;
-
-enum Status : int32_t {
-    /** operation completed successfully */
-    OK        = 0,
-
-    // bad input
-
-    /** argument has invalid value (user error) */
-    BAD_VALUE = -22,
-    /** argument uses invalid index (user error) */
-    BAD_INDEX = -75,
-    /** argument/index is valid but not possible */
-    CANNOT_DO = -2147483646,
-
-    // bad sequencing of events
-
-    /** object already exists */
-    DUPLICATE = -17,
-    /** object not found */
-    NOT_FOUND = -2,
-    /** operation is not permitted in the current state */
-    BAD_STATE = -38,
-    /** operation would block but blocking is not permitted */
-    BLOCKING  = -9930,
-
-    // bad environment
-
-    /** not enough memory to complete operation */
-    NO_MEMORY = -12,
-    /** missing permission to complete operation */
-    REFUSED   = -1,
-
-    /** operation did not complete within timeout */
-    TIMED_OUT = -110,
-
-    // missing functionality
-
-    /** operation is not implemented/supported (optional only) */
-    OMITTED   = -74,
-
-    // unknown fatal
-
-    /** some unexpected error prevented the operation */
-    CORRUPTED = -2147483648,
-
-    // uninitialized
-
-    /** status has not been initialized */
-    NO_INIT   = -19,
-};
-
-/**
- * Codec 2.0 parameter index
- */
-typedef uint32_t ParamIndex;
-
-/**
- * Codec 2.0 parameter structure
- *
- * The description of a Params is provided by supplying a ParamIndex to
- * IComponentStore::getStructDescriptors().
- */
-typedef vec<uint8_t> Params;
-
-/**
- * Struct uniquely specifying a field in an arbitrary parameter structure.
- */
-struct FieldId {
-    /** Offset of the field in bytes */
-    uint32_t offset;
-    /** Size of the field in bytes */
-    uint32_t size;
-};
-
-/**
- * Struct representing a location of a field in a parameter with a given index.
- */
-struct ParamField {
-    /** Index of the parameter */
-    ParamIndex index;
-    /** Field identifier */
-    FieldId fieldId;
-};
-
-/**
- * Struct describing basic properties of a parameter with a given index.
- */
-struct ParamDescriptor {
-    /** Parameter index */
-    ParamIndex index;
-
-    enum Attrib : uint32_t {
-        IS_REQUIRED   = 1u << 0,
-        IS_PERSISTENT = 1u << 1,
-    };
-    /** Parameter attributes */
-    bitfield<Attrib> attrib;
-
-    /** Parameter name */
-    string name;
-
-    /** index of other parameters that this parameter depends on */
-    vec<ParamIndex> dependencies;
-};
-
-// Generic way to describe supported numeric values for Codec 2.0 interfaces.
-
-/**
- * An untyped value that can fit on 64 bits - the type of which is communicated
- * via a separate channel (FieldType).
- */
-typedef uint64_t PrimitiveValue;
-
-/*
- * Generic supported values for a field.
- *
- * This can be either a range or a set of values. The range can be linear or
- * geometric with clear minimum and maximum values, and can have an optional
- * step size or geometric ratio. Values can optionally represent flags.
- */
-struct FieldSupportedValues {
-    struct Range {
-        PrimitiveValue min;
-        PrimitiveValue max;
-        PrimitiveValue step;
-        PrimitiveValue num;
-        PrimitiveValue denom;
-    };
-
-    enum Type : int32_t {
-        /** No supported values */
-        EMPTY,
-        /** Numeric range that can be continuous or discrete */
-        RANGE,
-        /** List of values */
-        VALUES,
-        /** List of flags that can be OR-ed */
-        FLAGS,
-        /** Other representations */
-        OTHER = 0xffffffff,
-    };
-    /**
-     * Type of the supported values. The framework may not recognize `OTHER`.
-     */
-    Type type;
-    /**
-     * Codec2.0 type code of the supported values.
-     *   * If #type is `OTHER`, #typeOther can be used to give more information.
-     *     In this case, the interpretation of this structure is
-     *     implementation-defined.
-     *   * For all other values of #type, #typeOther is not used.
-     * The framework may not inspect this value.
-     */
-    int32_t typeOther;
-
-    /*
-     * If #type = EMPTY, #range and #value are unused.
-     */
-
-    /**
-     * If #type = RANGE, #range will specify the range of possible values.
-     *
-     * The intended type of members of #range will be clear in the context where
-     * FieldSupportedValues is used.
-     */
-    Range range;
-
-    /**
-     * If #type is `VALUES` or `FLAGS`, #value will list supported values.
-     *
-     * The intended type of components of #value will be clear in the context
-     * where FieldSupportedValues is used.
-     */
-    vec<PrimitiveValue> values;
-};
-
-/**
- * Supported values for a specific field.
- *
- * This is a pair of the field specifier together with an optional supported
- * values object. This structure is used when reporting parameter configuration
- * failures and conflicts.
- */
-struct ParamFieldValues {
-    /** the field or parameter */
-    ParamField paramOrField;
-
-    /**
-     * optional supported values for the field if paramOrField specifies an
-     * actual field that is numeric (non struct, blob or string). Supported
-     * values for arrays (including string and blobs) describe the supported
-     * values for each element (character for string, and bytes for blobs). It
-     * is optional for read-only strings and blobs.
-     */
-    vec<FieldSupportedValues> values;
-};
-
-/**
- * Field descriptor.
- */
-struct FieldDescriptor {
-
-    /** Field id */
-    FieldId fieldId;
-
-    /**
-     * Possible types of a field.
-     */
-    enum Type : uint32_t {
-        NO_INIT,
-        INT32,
-        UINT32,
-        CNTR32,
-        INT64,
-        UINT64,
-        CNTR64,
-        FLOAT,
-        /**
-         * Fixed-size string (POD)
-         */
-        STRING = 0x100,
-        /**
-         * blobs have no sub-elements and can be thought of as byte arrays.
-         * However, bytes cannot be individually addressed by clients.
-         */
-        BLOB,
-        /**
-         * Structs. Marked with this flag in addition to their coreIndex.
-         */
-        STRUCT_FLAG = 0x20000,
-    };
-    /**
-     * Type of the field.
-     */
-    bitfield<Type> type;
-
-    /** Extent of the field */
-    uint32_t length;
-    /*
-     * Note: the last member of a param struct can be of arbitrary length (e.g.
-     * if it is T[] array, which extends to the last byte of the parameter.)
-     * This is marked with extent 0.
-     */
-
-    /** Name of the field */
-    string name;
-    /** Named value type */
-    struct NamedValue {
-        string name;
-        PrimitiveValue value;
-    };
-    /** Named values for the field */
-    vec<NamedValue> namedValues;
-};
-
-/**
- * Struct descriptor.
- */
-struct StructDescriptor {
-    /** Struct type */
-    ParamIndex type;
-    /** Field descriptors for each field */
-    vec<FieldDescriptor> fields;
-};
-
-/**
- * Information describing the reason a parameter settings may fail, or
- * may be overriden.
- */
-struct SettingResult {
-    /** Failure code (of Codec 2.0 SettingResult failure type) */
-    enum Failure : uint32_t {
-        /** Parameter is read-only and cannot be set. */
-        READ_ONLY,
-        /** Parameter mismatches input data. */
-        MISMATCH,
-        /** Parameter does not accept value. */
-        BAD_VALUE,
-        /** Parameter is not supported. */
-        BAD_TYPE,
-        /** Parameter is not supported on the specific port. */
-        BAD_PORT,
-        /** Parameter is not supported on the specific stream. */
-        BAD_INDEX,
-        /** Parameter is in conflict with an/other setting(s). */
-        CONFLICT,
-        /**
-         * Parameter is out of range due to other settings. (This failure mode
-         * can only be used for strict parameters.)
-         */
-        UNSUPPORTED,
-        /**
-         * Requested parameter value is in conflict with an/other setting(s)
-         * and has been corrected to the closest supported value. This failure
-         * mode is given to provide suggestion to the client as to how to enable
-         * the requested parameter value. */
-        INFO_CONFLICT,
-        /**
-         * This failure mode is reported when all the above failure modes do not
-         * apply.
-         */
-        OTHER = 0xffffffff,
-    };
-    /**
-     * The failure type. The framework might not recognize `OTHER`.
-     */
-    Failure failure;
-    /**
-     * The failure code.
-     *   * If #failure is `OTHER`, #failureOther can be used to give more
-     *     information.
-     *   * For all other values of #failure, #failureOther is not used.
-     * The framework may not inspect this value.
-     */
-    uint32_t failureOther;
-
-    /**
-     * Failing (or corrected) field. Currently supported values for the field.
-     * This is set if different from the globally supported values (e.g. due to
-     * restrictions by another param or input data)
-     */
-    ParamFieldValues field;
-
-    /**
-     * Conflicting parameters or fields with
-     * (optional) suggested values for any conflicting fields to avoid the conflict.
-     */
-    vec<ParamFieldValues> conflicts;
-};
-
-/**
- * Data structure for ordering Work objects. Each member is used for comparing
- * urgency in the same fashion: a smaller value indicates that the associated
- * Work object is more urgent.
- */
-struct WorkOrdinal {
-    /**
-     * Timestamp in microseconds - can wrap around.
-     */
-    uint64_t timestampUs;
-    /**
-     * Frame index - can wrap around.
-     */
-    uint64_t frameIndex;
-    /**
-     * Component specific frame ordinal - can wrap around.
-     */
-    uint64_t customOrdinal;
-};
-
-/**
- * A structure that holds information of a Block. There are two types of Blocks:
- * NATIVE and POOLED. Each type has its own way of identifying blocks.
- */
-struct BaseBlock {
-    enum Type : int32_t {
-        NATIVE,
-        POOLED,
-    };
-    /**
-     * There are two types of blocks: NATIVE and POOLED.
-     */
-    Type type;
-
-    /**
-     * A "NATIVE" block is represented by a native handle.
-     */
-    handle nativeBlock;
-
-    /*
-     * A "POOLED" block is represented by `BufferStatusMessage`.
-     */
-    BufferStatusMessage pooledBlock;
-};
-
-/**
- * A Block in transfer consists of an index into an array of BaseBlock plus some
- * extra information. One BaseBlock may occur in multiple blocks in one
- * `WorkBundle`.
- */
-struct Block {
-    /**
-     * Identity of the BaseBlock within a WorkBundle. This is an index into the
-     * `baseBlocks` array of a `WorkBundle` object.
-     */
-    uint32_t index;
-    /**
-     * Metadata associated with the block.
-     */
-    Params meta;
-    /**
-     * Fence for synchronizing block access.
-     */
-    handle fence;
-};
-
-/**
- * Type of buffers processed by a component.
- */
-struct Buffer {
-    /**
-     * Metadata associated with the buffer.
-     */
-    Params info;
-    /**
-     * Blocks contained in the buffer.
-     */
-    vec<Block> blocks;
-};
-
-/**
- * An extension of Buffer that also contains an index.
- */
-struct InfoBuffer {
-    ParamIndex index;
-    Buffer buffer;
-};
-
-/**
- * This structure represents a frame with its metadata. A frame consists of an
- * ordered set of buffers, configuration changes, and info buffers along with
- * some non-configuration metadata.
- */
-struct FrameData {
-    enum Flags : uint32_t {
-        /**
-         * For input frames: no output frame will be generated when processing
-         * this frame, but metadata must still be processed.
-         * For output frames: this frame must be discarded but metadata is still
-         * valid.
-         */
-        DROP_FRAME    = (1 << 0),
-        /**
-         * This frame is the last frame of the current stream. Further frames
-         * are part of a new stream.
-         */
-        END_OF_STREAM = (1 << 1),
-        /**
-         * This frame must be discarded with its metadata.
-         * This flag is only set by components - e.g. as a response to the flush
-         * command.
-         */
-        DISCARD_FRAME = (1 << 2),
-        /**
-         * This frame contains only codec-specific configuration data, and no
-         * actual access unit.
-         *
-         * \deprecated Pass codec configuration with the codec-specific
-         * configuration info together with the access unit.
-         */
-        CODEC_CONFIG  = (1u << 31),
-    };
-
-    /**
-     * Frame flags.
-     */
-    bitfield<Flags> flags;
-
-    /**
-     * Ordinal of the frame.
-     */
-    WorkOrdinal ordinal;
-
-    /**
-     * Frame buffers.
-     */
-    vec<Buffer> buffers;
-
-    /**
-     * Params determining a configuration update.
-     */
-    Params configUpdate;
-
-    /**
-     * Info buffers.
-     */
-    vec<InfoBuffer> infoBuffers;
-};
-
-/**
- * Struct for
- */
-struct Worklet {
-    /**
-     * List of Params describing tunings.
-     */
-    vec<Params> tunings;
-
-    /**
-     * List of failures.
-     */
-    vec<SettingResult> failures;
-
-    /**
-     * Output frame data.
-     */
-    FrameData output;
-
-    /* Note: Component id is not necessary as tunneling is not supported. */
-};
-
-/**
- * This structure holds information about a single work item. It must be passed
- * by the client to the component.
- */
-struct Work {
-    /**
-     * FrameData for the input. Indices of Blocks inside #input refer to
-     * BaseBlocks in the member `blocks` of the containing `WorkBundle`.
-     */
-    FrameData input;
-    /**
-     * Worklet. Indices of Blocks inside `worklet.output` refer to
-     * BaseBlocks in the member `blocks` of the containing `WorkBundle`.
-     */
-    Worklet worklet;
-    /**
-     * Whether the worklet was processed or not.
-     */
-    bool workletProcessed;
-    Status result;
-};
-
-/**
- * This structure holds a list of Work objects and a list of BaseBlocks.
- */
-struct WorkBundle {
-    /**
-     * A list of Work items.
-     */
-    vec<Work> works;
-    /**
-     * A list of blocks indexed by elements of #works.
-     */
-    vec<BaseBlock> baseBlocks;
-};
-
-/**
- * This structure describes a query for supported values of a field. This is
- * used as input to IConfigurable::queryFieldSupportedValues().
- */
-struct FieldSupportedValuesQuery {
-    enum Type : uint32_t {
-        /** Query all possible values regardless of other settings */
-        POSSIBLE,
-        /** Query currently possible values given dependent settings */
-        CURRENT,
-    };
-
-    ParamField field;
-    Type type;
-};
-
-/**
- * This structure is used to hold the result from
- * IConfigurable::queryFieldSupportedValues().
- */
-struct FieldSupportedValuesQueryResult {
-    Status status;
-    FieldSupportedValues values;
-};
-
diff --git a/media/libstagefright/codec2/include/C2.h b/media/libstagefright/codec2/include/C2.h
deleted file mode 100644
index e90fe42..0000000
--- a/media/libstagefright/codec2/include/C2.h
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef C2_H_
-#define C2_H_
-
-#include <errno.h>
-
-#include <string>
-
-/** nanoseconds with arbitrary origin. */
-typedef int64_t c2_nsecs_t;
-
-/** \mainpage Codec2
- *
- * Codec2 is a generic frame-based data processing API.
- *
- * The media subsystem accesses components via the \ref API.
- */
-
-/** \ingroup API
- *
- * The Codec2 API defines the operation of data processing components and their interaction with
- * the rest of the system.
- *
- * Coding Conventions
- *
- * Mitigating Binary Compatibility.
- *
- * While full binary compatibility is not a goal of the API (due to our use of STL), we try to
- * mitigate binary breaks by adhering to the following conventions:
- *
- * - at most one vtable with placeholder virtual methods
- * - all optional/placeholder virtual methods returning a c2_status_t, with C2_OMITTED not requiring
- *   any update to input/output arguments.
- * - limiting symbol export of inline methods
- * - use of pimpl (or shared-pimpl)
- *
- * Naming
- *
- * - all classes and types prefix with C2
- * - classes for internal use prefix with _C2
- * - enum values in global namespace prefix with C2_ all caps
- * - enum values inside classes have no C2_ prefix as class already has it
- * - supporting two kinds of enum naming: all-caps and kCamelCase
- * \todo revisit kCamelCase for param-type
- *
- * Aspects
- *
- * Aspects define certain common behavior across a group of objects.
- * - classes whose name matches _C2.*Aspect
- * - only protected constructors
- * - no desctructor and copiable
- * - all methods are inline or static (this is opposite of the interface paradigm where all methods
- *   are virtual, which would not work due to the at most one vtable rule.)
- * - only private variables (this prevents subclasses interfering with the aspects.)
- */
-
-/// \defgroup types Common Types
-/// @{
-
-/**
- * C2String: basic string implementation
- */
-typedef std::string C2String;
-
-/**
- * C2StringLiteral: basic string literal implementation.
- * \note these are never owned by any object, and can only refer to C string literals.
- */
-typedef const char *C2StringLiteral;
-
-/**
- * c2_status_t: status codes used.
- */
-enum c2_status_t : int32_t {
-/*
- * Use POSIX errno constants.
- */
-    C2_OK        = 0,            ///< operation completed successfully
-
-    // bad input
-    C2_BAD_VALUE = EINVAL,       ///< argument has invalid value (user error)
-    C2_BAD_INDEX = ENXIO,        ///< argument uses invalid index (user error)
-    C2_CANNOT_DO = ENOTSUP,      ///< argument/index is valid but not possible
-
-    // bad sequencing of events
-    C2_DUPLICATE = EEXIST,       ///< object already exists
-    C2_NOT_FOUND = ENOENT,       ///< object not found
-    C2_BAD_STATE = EPERM,        ///< operation is not permitted in the current state
-    C2_BLOCKING  = EWOULDBLOCK,  ///< operation would block but blocking is not permitted
-    C2_CANCELED  = EINTR,        ///< operation interrupted/canceled
-
-    // bad environment
-    C2_NO_MEMORY = ENOMEM,       ///< not enough memory to complete operation
-    C2_REFUSED   = EACCES,       ///< missing permission to complete operation
-
-    C2_TIMED_OUT = ETIMEDOUT,    ///< operation did not complete within timeout
-
-    // bad versioning
-    C2_OMITTED   = ENOSYS,       ///< operation is not implemented/supported (optional only)
-
-    // unknown fatal
-    C2_CORRUPTED = EFAULT,       ///< some unexpected error prevented the operation
-    C2_NO_INIT   = ENODEV,       ///< status has not been initialized
-};
-
-/**
- * Type that describes the desired blocking behavior for variable blocking calls. Blocking in this
- * API is used in a somewhat modified meaning such that operations that merely update variables
- * protected by mutexes are still considered "non-blocking" (always used in quotes).
- */
-enum c2_blocking_t : int32_t {
-    /**
-     * The operation SHALL be "non-blocking". This means that it shall not perform any file
-     * operations, or call/wait on other processes. It may use a protected region as long as the
-     * mutex is never used to protect code that is otherwise "may block".
-     */
-    C2_DONT_BLOCK = false,
-    /**
-     * The operation MAY be temporarily blocking.
-     */
-    C2_MAY_BLOCK = true,
-};
-
-/// @}
-
-/// \defgroup utils Utilities
-/// @{
-
-#define C2_DO_NOT_COPY(type) \
-    type& operator=(const type &) = delete; \
-    type(const type &) = delete; \
-
-#define C2_DEFAULT_MOVE(type) \
-    type& operator=(type &&) = default; \
-    type(type &&) = default; \
-
-#define C2_ALLOW_OVERFLOW __attribute__((no_sanitize("integer")))
-#define C2_CONST    __attribute__((const))
-#define C2_HIDE     __attribute__((visibility("hidden")))
-#define C2_INTERNAL __attribute__((internal_linkage))
-#define C2_PACK     __attribute__((packed))
-#define C2_PURE     __attribute__((pure))
-
-#define DEFINE_OTHER_COMPARISON_OPERATORS(type) \
-    inline bool operator!=(const type &other) const { return !(*this == other); } \
-    inline bool operator<=(const type &other) const { return (*this == other) || (*this < other); } \
-    inline bool operator>=(const type &other) const { return !(*this < other); } \
-    inline bool operator>(const type &other) const { return !(*this < other) && !(*this == other); }
-
-#define DEFINE_FIELD_BASED_COMPARISON_OPERATORS(type, field) \
-    inline bool operator<(const type &other) const { return field < other.field; } \
-    inline bool operator==(const type &other) const { return field == other.field; } \
-    DEFINE_OTHER_COMPARISON_OPERATORS(type)
-
-#define DEFINE_FIELD_AND_MASK_BASED_COMPARISON_OPERATORS(type, field, mask) \
-    inline bool operator<(const type &other) const { \
-        return (field & mask) < (other.field & (mask)); \
-    } \
-    inline bool operator==(const type &other) const { \
-        return (field & mask) == (other.field & (mask)); \
-    } \
-    DEFINE_OTHER_COMPARISON_OPERATORS(type)
-
-template<typename T, typename B>
-class C2_HIDE c2_cntr_t;
-
-/// \cond INTERNAL
-
-/// \defgroup utils_internal
-/// @{
-
-template<typename T>
-struct C2_HIDE _c2_cntr_compat_helper {
-    template<typename U, typename E=typename std::enable_if<std::is_integral<U>::value>::type>
-    C2_ALLOW_OVERFLOW
-    inline static constexpr T get(const U &value) {
-        return T(value);
-    }
-
-    template<typename U, typename E=typename std::enable_if<(sizeof(U) >= sizeof(T))>::type>
-    C2_ALLOW_OVERFLOW
-    inline static constexpr T get(const c2_cntr_t<U, void> &value) {
-        return T(value.mValue);
-    }
-};
-
-/// @}
-
-/// \endcond
-
-/**
- * Integral counter type.
- *
- * This is basically an unsigned integral type that is NEVER checked for overflow/underflow - and
- * comparison operators are redefined.
- *
- * \note Comparison of counter types is not fully transitive, e.g.
- * it could be that a > b > c but a !> c.
- * std::less<>, greater<>, less_equal<> and greater_equal<> specializations yield total ordering,
- * but may not match semantic ordering of the values.
- *
- * Technically: counter types represent integer values: A * 2^N + value, where A can be arbitrary.
- * This makes addition, subtraction, multiplication (as well as bitwise operations) well defined.
- * However, division is in general not well defined, as the result may depend on A. This is also
- * true for logical operators and boolean conversion.
- *
- * Even though well defined, bitwise operators are not implemented for counter types as they are not
- * meaningful.
- */
-template<typename T, typename B=typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value>::type>
-class C2_HIDE c2_cntr_t {
-    using compat = _c2_cntr_compat_helper<T>;
-
-    T mValue;
-    constexpr static T HALF_RANGE = T(~0) ^ (T(~0) >> 1);
-
-    template<typename U>
-    friend struct _c2_cntr_compat_helper;
-public:
-
-    /**
-     * Default constructor. Initialized counter to 0.
-     */
-    inline constexpr c2_cntr_t() : mValue(T(0)) {}
-
-    /**
-     * Construct from a compatible type.
-     */
-    template<typename U>
-    inline constexpr c2_cntr_t(const U &value) : mValue(compat::get(value)) {}
-
-    /**
-     * Peek as underlying signed type.
-     */
-    C2_ALLOW_OVERFLOW
-    inline constexpr typename std::make_signed<T>::type peek() const {
-        return static_cast<typename std::make_signed<T>::type>(mValue);
-    }
-
-    /**
-     * Peek as underlying unsigned type.
-     */
-    inline constexpr T peeku() const {
-        return mValue;
-    }
-
-    /**
-     * Peek as long long - e.g. for printing.
-     */
-    C2_ALLOW_OVERFLOW
-    inline constexpr long long peekll() const {
-        return (long long)mValue;
-    }
-
-    /**
-     * Peek as unsigned long long - e.g. for printing.
-     */
-    C2_ALLOW_OVERFLOW
-    inline constexpr unsigned long long peekull() const {
-        return (unsigned long long)mValue;
-    }
-
-    /**
-     * Convert to a smaller counter type. This is always safe.
-     */
-    template<typename U, typename E=typename std::enable_if<(sizeof(U) < sizeof(T))>::type>
-    inline operator c2_cntr_t<U>() {
-        return c2_cntr_t<U>(mValue);
-    }
-
-    /**
-     * Arithmetic operators
-     */
-
-#define DEFINE_C2_CNTR_BINARY_OP(attrib, op, op_assign) \
-    template<typename U> \
-    attrib inline c2_cntr_t<T>& operator op_assign(const U &value) { \
-        mValue op_assign compat::get(value); \
-        return *this; \
-    } \
-    \
-    template<typename U, typename E=decltype(compat::get(U(0)))> \
-    attrib inline constexpr c2_cntr_t<T> operator op(const U &value) const { \
-        return c2_cntr_t<T>(mValue op compat::get(value)); \
-    } \
-    \
-    template<typename U, typename E=typename std::enable_if<(sizeof(U) < sizeof(T))>::type> \
-    attrib inline constexpr c2_cntr_t<U> operator op(const c2_cntr_t<U> &value) const { \
-        return c2_cntr_t<U>(U(mValue) op value.peeku()); \
-    }
-
-#define DEFINE_C2_CNTR_UNARY_OP(attrib, op) \
-    attrib inline constexpr c2_cntr_t<T> operator op() const { \
-        return c2_cntr_t<T>(op mValue); \
-    }
-
-#define DEFINE_C2_CNTR_CREMENT_OP(attrib, op) \
-    attrib inline c2_cntr_t<T> &operator op() { \
-        op mValue; \
-        return *this; \
-    } \
-    attrib inline c2_cntr_t<T> operator op(int) { \
-        return c2_cntr_t<T, void>(mValue op); \
-    }
-
-    DEFINE_C2_CNTR_BINARY_OP(C2_ALLOW_OVERFLOW, +, +=)
-    DEFINE_C2_CNTR_BINARY_OP(C2_ALLOW_OVERFLOW, -, -=)
-    DEFINE_C2_CNTR_BINARY_OP(C2_ALLOW_OVERFLOW, *, *=)
-
-    DEFINE_C2_CNTR_UNARY_OP(C2_ALLOW_OVERFLOW, -)
-    DEFINE_C2_CNTR_UNARY_OP(C2_ALLOW_OVERFLOW, +)
-
-    DEFINE_C2_CNTR_CREMENT_OP(C2_ALLOW_OVERFLOW, ++)
-    DEFINE_C2_CNTR_CREMENT_OP(C2_ALLOW_OVERFLOW, --)
-
-    template<typename U, typename E=typename std::enable_if<std::is_unsigned<U>::value>::type>
-    C2_ALLOW_OVERFLOW
-    inline constexpr c2_cntr_t<T> operator<<(const U &value) const {
-        return c2_cntr_t<T>(mValue << value);
-    }
-
-    template<typename U, typename E=typename std::enable_if<std::is_unsigned<U>::value>::type>
-    C2_ALLOW_OVERFLOW
-    inline c2_cntr_t<T> &operator<<=(const U &value) {
-        mValue <<= value;
-        return *this;
-    }
-
-    /**
-     * Comparison operators
-     */
-    C2_ALLOW_OVERFLOW
-    inline constexpr bool operator<=(const c2_cntr_t<T> &other) const {
-        return T(other.mValue - mValue) < HALF_RANGE;
-    }
-
-    C2_ALLOW_OVERFLOW
-    inline constexpr bool operator>=(const c2_cntr_t<T> &other) const {
-        return T(mValue - other.mValue) < HALF_RANGE;
-    }
-
-    inline constexpr bool operator==(const c2_cntr_t<T> &other) const {
-        return mValue == other.mValue;
-    }
-
-    inline constexpr bool operator!=(const c2_cntr_t<T> &other) const {
-        return !(*this == other);
-    }
-
-    inline constexpr bool operator<(const c2_cntr_t<T> &other) const {
-        return *this <= other && *this != other;
-    }
-
-    inline constexpr bool operator>(const c2_cntr_t<T> &other) const {
-        return *this >= other && *this != other;
-    }
-};
-
-template<typename U, typename T, typename E=typename std::enable_if<std::is_integral<U>::value>::type>
-inline constexpr c2_cntr_t<T> operator+(const U &a, const c2_cntr_t<T> &b) {
-    return b + a;
-}
-
-template<typename U, typename T, typename E=typename std::enable_if<std::is_integral<U>::value>::type>
-inline constexpr c2_cntr_t<T> operator-(const U &a, const c2_cntr_t<T> &b) {
-    return c2_cntr_t<T>(a) - b;
-}
-
-template<typename U, typename T, typename E=typename std::enable_if<std::is_integral<U>::value>::type>
-inline constexpr c2_cntr_t<T> operator*(const U &a, const c2_cntr_t<T> &b) {
-    return b * a;
-}
-
-typedef c2_cntr_t<uint32_t> c2_cntr32_t; /** 32-bit counter type */
-typedef c2_cntr_t<uint64_t> c2_cntr64_t; /** 64-bit counter type */
-
-/// \cond INTERNAL
-
-/// \defgroup utils_internal
-/// @{
-
-template<typename... T> struct c2_types;
-
-/** specialization for a single type */
-template<typename T>
-struct c2_types<T> {
-    typedef typename std::decay<T>::type wide_type;
-    typedef wide_type narrow_type;
-    typedef wide_type min_type; // type for min(T...)
-};
-
-/** specialization for two types */
-template<typename T, typename U>
-struct c2_types<T, U> {
-    static_assert(std::is_floating_point<T>::value == std::is_floating_point<U>::value,
-                  "mixing floating point and non-floating point types is disallowed");
-    static_assert(std::is_signed<T>::value == std::is_signed<U>::value,
-                  "mixing signed and unsigned types is disallowed");
-
-    typedef typename std::decay<
-            decltype(true ? std::declval<T>() : std::declval<U>())>::type wide_type;
-    typedef typename std::decay<
-            typename std::conditional<sizeof(T) < sizeof(U), T, U>::type>::type narrow_type;
-    typedef typename std::conditional<
-            std::is_signed<T>::value, wide_type, narrow_type>::type min_type;
-};
-
-/// @}
-
-/// \endcond
-
-/**
- * Type support utility class. Only supports similar classes, such as:
- * - all floating point
- * - all unsigned/all signed
- * - all pointer
- */
-template<typename T, typename U, typename... V>
-struct c2_types<T, U, V...> {
-    /** Common type that accommodates all template parameter types. */
-    typedef typename c2_types<typename c2_types<T, U>::wide_type, V...>::wide_type wide_type;
-    /** Narrowest type of the template parameter types. */
-    typedef typename c2_types<typename c2_types<T, U>::narrow_type, V...>::narrow_type narrow_type;
-    /** Type that accommodates the minimum value for any input for the template parameter types. */
-    typedef typename c2_types<typename c2_types<T, U>::min_type, V...>::min_type min_type;
-};
-
-/**
- *  \ingroup utils_internal
- * specialization for two values */
-template<typename T, typename U>
-inline constexpr typename c2_types<T, U>::wide_type c2_max(const T a, const U b) {
-    typedef typename c2_types<T, U>::wide_type wide_type;
-    return ({ wide_type a_(a), b_(b); a_ > b_ ? a_ : b_; });
-}
-
-/**
- * Finds the maximum value of a list of "similarly typed" values.
- *
- * This is an extension to std::max where the types do not have to be identical, and the smallest
- * resulting type is used that accommodates the argument types.
- *
- * \note Value types must be similar, e.g. all floating point, all pointers, all signed, or all
- * unsigned.
- *
- * @return the largest of the input arguments.
- */
-template<typename T, typename U, typename... V>
-constexpr typename c2_types<T, U, V...>::wide_type c2_max(const T a, const U b, const V ... c) {
-    typedef typename c2_types<T, U, V...>::wide_type wide_type;
-    return ({ wide_type a_(a), b_(c2_max(b, c...)); a_ > b_ ? a_ : b_; });
-}
-
-/**
- *  \ingroup utils_internal
- * specialization for two values */
-template<typename T, typename U>
-inline constexpr typename c2_types<T, U>::min_type c2_min(const T a, const U b) {
-    typedef typename c2_types<T, U>::wide_type wide_type;
-    return ({
-        wide_type a_(a), b_(b);
-        static_cast<typename c2_types<T, U>::min_type>(a_ < b_ ? a_ : b_);
-    });
-}
-
-/**
- * Finds the minimum value of a list of "similarly typed" values.
- *
- * This is an extension to std::min where the types do not have to be identical, and the smallest
- * resulting type is used that accommodates the argument types.
- *
- * \note Value types must be similar, e.g. all floating point, all pointers, all signed, or all
- * unsigned.
- *
- * @return the smallest of the input arguments.
- */
-template<typename T, typename U, typename... V>
-constexpr typename c2_types<T, U, V...>::min_type c2_min(const T a, const U b, const V ... c) {
-    typedef typename c2_types<U, V...>::min_type rest_type;
-    typedef typename c2_types<T, rest_type>::wide_type wide_type;
-    return ({
-        wide_type a_(a), b_(c2_min(b, c...));
-        static_cast<typename c2_types<T, rest_type>::min_type>(a_ < b_ ? a_ : b_);
-    });
-}
-
-/**
- *  \ingroup utils_internal
- */
-template<typename T, typename U, typename V>
-inline constexpr typename c2_types<T, V>::wide_type c2_clamp(const T a, const U b, const V c) {
-    typedef typename c2_types<T, U, V>::wide_type wide_type;
-    return ({
-        wide_type a_(a), b_(b), c_(c);
-        static_cast<typename c2_types<T, V>::wide_type>(b_ < a_ ? a_ : b_ > c_ ? c_ : b_);
-    });
-}
-
-/// @}
-
-#include <functional>
-template<typename T>
-struct std::less<::c2_cntr_t<T>> {
-    constexpr bool operator()(const ::c2_cntr_t<T> &lh, const ::c2_cntr_t<T> &rh) const {
-        return lh.peeku() < rh.peeku();
-    }
-};
-template<typename T>
-struct std::less_equal<::c2_cntr_t<T>> {
-    constexpr bool operator()(const ::c2_cntr_t<T> &lh, const ::c2_cntr_t<T> &rh) const {
-        return lh.peeku() <= rh.peeku();
-    }
-};
-template<typename T>
-struct std::greater<::c2_cntr_t<T>> {
-    constexpr bool operator()(const ::c2_cntr_t<T> &lh, const ::c2_cntr_t<T> &rh) const {
-        return lh.peeku() > rh.peeku();
-    }
-};
-template<typename T>
-struct std::greater_equal<::c2_cntr_t<T>> {
-    constexpr bool operator()(const ::c2_cntr_t<T> &lh, const ::c2_cntr_t<T> &rh) const {
-        return lh.peeku() >= rh.peeku();
-    }
-};
-
-#endif  // C2_H_
diff --git a/media/libstagefright/codec2/include/C2Buffer.h b/media/libstagefright/codec2/include/C2Buffer.h
deleted file mode 100644
index 0e35f11..0000000
--- a/media/libstagefright/codec2/include/C2Buffer.h
+++ /dev/null
@@ -1,2283 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef C2BUFFER_H_
-#define C2BUFFER_H_
-
-#include <C2.h>
-#include <C2BufferBase.h>
-#include <C2Param.h> // for C2Info
-
-#include <memory>
-#include <vector>
-
-#ifdef __ANDROID__
-#include <android-C2Buffer.h>
-#else
-
-typedef void* C2Handle;
-
-#endif
-
-/// \defgroup buffer Buffers
-/// @{
-
-/// \defgroup buffer_sync Synchronization
-/// @{
-
-/**
- * Synchronization is accomplished using event and fence objects.
- *
- * These are cross-process extensions of promise/future infrastructure.
- * Events are analogous to std::promise<void>, whereas fences are to std::shared_future<void>.
- *
- * Fences and events are shareable/copyable.
- *
- * Fences are used in two scenarios, and all copied instances refer to the same event.
- * \todo do events need to be copyable or should they be unique?
- *
- * acquire sync fence object: signaled when it is safe for the component or client to access
- * (the contents of) an object.
- *
- * release sync fence object: \todo
- *
- * Fences can be backed by hardware. Hardware fences are guaranteed to signal NO MATTER WHAT within
- * a short (platform specific) amount of time; this guarantee is usually less than 15 msecs.
- */
-
-/**
- * Fence object used by components and the framework.
- *
- * Implements the waiting for an event, analogous to a 'future'.
- *
- * To be implemented by vendors if using HW fences.
- */
-class C2Fence {
-public:
-    /**
-     * Waits for a fence to be signaled with a timeout.
-     *
-     * \todo a mechanism to cancel a wait - for now the only way to do this is to abandon the
-     * event, but fences are shared so canceling a wait will cancel all waits.
-     *
-     * \param timeoutNs           the maximum time to wait in nsecs
-     *
-     * \retval C2_OK            the fence has been signaled
-     * \retval C2_TIMED_OUT     the fence has not been signaled within the timeout
-     * \retval C2_BAD_STATE     the fence has been abandoned without being signaled (it will never
-     *                          be signaled)
-     * \retval C2_REFUSED       no permission to wait for the fence (unexpected - system)
-     * \retval C2_CORRUPTED     some unknown error prevented waiting for the fence (unexpected)
-     */
-    c2_status_t wait(c2_nsecs_t timeoutNs);
-
-    /**
-     * Used to check if this fence is valid (if there is a chance for it to be signaled.)
-     * A fence becomes invalid if the controling event is destroyed without it signaling the fence.
-     *
-     * \return whether this fence is valid
-     */
-    bool valid() const;
-
-    /**
-     * Used to check if this fence has been signaled (is ready).
-     *
-     * \return whether this fence has been signaled
-     */
-    bool ready() const;
-
-    /**
-     * Returns a file descriptor that can be used to wait for this fence in a select system call.
-     * \note The returned file descriptor, if valid, must be closed by the caller.
-     *
-     * This can be used in e.g. poll() system calls. This file becomes readable (POLLIN) when the
-     * fence is signaled, and bad (POLLERR) if the fence is abandoned.
-     *
-     * \return a file descriptor representing this fence (with ownership), or -1 if the fence
-     * has already been signaled (\todo or abandoned).
-     *
-     * \todo this must be compatible with fences used by gralloc
-     */
-    int fd() const;
-
-    /**
-     * Returns whether this fence is a hardware-backed fence.
-     * \return whether this is a hardware fence
-     */
-    bool isHW() const;
-
-    /**
-     * Null-fence. A fence that has fired.
-     */
-    constexpr C2Fence() : mImpl(nullptr) { }
-
-private:
-    class Impl;
-    std::shared_ptr<Impl> mImpl;
-    C2Fence(std::shared_ptr<Impl> impl);
-    friend struct _C2FenceFactory;
-};
-
-/**
- * Event object used by components and the framework.
- *
- * Implements the signaling of an event, analogous to a 'promise'.
- *
- * Hardware backed events do not go through this object, and must be exposed directly as fences
- * by vendors.
- */
-class C2Event {
-public:
-    /**
-     * Returns a fence for this event.
-     */
-    C2Fence fence() const;
-
-    /**
-     * Signals (all) associated fence(s).
-     * This has no effect no effect if the event was already signaled or abandoned.
-     *
-     * \retval C2_OK            the fence(s) were successfully signaled
-     * \retval C2_BAD_STATE     the fence(s) have already been abandoned or merged (caller error)
-     * \retval C2_DUPLICATE     the fence(s) have already been signaled (caller error)
-     * \retval C2_REFUSED       no permission to signal the fence (unexpected - system)
-     * \retval C2_CORRUPTED     some unknown error prevented signaling the fence(s) (unexpected)
-     */
-    c2_status_t fire();
-
-    /**
-     * Trigger this event from the merging of the supplied fences. This means that it will be
-     * abandoned if any of these fences have been abandoned, and it will be fired if all of these
-     * fences have been signaled.
-     *
-     * \retval C2_OK            the merging was successfully done
-     * \retval C2_NO_MEMORY     not enough memory to perform the merging
-     * \retval C2_DUPLICATE     the fence have already been merged (caller error)
-     * \retval C2_BAD_STATE     the fence have already been signaled or abandoned (caller error)
-     * \retval C2_REFUSED       no permission to merge the fence (unexpected - system)
-     * \retval C2_CORRUPTED     some unknown error prevented merging the fence(s) (unexpected)
-     */
-    c2_status_t merge(std::vector<C2Fence> fences);
-
-    /**
-     * Abandons the event and any associated fence(s).
-     * \note Call this to explicitly abandon an event before it is destructed to avoid a warning.
-     *
-     * This has no effect no effect if the event was already signaled or abandoned.
-     *
-     * \retval C2_OK            the fence(s) were successfully signaled
-     * \retval C2_BAD_STATE     the fence(s) have already been signaled or merged (caller error)
-     * \retval C2_DUPLICATE     the fence(s) have already been abandoned (caller error)
-     * \retval C2_REFUSED       no permission to abandon the fence (unexpected - system)
-     * \retval C2_CORRUPTED     some unknown error prevented signaling the fence(s) (unexpected)
-     */
-    c2_status_t abandon();
-
-private:
-    class Impl;
-    std::shared_ptr<Impl> mImpl;
-};
-
-/// \addtogroup buf_internal Internal
-/// @{
-
-/**
- * Interface for objects that encapsulate an updatable status value.
- */
-struct _C2InnateStatus {
-    inline c2_status_t status() const { return mStatus; }
-
-protected:
-    _C2InnateStatus(c2_status_t status) : mStatus(status) { }
-
-    c2_status_t mStatus; // this status is updatable by the object
-};
-
-/// @}
-
-/**
- * This is a utility template for objects protected by an acquire fence, so that errors during
- * acquiring the object are propagated to the object itself.
- */
-template<typename T>
-class C2Acquirable : public C2Fence {
-public:
-    /**
-     * Acquires the object protected by an acquire fence. Any errors during the mapping will be
-     * passed to the object.
-     *
-     * \return acquired object potentially invalidated if waiting for the fence failed.
-     */
-    T get() {
-        // TODO:
-        // wait();
-        return mT;
-    }
-
-protected:
-    C2Acquirable(c2_status_t error, C2Fence fence, T t) : C2Fence(fence), mInitialError(error), mT(t) { }
-
-private:
-    c2_status_t mInitialError;
-    T mT; // TODO: move instead of copy
-};
-
-/// @}
-
-/// \defgroup linear Linear Data Blocks
-/// @{
-
-/**************************************************************************************************
-  LINEAR ASPECTS, BLOCKS AND VIEWS
-**************************************************************************************************/
-
-/**
- * Basic segment math support.
- */
-struct C2Segment {
-    uint32_t offset;
-    uint32_t size;
-
-    inline constexpr C2Segment(uint32_t offset_, uint32_t size_)
-        : offset(offset_),
-          size(size_) {
-    }
-
-    inline constexpr bool isEmpty() const {
-        return size == 0;
-    }
-
-    inline constexpr bool isValid() const {
-        return offset <= ~size;
-    }
-
-    inline constexpr operator bool() const {
-        return isValid() && !isEmpty();
-    }
-
-    inline constexpr bool operator!() const {
-        return !bool(*this);
-    }
-
-    C2_ALLOW_OVERFLOW
-    inline constexpr bool contains(const C2Segment &other) const {
-        if (!isValid() || !other.isValid()) {
-            return false;
-        } else {
-            return offset <= other.offset
-                    && offset + size >= other.offset + other.size;
-        }
-    }
-
-    inline constexpr bool operator==(const C2Segment &other) const {
-        if (!isValid()) {
-            return !other.isValid();
-        } else {
-            return offset == other.offset && size == other.size;
-        }
-    }
-
-    inline constexpr bool operator!=(const C2Segment &other) const {
-        return !operator==(other);
-    }
-
-    inline constexpr bool operator>=(const C2Segment &other) const {
-        return contains(other);
-    }
-
-    inline constexpr bool operator>(const C2Segment &other) const {
-        return contains(other) && !operator==(other);
-    }
-
-    inline constexpr bool operator<=(const C2Segment &other) const {
-        return other.contains(*this);
-    }
-
-    inline constexpr bool operator<(const C2Segment &other) const {
-        return other.contains(*this) && !operator==(other);
-    }
-
-    C2_ALLOW_OVERFLOW
-    inline constexpr uint32_t end() const {
-        return offset + size;
-    }
-
-    C2_ALLOW_OVERFLOW
-    inline constexpr C2Segment intersect(const C2Segment &other) const {
-        return C2Segment(c2_max(offset, other.offset),
-                         c2_min(end(), other.end()) - c2_max(offset, other.offset));
-    }
-
-    /** clamps end to offset if it overflows */
-    inline constexpr C2Segment normalize() const {
-        return C2Segment(offset, c2_max(offset, end()) - offset);
-    }
-
-    /** clamps end to max if it overflows */
-    inline constexpr C2Segment saturate() const {
-        return C2Segment(offset, c2_min(size, ~offset));
-    }
-
-};
-
-/**
- * Common aspect for all objects that have a linear capacity.
- */
-class _C2LinearCapacityAspect {
-/// \name Linear capacity interface
-/// @{
-public:
-    inline constexpr uint32_t capacity() const { return mCapacity; }
-
-    inline constexpr operator C2Segment() const {
-        return C2Segment(0, mCapacity);
-    }
-
-protected:
-
-#if UINTPTR_MAX == 0xffffffff
-    static_assert(sizeof(size_t) == sizeof(uint32_t), "size_t is too big");
-#else
-    static_assert(sizeof(size_t) > sizeof(uint32_t), "size_t is too small");
-    // explicitly disable construction from size_t
-    inline explicit _C2LinearCapacityAspect(size_t capacity) = delete;
-#endif
-
-    inline explicit constexpr _C2LinearCapacityAspect(uint32_t capacity)
-      : mCapacity(capacity) { }
-
-    inline explicit constexpr _C2LinearCapacityAspect(const _C2LinearCapacityAspect *parent)
-        : mCapacity(parent == nullptr ? 0 : parent->capacity()) { }
-
-private:
-    uint32_t mCapacity;
-/// @}
-};
-
-/**
- * Aspect for objects that have a linear range inside a linear capacity.
- *
- * This class is copiable.
- */
-class _C2LinearRangeAspect : public _C2LinearCapacityAspect {
-/// \name Linear range interface
-/// @{
-public:
-    inline constexpr uint32_t offset() const { return mOffset; }
-    inline constexpr uint32_t endOffset() const { return mOffset + mSize; }
-    inline constexpr uint32_t size() const { return mSize; }
-
-    inline constexpr operator C2Segment() const {
-        return C2Segment(mOffset, mSize);
-    }
-
-private:
-    // subrange of capacity [0, capacity] & [size, size + offset]
-    inline constexpr _C2LinearRangeAspect(uint32_t capacity_, size_t offset, size_t size)
-        : _C2LinearCapacityAspect(capacity_),
-          mOffset(c2_min(offset, capacity())),
-          mSize(c2_min(size, capacity() - mOffset)) {
-    }
-
-protected:
-    // copy constructor (no error check)
-    inline constexpr _C2LinearRangeAspect(const _C2LinearRangeAspect &other)
-        : _C2LinearCapacityAspect(other.capacity()),
-          mOffset(other.offset()),
-          mSize(other.size()) {
-    }
-
-    // parent capacity range [0, capacity]
-    inline constexpr explicit _C2LinearRangeAspect(const _C2LinearCapacityAspect *parent)
-        : _C2LinearCapacityAspect(parent),
-          mOffset(0),
-          mSize(capacity()) {
-    }
-
-    // subrange of parent capacity [0, capacity] & [size, size + offset]
-    inline constexpr _C2LinearRangeAspect(const _C2LinearCapacityAspect *parent, size_t offset, size_t size)
-        : _C2LinearCapacityAspect(parent),
-          mOffset(c2_min(offset, capacity())),
-          mSize(c2_min(size, capacity() - mOffset)) {
-    }
-
-    // subsection of the parent's and [offset, offset + size] ranges
-    inline constexpr _C2LinearRangeAspect(const _C2LinearRangeAspect *parent, size_t offset, size_t size)
-        : _C2LinearCapacityAspect(parent),
-          mOffset(c2_min(c2_max(offset, parent == nullptr ? 0 : parent->offset()), capacity())),
-          mSize(std::min(c2_min(size, parent == nullptr ? 0 : parent->size()), capacity() - mOffset)) {
-    }
-
-public:
-    inline constexpr _C2LinearRangeAspect childRange(size_t offset, size_t size) const {
-        return _C2LinearRangeAspect(
-            mSize,
-            c2_min(c2_max(offset, mOffset), capacity()) - mOffset,
-            c2_min(c2_min(size, mSize), capacity() - c2_min(c2_max(offset, mOffset), capacity())));
-    }
-
-    friend class _C2EditableLinearRangeAspect;
-    // invariants 0 <= mOffset <= mOffset + mSize <= capacity()
-    uint32_t mOffset;
-    uint32_t mSize;
-/// @}
-};
-
-/**
- * Utility class for safe range calculations using size_t-s.
- */
-class C2LinearRange : public _C2LinearRangeAspect {
-public:
-    inline constexpr C2LinearRange(const _C2LinearCapacityAspect &parent, size_t offset, size_t size)
-        : _C2LinearRangeAspect(&parent, offset, size) { }
-
-    inline constexpr C2LinearRange(const _C2LinearRangeAspect &parent, size_t offset, size_t size)
-        : _C2LinearRangeAspect(&parent, offset, size) { }
-
-    inline constexpr C2LinearRange intersect(size_t offset, size_t size) const {
-        return C2LinearRange(*this, offset, size);
-    }
-};
-
-/**
- * Utility class for simple and safe capacity and range construction.
- */
-class C2LinearCapacity : public _C2LinearCapacityAspect {
-public:
-    inline constexpr explicit C2LinearCapacity(size_t capacity)
-        : _C2LinearCapacityAspect(c2_min(capacity, std::numeric_limits<uint32_t>::max())) { }
-
-    inline constexpr C2LinearRange range(size_t offset, size_t size) const {
-        return C2LinearRange(*this, offset, size);
-    }
-};
-
-/**
- * Aspect for objects that have an editable linear range.
- *
- * This class is copiable.
- */
-class _C2EditableLinearRangeAspect : public _C2LinearRangeAspect {
-    using _C2LinearRangeAspect::_C2LinearRangeAspect;
-
-public:
-/// \name Editable linear range interface
-/// @{
-
-    /**
-     * Sets the offset to |offset|, while trying to keep the end of the buffer unchanged (e.g.
-     * size will grow if offset is decreased, and may shrink if offset is increased.) Returns
-     * true if successful, which is equivalent to if 0 <= |offset| <= capacity().
-     *
-     * Note: setting offset and size will yield different result depending on the order of the
-     * operations. Always set offset first to ensure proper size.
-     */
-    inline bool setOffset(uint32_t offset) {
-        if (offset > capacity()) {
-            return false;
-        }
-
-        if (offset > mOffset + mSize) {
-            mSize = 0;
-        } else {
-            mSize = mOffset + mSize - offset;
-        }
-        mOffset = offset;
-        return true;
-    }
-
-    /**
-     * Sets the size to |size|. Returns true if successful, which is equivalent to
-     * if 0 <= |size| <= capacity() - offset().
-     *
-     * Note: setting offset and size will yield different result depending on the order of the
-     * operations. Always set offset first to ensure proper size.
-     */
-    inline bool setSize(uint32_t size) {
-        if (size > capacity() - mOffset) {
-            return false;
-        } else {
-            mSize = size;
-            return true;
-        }
-    }
-
-    /**
-     * Sets the offset to |offset| with best effort. Same as setOffset() except that offset will
-     * be clamped to the buffer capacity.
-     *
-     * Note: setting offset and size (even using best effort) will yield different result depending
-     * on the order of the operations. Always set offset first to ensure proper size.
-     */
-    inline void setOffset_be(uint32_t offset) {
-        (void)setOffset(c2_min(offset, capacity()));
-    }
-
-    /**
-     * Sets the size to |size| with best effort. Same as setSize() except that the selected region
-     * will be clamped to the buffer capacity (e.g. size is clamped to [0, capacity() - offset()]).
-     *
-     * Note: setting offset and size (even using best effort) will yield different result depending
-     * on the order of the operations. Always set offset first to ensure proper size.
-     */
-    inline void setSize_be(uint32_t size) {
-        mSize = c2_min(size, capacity() - mOffset);
-    }
-/// @}
-};
-
-/**************************************************************************************************
-  ALLOCATIONS
-**************************************************************************************************/
-
-/// \ingroup allocator Allocation and memory placement
-/// @{
-
-class C2LinearAllocation;
-class C2GraphicAllocation;
-
-/**
- *  Allocators are used by the framework to allocate memory (allocations) for buffers. They can
- *  support either 1D or 2D allocations.
- *
- *  \note In theory they could support both, but in practice, we will use only one or the other.
- *
- *  Never constructed on stack.
- *
- *  Allocators are provided by vendors.
- */
-class C2Allocator {
-public:
-    /**
-     * Allocator ID type.
-     */
-    typedef uint32_t id_t;
-    enum : id_t {
-        BAD_ID = 0xBADD, // invalid allocator ID
-    };
-
-    /**
-     * Allocation types. This is a bitmask and is used in C2Allocator::Info
-     * to list the supported allocation types of an allocator.
-     */
-    enum type_t : uint32_t {
-        LINEAR  = 1 << 0, //
-        GRAPHIC = 1 << 1,
-    };
-
-    /**
-     * Information about an allocator.
-     *
-     * Allocators don't have a query API so all queriable information is stored here.
-     */
-    struct Traits {
-        C2String name;              ///< allocator name
-        id_t id;                    ///< allocator ID
-        type_t supportedTypes;      ///< supported allocation types
-        C2MemoryUsage minimumUsage; ///< usage that is minimally required for allocations
-        C2MemoryUsage maximumUsage; ///< usage that is maximally allowed for allocations
-    };
-
-    /**
-     * Returns the unique name of this allocator.
-     *
-     * This method MUST be "non-blocking" and return within 1ms.
-     *
-     * \return the name of this allocator.
-     * \retval an empty string if there was not enough memory to allocate the actual name.
-     */
-    virtual C2String getName() const = 0;
-
-    /**
-     * Returns a unique ID for this allocator. This ID is used to get this allocator from the
-     * allocator store, and to identify this allocator across all processes.
-     *
-     * This method MUST be "non-blocking" and return within 1ms.
-     *
-     * \return a unique ID for this allocator.
-     */
-    virtual id_t getId() const = 0;
-
-    /**
-     * Returns the allocator traits.
-     *
-     * This method MUST be "non-blocking" and return within 1ms.
-     *
-     * Allocators don't have a full-fledged query API, only this method.
-     *
-     * \return allocator information
-     */
-    virtual std::shared_ptr<const Traits> getTraits() const = 0;
-
-    /**
-     * Allocates a 1D allocation of given |capacity| and |usage|. If successful, the allocation is
-     * stored in |allocation|. Otherwise, |allocation| is set to 'nullptr'.
-     *
-     * \param capacity      the size of requested allocation (the allocation could be slightly
-     *                      larger, e.g. to account for any system-required alignment)
-     * \param usage         the memory usage info for the requested allocation. \note that the
-     *                      returned allocation may be later used/mapped with different usage.
-     *                      The allocator should layout the buffer to be optimized for this usage,
-     *                      but must support any usage. One exception: protected buffers can
-     *                      only be used in a protected scenario.
-     * \param allocation    pointer to where the allocation shall be stored on success. nullptr
-     *                      will be stored here on failure
-     *
-     * \retval C2_OK        the allocation was successful
-     * \retval C2_NO_MEMORY not enough memory to complete the allocation
-     * \retval C2_TIMED_OUT the allocation timed out
-     * \retval C2_REFUSED   no permission to complete the allocation
-     * \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error)
-     * \retval C2_OMITTED   this allocator does not support 1D allocations
-     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected)
-     */
-    virtual c2_status_t newLinearAllocation(
-            uint32_t capacity __unused, C2MemoryUsage usage __unused,
-            std::shared_ptr<C2LinearAllocation> *allocation /* nonnull */) {
-        *allocation = nullptr;
-        return C2_OMITTED;
-    }
-
-    /**
-     * (Re)creates a 1D allocation from a native |handle|. If successful, the allocation is stored
-     * in |allocation|. Otherwise, |allocation| is set to 'nullptr'.
-     *
-     * \param handle      the handle for the existing allocation. On success, the allocation will
-     *                    take ownership of |handle|.
-     * \param allocation  pointer to where the allocation shall be stored on success. nullptr
-     *                    will be stored here on failure
-     *
-     * \retval C2_OK        the allocation was recreated successfully
-     * \retval C2_NO_MEMORY not enough memory to recreate the allocation
-     * \retval C2_TIMED_OUT the recreation timed out (unexpected)
-     * \retval C2_REFUSED   no permission to recreate the allocation
-     * \retval C2_BAD_VALUE invalid handle (caller error)
-     * \retval C2_OMITTED   this allocator does not support 1D allocations
-     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected)
-     */
-    virtual c2_status_t priorLinearAllocation(
-            const C2Handle *handle __unused,
-            std::shared_ptr<C2LinearAllocation> *allocation /* nonnull */) {
-        *allocation = nullptr;
-        return C2_OMITTED;
-    }
-
-    /**
-     * Allocates a 2D allocation of given |width|, |height|, |format| and |usage|. If successful,
-     * the allocation is stored in |allocation|. Otherwise, |allocation| is set to 'nullptr'.
-     *
-     * \param width         the width of requested allocation (the allocation could be slightly
-     *                      larger, e.g. to account for any system-required alignment)
-     * \param height        the height of requested allocation (the allocation could be slightly
-     *                      larger, e.g. to account for any system-required alignment)
-     * \param format        the pixel format of requested allocation. This could be a vendor
-     *                      specific format.
-     * \param usage         the memory usage info for the requested allocation. \note that the
-     *                      returned allocation may be later used/mapped with different usage.
-     *                      The allocator should layout the buffer to be optimized for this usage,
-     *                      but must support any usage. One exception: protected buffers can
-     *                      only be used in a protected scenario.
-     * \param allocation    pointer to where the allocation shall be stored on success. nullptr
-     *                      will be stored here on failure
-     *
-     * \retval C2_OK        the allocation was successful
-     * \retval C2_NO_MEMORY not enough memory to complete the allocation
-     * \retval C2_TIMED_OUT the allocation timed out
-     * \retval C2_REFUSED   no permission to complete the allocation
-     * \retval C2_BAD_VALUE width, height, format or usage are not supported (invalid) (caller error)
-     * \retval C2_OMITTED   this allocator does not support 2D allocations
-     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected)
-     */
-    virtual c2_status_t newGraphicAllocation(
-            uint32_t width __unused, uint32_t height __unused, uint32_t format __unused,
-            C2MemoryUsage usage __unused,
-            std::shared_ptr<C2GraphicAllocation> *allocation /* nonnull */) {
-        *allocation = nullptr;
-        return C2_OMITTED;
-    }
-
-    /**
-     * (Re)creates a 2D allocation from a native handle.  If successful, the allocation is stored
-     * in |allocation|. Otherwise, |allocation| is set to 'nullptr'.
-     *
-     * \param handle      the handle for the existing allocation. On success, the allocation will
-     *                    take ownership of |handle|.
-     * \param allocation  pointer to where the allocation shall be stored on success. nullptr
-     *                    will be stored here on failure
-     *
-     * \retval C2_OK        the allocation was recreated successfully
-     * \retval C2_NO_MEMORY not enough memory to recreate the allocation
-     * \retval C2_TIMED_OUT the recreation timed out (unexpected)
-     * \retval C2_REFUSED   no permission to recreate the allocation
-     * \retval C2_BAD_VALUE invalid handle (caller error)
-     * \retval C2_OMITTED   this allocator does not support 2D allocations
-     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during recreation (unexpected)
-     */
-    virtual c2_status_t priorGraphicAllocation(
-            const C2Handle *handle __unused,
-            std::shared_ptr<C2GraphicAllocation> *allocation /* nonnull */) {
-        *allocation = nullptr;
-        return C2_OMITTED;
-    }
-
-protected:
-    C2Allocator() = default;
-
-    virtual ~C2Allocator() = default;
-};
-
-/**
- * \ingroup linear allocator
- * 1D allocation interface.
- */
-class C2LinearAllocation : public _C2LinearCapacityAspect {
-public:
-    /**
-     * Maps a portion of an allocation starting from |offset| with |size| into local process memory.
-     * Stores the starting address into |addr|, or NULL if the operation was unsuccessful.
-     * |fence| will contain an acquire sync fence object. If it is already
-     * safe to access the buffer contents, then it will contain an empty (already fired) fence.
-     *
-     * \param offset        starting position of the portion to be mapped (this does not have to
-     *                      be page aligned)
-     * \param size          size of the portion to be mapped (this does not have to be page
-     *                      aligned)
-     * \param usage         the desired usage. \todo this must be kSoftwareRead and/or
-     *                      kSoftwareWrite.
-     * \param fence         a pointer to a fence object if an async mapping is requested. If
-     *                      not-null, and acquire fence will be stored here on success, or empty
-     *                      fence on failure. If null, the mapping will be synchronous.
-     * \param addr          a pointer to where the starting address of the mapped portion will be
-     *                      stored. On failure, nullptr will be stored here.
-     *
-     * \todo Only one portion can be mapped at the same time - this is true for gralloc, but there
-     *       is no need for this for 1D buffers.
-     * \todo Do we need to support sync operation as we could just wait for the fence?
-     *
-     * \retval C2_OK        the operation was successful
-     * \retval C2_REFUSED   no permission to map the portion
-     * \retval C2_TIMED_OUT the operation timed out
-     * \retval C2_DUPLICATE if the allocation is already mapped.
-     * \retval C2_NO_MEMORY not enough memory to complete the operation
-     * \retval C2_BAD_VALUE the parameters (offset/size) are invalid or outside the allocation, or
-     *                      the usage flags are invalid (caller error)
-     * \retval C2_CORRUPTED some unknown error prevented the operation from completing (unexpected)
-     */
-    virtual c2_status_t map(
-            size_t offset, size_t size, C2MemoryUsage usage, C2Fence *fence /* nullable */,
-            void **addr /* nonnull */) = 0;
-
-    /**
-     * Unmaps a portion of an allocation at |addr| with |size|. These must be parameters previously
-     * passed to and returned by |map|; otherwise, this operation is a no-op.
-     *
-     * \param addr          starting address of the mapped region
-     * \param size          size of the mapped region
-     * \param fence         a pointer to a fence object if an async unmapping is requested. If
-     *                      not-null, a release fence will be stored here on success, or empty fence
-     *                      on failure. This fence signals when the original allocation contains
-     *                      all changes that happened to the mapped region. If null, the unmapping
-     *                      will be synchronous.
-     *
-     * \retval C2_OK        the operation was successful
-     * \retval C2_TIMED_OUT the operation timed out
-     * \retval C2_NOT_FOUND if the allocation was not mapped previously.
-     * \retval C2_BAD_VALUE the parameters (addr/size) do not correspond to previously mapped
-     *                      regions (caller error)
-     * \retval C2_CORRUPTED some unknown error prevented the operation from completing (unexpected)
-     * \retval C2_REFUSED   no permission to unmap the portion (unexpected - system)
-     */
-    virtual c2_status_t unmap(void *addr, size_t size, C2Fence *fence /* nullable */) = 0;
-
-    /**
-     * Returns the allocator ID for this allocation. This is useful to put the handle into context.
-     */
-    virtual C2Allocator::id_t getAllocatorId() const = 0;
-
-    /**
-     * Returns a pointer to the allocation handle.
-     */
-    virtual const C2Handle *handle() const = 0;
-
-    /**
-     * Returns true if this is the same allocation as |other|.
-     */
-    virtual bool equals(const std::shared_ptr<C2LinearAllocation> &other) const = 0;
-
-protected:
-    // \todo should we limit allocation directly?
-    C2LinearAllocation(size_t capacity) : _C2LinearCapacityAspect(c2_min(capacity, UINT32_MAX)) {}
-    virtual ~C2LinearAllocation() = default;
-};
-
-class C2CircularBlock;
-class C2LinearBlock;
-class C2GraphicBlock;
-
-/**
- *  Block pools are used by components to obtain output buffers in an efficient way. They can
- *  support either linear (1D), circular (1D) or graphic (2D) blocks.
- *
- *  Block pools decouple the recycling of memory/allocations from the components. They are meant to
- *  be an opaque service (there are no public APIs other than obtaining blocks) provided by the
- *  platform. Block pools are also meant to decouple allocations from memory used by buffers. This
- *  is accomplished by allowing pools to allot multiple memory 'blocks' on a single allocation. As
- *  their name suggest, block pools maintain a pool of memory blocks. When a component asks for
- *  a memory block, pools will try to return a free memory block already in the pool. If no such
- *  block exists, they will allocate memory using the backing allocator and allot a block on that
- *  allocation. When blocks are no longer used in the system, they are recycled back to the block
- *  pool and are available as free blocks.
- *
- *  Never constructed on stack.
- */
-class C2BlockPool {
-public:
-    /**
-     * Block pool ID type.
-     */
-    typedef uint64_t local_id_t;
-
-    enum : local_id_t {
-        BASIC_LINEAR = 0,  ///< ID of basic (unoptimized) block pool for fetching 1D blocks
-        BASIC_GRAPHIC = 1, ///< ID of basic (unoptimized) block pool for fetching 2D blocks
-        PLATFORM_START = 0x10,
-    };
-
-    /**
-     * Returns the ID for this block pool. This ID is used to get this block pool from the platform.
-     * It is only valid in the current process.
-     *
-     * This method MUST be "non-blocking" and return within 1ms.
-     *
-     * \return a local ID for this block pool.
-     */
-    virtual local_id_t getLocalId() const = 0;
-
-    /**
-     * Returns the ID of the backing allocator of this block pool.
-     *
-     * This method MUST be "non-blocking" and return within 1ms.
-     *
-     * \return the ID of the backing allocator of this block pool.
-     */
-    virtual C2Allocator::id_t getAllocatorId() const = 0;
-
-    /**
-     * Obtains a linear writeable block of given |capacity| and |usage|. If successful, the
-     * block is stored in |block|. Otherwise, |block| is set to 'nullptr'.
-     *
-     * \param capacity the size of requested block.
-     * \param usage    the memory usage info for the requested block. Returned blocks will be
-     *                 optimized for this usage, but may be used with any usage. One exception:
-     *                 protected blocks/buffers can only be used in a protected scenario.
-     * \param block    pointer to where the obtained block shall be stored on success. nullptr will
-     *                 be stored here on failure
-     *
-     * \retval C2_OK        the operation was successful
-     * \retval C2_NO_MEMORY not enough memory to complete any required allocation
-     * \retval C2_TIMED_OUT the operation timed out
-     * \retval C2_REFUSED   no permission to complete any required allocation
-     * \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error)
-     * \retval C2_OMITTED   this pool does not support linear blocks
-     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during operation (unexpected)
-     */
-    virtual c2_status_t fetchLinearBlock(
-            uint32_t capacity __unused, C2MemoryUsage usage __unused,
-            std::shared_ptr<C2LinearBlock> *block /* nonnull */) {
-        *block = nullptr;
-        return C2_OMITTED;
-    }
-
-    /**
-     * Obtains a circular writeable block of given |capacity| and |usage|. If successful, the
-     * block is stored in |block|. Otherwise, |block| is set to 'nullptr'.
-     *
-     * \param capacity the size of requested circular block. (note: the size of the obtained
-     *                 block could be slightly larger, e.g. to accommodate any system-required
-     *                 alignment)
-     * \param usage    the memory usage info for the requested block. Returned blocks will be
-     *                 optimized for this usage, but may be used with any usage. One exception:
-     *                 protected blocks/buffers can only be used in a protected scenario.
-     * \param block    pointer to where the obtained block shall be stored on success. nullptr
-     *                 will be stored here on failure
-     *
-     * \retval C2_OK        the operation was successful
-     * \retval C2_NO_MEMORY not enough memory to complete any required allocation
-     * \retval C2_TIMED_OUT the operation timed out
-     * \retval C2_REFUSED   no permission to complete any required allocation
-     * \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error)
-     * \retval C2_OMITTED   this pool does not support circular blocks
-     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during operation (unexpected)
-     */
-    virtual c2_status_t fetchCircularBlock(
-            uint32_t capacity __unused, C2MemoryUsage usage __unused,
-            std::shared_ptr<C2CircularBlock> *block /* nonnull */) {
-        *block = nullptr;
-        return C2_OMITTED;
-    }
-
-    /**
-     * Obtains a 2D graphic block of given |width|, |height|, |format| and |usage|. If successful,
-     * the block is stored in |block|. Otherwise, |block| is set to 'nullptr'.
-     *
-     * \param width  the width of requested block (the obtained block could be slightly larger, e.g.
-     *               to accommodate any system-required alignment)
-     * \param height the height of requested block (the obtained block could be slightly larger,
-     *               e.g. to accommodate any system-required alignment)
-     * \param format the pixel format of requested block. This could be a vendor specific format.
-     * \param usage  the memory usage info for the requested block. Returned blocks will be
-     *               optimized for this usage, but may be used with any usage. One exception:
-     *               protected blocks/buffers can only be used in a protected scenario.
-     * \param block  pointer to where the obtained block shall be stored on success. nullptr
-     *               will be stored here on failure
-     *
-     * \retval C2_OK        the operation was successful
-     * \retval C2_NO_MEMORY not enough memory to complete any required allocation
-     * \retval C2_TIMED_OUT the operation timed out
-     * \retval C2_REFUSED   no permission to complete any required allocation
-     * \retval C2_BAD_VALUE width, height, format or usage are not supported (invalid) (caller
-     *                      error)
-     * \retval C2_OMITTED   this pool does not support 2D blocks
-     * \retval C2_CORRUPTED some unknown, unrecoverable error occured during operation (unexpected)
-     */
-    virtual c2_status_t fetchGraphicBlock(
-            uint32_t width __unused, uint32_t height __unused, uint32_t format __unused,
-            C2MemoryUsage usage __unused,
-            std::shared_ptr<C2GraphicBlock> *block /* nonnull */) {
-        *block = nullptr;
-        return C2_OMITTED;
-    }
-
-protected:
-    C2BlockPool() = default;
-
-    virtual ~C2BlockPool() = default;
-};
-
-/// @}
-
-// ================================================================================================
-//  BLOCKS
-// ================================================================================================
-
-/**
- * Blocks are sections of allocations. They can be either 1D or 2D.
- */
-
-class C2LinearAllocation;
-
-/**
- * A 1D block.
- *
- * \note capacity() is not meaningful for users of blocks; instead size() is the capacity of the
- * usable portion. Use and offset() and size() if accessing the block directly through its handle
- * to represent the allotted range of the underlying allocation to this block.
- */
-class C2Block1D : public _C2LinearRangeAspect {
-public:
-    /**
-     * Returns the underlying handle for this allocation.
-     *
-     * \note that the block and its block pool has shared ownership of the handle
-     *       and if all references to the block are released, the underlying block
-     *       allocation may get reused even if a client keeps a clone of this handle.
-     */
-    const C2Handle *handle() const;
-
-    /**
-     * Returns the allocator's ID that created the underlying allocation for this block. This
-     * provides the context for understanding the handle.
-     */
-    C2Allocator::id_t getAllocatorId() const;
-
-protected:
-    class Impl;
-    /** construct a block. */
-    C2Block1D(std::shared_ptr<Impl> impl, const _C2LinearRangeAspect &range);
-
-    friend struct _C2BlockFactory;
-    std::shared_ptr<Impl> mImpl;
-};
-
-/**
- * Read view provides read-only access for a linear memory segment.
- *
- * This class is copiable.
- */
-class C2ReadView : public _C2LinearCapacityAspect {
-public:
-    /**
-     * \return pointer to the start of the block or nullptr on error.
-     *         This pointer is only valid during the lifetime of this view or until it is released.
-     */
-    const uint8_t *data() const;
-
-    /**
-     * Returns a portion of this view.
-     *
-     * \param offset  the start offset of the portion. \note This is clamped to the capacity of this
-     *              view.
-     * \param size    the size of the portion. \note This is clamped to the remaining data from offset.
-     *
-     * \return a read view containing a portion of this view
-     */
-    C2ReadView subView(size_t offset, size_t size) const;
-
-    /**
-     * \return error during the creation/mapping of this view.
-     */
-    c2_status_t error() const;
-
-    /**
-     * Releases this view. This sets error to C2_NO_INIT.
-     */
-    //void release();
-
-protected:
-    class Impl;
-    C2ReadView(std::shared_ptr<Impl> impl, uint32_t offset, uint32_t size);
-    explicit C2ReadView(c2_status_t error);
-
-private:
-    friend struct _C2BlockFactory;
-    std::shared_ptr<Impl> mImpl;
-    uint32_t mOffset; /**< offset into the linear block backing this read view */
-};
-
-/**
- * Write view provides read/write access for a linear memory segment.
- *
- * This class is copiable. \todo movable only?
- */
-class C2WriteView : public _C2EditableLinearRangeAspect {
-public:
-    /**
-     * Start of the block.
-     *
-     * \return pointer to the start of the block or nullptr on error.
-     *         This pointer is only valid during the lifetime of this view or until it is released.
-     */
-    uint8_t *base();
-
-    /**
-     * \return pointer to the block at the current offset or nullptr on error.
-     *         This pointer is only valid during the lifetime of this view or until it is released.
-     */
-    uint8_t *data();
-
-    /**
-     * \return error during the creation/mapping of this view.
-     */
-    c2_status_t error() const;
-
-    /**
-     * Releases this view. This sets error to C2_NO_INIT.
-     */
-    //void release();
-
-protected:
-    class Impl;
-    C2WriteView(std::shared_ptr<Impl> impl);
-    explicit C2WriteView(c2_status_t error);
-
-private:
-    friend struct _C2BlockFactory;
-    std::shared_ptr<Impl> mImpl;
-};
-
-/**
- * A constant (read-only) linear block (portion of an allocation) with an acquire fence.
- * Blocks are unmapped when created, and can be mapped into a read view on demand.
- *
- * This class is copiable and contains a reference to the allocation that it is based on.
- */
-class C2ConstLinearBlock : public C2Block1D {
-public:
-    /**
-     * Maps this block into memory and returns a read view for it.
-     *
-     * \return a read view for this block.
-     */
-    C2Acquirable<C2ReadView> map() const;
-
-    /**
-     * Returns a portion of this block.
-     *
-     * \param offset  the start offset of the portion. \note This is clamped to the capacity of this
-     *              block.
-     * \param size    the size of the portion. \note This is clamped to the remaining data from offset.
-     *
-     * \return a constant linear block containing a portion of this block
-     */
-    C2ConstLinearBlock subBlock(size_t offset, size_t size) const;
-
-    /**
-     * Returns the acquire fence for this block.
-     *
-     * \return a fence that must be waited on before reading the block.
-     */
-    C2Fence fence() const { return mFence; }
-
-protected:
-    C2ConstLinearBlock(std::shared_ptr<Impl> impl, const _C2LinearRangeAspect &range, C2Fence mFence);
-
-private:
-    friend struct _C2BlockFactory;
-    C2Fence mFence;
-};
-
-/**
- * Linear block is a writeable 1D block. Once written, it can be shared in whole or in parts with
- * consumers/readers as read-only const linear block(s).
- */
-class C2LinearBlock : public C2Block1D {
-public:
-    /**
-     * Maps this block into memory and returns a write view for it.
-     *
-     * \return a write view for this block.
-     */
-    C2Acquirable<C2WriteView> map();
-
-    /**
-     * Creates a read-only const linear block for a portion of this block; optionally protected
-     * by an acquire fence. There are two ways to use this:
-     *
-     * 1) share ready block after writing data into the block. In this case no fence shall be
-     *    supplied, and the block shall not be modified after calling this method.
-     * 2) share block metadata before actually (finishing) writing the data into the block. In
-     *    this case a fence must be supplied that will be triggered when the data is written.
-     *    The block shall be modified only until firing the event for the fence.
-     */
-    C2ConstLinearBlock share(size_t offset, size_t size, C2Fence fence);
-
-protected:
-    C2LinearBlock(std::shared_ptr<Impl> impl, const _C2LinearRangeAspect &range);
-
-    friend struct _C2BlockFactory;
-};
-
-/// @}
-
-/**************************************************************************************************
-  CIRCULAR BLOCKS AND VIEWS
-**************************************************************************************************/
-
-/// \defgroup circular Circular buffer support
-/// @{
-
-/**
- * Circular blocks can be used to share data between a writer and a reader (and/or other consumers)-
- * in a memory-efficient way by reusing a section of memory. Circular blocks are a bit more complex
- * than single reader/single writer schemes to facilitate block-based consuming of data.
- *
- * They can operate in two modes:
- *
- * 1) one writer that creates blocks to be consumed (this model can be used by components)
- *
- * 2) one writer that writes continuously, and one reader that can creates blocks to be consumed
- *    by further recipients (this model is used by the framework, and cannot be used by components.)
- *
- * Circular blocks have four segments with running pointers:
- *  - reserved: data reserved and available for the writer
- *  - committed: data committed by the writer and available to the reader (if present)
- *  - used: data used by consumers (if present)
- *  - available: unused data available to be reserved
- */
-class C2CircularBlock : public C2Block1D {
-    // TODO: add methods
-
-private:
-    size_t mReserved __unused;   // end of reserved section
-    size_t mCommitted __unused;  // end of committed section
-    size_t mUsed __unused;       // end of used section
-    size_t mFree __unused;       // end of free section
-};
-
-class _C2CircularBlockSegment : public _C2LinearCapacityAspect {
-public:
-    /**
-     * Returns the available size for this segment.
-     *
-     * \return currently available size for this segment
-     */
-    size_t available() const;
-
-    /**
-     * Reserve some space for this segment from its current start.
-     *
-     * \param size    desired space in bytes
-     * \param fence   a pointer to an acquire fence. If non-null, the reservation is asynchronous and
-     *              a fence will be stored here that will be signaled when the reservation is
-     *              complete. If null, the reservation is synchronous.
-     *
-     * \retval C2_OK            the space was successfully reserved
-     * \retval C2_NO_MEMORY     the space requested cannot be reserved
-     * \retval C2_TIMED_OUT     the reservation timed out \todo when?
-     * \retval C2_CORRUPTED     some unknown error prevented reserving space. (unexpected)
-     */
-    c2_status_t reserve(size_t size, C2Fence *fence /* nullable */);
-
-    /**
-     * Abandons a portion of this segment. This will move to the beginning of this segment.
-     *
-     * \note This methods is only allowed if this segment is producing blocks.
-     *
-     * \param size    number of bytes to abandon
-     *
-     * \retval C2_OK            the data was successfully abandoned
-     * \retval C2_TIMED_OUT     the operation timed out (unexpected)
-     * \retval C2_CORRUPTED     some unknown error prevented abandoning the data (unexpected)
-     */
-    c2_status_t abandon(size_t size);
-
-    /**
-     * Share a portion as block(s) with consumers (these are moved to the used section).
-     *
-     * \note This methods is only allowed if this segment is producing blocks.
-     * \note Share does not move the beginning of the segment. (\todo add abandon/offset?)
-     *
-     * \param size    number of bytes to share
-     * \param fence   fence to be used for the section
-     * \param blocks  vector where the blocks of the section are appended to
-     *
-     * \retval C2_OK            the portion was successfully shared
-     * \retval C2_NO_MEMORY     not enough memory to share the portion
-     * \retval C2_TIMED_OUT     the operation timed out (unexpected)
-     * \retval C2_CORRUPTED     some unknown error prevented sharing the data (unexpected)
-     */
-    c2_status_t share(size_t size, C2Fence fence, std::vector<C2ConstLinearBlock> &blocks);
-
-    /**
-     * Returns the beginning offset of this segment from the start of this circular block.
-     *
-     * @return beginning offset
-     */
-    size_t begin();
-
-    /**
-     * Returns the end offset of this segment from the start of this circular block.
-     *
-     * @return end offset
-     */
-    size_t end();
-};
-
-/**
- * A circular write-view is a dynamic mapped view for a segment of a circular block. Care must be
- * taken when using this view so that only the section owned by the segment is modified.
- */
-class C2CircularWriteView : public _C2LinearCapacityAspect {
-public:
-    /**
-     * Start of the circular block.
-     * \note the segment does not own this pointer.
-     *
-     * \return pointer to the start of the circular block or nullptr on error.
-     */
-    uint8_t *base();
-
-    /**
-     * \return error during the creation/mapping of this view.
-     */
-    c2_status_t error() const;
-};
-
-/**
- * The writer of a circular buffer.
- *
- * Can commit data to a reader (not supported for components) OR share data blocks directly with a
- * consumer.
- *
- * If a component supports outputting data into circular buffers, it must allocate a circular
- * block and use a circular writer.
- */
-class C2CircularWriter : public _C2CircularBlockSegment {
-public:
-    /**
-     * Commits a portion of this segment to the next segment. This moves the beginning of the
-     * segment.
-     *
-     * \param size    number of bytes to commit to the next segment
-     * \param fence   fence used for the commit (the fence must signal before the data is committed)
-     */
-    c2_status_t commit(size_t size, C2Fence fence);
-
-    /**
-     * Maps this block into memory and returns a write view for it.
-     *
-     * \return a write view for this block.
-     */
-    C2Acquirable<C2CircularWriteView> map();
-};
-
-/// @}
-
-/// \defgroup graphic Graphic Data Blocks
-/// @{
-
-/**
- * C2Rect: rectangle type with non-negative coordinates.
- *
- * \note This struct has public fields without getters/setters. All methods are inline.
- */
-struct C2Rect {
-// public:
-    uint32_t left;
-    uint32_t top;
-    uint32_t width;
-    uint32_t height;
-
-    constexpr inline C2Rect()
-        : C2Rect(0, 0, 0, 0) { }
-
-    constexpr inline C2Rect(uint32_t width_, uint32_t height_)
-        : C2Rect(width_, height_, 0, 0) { }
-
-    constexpr inline C2Rect(uint32_t width_, uint32_t height_, uint32_t left_, uint32_t top_)
-        : left(left_), top(top_), width(width_), height(height_) { }
-
-    // utility methods
-
-    inline constexpr bool isEmpty() const {
-        return width == 0 || height == 0;
-    }
-
-    inline constexpr bool isValid() const {
-        return left <= ~width && top <= ~height;
-    }
-
-    inline constexpr operator bool() const {
-        return isValid() && !isEmpty();
-    }
-
-    inline constexpr bool operator!() const {
-        return !bool(*this);
-    }
-
-    C2_ALLOW_OVERFLOW
-    inline constexpr bool contains(const C2Rect &other) const {
-        if (!isValid() || !other.isValid()) {
-            return false;
-        } else {
-            return left <= other.left && top <= other.top
-                    && left + width >= other.left + other.width
-                    && top + height >= other.top + other.height;
-        }
-    }
-
-    inline constexpr bool operator==(const C2Rect &other) const {
-        if (!isValid()) {
-            return !other.isValid();
-        } else {
-            return left == other.left && top == other.top
-                    && width == other.width && height == other.height;
-        }
-    }
-
-    inline constexpr bool operator!=(const C2Rect &other) const {
-        return !operator==(other);
-    }
-
-    inline constexpr bool operator>=(const C2Rect &other) const {
-        return contains(other);
-    }
-
-    inline constexpr bool operator>(const C2Rect &other) const {
-        return contains(other) && !operator==(other);
-    }
-
-    inline constexpr bool operator<=(const C2Rect &other) const {
-        return other.contains(*this);
-    }
-
-    inline constexpr bool operator<(const C2Rect &other) const {
-        return other.contains(*this) && !operator==(other);
-    }
-
-    C2_ALLOW_OVERFLOW
-    inline constexpr uint32_t right() const {
-        return left + width;
-    }
-
-    C2_ALLOW_OVERFLOW
-    inline constexpr uint32_t bottom() const {
-        return top + height;
-    }
-
-    C2_ALLOW_OVERFLOW
-    inline constexpr C2Rect intersect(const C2Rect &other) const {
-        return C2Rect(c2_min(right(), other.right()) - c2_max(left, other.left),
-                      c2_min(bottom(), other.bottom()) - c2_max(top, other.top),
-                      c2_max(left, other.left),
-                      c2_max(top, other.top));
-    }
-
-    /** clamps right and bottom to top, left if they overflow */
-    inline constexpr C2Rect normalize() const {
-        return C2Rect(c2_max(left, right()) - left, c2_max(top, bottom()) - top, left, top);
-    }
-};
-
-/**
- * Interface for objects that have a width and height (planar capacity).
- */
-class _C2PlanarCapacityAspect {
-/// \name Planar capacity interface
-/// @{
-public:
-    inline constexpr uint32_t width() const { return _mWidth; }
-    inline constexpr uint32_t height() const { return _mHeight; }
-
-    inline constexpr operator C2Rect() const {
-        return C2Rect(_mWidth, _mHeight);
-    }
-
-protected:
-    inline constexpr _C2PlanarCapacityAspect(uint32_t width, uint32_t height)
-      : _mWidth(width), _mHeight(height) { }
-
-    inline explicit constexpr _C2PlanarCapacityAspect(const _C2PlanarCapacityAspect *parent)
-        : _mWidth(parent == nullptr ? 0 : parent->width()),
-          _mHeight(parent == nullptr ? 0 : parent->height()) { }
-
-private:
-    uint32_t _mWidth;
-    uint32_t _mHeight;
-/// @}
-};
-
-/**
- * C2PlaneInfo: information on the layout of a singe flexible plane.
- *
- * Public fields without getters/setters.
- */
-struct C2PlaneInfo {
-//public:
-    enum channel_t : uint32_t {
-        CHANNEL_Y,  ///< luma
-        CHANNEL_R,  ///< red
-        CHANNEL_G,  ///< green
-        CHANNEL_B,  ///< blue
-        CHANNEL_A,  ///< alpha
-        CHANNEL_CR, ///< Cr
-        CHANNEL_CB, ///< Cb
-    } channel;
-
-    int32_t colInc;       ///< column increment in bytes. may be negative
-    int32_t rowInc;       ///< row increment in bytes. may be negative
-
-    uint32_t colSampling; ///< subsampling compared to width (must be a power of 2)
-    uint32_t rowSampling; ///< subsampling compared to height (must be a power of 2)
-
-    uint32_t allocatedDepth; ///< size of each sample (must be a multiple of 8)
-    uint32_t bitDepth;       ///< significant bits per sample
-    /**
-     * the right shift of the significant bits in the sample. E.g. if a 10-bit significant
-     * value is laid out in a 16-bit allocation aligned to LSB (values 0-1023), rightShift
-     * would be 0 as the 16-bit value read from the sample does not need to be right shifted
-     * and can be used as is (after applying a 10-bit mask of 0x3FF).
-     *
-     * +--------+--------+
-     * |      VV|VVVVVVVV|
-     * +--------+--------+
-     *  15     8 7      0
-     *
-     * If the value is laid out aligned to MSB, rightShift would be 6, as the value read
-     * from the allocated sample must be right-shifted by 6 to get the actual sample value.
-     *
-     * +--------+--------+
-     * |VVVVVVVV|VV      |
-     * +--------+--------+
-     *  15     8 7      0
-     */
-    uint32_t rightShift;
-
-    enum endianness_t : uint32_t {
-        NATIVE,
-        LITTLE_END, // LITTLE_ENDIAN is reserved macro
-        BIG_END,    // BIG_ENDIAN is a reserved macro
-    } endianness; ///< endianness of the samples
-
-    /**
-     * The following two fields define the relation between multiple planes. If multiple planes are
-     * interleaved, they share a root plane (whichever plane's start address is the lowest), and
-     * |offset| is the offset of this plane inside the root plane (in bytes). |rootIx| is the index
-     * of the root plane. If a plane is independent, rootIx is its index and offset is 0.
-     */
-    uint32_t rootIx; ///< index of the root plane
-    uint32_t offset; ///< offset of this plane inside of the root plane
-
-    inline constexpr ssize_t minOffset(uint32_t width, uint32_t height) const {
-        ssize_t offs = 0;
-        if (width > 0 && colInc < 0) {
-            offs += colInc * (ssize_t)(width - 1);
-        }
-        if (height > 0 && rowInc < 0) {
-            offs += rowInc * (ssize_t)(height - 1);
-        }
-        return offs;
-    }
-
-    inline constexpr ssize_t maxOffset(uint32_t width, uint32_t height) const {
-        ssize_t offs = (allocatedDepth + 7) >> 3;
-        if (width > 0 && colInc > 0) {
-            offs += colInc * (ssize_t)(width - 1);
-        }
-        if (height > 0 && rowInc > 0) {
-            offs += rowInc * (ssize_t)(height - 1);
-        }
-        return offs;
-    }
-} C2_PACK;
-
-struct C2PlanarLayout {
-//public:
-    enum type_t : uint32_t {
-        TYPE_UNKNOWN = 0,
-        TYPE_YUV = 0x100,   ///< YUV image with 3 planes
-        TYPE_YUVA,          ///< YUVA image with 4 planes
-        TYPE_RGB,           ///< RGB image with 3 planes
-        TYPE_RGBA,          ///< RBGA image with 4 planes
-    };
-
-    type_t type;                    // image type
-    uint32_t numPlanes;             // number of component planes
-    uint32_t rootPlanes;            // number of layout planes (root planes)
-
-    enum plane_index_t : uint32_t {
-        PLANE_Y = 0,
-        PLANE_U = 1,
-        PLANE_V = 2,
-        PLANE_R = 0,
-        PLANE_G = 1,
-        PLANE_B = 2,
-        PLANE_A = 3,
-        MAX_NUM_PLANES = 4,
-    };
-
-    C2PlaneInfo planes[MAX_NUM_PLANES];
-};
-
-/**
- * Aspect for objects that have a planar section (crop rectangle).
- *
- * This class is copiable.
- */
-class _C2PlanarSectionAspect : public _C2PlanarCapacityAspect {
-/// \name Planar section interface
-/// @{
-private:
-    inline constexpr _C2PlanarSectionAspect(uint32_t width, uint32_t height, const C2Rect &crop)
-        : _C2PlanarCapacityAspect(width, height),
-          mCrop(std::min(width - std::min(crop.left, width), crop.width),
-                std::min(height - std::min(crop.top, height), crop.height),
-                std::min(crop.left, width),
-                std::min(crop.height, height)) {
-    }
-
-public:
-    // crop can be an empty rect, does not have to line up with subsampling
-    // NOTE: we do not support floating-point crop
-    inline constexpr C2Rect crop() const { return mCrop; }
-
-    /**
-     * Returns a child planar section for |crop|, where the capacity represents this section.
-     */
-    inline constexpr _C2PlanarSectionAspect childSection(const C2Rect &crop) const {
-        return _C2PlanarSectionAspect(
-                mCrop.width, mCrop.height,
-                // crop and translate |crop| rect
-                C2Rect(c2_min(mCrop.right() - c2_clamp(mCrop.left, crop.left, mCrop.right()), crop.width),
-                       c2_min(mCrop.bottom() - c2_clamp(mCrop.top, crop.top, mCrop.bottom()), crop.height),
-                       c2_clamp(mCrop.left, crop.left, mCrop.right()) - mCrop.left,
-                       c2_clamp(mCrop.top, crop.top, mCrop.bottom()) - mCrop.top));
-    }
-
-protected:
-    inline constexpr _C2PlanarSectionAspect(const _C2PlanarCapacityAspect *parent)
-        : _C2PlanarCapacityAspect(parent), mCrop(width(), height()) {}
-
-    inline constexpr _C2PlanarSectionAspect(const _C2PlanarCapacityAspect *parent, const C2Rect &crop)
-        : _C2PlanarCapacityAspect(parent),
-          mCrop(parent == nullptr ? C2Rect(0, 0) : ((C2Rect)*parent).intersect(crop).normalize()) { }
-
-    inline constexpr _C2PlanarSectionAspect(const _C2PlanarSectionAspect *parent, const C2Rect &crop)
-        : _C2PlanarCapacityAspect(parent),
-          mCrop(parent == nullptr ? C2Rect(0, 0) : parent->crop().intersect(crop).normalize()) { }
-
-private:
-    friend class _C2EditablePlanarSectionAspect;
-    C2Rect mCrop;
-/// @}
-};
-
-/**
- * Aspect for objects that have an editable planar section (crop rectangle).
- *
- * This class is copiable.
- */
-class _C2EditablePlanarSectionAspect : public _C2PlanarSectionAspect {
-/// \name Planar section interface
-/// @{
-    using _C2PlanarSectionAspect::_C2PlanarSectionAspect;
-
-public:
-    // crop can be an empty rect, does not have to line up with subsampling
-    // NOTE: we do not support floating-point crop
-    inline constexpr C2Rect crop() const { return mCrop; }
-
-    /**
-     *  Sets crop to crop intersected with [(0,0) .. (width, height)]
-     */
-    inline void setCrop_be(const C2Rect &crop) {
-        mCrop.left = std::min(width(), crop.left);
-        mCrop.top = std::min(height(), crop.top);
-        // It's guaranteed that mCrop.left <= width() && mCrop.top <= height()
-        mCrop.width = std::min(width() - mCrop.left, crop.width);
-        mCrop.height = std::min(height() - mCrop.top, crop.height);
-    }
-
-    /**
-     * If crop is within the dimensions of this object, it sets crop to it.
-     *
-     * \return true iff crop is within the dimensions of this object
-     */
-    inline bool setCrop(const C2Rect &crop) {
-        if (width() < crop.width || height() < crop.height
-                || width() - crop.width < crop.left || height() - crop.height < crop.top) {
-            return false;
-        }
-        mCrop = crop;
-        return true;
-    }
-/// @}
-};
-
-/**
- * Utility class for safe range calculations using size_t-s.
- */
-class C2PlanarSection : public _C2PlanarSectionAspect {
-public:
-    inline constexpr C2PlanarSection(const _C2PlanarCapacityAspect &parent, const C2Rect &crop)
-        : _C2PlanarSectionAspect(&parent, crop) { }
-
-    inline constexpr C2PlanarSection(const _C2PlanarSectionAspect &parent, const C2Rect &crop)
-        : _C2PlanarSectionAspect(&parent, crop) { }
-
-    inline constexpr C2PlanarSection intersect(const C2Rect &crop) const {
-        return C2PlanarSection(*this, crop);
-    }
-};
-
-/**
- * Utility class for simple and safe planar capacity and section construction.
- */
-class C2PlanarCapacity : public _C2PlanarCapacityAspect {
-public:
-    inline constexpr explicit C2PlanarCapacity(size_t width, size_t height)
-        : _C2PlanarCapacityAspect(c2_min(width, std::numeric_limits<uint32_t>::max()),
-                                  c2_min(height, std::numeric_limits<uint32_t>::max())) { }
-
-    inline constexpr C2PlanarSection section(const C2Rect &crop) const {
-        return C2PlanarSection(*this, crop);
-    }
-};
-
-
-/**
- * \ingroup graphic allocator
- * 2D allocation interface.
- */
-class C2GraphicAllocation : public _C2PlanarCapacityAspect {
-public:
-    /**
-     * Maps a rectangular section (as defined by |rect|) of a 2D allocation into local process
-     * memory for flexible access. On success, it fills out |layout| with the plane specifications
-     * and fills the |addr| array with pointers to the first byte of the top-left pixel of each
-     * plane used. Otherwise, it leaves |layout| and |addr| untouched. |fence| will contain
-     * an acquire sync fence object. If it is already safe to access the
-     * buffer contents, then it will be an empty (already fired) fence.
-     *
-     * Safe regions for the pointer addresses returned can be gotten via C2LayoutInfo.minOffset()/
-     * maxOffset().
-     *
-     * \param rect          section to be mapped (this does not have to be aligned)
-     * \param usage         the desired usage. \todo this must be kSoftwareRead and/or
-     *                      kSoftwareWrite.
-     * \param fence         a pointer to a fence object if an async mapping is requested. If
-     *                      not-null, and acquire fence will be stored here on success, or empty
-     *                      fence on failure. If null, the mapping will be synchronous.
-     * \param layout        a pointer to where the mapped planes' descriptors will be
-     *                      stored. On failure, nullptr will be stored here.
-     * \param addr          pointer to an array with at least C2PlanarLayout::MAX_NUM_PLANES
-     *                      elements. Only layout.numPlanes elements will be modified on success.
-     *
-     * \retval C2_OK        the operation was successful
-     * \retval C2_REFUSED   no permission to map the section
-     * \retval C2_DUPLICATE there is already a mapped region and this allocation cannot support
-     *                      multi-mapping (caller error)
-     * \retval C2_TIMED_OUT the operation timed out
-     * \retval C2_NO_MEMORY not enough memory to complete the operation
-     * \retval C2_BAD_VALUE the parameters (rect) are invalid or outside the allocation, or the
-     *                      usage flags are invalid (caller error)
-     * \retval C2_CORRUPTED some unknown error prevented the operation from completing (unexpected)
-
-     */
-    virtual c2_status_t map(
-            C2Rect rect, C2MemoryUsage usage, C2Fence *fence,
-            C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) = 0;
-
-    /**
-     * Unmaps a section of an allocation at |addr| with |rect|. These must be parameters previously
-     * passed to and returned by |map|; otherwise, this operation is a no-op.
-     *
-     * \param addr          pointer to an array with at least C2PlanarLayout::MAX_NUM_PLANES
-     *                      elements containing the starting addresses of the mapped layers
-     * \param rect          boundaries of the mapped section
-     * \param fence         a pointer to a fence object if an async unmapping is requested. If
-     *                      not-null, a release fence will be stored here on success, or empty fence
-     *                      on failure. This fence signals when the original allocation contains
-     *                      all changes that happened to the mapped section. If null, the unmapping
-     *                      will be synchronous.
-     *
-     * \retval C2_OK        the operation was successful
-     * \retval C2_TIMED_OUT the operation timed out
-     * \retval C2_NOT_FOUND there is no such mapped region (caller error)
-     * \retval C2_CORRUPTED some unknown error prevented the operation from completing (unexpected)
-     * \retval C2_REFUSED   no permission to unmap the section (unexpected - system)
-     */
-    virtual c2_status_t unmap(
-            uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) = 0;
-
-    /**
-     * Returns the allocator ID for this allocation. This is useful to put the handle into context.
-     */
-    virtual C2Allocator::id_t getAllocatorId() const = 0;
-
-    /**
-     * Returns a pointer to the allocation handle.
-     */
-    virtual const C2Handle *handle() const = 0;
-
-    /**
-     * Returns true if this is the same allocation as |other|.
-     */
-    virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const = 0;
-
-protected:
-    using _C2PlanarCapacityAspect::_C2PlanarCapacityAspect;
-    virtual ~C2GraphicAllocation() = default;
-};
-
-class C2GraphicAllocation;
-
-/**
- * A 2D block.
- *
- * \note width()/height() is not meaningful for users of blocks; instead, crop().width() and
- * crop().height() is the capacity of the usable portion. Use and crop() if accessing the block
- * directly through its handle to represent the allotted region of the underlying allocation to this
- * block.
- */
-class C2Block2D : public _C2PlanarSectionAspect {
-public:
-    /**
-     * Returns the underlying handle for this allocation.
-     *
-     * \note that the block and its block pool has shared ownership of the handle
-     *       and if all references to the block are released, the underlying block
-     *       allocation may get reused even if a client keeps a clone of this handle.
-     */
-    const C2Handle *handle() const;
-
-    /**
-     * Returns the allocator's ID that created the underlying allocation for this block. This
-     * provides the context for understanding the handle.
-     */
-    C2Allocator::id_t getAllocatorId() const;
-
-protected:
-    class Impl;
-    C2Block2D(std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section);
-
-    friend struct _C2BlockFactory;
-    std::shared_ptr<Impl> mImpl;
-};
-
-/**
- * Graphic view provides read or read-write access for a graphic block.
- *
- * This class is copiable.
- *
- * \note Due to the subsampling of graphic buffers, a read view must still contain a crop rectangle
- * to ensure subsampling is followed. This results in nearly identical interface between read and
- * write views, so C2GraphicView can encompass both of them.
- */
-class C2GraphicView : public _C2EditablePlanarSectionAspect {
-public:
-    /**
-     * \return array of pointers (of layout().numPlanes elements) to the start of the planes or
-     * nullptr on error. Regardless of crop rect, they always point to the top-left corner of each
-     * plane. Access outside of the crop rect results in an undefined behavior.
-     */
-    const uint8_t *const *data() const;
-
-    /**
-     * \return array of pointers (of layout().numPlanes elements) to the start of the planes or
-     * nullptr on error. Regardless of crop rect, they always point to the top-left corner of each
-     * plane. Access outside of the crop rect results in an undefined behavior.
-     */
-    uint8_t *const *data();
-
-    /**
-     * \return layout of the graphic block to interpret the returned data.
-     */
-    const C2PlanarLayout layout() const;
-
-    /**
-     * Returns a section of this view.
-     *
-     * \param rect    the dimension of the section. \note This is clamped to the crop of this view.
-     *
-     * \return a read view containing the requested section of this view
-     */
-    const C2GraphicView subView(const C2Rect &rect) const;
-    C2GraphicView subView(const C2Rect &rect);
-
-    /**
-     * \return error during the creation/mapping of this view.
-     */
-    c2_status_t error() const;
-
-protected:
-    class Impl;
-    C2GraphicView(std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section);
-    explicit C2GraphicView(c2_status_t error);
-
-private:
-    friend struct _C2BlockFactory;
-    std::shared_ptr<Impl> mImpl;
-};
-
-/**
- * A constant (read-only) graphic block (portion of an allocation) with an acquire fence.
- * Blocks are unmapped when created, and can be mapped into a read view on demand.
- *
- * This class is copiable and contains a reference to the allocation that it is based on.
- */
-class C2ConstGraphicBlock : public C2Block2D {
-public:
-    /**
-     * Maps this block into memory and returns a read view for it.
-     *
-     * \return a read view for this block.
-     */
-    C2Acquirable<const C2GraphicView> map() const;
-
-    /**
-     * Returns a section of this block.
-     *
-     * \param rect    the coordinates of the section. \note This is clamped to the crop rectangle of
-     *              this block.
-     *
-     * \return a constant graphic block containing a portion of this block
-     */
-    C2ConstGraphicBlock subBlock(const C2Rect &rect) const;
-
-    /**
-     * Returns the acquire fence for this block.
-     *
-     * \return a fence that must be waited on before reading the block.
-     */
-    C2Fence fence() const { return mFence; }
-
-protected:
-    C2ConstGraphicBlock(
-            std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section, C2Fence fence);
-
-private:
-    friend struct _C2BlockFactory;
-    C2Fence mFence;
-};
-
-/**
- * Graphic block is a writeable 2D block. Once written, it can be shared in whole or in part with
- * consumers/readers as read-only const graphic block.
- */
-class C2GraphicBlock : public C2Block2D {
-public:
-    /**
-     * Maps this block into memory and returns a write view for it.
-     *
-     * \return a write view for this block.
-     */
-    C2Acquirable<C2GraphicView> map();
-
-    /**
-     * Creates a read-only const linear block for a portion of this block; optionally protected
-     * by an acquire fence. There are two ways to use this:
-     *
-     * 1) share ready block after writing data into the block. In this case no fence shall be
-     *    supplied, and the block shall not be modified after calling this method.
-     * 2) share block metadata before actually (finishing) writing the data into the block. In
-     *    this case a fence must be supplied that will be triggered when the data is written.
-     *    The block shall be modified only until firing the event for the fence.
-     */
-    C2ConstGraphicBlock share(const C2Rect &crop, C2Fence fence);
-
-protected:
-    C2GraphicBlock(std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section);
-
-    friend struct _C2BlockFactory;
-};
-
-/// @}
-
-/// \defgroup buffer_onj Buffer objects
-/// @{
-
-// ================================================================================================
-//  BUFFERS
-// ================================================================================================
-
-/// \todo: Do we still need this?
-///
-// There are 2 kinds of buffers: linear or graphic. Linear buffers can contain a single block, or
-// a list of blocks (LINEAR_CHUNKS). Support for list of blocks is optional, and can allow consuming
-// data from circular buffers or scattered data sources without extra memcpy. Currently, list of
-// graphic blocks is not supported.
-
-class C2LinearBuffer;   // read-write buffer
-class C2GraphicBuffer;  // read-write buffer
-class C2LinearChunksBuffer;
-
-/**
- * C2BufferData: the main, non-meta data of a buffer. A buffer can contain either linear blocks
- * or graphic blocks, and can contain either a single block or multiple blocks. This is determined
- * by its type.
- */
-class C2BufferData {
-public:
-    /**
-     *  The type of buffer data.
-     */
-    enum Type : uint32_t {
-        LINEAR,             ///< the buffer contains a single linear block
-        LINEAR_CHUNKS,      ///< the buffer contains one or more linear blocks
-        GRAPHIC,            ///< the buffer contains a single graphic block
-        GRAPHIC_CHUNKS,     ///< the buffer contains one of more graphic blocks
-    };
-
-    /**
-     * Gets the type of this buffer (data).
-     * \return the type of this buffer data.
-     */
-    Type type() const;
-
-    /**
-     * Gets the linear blocks of this buffer.
-     * \return a constant list of const linear blocks of this buffer.
-     * \retval empty list if this buffer does not contain linear block(s).
-     */
-    const std::vector<C2ConstLinearBlock> linearBlocks() const;
-
-    /**
-     * Gets the graphic blocks of this buffer.
-     * \return a constant list of const graphic blocks of this buffer.
-     * \retval empty list if this buffer does not contain graphic block(s).
-     */
-    const std::vector<C2ConstGraphicBlock> graphicBlocks() const;
-
-private:
-    class Impl;
-    std::shared_ptr<Impl> mImpl;
-
-protected:
-    // no public constructor
-    explicit C2BufferData(const std::vector<C2ConstLinearBlock> &blocks);
-    explicit C2BufferData(const std::vector<C2ConstGraphicBlock> &blocks);
-};
-
-/**
- * C2Buffer: buffer base class. These are always used as shared_ptrs. Though the underlying buffer
- * objects (native buffers, ion buffers, or dmabufs) are reference-counted by the system,
- * C2Buffers hold only a single reference.
- *
- * These objects cannot be used on the stack.
- */
-class C2Buffer {
-public:
-    /**
-     * Gets the buffer's data.
-     *
-     * \return the buffer's data.
-     */
-    const C2BufferData data() const;
-
-    /**
-     * These will still work if used in onDeathNotify.
-     */
-#if 0
-    inline std::shared_ptr<C2LinearBuffer> asLinearBuffer() const {
-        return mType == LINEAR ? std::shared_ptr::reinterpret_cast<C2LinearBuffer>(this) : nullptr;
-    }
-
-    inline std::shared_ptr<C2GraphicBuffer> asGraphicBuffer() const {
-        return mType == GRAPHIC ? std::shared_ptr::reinterpret_cast<C2GraphicBuffer>(this) : nullptr;
-    }
-
-    inline std::shared_ptr<C2CircularBuffer> asCircularBuffer() const {
-        return mType == CIRCULAR ? std::shared_ptr::reinterpret_cast<C2CircularBuffer>(this) : nullptr;
-    }
-#endif
-
-    ///@name Pre-destroy notification handling
-    ///@{
-
-    /**
-     * Register for notification just prior to the destruction of this object.
-     */
-    typedef void (*OnDestroyNotify) (const C2Buffer *buf, void *arg);
-
-    /**
-     * Registers for a pre-destroy notification. This is called just prior to the destruction of
-     * this buffer (when this buffer is no longer valid.)
-     *
-     * \param onDestroyNotify   the notification callback
-     * \param arg               an arbitrary parameter passed to the callback
-     *
-     * \retval C2_OK        the registration was successful.
-     * \retval C2_DUPLICATE a notification was already registered for this callback and argument
-     * \retval C2_NO_MEMORY not enough memory to register for this callback
-     * \retval C2_CORRUPTED an unknown error prevented the registration (unexpected)
-     */
-    c2_status_t registerOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg = nullptr);
-
-    /**
-     * Unregisters a previously registered pre-destroy notification.
-     *
-     * \param onDestroyNotify   the notification callback
-     * \param arg               an arbitrary parameter passed to the callback
-     *
-     * \retval C2_OK        the unregistration was successful.
-     * \retval C2_NOT_FOUND the notification was not found
-     * \retval C2_CORRUPTED an unknown error prevented the registration (unexpected)
-     */
-    c2_status_t unregisterOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg = nullptr);
-
-    ///@}
-
-    virtual ~C2Buffer() = default;
-
-    ///@name Buffer-specific arbitrary metadata handling
-    ///@{
-
-    /**
-     * Gets the list of metadata associated with this buffer.
-     *
-     * \return a constant list of info objects associated with this buffer.
-     */
-    const std::vector<std::shared_ptr<const C2Info>> info() const;
-
-    /**
-     * Attaches (or updates) an (existing) metadata for this buffer.
-     * If the metadata is stream specific, the stream information will be reset.
-     *
-     * \param info Metadata to update
-     *
-     * \retval C2_OK        the metadata was successfully attached/updated.
-     * \retval C2_NO_MEMORY not enough memory to attach the metadata (this return value is not
-     *                      used if the same kind of metadata is already attached to the buffer).
-     */
-    c2_status_t setInfo(const std::shared_ptr<C2Info> &info);
-
-    /**
-     * Checks if there is a certain type of metadata attached to this buffer.
-     *
-     * \param index the parameter type of the metadata
-     *
-     * \return true iff there is a metadata with the parameter type attached to this buffer.
-     */
-    bool hasInfo(C2Param::Type index) const;
-
-    /**
-     * Removes a metadata from the buffer.
-     */
-    std::shared_ptr<C2Info> removeInfo(C2Param::Type index);
-    ///@}
-
-    /**
-     * Creates a buffer containing a single linear block.
-     *
-     * \param block the content of the buffer.
-     *
-     * \return shared pointer to the created buffer.
-     */
-    static std::shared_ptr<C2Buffer> CreateLinearBuffer(const C2ConstLinearBlock &block);
-
-    /**
-     * Creates a buffer containing a single graphic block.
-     *
-     * \param block the content of the buffer.
-     *
-     * \return shared pointer to the created buffer.
-     */
-    static std::shared_ptr<C2Buffer> CreateGraphicBuffer(const C2ConstGraphicBlock &block);
-
-
-
-protected:
-    // no public constructor
-    explicit C2Buffer(const std::vector<C2ConstLinearBlock> &blocks);
-    explicit C2Buffer(const std::vector<C2ConstGraphicBlock> &blocks);
-
-private:
-    class Impl;
-    std::shared_ptr<Impl> mImpl;
-//    Type _mType;
-};
-
-/**
- * An extension of C2Info objects that can contain arbitrary buffer data.
- *
- * \note This object is not describable and contains opaque data.
- */
-class C2InfoBuffer {
-public:
-    /**
-     * Gets the index of this info object.
-     *
-     * \return the parameter index.
-     */
-    const C2Param::Index index() const;
-
-    /**
-     * Gets the buffer's data.
-     *
-     * \return the buffer's data.
-     */
-    const C2BufferData data() const;
-};
-
-/// @}
-
-/// \cond INTERNAL
-
-/// \todo These are no longer used
-
-/// \addtogroup linear
-/// @{
-
-/** \deprecated */
-class C2LinearBuffer
-    : public C2Buffer, public _C2LinearRangeAspect,
-      public std::enable_shared_from_this<C2LinearBuffer> {
-public:
-    /** \todo what is this? */
-    const C2Handle *handle() const;
-
-protected:
-    inline C2LinearBuffer(const C2ConstLinearBlock &block);
-
-private:
-    class Impl;
-    Impl *mImpl;
-};
-
-class C2ReadCursor;
-
-class C2WriteCursor {
-public:
-    uint32_t remaining() const; // remaining data to be read
-    void commit(); // commits the current position. discard data before current position
-    void reset() const;  // resets position to the last committed position
-    // slices off at most |size| bytes, and moves cursor ahead by the number of bytes
-    // sliced off.
-    C2ReadCursor slice(uint32_t size) const;
-    // slices off at most |size| bytes, and moves cursor ahead by the number of bytes
-    // sliced off.
-    C2WriteCursor reserve(uint32_t size);
-    // bool read(T&);
-    // bool write(T&);
-    C2Fence waitForSpace(uint32_t size);
-};
-
-/// @}
-
-/// \addtogroup graphic
-/// @{
-
-struct C2ColorSpace {
-//public:
-    enum Standard {
-        BT601,
-        BT709,
-        BT2020,
-        // TODO
-    };
-
-    enum Range {
-        LIMITED,
-        FULL,
-        // TODO
-    };
-
-    enum TransferFunction {
-        BT709Transfer,
-        BT2020Transfer,
-        HybridLogGamma2,
-        HybridLogGamma4,
-        // TODO
-    };
-};
-
-/** \deprecated */
-class C2GraphicBuffer : public C2Buffer {
-public:
-    // constant attributes
-    inline uint32_t width() const  { return mWidth; }
-    inline uint32_t height() const { return mHeight; }
-    inline uint32_t format() const { return mFormat; }
-    inline const C2MemoryUsage usage() const { return mUsage; }
-
-    // modifiable attributes
-
-
-    virtual const C2ColorSpace colorSpace() const = 0;
-    // best effort
-    virtual void setColorSpace_be(const C2ColorSpace &colorSpace) = 0;
-    virtual bool setColorSpace(const C2ColorSpace &colorSpace) = 0;
-
-    const C2Handle *handle() const;
-
-protected:
-    uint32_t mWidth;
-    uint32_t mHeight;
-    uint32_t mFormat;
-    C2MemoryUsage mUsage;
-
-    class Impl;
-    Impl *mImpl;
-};
-
-/// @}
-
-/// \endcond
-
-/// @}
-
-#endif  // C2BUFFER_H_
diff --git a/media/libstagefright/codec2/include/C2BufferBase.h b/media/libstagefright/codec2/include/C2BufferBase.h
deleted file mode 100644
index 68411f2..0000000
--- a/media/libstagefright/codec2/include/C2BufferBase.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef C2BUFFER_BASE_H_
-#define C2BUFFER_BASE_H_
-
-/// \defgroup allocator Allocation and memory placement
-/// @{
-
-/**
- * Buffer/memory usage bits. These shall be used by the allocators to select optimal memory type/
- * pool and buffer layout. Usage bits are conceptually separated into read and write usage, while
- * the buffer use life-cycle is separated into producers (writers) and consumers (readers).
- * These two concepts are related but not equivalent: consumers may only read buffers and only
- * producers may write to buffers; note, however, that buffer producers may also want or need to
- * read the buffers.
- *
- * Read and write buffer usage bits shall be or-ed to arrive at the full buffer usage. Admittedly,
- * this does not account for the amount of reading and writing (e.g. a buffer may have one or more
- * readers); however, the proper information necessary to properly weigh the various usages would be
- * the amount of data read/written for each usage type. This would result in an integer array of
- * size 64 (or the number of distinct usages) for memory usage, and likely such detailed information
- * would not always be available.
- *
- * That platform-agnostic Codec 2.0 API only defines the bare minimum usages. Platforms shall define
- * usage bits that are appropriate for the platform.
- */
-struct C2MemoryUsage {
-// public:
-    /**
-     * Buffer read usage.
-     */
-    enum Read : uint64_t {
-        /** Buffer is read by the CPU. */
-        CPU_READ        = 1 << 0,
-        /**
-         * Buffer shall only be read by trusted hardware. The definition of trusted hardware is
-         * platform specific, but this flag is reserved to prevent mapping this block into CPU
-         * readable memory resulting in bus fault. This flag can be used when buffer access must be
-         * protected.
-         */
-        READ_PROTECTED  = 1 << 1,
-    };
-
-    /**
-     * Buffer write usage.
-     */
-    enum Write : uint64_t {
-        /** Buffer is writted to by the CPU. */
-        CPU_WRITE        = 1 << 2,
-        /**
-         * Buffer shall only be written to by trusted hardware. The definition of trusted hardware
-         * is platform specific, but this flag is reserved to prevent mapping this block into CPU
-         * writable memory resulting in bus fault. This flag can be used when buffer integrity must
-         * be protected.
-         */
-        WRITE_PROTECTED  = 1 << 3,
-    };
-
-    enum : uint64_t {
-        /**
-         * Buffer usage bits reserved for the platform. We don't separately reserve read and
-         * write usages as platforms may have asymmetric distribution between them.
-         */
-        PLATFORM_MASK     = ~(CPU_READ | CPU_WRITE | READ_PROTECTED | WRITE_PROTECTED),
-    };
-
-    /** Create a usage from separate consumer and producer usage mask. \deprecated */
-    inline C2MemoryUsage(uint64_t consumer, uint64_t producer)
-        : expected(consumer | producer) { }
-
-    inline explicit C2MemoryUsage(uint64_t expected_)
-        : expected(expected_) { }
-
-    uint64_t expected; // expected buffer usage
-};
-
-/// @}
-
-#endif  // C2BUFFER_BASE_H_
-
diff --git a/media/libstagefright/codec2/include/C2Component.h b/media/libstagefright/codec2/include/C2Component.h
deleted file mode 100644
index dbcd82d..0000000
--- a/media/libstagefright/codec2/include/C2Component.h
+++ /dev/null
@@ -1,952 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef C2COMPONENT_H_
-
-#define C2COMPONENT_H_
-
-#include <stdbool.h>
-#include <stdint.h>
-
-#include <list>
-#include <memory>
-#include <vector>
-#include <functional>
-
-#include <C2Param.h>
-#include <C2Work.h>
-
-/// \defgroup components Components
-/// @{
-
-struct C2FieldSupportedValuesQuery {
-    enum type_t : uint32_t {
-        POSSIBLE, ///< query all possible values regardless of other settings
-        CURRENT,  ///< query currently possible values given dependent settings
-    };
-
-private:
-    C2ParamField _mField;
-    type_t _mType;
-public:
-    c2_status_t status;
-    C2FieldSupportedValues values;
-
-    C2FieldSupportedValuesQuery(const C2ParamField &field_, type_t type_)
-        : _mField(field_), _mType(type_), status(C2_NO_INIT) { }
-
-    static C2FieldSupportedValuesQuery
-    Current(const C2ParamField &field_) {
-        return C2FieldSupportedValuesQuery(field_, CURRENT);
-    }
-
-    static C2FieldSupportedValuesQuery
-    Possible(const C2ParamField &field_) {
-        return C2FieldSupportedValuesQuery(field_, POSSIBLE);
-    }
-
-    inline C2ParamField field() const { return _mField; };
-
-    inline type_t type() const { return _mType; }
-};
-
-/**
- * Component interface object. This object contains all of the configuration of a potential or
- * actual component. It can be created and used independently of an actual C2Component instance to
- * query support and parameters for various component settings and configurations for a potential
- * component. Actual components also expose this interface.
- */
-
-class C2ComponentInterface {
-public:
-    // ALWAYS AVAILABLE METHODS
-    // =============================================================================================
-
-    /**
-     * Returns the name of this component or component interface object.
-     * This is a unique name for this component or component interface 'class'; however, multiple
-     * instances of this component SHALL have the same name.
-     *
-     * When attached to a component, this method MUST be supported in any component state.
-     * This call does not change the state nor the internal configuration of the component.
-     *
-     * This method MUST be "non-blocking" and return within 1ms.
-     *
-     * \return the name of this component or component interface object.
-     * \retval an empty string if there was not enough memory to allocate the actual name.
-     */
-    virtual C2String getName() const = 0;
-
-    /**
-     * Returns a unique ID for this component or interface object.
-     * This ID is used as work targets, unique work IDs, and when configuring tunneling.
-     *
-     * When attached to a component, this method MUST be supported in any component state.
-     * This call does not change the state nor the internal configuration of the component.
-     *
-     * This method MUST be "non-blocking" and return within 1ms.
-     *
-     * \return a unique node ID for this component or component interface instance.
-     */
-    virtual c2_node_id_t getId() const = 0;
-
-    /**
-     * Queries a set of parameters from the component or interface object.
-     * Querying is performed at best effort: the component SHALL query all supported parameters and
-     * skip unsupported ones, heap allocated parameters that could not be allocated or parameters
-     * that could not be queried without blocking. Any errors are communicated in the return value.
-     * Additionally, preallocated (e.g. stack) parameters that could not be queried are invalidated.
-     * Invalid or blocking parameters to be allocated on the heap are omitted from the result.
-     *
-     * \note Parameter values do not depend on the order of query.
-     *
-     * \todo This method cannot be used to query info-buffers. Is that a problem?
-     *
-     * When attached to a component, this method MUST be supported in any component state except
-     * released.
-     * This call does not change the state nor the internal configuration of the component.
-     *
-     * This method has a variable blocking behavior based on state.
-     * In the stopped state this method MUST be "non-blocking" and return within 1ms.
-     * In the running states this method may be momentarily blocking, but MUST return within 5ms.
-     *
-     * \param[in,out] stackParams  a list of params queried. These are initialized specific to each
-     *                             setting; e.g. size and index are set and rest of the members are
-     *                             cleared.
-     *                             \note Flexible settings that are of incorrect size will be
-     *                             invalidated.
-     * \param[in] heapParamIndices a vector of param indices for params to be queried and returned
-     *                             on the heap. These parameters will be returned in heapParams.
-     *                             Unsupported param indices will be ignored.
-     * \param[in] mayBlock         if true (C2_MAY_BLOCK), implementation may momentarily block.
-     *                             Otherwise (C2_DONT_BLOCK), it must be "non-blocking".
-     * \param[out] heapParams      a list of params where to which the supported heap parameters
-     *                             will be appended in the order they appear in heapParamIndices.
-     *
-     * \retval C2_OK        all parameters could be queried
-     * \retval C2_BAD_INDEX all supported parameters could be queried, but some parameters were not
-     *                      supported
-     * \retval C2_BAD_STATE when called in the released component state (user error)
-     *                      (this error code is only allowed for interfaces connected to components)
-     * \retval C2_NO_MEMORY could not allocate memory for a supported parameter
-     * \retval C2_BLOCKING  the operation must block to complete but mayBlock is false
-     *                      (this error code is only allowed for interfaces connected to components)
-     * \retval C2_TIMED_OUT could not query the parameters within the time limit (unexpected)
-     *                      (this error code is only allowed for interfaces connected to components
-     *                      in the running state)
-     * \retval C2_CORRUPTED some unknown error prevented the querying of the parameters
-     *                      (unexpected)
-     *                      (this error code is only allowed for interfaces connected to components)
-     */
-    virtual c2_status_t query_vb(
-        const std::vector<C2Param*> &stackParams,
-        const std::vector<C2Param::Index> &heapParamIndices,
-        c2_blocking_t mayBlock,
-        std::vector<std::unique_ptr<C2Param>>* const heapParams) const = 0;
-
-    /**
-     * Sets a set of parameters for the component or interface object.
-     *
-     * Tuning is performed at best effort: the component SHALL process the configuration updates in
-     * the order they appear in |params|. If any parameter update fails, the component shall
-     * communicate the failure in the return value and in |failures|, and still process the
-     * remaining parameters. Unsupported parameters are skipped, though they are communicated in
-     * ther return value. Most parameters are updated at best effort - such that even if client
-     * specifies an unsupported value for a field, the closest supported value is used. On the
-     * other hand, strict parameters only accept specific values for their fields, and if the client
-     * specifies an unsupported value, the parameter setting shall fail for that field.
-     * If the client tries to change the value of a field that requires momentary blocking without
-     * setting |mayBlock| to C2_MAY_BLOCK, that parameter shall also be skipped and a specific
-     * return value shall be used. Final values for all parameters set are propagated back to the
-     * caller in |params|.
-     *
-     * \note Parameter tuning DOES depend on the order of the tuning parameters. E.g. some parameter
-     * update may allow some subsequent values for further parameter updates.
-     *
-     * When attached to a component, this method MUST be supported in any component state except
-     * released.
-     *
-     * This method has a variable blocking behavior based on state.
-     * In the stopped state this method MUST be "non-blocking" and return within 1ms.
-     * In the running states this method may be momentarily blocking, but MUST return within 5ms.
-     *
-     * \param[in,out] params a list of parameter updates. These will be updated to the actual
-     *                       parameter values after the updates (this is because tuning is performed
-     *                       at best effort).
-     *                       \todo params that could not be updated are not marked here, so are
-     *                       confusing - are they "existing" values or intended to be configured
-     *                       values?
-     * \param[in] mayBlock   if true (C2_MAY_BLOCK), implementation may momentarily block.
-     *                       Otherwise (C2_DONT_BLOCK), it must be "non-blocking".
-     * \param[out] failures  a list of parameter failures and optional guidance
-     *
-     * \retval C2_OK        all parameters could be updated successfully
-     * \retval C2_BAD_INDEX all supported parameters could be updated successfully, but some
-     *                      parameters were not supported
-     * \retval C2_BAD_VALUE some supported parameters could not be updated successfully because
-     *                      they contained unsupported values. These are returned in |failures|.
-     * \retval C2_BAD_STATE when called in the released component state (user error)
-     *                      (this error code is only allowed for interfaces connected to components)
-     * \retval C2_NO_MEMORY some supported parameters could not be updated successfully because
-     *                      they contained unsupported values, but could not allocate a failure
-     *                      object for them.
-     * \retval C2_TIMED_OUT could not set the parameters within the time limit (unexpected)
-     *                      (this error code is only allowed for interfaces connected to components
-     *                      in the running state)
-     * \retval C2_BLOCKING  the operation must block to complete but mayBlock is false
-     *                      (this error code is only allowed for interfaces connected to components)
-     * \retval C2_CORRUPTED some unknown error prevented the update of the parameters
-     *                      (unexpected)
-     *                      (this error code is only allowed for interfaces connected to components)
-     */
-    virtual c2_status_t config_vb(
-            const std::vector<C2Param*> &params,
-            c2_blocking_t mayBlock,
-            std::vector<std::unique_ptr<C2SettingResult>>* const failures) = 0;
-
-    // TUNNELING
-    // =============================================================================================
-
-    /**
-     * Creates a tunnel from this component to the target component.
-     *
-     * If the component is successfully created, subsequent work items queued may include a
-     * tunneled path between these components.
-     *
-     * When attached to a component, this method MUST be supported in any component state except
-     * released.
-     *
-     * This method may be momentarily blocking, but MUST return within 5ms.
-     *
-     * \retval C2_OK        the tunnel was successfully created
-     * \retval C2_BAD_INDEX the target component does not exist
-     * \retval C2_DUPLICATE the tunnel already exists
-     * \retval C2_OMITTED   tunneling is not supported by this component
-     * \retval C2_CANNOT_DO the specific tunnel is not supported
-     * \retval C2_BAD_STATE when called in the released component state (user error)
-     *                      (this error code is only allowed for interfaces connected to components)
-     *
-     * \retval C2_TIMED_OUT could not create the tunnel within the time limit (unexpected)
-     * \retval C2_CORRUPTED some unknown error prevented the creation of the tunnel (unexpected)
-     *                      (this error code is only allowed for interfaces connected to components)
-     */
-    virtual c2_status_t createTunnel_sm(c2_node_id_t targetComponent) = 0;
-
-    /**
-     * Releases a tunnel from this component to the target component.
-     *
-     * The release of a tunnel is delayed while there are pending work items for the tunnel.
-     * After releasing a tunnel, subsequent work items queued MUST NOT include a tunneled
-     * path between these components.
-     *
-     * When attached to a component, this method MUST be supported in any component state except
-     * released.
-     *
-     * This method may be momentarily blocking, but MUST return within 5ms.
-     *
-     * \retval C2_OK        the tunnel was marked for release successfully
-     * \retval C2_BAD_INDEX the target component does not exist
-     * \retval C2_NOT_FOUND the tunnel does not exist
-     * \retval C2_OMITTED   tunneling is not supported by this component
-     * \retval C2_BAD_STATE when called in the released component state (user error)
-     *                      (this error code is only allowed for interfaces connected to components)
-     *
-     * \retval C2_TIMED_OUT could not mark the tunnel for release within the time limit (unexpected)
-     * \retval C2_CORRUPTED some unknown error prevented the release of the tunnel (unexpected)
-     *                      (this error code is only allowed for interfaces connected to components)
-     */
-    virtual c2_status_t releaseTunnel_sm(c2_node_id_t targetComponent) = 0;
-
-    // REFLECTION MECHANISM (USED FOR EXTENSION)
-    // =============================================================================================
-
-    /**
-     * Returns the set of supported parameters.
-     *
-     * When attached to a component, this method MUST be supported in any component state except
-     * released.
-     *
-     * This method MUST be "non-blocking" and return within 1ms.
-     *
-     * \param[out] params a vector of supported parameters will be appended to this vector.
-     *
-     * \retval C2_OK        the operation completed successfully.
-     * \retval C2_BAD_STATE when called in the released component state (user error)
-     *                      (this error code is only allowed for interfaces connected to components)
-     * \retval C2_NO_MEMORY not enough memory to complete this method.
-     */
-    virtual c2_status_t querySupportedParams_nb(
-            std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const = 0;
-
-    /**
-     * Retrieves the supported values for the queried fields.
-     *
-     * Client SHALL set the parameter-field specifier and the type of supported values query (e.g.
-     * currently supported values, or potential supported values) in fields.
-     * Upon return the component SHALL fill in the supported values for the fields listed as well
-     * as a status for each field. Component shall process all fields queried even if some queries
-     * fail.
-     *
-     * When attached to a component, this method MUST be supported in any component state except
-     * released.
-     *
-     * This method has a variable blocking behavior based on state.
-     * In the stopped state this method MUST be "non-blocking" and return within 1ms.
-     * In the running states this method may be momentarily blocking, but MUST return within 5ms.
-     *
-     * \param[in out] fields a vector of fields descriptor structures.
-     * \param[in] mayBlock   if true (C2_MAY_BLOCK), implementation may momentarily block.
-     *                       Otherwise (C2_DONT_BLOCK), it must be "non-blocking".
-     *
-     * \retval C2_OK        the operation completed successfully.
-     * \retval C2_BAD_STATE when called in the released component state (user error)
-     *                      (this error code is only allowed for interfaces connected to components)
-     * \retval C2_BAD_INDEX at least one field was not recognized as a component field
-     * \retval C2_TIMED_OUT could not query supported values within the time limit (unexpected)
-     *                      (this error code is only allowed for interfaces connected to components
-     *                      in the running state)
-     * \retval C2_BLOCKING  the operation must block to complete but mayBlock is false
-     *                      (this error code is only allowed for interfaces connected to components)
-     * \retval C2_CORRUPTED some unknown error prevented the operation from completing (unexpected)
-     *                      (this error code is only allowed for interfaces connected to components)
-     */
-    virtual c2_status_t querySupportedValues_vb(
-            std::vector<C2FieldSupportedValuesQuery> &fields, c2_blocking_t mayBlock) const = 0;
-
-    virtual ~C2ComponentInterface() = default;
-};
-
-class C2Component {
-public:
-    class Listener {
-    public:
-        virtual void onWorkDone_nb(std::weak_ptr<C2Component> component,
-                                std::list<std::unique_ptr<C2Work>> workItems) = 0;
-
-        virtual void onTripped_nb(std::weak_ptr<C2Component> component,
-                               std::vector<std::shared_ptr<C2SettingResult>> settingResult) = 0;
-
-        virtual void onError_nb(std::weak_ptr<C2Component> component,
-                             uint32_t errorCode) = 0;
-
-        // virtual void onTunnelReleased(<from>, <to>) = 0;
-
-        // virtual void onComponentReleased(<id>) = 0;
-
-        virtual ~Listener() = default;
-    };
-
-    /**
-     * Sets the listener for this component
-     *
-     * This method MUST be supported in all states except released.
-     * The listener can only be set to non-null value in stopped state (that does not include
-     * tripped or error). It can be set to nullptr in both stopped and running states.
-     * Components only use the listener in running state.
-     *
-     * If listener is nullptr, the component SHALL guarantee that no more listener callbacks are
-     * done to the original listener once this method returns. (Any pending listener callbacks will
-     * need to be completed during this call - hence this call may be temporarily blocking.)
-     *
-     * This method has a variable blocking behavior based on state.
-     * In the stopped state this method MUST be "non-blocking" and return within 1ms.
-     * In the running states this method may be momentarily blocking, but MUST return within 5ms.
-     *
-     * Component SHALL handle listener notifications from the same thread (the thread used is
-     * at the component's discretion.)
-     *
-     * \note This could also be accomplished by passing a weak_ptr to a component-specific listener
-     * here and requiring the client to always promote the weak_ptr before any callback. This would
-     * put the burden on the client to clear the listener - wait for its deletion - at which point
-     * it is guaranteed that no more listener callbacks will occur.
-     *
-     * \param[in] listener the component listener object
-     * \param[in] mayBlock if true (C2_MAY_BLOCK), implementation may momentarily block.
-     *                     Otherwise (C2_DONT_BLOCK), it must be "non-blocking".
-     *
-     * \retval C2_BAD_STATE attempting to change the listener in the running state to a non-null
-     *                      value (user error), or called in the released state
-     * \retval C2_BLOCKING  the operation must block to complete but mayBlock is false
-     * \retval C2_OK        listener was updated successfully.
-     */
-    virtual c2_status_t setListener_vb(
-            const std::shared_ptr<Listener> &listener, c2_blocking_t mayBlock) = 0;
-
-    enum domain_t : uint32_t;
-    enum kind_t : uint32_t;
-    typedef uint32_t rank_t;
-
-    /**
-     * Information about a component.
-     */
-    struct Traits {
-    // public:
-        C2String name; ///< name of the component
-        domain_t domain; ///< component domain (e.g. audio or video)
-        kind_t kind; ///< component kind (e.g. encoder, decoder or filter)
-        rank_t rank; ///< rank used to determine component ordering (the lower the sooner)
-        C2String mediaType; ///< media type supported by the component
-
-        /**
-         * name alias(es) for backward compatibility.
-         * \note Multiple components can have the same alias as long as their media-type differs.
-         */
-        std::vector<C2StringLiteral> aliases; ///< name aliases for backward compatibility
-    };
-
-    // METHODS AVAILABLE WHEN RUNNING
-    // =============================================================================================
-
-    /**
-     * Queues up work for the component.
-     *
-     * This method MUST be supported in running (including tripped and error) states.
-     *
-     * This method MUST be "non-blocking" and return within 1 ms
-     *
-     * It is acceptable for this method to return OK and return an error value using the
-     * onWorkDone() callback.
-     *
-     * \retval C2_OK        the work was successfully queued
-     * \retval C2_BAD_INDEX some component(s) in the work do(es) not exist
-     * \retval C2_CANNOT_DO the components are not tunneled
-     * \retval C2_BAD_STATE when called in the stopped or released state (user error)
-     *
-     * \retval C2_NO_MEMORY not enough memory to queue the work
-     * \retval C2_CORRUPTED some unknown error prevented queuing the work (unexpected)
-     */
-    virtual c2_status_t queue_nb(std::list<std::unique_ptr<C2Work>>* const items) = 0;
-
-    /**
-     * Announces a work to be queued later for the component. This reserves a slot for the queue
-     * to ensure correct work ordering even if the work is queued later.
-     *
-     * This method MUST be supported in running (including tripped and error) states.
-     *
-     * This method MUST be "non-blocking" and return within 1 ms
-     *
-     * \retval C2_OK        the work announcement has been successfully recorded
-     * \retval C2_BAD_INDEX some component(s) in the work outline do(es) not exist
-     * \retval C2_CANNOT_DO the componentes are not tunneled
-     * \retval C2_BAD_STATE when called in the stopped or released state (user error)
-     *
-     * \retval C2_NO_MEMORY not enough memory to record the work announcement
-     * \retval C2_CORRUPTED some unknown error prevented recording the announcement (unexpected)
-     *
-     * \todo Can this be rolled into queue_nb?
-     * \todo Expose next work item for each component to detect stalls
-     */
-    virtual c2_status_t announce_nb(const std::vector<C2WorkOutline> &items) = 0;
-
-    enum flush_mode_t : uint32_t {
-        /// flush work from this component only
-        FLUSH_COMPONENT,
-
-        /// flush work from this component and all components connected downstream from it via
-        /// tunneling
-        FLUSH_CHAIN = (1 << 16),
-    };
-
-    /**
-     * Discards and abandons any pending work for the component, and optionally any component
-     * downstream.
-     *
-     * \todo define this: we could flush all work before last item queued for component across all
-     *                    components linked to this; flush only work items that are queued to this
-     *                    component
-     * \todo return work # of last flushed item; or all flushed (but not returned items)
-     * \todo we could make flush take a work item and flush all work before/after that item to allow
-     *       TBD (slicing/seek?)
-     * \todo we could simply take a list of numbers and flush those... this is bad for decoders
-     *       also, what would happen to fine grade references?
-     *
-     * This method MUST be supported in running (including tripped and error) states.
-     *
-     * This method may be momentarily blocking, but must return within 5ms.
-     *
-     * Work that could be immediately abandoned/discarded SHALL be returned in |flushedWork|; this
-     * can be done in an arbitrary order.
-     *
-     * Work that could not be abandoned or discarded immediately SHALL be marked to be
-     * discarded at the earliest opportunity, and SHALL be returned via the onWorkDone() callback.
-     * This shall be completed within 500ms.
-     *
-     * \param mode flush mode
-     *
-     * \retval C2_OK        the component has been successfully flushed
-     * \retval C2_BAD_STATE when called in the stopped or released state (user error)
-     * \retval C2_TIMED_OUT the flush could not be completed within the time limit (unexpected)
-     * \retval C2_CORRUPTED some unknown error prevented flushing from completion (unexpected)
-     */
-    virtual c2_status_t flush_sm(flush_mode_t mode, std::list<std::unique_ptr<C2Work>>* const flushedWork) = 0;
-
-    enum drain_mode_t : uint32_t {
-        /// drain component only and add an "end-of-stream" marker. Component shall process all
-        /// queued work and complete the current stream. If new input is received, it shall start
-        /// a new stream. \todo define what a stream is.
-        DRAIN_COMPONENT_WITH_EOS,
-        /// drain component without setting "end-of-stream" marker. Component shall process all
-        /// queued work but shall expect more work items for the same stream.
-        DRAIN_COMPONENT_NO_EOS = (1 << 0),
-
-        /// marks the last work item with a persistent "end-of-stream" marker that will drain
-        /// downstream components
-        /// \todo this may confuse work-ordering downstream
-        DRAIN_CHAIN = (1 << 16),
-
-        /**
-         * \todo define this; we could place EOS to all upstream components, just this component, or
-         *       all upstream and downstream component.
-         * \todo should EOS carry over to downstream components?
-         */
-    };
-
-    /**
-     * Drains the component, and optionally downstream components. This is a signalling method;
-     * as such it does not wait for any work completion.
-     *
-     * Marks last work item as "drain-till-here", so component is notified not to wait for further
-     * work before it processes work already queued. This method can also used to set the
-     * end-of-stream flag after work has been queued. Client can continue to queue further work
-     * immediately after this method returns.
-     *
-     * This method MUST be supported in running (including tripped) states.
-     *
-     * This method MUST be "non-blocking" and return within 1ms.
-     *
-     * Work that is completed SHALL be returned via the onWorkDone() callback.
-     *
-     * \param mode drain mode
-     *
-     * \retval C2_OK        the drain request has been successfully recorded
-     * \retval C2_BAD_STATE when called in the stopped or released state (user error)
-     * \retval C2_BAD_VALUE the drain mode is not supported by the component
-     *                      \todo define supported modes discovery
-     * \retval C2_TIMED_OUT the flush could not be completed within the time limit (unexpected)
-     * \retval C2_CORRUPTED some unknown error prevented flushing from completion (unexpected)
-     */
-    virtual c2_status_t drain_nb(drain_mode_t mode) = 0;
-
-    // STATE CHANGE METHODS
-    // =============================================================================================
-
-    /**
-     * Starts the component.
-     *
-     * This method MUST be supported in stopped state, as well as during the tripped state.
-     *
-     * If the return value is C2_OK, the component shall be in the running state.
-     * If the return value is C2_BAD_STATE or C2_DUPLICATE, no state change is expected as a
-     * response to this call.
-     * Otherwise, the component shall be in the stopped state.
-     *
-     * \note If a component is in the tripped state and start() is called while the component
-     * configuration still results in a trip, start shall succeed and a new onTripped callback
-     * should be used to communicate the configuration conflict that results in the new trip.
-     *
-     * \todo This method MUST return within 500ms. Seems this should be able to return quickly, as
-     * there are no immediate guarantees. Though there are guarantees for responsiveness immediately
-     * after start returns.
-     *
-     * \retval C2_OK        the component has started (or resumed) successfully
-     * \retval C2_DUPLICATE when called during another start call from another thread
-     * \retval C2_BAD_STATE when called in any state other than the stopped state or tripped state,
-     *                      including when called during another state change call from another
-     *                      thread (user error)
-     * \retval C2_NO_MEMORY not enough memory to start the component
-     * \retval C2_TIMED_OUT the component could not be started within the time limit (unexpected)
-     * \retval C2_CORRUPTED some unknown error prevented starting the component (unexpected)
-     */
-    virtual c2_status_t start() = 0;
-
-    /**
-     * Stops the component.
-     *
-     * This method MUST be supported in running (including tripped) state.
-     *
-     * This method MUST return withing 500ms.
-     *
-     * Upon this call, all pending work SHALL be abandoned and all buffer references SHALL be
-     * released.
-     * If the return value is C2_BAD_STATE or C2_DUPLICATE, no state change is expected as a
-     * response to this call.
-     * For all other return values, the component shall be in the stopped state.
-     *
-     * \todo should this return completed work, since client will just free it? Perhaps just to
-     * verify accounting.
-     *
-     * This does not alter any settings and tunings that may have resulted in a tripped state.
-     * (Is this material given the definition? Perhaps in case we want to start again.)
-     *
-     * \retval C2_OK        the component has started successfully
-     * \retval C2_DUPLICATE when called during another stop call from another thread
-     * \retval C2_BAD_STATE when called in any state other than the running state, including when
-     *                      called during another state change call from another thread (user error)
-     * \retval C2_TIMED_OUT the component could not be stopped within the time limit (unexpected)
-     * \retval C2_CORRUPTED some unknown error prevented stopping the component (unexpected)
-     */
-    virtual c2_status_t stop() = 0;
-
-    /**
-     * Resets the component.
-     *
-     * This method MUST be supported in all (including tripped) states other than released.
-     *
-     * This method MUST be supported during any other blocking call.
-     *
-     * This method MUST return withing 500ms.
-     *
-     * After this call returns all work SHALL be abandoned, all buffer references SHALL be released.
-     * If the return value is C2_BAD_STATE or C2_DUPLICATE, no state change is expected as a
-     * response to this call.
-     * For all other return values, the component shall be in the stopped state.
-     *
-     * \todo should this return completed work, since client will just free it? Also, if it unblocks
-     * a stop, where should completed work be returned?
-     *
-     * This brings settings back to their default - "guaranteeing" no tripped space.
-     *
-     * \todo reclaim support - it seems that since ownership is passed, this will allow reclaiming
-     * stuff.
-     *
-     * \retval C2_OK        the component has been reset
-     * \retval C2_DUPLICATE when called during another reset call from another thread
-     * \retval C2_BAD_STATE when called in the released state
-     * \retval C2_TIMED_OUT the component could not be reset within the time limit (unexpected)
-     * \retval C2_CORRUPTED some unknown error prevented resetting the component (unexpected)
-     */
-    virtual c2_status_t reset() = 0;
-
-    /**
-     * Releases the component.
-     *
-     * This method MUST be supported in stopped state.
-     *
-     * This method MUST return withing 500ms. Upon return all references shall be abandoned.
-     *
-     * \retval C2_OK        the component has been released
-     * \retval C2_DUPLICATE the component is already released
-     * \retval C2_BAD_STATE the component is running
-     * \retval C2_TIMED_OUT the component could not be released within the time limit (unexpected)
-     * \retval C2_CORRUPTED some unknown error prevented releasing the component (unexpected)
-     */
-    virtual c2_status_t release() = 0;
-
-    /**
-     * Returns the interface for this component.
-     *
-     * \return the component interface
-     */
-    virtual std::shared_ptr<C2ComponentInterface> intf() = 0;
-
-    virtual ~C2Component() = default;
-};
-
-class C2FrameInfoParser {
-public:
-    /**
-     * \return the content type supported by this info parser.
-     *
-     * \todo this may be redundant
-     */
-    virtual C2StringLiteral getType() const = 0;
-
-    /**
-     * \return a vector of supported parameter indices parsed by this info parser.
-     *
-     * This method MUST be "non-blocking" and return within 1ms.
-     *
-     * \todo sticky vs. non-sticky params? this may be communicated by param-reflector.
-     */
-    virtual const std::vector<C2Param::Index> getParsedParams() const = 0;
-
-    /**
-     * Resets this info parser. This brings this parser to its initial state after creation.
-     *
-     * This method SHALL return within 5ms.
-     *
-     * \retval C2_OK        the info parser was reset
-     * \retval C2_TIMED_OUT could not reset the parser within the time limit (unexpected)
-     * \retval C2_CORRUPTED some unknown error prevented the resetting of the parser (unexpected)
-     */
-    virtual c2_status_t reset() { return C2_OK; }
-
-    virtual c2_status_t parseFrame(C2FrameData &frame);
-
-    virtual ~C2FrameInfoParser() = default;
-};
-
-class C2AllocatorStore {
-public:
-    typedef C2Allocator::id_t id_t;
-
-    enum : C2Allocator::id_t {
-        DEFAULT_LINEAR,     ///< basic linear allocator type
-        DEFAULT_GRAPHIC,    ///< basic graphic allocator type
-        PLATFORM_START = 0x10,
-        VENDOR_START   = 0x100,
-        BAD_ID         = C2Allocator::BAD_ID, ///< DO NOT USE
-    };
-
-    /**
-     * Returns the unique name of this allocator store.
-     *
-     * This method MUST be "non-blocking" and return within 1ms.
-     *
-     * \return the name of this allocator store.
-     * \retval an empty string if there was not enough memory to allocate the actual name.
-     */
-    virtual C2String getName() const = 0;
-
-    /**
-     * Returns the set of allocators supported by this allocator store.
-     *
-     * This method MUST be "non-blocking" and return within 1ms.
-     *
-     * \retval vector of allocator information (as shared pointers)
-     * \retval an empty vector if there was not enough memory to allocate the whole vector.
-     */
-    virtual std::vector<std::shared_ptr<const C2Allocator::Traits>> listAllocators_nb() const = 0;
-
-    /**
-     * Retrieves/creates a shared allocator object.
-     *
-     * This method MUST be return within 5ms.
-     *
-     * The allocator is created on first use, and the same allocator is returned on subsequent
-     * concurrent uses in the same process. The allocator is freed when it is no longer referenced.
-     *
-     * \param id      the ID of the allocator to create. This is defined by the store, but
-     *                the ID of the default linear and graphic allocators is formalized.
-     * \param allocator shared pointer where the created allocator is stored. Cleared on failure
-     *                  and updated on success.
-     *
-     * \retval C2_OK        the allocator was created successfully
-     * \retval C2_TIMED_OUT could not create the allocator within the time limit (unexpected)
-     * \retval C2_CORRUPTED some unknown error prevented the creation of the allocator (unexpected)
-     *
-     * \retval C2_NOT_FOUND no such allocator
-     * \retval C2_NO_MEMORY not enough memory to create the allocator
-     */
-    virtual c2_status_t fetchAllocator(id_t id, std::shared_ptr<C2Allocator>* const allocator) = 0;
-
-    virtual ~C2AllocatorStore() = default;
-};
-
-class C2ComponentStore {
-public:
-    /**
-     * Returns the name of this component or component interface object.
-     * This is a unique name for this component or component interface 'class'; however, multiple
-     * instances of this component SHALL have the same name.
-     *
-     * This method MUST be supported in any state. This call does not change the state nor the
-     * internal states of the component.
-     *
-     * This method MUST be "non-blocking" and return within 1ms.
-     *
-     * \return the name of this component or component interface object.
-     * \retval an empty string if there was not enough memory to allocate the actual name.
-     */
-    virtual C2String getName() const = 0;
-
-    /**
-     * Creates a component.
-     *
-     * This method SHALL return within 100ms.
-     *
-     * \param name          name of the component to create
-     * \param component     shared pointer where the created component is stored. Cleared on
-     *                      failure and updated on success.
-     *
-     * \retval C2_OK        the component was created successfully
-     * \retval C2_TIMED_OUT could not create the component within the time limit (unexpected)
-     * \retval C2_CORRUPTED some unknown error prevented the creation of the component (unexpected)
-     *
-     * \retval C2_NOT_FOUND no such component
-     * \retval C2_NO_MEMORY not enough memory to create the component
-     */
-    virtual c2_status_t createComponent(
-            C2String name, std::shared_ptr<C2Component>* const component) = 0;
-
-    /**
-     * Creates a component interface.
-     *
-     * This method SHALL return within 100ms.
-     *
-     * \param name          name of the component interface to create
-     * \param interface     shared pointer where the created interface is stored
-     *
-     * \retval C2_OK        the component interface was created successfully
-     * \retval C2_TIMED_OUT could not create the component interface within the time limit
-     *                      (unexpected)
-     * \retval C2_CORRUPTED some unknown error prevented the creation of the component interface
-     *                      (unexpected)
-     *
-     * \retval C2_NOT_FOUND no such component interface
-     * \retval C2_NO_MEMORY not enough memory to create the component interface
-     *
-     * \todo Do we need an interface, or could this just be a component that is never started?
-     */
-    virtual c2_status_t createInterface(
-            C2String name, std::shared_ptr<C2ComponentInterface>* const interface) = 0;
-
-    /**
-     * Returns the list of components supported by this component store.
-     *
-     * This method MUST return within 500ms.
-     *
-     * \retval vector of component information.
-     */
-    virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() = 0;
-
-    // -------------------------------------- UTILITY METHODS --------------------------------------
-
-    // on-demand buffer layout conversion (swizzling)
-    //
-    virtual c2_status_t copyBuffer(
-            std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) = 0;
-
-    // -------------------------------------- CONFIGURATION API -----------------------------------
-    // e.g. for global settings (system-wide stride, etc.)
-
-    /**
-     * Queries a set of system-wide parameters.
-     * Querying is performed at best effort: the store SHALL query all supported parameters and
-     * skip unsupported ones, or heap allocated parameters that could not be allocated. Any errors
-     * are communicated in the return value. Additionally, preallocated (e.g. stack) parameters that
-     * could not be queried are invalidated. Parameters to be allocated on the heap are omitted from
-     * the result.
-     *
-     * \note Parameter values do not depend on the order of query.
-     *
-     * This method may be momentarily blocking, but MUST return within 5ms.
-     *
-     * \param stackParams   a list of params queried. These are initialized specific to each
-     *                      setting; e.g. size and index are set and rest of the members are
-     *                      cleared.
-     *                      NOTE: Flexible settings that are of incorrect size will be invalidated.
-     * \param heapParamIndices a vector of param indices for params to be queried and returned on the
-     *                      heap. These parameters will be returned in heapParams. Unsupported param
-     *                      indices will be ignored.
-     * \param heapParams    a list of params where to which the supported heap parameters will be
-     *                      appended in the order they appear in heapParamIndices.
-     *
-     * \retval C2_OK        all parameters could be queried
-     * \retval C2_BAD_INDEX all supported parameters could be queried, but some parameters were not
-     *                      supported
-     * \retval C2_NO_MEMORY could not allocate memory for a supported parameter
-     * \retval C2_CORRUPTED some unknown error prevented the querying of the parameters
-     *                      (unexpected)
-     */
-    virtual c2_status_t query_sm(
-        const std::vector<C2Param*> &stackParams,
-        const std::vector<C2Param::Index> &heapParamIndices,
-        std::vector<std::unique_ptr<C2Param>>* const heapParams) const = 0;
-
-    /**
-     * Sets a set of system-wide parameters.
-     *
-     * \note There are no settable system-wide parameters defined thus far, but may be added in the
-     * future.
-     *
-     * Tuning is performed at best effort: the store SHALL update all supported configuration at
-     * best effort (unless configured otherwise) and skip unsupported ones. Any errors are
-     * communicated in the return value and in |failures|.
-     *
-     * \note Parameter tuning DOES depend on the order of the tuning parameters. E.g. some parameter
-     * update may allow some subsequent parameter update.
-     *
-     * This method may be momentarily blocking, but MUST return within 5ms.
-     *
-     * \param params        a list of parameter updates. These will be updated to the actual
-     *                      parameter values after the updates (this is because tuning is performed
-     *                      at best effort).
-     *                      \todo params that could not be updated are not marked here, so are
-     *                      confusing - are they "existing" values or intended to be configured
-     *                      values?
-     * \param failures      a list of parameter failures
-     *
-     * \retval C2_OK        all parameters could be updated successfully
-     * \retval C2_BAD_INDEX all supported parameters could be updated successfully, but some
-     *                      parameters were not supported
-     * \retval C2_BAD_VALUE some supported parameters could not be updated successfully because
-     *                      they contained unsupported values. These are returned in |failures|.
-     * \retval C2_NO_MEMORY some supported parameters could not be updated successfully because
-     *                      they contained unsupported values, but could not allocate a failure
-     *                      object for them.
-     * \retval C2_CORRUPTED some unknown error prevented the update of the parameters
-     *                      (unexpected)
-     */
-    virtual c2_status_t config_sm(
-            const std::vector<C2Param*> &params,
-            std::vector<std::unique_ptr<C2SettingResult>>* const failures) = 0;
-
-    // REFLECTION MECHANISM (USED FOR EXTENSION)
-    // =============================================================================================
-
-    /**
-     * Returns the parameter reflector.
-     *
-     * This is used to describe parameter fields. This is shared for all components created by
-     * this component store.
-     *
-     * This method MUST be "non-blocking" and return within 1ms.
-     *
-     * \return a shared parameter reflector object.
-     */
-    virtual std::shared_ptr<C2ParamReflector> getParamReflector() const = 0;
-
-    /**
-     * Returns the set of supported parameters.
-     *
-     * This method MUST be "non-blocking" and return within 1ms.
-     *
-     * \param[out] params a vector of supported parameters will be appended to this vector.
-     *
-     * \retval C2_OK        the operation completed successfully.
-     * \retval C2_NO_MEMORY not enough memory to complete this method.
-     */
-    virtual c2_status_t querySupportedParams_nb(
-            std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const = 0;
-
-    /**
-     * Retrieves the supported values for the queried fields.
-     *
-     * Client SHALL set the parameter-field specifier and the type of supported values query (e.g.
-     * currently supported values, or potential supported values) in fields.
-     * Upon return the store SHALL fill in the supported values for the fields listed as well
-     * as a status for each field. Store shall process all fields queried even if some queries
-     * fail.
-     *
-     * This method may be momentarily blocking, but MUST return within 5ms.
-     *
-     * \param[in out] fields a vector of fields descriptor structures.
-     *
-     * \retval C2_OK        the operation completed successfully.
-     * \retval C2_BAD_INDEX at least one field was not recognized as a component store field
-     */
-    virtual c2_status_t querySupportedValues_sm(
-            std::vector<C2FieldSupportedValuesQuery> &fields) const = 0;
-
-    virtual ~C2ComponentStore() = default;
-};
-
-// ================================================================================================
-
-/// @}
-
-#endif  // C2COMPONENT_H_
diff --git a/media/libstagefright/codec2/include/C2Config.h b/media/libstagefright/codec2/include/C2Config.h
deleted file mode 100644
index 3f149bb..0000000
--- a/media/libstagefright/codec2/include/C2Config.h
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef C2CONFIG_H_
-#define C2CONFIG_H_
-
-#include <C2ParamDef.h>
-
-/// \defgroup config Component configuration
-/// @{
-
-#ifndef DEFINE_C2_ENUM_VALUE_AUTO_HELPER
-#define DEFINE_C2_ENUM_VALUE_AUTO_HELPER(name, type, prefix, ...)
-#define DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER(name, type, names, ...)
-#endif
-
-#define C2ENUM(name, type, ...) \
-enum name : type { __VA_ARGS__ }; \
-DEFINE_C2_ENUM_VALUE_AUTO_HELPER(name, type, NULL, __VA_ARGS__)
-
-#define C2ENUM_CUSTOM_PREFIX(name, type, prefix, ...) \
-enum name : type { __VA_ARGS__ }; \
-DEFINE_C2_ENUM_VALUE_AUTO_HELPER(name, type, prefix, __VA_ARGS__)
-
-#define C2ENUM_CUSTOM_NAMES(name, type, names, ...) \
-enum name : type { __VA_ARGS__ }; \
-DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER(name, type, names, __VA_ARGS__)
-
-enum C2ParamIndexKind : C2Param::type_index_t {
-    /// domain
-    kParamIndexDomain,
-
-    /// configuration descriptors
-    kParamIndexSupportedParams,
-    kParamIndexRequiredParams,
-    kParamIndexReadOnlyParams,
-    kParamIndexRequestedInfos,
-
-    /// latency
-    kParamIndexLatency,
-
-    // generic time behavior
-    kParamIndexTemporal,
-
-    /// port configuration
-    kParamIndexMime,
-    kParamIndexStreamCount,
-    kParamIndexFormat,
-    kParamIndexBlockPools,
-
-    kParamIndexMaxVideoSizeHint,
-    kParamIndexVideoSizeTuning,
-
-    kParamIndexCsd,
-    kParamIndexPictureTypeMask,
-
-    // video info
-
-    kParamIndexStructStart = 0x1,
-    kParamIndexVideoSize,
-
-    kParamIndexParamStart = 0x800,
-};
-
-C2ENUM(C2DomainKind, uint32_t,
-    C2DomainVideo,
-    C2DomainAudio,
-    C2DomainOther = C2DomainAudio + 1
-);
-
-// read-only
-
-typedef C2GlobalParam<C2Info, C2SimpleValueStruct<C2DomainKind>, kParamIndexDomain> C2ComponentDomainInfo;
-// typedef C2GlobalParam<C2Info, C2Uint32Value, kParamIndexDomain> C2ComponentDomainInfo;
-//DESCRIBE_TEMPLATED_C2STRUCT(C2SimpleValueStruct<C2DomainKind>, { C2FIELD(mValue, "value") });
-
-// read-only
-typedef C2GlobalParam<C2Info, C2Uint32Array, kParamIndexSupportedParams> C2SupportedParamsInfo;
-
-/// \todo do we define it as a param?
-// read-only
-typedef C2GlobalParam<C2Info, C2Uint32Array, kParamIndexRequiredParams> C2RequiredParamsInfo;
-
-// read-only
-typedef C2GlobalParam<C2Info, C2Uint32Array, kParamIndexReadOnlyParams> C2ReadOnlyParamsInfo;
-
-// read-only
-typedef C2GlobalParam<C2Info, C2Uint32Array, kParamIndexRequestedInfos> C2RequestedInfosInfo;
-
-// read-only
-//typedef C2GlobalParam<C2Info, C2Uint32Value, kParamIndexRequestedInfos> C2RequestedInfosInfo;
-
-/// latency
-
-typedef C2PortParam<C2Info, C2Uint32Value, kParamIndexLatency> C2PortLatencyInfo;
-
-typedef C2GlobalParam<C2Info, C2Uint32Value, kParamIndexLatency> C2ComponentLatencyInfo;
-
-/// \todo
-typedef C2GlobalParam<C2Info, C2Uint32Value, kParamIndexTemporal> C2ComponentTemporalInfo;
-
-/// port configuration
-
-typedef C2PortParam<C2Tuning, C2StringValue, kParamIndexMime> C2PortMimeConfig;
-
-typedef C2PortParam<C2Tuning, C2Uint32Value, kParamIndexStreamCount> C2PortStreamCountConfig;
-
-typedef C2StreamParam<C2Tuning, C2StringValue, kParamIndexMime> C2StreamMimeConfig;
-
-C2ENUM(C2FormatKind, uint32_t,
-    C2FormatCompressed,
-    C2FormatAudio = 1,
-    C2FormatVideo = 4,
-)
-
-typedef C2StreamParam<C2Tuning, C2Uint32Value, kParamIndexFormat> C2StreamFormatConfig;
-
-typedef C2PortParam<C2Tuning, C2Uint64Array, kParamIndexBlockPools> C2PortBlockPoolsTuning;
-
-typedef C2StreamParam<C2Info, C2BlobValue, kParamIndexCsd> C2StreamCsdInfo;
-
-C2ENUM(C2PictureTypeMask, uint32_t,
-    C2PictureTypeKeyFrame = (1u << 0),
-)
-
-typedef C2StreamParam<C2Info, C2Uint32Value, kParamIndexPictureTypeMask> C2StreamPictureTypeMaskInfo;
-
-/*
-   Component description fields:
-
-// format (video/compressed/audio/other-do we need other?) per stream
-
-// likely some of these are exposed as separate settings:
-
-struct C2BaseTuning {
-    // latency characteristics
-    uint32_t latency;
-    bool temporal;               // seems this only makes sense if latency is 1..., so this could be captured as latency = 0
-    uint32_t delay;
-
-    uint32_t numInputStreams;    // RW? - or suggestion only: RO
-    uint32_t numOutputStreams;   // RW
-                                 //
-    // refs characteristics (per stream?)
-    uint32_t maxInputRefs;       // RO
-    uint32_t maxOutputRefs;      // RO
-    uint32_t maxInputMemory;     // RO - max time refs are held for
-    uint32_t maxOutputMemory;    // RO
-
-    // per stream
-    bool compressed;
-    // format... video/compressed/audio/other?
-    // actual "audio/video" format type
-    uint32_t width/height? is this needed, or just queue...
-    // mime...
-};
-*/
-
-
-
-
-
-
-// overall component
-//   => C: domain: audio or video
-//   => C: kind: decoder, encoder or filter
-//   => "mime" class
-
-//   => C: temporal (bool) => does this depend on ordering?
-//   => I: latency
-//   => I: history max duration...
-//   => I: history max frames kept...
-//   => I: reordering depth
-//   => I: frc (bool) (perhaps ratio?)
-//   => I: current frc
-
-//   - pause
-//   => last frame 'number' processed
-//   => current frame 'number' processed
-//   => invalid settings =>[]
-
-// video decoder configuration:                                 // audio
-//   - encoding                                                 // -encoding
-//   - hint: max width/height                                   // -hint: sample rate, channels
-//   - hint: profile/level                                      // -hint: tools used
-//   - hint: framerate (bitrate?)                               // -hint: bitrate
-//   - default: color space (from container)
-//   - hint: color format                                       // -hint: pcm-encoding
-//   - hint: # of views (e.g. MVC)                              // -hint?: channel groups
-//   - default: HDR static info (from container)                // -hint?: channel mappings
-//   - hint: rotation (e.g. for allocator)
-
-// => # of streams required and their formats? (setting?)
-// => # of streams produced and their formats? (tuning)
-
-// => output
-//   - # of views                                               // -channel groups && channel mappings
-//   - width/height/crop/color format/color space/HDR static info (from buffers)
-//     (as required by the allocator & framework)
-//   - SEI (or equivalent) <= [port]
-//     - CC
-//   - reference info
-
-// video encoder configurations
-//   - encoding                                                 // - encoding
-//   - hint: width/height                                       // - hint: sample rate, channels
-//   - hint: frame rate
-//   - hint: max width/height (? does this differ from width/height?)
-//   - # of input (e.g. MVC)                                    // - hint: # groups and mappings
-//   - # of output (e.g. SVC) => bitrates/width/height/framerates? per stream
-//   - hint: profile/level                                      // - hint: profile/level
-//   - HDR static info + (info: HDR)
-//   - color space
-//   - hint: color format?                                      // - hint: pcm encoding
-//   - SEI
-//     - CC
-//   - reference directive
-//   - hint: bitrate (or quality)                               // - hint: bitrate/quality
-//   - optional: codec-specific parameters                      // - optional: csd
-
-// => output                                                    // => output
-//   - layers per stream?                                       // E-AC3?... DTS?...Dolby-Vision?
-//   - reference info
-
-
-// RM:
-//   - need SPS for full knowledge => component should return max. (component can use less)
-//   - critical parameters? (interlaced? profile? level?)
-
-struct C2VideoSizeStruct {
-    int32_t width;     ///< video width
-    int32_t height;    ///< video height
-
-    DEFINE_AND_DESCRIBE_BASE_C2STRUCT(VideoSize)
-    C2FIELD(width, "width")
-    C2FIELD(height, "height")
-};
-
-// video size for video decoder [OUT]
-typedef C2StreamParam<C2Info, C2VideoSizeStruct, kParamIndexVideoSize> C2VideoSizeStreamInfo;
-
-// max video size for video decoder [IN]
-typedef C2PortParam<C2Setting, C2VideoSizeStruct, kParamIndexMaxVideoSizeHint> C2MaxVideoSizeHintPortSetting;
-
-// video encoder size [IN]
-typedef C2StreamParam<C2Tuning, C2VideoSizeStruct, kParamIndexVideoSizeTuning> C2VideoSizeStreamTuning;
-
-/// @}
-
-#endif
diff --git a/media/libstagefright/codec2/include/C2Param.h b/media/libstagefright/codec2/include/C2Param.h
deleted file mode 100644
index e0a743c..0000000
--- a/media/libstagefright/codec2/include/C2Param.h
+++ /dev/null
@@ -1,1470 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef C2PARAM_H_
-#define C2PARAM_H_
-
-#include <C2.h>
-
-#include <stdbool.h>
-#include <stdint.h>
-
-#include <algorithm>
-#include <string>
-#include <type_traits>
-#include <utility>
-#include <vector>
-
-/// \addtogroup Parameters
-/// @{
-
-/// \defgroup internal Internal helpers.
-
-/*!
- * \file
- * PARAMETERS: SETTINGs, TUNINGs, and INFOs
- * ===
- *
- * These represent miscellaneous control and metadata information and are likely copied into
- * kernel space. Therefore, these are C-like structures designed to carry just a small amount of
- * information. We are using C++ to be able to add constructors, as well as non-virtual and class
- * methods.
- *
- * ==Specification details:
- *
- * Restrictions:
- *   - must be POD struct, e.g. no vtable (no virtual destructor)
- *   - must have the same size in 64-bit and 32-bit mode (no size_t)
- *   - as such, no pointer members
- *   - some common member field names are reserved as they are defined as methods for all
- *     parameters:
- *     they are: size, type, kind, index and stream
- *
- * Behavior:
- * - Params can be global (not related to input or output), related to input or output,
- *   or related to an input/output stream.
- * - All params are queried/set using a unique param index, which incorporates a potential stream
- *   index and/or port.
- * - Querying (supported) params MUST never fail.
- * - All params MUST have default values.
- * - If some fields have "unsupported" or "invalid" values during setting, this SHOULD be
- *   communicated to the app.
- *   a) Ideally, this should be avoided.  When setting parameters, in general, component should do
- *     "best effort" to apply all settings. It should change "invalid/unsupported" values to the
- *     nearest supported values.
- *   - This is communicated to the client by changing the source values in tune()/
- *     configure().
- *   b) If falling back to a supported value is absolutely impossible, the component SHALL return
- *     an error for the specific setting, but should continue to apply other settings.
- *     TODO: this currently may result in unintended results.
- *
- * **NOTE:** unlike OMX, params are not versioned. Instead, a new struct with new param index
- * SHALL be added as new versions are required.
- *
- * The proper subtype (Setting, Info or Param) is incorporated into the class type. Define structs
- * to define multiple subtyped versions of related parameters.
- *
- * ==Implementation details:
- *
- * - Use macros to define parameters
- * - All parameters must have a default constructor
- *   - This is only used for instantiating the class in source (e.g. will not be used
- *     when building a parameter by the framework from key/value pairs.)
- */
-
-/// \ingroup internal
-
-/**
- * Parameter base class.
- */
-struct C2Param {
-    // param index encompasses the following:
-    //
-    // - kind (setting, tuning, info, struct)
-    // - scope
-    //   - direction (global, input, output)
-    //   - stream flag
-    //   - stream ID (usually 0)
-    // - and the parameter's type (core index)
-    //   - flexible parameter flag
-    //   - vendor extension flag
-    //   - type index (this includes the vendor extension flag)
-    //
-    // layout:
-    //
-    //        kind : <------- scope -------> : <----- core index ----->
-    //      +------+-----+---+------+--------+----|------+--------------+
-    //      | kind | dir | - |stream|streamID|flex|vendor|  type index  |
-    //      +------+-----+---+------+--------+----+------+--------------+
-    //  bit: 31..30 29.28       25   24 .. 17  16    15   14    ..     0
-    //
-public:
-    /**
-     * C2Param kinds, usable as bitmaps.
-     */
-    enum kind_t : uint32_t {
-        NONE    = 0,
-        STRUCT  = (1 << 0),
-        INFO    = (1 << 1),
-        SETTING = (1 << 2),
-        TUNING  = (1 << 3) | SETTING, // tunings are settings
-    };
-
-    /**
-     * The parameter type index specifies the underlying parameter type of a parameter as
-     * an integer value.
-     *
-     * Parameter types are divided into two groups: platform types and vendor types.
-     *
-     * Platform types are defined by the platform and are common for all implementations.
-     *
-     * Vendor types are defined by each vendors, so they may differ between implementations.
-     * It is recommended that vendor types be the same for all implementations by a specific
-     * vendor.
-     */
-    typedef uint32_t type_index_t;
-    enum : uint32_t {
-            TYPE_INDEX_VENDOR_START = 0x00008000, ///< vendor indices SHALL start after this
-    };
-
-    /**
-     * Core index is the underlying parameter type for a parameter. It is used to describe the
-     * layout of the parameter structure regardless of the component or parameter kind/scope.
-     *
-     * It is used to identify and distinguish global parameters, and also parameters on a given
-     * port or stream. They must be unique for the set of global parameters, as well as for the
-     * set of parameters on each port or each stream, but the same core index can be used for
-     * parameters on different streams or ports, as well as for global parameters and port/stream
-     * parameters.
-     *
-     * Multiple parameter types can share the same layout.
-     *
-     * \note The layout for all parameters with the same core index across all components must
-     * be identical.
-     */
-    struct CoreIndex {
-    //public:
-        enum : uint32_t {
-            IS_FLEX_FLAG = 0x00010000,
-        };
-
-    protected:
-        enum : uint32_t {
-            KIND_MASK      = 0xC0000000,
-            KIND_STRUCT    = 0x00000000,
-            KIND_TUNING    = 0x40000000,
-            KIND_SETTING   = 0x80000000,
-            KIND_INFO      = 0xC0000000,
-
-            DIR_MASK       = 0x30000000,
-            DIR_GLOBAL     = 0x20000000,
-            DIR_UNDEFINED  = DIR_MASK, // MUST have all bits set
-            DIR_INPUT      = 0x00000000,
-            DIR_OUTPUT     = 0x10000000,
-
-            IS_STREAM_FLAG  = 0x02000000,
-            STREAM_ID_MASK  = 0x01FE0000,
-            STREAM_ID_SHIFT = 17,
-            MAX_STREAM_ID   = STREAM_ID_MASK >> STREAM_ID_SHIFT,
-            STREAM_MASK     = IS_STREAM_FLAG | STREAM_ID_MASK,
-
-            IS_VENDOR_FLAG  = 0x00008000,
-            TYPE_INDEX_MASK = 0x0000FFFF,
-            CORE_MASK       = TYPE_INDEX_MASK | IS_FLEX_FLAG,
-        };
-
-    public:
-        /// constructor/conversion from uint32_t
-        inline CoreIndex(uint32_t index) : mIndex(index) { }
-
-        // no conversion from uint64_t
-        inline CoreIndex(uint64_t index) = delete;
-
-        /// returns true iff this is a vendor extension parameter
-        inline bool isVendor() const { return mIndex & IS_VENDOR_FLAG; }
-
-        /// returns true iff this is a flexible parameter (with variable size)
-        inline bool isFlexible() const { return mIndex & IS_FLEX_FLAG; }
-
-        /// returns the core index
-        /// This is the combination of the parameter type index and the flexible flag.
-        inline uint32_t coreIndex() const { return mIndex & CORE_MASK; }
-
-        /// returns the parameter type index
-        inline type_index_t typeIndex() const { return mIndex & TYPE_INDEX_MASK; }
-
-        DEFINE_FIELD_AND_MASK_BASED_COMPARISON_OPERATORS(CoreIndex, mIndex, CORE_MASK)
-
-    protected:
-        uint32_t mIndex;
-    };
-
-    /**
-     * Type encompasses the parameter's kind (tuning, setting, info), its scope (whether the
-     * parameter is global, input or output, and whether it is for a stream) and the its base
-     * index (which also determines its layout).
-     */
-    struct Type : public CoreIndex {
-    //public:
-        /// returns true iff this is a global parameter (not for input nor output)
-        inline bool isGlobal() const { return (mIndex & DIR_MASK) == DIR_GLOBAL; }
-        /// returns true iff this is an input or input stream parameter
-        inline bool forInput() const { return (mIndex & DIR_MASK) == DIR_INPUT; }
-        /// returns true iff this is an output or output stream parameter
-        inline bool forOutput() const { return (mIndex & DIR_MASK) == DIR_OUTPUT; }
-
-        /// returns true iff this is a stream parameter
-        inline bool forStream() const { return mIndex & IS_STREAM_FLAG; }
-        /// returns true iff this is a port (input or output) parameter
-        inline bool forPort() const   { return !forStream() && !isGlobal(); }
-
-        /// returns the parameter type: the parameter index without the stream ID
-        inline uint32_t type() const { return mIndex & (~STREAM_ID_MASK); }
-
-        /// return the kind (struct, info, setting or tuning) of this param
-        inline kind_t kind() const {
-            switch (mIndex & KIND_MASK) {
-                case KIND_STRUCT: return STRUCT;
-                case KIND_INFO: return INFO;
-                case KIND_SETTING: return SETTING;
-                case KIND_TUNING: return TUNING;
-                default: return NONE; // should not happen
-            }
-        }
-
-        /// constructor/conversion from uint32_t
-        inline Type(uint32_t index) : CoreIndex(index) { }
-
-        // no conversion from uint64_t
-        inline Type(uint64_t index) = delete;
-
-        DEFINE_FIELD_AND_MASK_BASED_COMPARISON_OPERATORS(Type, mIndex, ~STREAM_ID_MASK)
-
-    private:
-        friend struct C2Param;   // for setPort()
-        friend struct C2Tuning;  // for KIND_TUNING
-        friend struct C2Setting; // for KIND_SETTING
-        friend struct C2Info;    // for KIND_INFO
-        // for DIR_GLOBAL
-        template<typename T, typename S, int I, class F> friend struct C2GlobalParam;
-        template<typename T, typename S, int I, class F> friend struct C2PortParam;   // for kDir*
-        template<typename T, typename S, int I, class F> friend struct C2StreamParam; // for kDir*
-        friend struct _C2ParamInspector; // for testing
-
-        /**
-         * Sets the port/stream direction.
-         * @return true on success, false if could not set direction (e.g. it is global param).
-         */
-        inline bool setPort(bool output) {
-            if (isGlobal()) {
-                return false;
-            } else {
-                mIndex = (mIndex & ~DIR_MASK) | (output ? DIR_OUTPUT : DIR_INPUT);
-                return true;
-            }
-        }
-    };
-
-    /**
-     * index encompasses all remaining information: basically the stream ID.
-     */
-    struct Index : public Type {
-        /// returns the index as uint32_t
-        inline operator uint32_t() const { return mIndex; }
-
-        /// constructor/conversion from uint32_t
-        inline Index(uint32_t index) : Type(index) { }
-
-        // no conversion from uint64_t
-        inline Index(uint64_t index) = delete;
-
-        /// returns the stream ID or ~0 if not a stream
-        inline unsigned stream() const {
-            return forStream() ? rawStream() : ~0U;
-        }
-
-        DEFINE_FIELD_BASED_COMPARISON_OPERATORS(Index, mIndex)
-
-    private:
-        friend struct C2Param;           // for setStream, MakeStreamId, isValid
-        friend struct _C2ParamInspector; // for testing
-
-        /**
-         * @return true if the type is valid, e.g. direction is not undefined AND
-         * stream is 0 if not a stream param.
-         */
-        inline bool isValid() const {
-            // there is no Type::isValid (even though some of this check could be
-            // performed on types) as this is only used on index...
-            return (forStream() ? rawStream() < MAX_STREAM_ID : rawStream() == 0)
-                    && (mIndex & DIR_MASK) != DIR_UNDEFINED;
-        }
-
-        /// returns the raw stream ID field
-        inline unsigned rawStream() const {
-            return (mIndex & STREAM_ID_MASK) >> STREAM_ID_SHIFT;
-        }
-
-        /// returns the streamId bitfield for a given |stream|. If stream is invalid,
-        /// returns an invalid bitfield.
-        inline static uint32_t MakeStreamId(unsigned stream) {
-            // saturate stream ID (max value is invalid)
-            if (stream > MAX_STREAM_ID) {
-                stream = MAX_STREAM_ID;
-            }
-            return (stream << STREAM_ID_SHIFT) & STREAM_ID_MASK;
-        }
-
-        /**
-         * Sets the stream index.
-         * \return true on success, false if could not set index (e.g. not a stream param).
-         */
-        inline bool setStream(unsigned stream) {
-            if (forStream()) {
-                mIndex = (mIndex & ~STREAM_ID_MASK) | MakeStreamId(stream);
-                return this->stream() < MAX_STREAM_ID;
-            }
-            return false;
-        }
-    };
-
-public:
-    // public getters for Index methods
-
-    /// returns true iff this is a vendor extension parameter
-    inline bool isVendor() const { return _mIndex.isVendor(); }
-    /// returns true iff this is a flexible parameter
-    inline bool isFlexible() const { return _mIndex.isFlexible(); }
-    /// returns true iff this is a global parameter (not for input nor output)
-    inline bool isGlobal() const { return _mIndex.isGlobal(); }
-    /// returns true iff this is an input or input stream parameter
-    inline bool forInput() const { return _mIndex.forInput(); }
-    /// returns true iff this is an output or output stream parameter
-    inline bool forOutput() const { return _mIndex.forOutput(); }
-
-    /// returns true iff this is a stream parameter
-    inline bool forStream() const { return _mIndex.forStream(); }
-    /// returns true iff this is a port (input or output) parameter
-    inline bool forPort() const   { return _mIndex.forPort(); }
-
-    /// returns the stream ID or ~0 if not a stream
-    inline unsigned stream() const { return _mIndex.stream(); }
-
-    /// returns the parameter type: the parameter index without the stream ID
-    inline Type type() const { return _mIndex.type(); }
-
-    /// returns the index of this parameter
-    /// \todo: should we restrict this to C2ParamField?
-    inline uint32_t index() const { return (uint32_t)_mIndex; }
-
-    /// returns the core index of this parameter
-    inline CoreIndex coreIndex() const { return _mIndex.coreIndex(); }
-
-    /// returns the kind of this parameter
-    inline kind_t kind() const { return _mIndex.kind(); }
-
-    /// returns the size of the parameter or 0 if the parameter is invalid
-    inline size_t size() const { return _mSize; }
-
-    /// returns true iff the parameter is valid
-    inline operator bool() const { return _mIndex.isValid() && _mSize > 0; }
-
-    /// returns true iff the parameter is invalid
-    inline bool operator!() const { return !operator bool(); }
-
-    // equality is done by memcmp (use equals() to prevent any overread)
-    inline bool operator==(const C2Param &o) const {
-        return equals(o) && memcmp(this, &o, _mSize) == 0;
-    }
-    inline bool operator!=(const C2Param &o) const { return !operator==(o); }
-
-    /// safe(r) type cast from pointer and size
-    inline static C2Param* From(void *addr, size_t len) {
-        // _mSize must fit into size, but really C2Param must also to be a valid param
-        if (len < sizeof(C2Param)) {
-            return nullptr;
-        }
-        // _mSize must match length
-        C2Param *param = (C2Param*)addr;
-        if (param->_mSize != len) {
-            return nullptr;
-        }
-        return param;
-    }
-
-    /// Returns managed clone of |orig| at heap.
-    inline static std::unique_ptr<C2Param> Copy(const C2Param &orig) {
-        if (orig.size() == 0) {
-            return nullptr;
-        }
-        void *mem = ::operator new (orig.size());
-        C2Param *param = new (mem) C2Param(orig.size(), orig._mIndex);
-        param->updateFrom(orig);
-        return std::unique_ptr<C2Param>(param);
-    }
-
-#if 0
-    template<typename P, class=decltype(C2Param(P()))>
-    P *As() { return P::From(this); }
-    template<typename P>
-    const P *As() const { return const_cast<const P*>(P::From(const_cast<C2Param*>(this))); }
-#endif
-
-protected:
-    /// sets the stream field. Returns true iff successful.
-    inline bool setStream(unsigned stream) {
-        return _mIndex.setStream(stream);
-    }
-
-    /// sets the port (direction). Returns true iff successful.
-    inline bool setPort(bool output) {
-        return _mIndex.setPort(output);
-    }
-
-public:
-    /// invalidate this parameter. There is no recovery from this call; e.g. parameter
-    /// cannot be 'corrected' to be valid.
-    inline void invalidate() { _mSize = 0; }
-
-    // if other is the same kind of (valid) param as this, copy it into this and return true.
-    // otherwise, do not copy anything, and return false.
-    inline bool updateFrom(const C2Param &other) {
-        if (other._mSize <= _mSize && other._mIndex == _mIndex && _mSize > 0) {
-            memcpy(this, &other, _mSize);
-            return true;
-        }
-        return false;
-    }
-
-protected:
-    // returns |o| if it is a null ptr, or if can suitably be a param of given |type| (e.g. has
-    // same type (ignoring stream ID), and size). Otherwise, returns null. If |checkDir| is false,
-    // allow undefined or different direction (e.g. as constructed from C2PortParam() vs.
-    // C2PortParam::input), but still require equivalent type (stream, port or global); otherwise,
-    // return null.
-    inline static const C2Param* IfSuitable(
-            const C2Param* o, size_t size, Type type, size_t flexSize = 0, bool checkDir = true) {
-        if (o == nullptr || o->_mSize < size || (flexSize && ((o->_mSize - size) % flexSize))) {
-            return nullptr;
-        } else if (checkDir) {
-            return o->_mIndex.type() == type.mIndex ? o : nullptr;
-        } else if (o->_mIndex.isGlobal()) {
-            return nullptr;
-        } else {
-            return ((o->_mIndex.type() ^ type.mIndex) & ~Type::DIR_MASK) ? nullptr : o;
-        }
-    }
-
-    /// base constructor
-    inline C2Param(uint32_t paramSize, Index paramIndex)
-        : _mSize(paramSize),
-          _mIndex(paramIndex) {
-        if (paramSize > sizeof(C2Param)) {
-            memset(this + 1, 0, paramSize - sizeof(C2Param));
-        }
-    }
-
-    /// base constructor with stream set
-    inline C2Param(uint32_t paramSize, Index paramIndex, unsigned stream)
-        : _mSize(paramSize),
-          _mIndex(paramIndex | Index::MakeStreamId(stream)) {
-        if (paramSize > sizeof(C2Param)) {
-            memset(this + 1, 0, paramSize - sizeof(C2Param));
-        }
-        if (!forStream()) {
-            invalidate();
-        }
-    }
-
-private:
-    friend struct _C2ParamInspector; // for testing
-
-    /// returns true iff |o| has the same size and index as this. This performs the
-    /// basic check for equality.
-    inline bool equals(const C2Param &o) const {
-        return _mSize == o._mSize && _mIndex == o._mIndex;
-    }
-
-    uint32_t _mSize;
-    Index _mIndex;
-};
-
-/// \ingroup internal
-/// allow C2Params access to private methods, e.g. constructors
-#define C2PARAM_MAKE_FRIENDS \
-    template<typename U, typename S, int I, class F> friend struct C2GlobalParam; \
-    template<typename U, typename S, int I, class F> friend struct C2PortParam; \
-    template<typename U, typename S, int I, class F> friend struct C2StreamParam; \
-
-/**
- * Setting base structure for component method signatures. Wrap constructors.
- */
-struct C2Setting : public C2Param {
-protected:
-    template<typename ...Args>
-    inline C2Setting(const Args(&... args)) : C2Param(args...) { }
-public: // TODO
-    enum : uint32_t { PARAM_KIND = Type::KIND_SETTING };
-};
-
-/**
- * Tuning base structure for component method signatures. Wrap constructors.
- */
-struct C2Tuning : public C2Setting {
-protected:
-    template<typename ...Args>
-    inline C2Tuning(const Args(&... args)) : C2Setting(args...) { }
-public: // TODO
-    enum : uint32_t { PARAM_KIND = Type::KIND_TUNING };
-};
-
-/**
- * Info base structure for component method signatures. Wrap constructors.
- */
-struct C2Info : public C2Param {
-protected:
-    template<typename ...Args>
-    inline C2Info(const Args(&... args)) : C2Param(args...) { }
-public: // TODO
-    enum : uint32_t { PARAM_KIND = Type::KIND_INFO };
-};
-
-/**
- * Structure uniquely specifying a field in an arbitrary structure.
- *
- * \note This structure is used differently in C2FieldDescriptor to
- * identify array fields, such that _mSize is the size of each element. This is
- * because the field descriptor contains the array-length, and we want to keep
- * a relevant element size for variable length arrays.
- */
-struct _C2FieldId {
-//public:
-    /**
-     * Constructor used for C2FieldDescriptor that removes the array extent.
-     *
-     * \param[in] offset pointer to the field in an object at address 0.
-     */
-    template<typename T, class B=typename std::remove_extent<T>::type>
-    inline _C2FieldId(T* offset)
-        : // offset is from "0" so will fit on 32-bits
-          _mOffset((uint32_t)(uintptr_t)(offset)),
-          _mSize(sizeof(B)) { }
-
-    /**
-     * Direct constructor from offset and size.
-     *
-     * \param[in] offset offset of the field.
-     * \param[in] size size of the field.
-     */
-    inline _C2FieldId(size_t offset, size_t size)
-        : _mOffset(offset), _mSize(size) {}
-
-    /**
-     * Constructor used to identify a field in an object.
-     *
-     * \param U[type] pointer to the object that contains this field. This is needed in case the
-     *        field is in an (inherited) base class, in which case T will be that base class.
-     * \param pm[im] member pointer to the field
-     */
-    template<typename R, typename T, typename U, typename B=typename std::remove_extent<R>::type>
-    inline _C2FieldId(U *, R T::* pm)
-        : _mOffset((uint32_t)(uintptr_t)(&(((U*)256)->*pm)) - 256u),
-          _mSize(sizeof(B)) { }
-
-    /**
-     * Constructor used to identify a field in an object.
-     *
-     * \param pm[im] member pointer to the field
-     */
-    template<typename R, typename T, typename B=typename std::remove_extent<R>::type>
-    inline _C2FieldId(R T::* pm)
-        : _mOffset((uint32_t)(uintptr_t)(&(((T*)0)->*pm))),
-          _mSize(sizeof(B)) { }
-
-    inline bool operator==(const _C2FieldId &other) const {
-        return _mOffset == other._mOffset && _mSize == other._mSize;
-    }
-
-    inline bool operator<(const _C2FieldId &other) const {
-        return _mOffset < other._mOffset ||
-            // NOTE: order parent structure before sub field
-            (_mOffset == other._mOffset && _mSize > other._mSize);
-    }
-
-    DEFINE_OTHER_COMPARISON_OPERATORS(_C2FieldId)
-
-#if 0
-    inline uint32_t offset() const { return _mOffset; }
-    inline uint32_t size() const { return _mSize; }
-#endif
-
-#if defined(FRIEND_TEST)
-    friend void PrintTo(const _C2FieldId &d, ::std::ostream*);
-#endif
-
-private:
-    friend struct _C2ParamInspector;
-
-    uint32_t _mOffset; // offset of field
-    uint32_t _mSize;   // size of field
-};
-
-/**
- * Structure uniquely specifying a 'field' in a configuration. The field
- * can be a field of a configuration, a subfield of a field of a configuration,
- * and even the whole configuration. Moreover, if the field can point to an
- * element in a array field, or to the entire array field.
- *
- * This structure is used for querying supported values for a field, as well
- * as communicating configuration failures and conflicts when trying to change
- * a configuration for a component/interface or a store.
- */
-struct C2ParamField {
-//public:
-    /**
-     * Create a field identifier using a configuration parameter (variable),
-     * and a pointer to member.
-     *
-     * ~~~~~~~~~~~~~ (.cpp)
-     *
-     * struct C2SomeParam {
-     *   uint32_t mField;
-     *   uint32_t mArray[2];
-     *   C2OtherStruct mStruct;
-     *   uint32_t mFlexArray[];
-     * } *mParam;
-     *
-     * C2ParamField(mParam, &mParam->mField);
-     * C2ParamField(mParam, &mParam->mArray);
-     * C2ParamField(mParam, &mParam->mArray[0]);
-     * C2ParamField(mParam, &mParam->mStruct.mSubField);
-     * C2ParamField(mParam, &mParam->mFlexArray);
-     * C2ParamField(mParam, &mParam->mFlexArray[2]);
-     *
-     * ~~~~~~~~~~~~~
-     *
-     * \todo fix what this is for T[] (for now size becomes T[1])
-     *
-     * \param param pointer to parameter
-     * \param offset member pointer
-     */
-    template<typename S, typename T>
-    inline C2ParamField(S* param, T* offset)
-        : _mIndex(param->index()),
-          _mFieldId((T*)((uintptr_t)offset - (uintptr_t)param)) {}
-
-    /**
-     * Create a field identifier using a configuration parameter (variable),
-     * and a member pointer. This method cannot be used to refer to an
-     * array element or a subfield.
-     *
-     * ~~~~~~~~~~~~~ (.cpp)
-     *
-     * C2SomeParam mParam;
-     * C2ParamField(&mParam, &C2SomeParam::mMemberField);
-     *
-     * ~~~~~~~~~~~~~
-     *
-     * \param p pointer to parameter
-     * \param T member pointer to the field member
-     */
-    template<typename R, typename T, typename U>
-    inline C2ParamField(U *p, R T::* pm) : _mIndex(p->index()), _mFieldId(p, pm) { }
-
-    /**
-     * Create a field identifier to a configuration parameter (variable).
-     *
-     * ~~~~~~~~~~~~~ (.cpp)
-     *
-     * C2SomeParam mParam;
-     * C2ParamField(&mParam);
-     *
-     * ~~~~~~~~~~~~~
-     *
-     * \param param pointer to parameter
-     */
-    template<typename S>
-    inline C2ParamField(S* param)
-        : _mIndex(param->index()), _mFieldId(0u, param->size()) { }
-
-    /**
-     * Equality operator.
-     */
-    inline bool operator==(const C2ParamField &other) const {
-        return _mIndex == other._mIndex && _mFieldId == other._mFieldId;
-    }
-
-    /**
-     * Ordering operator.
-     */
-    inline bool operator<(const C2ParamField &other) const {
-        return _mIndex < other._mIndex ||
-            (_mIndex == other._mIndex && _mFieldId < other._mFieldId);
-    }
-
-    DEFINE_OTHER_COMPARISON_OPERATORS(C2ParamField)
-
-protected:
-    inline C2ParamField(C2Param::Index index, uint32_t offset, uint32_t size)
-        : _mIndex(index), _mFieldId(offset, size) {}
-
-private:
-    friend struct _C2ParamInspector;
-
-    C2Param::Index _mIndex; ///< parameter index
-    _C2FieldId _mFieldId;   ///< field identifier
-};
-
-/**
- * A shared (union) representation of numeric values
- */
-class C2Value {
-public:
-    /// A union of supported primitive types.
-    union Primitive {
-        // first member is always zero initialized so it must be the largest
-        uint64_t    u64;   ///< uint64_t value
-        int64_t     i64;   ///< int64_t value
-        c2_cntr64_t c64;   ///< c2_cntr64_t value
-        uint32_t    u32;   ///< uint32_t value
-        int32_t     i32;   ///< int32_t value
-        c2_cntr32_t c32;   ///< c2_cntr32_t value
-        float       fp;    ///< float value
-
-        // constructors - implicit
-        Primitive(uint64_t value)    : u64(value) { }
-        Primitive(int64_t value)     : i64(value) { }
-        Primitive(c2_cntr64_t value) : c64(value) { }
-        Primitive(uint32_t value)    : u32(value) { }
-        Primitive(int32_t value)     : i32(value) { }
-        Primitive(c2_cntr32_t value) : c32(value) { }
-        Primitive(float value)       : fp(value)  { }
-
-        Primitive() : u64(0) { }
-
-        /** gets value out of the union */
-        template<typename T> const T &ref() const;
-    };
-
-    enum type_t : uint32_t {
-        NO_INIT,
-        INT32,
-        UINT32,
-        CNTR32,
-        INT64,
-        UINT64,
-        CNTR64,
-        FLOAT,
-    };
-
-    template<typename T> static constexpr type_t typeFor();
-
-    // constructors - implicit
-    template<typename T>
-    C2Value(T value)  : _mType(typeFor<T>()), _mValue(value) { }
-
-    C2Value() : _mType(NO_INIT) { }
-
-    inline type_t type() const { return _mType; }
-
-    template<typename T>
-    inline bool get(T *value) const {
-        if (_mType == typeFor<T>()) {
-            *value = _mValue.ref<T>();
-            return true;
-        }
-        return false;
-    }
-
-private:
-    type_t _mType;
-    Primitive _mValue;
-};
-
-template<> inline const int32_t &C2Value::Primitive::ref<int32_t>() const { return i32; }
-template<> inline const int64_t &C2Value::Primitive::ref<int64_t>() const { return i64; }
-template<> inline const uint32_t &C2Value::Primitive::ref<uint32_t>() const { return u32; }
-template<> inline const uint64_t &C2Value::Primitive::ref<uint64_t>() const { return u64; }
-template<> inline const c2_cntr32_t &C2Value::Primitive::ref<c2_cntr32_t>() const { return c32; }
-template<> inline const c2_cntr64_t &C2Value::Primitive::ref<c2_cntr64_t>() const { return c64; }
-template<> inline const float &C2Value::Primitive::ref<float>() const { return fp; }
-
-template<> constexpr C2Value::type_t C2Value::typeFor<int32_t>() { return INT32; }
-template<> constexpr C2Value::type_t C2Value::typeFor<int64_t>() { return INT64; }
-template<> constexpr C2Value::type_t C2Value::typeFor<uint32_t>() { return UINT32; }
-template<> constexpr C2Value::type_t C2Value::typeFor<uint64_t>() { return UINT64; }
-template<> constexpr C2Value::type_t C2Value::typeFor<c2_cntr32_t>() { return CNTR32; }
-template<> constexpr C2Value::type_t C2Value::typeFor<c2_cntr64_t>() { return CNTR64; }
-template<> constexpr C2Value::type_t C2Value::typeFor<float>() { return FLOAT; }
-
-/**
- * field descriptor. A field is uniquely defined by an index into a parameter.
- * (Note: Stream-id is not captured as a field.)
- *
- * Ordering of fields is by offset. In case of structures, it is depth first,
- * with a structure taking an index just before and in addition to its members.
- */
-struct C2FieldDescriptor {
-//public:
-    /** field types and flags
-     * \note: only 32-bit and 64-bit fields are supported (e.g. no boolean, as that
-     * is represented using INT32).
-     */
-    enum type_t : uint32_t {
-        // primitive types
-        INT32   = C2Value::INT32,  ///< 32-bit signed integer
-        UINT32  = C2Value::UINT32, ///< 32-bit unsigned integer
-        CNTR32  = C2Value::CNTR32, ///< 32-bit counter
-        INT64   = C2Value::INT64,  ///< 64-bit signed integer
-        UINT64  = C2Value::UINT64, ///< 64-bit signed integer
-        CNTR64  = C2Value::CNTR64, ///< 64-bit counter
-        FLOAT   = C2Value::FLOAT,  ///< 32-bit floating point
-
-        // array types
-        STRING = 0x100, ///< fixed-size string (POD)
-        BLOB,           ///< blob. Blobs have no sub-elements and can be thought of as byte arrays;
-                        ///< however, bytes cannot be individually addressed by clients.
-
-        // complex types
-        STRUCT_FLAG = 0x20000, ///< structs. Marked with this flag in addition to their coreIndex.
-    };
-
-    typedef std::pair<C2String, C2Value::Primitive> NamedValueType;
-    typedef std::vector<const NamedValueType> NamedValuesType;
-    //typedef std::pair<std::vector<C2String>, std::vector<C2Value::Primitive>> NamedValuesType;
-
-    /**
-     * Template specialization that returns the named values for a type.
-     *
-     * \todo hide from client.
-     *
-     * \return a vector of name-value pairs.
-     */
-    template<typename B>
-    static NamedValuesType namedValuesFor(const B &);
-
-    inline C2FieldDescriptor(uint32_t type, uint32_t extent, C2StringLiteral name, size_t offset, size_t size)
-        : _mType((type_t)type), _mExtent(extent), _mName(name), _mFieldId(offset, size) { }
-
-    template<typename T, class B=typename std::remove_extent<T>::type>
-    inline C2FieldDescriptor(const T* offset, const char *name)
-        : _mType(this->GetType((B*)nullptr)),
-          _mExtent(std::is_array<T>::value ? std::extent<T>::value : 1),
-          _mName(name),
-          _mNamedValues(namedValuesFor(*(B*)0)),
-          _mFieldId(offset) {}
-
-/*
-    template<typename T, typename B=typename std::remove_extent<T>::type>
-    inline C2FieldDescriptor<T, B, false>(T* offset, const char *name)
-        : _mType(this->GetType((B*)nullptr)),
-          _mExtent(std::is_array<T>::value ? std::extent<T>::value : 1),
-          _mName(name),
-          _mFieldId(offset) {}
-*/
-
-    /// \deprecated
-    template<typename T, typename S, class B=typename std::remove_extent<T>::type>
-    constexpr inline C2FieldDescriptor(S*, T S::* field, const char *name)
-        : _mType(this->GetType((B*)nullptr)),
-          _mExtent(std::is_array<T>::value ? std::extent<T>::value : 1),
-          _mName(name),
-          _mFieldId(&(((S*)0)->*field)) {}
-
-    /// returns the type of this field
-    inline type_t type() const { return _mType; }
-    /// returns the length of the field in case it is an array. Returns 0 for
-    /// T[] arrays, returns 1 for T[1] arrays as well as if the field is not an array.
-    inline size_t extent() const { return _mExtent; }
-    /// returns the name of the field
-    inline C2StringLiteral name() const { return _mName; }
-
-    const NamedValuesType &namedValues() const { return _mNamedValues; }
-
-#if defined(FRIEND_TEST)
-    friend void PrintTo(const C2FieldDescriptor &, ::std::ostream*);
-    friend bool operator==(const C2FieldDescriptor &, const C2FieldDescriptor &);
-    FRIEND_TEST(C2ParamTest_ParamFieldList, VerifyStruct);
-#endif
-
-private:
-    type_t _mType;
-    uint32_t _mExtent; // the last member can be arbitrary length if it is T[] array,
-                       // extending to the end of the parameter (this is marked with
-                       // 0). T[0]-s are not fields.
-    C2StringLiteral _mName;
-    NamedValuesType _mNamedValues;
-
-    _C2FieldId _mFieldId;   // field identifier (offset and size)
-
-    // NOTE: We do not capture default value(s) here as that may depend on the component.
-    // NOTE: We also do not capture bestEffort, as 1) this should be true for most fields,
-    // 2) this is at parameter granularity.
-
-    // type resolution
-    inline static type_t GetType(int32_t*)     { return INT32; }
-    inline static type_t GetType(uint32_t*)    { return UINT32; }
-    inline static type_t GetType(c2_cntr32_t*) { return CNTR32; }
-    inline static type_t GetType(int64_t*)     { return INT64; }
-    inline static type_t GetType(uint64_t*)    { return UINT64; }
-    inline static type_t GetType(c2_cntr64_t*) { return CNTR64; }
-    inline static type_t GetType(float*)       { return FLOAT; }
-    inline static type_t GetType(char*)        { return STRING; }
-    inline static type_t GetType(uint8_t*)     { return BLOB; }
-
-    template<typename T,
-             class=typename std::enable_if<std::is_enum<T>::value>::type>
-    inline static type_t GetType(T*) {
-        typename std::underlying_type<T>::type underlying(0);
-        return GetType(&underlying);
-    }
-
-    // verify C2Struct by having a FIELD_LIST and a CORE_INDEX.
-    template<typename T,
-             class=decltype(T::CORE_INDEX + 1), class=decltype(T::FIELD_LIST)>
-    inline static type_t GetType(T*) {
-        static_assert(!std::is_base_of<C2Param, T>::value, "cannot use C2Params as fields");
-        return (type_t)(T::CORE_INDEX | STRUCT_FLAG);
-    }
-
-    friend struct _C2ParamInspector;
-};
-
-#define DEFINE_NO_NAMED_VALUES_FOR(type) \
-template<> inline C2FieldDescriptor::NamedValuesType C2FieldDescriptor::namedValuesFor(const type &) { \
-    return NamedValuesType(); \
-}
-
-// We cannot subtype constructor for enumerated types so insted define no named values for
-// non-enumerated integral types.
-DEFINE_NO_NAMED_VALUES_FOR(int32_t)
-DEFINE_NO_NAMED_VALUES_FOR(uint32_t)
-DEFINE_NO_NAMED_VALUES_FOR(c2_cntr32_t)
-DEFINE_NO_NAMED_VALUES_FOR(int64_t)
-DEFINE_NO_NAMED_VALUES_FOR(uint64_t)
-DEFINE_NO_NAMED_VALUES_FOR(c2_cntr64_t)
-DEFINE_NO_NAMED_VALUES_FOR(uint8_t)
-DEFINE_NO_NAMED_VALUES_FOR(char)
-DEFINE_NO_NAMED_VALUES_FOR(float)
-
-/**
- * Describes the fields of a structure.
- */
-struct C2StructDescriptor {
-public:
-    /// Returns the core index of the struct
-    inline C2Param::CoreIndex coreIndex() const { return _mType.coreIndex(); }
-
-    // Returns the number of fields in this struct (not counting any recursive fields).
-    // Must be at least 1 for valid structs.
-    inline size_t numFields() const { return _mFields.size(); }
-
-    // Returns the list of direct fields (not counting any recursive fields).
-    typedef std::vector<const C2FieldDescriptor>::const_iterator field_iterator;
-    inline field_iterator cbegin() const { return _mFields.cbegin(); }
-    inline field_iterator cend() const { return _mFields.cend(); }
-
-    // only supplying const iterator - but these names are needed for range based loops
-    inline field_iterator begin() const { return _mFields.cbegin(); }
-    inline field_iterator end() const { return _mFields.cend(); }
-
-    template<typename T>
-    inline C2StructDescriptor(T*)
-        : C2StructDescriptor(T::CORE_INDEX, T::FIELD_LIST) { }
-
-    inline C2StructDescriptor(
-            C2Param::CoreIndex type,
-            std::initializer_list<const C2FieldDescriptor> fields)
-        : _mType(type), _mFields(fields) { }
-
-private:
-    const C2Param::CoreIndex _mType;
-    const std::vector<const C2FieldDescriptor> _mFields;
-};
-
-/**
- * Describes parameters for a component.
- */
-struct C2ParamDescriptor {
-public:
-    /**
-     * Returns whether setting this param is required to configure this component.
-     * This can only be true for builtin params for platform-defined components (e.g. video and
-     * audio encoders/decoders, video/audio filters).
-     * For vendor-defined components, it can be true even for vendor-defined params,
-     * but it is not recommended, in case the component becomes platform-defined.
-     */
-    inline bool isRequired() const { return _mAttrib & IS_REQUIRED; }
-
-    /**
-     * Returns whether this parameter is persistent. This is always true for C2Tuning and C2Setting,
-     * but may be false for C2Info. If true, this parameter persists across frames and applies to
-     * the current and subsequent frames. If false, this C2Info parameter only applies to the
-     * current frame and is not assumed to have the same value (or even be present) on subsequent
-     * frames, unless it is specified for those frames.
-     */
-    inline bool isPersistent() const { return _mAttrib & IS_PERSISTENT; }
-
-    inline bool isStrict() const { return _mAttrib & IS_STRICT; }
-
-    inline bool isReadOnly() const { return _mAttrib & IS_READ_ONLY; }
-
-    inline bool isVisible() const { return !(_mAttrib & IS_HIDDEN); }
-
-    inline bool isPublic() const { return !(_mAttrib & IS_INTERNAL); }
-
-    /// Returns the name of this param.
-    /// This defaults to the underlying C2Struct's name, but could be altered for a component.
-    inline C2String name() const { return _mName; }
-
-    /// Returns the parameter index
-    inline C2Param::Index index() const { return _mIndex; }
-
-    /// Returns the indices of parameters that this parameter has a dependency on
-    inline const std::vector<C2Param::Index> &dependencies() const { return _mDependencies; }
-
-    /// \deprecated
-    template<typename T>
-    inline C2ParamDescriptor(bool isRequired, C2StringLiteral name, const T*)
-        : _mIndex(T::PARAM_TYPE),
-          _mAttrib(IS_PERSISTENT | (isRequired ? IS_REQUIRED : 0)),
-          _mName(name) { }
-
-    /// \deprecated
-    inline C2ParamDescriptor(
-            bool isRequired, C2StringLiteral name, C2Param::Index index)
-        : _mIndex(index),
-          _mAttrib(IS_PERSISTENT | (isRequired ? IS_REQUIRED : 0)),
-          _mName(name) { }
-
-    enum attrib_t : uint32_t {
-        // flags that default on
-        IS_REQUIRED   = 1u << 0, ///< parameter is required to be specified
-        IS_PERSISTENT = 1u << 1, ///< parameter retains its value
-        // flags that default off
-        IS_STRICT     = 1u << 2, ///< parameter is strict
-        IS_READ_ONLY  = 1u << 3, ///< parameter is publicly read-only
-        IS_HIDDEN     = 1u << 4, ///< parameter shall not be visible to clients
-        IS_INTERNAL   = 1u << 5, ///< parameter shall not be used by framework (other than testing)
-    };
-
-    inline C2ParamDescriptor(
-        C2Param::Index index, attrib_t attrib, C2StringLiteral name)
-        : _mIndex(index),
-          _mAttrib(attrib),
-          _mName(name) { }
-
-    inline C2ParamDescriptor(
-        C2Param::Index index, attrib_t attrib, C2String &&name,
-        std::vector<C2Param::Index> &&dependencies)
-        : _mIndex(index),
-          _mAttrib(attrib),
-          _mName(name),
-          _mDependencies(std::move(dependencies)) { }
-
-private:
-    const C2Param::Index _mIndex;
-    const uint32_t _mAttrib;
-    const C2String _mName;
-    std::vector<C2Param::Index> _mDependencies;
-
-    friend struct _C2ParamInspector;
-};
-
-/// \ingroup internal
-/// Define a structure without CORE_INDEX.
-#define DEFINE_BASE_C2STRUCT(name) \
-public: \
-    typedef C2##name##Struct _type; /**< type name shorthand */ \
-    const static std::initializer_list<const C2FieldDescriptor> FIELD_LIST; /**< structure fields */
-
-/// Define a structure with matching CORE_INDEX.
-#define DEFINE_C2STRUCT(name) \
-public: \
-    enum : uint32_t { CORE_INDEX = kParamIndex##name }; \
-    DEFINE_BASE_C2STRUCT(name)
-
-/// Define a flexible structure without CORE_INDEX.
-#define DEFINE_BASE_FLEX_C2STRUCT(name, flexMember) \
-public: \
-    FLEX(C2##name##Struct, flexMember) \
-    DEFINE_BASE_C2STRUCT(name)
-
-/// Define a flexible structure with matching CORE_INDEX.
-#define DEFINE_FLEX_C2STRUCT(name, flexMember) \
-public: \
-    FLEX(C2##name##Struct, flexMember) \
-    enum : uint32_t { CORE_INDEX = kParamIndex##name | C2Param::CoreIndex::IS_FLEX_FLAG }; \
-    DEFINE_BASE_C2STRUCT(name)
-
-#ifdef __C2_GENERATE_GLOBAL_VARS__
-/// \ingroup internal
-/// Describe a structure of a templated structure.
-#define DESCRIBE_TEMPLATED_C2STRUCT(strukt, list) \
-    template<> \
-    const std::initializer_list<const C2FieldDescriptor> strukt::FIELD_LIST = list;
-
-/// \deprecated
-/// Describe the fields of a structure using an initializer list.
-#define DESCRIBE_C2STRUCT(name, list) \
-    const std::initializer_list<const C2FieldDescriptor> C2##name##Struct::FIELD_LIST = list;
-#else
-/// \if 0
-#define DESCRIBE_TEMPLATED_C2STRUCT(strukt, list)
-#define DESCRIBE_C2STRUCT(name, list)
-/// \endif
-#endif
-
-/**
- * Describe a field of a structure.
- * These must be in order.
- *
- * There are two ways to use this macro:
- *
- *  ~~~~~~~~~~~~~ (.cpp)
- *  struct C2VideoWidthStruct {
- *      int32_t width;
- *      C2VideoWidthStruct() {} // optional default constructor
- *      C2VideoWidthStruct(int32_t _width) : width(_width) {}
- *
- *      DEFINE_AND_DESCRIBE_C2STRUCT(VideoWidth)
- *      C2FIELD(width, "width")
- *  };
- *  ~~~~~~~~~~~~~
- *
- *  ~~~~~~~~~~~~~ (.cpp)
- *  struct C2VideoWidthStruct {
- *      int32_t width;
- *      C2VideoWidthStruct() = default; // optional default constructor
- *      C2VideoWidthStruct(int32_t _width) : width(_width) {}
- *
- *      DEFINE_C2STRUCT(VideoWidth)
- *  } C2_PACK;
- *
- *  DESCRIBE_C2STRUCT(VideoWidth, {
- *      C2FIELD(width, "width")
- *  })
- *  ~~~~~~~~~~~~~
- *
- *  For flexible structures (those ending in T[]), use the flexible macros:
- *
- *  ~~~~~~~~~~~~~ (.cpp)
- *  struct C2VideoFlexWidthsStruct {
- *      int32_t widths[];
- *      C2VideoFlexWidthsStruct(); // must have a default constructor
- *
- *  private:
- *      // may have private constructors taking number of widths as the first argument
- *      // This is used by the C2Param factory methods, e.g.
- *      //   C2VideoFlexWidthsGlobalParam::AllocUnique(size_t, int32_t);
- *      C2VideoFlexWidthsStruct(size_t flexCount, int32_t value) {
- *          for (size_t i = 0; i < flexCount; ++i) {
- *              widths[i] = value;
- *          }
- *      }
- *
- *      // If the last argument is T[N] or std::initializer_list<T>, the flexCount will
- *      // be automatically calculated and passed by the C2Param factory methods, e.g.
- *      //   int widths[] = { 1, 2, 3 };
- *      //   C2VideoFlexWidthsGlobalParam::AllocUnique(widths);
- *      template<unsigned N>
- *      C2VideoFlexWidthsStruct(size_t flexCount, const int32_t(&init)[N]) {
- *          for (size_t i = 0; i < flexCount; ++i) {
- *              widths[i] = init[i];
- *          }
- *      }
- *
- *      DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(VideoFlexWidths, widths)
- *      C2FIELD(widths, "widths")
- *  };
- *  ~~~~~~~~~~~~~
- *
- *  ~~~~~~~~~~~~~ (.cpp)
- *  struct C2VideoFlexWidthsStruct {
- *      int32_t mWidths[];
- *      C2VideoFlexWidthsStruct(); // must have a default constructor
- *
- *      DEFINE_FLEX_C2STRUCT(VideoFlexWidths, mWidths)
- *  } C2_PACK;
- *
- *  DESCRIBE_C2STRUCT(VideoFlexWidths, {
- *      C2FIELD(mWidths, "widths")
- *  })
- *  ~~~~~~~~~~~~~
- *
- */
-#ifdef __C2_GENERATE_GLOBAL_VARS__
-#define C2FIELD(member, name) \
-  C2FieldDescriptor(&((_type*)(nullptr))->member, name),
-
-/// \deprecated
-#define C2SOLE_FIELD(member, name) \
-  C2FieldDescriptor(&_type::member, name, 0)
-
-/// Define a structure with matching CORE_INDEX and start describing its fields.
-/// This must be at the end of the structure definition.
-#define DEFINE_AND_DESCRIBE_C2STRUCT(name) \
-    DEFINE_C2STRUCT(name) } C2_PACK; \
-    const std::initializer_list<const C2FieldDescriptor> C2##name##Struct::FIELD_LIST = {
-
-/// Define a flexible structure with matching CORE_INDEX and start describing its fields.
-/// This must be at the end of the structure definition.
-#define DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(name, flexMember) \
-    DEFINE_FLEX_C2STRUCT(name, flexMember) } C2_PACK; \
-    const std::initializer_list<const C2FieldDescriptor> C2##name##Struct::FIELD_LIST = {
-
-/// Define a base structure (with no CORE_INDEX) and start describing its fields.
-/// This must be at the end of the structure definition.
-#define DEFINE_AND_DESCRIBE_BASE_C2STRUCT(name) \
-    DEFINE_BASE_C2STRUCT(name) } C2_PACK; \
-    const std::initializer_list<const C2FieldDescriptor> C2##name##Struct::FIELD_LIST = {
-
-/// Define a flexible base structure (with no CORE_INDEX) and start describing its fields.
-/// This must be at the end of the structure definition.
-#define DEFINE_AND_DESCRIBE_BASE_FLEX_C2STRUCT(name, flexMember) \
-    DEFINE_BASE_FLEX_C2STRUCT(name, flexMember) } C2_PACK; \
-    const std::initializer_list<const C2FieldDescriptor> C2##name##Struct::FIELD_LIST = {
-
-#else
-/// \if 0
-/* Alternate declaration of field definitions in case no field list is to be generated.
-   TRICKY: use namespace declaration to handle closing bracket that is normally after
-   these macros. */
-#define C2FIELD(member, name)
-/// \deprecated
-#define C2SOLE_FIELD(member, name)
-/// Define a structure with matching CORE_INDEX and start describing its fields.
-/// This must be at the end of the structure definition.
-#define DEFINE_AND_DESCRIBE_C2STRUCT(name) \
-    DEFINE_C2STRUCT(name) }  C2_PACK; namespace ignored {
-/// Define a flexible structure with matching CORE_INDEX and start describing its fields.
-/// This must be at the end of the structure definition.
-#define DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(name, flexMember) \
-    DEFINE_FLEX_C2STRUCT(name, flexMember) } C2_PACK; namespace ignored {
-/// Define a base structure (with no CORE_INDEX) and start describing its fields.
-/// This must be at the end of the structure definition.
-#define DEFINE_AND_DESCRIBE_BASE_C2STRUCT(name) \
-    DEFINE_BASE_C2STRUCT(name) } C2_PACK; namespace ignored {
-/// Define a flexible base structure (with no CORE_INDEX) and start describing its fields.
-/// This must be at the end of the structure definition.
-#define DEFINE_AND_DESCRIBE_BASE_FLEX_C2STRUCT(name, flexMember) \
-    DEFINE_BASE_FLEX_C2STRUCT(name, flexMember) } C2_PACK; namespace ignored {
-/// \endif
-#endif
-
-/**
- * Parameter reflector class.
- *
- * This class centralizes the description of parameter structures. This can be shared
- * by multiple components as describing a parameter does not imply support of that
- * parameter. However, each supported parameter and any dependent structures within
- * must be described by the parameter reflector provided by a component.
- */
-class C2ParamReflector {
-public:
-    /**
-     *  Describes a parameter structure.
-     *
-     *  \param[in] coreIndex the core index of the parameter structure containing at least the
-     *  core index
-     *
-     *  \return the description of the parameter structure
-     *  \retval nullptr if the parameter is not supported by this reflector
-     *
-     *  This methods shall not block and return immediately.
-     *
-     *  \note this class does not take a set of indices because we would then prefer
-     *  to also return any dependent structures, and we don't want this logic to be
-     *  repeated in each reflector. Alternately, this could just return a map of all
-     *  descriptions, but we want to conserve memory if client only wants the description
-     *  of a few indices.
-     */
-    virtual std::unique_ptr<C2StructDescriptor> describe(C2Param::CoreIndex coreIndex) const = 0;
-
-protected:
-    virtual ~C2ParamReflector() = default;
-};
-
-/**
- * Generic supported values for a field.
- *
- * This can be either a range or a set of values. The range can be a simple range, an arithmetic,
- * geometric or multiply-accumulate series with a clear minimum and maximum value. Values can
- * be discrete values, or can optionally represent flags to be or-ed.
- *
- * \note Do not use flags to represent bitfields. Use individual values or separate fields instead.
- */
-struct C2FieldSupportedValues {
-//public:
-    enum type_t {
-        EMPTY,      ///< no supported values
-        RANGE,      ///< a numeric range that can be continuous or discrete
-        VALUES,     ///< a list of values
-        FLAGS       ///< a list of flags that can be OR-ed
-    };
-
-    type_t type; /** Type of values for this field. */
-
-    typedef C2Value::Primitive Primitive;
-
-    /**
-     * Range specifier for supported value. Used if type is RANGE.
-     *
-     * If step is 0 and num and denom are both 1, the supported values are any value, for which
-     * min <= value <= max.
-     *
-     * Otherwise, the range represents a geometric/arithmetic/multiply-accumulate series, where
-     * successive supported values can be derived from previous values (starting at min), using the
-     * following formula:
-     *  v[0] = min
-     *  v[i] = v[i-1] * num / denom + step for i >= 1, while min < v[i] <= max.
-     */
-    struct {
-        /** Lower end of the range (inclusive). */
-        Primitive min;
-        /** Upper end of the range (inclusive if permitted by series). */
-        Primitive max;
-        /** Step between supported values. */
-        Primitive step;
-        /** Numerator of a geometric series. */
-        Primitive num;
-        /** Denominator of a geometric series. */
-        Primitive denom;
-    } range;
-
-    /**
-     * List of values. Used if type is VALUES or FLAGS.
-     *
-     * If type is VALUES, this is the list of supported values in decreasing preference.
-     *
-     * If type is FLAGS, this vector contains { min-mask, flag1, flag2... }. Basically, the first
-     * value is the required set of flags to be set, and the rest of the values are flags that can
-     * be set independently. FLAGS is only supported for integral types. Supported flags should
-     * not overlap, as it can make validation non-deterministic. The standard validation method
-     * is that starting from the original value, if each flag is removed when fully present (the
-     * min-mask must be fully present), we shall arrive at 0.
-     */
-    std::vector<Primitive> values;
-
-    C2FieldSupportedValues()
-        : type(EMPTY) {
-    }
-
-    template<typename T>
-    C2FieldSupportedValues(T min, T max, T step = T(std::is_floating_point<T>::value ? 0 : 1))
-        : type(RANGE),
-          range{min, max, step, (T)1, (T)1} { }
-
-    template<typename T>
-    C2FieldSupportedValues(T min, T max, T num, T den) :
-        type(RANGE),
-        range{min, max, (T)0, num, den} { }
-
-    template<typename T>
-    C2FieldSupportedValues(T min, T max, T step, T num, T den)
-        : type(RANGE),
-          range{min, max, step, num, den} { }
-
-    /// \deprecated
-    template<typename T>
-    C2FieldSupportedValues(bool flags, std::initializer_list<T> list)
-        : type(flags ? FLAGS : VALUES),
-          range{(T)0, (T)0, (T)0, (T)0, (T)0} {
-        for (T value : list) {
-            values.emplace_back(value);
-        }
-    }
-
-    /// \deprecated
-    template<typename T>
-    C2FieldSupportedValues(bool flags, const std::vector<T>& list)
-        : type(flags ? FLAGS : VALUES),
-          range{(T)0, (T)0, (T)0, (T)0, (T)0} {
-        for(T value : list) {
-            values.emplace_back(value);
-        }
-    }
-
-    /// \internal
-    /// \todo: create separate values vs. flags initializer as for flags we want
-    /// to list both allowed and required flags
-    template<typename T, typename E=decltype(C2FieldDescriptor::namedValuesFor(*(T*)0))>
-    C2FieldSupportedValues(bool flags, const T*)
-        : type(flags ? FLAGS : VALUES),
-          range{(T)0, (T)0, (T)0, (T)0, (T)0} {
-              C2FieldDescriptor::NamedValuesType named = C2FieldDescriptor::namedValuesFor(*(T*)0);
-        if (flags) {
-            values.emplace_back(0); // min-mask defaults to 0
-        }
-        for (const C2FieldDescriptor::NamedValueType &item : named){
-            values.emplace_back(item.second);
-        }
-    }
-};
-
-/**
- * Supported values for a specific field.
- *
- * This is a pair of the field specifier together with an optional supported values object.
- * This structure is used when reporting parameter configuration failures and conflicts.
- */
-struct C2ParamFieldValues {
-    C2ParamField paramOrField; ///< the field or parameter
-    /// optional supported values for the field if paramOrField specifies an actual field that is
-    /// numeric (non struct, blob or string). Supported values for arrays (including string and
-    /// blobs) describe the supported values for each element (character for string, and bytes for
-    /// blobs). It is optional for read-only strings and blobs.
-    std::unique_ptr<C2FieldSupportedValues> values;
-
-    // This struct is meant to be move constructed.
-    C2_DEFAULT_MOVE(C2ParamFieldValues);
-
-    // Copy constructor/assignment is also provided as this object may get copied.
-    C2ParamFieldValues(const C2ParamFieldValues &other)
-        : paramOrField(other.paramOrField),
-          values(other.values ? std::make_unique<C2FieldSupportedValues>(*other.values) : nullptr) { }
-
-    C2ParamFieldValues& operator=(const C2ParamFieldValues &other) {
-        paramOrField = other.paramOrField;
-        values = other.values ? std::make_unique<C2FieldSupportedValues>(*other.values) : nullptr;
-        return *this;
-    }
-
-
-    /**
-     * Construct with no values.
-     */
-    C2ParamFieldValues(const C2ParamField &paramOrField_)
-        : paramOrField(paramOrField_) { }
-
-    /**
-     * Construct with values.
-     */
-    C2ParamFieldValues(const C2ParamField &paramOrField_, const C2FieldSupportedValues &values_)
-        : paramOrField(paramOrField_),
-          values(std::make_unique<C2FieldSupportedValues>(values_)) { }
-
-    /**
-     * Construct from fields.
-     */
-    C2ParamFieldValues(const C2ParamField &paramOrField_, std::unique_ptr<C2FieldSupportedValues> &&values_)
-        : paramOrField(paramOrField_),
-          values(std::move(values_)) { }
-};
-
-/// @}
-
-#endif  // C2PARAM_H_
diff --git a/media/libstagefright/codec2/include/C2ParamDef.h b/media/libstagefright/codec2/include/C2ParamDef.h
deleted file mode 100644
index 86c6833..0000000
--- a/media/libstagefright/codec2/include/C2ParamDef.h
+++ /dev/null
@@ -1,906 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/** \file
- * Templates used to declare parameters.
- */
-#ifndef C2PARAM_DEF_H_
-#define C2PARAM_DEF_H_
-
-#include <type_traits>
-
-#include <C2Param.h>
-
-/// \addtogroup Parameters
-/// @{
-
-/* ======================== UTILITY TEMPLATES FOR PARAMETER DEFINITIONS ======================== */
-
-/// \addtogroup internal
-/// @{
-
-/// Helper class that checks if a type has equality and inequality operators.
-struct C2_HIDE _C2Comparable_impl
-{
-    template<typename S, typename=decltype(S() == S())>
-    static std::true_type TestEqual(int);
-    template<typename>
-    static std::false_type TestEqual(...);
-
-    template<typename S, typename=decltype(S() != S())>
-    static std::true_type TestNotEqual(int);
-    template<typename>
-    static std::false_type TestNotEqual(...);
-};
-
-/**
- * Helper template that returns if a type has equality and inequality operators.
- *
- * Use as _C2Comparable<typename S>::value.
- */
-template<typename S>
-struct C2_HIDE _C2Comparable
-    : public std::integral_constant<bool, decltype(_C2Comparable_impl::TestEqual<S>(0))::value
-                        || decltype(_C2Comparable_impl::TestNotEqual<S>(0))::value> {
-};
-
-///  Helper class that checks if a type has a CORE_INDEX constant.
-struct C2_HIDE _C2CoreIndexHelper_impl
-{
-    template<typename S, int=S::CORE_INDEX>
-    static std::true_type TestCoreIndex(int);
-    template<typename>
-    static std::false_type TestCoreIndex(...);
-};
-
-/// Helper template that verifies a type's CORE_INDEX and creates it if the type does not have one.
-template<typename S, int CoreIndex,
-        bool HasBase=decltype(_C2CoreIndexHelper_impl::TestCoreIndex<S>(0))::value>
-struct C2_HIDE _C2CoreIndexOverride {
-    // TODO: what if we allow structs without CORE_INDEX?
-    static_assert(CoreIndex == S::CORE_INDEX, "CORE_INDEX differs from structure");
-};
-
-/// Specialization for types without a CORE_INDEX.
-template<typename S, int CoreIndex>
-struct C2_HIDE _C2CoreIndexOverride<S, CoreIndex, false> {
-public:
-    enum : uint32_t {
-        CORE_INDEX = CoreIndex, ///< CORE_INDEX override.
-    };
-};
-
-/// Helper template that adds a CORE_INDEX to a type if it does not have one.
-template<typename S, int CoreIndex>
-struct C2_HIDE _C2AddCoreIndex : public S, public _C2CoreIndexOverride<S, CoreIndex> {};
-
-/**
- * \brief Helper class to check struct requirements for parameters.
- *
- * Features:
- *  - verify default constructor, no virtual methods, and no equality operators.
- *  - expose PARAM_TYPE, and non-flex FLEX_SIZE.
- */
-template<typename S, int CoreIndex, unsigned TypeFlags>
-struct C2_HIDE _C2StructCheck {
-    static_assert(
-            std::is_default_constructible<S>::value, "C2 structure must have default constructor");
-    static_assert(!std::is_polymorphic<S>::value, "C2 structure must not have virtual methods");
-    static_assert(!_C2Comparable<S>::value, "C2 structure must not have operator== or !=");
-
-public:
-    enum : uint32_t {
-        PARAM_TYPE = CoreIndex | TypeFlags
-    };
-
-protected:
-    enum : uint32_t {
-        FLEX_SIZE = 0, // TODO: is this still needed? this may be confusing.
-    };
-};
-
-/// Helper class that checks if a type has an integer FLEX_SIZE member.
-struct C2_HIDE _C2Flexible_impl {
-    /// specialization for types that have a FLEX_SIZE member
-    template<typename S, unsigned=S::FLEX_SIZE>
-    static std::true_type TestFlexSize(int);
-    template<typename>
-    static std::false_type TestFlexSize(...);
-};
-
-/// Helper template that returns if a type has an integer FLEX_SIZE member.
-template<typename S>
-struct C2_HIDE _C2Flexible
-    : public std::integral_constant<bool, decltype(_C2Flexible_impl::TestFlexSize<S>(0))::value> {
-};
-
-/// Macro to test if a type is flexible (has a FLEX_SIZE member).
-#define IF_FLEXIBLE(S) ENABLE_IF(_C2Flexible<S>::value)
-/// Shorthand for std::enable_if
-#define ENABLE_IF(cond) typename std::enable_if<cond>::type
-
-/// Helper template that exposes the flexible subtype of a struct.
-template<typename S, typename E=void>
-struct C2_HIDE _C2FlexHelper {
-    typedef void FlexType;
-    enum : uint32_t { FLEX_SIZE = 0 };
-};
-
-/// Specialization for flexible types.
-template<typename S>
-struct C2_HIDE _C2FlexHelper<S,
-        typename std::enable_if<!std::is_void<typename S::flexMemberType>::value>::type> {
-    typedef typename _C2FlexHelper<typename S::flexMemberType>::FlexType FlexType;
-    enum : uint32_t { FLEX_SIZE = _C2FlexHelper<typename S::flexMemberType>::FLEX_SIZE };
-};
-
-/// Specialization for flex arrays.
-template<typename S>
-struct C2_HIDE _C2FlexHelper<S[],
-        typename std::enable_if<std::is_void<typename _C2FlexHelper<S>::FlexType>::value>::type> {
-    typedef S FlexType;
-    enum : uint32_t { FLEX_SIZE = sizeof(S) };
-};
-
-/**
- * \brief Helper class to check flexible struct requirements and add common operations.
- *
- * Features:
- *  - expose CORE_INDEX and FIELD_LIST (this is normally inherited from the struct, but flexible
- *    structs cannot be base classes and thus inherited from)
- *  - disable copy assignment and construction (TODO: this is already done in the FLEX macro for the
- *    flexible struct, so may not be needed here)
- */
-template<typename S, int ParamIndex, unsigned TypeFlags>
-struct C2_HIDE _C2FlexStructCheck :
-// add flexible flag as _C2StructCheck defines PARAM_TYPE
-        public _C2StructCheck<S, ParamIndex | C2Param::CoreIndex::IS_FLEX_FLAG, TypeFlags> {
-public:
-    enum : uint32_t {
-        /// \hideinitializer
-        CORE_INDEX = ParamIndex | C2Param::CoreIndex::IS_FLEX_FLAG, ///< flexible struct core-index
-    };
-
-    const static std::initializer_list<const C2FieldDescriptor> FIELD_LIST; // TODO assign here
-
-    // default constructor needed because of the disabled copy constructor
-    inline _C2FlexStructCheck() = default;
-
-protected:
-    // cannot copy flexible params
-    _C2FlexStructCheck(const _C2FlexStructCheck<S, ParamIndex, TypeFlags> &) = delete;
-    _C2FlexStructCheck& operator= (const _C2FlexStructCheck<S, ParamIndex, TypeFlags> &) = delete;
-
-    // constants used for helper methods
-    enum : uint32_t {
-        /// \hideinitializer
-        FLEX_SIZE = _C2FlexHelper<S>::FLEX_SIZE, ///< size of flexible type
-        /// \hideinitializer
-        MAX_SIZE = (uint32_t)std::min((size_t)UINT32_MAX, SIZE_MAX), // TODO: is this always u32 max?
-        /// \hideinitializer
-        BASE_SIZE = sizeof(S) + sizeof(C2Param), ///< size of the base param
-    };
-
-    /// returns the allocated size of this param with flexCount, or 0 if it would overflow.
-    inline static size_t CalcSize(size_t flexCount, size_t size = BASE_SIZE) {
-        if (flexCount <= (MAX_SIZE - size) / S::FLEX_SIZE) {
-            return size + S::FLEX_SIZE * flexCount;
-        }
-        return 0;
-    }
-
-    /// dynamic new operator usable for params of type S
-    inline void* operator new(size_t size, size_t flexCount) noexcept {
-        // TODO: assert(size == BASE_SIZE);
-        size = CalcSize(flexCount, size);
-        if (size > 0) {
-            return ::operator new(size);
-        }
-        return nullptr;
-    }
-};
-
-// TODO: this probably does not work.
-/// Expose FIELD_LIST from subClass;
-template<typename S, int ParamIndex, unsigned TypeFlags>
-const std::initializer_list<const C2FieldDescriptor>
-_C2FlexStructCheck<S, ParamIndex, TypeFlags>::FIELD_LIST = S::FIELD_LIST;
-
-/// Define From() cast operators for params.
-#define DEFINE_CAST_OPERATORS(_Type) \
-    inline static _Type* From(C2Param *other) { \
-        return (_Type*)C2Param::IfSuitable( \
-                other, sizeof(_Type), _Type::PARAM_TYPE, _Type::FLEX_SIZE, \
-                (_Type::PARAM_TYPE & T::Index::DIR_UNDEFINED) != T::Index::DIR_UNDEFINED); \
-    } \
-    inline static const _Type* From(const C2Param *other) { \
-        return const_cast<const _Type*>(From(const_cast<C2Param *>(other))); \
-    } \
-    inline static _Type* From(std::nullptr_t) { return nullptr; } \
-
-/**
- * Define flexible allocators (AllocShared or AllocUnique) for flexible params.
- *  - P::AllocXyz(flexCount, args...): allocate for given flex-count.
- *  - P::AllocXyz(args..., T[]): allocate for size of (and with) init array.
- *  - P::AllocXyz(T[]): allocate for size of (and with) init array with no other args.
- *  - P::AllocXyz(args..., std::initializer_list<T>): allocate for size of (and with) initializer
- *    list.
- */
-#define DEFINE_FLEXIBLE_ALLOC(_Type, S, ptr, Ptr) \
-    template<typename ...Args> \
-    inline static std::ptr##_ptr<_Type> Alloc##Ptr(size_t flexCount, const Args(&... args)) { \
-        return std::ptr##_ptr<_Type>(new(flexCount) _Type(flexCount, args...)); \
-    } \
-    /* NOTE: unfortunately this is not supported by clang yet */ \
-    template<typename ...Args, typename U=typename S::FlexType, unsigned N> \
-    inline static std::ptr##_ptr<_Type> Alloc##Ptr(const Args(&... args), const U(&init)[N]) { \
-        return std::ptr##_ptr<_Type>(new(N) _Type(N, args..., init)); \
-    } \
-    /* so for now, specialize for no args */ \
-    template<typename U=typename S::FlexType, unsigned N> \
-    inline static std::ptr##_ptr<_Type> Alloc##Ptr(const U(&init)[N]) { \
-        return std::ptr##_ptr<_Type>(new(N) _Type(N, init)); \
-    } \
-    template<typename ...Args, typename U=typename S::FlexType> \
-    inline static std::ptr##_ptr<_Type> Alloc##Ptr( \
-            const Args(&... args), const std::initializer_list<U> &init) { \
-        return std::ptr##_ptr<_Type>(new(init.size()) _Type(init.size(), args..., init)); \
-    } \
-
-/**
- * Define flexible methods AllocShared, AllocUnique and flexCount.
- */
-#define DEFINE_FLEXIBLE_METHODS(_Type, S) \
-    DEFINE_FLEXIBLE_ALLOC(_Type, S, shared, Shared) \
-    DEFINE_FLEXIBLE_ALLOC(_Type, S, unique, Unique) \
-    inline size_t flexCount() const { \
-        static_assert(sizeof(_Type) == _Type::BASE_SIZE, "incorrect BASE_SIZE"); \
-        size_t sz = this->size(); \
-        if (sz >= sizeof(_Type)) { \
-            return (sz - sizeof(_Type)) / _Type::FLEX_SIZE; \
-        } \
-        return 0; \
-    } \
-
-/// Mark flexible member variable and make structure flexible.
-#define FLEX(cls, m) \
-    C2_DO_NOT_COPY(cls) \
-private: \
-    C2PARAM_MAKE_FRIENDS \
-    /* default constructor with flexCount */ \
-    inline cls(size_t) : cls() {} \
-    /** \if 0 */ \
-    template<typename, typename> friend struct _C2FlexHelper; \
-    typedef decltype(m) flexMemberType; \
-public: \
-    /* constexpr static flexMemberType cls::* flexMember = &cls::m; */ \
-    typedef typename _C2FlexHelper<flexMemberType>::FlexType FlexType; \
-    static_assert(\
-            !std::is_void<FlexType>::value, \
-            "member is not flexible, or a flexible array of a flexible type"); \
-    enum : uint32_t { FLEX_SIZE = _C2FlexHelper<flexMemberType>::FLEX_SIZE }; \
-    /** \endif */ \
-
-/// @}
-
-/**
- * Global-parameter template.
- *
- * Base template to define a global setting/tuning or info based on a structure and
- * an optional ParamIndex. Global parameters are not tied to a port (input or output).
- *
- * Parameters wrap structures by prepending a (parameter) header. The fields of the wrapped
- * structure can be accessed directly, and constructors and potential public methods are also
- * wrapped.
- *
- * \tparam T param type C2Setting, C2Tuning or C2Info
- * \tparam S wrapped structure
- * \tparam ParamIndex optional parameter index override. Must be specified for base/reused
- * structures.
- */
-template<typename T, typename S, int ParamIndex=S::CORE_INDEX, class Flex=void>
-struct C2_HIDE C2GlobalParam : public T, public S, public _C2CoreIndexOverride<S, ParamIndex>,
-        public _C2StructCheck<S, ParamIndex, T::PARAM_KIND | T::Type::DIR_GLOBAL> {
-private:
-    typedef C2GlobalParam<T, S, ParamIndex> _Type;
-
-public:
-    /// Wrapper around base structure's constructor.
-    template<typename ...Args>
-    inline C2GlobalParam(const Args(&... args)) : T(sizeof(_Type), _Type::PARAM_TYPE), S(args...) { }
-
-    DEFINE_CAST_OPERATORS(_Type)
-};
-
-/**
- * Global-parameter template for flexible structures.
- *
- * Base template to define a global setting/tuning or info based on a flexible structure and
- * an optional ParamIndex. Global parameters are not tied to a port (input or output).
- *
- * \tparam T param type C2Setting, C2Tuning or C2Info
- * \tparam S wrapped flexible structure
- * \tparam ParamIndex optional parameter index override. Must be specified for base/reused
- *         structures.
- *
- * Parameters wrap structures by prepending a (parameter) header. The fields and methods of flexible
- * structures can be accessed via the m member variable; however, the constructors of the structure
- * are wrapped directly. (This is because flexible types cannot be subclassed.)
- */
-template<typename T, typename S, int ParamIndex>
-struct C2_HIDE C2GlobalParam<T, S, ParamIndex, IF_FLEXIBLE(S)>
-    : public T, public _C2FlexStructCheck<S, ParamIndex, T::PARAM_KIND | T::Type::DIR_GLOBAL> {
-private:
-    typedef C2GlobalParam<T, S, ParamIndex> _Type;
-
-    /// Wrapper around base structure's constructor.
-    template<typename ...Args>
-    inline C2GlobalParam(size_t flexCount, const Args(&... args))
-        : T(_Type::CalcSize(flexCount), _Type::PARAM_TYPE), m(flexCount, args...) { }
-
-public:
-    S m; ///< wrapped flexible structure
-
-    DEFINE_FLEXIBLE_METHODS(_Type, S)
-    DEFINE_CAST_OPERATORS(_Type)
-};
-
-/**
- * Port-parameter template.
- *
- * Base template to define a port setting/tuning or info based on a structure and
- * an optional ParamIndex. Port parameters are tied to a port (input or output), but not to a
- * specific stream.
- *
- * \tparam T param type C2Setting, C2Tuning or C2Info
- * \tparam S wrapped structure
- * \tparam ParamIndex optional parameter index override. Must be specified for base/reused
- *         structures.
- *
- * Parameters wrap structures by prepending a (parameter) header. The fields of the wrapped
- * structure can be accessed directly, and constructors and potential public methods are also
- * wrapped.
- *
- * There are 3 flavors of port parameters: unspecified, input and output. Parameters with
- * unspecified port expose a setPort method, and add an initial port parameter to the constructor.
- */
-template<typename T, typename S, int ParamIndex=S::CORE_INDEX, class Flex=void>
-struct C2_HIDE C2PortParam : public T, public S, public _C2CoreIndexOverride<S, ParamIndex>,
-        private _C2StructCheck<S, ParamIndex, T::PARAM_KIND | T::Index::DIR_UNDEFINED> {
-private:
-    typedef C2PortParam<T, S, ParamIndex> _Type;
-
-public:
-    /// Default constructor.
-    inline C2PortParam() : T(sizeof(_Type), _Type::PARAM_TYPE) { }
-    template<typename ...Args>
-    /// Wrapper around base structure's constructor while specifying port/direction.
-    inline C2PortParam(bool _output, const Args(&... args))
-        : T(sizeof(_Type), _output ? output::PARAM_TYPE : input::PARAM_TYPE), S(args...) { }
-    /// Set port/direction.
-    inline void setPort(bool output) { C2Param::setPort(output); }
-
-    DEFINE_CAST_OPERATORS(_Type)
-
-    /// Specialization for an input port parameter.
-    struct input : public T, public S, public _C2CoreIndexOverride<S, ParamIndex>,
-            public _C2StructCheck<S, ParamIndex, T::PARAM_KIND | T::Index::DIR_INPUT> {
-        /// Wrapper around base structure's constructor.
-        template<typename ...Args>
-        inline input(const Args(&... args)) : T(sizeof(_Type), input::PARAM_TYPE), S(args...) { }
-
-        DEFINE_CAST_OPERATORS(input)
-
-    };
-
-    /// Specialization for an output port parameter.
-    struct output : public T, public S, public _C2CoreIndexOverride<S, ParamIndex>,
-            public _C2StructCheck<S, ParamIndex, T::PARAM_KIND | T::Index::DIR_OUTPUT> {
-        /// Wrapper around base structure's constructor.
-        template<typename ...Args>
-        inline output(const Args(&... args)) : T(sizeof(_Type), output::PARAM_TYPE), S(args...) { }
-
-        DEFINE_CAST_OPERATORS(output)
-    };
-};
-
-/**
- * Port-parameter template for flexible structures.
- *
- * Base template to define a port setting/tuning or info based on a flexible structure and
- * an optional ParamIndex. Port parameters are tied to a port (input or output), but not to a
- * specific stream.
- *
- * \tparam T param type C2Setting, C2Tuning or C2Info
- * \tparam S wrapped flexible structure
- * \tparam ParamIndex optional parameter index override. Must be specified for base/reused
- *         structures.
- *
- * Parameters wrap structures by prepending a (parameter) header. The fields and methods of flexible
- * structures can be accessed via the m member variable; however, the constructors of the structure
- * are wrapped directly. (This is because flexible types cannot be subclassed.)
- *
- * There are 3 flavors of port parameters: unspecified, input and output. Parameters with
- * unspecified port expose a setPort method, and add an initial port parameter to the constructor.
- */
-template<typename T, typename S, int ParamIndex>
-struct C2_HIDE C2PortParam<T, S, ParamIndex, IF_FLEXIBLE(S)>
-    : public T, public _C2FlexStructCheck<S, ParamIndex, T::PARAM_KIND | T::Type::DIR_UNDEFINED> {
-private:
-    typedef C2PortParam<T, S, ParamIndex> _Type;
-
-    /// Default constructor for basic allocation: new(flexCount) P.
-    inline C2PortParam(size_t flexCount) : T(_Type::CalcSize(flexCount), _Type::PARAM_TYPE) { }
-    template<typename ...Args>
-    /// Wrapper around base structure's constructor while also specifying port/direction.
-    inline C2PortParam(size_t flexCount, bool _output, const Args(&... args))
-        : T(_Type::CalcSize(flexCount), _output ? output::PARAM_TYPE : input::PARAM_TYPE),
-          m(flexCount, args...) { }
-
-public:
-    /// Set port/direction.
-    inline void setPort(bool output) { C2Param::setPort(output); }
-
-    S m; ///< wrapped flexible structure
-
-    DEFINE_FLEXIBLE_METHODS(_Type, S)
-    DEFINE_CAST_OPERATORS(_Type)
-
-    /// Specialization for an input port parameter.
-    struct input : public T,
-            public _C2FlexStructCheck<S, ParamIndex, T::PARAM_KIND | T::Index::DIR_INPUT> {
-    private:
-        /// Wrapper around base structure's constructor while also specifying port/direction.
-        template<typename ...Args>
-        inline input(size_t flexCount, const Args(&... args))
-            : T(_Type::CalcSize(flexCount), input::PARAM_TYPE), m(flexCount, args...) { }
-
-    public:
-        S m; ///< wrapped flexible structure
-
-        DEFINE_FLEXIBLE_METHODS(input, S)
-        DEFINE_CAST_OPERATORS(input)
-    };
-
-    /// Specialization for an output port parameter.
-    struct output : public T,
-            public _C2FlexStructCheck<S, ParamIndex, T::PARAM_KIND | T::Index::DIR_OUTPUT> {
-    private:
-        /// Wrapper around base structure's constructor while also specifying port/direction.
-        template<typename ...Args>
-        inline output(size_t flexCount, const Args(&... args))
-            : T(_Type::CalcSize(flexCount), output::PARAM_TYPE), m(flexCount, args...) { }
-
-    public:
-        S m; ///< wrapped flexible structure
-
-        DEFINE_FLEXIBLE_METHODS(output, S)
-        DEFINE_CAST_OPERATORS(output)
-    };
-};
-
-/**
- * Stream-parameter template.
- *
- * Base template to define a stream setting/tuning or info based on a structure and
- * an optional ParamIndex. Stream parameters are tied to a specific stream on a port (input or
- * output).
- *
- * \tparam T param type C2Setting, C2Tuning or C2Info
- * \tparam S wrapped structure
- * \tparam ParamIndex optional paramter index override. Must be specified for base/reused
- *         structures.
- *
- * Parameters wrap structures by prepending a (parameter) header. The fields of the wrapped
- * structure can be accessed directly, and constructors and potential public methods are also
- * wrapped.
- *
- * There are 3 flavors of stream parameters: unspecified port, input and output. All of these expose
- * a setStream method and an extra initial streamID parameter for the constructor. Moreover,
- * parameters with unspecified port expose a setPort method, and add an additional initial port
- * parameter to the constructor.
- */
-template<typename T, typename S, int ParamIndex=S::CORE_INDEX, class Flex=void>
-struct C2_HIDE C2StreamParam : public T, public S, public _C2CoreIndexOverride<S, ParamIndex>,
-        private _C2StructCheck<S, ParamIndex,
-                T::PARAM_KIND | T::Index::IS_STREAM_FLAG | T::Index::DIR_UNDEFINED> {
-private:
-    typedef C2StreamParam<T, S, ParamIndex> _Type;
-
-public:
-    /// Default constructor. Port/direction and stream-ID is undefined.
-    inline C2StreamParam() : T(sizeof(_Type), _Type::PARAM_TYPE) { }
-    /// Wrapper around base structure's constructor while also specifying port/direction and
-    /// stream-ID.
-    template<typename ...Args>
-    inline C2StreamParam(bool _output, unsigned stream, const Args(&... args))
-        : T(sizeof(_Type), _output ? output::PARAM_TYPE : input::PARAM_TYPE, stream),
-          S(args...) { }
-    /// Set port/direction.
-    inline void setPort(bool output) { C2Param::setPort(output); }
-    /// Set stream-id. \retval true if the stream-id was successfully set.
-    inline bool setStream(unsigned stream) { return C2Param::setStream(stream); }
-
-    DEFINE_CAST_OPERATORS(_Type)
-
-    /// Specialization for an input stream parameter.
-    struct input : public T, public S, public _C2CoreIndexOverride<S, ParamIndex>,
-            public _C2StructCheck<S, ParamIndex,
-                    T::PARAM_KIND | T::Index::IS_STREAM_FLAG | T::Type::DIR_INPUT> {
-        /// Default constructor. Stream-ID is undefined.
-        inline input() : T(sizeof(_Type), input::PARAM_TYPE) { }
-        /// Wrapper around base structure's constructor while also specifying stream-ID.
-        template<typename ...Args>
-        inline input(unsigned stream, const Args(&... args))
-            : T(sizeof(_Type), input::PARAM_TYPE, stream), S(args...) { }
-        /// Set stream-id. \retval true if the stream-id was successfully set.
-        inline bool setStream(unsigned stream) { return C2Param::setStream(stream); }
-
-        DEFINE_CAST_OPERATORS(input)
-    };
-
-    /// Specialization for an output stream parameter.
-    struct output : public T, public S, public _C2CoreIndexOverride<S, ParamIndex>,
-            public _C2StructCheck<S, ParamIndex,
-                    T::PARAM_KIND | T::Index::IS_STREAM_FLAG | T::Type::DIR_OUTPUT> {
-        /// Default constructor. Stream-ID is undefined.
-        inline output() : T(sizeof(_Type), output::PARAM_TYPE) { }
-        /// Wrapper around base structure's constructor while also specifying stream-ID.
-        template<typename ...Args>
-        inline output(unsigned stream, const Args(&... args))
-            : T(sizeof(_Type), output::PARAM_TYPE, stream), S(args...) { }
-        /// Set stream-id. \retval true if the stream-id was successfully set.
-        inline bool setStream(unsigned stream) { return C2Param::setStream(stream); }
-
-        DEFINE_CAST_OPERATORS(output)
-    };
-};
-
-/**
- * Stream-parameter template for flexible structures.
- *
- * Base template to define a stream setting/tuning or info based on a flexible structure and
- * an optional ParamIndex. Stream parameters are tied to a specific stream on a port (input or
- * output).
- *
- * \tparam T param type C2Setting, C2Tuning or C2Info
- * \tparam S wrapped flexible structure
- * \tparam ParamIndex optional parameter index override. Must be specified for base/reused
- *         structures.
- *
- * Parameters wrap structures by prepending a (parameter) header. The fields and methods of flexible
- * structures can be accessed via the m member variable; however, the constructors of the structure
- * are wrapped directly. (This is because flexible types cannot be subclassed.)
- *
- * There are 3 flavors of stream parameters: unspecified port, input and output. All of these expose
- * a setStream method and an extra initial streamID parameter for the constructor. Moreover,
- * parameters with unspecified port expose a setPort method, and add an additional initial port
- * parameter to the constructor.
- */
-template<typename T, typename S, int ParamIndex>
-struct C2_HIDE C2StreamParam<T, S, ParamIndex, IF_FLEXIBLE(S)>
-    : public T,
-      public _C2FlexStructCheck<S, ParamIndex,
-              T::PARAM_KIND | T::Index::IS_STREAM_FLAG | T::Index::DIR_UNDEFINED> {
-private:
-    typedef C2StreamParam<T, S, ParamIndex> _Type;
-    /// Default constructor. Port/direction and stream-ID is undefined.
-    inline C2StreamParam(size_t flexCount) : T(_Type::CalcSize(flexCount), _Type::PARAM_TYPE, 0u) { }
-    /// Wrapper around base structure's constructor while also specifying port/direction and
-    /// stream-ID.
-    template<typename ...Args>
-    inline C2StreamParam(size_t flexCount, bool _output, unsigned stream, const Args(&... args))
-        : T(_Type::CalcSize(flexCount), _output ? output::PARAM_TYPE : input::PARAM_TYPE, stream),
-          m(flexCount, args...) { }
-
-public:
-    S m; ///< wrapped flexible structure
-
-    /// Set port/direction.
-    inline void setPort(bool output) { C2Param::setPort(output); }
-    /// Set stream-id. \retval true if the stream-id was successfully set.
-    inline bool setStream(unsigned stream) { return C2Param::setStream(stream); }
-
-    DEFINE_FLEXIBLE_METHODS(_Type, S)
-    DEFINE_CAST_OPERATORS(_Type)
-
-    /// Specialization for an input stream parameter.
-    struct input : public T,
-            public _C2FlexStructCheck<S, ParamIndex,
-                    T::PARAM_KIND | T::Index::IS_STREAM_FLAG | T::Type::DIR_INPUT> {
-    private:
-        /// Default constructor. Stream-ID is undefined.
-        inline input(size_t flexCount) : T(_Type::CalcSize(flexCount), input::PARAM_TYPE) { }
-        /// Wrapper around base structure's constructor while also specifying stream-ID.
-        template<typename ...Args>
-        inline input(size_t flexCount, unsigned stream, const Args(&... args))
-            : T(_Type::CalcSize(flexCount), input::PARAM_TYPE, stream), m(flexCount, args...) { }
-
-    public:
-        S m; ///< wrapped flexible structure
-
-        /// Set stream-id. \retval true if the stream-id was successfully set.
-        inline bool setStream(unsigned stream) { return C2Param::setStream(stream); }
-
-        DEFINE_FLEXIBLE_METHODS(input, S)
-        DEFINE_CAST_OPERATORS(input)
-    };
-
-    /// Specialization for an output stream parameter.
-    struct output : public T,
-            public _C2FlexStructCheck<S, ParamIndex,
-                    T::PARAM_KIND | T::Index::IS_STREAM_FLAG | T::Type::DIR_OUTPUT> {
-    private:
-        /// Default constructor. Stream-ID is undefined.
-        inline output(size_t flexCount) : T(_Type::CalcSize(flexCount), output::PARAM_TYPE) { }
-        /// Wrapper around base structure's constructor while also specifying stream-ID.
-        template<typename ...Args>
-        inline output(size_t flexCount, unsigned stream, const Args(&... args))
-            : T(_Type::CalcSize(flexCount), output::PARAM_TYPE, stream), m(flexCount, args...) { }
-
-    public:
-        S m; ///< wrapped flexible structure
-
-        /// Set stream-id. \retval true if the stream-id was successfully set.
-        inline bool setStream(unsigned stream) { return C2Param::setStream(stream); }
-
-        DEFINE_FLEXIBLE_METHODS(output, S)
-        DEFINE_CAST_OPERATORS(output)
-    };
-};
-
-/* ======================== SIMPLE VALUE PARAMETERS ======================== */
-
-/**
- * \ingroup internal
- * A structure template encapsulating a single element with default constructors and no core-index.
- */
-template<typename T>
-struct C2SimpleValueStruct {
-    T value; ///< simple value of the structure
-    // Default constructor.
-    inline C2SimpleValueStruct() = default;
-    // Constructor with an initial value.
-    inline C2SimpleValueStruct(T value) : value(value) {}
-    DEFINE_BASE_C2STRUCT(SimpleValue)
-};
-
-// TODO: move this and next to some generic place
-/**
- * Interface to a block of (mapped) memory containing an array of some type (T).
- */
-template<typename T>
-struct C2MemoryBlock {
-    /// \returns the number of elements in this block.
-    virtual size_t size() const = 0;
-    /// \returns a const pointer to the start of this block. Care must be taken to not read outside
-    /// the block.
-    virtual const T *data() const = 0; // TODO: should this be friend access only in some C2Memory module?
-    /// \returns a pointer to the start of this block. Care must be taken to not read or write
-    /// outside the block.
-    inline T *data() { return const_cast<T*>(data()); }
-protected:
-    // TODO: for now it should never be deleted as C2MemoryBlock
-    virtual ~C2MemoryBlock() = default;
-};
-
-/**
- * Interface to a block of memory containing a constant (constexpr) array of some type (T).
- */
-template<typename T>
-struct C2ConstMemoryBlock : public C2MemoryBlock<T> {
-    virtual const T * data() const { return _mData; }
-    virtual size_t size() const { return _mSize; }
-
-    /// Constructor.
-    template<unsigned N>
-    inline constexpr C2ConstMemoryBlock(const T(&init)[N]) : _mData(init), _mSize(N) {}
-
-private:
-    const T *_mData;
-    const size_t _mSize;
-};
-
-/// \addtogroup internal
-/// @{
-
-/// Helper class to initialize flexible arrays with various initalizers.
-struct _C2ValueArrayHelper {
-    // char[]-s are used as null terminated strings, so the last element is never inited.
-
-    /// Initialize a flexible array using a constexpr memory block.
-    template<typename T>
-    static void init(T(&array)[], size_t arrayLen, const C2MemoryBlock<T> &block) {
-        // reserve last element for terminal 0 for strings
-        if (arrayLen && std::is_same<T, char>::value) {
-            --arrayLen;
-        }
-        if (block.data()) {
-            memcpy(array, block.data(), std::min(arrayLen, block.size()) * sizeof(T));
-        }
-    }
-
-    /// Initialize a flexible array using an initializer list.
-    template<typename T>
-    static void init(T(&array)[], size_t arrayLen, const std::initializer_list<T> &init) {
-        size_t ix = 0;
-        // reserve last element for terminal 0 for strings
-        if (arrayLen && std::is_same<T, char>::value) {
-            --arrayLen;
-        }
-        for (const T &item : init) {
-            if (ix == arrayLen) {
-                break;
-            }
-            array[ix++] = item;
-        }
-    }
-
-    /// Initialize a flexible array using another flexible array.
-    template<typename T, unsigned N>
-    static void init(T(&array)[], size_t arrayLen, const T(&str)[N]) {
-        // reserve last element for terminal 0 for strings
-        if (arrayLen && std::is_same<T, char>::value) {
-            --arrayLen;
-        }
-        if (arrayLen) {
-            strncpy(array, str, std::min(arrayLen, (size_t)N));
-        }
-    }
-};
-
-/**
- * Specialization for a flexible blob and string arrays. A structure template encapsulating a single
- * flexible array member with default flexible constructors and no core-index. This type cannot be
- * constructed on its own as it's size is 0.
- *
- * \internal This is different from C2SimpleArrayStruct<T[]> simply because its member has the name
- * as value to reflect this is a single value.
- */
-template<typename T>
-struct C2SimpleValueStruct<T[]> {
-    static_assert(std::is_same<T, char>::value || std::is_same<T, uint8_t>::value,
-                  "C2SimpleValueStruct<T[]> is only for BLOB or STRING");
-    T value[];
-
-    inline C2SimpleValueStruct() = default;
-    DEFINE_BASE_C2STRUCT(SimpleValue)
-    FLEX(C2SimpleValueStruct, value)
-
-private:
-    inline C2SimpleValueStruct(size_t flexCount, const C2MemoryBlock<T> &block) {
-        _C2ValueArrayHelper::init(value, flexCount, block);
-    }
-
-    inline C2SimpleValueStruct(size_t flexCount, const std::initializer_list<T> &init) {
-        _C2ValueArrayHelper::init(value, flexCount, init);
-    }
-
-    template<unsigned N>
-    inline C2SimpleValueStruct(size_t flexCount, const T(&init)[N]) {
-        _C2ValueArrayHelper::init(value, flexCount, init);
-    }
-};
-
-/// @}
-
-/**
- * A structure template encapsulating a single flexible array element of a specific type (T) with
- * default constructors and no core-index. This type cannot be constructed on its own as it's size
- * is 0. Instead, it is meant to be used as a parameter, e.g.
- *
- *   typedef C2StreamParam<C2Info, C2SimpleArrayStruct<C2MyFancyStruct>,
- *           kParamIndexMyFancyArrayStreamParam> C2MyFancyArrayStreamInfo;
- */
-template<typename T>
-struct C2SimpleArrayStruct {
-    static_assert(!std::is_same<T, char>::value && !std::is_same<T, uint8_t>::value,
-                  "use C2SimpleValueStruct<T[]> is for BLOB or STRING");
-
-    T values[]; ///< array member
-    /// Default constructor
-    inline C2SimpleArrayStruct() = default;
-    DEFINE_BASE_FLEX_C2STRUCT(SimpleArray, values)
-    //FLEX(C2SimpleArrayStruct, values)
-
-private:
-    /// Construct from a C2MemoryBlock.
-    /// Used only by the flexible parameter allocators (AllocUnique & AllocShared).
-    inline C2SimpleArrayStruct(size_t flexCount, const C2MemoryBlock<T> &block) {
-        _C2ValueArrayHelper::init(values, flexCount, block);
-    }
-
-    /// Construct from an initializer list.
-    /// Used only by the flexible parameter allocators (AllocUnique & AllocShared).
-    inline C2SimpleArrayStruct(size_t flexCount, const std::initializer_list<T> &init) {
-        _C2ValueArrayHelper::init(values, flexCount, init);
-    }
-
-    /// Construct from another flexible array.
-    /// Used only by the flexible parameter allocators (AllocUnique & AllocShared).
-    template<unsigned N>
-    inline C2SimpleArrayStruct(size_t flexCount, const T(&init)[N]) {
-        _C2ValueArrayHelper::init(values, flexCount, init);
-    }
-};
-
-/**
- * \addtogroup simplevalue Simple value and array structures.
- * @{
- *
- * Simple value structures.
- *
- * Structures containing a single simple value. These can be reused to easily define simple
- * parameters of various types:
- *
- *   typedef C2PortParam<C2Tuning, C2Int32Value, kParamIndexMyIntegerPortParam>
- *           C2MyIntegerPortParamTuning;
- *
- * They contain a single member (value or values) that is described as "value" or "values".
- */
-/// A 32-bit signed integer parameter in value, described as "value"
-typedef C2SimpleValueStruct<int32_t> C2Int32Value;
-/// A 32-bit signed integer array parameter in values, described as "values"
-typedef C2SimpleArrayStruct<int32_t> C2Int32Array;
-/// A 32-bit unsigned integer parameter in value, described as "value"
-typedef C2SimpleValueStruct<uint32_t> C2Uint32Value;
-/// A 32-bit unsigned integer array parameter in values, described as "values"
-typedef C2SimpleArrayStruct<uint32_t> C2Uint32Array;
-/// A 64-bit signed integer parameter in value, described as "value"
-typedef C2SimpleValueStruct<int64_t> C2Int64Value;
-/// A 64-bit signed integer array parameter in values, described as "values"
-typedef C2SimpleArrayStruct<int64_t> C2Int64Array;
-/// A 64-bit unsigned integer parameter in value, described as "value"
-typedef C2SimpleValueStruct<uint64_t> C2Uint64Value;
-/// A 64-bit unsigned integer array parameter in values, described as "values"
-typedef C2SimpleArrayStruct<uint64_t> C2Uint64Array;
-/// A float parameter in value, described as "value"
-typedef C2SimpleValueStruct<float> C2FloatValue;
-/// A float array parameter in values, described as "values"
-typedef C2SimpleArrayStruct<float> C2FloatArray;
-/// A blob flexible parameter in value, described as "value"
-typedef C2SimpleValueStruct<uint8_t[]> C2BlobValue;
-/// A string flexible parameter in value, described as "value"
-typedef C2SimpleValueStruct<char[]> C2StringValue;
-
-#if 1
-template<typename T>
-const std::initializer_list<const C2FieldDescriptor> C2SimpleValueStruct<T>::FIELD_LIST = { C2FIELD(value, "value") };
-template<typename T>
-const std::initializer_list<const C2FieldDescriptor> C2SimpleValueStruct<T[]>::FIELD_LIST = { C2FIELD(value, "value") };
-template<typename T>
-const std::initializer_list<const C2FieldDescriptor> C2SimpleArrayStruct<T>::FIELD_LIST = { C2FIELD(values, "values") };
-#else
-// This seem to be able to be handled by the template above
-DESCRIBE_TEMPLATED_C2STRUCT(C2SimpleValueStruct<int32_t>, { C2FIELD(value, "value") });
-DESCRIBE_TEMPLATED_C2STRUCT(C2SimpleValueStruct<uint32_t>, { C2FIELD(value, "value") });
-DESCRIBE_TEMPLATED_C2STRUCT(C2SimpleValueStruct<int64_t>, { C2FIELD(value, "value") });
-DESCRIBE_TEMPLATED_C2STRUCT(C2SimpleValueStruct<uint64_t>, { C2FIELD(value, "value") });
-DESCRIBE_TEMPLATED_C2STRUCT(C2SimpleValueStruct<float>, { C2FIELD(value, "value") });
-DESCRIBE_TEMPLATED_C2STRUCT(C2SimpleValueStruct<uint8_t[]>, { C2FIELD(value, "value") });
-DESCRIBE_TEMPLATED_C2STRUCT(C2SimpleValueStruct<char[]>, { C2FIELD(value, "value") });
-DESCRIBE_TEMPLATED_C2STRUCT(C2SimpleArrayStruct<int32_t>, { C2FIELD(values, "values") });
-DESCRIBE_TEMPLATED_C2STRUCT(C2SimpleArrayStruct<uint32_t>, { C2FIELD(values, "values") });
-DESCRIBE_TEMPLATED_C2STRUCT(C2SimpleArrayStruct<int64_t>, { C2FIELD(values, "values") });
-DESCRIBE_TEMPLATED_C2STRUCT(C2SimpleArrayStruct<uint64_t>, { C2FIELD(values, "values") });
-DESCRIBE_TEMPLATED_C2STRUCT(C2SimpleArrayStruct<float>, { C2FIELD(values, "values") });
-#endif
-
-/// @}
-
-/// @}
-
-#endif  // C2PARAM_DEF_H_
diff --git a/media/libstagefright/codec2/include/C2Work.h b/media/libstagefright/codec2/include/C2Work.h
deleted file mode 100644
index 1a35519..0000000
--- a/media/libstagefright/codec2/include/C2Work.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef C2WORK_H_
-
-#define C2WORK_H_
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <C2Param.h>
-#include <C2Buffer.h>
-#include <C2Config.h>
-
-#include <memory>
-#include <list>
-#include <vector>
-
-/// \defgroup work Work and data processing
-/// @{
-
-/**
- * Information describing the reason a parameter settings may fail, or
- * may be overriden.
- */
-struct C2SettingResult {
-    enum Failure : uint32_t {
-        /* parameter failures below */
-        BAD_TYPE,   ///< parameter is not supported
-        BAD_PORT,   ///< parameter is not supported on the specific port
-        BAD_INDEX,  ///< parameter is not supported on the specific stream
-        READ_ONLY,  ///< parameter is read-only and cannot be set
-        MISMATCH,   ///< parameter mismatches input data
-
-        /* field failures below */
-        BAD_VALUE,  ///< parameter does not accept value for the field at all
-        CONFLICT,   ///< parameter field value is in conflict with an/other setting(s)
-
-        /// parameter field is out of range due to other settings (this failure mode
-        /// can only be used for strict calculated parameters)
-        UNSUPPORTED,
-
-        /// requested parameter value is in conflict with an/other setting(s)
-        /// and has been corrected to the closest supported value. This failure
-        /// mode is given to provide suggestion to the client as to how to
-        /// enable the requested parameter value.
-        INFO_CONFLICT,
-    };
-
-    Failure failure;    ///< failure code
-
-    /// Failing (or corrected) field or parameterand optionally, currently supported values for the
-    /// field. Values must only be set for field failures other than BAD_VALUE, and only if they are
-    /// different from the globally supported values (e.g. due to restrictions by another param or
-    /// input data).
-    C2ParamFieldValues field;
-
-    /// Conflicting parameters or fields with optional suggestions with (optional) suggested values
-    /// for any conflicting fields to avoid the conflict. Must only be set for CONFLICT, UNSUPPORTED
-    /// and INFO_CONFLICT failure codes.
-    std::vector<C2ParamFieldValues> conflicts;
-};
-
-// ================================================================================================
-//  WORK
-// ================================================================================================
-
-/** Unique ID for a processing node. */
-typedef uint32_t c2_node_id_t;
-
-enum {
-    kParamIndexWorkOrdinal,
-};
-
-/**
- * Information for ordering work items on a component port.
- */
-struct C2WorkOrdinalStruct {
-//public:
-    c2_cntr64_t timestamp;     /** frame timestamp in microseconds */
-    c2_cntr64_t frameIndex;    /** submission ordinal on the initial component */
-    c2_cntr64_t customOrdinal; /** can be given by the component, e.g. decode order */
-
-    DEFINE_AND_DESCRIBE_C2STRUCT(WorkOrdinal)
-    C2FIELD(timestamp, "timestamp")
-    C2FIELD(frameIndex, "frame-index")
-    C2FIELD(customOrdinal, "custom-ordinal")
-};
-
-/**
- * This structure represents a Codec 2.0 frame with its metadata.
- *
- * A frame basically consists of an ordered sets of buffers, configuration changes and info buffers
- * along with some non-configuration metadata.
- */
-struct C2FrameData {
-//public:
-    enum flags_t : uint32_t {
-        /**
-         * For input frames: no output frame shall be generated when processing this frame, but
-         * metadata shall still be processed.
-         * For output frames: this frame shall be discarded and but metadata is still valid.
-         */
-        FLAG_DROP_FRAME    = (1 << 0),
-        /**
-         * This frame is the last frame of the current stream. Further frames are part of a new
-         * stream.
-         */
-        FLAG_END_OF_STREAM = (1 << 1),
-        /**
-         * This frame shall be discarded with its metadata.
-         * This flag is only set by components - e.g. as a response to the flush command.
-         */
-        FLAG_DISCARD_FRAME = (1 << 2),
-        /**
-         * This frame contains only codec-specific configuration data, and no actual access unit.
-         *
-         * \deprecated pass codec configuration with using the \todo codec-specific configuration
-         * info together with the access unit.
-         */
-        FLAG_CODEC_CONFIG  = (1u << 31),
-    };
-
-    /**
-     * Frame flags */
-    flags_t  flags;
-    C2WorkOrdinalStruct ordinal;
-    std::vector<std::shared_ptr<C2Buffer>> buffers;
-    //< for initial work item, these may also come from the parser - if provided
-    //< for output buffers, these are the responses to requestedInfos
-    std::vector<std::unique_ptr<C2Param>>      configUpdate;
-    std::vector<std::shared_ptr<C2InfoBuffer>> infoBuffers;
-};
-
-struct C2Worklet {
-//public:
-    // IN
-    c2_node_id_t component;
-
-    /** Configuration changes to be applied before processing this worklet. */
-    std::vector<std::unique_ptr<C2Tuning>> tunings;
-    std::vector<std::unique_ptr<C2SettingResult>> failures;
-
-    // OUT
-    C2FrameData output;
-};
-
-/**
- * Information about partial work-chains not part of the current work items.
- *
- * To be defined later.
- */
-struct C2WorkChainInfo;
-
-/**
- * This structure holds information about all a single work item.
- *
- * This structure shall be passed by the client to the component for the first worklet. As such,
- * worklets must not be empty. The ownership of this object is passed.
- */
-struct C2Work {
-//public:
-    /// additional work chain info not part of this work
-    std::shared_ptr<C2WorkChainInfo> chainInfo;
-
-    /// The input data to be processed as part of this work/work-chain. This is provided by the
-    /// client with ownership. When the work is returned (via onWorkDone), the input buffer-pack's
-    /// buffer vector shall contain nullptrs.
-    C2FrameData input;
-
-    /// The chain of components, tunings (including output buffer pool IDs) and info requests that the
-    /// data must pass through. If this has more than a single element, the tunnels between successive
-    /// components of the worklet chain must have been (successfully) pre-registered at the time that
-    /// the work is submitted. Allocating the output buffers in the worklets is the responsibility of
-    /// each component. Upon work submission, each output buffer-pack shall be an appropriately sized
-    /// vector containing nullptrs. When the work is completed/returned to the client, output buffers
-    /// pointers from all but the final worklet shall be nullptrs.
-    std::list<std::unique_ptr<C2Worklet>> worklets;
-
-    /// Number of worklets successfully processed in this chain. This shall be initialized to 0 by the
-    /// client when the work is submitted. It shall contain the number of worklets that were
-    /// successfully processed when the work is returned to the client. If this is less then the number
-    /// of worklets, result must not be success. It must be in the range of [0, worklets.size()].
-    uint32_t workletsProcessed;
-
-    /// The final outcome of the work (corresponding to the current workletsProcessed). If 0 when
-    /// work is returned, it is assumed that all worklets have been processed.
-    c2_status_t result;
-};
-
-/**
- * Information about a future work to be submitted to the component. The information is used to
- * reserve the work for work ordering purposes.
- */
-struct C2WorkOutline {
-//public:
-    C2WorkOrdinalStruct ordinal;
-    std::vector<c2_node_id_t> chain;
-};
-
-/// @}
-
-#endif  // C2WORK_H_
diff --git a/media/libstagefright/codec2/include/SimpleC2Component.h b/media/libstagefright/codec2/include/SimpleC2Component.h
deleted file mode 100644
index 168e79f..0000000
--- a/media/libstagefright/codec2/include/SimpleC2Component.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2017 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 SIMPLE_C2_COMPONENT_H_
-#define SIMPLE_C2_COMPONENT_H_
-
-#include <list>
-#include <thread>
-#include <unordered_map>
-
-#include <C2Component.h>
-
-#include <media/stagefright/foundation/Mutexed.h>
-
-namespace android {
-
-class SimpleC2Component
-        : public C2Component, public std::enable_shared_from_this<SimpleC2Component> {
-public:
-    SimpleC2Component(
-            const std::shared_ptr<C2ComponentInterface> &intf);
-    virtual ~SimpleC2Component() = default;
-
-    // C2Component
-    // From C2Component
-    virtual c2_status_t setListener_vb(
-            const std::shared_ptr<Listener> &listener, c2_blocking_t mayBlock) override;
-    virtual c2_status_t queue_nb(std::list<std::unique_ptr<C2Work>>* const items) override;
-    virtual c2_status_t announce_nb(const std::vector<C2WorkOutline> &items) override;
-    virtual c2_status_t flush_sm(
-            flush_mode_t mode, std::list<std::unique_ptr<C2Work>>* const flushedWork) override;
-    virtual c2_status_t drain_nb(drain_mode_t mode) override;
-    virtual c2_status_t start() override;
-    virtual c2_status_t stop() override;
-    virtual c2_status_t reset() override;
-    virtual c2_status_t release() override;
-    virtual std::shared_ptr<C2ComponentInterface> intf() override;
-
-    // for thread
-    inline bool exitRequested() { return mExitRequested; }
-    void processQueue();
-    void signalExit();
-
-protected:
-    /**
-     * Initialize internal states of the component according to the config set
-     * in the interface.
-     *
-     * This method is called during start(), but only at the first invocation or
-     * after reset().
-     */
-    virtual c2_status_t onInit() = 0;
-
-    /**
-     * Stop the component.
-     */
-    virtual c2_status_t onStop() = 0;
-
-    /**
-     * Reset the component.
-     */
-    virtual void onReset() = 0;
-
-    /**
-     * Release the component.
-     */
-    virtual void onRelease() = 0;
-
-    /**
-     * Flush the component.
-     */
-    virtual c2_status_t onFlush_sm() = 0;
-
-    /**
-     * Process the given work and finish pending work using finish().
-     *
-     * \param[in,out]   work    the work to process
-     * \param[in]       pool    the pool to use for allocating output blocks.
-     */
-    virtual void process(
-            const std::unique_ptr<C2Work> &work,
-            const std::shared_ptr<C2BlockPool> &pool) = 0;
-
-    /**
-     * Drain the component and finish pending work using finish().
-     *
-     * \param[in]   drainMode   mode of drain.
-     * \param[in]   pool        the pool to use for allocating output blocks.
-     *
-     * \retval C2_OK            The component has drained all pending output
-     *                          work.
-     * \retval C2_OMITTED       Unsupported mode (e.g. DRAIN_CHAIN)
-     */
-    virtual c2_status_t drain(
-            uint32_t drainMode,
-            const std::shared_ptr<C2BlockPool> &pool) = 0;
-
-    // for derived classes
-    /**
-     * Finish pending work.
-     *
-     * This method will retrieve the pending work according to |frameIndex| and
-     * feed the work into |fillWork| function. |fillWork| must be
-     * "non-blocking". Once |fillWork| returns the filled work will be returned
-     * to the client.
-     *
-     * \param[in]   frameIndex    the index of the pending work
-     * \param[in]   fillWork      the function to fill the retrieved work.
-     */
-    void finish(uint64_t frameIndex, std::function<void(const std::unique_ptr<C2Work> &)> fillWork);
-
-    std::shared_ptr<C2Buffer> createLinearBuffer(
-            const std::shared_ptr<C2LinearBlock> &block);
-
-    std::shared_ptr<C2Buffer> createLinearBuffer(
-            const std::shared_ptr<C2LinearBlock> &block, size_t offset, size_t size);
-
-    std::shared_ptr<C2Buffer> createGraphicBuffer(
-            const std::shared_ptr<C2GraphicBlock> &block);
-
-    std::shared_ptr<C2Buffer> createGraphicBuffer(
-            const std::shared_ptr<C2GraphicBlock> &block,
-            const C2Rect &crop);
-
-    static constexpr uint32_t NO_DRAIN = ~0u;
-
-private:
-    const std::shared_ptr<C2ComponentInterface> mIntf;
-    std::atomic_bool mExitRequested;
-
-    enum {
-        UNINITIALIZED,
-        STOPPED,
-        RUNNING,
-    };
-
-    struct ExecState {
-        ExecState() : mState(UNINITIALIZED) {}
-
-        int mState;
-        std::thread mThread;
-        std::shared_ptr<C2Component::Listener> mListener;
-    };
-    Mutexed<ExecState> mExecState;
-
-    class WorkQueue {
-    public:
-        inline WorkQueue() : mFlush(false), mGeneration(0ul) {}
-
-        inline uint64_t generation() const { return mGeneration; }
-        inline void incGeneration() { ++mGeneration; mFlush = true; }
-
-        std::unique_ptr<C2Work> pop_front();
-        void push_back(std::unique_ptr<C2Work> work);
-        bool empty() const;
-        uint32_t drainMode() const;
-        void markDrain(uint32_t drainMode);
-        inline bool popPendingFlush() {
-            bool flush = mFlush;
-            mFlush = false;
-            return flush;
-        }
-        void clear();
-
-        Condition mCondition;
-
-    private:
-        struct Entry {
-            std::unique_ptr<C2Work> work;
-            uint32_t drainMode;
-        };
-
-        bool mFlush;
-        uint64_t mGeneration;
-        std::list<Entry> mQueue;
-    };
-    Mutexed<WorkQueue> mWorkQueue;
-
-    typedef std::unordered_map<uint64_t, std::unique_ptr<C2Work>> PendingWork;
-    Mutexed<PendingWork> mPendingWork;
-
-    struct ExitMonitor {
-        inline ExitMonitor() : mExited(false) {}
-        Condition mCondition;
-        bool mExited;
-    };
-    Mutexed<ExitMonitor> mExitMonitor;
-
-    std::shared_ptr<C2BlockPool> mOutputBlockPool;
-
-    SimpleC2Component() = delete;
-
-    void requestExitAndWait(std::function<void()> job);
-};
-
-}  // namespace android
-
-#endif  // SIMPLE_C2_COMPONENT_H_
diff --git a/media/libstagefright/codec2/include/SimpleC2Interface.h b/media/libstagefright/codec2/include/SimpleC2Interface.h
deleted file mode 100644
index 310096f..0000000
--- a/media/libstagefright/codec2/include/SimpleC2Interface.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2017 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 SIMPLE_C2_INTERFACE_H_
-#define SIMPLE_C2_INTERFACE_H_
-
-#include <C2Component.h>
-
-namespace android {
-
-class SimpleC2Interface : public C2ComponentInterface {
-public:
-    class Builder {
-    public:
-        inline Builder(
-                const char *name,
-                c2_node_id_t id,
-                std::function<void(C2ComponentInterface*)> deleter =
-                    std::default_delete<C2ComponentInterface>())
-            : mIntf(new SimpleC2Interface(name, id), deleter) {}
-
-        inline Builder &inputFormat(C2FormatKind input) {
-            mIntf->mInputFormat.value = input;
-            return *this;
-        }
-
-        inline Builder &outputFormat(C2FormatKind output) {
-            mIntf->mOutputFormat.value = output;
-            return *this;
-        }
-
-        inline Builder &inputMediaType(const char *mediaType, size_t maxLen = 128) {
-            mIntf->mInputMediaType = C2PortMimeConfig::input::AllocShared(maxLen);
-            std::strncpy(mIntf->mInputMediaType->m.value, mediaType, maxLen);
-            return *this;
-        }
-
-        inline Builder &outputMediaType(const char *mediaType, size_t maxLen = 128) {
-            mIntf->mOutputMediaType = C2PortMimeConfig::output::AllocShared(maxLen);
-            std::strncpy(mIntf->mOutputMediaType->m.value, mediaType, maxLen);
-            return *this;
-        }
-
-        template<size_t N>
-        inline Builder &inputMediaType(const char mediaType[N]) {
-            return inputMediaType(mediaType, N);
-        }
-
-        template<size_t N>
-        inline Builder &outputMediaType(const char mediaType[N]) {
-            return outputMediaType(mediaType, N);
-        }
-
-        inline std::shared_ptr<SimpleC2Interface> build() {
-            return mIntf;
-        }
-    private:
-        std::shared_ptr<SimpleC2Interface> mIntf;
-    };
-
-    virtual ~SimpleC2Interface() = default;
-
-    // From C2ComponentInterface
-    inline C2String getName() const override { return mName; }
-    inline c2_node_id_t getId() const override { return mId; }
-    c2_status_t query_vb(
-            const std::vector<C2Param*> &stackParams,
-            const std::vector<C2Param::Index> &heapParamIndices,
-            c2_blocking_t mayBlock,
-            std::vector<std::unique_ptr<C2Param>>* const heapParams) const override;
-    inline c2_status_t config_vb(
-            const std::vector<C2Param*> &,
-            c2_blocking_t,
-            std::vector<std::unique_ptr<C2SettingResult>>* const) override {
-        return C2_OMITTED;
-    }
-    inline c2_status_t createTunnel_sm(c2_node_id_t) override { return C2_OMITTED; }
-    inline c2_status_t releaseTunnel_sm(c2_node_id_t) override { return C2_OMITTED; }
-    inline c2_status_t querySupportedParams_nb(
-            std::vector<std::shared_ptr<C2ParamDescriptor>> * const) const override {
-        return C2_OMITTED;
-    }
-    c2_status_t querySupportedValues_vb(
-            std::vector<C2FieldSupportedValuesQuery> &,
-            c2_blocking_t) const override {
-        return C2_OMITTED;
-    }
-
-private:
-    inline SimpleC2Interface(const char *name, c2_node_id_t id)
-        : mName(name), mId(id), mInputFormat(0u), mOutputFormat(0u) {}
-
-    const C2String mName;
-    const c2_node_id_t mId;
-    C2StreamFormatConfig::input mInputFormat;
-    C2StreamFormatConfig::output mOutputFormat;
-    std::shared_ptr<C2PortMimeConfig::input> mInputMediaType;
-    std::shared_ptr<C2PortMimeConfig::output> mOutputMediaType;
-
-    SimpleC2Interface() = delete;
-};
-
-}  // namespace android
-
-#endif  // SIMPLE_C2_INTERFACE_H_
diff --git a/media/libstagefright/codec2/include/android-C2Buffer.h b/media/libstagefright/codec2/include/android-C2Buffer.h
deleted file mode 100644
index c71f2cf..0000000
--- a/media/libstagefright/codec2/include/android-C2Buffer.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_C2BUFFER_H_
-#define ANDROID_C2BUFFER_H_
-
-#include <cutils/native_handle.h>
-#include <hardware/gralloc.h>
-
-/* Use android native handle for C2Handle */
-typedef ::native_handle_t C2Handle;
-
-namespace android {
-
-/**
- * Android platform buffer/memory usage bits.
- */
-struct C2AndroidMemoryUsage : public C2MemoryUsage {
-// public:
-    /**
-     * Reuse gralloc flags where possible, as Codec 2.0 API only uses bits 0 and 1.
-     */
-    enum Consumer : uint64_t {
-        RENDERSCRIPT_READ = GRALLOC_USAGE_RENDERSCRIPT,
-        HW_TEXTURE_READ   = GRALLOC_USAGE_HW_TEXTURE,
-        HW_COMPOSER_READ  = GRALLOC_USAGE_HW_COMPOSER,
-        HW_CODEC_READ     = GRALLOC_USAGE_HW_VIDEO_ENCODER,
-        READ_PROTECTED    = GRALLOC_USAGE_PROTECTED,
-    };
-
-    enum Producer : uint64_t {
-        RENDERSCRIPT_WRITE = GRALLOC_USAGE_RENDERSCRIPT,
-        HW_TEXTURE_WRITE   = GRALLOC_USAGE_HW_RENDER,
-        HW_COMPOSER_WRITE  = GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER,
-        HW_CODEC_WRITE     = GRALLOC_USAGE_HW_VIDEO_ENCODER,
-        WRITE_PROTECTED    = GRALLOC_USAGE_PROTECTED,
-    };
-
-    /**
-     * Convert from gralloc usage.
-     */
-    static C2MemoryUsage FromGrallocUsage(uint64_t usage);
-
-    /**
-     * Convert to gralloc usage.
-     */
-    uint64_t asGrallocUsage() const;
-};
-
-}  // namespace android
-
-#endif  // ANDROID_C2BUFFER_H_
diff --git a/media/libstagefright/codec2/include/media/stagefright/codec2/1.0/InputSurface.h b/media/libstagefright/codec2/include/media/stagefright/codec2/1.0/InputSurface.h
deleted file mode 100644
index b011a06..0000000
--- a/media/libstagefright/codec2/include/media/stagefright/codec2/1.0/InputSurface.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2018, 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_HARDWARE_MEDIA_C2_V1_0_INPUT_SURFACE_H
-#define ANDROID_HARDWARE_MEDIA_C2_V1_0_INPUT_SURFACE_H
-
-#include <memory>
-
-#include <C2Component.h>
-#include <media/stagefright/bqhelper/WGraphicBufferProducer.h>
-#include <media/stagefright/codec2/1.0/InputSurfaceConnection.h>
-
-namespace android {
-
-class GraphicBufferSource;
-
-namespace hardware {
-namespace media {
-namespace c2 {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::sp;
-
-typedef ::android::hardware::graphics::bufferqueue::V1_0::IGraphicBufferProducer
-        HGraphicBufferProducer;
-typedef ::android::IGraphicBufferProducer BGraphicBufferProducer;
-
-// TODO: ::android::TWGraphicBufferProducer<IInputSurface>
-typedef ::android::TWGraphicBufferProducer<HGraphicBufferProducer> InputSurfaceBase;
-
-class InputSurface : public InputSurfaceBase {
-public:
-    virtual ~InputSurface() = default;
-
-    // Methods from IInputSurface
-    sp<InputSurfaceConnection> connectToComponent(
-            const std::shared_ptr<::C2Component> &comp);
-    // TODO: intf()
-
-    static sp<InputSurface> Create();
-
-private:
-    InputSurface(
-            const sp<BGraphicBufferProducer> &base,
-            const sp<::android::GraphicBufferSource> &source);
-
-    sp<::android::GraphicBufferSource> mSource;
-};
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace c2
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_MEDIA_C2_V1_0_INPUT_SURFACE_H
diff --git a/media/libstagefright/codec2/include/media/stagefright/codec2/1.0/InputSurfaceConnection.h b/media/libstagefright/codec2/include/media/stagefright/codec2/1.0/InputSurfaceConnection.h
deleted file mode 100644
index b24a416..0000000
--- a/media/libstagefright/codec2/include/media/stagefright/codec2/1.0/InputSurfaceConnection.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright 2018, 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_HARDWARE_MEDIA_C2_V1_0_INPUT_SURFACE_CONNECTION_H
-#define ANDROID_HARDWARE_MEDIA_C2_V1_0_INPUT_SURFACE_CONNECTION_H
-
-#include <memory>
-
-#include <C2Component.h>
-#include <media/stagefright/bqhelper/GraphicBufferSource.h>
-#include <media/stagefright/bqhelper/WGraphicBufferProducer.h>
-#include <media/stagefright/codec2/1.0/InputSurfaceConnection.h>
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace c2 {
-namespace V1_0 {
-namespace implementation {
-
-// TODO: inherit from IInputSurfaceConnection
-class InputSurfaceConnection : public RefBase {
-public:
-    virtual ~InputSurfaceConnection();
-
-    // From IInputSurfaceConnection
-    void disconnect();
-
-private:
-    friend class InputSurface;
-
-    // For InputSurface
-    InputSurfaceConnection(
-            const sp<GraphicBufferSource> &source, const std::shared_ptr<C2Component> &comp);
-    bool init();
-
-    InputSurfaceConnection() = delete;
-
-    class Impl;
-
-    sp<GraphicBufferSource> mSource;
-    sp<Impl> mImpl;
-
-    DISALLOW_EVIL_CONSTRUCTORS(InputSurfaceConnection);
-};
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace c2
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_MEDIA_C2_V1_0_INPUT_SURFACE_CONNECTION_H
diff --git a/media/libstagefright/codec2/tests/Android.bp b/media/libstagefright/codec2/tests/Android.bp
deleted file mode 100644
index f26fbd0..0000000
--- a/media/libstagefright/codec2/tests/Android.bp
+++ /dev/null
@@ -1,90 +0,0 @@
-cc_test {
-    name: "codec2_param_test",
-
-    tags: [
-        "tests",
-    ],
-
-    srcs: [
-        "C2Param_test.cpp",
-        "vndk/C2UtilTest.cpp",
-    ],
-
-    include_dirs: [
-        "frameworks/av/media/libstagefright/codec2/include",
-        "frameworks/av/media/libstagefright/codec2/vndk/include",
-    ],
-
-    // param tests must not depend on any codec2 libraries as all params should be templated
-    shared_libs: [
-    ],
-
-    static_libs: [
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-        "-std=c++14",
-    ],
-}
-
-cc_test {
-    name: "codec2_test",
-
-    tags: [
-        "tests",
-    ],
-
-    srcs: [
-        "vndk/C2BufferTest.cpp",
-        "C2_test.cpp",
-    ],
-
-    include_dirs: [
-    ],
-
-    shared_libs: [
-        "libcutils",
-        "liblog",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libutils",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-        "-std=c++14",
-    ],
-}
-
-cc_test {
-    name: "codec2_interface_test",
-
-    tags: [
-        "tests",
-    ],
-
-    srcs: [
-        "C2ComponentInterface_test.cpp",
-    ],
-
-    include_dirs: [
-        "frameworks/native/include/media/openmax",
-    ],
-
-    shared_libs: [
-        "libcutils",
-        "liblog",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-        "libutils",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-        "-std=c++14",
-    ],
-}
diff --git a/media/libstagefright/codec2/tests/C2ComponentInterface_test.cpp b/media/libstagefright/codec2/tests/C2ComponentInterface_test.cpp
deleted file mode 100644
index e555e8c..0000000
--- a/media/libstagefright/codec2/tests/C2ComponentInterface_test.cpp
+++ /dev/null
@@ -1,714 +0,0 @@
-/*
- * Copyright 2017 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_TAG "C2ComponentInterface_test"
-
-#include <dlfcn.h>
-#include <stdio.h>
-
-#include <gtest/gtest.h>
-#include <utils/Log.h>
-
-#include <C2Component.h>
-#include <C2Param.h>
-
-#if !defined(UNUSED)
-#define UNUSED(expr)                                                           \
-  do {                                                                         \
-      (void)(expr);                                                            \
-  } while (0)
-
-#endif //!defined(UNUSED)
-
-namespace android {
-
-template <class T> std::unique_ptr<T> alloc_unique_cstr(const char *cstr) {
-    size_t len = strlen(cstr);
-    std::unique_ptr<T> ptr = T::AllocUnique(len);
-    memcpy(ptr->m.value, cstr, len);
-    return ptr;
-}
-
-class C2CompIntfTest : public ::testing::Test {
-protected:
-    C2CompIntfTest() {}
-    ~C2CompIntfTest() override {}
-
-    void setComponent(std::shared_ptr<C2ComponentInterface> intf) {
-        mIntf = intf;
-    }
-
-    void resetResults() {
-        mIntf = nullptr;
-        mParamResults.clear();
-    }
-
-    template <typename T> void testUnsupportedParam();
-
-    template <typename T> void testSupportedParam();
-
-    // testReadOnlyParam() and testWritableParam() are the main functions for testing a parameter.
-    // A caller should find out if a tested parameter is read-only or writable before calling them
-    // and it must call one of the corresponded them.
-
-    // If a parameter is read-only this is called.
-    // Test read-only parameter |preParam|. The test expects failure while config() with |newParam|,
-    // and make sure |preParam| stay unchanged.
-    template <typename T>
-    void testReadOnlyParam(const T &preParam, const T &newParam);
-
-    // If a parameter is writable this is called.
-    // Test one filed |writableField| for given writable parameter |param|.
-    // |validValues| contains all values obtained from querySupportedValues() for |writableField|.
-    // The test checks validity for config() with each value, and make sure values are config-ed
-    // by query() them out. |invalidValues| contains some values which are not in |validValues|.
-    // The test expects C2_BAD_VALUE while config() with these values,
-    // and |param| should stay unchanged.
-    template <typename TParam, typename TRealField, typename TField>
-    void testWritableParam(TParam *const param, TRealField *const writableField,
-                           const std::vector<TField> &validValues,
-                           const std::vector<TField> &invalidValues);
-
-    // Test all the defined parameters in C2Param.h.
-    void testMain(std::shared_ptr<C2ComponentInterface> intf,
-                  const std::string &componentName);
-
-    // Check permission of parameter type |T| for testing interface.
-    // This should be called first of the testing per parameter type,
-    // therefore different testing process is applied according to the permission type.
-    template <typename T>
-    void checkParamPermission(
-            int *const writable,
-            const std::vector<std::shared_ptr<C2ParamDescriptor>> &supportedParams);
-
-private:
-    enum ParamPermission : int {
-        WRITABLE,
-        READONLY,
-        UNSUPPORTED,
-    };
-
-    struct paramTestInfo {
-        std::string name;
-        int result;
-        paramTestInfo(const char *name_, int result_)
-            : name(name_), result(result_) {}
-    };
-
-    // queryOnStack() and queryonHeap() both call an interface's query_vb() and
-    // check if a component has a parameter whose type is |T|.
-    // If a component has, the value should be copied into an argument, that is
-    // |p| in queryOnStack() and |heapParams| in queryOnHeap().
-    // The return value is c2_status_t (e.g. C2_OK).
-    template <typename T> c2_status_t queryOnStack(T *const p);
-
-    template <typename T>
-    c2_status_t queryOnHeap(const T &p,
-                         std::vector<std::unique_ptr<C2Param>> *const heapParams);
-
-    // Get a value whose type is |T| in a component. The value is copied to |param|.
-    // This should be called only if a component has the parameter.
-    template <typename T> void getValue(T *const param);
-
-    // Check if the parameter's value in component is equal to |expected| and
-    // queryOnStack() and queryOnHeap() are succeeded. When this function called,
-    // it should be guaranteed a component has the parameter.
-    template <typename T> void queryParamAsExpected(const T &expected);
-
-    // Test if query functions works correctly for supported parameters.
-    // "Support" means here a component has the parameter.
-    template <typename T> void querySupportedParam();
-
-    // Test query functions works correctly for unsupported parameters.
-    // "Unsupport" means here a component doesn't have the parameter.
-    template <typename T> void queryUnsupportedParam();
-
-    // Execute an interface's config_vb(). |T| is a single parameter type, not std::vector.
-    // config() creates std::vector<C2Param *> {p} and passes it to config_vb().
-    template <typename T>
-    c2_status_t
-    config(T *const p,
-           std::vector<std::unique_ptr<C2SettingResult>> *const failures);
-
-    // Test if config works correctly for read-only parameters.
-    // Because the failure of config() is assumed, |newParam| doesn't matter.
-    template <typename T> void configReadOnlyParam(const T &newParam);
-
-    // Test if config works correctly for writable parameters.
-    // This changes the parameter's value to |newParam|.
-    // |stConfig| is a return value of config().
-    template <typename T> void configWritableParamValidValue(const T &newParam, c2_status_t *stConfig);
-
-    // Test if config works correctly in the case an invalid value |newParam| is tried to write
-    // to an writable parameter.
-    template <typename T> void configWritableParamInvalidValue(const T &newParam);
-
-    // Create values for testing from |validValueInfos|. The values are returned as arguments.
-    // |validValues| : valid values, which can be written for the parameter.
-    // |InvalidValues| : invalid values, which cannot be written for the parameter.
-    //                   config() should be failed if these values are used as new values.
-    // This function should be called only for writable and supported parameters.
-    template <typename TField>
-    void getTestValues(const C2FieldSupportedValues &validValueInfos,
-                       std::vector<TField> *const validValues,
-                       std::vector<TField> *const invalidValues);
-
-    // Output the summary of test results. Categorizes parameters with their configuration.
-    void outputResults(const std::string &name);
-
-    std::shared_ptr<C2ComponentInterface> mIntf;
-    std::vector<paramTestInfo> mParamResults;
-    std::string mCurrentParamName;
-};
-
-// factory function
-// TODO(hiroh): Add factory functions for other types.
-template <typename T> std::unique_ptr<T> makeParam() {
-    return std::make_unique<T>();
-}
-
-template <> std::unique_ptr<C2PortMimeConfig::input> makeParam() {
-    // TODO(hiroh): Set more precise length.
-    return C2PortMimeConfig::input::AllocUnique(100);
-}
-
-#define TRACED_FAILURE(func)                            \
-    do {                                                \
-        SCOPED_TRACE(mCurrentParamName);             \
-        func;                                           \
-        if (::testing::Test::HasFatalFailure()) {       \
-            return;                                     \
-        }                                               \
-    } while (false)
-
-template <typename T> c2_status_t C2CompIntfTest::queryOnStack(T *const p) {
-    std::vector<C2Param*> stackParams{p};
-    return mIntf->query_vb(stackParams, {}, C2_DONT_BLOCK, nullptr);
-}
-
-template <typename T>
-c2_status_t C2CompIntfTest::queryOnHeap(
-        const T &p, std::vector<std::unique_ptr<C2Param>> *const heapParams) {
-    uint32_t index = p.index() & ~0x03FE0000;
-    if (p.forStream()) {
-        index |= ((p.stream() << 17) & 0x01FE0000) | 0x02000000;
-    }
-    return mIntf->query_vb({}, {index}, C2_DONT_BLOCK, heapParams);
-}
-
-template <typename T> void C2CompIntfTest::getValue(T *const param) {
-    // When getValue() is called, a component has to have the parameter.
-    ASSERT_EQ(C2_OK, queryOnStack(param));
-}
-
-template <typename T>
-void C2CompIntfTest::queryParamAsExpected(const T &expected) {
-    // TODO(hiroh): Don't create param on stack and call queryOnStack for flex params.
-    // Note that all the current supported parameters are non-flex params.
-    T stack;
-    std::unique_ptr<T> pHeap = makeParam<T>();
-    std::vector<std::unique_ptr<C2Param>> heapParams;
-
-    ASSERT_EQ(C2_OK, queryOnStack(&stack));
-
-    // |stack| is a parameter value. The parameter size shouldn't be 0.
-    EXPECT_NE(0u, stack.size());
-    EXPECT_EQ(stack, expected);
-
-    ASSERT_EQ(C2_OK, queryOnHeap(*pHeap, &heapParams));
-
-    // |*heapParams[0]| is a parameter value. The size of |heapParams| has to be one.
-    ASSERT_EQ(1u, heapParams.size());
-    EXPECT_TRUE(heapParams[0]);
-    EXPECT_EQ(*heapParams[0], expected);
-}
-
-template <typename T> void C2CompIntfTest::querySupportedParam() {
-    std::unique_ptr<T> param = makeParam<T>();
-    // The current parameter's value is acquired by getValue(), which should be succeeded.
-    getValue(param.get());
-    queryParamAsExpected(*param);
-}
-
-template <typename T> void C2CompIntfTest::queryUnsupportedParam() {
-    // TODO(hiroh): Don't create param on stack and call queryOnStack for flex params.
-    // Note that all the current supported parameters are non-flex params.
-    T stack;
-    std::unique_ptr<T> pHeap = makeParam<T>();
-    std::vector<std::unique_ptr<C2Param>> heapParams;
-    // If a component doesn't have the parameter, queryOnStack() and queryOnHeap()
-    // should return C2_BAD_INDEX.
-    ASSERT_EQ(C2_BAD_INDEX, queryOnStack(&stack));
-    EXPECT_FALSE(stack);
-    ASSERT_EQ(C2_BAD_INDEX, queryOnHeap(*pHeap, &heapParams));
-    EXPECT_EQ(0u, heapParams.size());
-}
-
-template <typename T>
-c2_status_t C2CompIntfTest::config(
-        T *const p, std::vector<std::unique_ptr<C2SettingResult>> *const failures) {
-    std::vector<C2Param*> params{p};
-    return mIntf->config_vb(params, C2_DONT_BLOCK, failures);
-}
-
-// Create a new parameter copied from |p|.
-template <typename T> std::unique_ptr<T> makeParamFrom(const T &p) {
-    std::unique_ptr<T> retP = makeParam<T>();
-    EXPECT_TRUE(retP->updateFrom(p));
-    EXPECT_TRUE(memcmp(retP.get(), &p, sizeof(T)) == 0);
-    return retP;
-}
-
-template <typename T>
-void C2CompIntfTest::configReadOnlyParam(const T &newParam) {
-    std::unique_ptr<T> p = makeParamFrom(newParam);
-
-    std::vector<C2Param*> params{p.get()};
-    std::vector<std::unique_ptr<C2SettingResult>> failures;
-
-    // config_vb should be failed because a parameter is read-only.
-    ASSERT_EQ(C2_BAD_VALUE, mIntf->config_vb(params, C2_DONT_BLOCK, &failures));
-    ASSERT_EQ(1u, failures.size());
-    EXPECT_EQ(C2SettingResult::READ_ONLY, failures[0]->failure);
-}
-
-template <typename T>
-void C2CompIntfTest::configWritableParamValidValue(const T &newParam, c2_status_t *configResult) {
-    std::unique_ptr<T> p = makeParamFrom(newParam);
-
-    std::vector<C2Param*> params{p.get()};
-    std::vector<std::unique_ptr<C2SettingResult>> failures;
-    // In most cases, config_vb return C2_OK and the parameter's value should be changed
-    // to |newParam|, which is confirmed in a caller of configWritableParamValueValue().
-    // However, this can return ~~~~ and the parameter's values is not changed,
-    // because there may be dependent limitations between fields or between parameters.
-    // TODO(hiroh): I have to fill the return value. Comments in C2Component.h doesn't mention
-    // about the return value when conflict happens. I set C2_BAD_VALUE to it temporarily now.
-    c2_status_t stConfig = mIntf->config_vb(params, C2_DONT_BLOCK, &failures);
-    if (stConfig == C2_OK) {
-        EXPECT_EQ(0u, failures.size());
-    } else {
-        ASSERT_EQ(C2_BAD_VALUE, stConfig);
-        EXPECT_EQ(1u, failures.size());
-        EXPECT_EQ(C2SettingResult::CONFLICT, failures[0]->failure);
-    }
-    *configResult = stConfig;
-}
-
-template <typename T>
-void C2CompIntfTest::configWritableParamInvalidValue(const T &newParam) {
-    std::unique_ptr<T> p = makeParamFrom(newParam);
-
-    std::vector<C2Param*> params{p.get()};
-    std::vector<std::unique_ptr<C2SettingResult>> failures;
-    // Although a parameter is writable, config_vb should be failed,
-    // because a new value is invalid.
-    ASSERT_EQ(C2_BAD_VALUE, mIntf->config_vb(params, C2_DONT_BLOCK, &failures));
-    ASSERT_EQ(1u, failures.size());
-    EXPECT_EQ(C2SettingResult::BAD_VALUE, failures[0]->failure);
-}
-
-// There is only used enum type for the field type, that is C2DomainKind.
-// If another field type is added, it is necessary to add function for that.
-template <>
-void C2CompIntfTest::getTestValues(
-        const C2FieldSupportedValues &validValueInfos,
-        std::vector<C2DomainKind> *const validValues,
-        std::vector<C2DomainKind> *const invalidValues) {
-    UNUSED(validValueInfos);
-    validValues->emplace_back(C2DomainVideo);
-    validValues->emplace_back(C2DomainAudio);
-    validValues->emplace_back(C2DomainOther);
-
-    // There is no invalid value.
-    UNUSED(invalidValues);
-}
-
-template <typename TField>
-void C2CompIntfTest::getTestValues(
-        const C2FieldSupportedValues &validValueInfos,
-        std::vector<TField> *const validValues,
-        std::vector<TField> *const invalidValues) {
-
-    // The supported values are represented by C2Values. C2Value::Primitive needs to
-    // be transformed to a primitive value. This function is one to do that.
-    auto prim2Value = [](const C2Value::Primitive &prim) -> TField {
-        if (std::is_same<TField, int32_t>::value) {
-            return prim.i32;
-        } else if (std::is_same<TField, uint32_t>::value) {
-            return prim.u32;
-        } else if (std::is_same<TField, int64_t>::value) {
-            return prim.i64;
-        } else if (std::is_same<TField, uint64_t>::value) {
-            return prim.u64;
-        } else if (std::is_same<TField, float>::value) {
-            return prim.fp;
-        }
-        static_assert(std::is_same<TField, int32_t>::value ||
-                      std::is_same<TField, uint32_t>::value ||
-                      std::is_same<TField, int64_t>::value ||
-                      std::is_same<TField, uint64_t>::value ||
-                      std::is_same<TField, float>::value, "Invalid TField type.");
-        return 0;
-    };
-
-    // The size of validValueInfos is one.
-    const auto &c2FSV = validValueInfos;
-
-    switch (c2FSV.type) {
-    case C2FieldSupportedValues::type_t::EMPTY: {
-        invalidValues->emplace_back(TField(0));
-        // TODO(hiroh) : Should other invalid values be tested?
-        break;
-    }
-    case C2FieldSupportedValues::type_t::RANGE: {
-        const auto &range = c2FSV.range;
-        auto rmin = prim2Value(range.min);
-        auto rmax = prim2Value(range.max);
-        auto rstep = prim2Value(range.step);
-
-        ASSERT_LE(rmin, rmax);
-
-        if (rstep != 0) {
-            // Increase linear
-            for (auto v = rmin; v <= rmax; v += rstep) {
-                validValues->emplace_back(v);
-            }
-            if (rmin > std::numeric_limits<TField>::min()) {
-                invalidValues->emplace_back(rmin - 1);
-            }
-            if (rmax < std::numeric_limits<TField>::max()) {
-                invalidValues->emplace_back(rmax + 1);
-            }
-            const unsigned int N = validValues->size();
-            if (N >= 2) {
-                if (std::is_same<TField, float>::value) {
-                    invalidValues->emplace_back((validValues->at(0) + validValues->at(1)) / 2);
-                    invalidValues->emplace_back((validValues->at(N - 2) + validValues->at(N - 1)) / 2);
-                } else {
-                    if (rstep > 1) {
-                        invalidValues->emplace_back(validValues->at(0) + 1);
-                        invalidValues->emplace_back(validValues->at(N - 1) - 1);
-                    }
-                }
-            }
-        } else {
-            // There should be two cases, except linear case.
-            // 1. integer geometric case
-            // 2. float geometric case
-
-            auto num = prim2Value(range.num);
-            auto denom = prim2Value(range.denom);
-
-            // If both range.num and range.denom are 1 and step is 0, we should use
-            // VALUES, shouldn't we?
-            ASSERT_FALSE(num == 1 && denom == 1);
-
-            // (num / denom) is not less than 1.
-            ASSERT_FALSE(denom == 0);
-            ASSERT_LE(denom, num);
-            for (auto v = rmin; v <= rmax; v = v * num / denom) {
-                validValues->emplace_back(v);
-            }
-
-            if (rmin > std::numeric_limits<TField>::min()) {
-                invalidValues->emplace_back(rmin - 1);
-            }
-            if (rmax < std::numeric_limits<TField>::max()) {
-                invalidValues->emplace_back(rmax + 1);
-            }
-
-            const unsigned int N = validValues->size();
-            if (N >= 2) {
-                if (std::is_same<TField, float>::value) {
-                    invalidValues->emplace_back((validValues->at(0) + validValues->at(1)) / 2);
-                    invalidValues->emplace_back((validValues->at(N - 2) + validValues->at(N - 1)) / 2);
-                } else {
-                    if (validValues->at(1) - validValues->at(0) > 1) {
-                        invalidValues->emplace_back(validValues->at(0) + 1);
-                    }
-                    if (validValues->at(N - 1) - validValues->at(N - 2) > 1) {
-                        invalidValues->emplace_back(validValues->at(N - 1) - 1);
-                    }
-                }
-            }
-        }
-        break;
-    }
-    case C2FieldSupportedValues::type_t::VALUES: {
-        for (const C2Value::Primitive &prim : c2FSV.values) {
-            validValues->emplace_back(prim2Value(prim));
-        }
-        auto minv = *std::min_element(validValues->begin(), validValues->end());
-        auto maxv = *std::max_element(validValues->begin(), validValues->end());
-        if (minv - 1 > std::numeric_limits<TField>::min()) {
-            invalidValues->emplace_back(minv - 1);
-        }
-        if (maxv + 1 < std::numeric_limits<TField>::max()) {
-            invalidValues->emplace_back(maxv + 1);
-        }
-        break;
-    }
-    case C2FieldSupportedValues::type_t::FLAGS: {
-        // TODO(hiroh) : Implement the case that param.type is FLAGS.
-        break;
-    }
-    }
-}
-
-template <typename T>
-void C2CompIntfTest::testReadOnlyParam(const T &preParam, const T &newParam) {
-    TRACED_FAILURE(configReadOnlyParam(newParam));
-    // Parameter value must not be changed
-    TRACED_FAILURE(queryParamAsExpected(preParam));
-}
-
-template <typename TParam, typename TRealField, typename TField>
-void C2CompIntfTest::testWritableParam(
-        TParam *const param, TRealField *const writableField,
-        const std::vector<TField> &validValues,
-        const std::vector<TField> &invalidValues) {
-    c2_status_t stConfig;
-
-    // Get the parameter's value in the beginning in order to reset the value at the end.
-    TRACED_FAILURE(getValue(param));
-    std::unique_ptr<TParam> defaultParam = makeParamFrom(*param);
-
-    // Test valid values
-    for (const auto &val : validValues) {
-        std::unique_ptr<TParam> preParam = makeParamFrom(*param);
-
-        // Param is try to be changed
-        *writableField = val;
-        TRACED_FAILURE(configWritableParamValidValue(*param, &stConfig));
-        if (stConfig == C2_OK) {
-            TRACED_FAILURE(queryParamAsExpected(*param));
-        } else {
-            // Param is unchanged because a field value conflicts with other field or parameter.
-            TRACED_FAILURE(queryParamAsExpected(*preParam));
-        }
-    }
-
-    // Store the current parameter in order to test |param| is unchanged
-    // after trying to write an invalid value.
-    std::unique_ptr<TParam> lastValidParam = makeParamFrom(*param);
-
-    // Test invalid values
-    for (const auto &val : invalidValues) {
-        // Param is changed
-        *writableField = val;
-        TRACED_FAILURE(configWritableParamInvalidValue(*param));
-        TRACED_FAILURE(queryParamAsExpected(*lastValidParam));
-    }
-    // Reset the parameter by config().
-    TRACED_FAILURE(configWritableParamValidValue(*defaultParam, &stConfig));
-}
-
-template <typename T> void C2CompIntfTest::testUnsupportedParam() {
-    TRACED_FAILURE(queryUnsupportedParam<T>());
-}
-
-template <typename T> void C2CompIntfTest::testSupportedParam() {
-    TRACED_FAILURE(querySupportedParam<T>());
-}
-
-bool isSupportedParam(
-        const C2Param &param,
-        const std::vector<std::shared_ptr<C2ParamDescriptor>> &sParams) {
-    for (const auto &pd : sParams) {
-        if (param.type() == pd->index().type()) {
-            return true;
-        }
-    }
-    return false;
-}
-
-template <typename T>
-void C2CompIntfTest::checkParamPermission(
-    int *const result,
-    const std::vector<std::shared_ptr<C2ParamDescriptor>> &supportedParams) {
-    std::unique_ptr<T> param = makeParam<T>();
-
-    if (!isSupportedParam(*param, supportedParams)) {
-        // If a parameter isn't supported, it just finish after calling testUnsupportedParam().
-        testUnsupportedParam<T>();
-        *result = ParamPermission::UNSUPPORTED;
-        return;
-    }
-
-    testSupportedParam<T>();
-
-    TRACED_FAILURE(getValue(param.get()));
-    std::vector<std::unique_ptr<C2SettingResult>> failures;
-    // Config does not change the parameter, because param is the present param.
-    // This config is executed to find out if a parameter is read-only or writable.
-    c2_status_t stStack = config(param.get(), &failures);
-    if (stStack == C2_BAD_VALUE) {
-        // Read-only
-        std::unique_ptr<T> newParam = makeParam<T>();
-        testReadOnlyParam(*param, *newParam);
-        *result = ParamPermission::READONLY;
-    } else {
-        // Writable
-        EXPECT_EQ(stStack, C2_OK);
-        *result = ParamPermission::WRITABLE;
-    }
-}
-
-void C2CompIntfTest::outputResults(const std::string &name) {
-    std::vector<std::string> params[3];
-    for (const auto &testInfo : mParamResults) {
-        int result = testInfo.result;
-        ASSERT_TRUE(0 <= result && result <= 2);
-        params[result].emplace_back(testInfo.name);
-    }
-    const char *resultString[] = {"Writable", "Read-Only", "Unsupported"};
-    printf("\n----TEST RESULTS (%s)----\n\n", name.c_str());
-    for (int i = 0; i < 3; i++) {
-        printf("[ %s ]\n", resultString[i]);
-        for (const auto &t : params[i]) {
-            printf("%s\n", t.c_str());
-        }
-        printf("\n");
-    }
-}
-
-#define TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, field_name_) \
-    do {                                                                \
-        std::unique_ptr<TParam_> param = makeParam<TParam_>();          \
-        std::vector<C2FieldSupportedValuesQuery> validValueInfos = {    \
-            C2FieldSupportedValuesQuery::Current(                       \
-                    C2ParamField(param.get(), &field_type_name_::field_name_)) \
-        };                                                              \
-        ASSERT_EQ(C2_OK,                                                \
-                  mIntf->querySupportedValues_vb(validValueInfos, C2_DONT_BLOCK));     \
-        ASSERT_EQ(1u, validValueInfos.size());                          \
-        std::vector<decltype(param->field_name_)> validValues;          \
-        std::vector<decltype(param->field_name_)> invalidValues;        \
-        getTestValues(validValueInfos[0].values, &validValues, &invalidValues);   \
-        testWritableParam(param.get(), &param->field_name_, validValues,\
-                          invalidValues);                               \
-    } while (0)
-
-#define TEST_VSSTRUCT_WRITABLE_FIELD(TParam_, field_type_name_)         \
-    do {                                                                \
-        TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, width);  \
-        TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, height); \
-    } while (0)
-
-#define TEST_U32_WRITABLE_FIELD(TParam_, field_type_name_)              \
-  TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, value)
-
-#define TEST_ENUM_WRITABLE_FIELD(TParam_, field_type_name_)             \
-  TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, value)
-
-// TODO(hiroh): Support parameters based on char[] and uint32_t[].
-//#define TEST_STRING_WRITABLE_FIELD(TParam_, field_type_name_)
-// TEST_GENERAL_WRITABLE_FIELD(TParam_, field_type_name_, m.value)
-//#define TEST_U32ARRAY_WRITABLE_FIELD(Tparam_, field_type_name_)
-// TEST_GENERAL_WRITABLE_FIELD(Tparam_, uint32_t[], field_type_name_, values)
-
-#define EACH_TEST(TParam_, field_type_name_, test_name)                 \
-    do {                                                                \
-      int result = 0;                                                   \
-      this->mCurrentParamName = #TParam_;                            \
-      checkParamPermission<TParam_>(&result, supportedParams);          \
-      if (result == ParamPermission::WRITABLE) {                        \
-          test_name(TParam_, field_type_name_);                         \
-      }                                                                 \
-      mParamResults.emplace_back(#TParam_, result);                      \
-  } while (0)
-
-#define EACH_TEST_SELF(type_, test_name) EACH_TEST(type_, type_, test_name)
-#define EACH_TEST_INPUT(type_, test_name) EACH_TEST(type_::input, type_, test_name)
-#define EACH_TEST_OUTPUT(type_, test_name) EACH_TEST(type_::output, type_, test_name)
-void C2CompIntfTest::testMain(std::shared_ptr<C2ComponentInterface> intf,
-                              const std::string &componentName) {
-    setComponent(intf);
-
-    std::vector<std::shared_ptr<C2ParamDescriptor>> supportedParams;
-    ASSERT_EQ(C2_OK, mIntf->querySupportedParams_nb(&supportedParams));
-
-    EACH_TEST_SELF(C2ComponentLatencyInfo, TEST_U32_WRITABLE_FIELD);
-    EACH_TEST_SELF(C2ComponentTemporalInfo, TEST_U32_WRITABLE_FIELD);
-    EACH_TEST_INPUT(C2PortLatencyInfo, TEST_U32_WRITABLE_FIELD);
-    EACH_TEST_OUTPUT(C2PortLatencyInfo, TEST_U32_WRITABLE_FIELD);
-    EACH_TEST_INPUT(C2StreamFormatConfig, TEST_U32_WRITABLE_FIELD);
-    EACH_TEST_OUTPUT(C2StreamFormatConfig, TEST_U32_WRITABLE_FIELD);
-    EACH_TEST_INPUT(C2PortStreamCountConfig, TEST_U32_WRITABLE_FIELD);
-    EACH_TEST_OUTPUT(C2PortStreamCountConfig, TEST_U32_WRITABLE_FIELD);
-
-    EACH_TEST_SELF(C2ComponentDomainInfo, TEST_ENUM_WRITABLE_FIELD);
-
-    // TODO(hiroh): Support parameters based on uint32_t[] and char[].
-    // EACH_TEST_INPUT(C2PortMimeConfig, TEST_STRING_WRITABLE_FIELD);
-    // EACH_TEST_OUTPUT(C2PortMimeConfig, TEST_STRING_WRITABLE_FIELD);
-    // EACH_TEST_INPUT(C2StreamMimeConfig, TEST_STRING_WRITABLE_FIELD);
-    // EACH_TEST_OUTPUT(C2StreamMimeConfig, TEST_STRING_WRITABLE_FIELD);
-
-    // EACH_TEST_SELF(C2SupportedParamsInfo, TEST_U32ARRAY_WRITABLE_FIELD);
-    // EACH_TEST_SELF(C2RequiredParamsInfo, TEST_U32ARRAY_WRITABLE_FIELD);
-    // EACH_TEST_SELF(C2ReadOnlyParamsInfo, TEST_U32ARRAY_WRITABLE_FIELD);
-    // EACH_TEST_SELF(C2RequestedInfosInfo, TEST_U32ARRAY_WRITABLE_FIELD);
-
-    EACH_TEST_INPUT(C2VideoSizeStreamInfo, TEST_VSSTRUCT_WRITABLE_FIELD);
-    EACH_TEST_OUTPUT(C2VideoSizeStreamInfo, TEST_VSSTRUCT_WRITABLE_FIELD);
-    EACH_TEST_INPUT(C2VideoSizeStreamTuning, TEST_VSSTRUCT_WRITABLE_FIELD);
-    EACH_TEST_OUTPUT(C2VideoSizeStreamTuning, TEST_VSSTRUCT_WRITABLE_FIELD);
-    EACH_TEST_INPUT(C2MaxVideoSizeHintPortSetting, TEST_VSSTRUCT_WRITABLE_FIELD);
-    EACH_TEST_OUTPUT(C2MaxVideoSizeHintPortSetting, TEST_VSSTRUCT_WRITABLE_FIELD);
-
-    outputResults(componentName);
-    resetResults();
-}
-
-TEST_F(C2CompIntfTest, C2V4L2CodecIntf) {
-
-    // Read a shared object library.
-    void* compLib = dlopen("system/lib/libv4l2_codec2.so", RTLD_NOW);
-
-    if (!compLib) {
-        printf("Cannot open library: %s.\n", dlerror());
-        FAIL();
-        return;
-    }
-
-    typedef C2ComponentStore* create_t();
-    create_t* create_store= (create_t*) dlsym(compLib, "create_store");
-    const char* dlsym_error = dlerror();
-    if (dlsym_error) {
-        printf("Cannot load symbol create: %s.\n", dlsym_error);
-        FAIL();
-        return;
-    }
-
-    typedef void destroy_t(C2ComponentStore*);
-    destroy_t* destroy_store = (destroy_t*) dlsym(compLib, "destroy_store");
-    dlsym_error = dlerror();
-    if (dlsym_error) {
-        printf("Cannot load symbol destroy: %s.\n", dlsym_error);
-        FAIL();
-        return;
-    }
-
-    std::shared_ptr<C2ComponentStore> componentStore(create_store(), destroy_store);
-    std::shared_ptr<C2ComponentInterface> componentIntf;
-    componentStore->createInterface("v4l2.decoder", &componentIntf);
-    auto componentName = "C2V4L2Codec";
-    testMain(componentIntf, componentName);
-}
-
-} // namespace android
diff --git a/media/libstagefright/codec2/tests/C2Param_test.cpp b/media/libstagefright/codec2/tests/C2Param_test.cpp
deleted file mode 100644
index fcfbafd..0000000
--- a/media/libstagefright/codec2/tests/C2Param_test.cpp
+++ /dev/null
@@ -1,2931 +0,0 @@
-/*
- * Copyright 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "C2Param_test"
-
-#include <gtest/gtest.h>
-
-#define __C2_GENERATE_GLOBAL_VARS__
-#include <util/C2ParamUtils.h>
-#include <C2ParamDef.h>
-
-void PrintTo(const _C2FieldId &id, ::std::ostream* os) {
-    *os << "@" << id._mOffset << "+" << id._mSize;
-}
-
-void PrintTo(const C2FieldDescriptor &fd, ::std::ostream *os) {
-    using FD=C2FieldDescriptor;
-    switch (fd.type()) {
-    case FD::INT32: *os << "i32"; break;
-    case FD::INT64: *os << "i64"; break;
-    case FD::UINT32: *os << "u32"; break;
-    case FD::UINT64: *os << "u64"; break;
-    case FD::FLOAT: *os << "float"; break;
-    case FD::STRING: *os << "char"; break;
-    case FD::BLOB: *os << "u8"; break;
-    default:
-        if (fd.type() & FD::STRUCT_FLAG) {
-            *os << "struct-" << (fd.type() & ~FD::STRUCT_FLAG);
-        } else {
-            *os << "type-" << fd.type();
-        }
-    }
-    *os << " " << fd.name();
-    if (fd.extent() > 1) {
-        *os << "[" << fd.extent() << "]";
-    } else if (fd.extent() == 0) {
-        *os << "[]";
-    }
-    *os << " (";
-    PrintTo(fd._mFieldId, os);
-    *os << "*" << fd.extent() << ")";
-}
-
-enum C2ParamIndexType : C2Param::type_index_t {
-    kParamIndexNumber,
-    kParamIndexNumbers,
-    kParamIndexNumber2,
-    kParamIndexVendorStart = C2Param::TYPE_INDEX_VENDOR_START,
-    kParamIndexVendorNumbers,
-};
-
-void ffff(int(*)(int)) {}
-
-/* ============================= STRUCT DECLARATION AND DESCRIPTION ============================= */
-
-typedef C2FieldDescriptor FD;
-
-class C2ParamTest : public ::testing::Test {
-};
-
-class C2ParamTest_ParamFieldList
-        : public ::testing::TestWithParam<std::initializer_list<const C2FieldDescriptor>> {
-};
-
-enum {
-    kParamIndexSize,
-    kParamIndexTestA,
-    kParamIndexTestB,
-    kParamIndexTestFlexS32,
-    kParamIndexTestFlexEndS32,
-    kParamIndexTestFlexS64,
-    kParamIndexTestFlexEndS64,
-    kParamIndexTestFlexSize,
-    kParamIndexTestFlexEndSize,
-};
-
-struct C2SizeStruct {
-    int32_t width;
-    int32_t height;
-    enum : uint32_t { CORE_INDEX = kParamIndexSize };                        // <= needed for C2FieldDescriptor
-    const static std::initializer_list<const C2FieldDescriptor> FIELD_LIST;  // <= needed for C2FieldDescriptor
-    const static FD::type_t TYPE = (FD::type_t)(CORE_INDEX | FD::STRUCT_FLAG);
-};
-
-DEFINE_NO_NAMED_VALUES_FOR(C2SizeStruct)
-
-// Test 1. define a structure without any helper methods
-
-bool operator==(const C2FieldDescriptor &a, const C2FieldDescriptor &b) {
-    return a.type() == b.type()
-            && a.extent() == b.extent()
-            && strcmp(a.name(), b.name()) == 0
-            && a._mFieldId == b._mFieldId;
-}
-
-struct C2TestStruct_A {
-    int32_t signed32;
-    int64_t signed64[2];
-    uint32_t unsigned32[1];
-    uint64_t unsigned64;
-    float fp32;
-    C2SizeStruct sz[3];
-    uint8_t blob[100];
-    char string[100];
-    bool yesNo[100];
-
-    const static std::initializer_list<const C2FieldDescriptor> FIELD_LIST;
-    // enum : uint32_t { CORE_INDEX = kParamIndexTest };
-    // typedef C2TestStruct_A _type;
-} __attribute__((packed));
-
-const std::initializer_list<const C2FieldDescriptor> C2TestStruct_A::FIELD_LIST =
-    { { FD::INT32,    1, "s32",   0, 4 },
-      { FD::INT64,    2, "s64",   4, 8 },
-      { FD::UINT32,   1, "u32",  20, 4 },
-      { FD::UINT64,   1, "u64",  24, 8 },
-      { FD::FLOAT,    1, "fp",   32, 4 },
-      { C2SizeStruct::TYPE, 3, "size", 36, 8 },
-      { FD::BLOB,   100, "blob", 60, 1 },
-      { FD::STRING, 100, "str", 160, 1 },
-      { FD::BLOB,   100, "y-n", 260, 1 } };
-
-TEST_P(C2ParamTest_ParamFieldList, VerifyStruct) {
-    std::vector<const C2FieldDescriptor> fields = GetParam(), expected = C2TestStruct_A::FIELD_LIST;
-
-    // verify first field descriptor
-    EXPECT_EQ(FD::INT32, fields[0].type());
-    EXPECT_STREQ("s32", fields[0].name());
-    EXPECT_EQ(1u, fields[0].extent());
-    EXPECT_EQ(_C2FieldId(0, 4), fields[0]._mFieldId);
-
-    EXPECT_EQ(expected[0], fields[0]);
-    EXPECT_EQ(expected[1], fields[1]);
-    EXPECT_EQ(expected[2], fields[2]);
-    EXPECT_EQ(expected[3], fields[3]);
-    EXPECT_EQ(expected[4], fields[4]);
-    EXPECT_EQ(expected[5], fields[5]);
-    EXPECT_EQ(expected[6], fields[6]);
-    EXPECT_EQ(expected[7], fields[7]);
-    for (size_t i = 8; i < fields.size() && i < expected.size(); ++i) {
-        EXPECT_EQ(expected[i], fields[i]);
-    }
-}
-
-INSTANTIATE_TEST_CASE_P(InitializerList, C2ParamTest_ParamFieldList, ::testing::Values(C2TestStruct_A::FIELD_LIST));
-
-// define fields using C2FieldDescriptor pointer constructor
-const std::initializer_list<const C2FieldDescriptor> C2TestStruct_A_FD_PTR_fieldList =
-    { C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->signed32,   "s32"),
-      C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->signed64,   "s64"),
-      C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->unsigned32, "u32"),
-      C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->unsigned64, "u64"),
-      C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->fp32,      "fp"),
-      C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->sz,       "size"),
-      C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->blob,       "blob"),
-      C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->string,     "str"),
-    //  C2FieldDescriptor(&((C2TestStruct_A*)(nullptr))->yesNo,      "y-n")
-    };
-
-INSTANTIATE_TEST_CASE_P(PointerConstructor, C2ParamTest_ParamFieldList, ::testing::Values(C2TestStruct_A_FD_PTR_fieldList));
-
-// define fields using C2FieldDescriptor member-pointer constructor
-const std::initializer_list<const C2FieldDescriptor> C2TestStruct_A_FD_MEM_PTR_fieldList =
-    { C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::signed32,   "s32"),
-      C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::signed64,   "s64"),
-      C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::unsigned32, "u32"),
-      C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::unsigned64, "u64"),
-      C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::fp32,      "fp"),
-      C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::sz,       "size"),
-      C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::blob,       "blob"),
-      C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::string,     "str"),
-    //  C2FieldDescriptor((C2TestStruct_A*)0, &C2TestStruct_A::yesNo,      "y-n")
-    };
-
-INSTANTIATE_TEST_CASE_P(MemberPointerConstructor, C2ParamTest_ParamFieldList, ::testing::Values(C2TestStruct_A_FD_MEM_PTR_fieldList));
-
-// Test 2. define a structure with two-step helper methods
-
-struct C2TestAStruct {
-    int32_t signed32;
-    int64_t signed64[2];
-    uint32_t unsigned32[1];
-    uint64_t unsigned64;
-    float fp32;
-    C2SizeStruct sz[3];
-    uint8_t blob[100];
-    char string[100];
-    bool yesNo[100];
-
-private: // test access level
-    DEFINE_C2STRUCT(TestA)
-} C2_PACK;
-
-DESCRIBE_C2STRUCT(TestA, {
-    C2FIELD(signed32, "s32")
-    C2FIELD(signed64, "s64")
-    C2FIELD(unsigned32, "u32")
-    C2FIELD(unsigned64, "u64")
-    C2FIELD(fp32, "fp")
-    C2FIELD(sz, "size")
-    C2FIELD(blob, "blob")
-    C2FIELD(string, "str")
-    // C2FIELD(yesNo, "y-n")
-}) // ; optional
-
-INSTANTIATE_TEST_CASE_P(DescribeStruct2Step, C2ParamTest_ParamFieldList, ::testing::Values(C2TestAStruct::FIELD_LIST));
-
-// Test 3. define a structure with one-step helper method
-
-struct C2TestBStruct {
-    int32_t signed32;
-    int64_t signed64[2];
-    uint32_t unsigned32[1];
-    uint64_t unsigned64;
-    float fp32;
-    C2SizeStruct sz[3];
-    uint8_t blob[100];
-    char string[100];
-    bool yesNo[100];
-
-private: // test access level
-    DEFINE_AND_DESCRIBE_C2STRUCT(TestB)
-
-    C2FIELD(signed32, "s32")
-    C2FIELD(signed64, "s64")
-    C2FIELD(unsigned32, "u32")
-    C2FIELD(unsigned64, "u64")
-    C2FIELD(fp32, "fp")
-    C2FIELD(sz, "size")
-    C2FIELD(blob, "blob")
-    C2FIELD(string, "str")
-    // C2FIELD(yesNo, "y-n")
-};
-
-INSTANTIATE_TEST_CASE_P(DescribeStruct1Step, C2ParamTest_ParamFieldList, ::testing::Values(C2TestBStruct::FIELD_LIST));
-
-// Test 4. flexible members
-
-template<typename T>
-class C2ParamTest_FlexParamFieldList : public ::testing::Test {
-protected:
-    using type_t=FD::type_t;
-
-    // static std::initializer_list<std::initializer_list<const C2FieldDescriptor>>
-    static std::vector<std::vector<const C2FieldDescriptor>>
-            GetLists();
-
-    constexpr static type_t FlexType =
-            std::is_same<T, int32_t>::value ? FD::INT32 :
-            std::is_same<T, int64_t>::value ? FD::INT64 :
-            std::is_same<T, uint32_t>::value ? FD::UINT32 :
-            std::is_same<T, uint64_t>::value ? FD::UINT64 :
-            std::is_same<T, float>::value ? FD::FLOAT :
-            std::is_same<T, uint8_t>::value ? FD::BLOB :
-            std::is_same<T, char>::value ? FD::STRING :
-            std::is_same<T, C2SizeStruct>::value ? C2SizeStruct::TYPE : (type_t)0;
-    constexpr static size_t FLEX_SIZE = sizeof(T);
-};
-
-typedef ::testing::Types<int32_t, int64_t, C2SizeStruct> FlexTypes;
-TYPED_TEST_CASE(C2ParamTest_FlexParamFieldList, FlexTypes);
-
-TYPED_TEST(C2ParamTest_FlexParamFieldList, VerifyStruct) {
-    for (auto a : this->GetLists()) {
-        std::vector<const C2FieldDescriptor> fields = a;
-        if (fields.size() > 1) {
-            EXPECT_EQ(2u, fields.size());
-            EXPECT_EQ(C2FieldDescriptor(FD::INT32, 1, "s32", 0, 4), fields[0]);
-            EXPECT_EQ(C2FieldDescriptor(this->FlexType, 0, "flex", 4, this->FLEX_SIZE),
-                      fields[1]);
-        } else {
-            EXPECT_EQ(1u, fields.size());
-            EXPECT_EQ(C2FieldDescriptor(this->FlexType, 0, "flex", 0, this->FLEX_SIZE),
-                      fields[0]);
-        }
-    }
-}
-
-struct C2TestStruct_FlexS32 {
-    int32_t mFlex[];
-
-    const static std::initializer_list<const C2FieldDescriptor> FIELD_LIST;
-    // enum : uint32_t { CORE_INDEX = kParamIndexTestFlex, FLEX_SIZE = 4 };
-    // typedef C2TestStruct_FlexS32 _type;
-    // typedef int32_t FlexType;
-};
-
-const std::initializer_list<const C2FieldDescriptor> C2TestStruct_FlexS32::FIELD_LIST = {
-    { FD::INT32, 0, "flex", 0, 4 }
-};
-
-struct C2TestStruct_FlexEndS32 {
-    int32_t signed32;
-    int32_t mFlex[];
-
-    const static std::initializer_list<const C2FieldDescriptor> FIELD_LIST;
-    // enum : uint32_t { CORE_INDEX = kParamIndexTestFlexEnd, FLEX_SIZE = 4 };
-    // typedef C2TestStruct_FlexEnd _type;
-    // typedef int32_t FlexType;
-};
-
-const std::initializer_list<const C2FieldDescriptor> C2TestStruct_FlexEndS32::FIELD_LIST = {
-    { FD::INT32, 1, "s32", 0, 4 },
-    { FD::INT32, 0, "flex", 4, 4 },
-};
-
-const static std::initializer_list<const C2FieldDescriptor> C2TestStruct_FlexEndS32_ptr_fieldList = {
-    C2FieldDescriptor(&((C2TestStruct_FlexEndS32*)0)->signed32, "s32"),
-    C2FieldDescriptor(&((C2TestStruct_FlexEndS32*)0)->mFlex, "flex"),
-};
-
-struct C2TestFlexS32Struct {
-    int32_t mFlexSigned32[];
-private: // test access level
-    C2TestFlexS32Struct() {}
-
-    DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(TestFlexS32, mFlexSigned32)
-    C2FIELD(mFlexSigned32, "flex")
-};
-
-struct C2TestFlexEndS32Struct {
-    int32_t signed32;
-    int32_t mFlexSigned32[];
-private: // test access level
-    C2TestFlexEndS32Struct() {}
-
-    DEFINE_FLEX_C2STRUCT(TestFlexEndS32, mFlexSigned32)
-} C2_PACK;
-
-DESCRIBE_C2STRUCT(TestFlexEndS32, {
-    C2FIELD(signed32, "s32")
-    C2FIELD(mFlexSigned32, "flex")
-}) // ; optional
-
-template<>
-std::vector<std::vector<const C2FieldDescriptor>>
-//std::initializer_list<std::initializer_list<const C2FieldDescriptor>>
-C2ParamTest_FlexParamFieldList<int32_t>::GetLists() {
-    return {
-        C2TestStruct_FlexS32::FIELD_LIST,
-        C2TestStruct_FlexEndS32::FIELD_LIST,
-        C2TestStruct_FlexEndS32_ptr_fieldList,
-        C2TestFlexS32Struct::FIELD_LIST,
-        C2TestFlexEndS32Struct::FIELD_LIST,
-    };
-}
-
-struct C2TestStruct_FlexS64 {
-    int64_t mFlexSigned64[];
-
-    const static std::initializer_list<const C2FieldDescriptor> FIELD_LIST;
-    // enum : uint32_t { CORE_INDEX = kParamIndexTestFlexS64, FLEX_SIZE = 8 };
-    // typedef C2TestStruct_FlexS64 _type;
-    // typedef int64_t FlexType;
-};
-
-const std::initializer_list<const C2FieldDescriptor> C2TestStruct_FlexS64::FIELD_LIST = {
-    { FD::INT64, 0, "flex", 0, 8 }
-};
-
-struct C2TestStruct_FlexEndS64 {
-    int32_t signed32;
-    int64_t mSigned64Flex[];
-
-    const static std::initializer_list<const C2FieldDescriptor> FIELD_LIST;
-    // enum : uint32_t { CORE_INDEX = C2TestStruct_FlexEndS64, FLEX_SIZE = 8 };
-    // typedef C2TestStruct_FlexEndS64 _type;
-    // typedef int64_t FlexType;
-};
-
-const std::initializer_list<const C2FieldDescriptor> C2TestStruct_FlexEndS64::FIELD_LIST = {
-    { FD::INT32, 1, "s32", 0, 4 },
-    { FD::INT64, 0, "flex", 4, 8 },
-};
-
-struct C2TestFlexS64Struct {
-    int64_t mFlexSigned64[];
-    C2TestFlexS64Struct() {}
-
-    DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(TestFlexS64, mFlexSigned64)
-    C2FIELD(mFlexSigned64, "flex")
-};
-
-struct C2TestFlexEndS64Struct {
-    int32_t signed32;
-    int64_t mFlexSigned64[];
-    C2TestFlexEndS64Struct() {}
-
-    DEFINE_FLEX_C2STRUCT(TestFlexEndS64, mFlexSigned64)
-} C2_PACK;
-
-DESCRIBE_C2STRUCT(TestFlexEndS64, {
-    C2FIELD(signed32, "s32")
-    C2FIELD(mFlexSigned64, "flex")
-}) // ; optional
-
-template<>
-std::vector<std::vector<const C2FieldDescriptor>>
-//std::initializer_list<std::initializer_list<const C2FieldDescriptor>>
-C2ParamTest_FlexParamFieldList<int64_t>::GetLists() {
-    return {
-        C2TestStruct_FlexS64::FIELD_LIST,
-        C2TestStruct_FlexEndS64::FIELD_LIST,
-        C2TestFlexS64Struct::FIELD_LIST,
-        C2TestFlexEndS64Struct::FIELD_LIST,
-    };
-}
-
-struct C2TestStruct_FlexSize {
-    C2SizeStruct mFlexSize[];
-
-    const static std::initializer_list<const C2FieldDescriptor> FIELD_LIST;
-    // enum : uint32_t { CORE_INDEX = kParamIndexTestFlexSize, FLEX_SIZE = 8 };
-    // typedef C2TestStruct_FlexSize _type;
-    // typedef C2SizeStruct FlexType;
-};
-
-const std::initializer_list<const C2FieldDescriptor> C2TestStruct_FlexSize::FIELD_LIST = {
-    { C2SizeStruct::TYPE, 0, "flex", 0, sizeof(C2SizeStruct) }
-};
-
-struct C2TestStruct_FlexEndSize {
-    int32_t signed32;
-    C2SizeStruct mSizeFlex[];
-
-    const static std::initializer_list<const C2FieldDescriptor> FIELD_LIST;
-    // enum : uint32_t { CORE_INDEX = C2TestStruct_FlexEndSize, FLEX_SIZE = 8 };
-    // typedef C2TestStruct_FlexEndSize _type;
-    // typedef C2SizeStruct FlexType;
-};
-
-const std::initializer_list<const C2FieldDescriptor> C2TestStruct_FlexEndSize::FIELD_LIST = {
-    { FD::INT32, 1, "s32", 0, 4 },
-    { C2SizeStruct::TYPE, 0, "flex", 4, sizeof(C2SizeStruct) },
-};
-
-struct C2TestFlexSizeStruct {
-    C2SizeStruct mFlexSize[];
-    C2TestFlexSizeStruct() {}
-
-    DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(TestFlexSize, mFlexSize)
-    C2FIELD(mFlexSize, "flex")
-};
-
-struct C2TestFlexEndSizeStruct {
-    int32_t signed32;
-    C2SizeStruct mFlexSize[];
-    C2TestFlexEndSizeStruct() {}
-
-    DEFINE_FLEX_C2STRUCT(TestFlexEndSize, mFlexSize)
-} C2_PACK;
-
-DESCRIBE_C2STRUCT(TestFlexEndSize, {
-    C2FIELD(signed32, "s32")
-    C2FIELD(mFlexSize, "flex")
-}) // ; optional
-
-struct C2TestBaseFlexEndSizeStruct {
-    int32_t signed32;
-    C2SizeStruct mFlexSize[];
-    C2TestBaseFlexEndSizeStruct() {}
-
-    DEFINE_BASE_FLEX_C2STRUCT(TestBaseFlexEndSize, mFlexSize)
-} C2_PACK;
-
-DESCRIBE_C2STRUCT(TestBaseFlexEndSize, {
-    C2FIELD(signed32, "s32")
-    C2FIELD(mFlexSize, "flex")
-}) // ; optional
-
-struct C2TestBaseFlexEndSize2Struct {
-    int32_t signed32;
-    C2SizeStruct mFlexSize[];
-    C2TestBaseFlexEndSize2Struct() {}
-
-    DEFINE_AND_DESCRIBE_BASE_FLEX_C2STRUCT(TestBaseFlexEndSize2, mFlexSize)
-    C2FIELD(signed32, "s32")
-    C2FIELD(mFlexSize, "flex")
-};
-
-template<>
-std::vector<std::vector<const C2FieldDescriptor>>
-//std::initializer_list<std::initializer_list<const C2FieldDescriptor>>
-C2ParamTest_FlexParamFieldList<C2SizeStruct>::GetLists() {
-    return {
-        C2TestStruct_FlexSize::FIELD_LIST,
-        C2TestStruct_FlexEndSize::FIELD_LIST,
-        C2TestFlexSizeStruct::FIELD_LIST,
-        C2TestFlexEndSizeStruct::FIELD_LIST,
-        C2TestBaseFlexEndSizeStruct::FIELD_LIST,
-        C2TestBaseFlexEndSize2Struct::FIELD_LIST,
-    };
-}
-
-TEST_F(C2ParamTest, FieldId) {
-    // pointer constructor
-    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&((C2TestStruct_A*)0)->signed32));
-    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&((C2TestStruct_A*)0)->signed64));
-    EXPECT_EQ(_C2FieldId(20, 4), _C2FieldId(&((C2TestStruct_A*)0)->unsigned32));
-    EXPECT_EQ(_C2FieldId(24, 8), _C2FieldId(&((C2TestStruct_A*)0)->unsigned64));
-    EXPECT_EQ(_C2FieldId(32, 4), _C2FieldId(&((C2TestStruct_A*)0)->fp32));
-    EXPECT_EQ(_C2FieldId(36, 8), _C2FieldId(&((C2TestStruct_A*)0)->sz));
-    EXPECT_EQ(_C2FieldId(60, 1), _C2FieldId(&((C2TestStruct_A*)0)->blob));
-    EXPECT_EQ(_C2FieldId(160, 1), _C2FieldId(&((C2TestStruct_A*)0)->string));
-    EXPECT_EQ(_C2FieldId(260, 1), _C2FieldId(&((C2TestStruct_A*)0)->yesNo));
-
-    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&((C2TestFlexEndSizeStruct*)0)->signed32));
-    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&((C2TestFlexEndSizeStruct*)0)->mFlexSize));
-
-    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&((C2TestBaseFlexEndSizeStruct*)0)->signed32));
-    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&((C2TestBaseFlexEndSizeStruct*)0)->mFlexSize));
-
-    // member pointer constructor
-    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::signed32));
-    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::signed64));
-    EXPECT_EQ(_C2FieldId(20, 4), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::unsigned32));
-    EXPECT_EQ(_C2FieldId(24, 8), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::unsigned64));
-    EXPECT_EQ(_C2FieldId(32, 4), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::fp32));
-    EXPECT_EQ(_C2FieldId(36, 8), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::sz));
-    EXPECT_EQ(_C2FieldId(60, 1), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::blob));
-    EXPECT_EQ(_C2FieldId(160, 1), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::string));
-    EXPECT_EQ(_C2FieldId(260, 1), _C2FieldId((C2TestStruct_A*)0, &C2TestStruct_A::yesNo));
-
-    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId((C2TestFlexEndSizeStruct*)0, &C2TestFlexEndSizeStruct::signed32));
-    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId((C2TestFlexEndSizeStruct*)0, &C2TestFlexEndSizeStruct::mFlexSize));
-
-    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId((C2TestBaseFlexEndSizeStruct*)0, &C2TestBaseFlexEndSizeStruct::signed32));
-    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId((C2TestBaseFlexEndSizeStruct*)0, &C2TestBaseFlexEndSizeStruct::mFlexSize));
-
-    // member pointer sans type pointer
-    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&C2TestStruct_A::signed32));
-    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&C2TestStruct_A::signed64));
-    EXPECT_EQ(_C2FieldId(20, 4), _C2FieldId(&C2TestStruct_A::unsigned32));
-    EXPECT_EQ(_C2FieldId(24, 8), _C2FieldId(&C2TestStruct_A::unsigned64));
-    EXPECT_EQ(_C2FieldId(32, 4), _C2FieldId(&C2TestStruct_A::fp32));
-    EXPECT_EQ(_C2FieldId(36, 8), _C2FieldId(&C2TestStruct_A::sz));
-    EXPECT_EQ(_C2FieldId(60, 1), _C2FieldId(&C2TestStruct_A::blob));
-    EXPECT_EQ(_C2FieldId(160, 1), _C2FieldId(&C2TestStruct_A::string));
-    EXPECT_EQ(_C2FieldId(260, 1), _C2FieldId(&C2TestStruct_A::yesNo));
-
-    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&C2TestFlexEndSizeStruct::signed32));
-    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&C2TestFlexEndSizeStruct::mFlexSize));
-
-    EXPECT_EQ(_C2FieldId(0, 4), _C2FieldId(&C2TestBaseFlexEndSizeStruct::signed32));
-    EXPECT_EQ(_C2FieldId(4, 8), _C2FieldId(&C2TestBaseFlexEndSizeStruct::mFlexSize));
-
-    typedef C2GlobalParam<C2Info, C2TestAStruct> C2TestAInfo;
-    typedef C2GlobalParam<C2Info, C2TestFlexEndSizeStruct> C2TestFlexEndSizeInfo;
-    typedef C2GlobalParam<C2Info, C2TestBaseFlexEndSizeStruct, kParamIndexTestFlexEndSize> C2TestFlexEndSizeInfoFromBase;
-
-    // pointer constructor in C2Param
-    EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&((C2TestAInfo*)0)->signed32));
-    EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&((C2TestAInfo*)0)->signed64));
-    EXPECT_EQ(_C2FieldId(28, 4), _C2FieldId(&((C2TestAInfo*)0)->unsigned32));
-    EXPECT_EQ(_C2FieldId(32, 8), _C2FieldId(&((C2TestAInfo*)0)->unsigned64));
-    EXPECT_EQ(_C2FieldId(40, 4), _C2FieldId(&((C2TestAInfo*)0)->fp32));
-    EXPECT_EQ(_C2FieldId(44, 8), _C2FieldId(&((C2TestAInfo*)0)->sz));
-    EXPECT_EQ(_C2FieldId(68, 1), _C2FieldId(&((C2TestAInfo*)0)->blob));
-    EXPECT_EQ(_C2FieldId(168, 1), _C2FieldId(&((C2TestAInfo*)0)->string));
-    EXPECT_EQ(_C2FieldId(268, 1), _C2FieldId(&((C2TestAInfo*)0)->yesNo));
-
-    EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&((C2TestFlexEndSizeInfo*)0)->m.signed32));
-    EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&((C2TestFlexEndSizeInfo*)0)->m.mFlexSize));
-
-    EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&((C2TestFlexEndSizeInfoFromBase*)0)->m.signed32));
-    EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&((C2TestFlexEndSizeInfoFromBase*)0)->m.mFlexSize));
-
-    // member pointer in C2Param
-    EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::signed32));
-    EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::signed64));
-    EXPECT_EQ(_C2FieldId(28, 4), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::unsigned32));
-    EXPECT_EQ(_C2FieldId(32, 8), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::unsigned64));
-    EXPECT_EQ(_C2FieldId(40, 4), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::fp32));
-    EXPECT_EQ(_C2FieldId(44, 8), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::sz));
-    EXPECT_EQ(_C2FieldId(68, 1), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::blob));
-    EXPECT_EQ(_C2FieldId(168, 1), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::string));
-    EXPECT_EQ(_C2FieldId(268, 1), _C2FieldId((C2TestAInfo*)0, &C2TestAInfo::yesNo));
-
-    // NOTE: cannot use a member pointer for flex params due to introduction of 'm'
-    // EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&C2TestFlexEndSizeInfo::m.signed32));
-    // EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&C2TestFlexEndSizeInfo::m.mFlexSize));
-
-    // EXPECT_EQ(_C2FieldId(8, 4), _C2FieldId(&C2TestFlexEndSizeInfoFromBase::m.signed32));
-    // EXPECT_EQ(_C2FieldId(12, 8), _C2FieldId(&C2TestFlexEndSizeInfoFromBase::m.mFlexSize));
-
-
-}
-
-struct S32 {
-    template<typename T, class B=typename std::remove_extent<T>::type>
-    inline S32(const T*) {
-        static_assert(!std::is_array<T>::value, "should not be an array");
-        static_assert(std::is_same<B, int32_t>::value, "should be int32_t");
-    }
-};
-
-struct FLX {
-    template<typename U, typename T, class B=typename std::remove_extent<T>::type>
-    inline FLX(const T*, const U*) {
-        static_assert(std::is_array<T>::value, "should be an array");
-        static_assert(std::extent<T>::value == 0, "should be an array of 0 extent");
-        static_assert(std::is_same<B, U>::value, "should be type U");
-    }
-};
-
-struct MP {
-    template<typename U, typename T, typename ExpectedU, typename UnexpectedU>
-    inline MP(T U::*, const ExpectedU*, const UnexpectedU*) {
-        static_assert(!std::is_same<U, UnexpectedU>::value, "should not be member pointer of the base type");
-        static_assert(std::is_same<U, ExpectedU>::value, "should be member pointer of the derived type");
-    }
-
-    template<typename U, typename T, typename B, typename D>
-    inline MP(T D::*, const D*) { }
-};
-
-void compiledStatic_arrayTypePropagationTest() {
-    (void)S32(&((C2TestFlexEndS32Struct *)0)->signed32);
-    (void)FLX(&((C2TestFlexEndS32Struct *)0)->mFlexSigned32, (int32_t*)0);
-    (void)FLX(&((C2TestFlexS32Struct *)0)->mFlexSigned32, (int32_t*)0);
-
-    typedef C2GlobalParam<C2Info, C2TestAStruct> C2TestAInfo;
-
-    // TRICKY: &derivedClass::baseMember has type of baseClass::*
-    static_assert(std::is_same<decltype(&C2TestAInfo::signed32), int32_t C2TestAStruct::*>::value,
-                  "base member pointer should have base class in type");
-
-    // therefore, member pointer expands to baseClass::* in templates
-    (void)MP(&C2TestAInfo::signed32,
-             (C2TestAStruct*)0 /* expected */, (C2TestAInfo*)0 /* unexpected */);
-    // but can be cast to derivedClass::*
-    (void)MP((int32_t C2TestAInfo::*)&C2TestAInfo::signed32,
-             (C2TestAInfo*)0 /* expected */, (C2TestAStruct*)0 /* unexpected */);
-
-    // TRICKY: baseClass::* does not autoconvert to derivedClass::* even in templates
-    // (void)MP(&C2TestAInfo::signed32, (C2TestAInfo*)0);
-}
-
-TEST_F(C2ParamTest, MemberPointerCast) {
-    typedef C2GlobalParam<C2Info, C2TestAStruct> C2TestAInfo;
-
-    static_assert(offsetof(C2TestAInfo, signed32) == 8, "offset should be 8");
-    constexpr int32_t C2TestAStruct::* s32ptr = &C2TestAInfo::signed32;
-    constexpr int32_t C2TestAInfo::* s32ptr_derived = (int32_t C2TestAStruct::*)&C2TestAInfo::signed32;
-    constexpr int32_t C2TestAInfo::* s32ptr_cast2derived = (int32_t C2TestAInfo::*)s32ptr;
-    C2TestAInfo *info = (C2TestAInfo *)256;
-    C2TestAStruct *strukt = (C2TestAStruct *)info;
-    int32_t *info_s32_derived = &(info->*s32ptr_derived);
-    int32_t *info_s32_cast2derived = &(info->*s32ptr_cast2derived);
-    int32_t *info_s32 = &(info->*s32ptr);
-    int32_t *strukt_s32 = &(strukt->*s32ptr);
-
-    EXPECT_EQ(256u, (uintptr_t)info);
-    EXPECT_EQ(264u, (uintptr_t)strukt);
-    EXPECT_EQ(264u, (uintptr_t)info_s32_derived);
-    EXPECT_EQ(264u, (uintptr_t)info_s32_cast2derived);
-    EXPECT_EQ(264u, (uintptr_t)info_s32);
-    EXPECT_EQ(264u, (uintptr_t)strukt_s32);
-
-    typedef C2GlobalParam<C2Info, C2TestFlexEndSizeStruct> C2TestFlexEndSizeInfo;
-    static_assert(offsetof(C2TestFlexEndSizeInfo, m.signed32) == 8, "offset should be 8");
-    static_assert(offsetof(C2TestFlexEndSizeInfo, m.mFlexSize) == 12, "offset should be 12");
-
-    typedef C2GlobalParam<C2Info, C2TestBaseFlexEndSizeStruct, kParamIndexTestFlexEndSize> C2TestFlexEndSizeInfoFromBase;
-    static_assert(offsetof(C2TestFlexEndSizeInfoFromBase, m.signed32) == 8, "offset should be 8");
-    static_assert(offsetof(C2TestFlexEndSizeInfoFromBase, m.mFlexSize) == 12, "offset should be 12");
-}
-
-/* ===================================== PARAM USAGE TESTS ===================================== */
-
-struct C2NumberStruct {
-    int32_t mNumber;
-    C2NumberStruct() {}
-    C2NumberStruct(int32_t _number) : mNumber(_number) {}
-
-    DEFINE_AND_DESCRIBE_C2STRUCT(Number)
-    C2FIELD(mNumber, "number")
-};
-
-struct C2NumberBaseStruct {
-    int32_t mNumber;
-    C2NumberBaseStruct() {}
-    C2NumberBaseStruct(int32_t _number) : mNumber(_number) {}
-
-    DEFINE_AND_DESCRIBE_BASE_C2STRUCT(NumberBase)
-    C2FIELD(mNumber, "number")
-};
-
-struct C2NumbersStruct {
-    int32_t mNumbers[];
-    C2NumbersStruct() {}
-
-    DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(Numbers, mNumbers)
-    C2FIELD(mNumbers, "numbers")
-};
-static_assert(sizeof(C2NumbersStruct) == 0, "C2NumbersStruct has incorrect size");
-
-typedef C2GlobalParam<C2Info, C2NumberStruct> C2NumberInfo;
-
-typedef C2GlobalParam<C2Tuning, C2NumberStruct> C2NumberTuning;
-typedef   C2PortParam<C2Tuning, C2NumberStruct> C2NumberPortTuning;
-typedef C2StreamParam<C2Tuning, C2NumberStruct> C2NumberStreamTuning;
-
-typedef C2GlobalParam<C2Tuning, C2NumbersStruct> C2NumbersTuning;
-typedef   C2PortParam<C2Tuning, C2NumbersStruct> C2NumbersPortTuning;
-typedef C2StreamParam<C2Tuning, C2NumbersStruct> C2NumbersStreamTuning;
-
-//
-#if 0
-
-void test() {
-    C2NumberStruct s(10);
-    (void)C2NumberStruct::FIELD_LIST;
-};
-
-typedef C2StreamParam<C2Tuning, C2Int64Value, kParamIndexNumberB> C2NumberConfig4;
-typedef C2PortParam<C2Tuning, C2Int32Value, kParamIndexNumber> C2NumberConfig3;
-typedef C2GlobalParam<C2Tuning, C2StringValue, kParamIndexNumber> C2VideoNameConfig;
-
-void test3() {
-    C2NumberConfig3 s(10);
-    s.value = 11;
-    s = 12;
-    (void)C2NumberConfig3::FIELD_LIST;
-    std::shared_ptr<C2VideoNameConfig> n = C2VideoNameConfig::AllocShared(25);
-    strcpy(n->m.value, "lajos");
-    C2NumberConfig4 t(false, 0, 11);
-    t.value = 15;
-};
-
-struct C2NumbersStruct {
-    int32_t mNumbers[];
-    enum { CORE_INDEX = kParamIndexNumber };
-    const static std::initializer_list<const C2FieldDescriptor> FIELD_LIST;
-    C2NumbersStruct() {}
-
-    FLEX(C2NumbersStruct, mNumbers);
-};
-
-static_assert(sizeof(C2NumbersStruct) == 0, "yes");
-
-
-typedef C2GlobalParam<C2Info, C2NumbersStruct> C2NumbersInfo;
-
-const std::initializer_list<const C2FieldDescriptor> C2NumbersStruct::FIELD_LIST =
-//    { { FD::INT32, 0, "widths" } };
-    { C2FieldDescriptor(&((C2NumbersStruct*)(nullptr))->mNumbers, "number") };
-
-typedef C2PortParam<C2Tuning, C2NumberStruct> C2NumberConfig;
-
-std::list<const C2FieldDescriptor> myList = C2NumberConfig::FIELD_LIST;
-
-    std::unique_ptr<C2ParamDescriptor> __test_describe(uint32_t paramType) {
-        std::list<const C2FieldDescriptor> fields = describeC2Params<C2NumberConfig>();
-
-        auto widths = C2NumbersInfo::AllocShared(5);
-        widths->flexCount();
-        widths->m.mNumbers[4] = 1;
-
-        test();
-        test3();
-
-        C2NumberConfig outputWidth(false, 123);
-
-        C2Param::Index index(paramType);
-        switch (paramType) {
-        case C2NumberConfig::CORE_INDEX:
-            return std::unique_ptr<C2ParamDescriptor>(new C2ParamDescriptor{
-                true /* isRequired */,
-                "number",
-                index,
-            });
-        }
-        return nullptr;
-    }
-
-
-} // namespace android
-
-#endif
-//
-
-template<typename T>
-bool canSetPort(T &o, bool output) { return o.setPort(output); }
-bool canSetPort(...) { return false; }
-
-template<typename S, typename=decltype(((S*)0)->setPort(true))>
-static std::true_type _canCallSetPort(int);
-template<typename>
-static std::false_type _canCallSetPort(...);
-#define canCallSetPort(x) decltype(_canCallSetPort<std::remove_reference<decltype(x)>::type>(0))::value
-
-/* ======================================= STATIC TESTS ======================================= */
-
-static_assert(_C2Comparable<int>::value, "int is not comparable");
-static_assert(!_C2Comparable<void>::value, "void is comparable");
-
-struct C2_HIDE _test0 {
-    bool operator==(const _test0&);
-    bool operator!=(const _test0&);
-};
-struct C2_HIDE _test1 {
-    bool operator==(const _test1&);
-};
-struct C2_HIDE _test2 {
-    bool operator!=(const _test2&);
-};
-static_assert(_C2Comparable<_test0>::value, "class with == and != is not comparable");
-static_assert(_C2Comparable<_test1>::value, "class with == is not comparable");
-static_assert(_C2Comparable<_test2>::value, "class with != is not comparable");
-
-/* ======================================= C2PARAM TESTS ======================================= */
-
-struct _C2ParamInspector {
-    static void StaticTest();
-    static void StaticFromBaseTest();
-    static void StaticFlexTest();
-    static void StaticFlexFromBaseTest();
-};
-
-// TEST_F(_C2ParamInspector, StaticTest) {
-void _C2ParamInspector::StaticTest() {
-    typedef C2Param::Index I;
-
-    // C2NumberStruct: CORE_INDEX = kIndex                          (args)
-    static_assert(C2NumberStruct::CORE_INDEX == kParamIndexNumber, "bad index");
-    static_assert(sizeof(C2NumberStruct) == 4, "bad size");
-
-    // C2NumberTuning:             kIndex | tun | global           (args)
-    static_assert(C2NumberTuning::CORE_INDEX == kParamIndexNumber, "bad index");
-    static_assert(C2NumberTuning::PARAM_TYPE == (kParamIndexNumber | I::KIND_TUNING | I::DIR_GLOBAL), "bad index");
-    static_assert(sizeof(C2NumberTuning) == 12, "bad size");
-
-    static_assert(offsetof(C2NumberTuning, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2NumberTuning, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2NumberTuning, mNumber) == 8, "bad offset");
-
-    // C2NumberPortTuning:         kIndex | tun | port             (bool, args)
-    static_assert(sizeof(C2NumberPortTuning) == 12, "bad size");
-    // C2NumberPortTuning::input:  kIndex | tun | port | input     (args)
-    // C2NumberPortTuning::output: kIndex | tun | port | output    (args)
-    static_assert(C2NumberPortTuning::input::CORE_INDEX ==
-                  kParamIndexNumber, "bad index");
-    static_assert(C2NumberPortTuning::input::PARAM_TYPE ==
-                  (kParamIndexNumber | I::KIND_TUNING | I::DIR_INPUT), "bad index");
-    static_assert(C2NumberPortTuning::output::CORE_INDEX ==
-                  kParamIndexNumber, "bad index");
-    static_assert(C2NumberPortTuning::output::PARAM_TYPE ==
-                  (kParamIndexNumber | I::KIND_TUNING | I::DIR_OUTPUT), "bad index");
-    static_assert(sizeof(C2NumberPortTuning::input) == 12, "bad size");
-    static_assert(sizeof(C2NumberPortTuning::output) == 12, "bad size");
-    static_assert(offsetof(C2NumberPortTuning::input, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2NumberPortTuning::input, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2NumberPortTuning::input, mNumber) == 8, "bad offset");
-    static_assert(offsetof(C2NumberPortTuning::output, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2NumberPortTuning::output, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2NumberPortTuning::output, mNumber) == 8, "bad offset");
-
-    // C2NumberStreamTuning:       kIndex | tun | str              (bool, uint, args)
-    static_assert(sizeof(C2NumberStreamTuning) == 12u, "bad size");
-    // C2NumberStreamTuning::input kIndex | tun | str | input      (int, args)
-    // C2NumberStreamTuning::output kIx   | tun | str | output     (int, args)
-    static_assert(C2NumberStreamTuning::input::CORE_INDEX ==
-                  kParamIndexNumber, "bad index");
-    static_assert(C2NumberStreamTuning::input::PARAM_TYPE ==
-                  (kParamIndexNumber | I::KIND_TUNING | I::DIR_INPUT | I::IS_STREAM_FLAG), "bad index");
-    static_assert(C2NumberStreamTuning::output::CORE_INDEX ==
-                  kParamIndexNumber, "bad index");
-    static_assert(C2NumberStreamTuning::output::PARAM_TYPE ==
-                  (kParamIndexNumber | I::KIND_TUNING | I::DIR_OUTPUT | I::IS_STREAM_FLAG), "bad index");
-    static_assert(sizeof(C2NumberStreamTuning::input) == 12u, "bad size");
-    static_assert(sizeof(C2NumberStreamTuning::output) == 12u, "bad size");
-    static_assert(offsetof(C2NumberStreamTuning::input, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2NumberStreamTuning::input, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2NumberStreamTuning::input, mNumber) == 8, "bad offset");
-    static_assert(offsetof(C2NumberStreamTuning::output, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2NumberStreamTuning::output, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2NumberStreamTuning::output, mNumber) == 8, "bad offset");
-}
-
-void _C2ParamInspector::StaticFromBaseTest() {
-    enum { kParamIndexMy = 3102 };
-    typedef C2NumberBaseStruct C2MyStruct;
-    typedef C2GlobalParam<C2Setting, C2MyStruct, kParamIndexMy> C2MySetting;
-    typedef   C2PortParam<C2Setting, C2MyStruct, kParamIndexMy> C2MyPortSetting;
-    typedef C2StreamParam<C2Setting, C2MyStruct, kParamIndexMy> C2MyStreamSetting;
-
-    typedef C2Param::Index I;
-
-    // C2MyStruct has no CORE_INDEX
-    //static_assert(C2MyStruct::CORE_INDEX == kParamIndexMy, "bad index");
-    static_assert(sizeof(C2MyStruct) == 4, "bad size");
-
-    // C2MySetting:             kIndex | tun | global           (args)
-    static_assert(C2MySetting::CORE_INDEX == kParamIndexMy, "bad index");
-    static_assert(C2MySetting::PARAM_TYPE == (kParamIndexMy | I::KIND_SETTING | I::DIR_GLOBAL), "bad index");
-    static_assert(sizeof(C2MySetting) == 12, "bad size");
-
-    static_assert(offsetof(C2MySetting, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2MySetting, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2MySetting, mNumber) == 8, "bad offset");
-
-    // C2MyPortSetting:         kIndex | tun | port             (bool, args)
-    static_assert(sizeof(C2MyPortSetting) == 12, "bad size");
-    // C2MyPortSetting::input:  kIndex | tun | port | input     (args)
-    // C2MyPortSetting::output: kIndex | tun | port | output    (args)
-    static_assert(C2MyPortSetting::input::CORE_INDEX ==
-                  kParamIndexMy, "bad index");
-    static_assert(C2MyPortSetting::input::PARAM_TYPE ==
-                  (kParamIndexMy | I::KIND_SETTING | I::DIR_INPUT), "bad index");
-    static_assert(C2MyPortSetting::output::CORE_INDEX ==
-                  kParamIndexMy, "bad index");
-    static_assert(C2MyPortSetting::output::PARAM_TYPE ==
-                  (kParamIndexMy | I::KIND_SETTING | I::DIR_OUTPUT), "bad index");
-    static_assert(sizeof(C2MyPortSetting::input) == 12, "bad size");
-    static_assert(sizeof(C2MyPortSetting::output) == 12, "bad size");
-    static_assert(offsetof(C2MyPortSetting::input, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2MyPortSetting::input, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2MyPortSetting::input, mNumber) == 8, "bad offset");
-    static_assert(offsetof(C2MyPortSetting::output, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2MyPortSetting::output, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2MyPortSetting::output, mNumber) == 8, "bad offset");
-
-    // C2MyStreamSetting:       kIndex | tun | str              (bool, uint, args)
-    static_assert(sizeof(C2MyStreamSetting) == 12u, "bad size");
-    // C2MyStreamSetting::input kIndex | tun | str | input      (int, args)
-    // C2MyStreamSetting::output kIx   | tun | str | output     (int, args)
-    static_assert(C2MyStreamSetting::input::CORE_INDEX ==
-                  kParamIndexMy, "bad index");
-    static_assert(C2MyStreamSetting::input::PARAM_TYPE ==
-                  (kParamIndexMy | I::KIND_SETTING | I::DIR_INPUT | I::IS_STREAM_FLAG), "bad index");
-    static_assert(C2MyStreamSetting::output::CORE_INDEX ==
-                  kParamIndexMy, "bad index");
-    static_assert(C2MyStreamSetting::output::PARAM_TYPE ==
-                  (kParamIndexMy | I::KIND_SETTING | I::DIR_OUTPUT | I::IS_STREAM_FLAG), "bad index");
-    static_assert(sizeof(C2MyStreamSetting::input) == 12u, "bad size");
-    static_assert(sizeof(C2MyStreamSetting::output) == 12u, "bad size");
-    static_assert(offsetof(C2MyStreamSetting::input, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2MyStreamSetting::input, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2MyStreamSetting::input, mNumber) == 8, "bad offset");
-    static_assert(offsetof(C2MyStreamSetting::output, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2MyStreamSetting::output, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2MyStreamSetting::output, mNumber) == 8, "bad offset");
-}
-
-void _C2ParamInspector::StaticFlexTest() {
-    typedef C2Param::Index I;
-
-    // C2NumbersStruct: CORE_INDEX = kIndex                          (args)
-    static_assert(C2NumbersStruct::CORE_INDEX == (I::IS_FLEX_FLAG | kParamIndexNumbers), "bad index");
-    static_assert(sizeof(C2NumbersStruct) == 0, "bad size");
-
-    // C2NumbersTuning:             kIndex | tun | global           (args)
-    static_assert(C2NumbersTuning::CORE_INDEX == (I::IS_FLEX_FLAG | kParamIndexNumbers), "bad index");
-    static_assert(C2NumbersTuning::PARAM_TYPE == (I::IS_FLEX_FLAG | kParamIndexNumbers | I::KIND_TUNING | I::DIR_GLOBAL), "bad index");
-    static_assert(sizeof(C2NumbersTuning) == 8, "bad size");
-
-    static_assert(offsetof(C2NumbersTuning, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2NumbersTuning, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2NumbersTuning, m.mNumbers) == 8, "bad offset");
-
-    // C2NumbersPortTuning:         kIndex | tun | port             (bool, args)
-    static_assert(sizeof(C2NumbersPortTuning) == 8, "bad size");
-    // C2NumbersPortTuning::input:  kIndex | tun | port | input     (args)
-    // C2NumbersPortTuning::output: kIndex | tun | port | output    (args)
-    static_assert(C2NumbersPortTuning::input::CORE_INDEX ==
-                  (I::IS_FLEX_FLAG | kParamIndexNumbers), "bad index");
-    static_assert(C2NumbersPortTuning::input::PARAM_TYPE ==
-                  (I::IS_FLEX_FLAG | kParamIndexNumbers | I::KIND_TUNING | I::DIR_INPUT), "bad index");
-    static_assert(C2NumbersPortTuning::output::CORE_INDEX ==
-                  (I::IS_FLEX_FLAG | kParamIndexNumbers), "bad index");
-    static_assert(C2NumbersPortTuning::output::PARAM_TYPE ==
-                  (I::IS_FLEX_FLAG | kParamIndexNumbers | I::KIND_TUNING | I::DIR_OUTPUT), "bad index");
-    static_assert(sizeof(C2NumbersPortTuning::input) == 8, "bad size");
-    static_assert(sizeof(C2NumbersPortTuning::output) == 8, "bad size");
-    static_assert(offsetof(C2NumbersPortTuning::input, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2NumbersPortTuning::input, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2NumbersPortTuning::input, m.mNumbers) == 8, "bad offset");
-    static_assert(offsetof(C2NumbersPortTuning::output, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2NumbersPortTuning::output, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2NumbersPortTuning::output, m.mNumbers) == 8, "bad offset");
-
-    // C2NumbersStreamTuning:       kIndex | tun | str              (bool, uint, args)
-    static_assert(sizeof(C2NumbersStreamTuning) == 8, "bad size");
-    // C2NumbersStreamTuning::input kIndex | tun | str | input      (int, args)
-    // C2NumbersStreamTuning::output kIx   | tun | str | output     (int, args)
-    static_assert(C2NumbersStreamTuning::input::CORE_INDEX ==
-                  (I::IS_FLEX_FLAG | kParamIndexNumbers), "bad index");
-    static_assert(C2NumbersStreamTuning::input::PARAM_TYPE ==
-                  (I::IS_FLEX_FLAG | kParamIndexNumbers | I::KIND_TUNING | I::DIR_INPUT | I::IS_STREAM_FLAG), "bad index");
-    static_assert(C2NumbersStreamTuning::output::CORE_INDEX ==
-                  (I::IS_FLEX_FLAG | kParamIndexNumbers), "bad index");
-    static_assert(C2NumbersStreamTuning::output::PARAM_TYPE ==
-                  (I::IS_FLEX_FLAG | kParamIndexNumbers | I::KIND_TUNING | I::DIR_OUTPUT | I::IS_STREAM_FLAG), "bad index");
-    static_assert(sizeof(C2NumbersStreamTuning::input) == 8, "bad size");
-    static_assert(sizeof(C2NumbersStreamTuning::output) == 8, "bad size");
-    static_assert(offsetof(C2NumbersStreamTuning::input, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2NumbersStreamTuning::input, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2NumbersStreamTuning::input, m.mNumbers) == 8, "bad offset");
-    static_assert(offsetof(C2NumbersStreamTuning::output, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2NumbersStreamTuning::output, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2NumbersStreamTuning::output, m.mNumbers) == 8, "bad offset");
-}
-
-template<bool, unsigned ...N>
-struct _print_as_warning { };
-
-template<unsigned ...N>
-struct _print_as_warning<true, N...> : std::true_type { };
-
-#define static_assert_equals(a, b, msg) \
-static_assert(_print_as_warning<(a) == (b), a, b>::value, msg)
-
-void _C2ParamInspector::StaticFlexFromBaseTest() {
-    enum { kParamIndexMy = 1203 };
-    typedef C2TestBaseFlexEndSizeStruct C2MyStruct;
-    typedef C2GlobalParam<C2Info, C2MyStruct, kParamIndexMy> C2MyInfo;
-    typedef   C2PortParam<C2Info, C2MyStruct, kParamIndexMy> C2MyPortInfo;
-    typedef C2StreamParam<C2Info, C2MyStruct, kParamIndexMy> C2MyStreamInfo;
-
-    typedef C2Param::Index I;
-
-    // C2MyStruct has no CORE_INDEX
-    //static_assert(C2MyStruct::CORE_INDEX == (I::IS_FLEX_FLAG | kParamIndexMy), "bad index");
-    static_assert(sizeof(C2MyStruct) == 4, "bad size");
-
-    // C2MyInfo:             kIndex | tun | global           (args)
-    static_assert_equals(C2MyInfo::CORE_INDEX, (I::IS_FLEX_FLAG | kParamIndexMy), "bad index");
-    static_assert_equals(C2MyInfo::PARAM_TYPE, (I::IS_FLEX_FLAG | kParamIndexMy | I::KIND_INFO | I::DIR_GLOBAL), "bad index");
-    static_assert(sizeof(C2MyInfo) == 12, "bad size");
-
-    static_assert(offsetof(C2MyInfo, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2MyInfo, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2MyInfo, m.signed32) == 8, "bad offset");
-
-    // C2MyPortInfo:         kIndex | tun | port             (bool, args)
-    static_assert(sizeof(C2MyPortInfo) == 12, "bad size");
-    // C2MyPortInfo::input:  kIndex | tun | port | input     (args)
-    // C2MyPortInfo::output: kIndex | tun | port | output    (args)
-    static_assert(C2MyPortInfo::input::CORE_INDEX ==
-                  (I::IS_FLEX_FLAG | kParamIndexMy), "bad index");
-    static_assert(C2MyPortInfo::input::PARAM_TYPE ==
-                  (I::IS_FLEX_FLAG | kParamIndexMy | I::KIND_INFO | I::DIR_INPUT), "bad index");
-    static_assert(C2MyPortInfo::output::CORE_INDEX ==
-                  (I::IS_FLEX_FLAG | kParamIndexMy), "bad index");
-    static_assert(C2MyPortInfo::output::PARAM_TYPE ==
-                  (I::IS_FLEX_FLAG | kParamIndexMy | I::KIND_INFO | I::DIR_OUTPUT), "bad index");
-    static_assert(sizeof(C2MyPortInfo::input) == 12, "bad size");
-    static_assert(sizeof(C2MyPortInfo::output) == 12, "bad size");
-    static_assert(offsetof(C2MyPortInfo::input, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2MyPortInfo::input, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2MyPortInfo::input, m.signed32) == 8, "bad offset");
-    static_assert(offsetof(C2MyPortInfo::output, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2MyPortInfo::output, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2MyPortInfo::output, m.signed32) == 8, "bad offset");
-
-    // C2MyStreamInfo:       kIndex | tun | str              (bool, uint, args)
-    static_assert(sizeof(C2MyStreamInfo) == 12, "bad size");
-    // C2MyStreamInfo::input kIndex | tun | str | input      (int, args)
-    // C2MyStreamInfo::output kIx   | tun | str | output     (int, args)
-    static_assert(C2MyStreamInfo::input::CORE_INDEX ==
-                  (I::IS_FLEX_FLAG | kParamIndexMy), "bad index");
-    static_assert(C2MyStreamInfo::input::PARAM_TYPE ==
-                  (I::IS_FLEX_FLAG | kParamIndexMy | I::KIND_INFO | I::DIR_INPUT | I::IS_STREAM_FLAG), "bad index");
-    static_assert(C2MyStreamInfo::output::CORE_INDEX ==
-                  (I::IS_FLEX_FLAG | kParamIndexMy), "bad index");
-    static_assert(C2MyStreamInfo::output::PARAM_TYPE ==
-                  (I::IS_FLEX_FLAG | kParamIndexMy | I::KIND_INFO | I::DIR_OUTPUT | I::IS_STREAM_FLAG), "bad index");
-    static_assert(sizeof(C2MyStreamInfo::input) == 12, "bad size");
-    static_assert(sizeof(C2MyStreamInfo::output) == 12, "bad size");
-    static_assert(offsetof(C2MyStreamInfo::input, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2MyStreamInfo::input, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2MyStreamInfo::input, m.signed32) == 8, "bad offset");
-    static_assert(offsetof(C2MyStreamInfo::output, _mSize) == 0, "bad size");
-    static_assert(offsetof(C2MyStreamInfo::output, _mIndex) == 4, "bad offset");
-    static_assert(offsetof(C2MyStreamInfo::output, m.signed32) == 8, "bad offset");
-}
-
-TEST_F(C2ParamTest, ParamOpsTest) {
-    const C2NumberStruct str(100);
-    C2NumberStruct bstr;
-
-    {
-        EXPECT_EQ(100, str.mNumber);
-        bstr.mNumber = 100;
-
-        C2Param::CoreIndex index = C2NumberStruct::CORE_INDEX;
-        EXPECT_FALSE(index.isVendor());
-        EXPECT_FALSE(index.isFlexible());
-        EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
-        EXPECT_EQ(index.typeIndex(), kParamIndexNumber);
-    }
-
-    const C2NumberTuning tun(100);
-    C2NumberTuning btun;
-
-    {
-      C2NumberInfo inf(100);
-      std::unique_ptr<C2NumbersTuning> tun_ = C2NumbersTuning::AllocUnique(1);
-
-      EXPECT_EQ(tun.coreIndex(), inf.coreIndex());
-      EXPECT_NE(tun.coreIndex(), tun_->coreIndex());
-      EXPECT_NE(tun.type(), inf.type());
-      EXPECT_NE(tun.type(), tun_->type());
-    }
-
-    {
-        // flags & invariables
-        for (const auto &p : { tun, btun }) {
-            EXPECT_TRUE((bool)p);
-            EXPECT_FALSE(!p);
-            EXPECT_EQ(12u, p.size());
-
-            EXPECT_FALSE(p.isVendor());
-            EXPECT_FALSE(p.isFlexible());
-            EXPECT_TRUE(p.isGlobal());
-            EXPECT_FALSE(p.forInput());
-            EXPECT_FALSE(p.forOutput());
-            EXPECT_FALSE(p.forStream());
-            EXPECT_FALSE(p.forPort());
-        }
-
-        // value
-        EXPECT_EQ(100, tun.mNumber);
-        EXPECT_EQ(0, btun.mNumber);
-        EXPECT_FALSE(tun == btun);
-        EXPECT_FALSE(tun.operator==(btun));
-        EXPECT_TRUE(tun != btun);
-        EXPECT_TRUE(tun.operator!=(btun));
-        btun.mNumber = 100;
-        EXPECT_EQ(tun, btun);
-
-        // index
-        EXPECT_EQ(C2Param::Type(tun.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
-        EXPECT_EQ(C2Param::Type(tun.type()).typeIndex(), kParamIndexNumber);
-        EXPECT_EQ(tun.type(), C2NumberTuning::PARAM_TYPE);
-        EXPECT_EQ(tun.stream(), ~0u);
-
-        C2Param::CoreIndex index = C2NumberTuning::CORE_INDEX;
-        EXPECT_FALSE(index.isVendor());
-        EXPECT_FALSE(index.isFlexible());
-        EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
-        EXPECT_EQ(index.typeIndex(), kParamIndexNumber);
-
-        C2Param::Type type = C2NumberTuning::PARAM_TYPE;
-        EXPECT_FALSE(type.isVendor());
-        EXPECT_FALSE(type.isFlexible());
-        EXPECT_TRUE(type.isGlobal());
-        EXPECT_FALSE(type.forInput());
-        EXPECT_FALSE(type.forOutput());
-        EXPECT_FALSE(type.forStream());
-        EXPECT_FALSE(type.forPort());
-
-        EXPECT_EQ(C2NumberTuning::From(nullptr), nullptr);
-        EXPECT_EQ(C2NumberTuning::From(&tun), &tun);
-        EXPECT_EQ(C2NumberPortTuning::From(&tun), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::input::From(&tun), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::output::From(&tun), nullptr);
-        EXPECT_EQ(C2NumberStreamTuning::From(&tun), nullptr);
-        EXPECT_EQ(C2NumberStreamTuning::input::From(&tun), nullptr);
-        EXPECT_EQ(C2NumberStreamTuning::output::From(&tun), nullptr);
-
-        EXPECT_EQ(*(C2Param::Copy(btun)), btun);
-        btun.invalidate();
-        EXPECT_FALSE(C2Param::Copy(btun));
-    }
-
-    const C2NumberPortTuning outp1(true, 100), inp1(false, 100);
-    C2NumberPortTuning boutp1, binp1, binp3(false, 100);
-    const C2NumberPortTuning::input inp2(100);
-    C2NumberPortTuning::input binp2;
-    const C2NumberPortTuning::output outp2(100);
-    C2NumberPortTuning::output boutp2;
-
-    EXPECT_EQ(inp1.coreIndex(), tun.coreIndex());
-    EXPECT_EQ(outp1.coreIndex(), tun.coreIndex());
-    EXPECT_EQ(binp1.coreIndex(), tun.coreIndex());
-    EXPECT_EQ(boutp1.coreIndex(), tun.coreIndex());
-    EXPECT_EQ(inp2.coreIndex(), tun.coreIndex());
-    EXPECT_EQ(outp2.coreIndex(), tun.coreIndex());
-
-    EXPECT_EQ(inp1.type(), inp2.type());
-    EXPECT_EQ(outp1.type(), outp2.type());
-    EXPECT_NE(inp1.type(), outp1.type());
-    EXPECT_NE(inp2.type(), outp2.type());
-    EXPECT_NE(inp1.type(), binp1.type());
-    EXPECT_NE(outp1.type(), boutp1.type());
-    EXPECT_NE(inp1.type(), tun.type());
-    EXPECT_NE(inp2.type(), tun.type());
-
-    {
-        static_assert(canCallSetPort(binp3), "should be able to");
-        static_assert(canCallSetPort(binp1), "should be able to");
-        static_assert(!canCallSetPort(inp1), "should not be able to (const)");
-        static_assert(!canCallSetPort(inp2), "should not be able to (const & type)");
-        static_assert(!canCallSetPort(binp2), "should not be able to (type)");
-
-        // flags & invariables
-        for (const auto &p : { outp1, inp1, boutp1 }) {
-            EXPECT_EQ(12u, p.size());
-            EXPECT_FALSE(p.isVendor());
-            EXPECT_FALSE(p.isFlexible());
-            EXPECT_FALSE(p.isGlobal());
-            EXPECT_FALSE(p.forStream());
-            EXPECT_TRUE(p.forPort());
-        }
-        for (const auto &p : { inp2, binp2 }) {
-            EXPECT_EQ(12u, p.size());
-            EXPECT_FALSE(p.isVendor());
-            EXPECT_FALSE(p.isFlexible());
-            EXPECT_FALSE(p.isGlobal());
-            EXPECT_FALSE(p.forStream());
-            EXPECT_TRUE(p.forPort());
-        }
-        for (const auto &p : { outp2, boutp2 }) {
-            EXPECT_EQ(12u, p.size());
-            EXPECT_FALSE(p.isVendor());
-            EXPECT_FALSE(p.isFlexible());
-            EXPECT_FALSE(p.isGlobal());
-            EXPECT_FALSE(p.forStream());
-            EXPECT_TRUE(p.forPort());
-        }
-
-        // port specific flags & invariables
-        EXPECT_FALSE(outp1.forInput());
-        EXPECT_TRUE(outp1.forOutput());
-
-        EXPECT_TRUE(inp1.forInput());
-        EXPECT_FALSE(inp1.forOutput());
-
-        for (const auto &p : { outp1, inp1 }) {
-            EXPECT_TRUE((bool)p);
-            EXPECT_FALSE(!p);
-            EXPECT_EQ(100, p.mNumber);
-        }
-        for (const auto &p : { outp2, boutp2 }) {
-            EXPECT_TRUE((bool)p);
-            EXPECT_FALSE(!p);
-
-            EXPECT_FALSE(p.forInput());
-            EXPECT_TRUE(p.forOutput());
-        }
-        for (const auto &p : { inp2, binp2 }) {
-            EXPECT_TRUE((bool)p);
-            EXPECT_FALSE(!p);
-
-            EXPECT_TRUE(p.forInput());
-            EXPECT_FALSE(p.forOutput());
-        }
-        for (const auto &p : { boutp1 } ) {
-            EXPECT_FALSE((bool)p);
-            EXPECT_TRUE(!p);
-
-            EXPECT_FALSE(p.forInput());
-            EXPECT_FALSE(p.forOutput());
-            EXPECT_EQ(0, p.mNumber);
-        }
-
-        // values
-        EXPECT_EQ(100, inp2.mNumber);
-        EXPECT_EQ(100, outp2.mNumber);
-        EXPECT_EQ(0, binp1.mNumber);
-        EXPECT_EQ(0, binp2.mNumber);
-        EXPECT_EQ(0, boutp1.mNumber);
-        EXPECT_EQ(0, boutp2.mNumber);
-
-        EXPECT_TRUE(inp1 != outp1);
-        EXPECT_TRUE(inp1 == inp2);
-        EXPECT_TRUE(outp1 == outp2);
-        EXPECT_TRUE(binp1 == boutp1);
-        EXPECT_TRUE(binp2 != boutp2);
-
-        EXPECT_TRUE(inp1 != binp1);
-        binp1.mNumber = 100;
-        EXPECT_TRUE(inp1 != binp1);
-        binp1.setPort(false /* output */);
-        EXPECT_TRUE((bool)binp1);
-        EXPECT_FALSE(!binp1);
-        EXPECT_TRUE(inp1 == binp1);
-
-        EXPECT_TRUE(inp2 != binp2);
-        binp2.mNumber = 100;
-        EXPECT_TRUE(inp2 == binp2);
-
-        binp1.setPort(true /* output */);
-        EXPECT_TRUE(outp1 == binp1);
-
-        EXPECT_TRUE(outp1 != boutp1);
-        boutp1.mNumber = 100;
-        EXPECT_TRUE(outp1 != boutp1);
-        boutp1.setPort(true /* output */);
-        EXPECT_TRUE((bool)boutp1);
-        EXPECT_FALSE(!boutp1);
-        EXPECT_TRUE(outp1 == boutp1);
-
-        EXPECT_TRUE(outp2 != boutp2);
-        boutp2.mNumber = 100;
-        EXPECT_TRUE(outp2 == boutp2);
-
-        boutp1.setPort(false /* output */);
-        EXPECT_TRUE(inp1 == boutp1);
-
-        // index
-        EXPECT_EQ(C2Param::Type(inp1.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
-        EXPECT_EQ(C2Param::Type(inp1.type()).typeIndex(), kParamIndexNumber);
-        EXPECT_EQ(inp1.type(), C2NumberPortTuning::input::PARAM_TYPE);
-        EXPECT_EQ(inp1.stream(), ~0u);
-
-        EXPECT_EQ(C2Param::Type(inp2.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
-        EXPECT_EQ(C2Param::Type(inp2.type()).typeIndex(), kParamIndexNumber);
-        EXPECT_EQ(inp2.type(), C2NumberPortTuning::input::PARAM_TYPE);
-        EXPECT_EQ(inp2.stream(), ~0u);
-
-        EXPECT_EQ(C2Param::Type(outp1.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
-        EXPECT_EQ(C2Param::Type(outp1.type()).typeIndex(), kParamIndexNumber);
-        EXPECT_EQ(outp1.type(), C2NumberPortTuning::output::PARAM_TYPE);
-        EXPECT_EQ(outp1.stream(), ~0u);
-
-        EXPECT_EQ(C2Param::Type(outp2.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
-        EXPECT_EQ(C2Param::Type(outp2.type()).typeIndex(), kParamIndexNumber);
-        EXPECT_EQ(outp2.type(), C2NumberPortTuning::output::PARAM_TYPE);
-        EXPECT_EQ(outp2.stream(), ~0u);
-
-        C2Param::CoreIndex index = C2NumberPortTuning::input::PARAM_TYPE;
-        EXPECT_FALSE(index.isVendor());
-        EXPECT_FALSE(index.isFlexible());
-        EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
-        EXPECT_EQ(index.typeIndex(), kParamIndexNumber);
-
-        index = C2NumberPortTuning::output::PARAM_TYPE;
-        EXPECT_FALSE(index.isVendor());
-        EXPECT_FALSE(index.isFlexible());
-        EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
-        EXPECT_EQ(index.typeIndex(), kParamIndexNumber);
-
-        C2Param::Type type = C2NumberPortTuning::input::PARAM_TYPE;
-        EXPECT_FALSE(type.isVendor());
-        EXPECT_FALSE(type.isFlexible());
-        EXPECT_FALSE(type.isGlobal());
-        EXPECT_TRUE(type.forInput());
-        EXPECT_FALSE(type.forOutput());
-        EXPECT_FALSE(type.forStream());
-        EXPECT_TRUE(type.forPort());
-
-        type = C2NumberPortTuning::output::PARAM_TYPE;
-        EXPECT_FALSE(type.isVendor());
-        EXPECT_FALSE(type.isFlexible());
-        EXPECT_FALSE(type.isGlobal());
-        EXPECT_FALSE(type.forInput());
-        EXPECT_TRUE(type.forOutput());
-        EXPECT_FALSE(type.forStream());
-        EXPECT_TRUE(type.forPort());
-
-        EXPECT_EQ(C2NumberPortTuning::From(nullptr), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::input::From(nullptr), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::output::From(nullptr), nullptr);
-        EXPECT_EQ(C2NumberTuning::From(&inp1), nullptr);
-        EXPECT_EQ(C2NumberTuning::From(&inp2), nullptr);
-        EXPECT_EQ(C2NumberTuning::From(&outp1), nullptr);
-        EXPECT_EQ(C2NumberTuning::From(&outp2), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::From(&inp1), &inp1);
-        EXPECT_EQ(C2NumberPortTuning::From(&inp2), (C2NumberPortTuning*)&inp2);
-        EXPECT_EQ(C2NumberPortTuning::From(&outp1), &outp1);
-        EXPECT_EQ(C2NumberPortTuning::From(&outp2), (C2NumberPortTuning*)&outp2);
-        EXPECT_EQ(C2NumberPortTuning::input::From(&inp1), (C2NumberPortTuning::input*)&inp1);
-        EXPECT_EQ(C2NumberPortTuning::input::From(&inp2), &inp2);
-        EXPECT_EQ(C2NumberPortTuning::input::From(&outp1), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::input::From(&outp2), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::output::From(&inp1), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::output::From(&inp2), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::output::From(&outp1), (C2NumberPortTuning::output*)&outp1);
-        EXPECT_EQ(C2NumberPortTuning::output::From(&outp2), &outp2);
-        EXPECT_EQ(C2NumberStreamTuning::From(&inp1), nullptr);
-        EXPECT_EQ(C2NumberStreamTuning::From(&inp2), nullptr);
-        EXPECT_EQ(C2NumberStreamTuning::From(&outp1), nullptr);
-        EXPECT_EQ(C2NumberStreamTuning::From(&outp2), nullptr);
-        EXPECT_EQ(C2NumberStreamTuning::input::From(&inp1), nullptr);
-        EXPECT_EQ(C2NumberStreamTuning::input::From(&inp2), nullptr);
-        EXPECT_EQ(C2NumberStreamTuning::input::From(&outp1), nullptr);
-        EXPECT_EQ(C2NumberStreamTuning::input::From(&outp2), nullptr);
-        EXPECT_EQ(C2NumberStreamTuning::output::From(&inp1), nullptr);
-        EXPECT_EQ(C2NumberStreamTuning::output::From(&inp2), nullptr);
-        EXPECT_EQ(C2NumberStreamTuning::output::From(&outp1), nullptr);
-        EXPECT_EQ(C2NumberStreamTuning::output::From(&outp2), nullptr);
-
-        EXPECT_EQ(*(C2Param::Copy(inp1)), inp1);
-        EXPECT_EQ(*(C2Param::Copy(inp2)), inp2);
-        EXPECT_EQ(*(C2Param::Copy(outp1)), outp1);
-        EXPECT_EQ(*(C2Param::Copy(outp2)), outp2);
-    }
-
-    const C2NumberStreamTuning outs1(true, 1u, 100), ins1(false, 1u, 100);
-    C2NumberStreamTuning bouts1, bins1, bins3(false, 1u, 100);
-    const C2NumberStreamTuning::input ins2(1u, 100);
-    C2NumberStreamTuning::input bins2;
-    const C2NumberStreamTuning::output outs2(1u, 100);
-    C2NumberStreamTuning::output bouts2;
-
-    EXPECT_EQ(ins1.coreIndex(), tun.coreIndex());
-    EXPECT_EQ(outs1.coreIndex(), tun.coreIndex());
-    EXPECT_EQ(bins1.coreIndex(), tun.coreIndex());
-    EXPECT_EQ(bouts1.coreIndex(), tun.coreIndex());
-    EXPECT_EQ(ins2.coreIndex(), tun.coreIndex());
-    EXPECT_EQ(outs2.coreIndex(), tun.coreIndex());
-
-    EXPECT_EQ(ins1.type(), ins2.type());
-    EXPECT_EQ(ins1.type(), bins2.type());
-    EXPECT_EQ(outs1.type(), outs2.type());
-    EXPECT_EQ(outs1.type(), bouts2.type());
-    EXPECT_NE(ins1.type(), outs1.type());
-    EXPECT_NE(ins2.type(), outs2.type());
-    EXPECT_NE(ins1.type(), bins1.type());
-    EXPECT_NE(outs1.type(), bouts1.type());
-    EXPECT_NE(ins1.type(), tun.type());
-    EXPECT_NE(ins2.type(), tun.type());
-
-    {
-        static_assert(canCallSetPort(bins3), "should be able to");
-        static_assert(canCallSetPort(bins1), "should be able to");
-        static_assert(!canCallSetPort(ins1), "should not be able to (const)");
-        static_assert(!canCallSetPort(ins2), "should not be able to (const & type)");
-        static_assert(!canCallSetPort(bins2), "should not be able to (type)");
-
-        // flags & invariables
-        for (const auto &p : { outs1, ins1, bouts1 }) {
-            EXPECT_EQ(12u, p.size());
-            EXPECT_FALSE(p.isVendor());
-            EXPECT_FALSE(p.isFlexible());
-            EXPECT_FALSE(p.isGlobal());
-            EXPECT_TRUE(p.forStream());
-            EXPECT_FALSE(p.forPort());
-        }
-        for (const auto &p : { ins2, bins2 }) {
-            EXPECT_EQ(12u, p.size());
-            EXPECT_FALSE(p.isVendor());
-            EXPECT_FALSE(p.isFlexible());
-            EXPECT_FALSE(p.isGlobal());
-            EXPECT_TRUE(p.forStream());
-            EXPECT_FALSE(p.forPort());
-        }
-        for (const auto &p : { outs2, bouts2 }) {
-            EXPECT_EQ(12u, p.size());
-            EXPECT_FALSE(p.isVendor());
-            EXPECT_FALSE(p.isFlexible());
-            EXPECT_FALSE(p.isGlobal());
-            EXPECT_TRUE(p.forStream());
-            EXPECT_FALSE(p.forPort());
-        }
-
-        // port specific flags & invariables
-        EXPECT_FALSE(outs1.forInput());
-        EXPECT_TRUE(outs1.forOutput());
-
-        EXPECT_TRUE(ins1.forInput());
-        EXPECT_FALSE(ins1.forOutput());
-
-        for (const auto &p : { outs1, ins1 }) {
-            EXPECT_TRUE((bool)p);
-            EXPECT_FALSE(!p);
-            EXPECT_EQ(100, p.mNumber);
-            EXPECT_EQ(1u, p.stream());
-        }
-        for (const auto &p : { outs2, bouts2 }) {
-            EXPECT_TRUE((bool)p);
-            EXPECT_FALSE(!p);
-
-            EXPECT_FALSE(p.forInput());
-            EXPECT_TRUE(p.forOutput());
-        }
-        for (const auto &p : { ins2, bins2 }) {
-            EXPECT_TRUE((bool)p);
-            EXPECT_FALSE(!p);
-
-            EXPECT_TRUE(p.forInput());
-            EXPECT_FALSE(p.forOutput());
-        }
-        for (const auto &p : { bouts1 } ) {
-            EXPECT_FALSE((bool)p);
-            EXPECT_TRUE(!p);
-
-            EXPECT_FALSE(p.forInput());
-            EXPECT_FALSE(p.forOutput());
-            EXPECT_EQ(0, p.mNumber);
-        }
-
-        // values
-        EXPECT_EQ(100, ins2.mNumber);
-        EXPECT_EQ(100, outs2.mNumber);
-        EXPECT_EQ(0, bins1.mNumber);
-        EXPECT_EQ(0, bins2.mNumber);
-        EXPECT_EQ(0, bouts1.mNumber);
-        EXPECT_EQ(0, bouts2.mNumber);
-
-        EXPECT_EQ(1u, ins2.stream());
-        EXPECT_EQ(1u, outs2.stream());
-        EXPECT_EQ(0u, bins1.stream());
-        EXPECT_EQ(0u, bins2.stream());
-        EXPECT_EQ(0u, bouts1.stream());
-        EXPECT_EQ(0u, bouts2.stream());
-
-        EXPECT_TRUE(ins1 != outs1);
-        EXPECT_TRUE(ins1 == ins2);
-        EXPECT_TRUE(outs1 == outs2);
-        EXPECT_TRUE(bins1 == bouts1);
-        EXPECT_TRUE(bins2 != bouts2);
-
-        EXPECT_TRUE(ins1 != bins1);
-        bins1.mNumber = 100;
-        EXPECT_TRUE(ins1 != bins1);
-        bins1.setPort(false /* output */);
-        EXPECT_TRUE(ins1 != bins1);
-        bins1.setStream(1u);
-        EXPECT_TRUE(ins1 == bins1);
-
-        EXPECT_TRUE(ins2 != bins2);
-        bins2.mNumber = 100;
-        EXPECT_TRUE(ins2 != bins2);
-        bins2.setStream(1u);
-        EXPECT_TRUE(ins2 == bins2);
-
-        bins1.setPort(true /* output */);
-        EXPECT_TRUE(outs1 == bins1);
-
-        EXPECT_TRUE(outs1 != bouts1);
-        bouts1.mNumber = 100;
-        EXPECT_TRUE(outs1 != bouts1);
-        bouts1.setPort(true /* output */);
-        EXPECT_TRUE(outs1 != bouts1);
-        bouts1.setStream(1u);
-        EXPECT_TRUE(outs1 == bouts1);
-
-        EXPECT_TRUE(outs2 != bouts2);
-        bouts2.mNumber = 100;
-        EXPECT_TRUE(outs2 != bouts2);
-        bouts2.setStream(1u);
-        EXPECT_TRUE(outs2 == bouts2);
-
-        bouts1.setPort(false /* output */);
-        EXPECT_TRUE(ins1 == bouts1);
-
-        // index
-        EXPECT_EQ(C2Param::Type(ins1.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
-        EXPECT_EQ(C2Param::Type(ins1.type()).typeIndex(), kParamIndexNumber);
-        EXPECT_EQ(ins1.type(), C2NumberStreamTuning::input::PARAM_TYPE);
-
-        EXPECT_EQ(C2Param::Type(ins2.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
-        EXPECT_EQ(C2Param::Type(ins2.type()).typeIndex(), kParamIndexNumber);
-        EXPECT_EQ(ins2.type(), C2NumberStreamTuning::input::PARAM_TYPE);
-
-        EXPECT_EQ(C2Param::Type(outs1.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
-        EXPECT_EQ(C2Param::Type(outs1.type()).typeIndex(), kParamIndexNumber);
-        EXPECT_EQ(outs1.type(), C2NumberStreamTuning::output::PARAM_TYPE);
-
-        EXPECT_EQ(C2Param::Type(outs2.type()).coreIndex(), C2NumberStruct::CORE_INDEX);
-        EXPECT_EQ(C2Param::Type(outs2.type()).typeIndex(), kParamIndexNumber);
-        EXPECT_EQ(outs2.type(), C2NumberStreamTuning::output::PARAM_TYPE);
-
-        C2Param::CoreIndex index = C2NumberStreamTuning::input::PARAM_TYPE;
-        EXPECT_FALSE(index.isVendor());
-        EXPECT_FALSE(index.isFlexible());
-        EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
-        EXPECT_EQ(index.typeIndex(), kParamIndexNumber);
-
-        index = C2NumberStreamTuning::output::PARAM_TYPE;
-        EXPECT_FALSE(index.isVendor());
-        EXPECT_FALSE(index.isFlexible());
-        EXPECT_EQ(index.coreIndex(), kParamIndexNumber);
-        EXPECT_EQ(index.typeIndex(), kParamIndexNumber);
-
-        C2Param::Type type = C2NumberStreamTuning::input::PARAM_TYPE;
-        EXPECT_FALSE(type.isVendor());
-        EXPECT_FALSE(type.isFlexible());
-        EXPECT_FALSE(type.isGlobal());
-        EXPECT_TRUE(type.forInput());
-        EXPECT_FALSE(type.forOutput());
-        EXPECT_TRUE(type.forStream());
-        EXPECT_FALSE(type.forPort());
-
-        type = C2NumberStreamTuning::output::PARAM_TYPE;
-        EXPECT_FALSE(type.isVendor());
-        EXPECT_FALSE(type.isFlexible());
-        EXPECT_FALSE(type.isGlobal());
-        EXPECT_FALSE(type.forInput());
-        EXPECT_TRUE(type.forOutput());
-        EXPECT_TRUE(type.forStream());
-        EXPECT_FALSE(type.forPort());
-
-        EXPECT_EQ(C2NumberPortTuning::From(nullptr), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::input::From(nullptr), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::output::From(nullptr), nullptr);
-        EXPECT_EQ(C2NumberTuning::From(&ins1), nullptr);
-        EXPECT_EQ(C2NumberTuning::From(&ins2), nullptr);
-        EXPECT_EQ(C2NumberTuning::From(&outs1), nullptr);
-        EXPECT_EQ(C2NumberTuning::From(&outs2), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::From(&ins1), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::From(&ins2), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::From(&outs1), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::From(&outs2), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::input::From(&ins1), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::input::From(&ins2), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::input::From(&outs1), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::input::From(&outs2), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::output::From(&ins1), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::output::From(&ins2), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::output::From(&outs1), nullptr);
-        EXPECT_EQ(C2NumberPortTuning::output::From(&outs2), nullptr);
-        EXPECT_EQ(C2NumberStreamTuning::From(&ins1), &ins1);
-        EXPECT_EQ(C2NumberStreamTuning::From(&ins2), (C2NumberStreamTuning*)&ins2);
-        EXPECT_EQ(C2NumberStreamTuning::From(&outs1), &outs1);
-        EXPECT_EQ(C2NumberStreamTuning::From(&outs2), (C2NumberStreamTuning*)&outs2);
-        EXPECT_EQ(C2NumberStreamTuning::input::From(&ins1), (C2NumberStreamTuning::input*)&ins1);
-        EXPECT_EQ(C2NumberStreamTuning::input::From(&ins2), &ins2);
-        EXPECT_EQ(C2NumberStreamTuning::input::From(&outs1), nullptr);
-        EXPECT_EQ(C2NumberStreamTuning::input::From(&outs2), nullptr);
-        EXPECT_EQ(C2NumberStreamTuning::output::From(&ins1), nullptr);
-        EXPECT_EQ(C2NumberStreamTuning::output::From(&ins2), nullptr);
-        EXPECT_EQ(C2NumberStreamTuning::output::From(&outs1), (C2NumberStreamTuning::output*)&outs1);
-        EXPECT_EQ(C2NumberStreamTuning::output::From(&outs2), &outs2);
-
-        EXPECT_EQ(*(C2Param::Copy(ins1)), ins1);
-        EXPECT_EQ(*(C2Param::Copy(ins2)), ins2);
-        EXPECT_EQ(*(C2Param::Copy(outs1)), outs1);
-        EXPECT_EQ(*(C2Param::Copy(outs2)), outs2);
-    }
-
-    {
-        uint32_t videoWidth[] = { 12u, C2NumberStreamTuning::output::PARAM_TYPE, 100 };
-        C2Param *p1 = C2Param::From(videoWidth, sizeof(videoWidth));
-        EXPECT_NE(p1, nullptr);
-        EXPECT_EQ(12u, p1->size());
-        EXPECT_EQ(p1->type(), C2NumberStreamTuning::output::PARAM_TYPE);
-
-        p1 = C2Param::From(videoWidth, sizeof(videoWidth) + 2);
-        EXPECT_EQ(p1, nullptr);
-
-        p1 = C2Param::From(videoWidth, sizeof(videoWidth) - 2);
-        EXPECT_EQ(p1, nullptr);
-
-        p1 = C2Param::From(videoWidth, 3);
-        EXPECT_EQ(p1, nullptr);
-
-        p1 = C2Param::From(videoWidth, 0);
-        EXPECT_EQ(p1, nullptr);
-    }
-}
-
-void StaticTestAddCoreIndex() {
-    struct nobase {};
-    struct base { enum : uint32_t { CORE_INDEX = 1 }; };
-    static_assert(_C2AddCoreIndex<nobase, 2>::CORE_INDEX == 2, "should be 2");
-    static_assert(_C2AddCoreIndex<base, 1>::CORE_INDEX == 1, "should be 1");
-}
-
-class TestFlexHelper {
-    struct _Flex {
-        int32_t a;
-        char b[];
-        _Flex() {}
-        FLEX(_Flex, b);
-    };
-
-    struct _BoFlex {
-        _Flex a;
-        _BoFlex() {}
-        FLEX(_BoFlex, a);
-    };
-
-    struct _NonFlex {
-    };
-
-
-    static void StaticTest() {
-        static_assert(std::is_same<_C2FlexHelper<char>::FlexType, void>::value, "should be void");
-        static_assert(std::is_same<_C2FlexHelper<char[]>::FlexType, char>::value, "should be char");
-        static_assert(std::is_same<_C2FlexHelper<_Flex>::FlexType, char>::value, "should be char");
-
-        static_assert(std::is_same<_C2FlexHelper<_BoFlex>::FlexType, char>::value, "should be void");
-
-        static_assert(_C2Flexible<_Flex>::value, "should be flexible");
-        static_assert(!_C2Flexible<_NonFlex>::value, "should not be flexible");
-    }
-};
-
-TEST_F(C2ParamTest, FlexParamOpsTest) {
-//    const C2NumbersStruct str{100};
-    C2NumbersStruct bstr;
-    {
-//        EXPECT_EQ(100, str->m.mNumbers[0]);
-        (void)&bstr.mNumbers[0];
-
-        C2Param::CoreIndex index = C2NumbersStruct::CORE_INDEX;
-        EXPECT_FALSE(index.isVendor());
-        EXPECT_TRUE(index.isFlexible());
-        EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::CoreIndex::IS_FLEX_FLAG);
-        EXPECT_EQ(index.typeIndex(), kParamIndexNumbers);
-    }
-
-    std::unique_ptr<C2NumbersTuning> tun_ = C2NumbersTuning::AllocUnique(1);
-    tun_->m.mNumbers[0] = 100;
-    std::unique_ptr<const C2NumbersTuning> tun = std::move(tun_);
-    std::shared_ptr<C2NumbersTuning> btun = C2NumbersTuning::AllocShared(1);
-
-    {
-        // flags & invariables
-        const C2NumbersTuning *T[] = { tun.get(), btun.get() };
-        for (const auto p : T) {
-            EXPECT_TRUE((bool)(*p));
-            EXPECT_FALSE(!(*p));
-            EXPECT_EQ(12u, p->size());
-
-            EXPECT_FALSE(p->isVendor());
-            EXPECT_TRUE(p->isFlexible());
-            EXPECT_TRUE(p->isGlobal());
-            EXPECT_FALSE(p->forInput());
-            EXPECT_FALSE(p->forOutput());
-            EXPECT_FALSE(p->forStream());
-            EXPECT_FALSE(p->forPort());
-        }
-
-        // value
-        EXPECT_EQ(100, tun->m.mNumbers[0]);
-        EXPECT_EQ(0, btun->m.mNumbers[0]);
-        EXPECT_FALSE(*tun == *btun);
-        EXPECT_FALSE(tun->operator==(*btun));
-        EXPECT_TRUE(*tun != *btun);
-        EXPECT_TRUE(tun->operator!=(*btun));
-        btun->m.mNumbers[0] = 100;
-        EXPECT_EQ(*tun, *btun);
-
-        // index
-        EXPECT_EQ(C2Param::Type(tun->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
-        EXPECT_EQ(C2Param::Type(tun->type()).typeIndex(), kParamIndexNumbers);
-        EXPECT_EQ(tun->type(), C2NumbersTuning::PARAM_TYPE);
-        EXPECT_EQ(tun->stream(), ~0u);
-
-        C2Param::CoreIndex index = C2NumbersTuning::CORE_INDEX;
-        EXPECT_FALSE(index.isVendor());
-        EXPECT_TRUE(index.isFlexible());
-        EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::CoreIndex::IS_FLEX_FLAG);
-        EXPECT_EQ(index.typeIndex(), kParamIndexNumbers);
-
-        C2Param::Type type = C2NumbersTuning::PARAM_TYPE;
-        EXPECT_FALSE(type.isVendor());
-        EXPECT_TRUE(type.isFlexible());
-        EXPECT_TRUE(type.isGlobal());
-        EXPECT_FALSE(type.forInput());
-        EXPECT_FALSE(type.forOutput());
-        EXPECT_FALSE(type.forStream());
-        EXPECT_FALSE(type.forPort());
-
-        EXPECT_EQ(C2NumbersTuning::From(nullptr), nullptr);
-        EXPECT_EQ(C2NumbersTuning::From(tun.get()), tun.get());
-        EXPECT_EQ(C2NumbersPortTuning::From(tun.get()), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::input::From(tun.get()), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::output::From(tun.get()), nullptr);
-        EXPECT_EQ(C2NumbersStreamTuning::From(tun.get()), nullptr);
-        EXPECT_EQ(C2NumbersStreamTuning::input::From(tun.get()), nullptr);
-        EXPECT_EQ(C2NumbersStreamTuning::output::From(tun.get()), nullptr);
-
-        EXPECT_EQ(*(C2Param::Copy(*tun)), *tun);
-    }
-
-    std::unique_ptr<C2NumbersPortTuning> outp1_(C2NumbersPortTuning::AllocUnique(1, true)),
-            inp1_ = C2NumbersPortTuning::AllocUnique(1, false);
-    outp1_->m.mNumbers[0] = 100;
-    inp1_->m.mNumbers[0] = 100;
-    std::unique_ptr<const C2NumbersPortTuning> outp1 = std::move(outp1_);
-    std::unique_ptr<const C2NumbersPortTuning> inp1 = std::move(inp1_);
-    std::shared_ptr<C2NumbersPortTuning> boutp1(C2NumbersPortTuning::AllocShared(1)),
-            binp1 = C2NumbersPortTuning::AllocShared(1),
-            binp3 = C2NumbersPortTuning::AllocShared(1, false);
-    binp3->m.mNumbers[0] = 100;
-    std::unique_ptr<C2NumbersPortTuning::input> inp2_(C2NumbersPortTuning::input::AllocUnique(1));
-    inp2_->m.mNumbers[0] = 100;
-    std::unique_ptr<const C2NumbersPortTuning::input> inp2 = std::move(inp2_);
-    std::shared_ptr<C2NumbersPortTuning::input> binp2(C2NumbersPortTuning::input::AllocShared(1));
-    std::unique_ptr<C2NumbersPortTuning::output> outp2_(C2NumbersPortTuning::output::AllocUnique(1));
-    outp2_->m.mNumbers[0] = 100;
-    std::unique_ptr<const C2NumbersPortTuning::output> outp2 = std::move(outp2_);
-    std::shared_ptr<C2NumbersPortTuning::output> boutp2(C2NumbersPortTuning::output::AllocShared(1));
-
-    {
-        static_assert(canCallSetPort(*binp3), "should be able to");
-        static_assert(canCallSetPort(*binp1), "should be able to");
-        static_assert(!canCallSetPort(*inp1), "should not be able to (const)");
-        static_assert(!canCallSetPort(*inp2), "should not be able to (const & type)");
-        static_assert(!canCallSetPort(*binp2), "should not be able to (type)");
-
-        // flags & invariables
-        const C2NumbersPortTuning *P[] = { outp1.get(), inp1.get(), boutp1.get() };
-        for (const auto p : P) {
-            EXPECT_EQ(12u, p->size());
-            EXPECT_FALSE(p->isVendor());
-            EXPECT_TRUE(p->isFlexible());
-            EXPECT_FALSE(p->isGlobal());
-            EXPECT_FALSE(p->forStream());
-            EXPECT_TRUE(p->forPort());
-        }
-        const C2NumbersPortTuning::input *PI[] = { inp2.get(), binp2.get() };
-        for (const auto p : PI) {
-            EXPECT_EQ(12u, p->size());
-            EXPECT_FALSE(p->isVendor());
-            EXPECT_TRUE(p->isFlexible());
-            EXPECT_FALSE(p->isGlobal());
-            EXPECT_FALSE(p->forStream());
-            EXPECT_TRUE(p->forPort());
-        }
-        const C2NumbersPortTuning::output *PO[] = { outp2.get(), boutp2.get() };
-        for (const auto p : PO) {
-            EXPECT_EQ(12u, p->size());
-            EXPECT_FALSE(p->isVendor());
-            EXPECT_TRUE(p->isFlexible());
-            EXPECT_FALSE(p->isGlobal());
-            EXPECT_FALSE(p->forStream());
-            EXPECT_TRUE(p->forPort());
-        }
-
-        // port specific flags & invariables
-        EXPECT_FALSE(outp1->forInput());
-        EXPECT_TRUE(outp1->forOutput());
-
-        EXPECT_TRUE(inp1->forInput());
-        EXPECT_FALSE(inp1->forOutput());
-
-        const C2NumbersPortTuning *P2[] = { outp1.get(), inp1.get() };
-        for (const auto p : P2) {
-            EXPECT_TRUE((bool)(*p));
-            EXPECT_FALSE(!(*p));
-            EXPECT_EQ(100, p->m.mNumbers[0]);
-        }
-        for (const auto p : PO) {
-            EXPECT_TRUE((bool)(*p));
-            EXPECT_FALSE(!(*p));
-
-            EXPECT_FALSE(p->forInput());
-            EXPECT_TRUE(p->forOutput());
-        }
-        for (const auto p : PI) {
-            EXPECT_TRUE((bool)(*p));
-            EXPECT_FALSE(!(*p));
-
-            EXPECT_TRUE(p->forInput());
-            EXPECT_FALSE(p->forOutput());
-        }
-        const C2NumbersPortTuning *P3[] = { boutp1.get() };
-        for (const auto p : P3) {
-            EXPECT_FALSE((bool)(*p));
-            EXPECT_TRUE(!(*p));
-
-            EXPECT_FALSE(p->forInput());
-            EXPECT_FALSE(p->forOutput());
-            EXPECT_EQ(0, p->m.mNumbers[0]);
-        }
-
-        // values
-        EXPECT_EQ(100, inp2->m.mNumbers[0]);
-        EXPECT_EQ(100, outp2->m.mNumbers[0]);
-        EXPECT_EQ(0, binp1->m.mNumbers[0]);
-        EXPECT_EQ(0, binp2->m.mNumbers[0]);
-        EXPECT_EQ(0, boutp1->m.mNumbers[0]);
-        EXPECT_EQ(0, boutp2->m.mNumbers[0]);
-
-        EXPECT_TRUE(*inp1 != *outp1);
-        EXPECT_TRUE(*inp1 == *inp2);
-        EXPECT_TRUE(*outp1 == *outp2);
-        EXPECT_TRUE(*binp1 == *boutp1);
-        EXPECT_TRUE(*binp2 != *boutp2);
-
-        EXPECT_TRUE(*inp1 != *binp1);
-        binp1->m.mNumbers[0] = 100;
-        EXPECT_TRUE(*inp1 != *binp1);
-        binp1->setPort(false /* output */);
-        EXPECT_TRUE((bool)*binp1);
-        EXPECT_FALSE(!*binp1);
-        EXPECT_TRUE(*inp1 == *binp1);
-
-        EXPECT_TRUE(*inp2 != *binp2);
-        binp2->m.mNumbers[0] = 100;
-        EXPECT_TRUE(*inp2 == *binp2);
-
-        binp1->setPort(true /* output */);
-        EXPECT_TRUE(*outp1 == *binp1);
-
-        EXPECT_TRUE(*outp1 != *boutp1);
-        boutp1->m.mNumbers[0] = 100;
-        EXPECT_TRUE(*outp1 != *boutp1);
-        boutp1->setPort(true /* output */);
-        EXPECT_TRUE((bool)*boutp1);
-        EXPECT_FALSE(!*boutp1);
-        EXPECT_TRUE(*outp1 == *boutp1);
-
-        EXPECT_TRUE(*outp2 != *boutp2);
-        boutp2->m.mNumbers[0] = 100;
-        EXPECT_TRUE(*outp2 == *boutp2);
-
-        boutp1->setPort(false /* output */);
-        EXPECT_TRUE(*inp1 == *boutp1);
-
-        // index
-        EXPECT_EQ(C2Param::Type(inp1->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
-        EXPECT_EQ(C2Param::Type(inp1->type()).typeIndex(), kParamIndexNumbers);
-        EXPECT_EQ(inp1->type(), C2NumbersPortTuning::input::PARAM_TYPE);
-        EXPECT_EQ(inp1->stream(), ~0u);
-
-        EXPECT_EQ(C2Param::Type(inp2->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
-        EXPECT_EQ(C2Param::Type(inp2->type()).typeIndex(), kParamIndexNumbers);
-        EXPECT_EQ(inp2->type(), C2NumbersPortTuning::input::PARAM_TYPE);
-        EXPECT_EQ(inp2->stream(), ~0u);
-
-        EXPECT_EQ(C2Param::Type(outp1->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
-        EXPECT_EQ(C2Param::Type(outp1->type()).typeIndex(), kParamIndexNumbers);
-        EXPECT_EQ(outp1->type(), C2NumbersPortTuning::output::PARAM_TYPE);
-        EXPECT_EQ(outp1->stream(), ~0u);
-
-        EXPECT_EQ(C2Param::Type(outp2->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
-        EXPECT_EQ(C2Param::Type(outp2->type()).typeIndex(), kParamIndexNumbers);
-        EXPECT_EQ(outp2->type(), C2NumbersPortTuning::output::PARAM_TYPE);
-        EXPECT_EQ(outp2->stream(), ~0u);
-
-        C2Param::CoreIndex index = C2NumbersPortTuning::input::PARAM_TYPE;
-        EXPECT_FALSE(index.isVendor());
-        EXPECT_TRUE(index.isFlexible());
-        EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::CoreIndex::IS_FLEX_FLAG);
-        EXPECT_EQ(index.typeIndex(), kParamIndexNumbers);
-
-        index = C2NumbersPortTuning::output::PARAM_TYPE;
-        EXPECT_FALSE(index.isVendor());
-        EXPECT_TRUE(index.isFlexible());
-        EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::CoreIndex::IS_FLEX_FLAG);
-        EXPECT_EQ(index.typeIndex(), kParamIndexNumbers);
-
-        C2Param::Type type = C2NumbersPortTuning::input::PARAM_TYPE;
-        EXPECT_FALSE(type.isVendor());
-        EXPECT_TRUE(type.isFlexible());
-        EXPECT_FALSE(type.isGlobal());
-        EXPECT_TRUE(type.forInput());
-        EXPECT_FALSE(type.forOutput());
-        EXPECT_FALSE(type.forStream());
-        EXPECT_TRUE(type.forPort());
-
-        type = C2NumbersPortTuning::output::PARAM_TYPE;
-        EXPECT_FALSE(type.isVendor());
-        EXPECT_TRUE(type.isFlexible());
-        EXPECT_FALSE(type.isGlobal());
-        EXPECT_FALSE(type.forInput());
-        EXPECT_TRUE(type.forOutput());
-        EXPECT_FALSE(type.forStream());
-        EXPECT_TRUE(type.forPort());
-
-        EXPECT_EQ(C2NumbersPortTuning::From(nullptr), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::input::From(nullptr), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::output::From(nullptr), nullptr);
-        EXPECT_EQ(C2NumbersTuning::From(inp1.get()), nullptr);
-        EXPECT_EQ(C2NumbersTuning::From(inp2.get()), nullptr);
-        EXPECT_EQ(C2NumbersTuning::From(outp1.get()), nullptr);
-        EXPECT_EQ(C2NumbersTuning::From(outp2.get()), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::From(inp1.get()), inp1.get());
-        EXPECT_EQ(C2NumbersPortTuning::From(inp2.get()), (C2NumbersPortTuning*)inp2.get());
-        EXPECT_EQ(C2NumbersPortTuning::From(outp1.get()), outp1.get());
-        EXPECT_EQ(C2NumbersPortTuning::From(outp2.get()), (C2NumbersPortTuning*)outp2.get());
-        EXPECT_EQ(C2NumbersPortTuning::input::From(inp1.get()), (C2NumbersPortTuning::input*)inp1.get());
-        EXPECT_EQ(C2NumbersPortTuning::input::From(inp2.get()), inp2.get());
-        EXPECT_EQ(C2NumbersPortTuning::input::From(outp1.get()), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::input::From(outp2.get()), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::output::From(inp1.get()), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::output::From(inp2.get()), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::output::From(outp1.get()), (C2NumbersPortTuning::output*)outp1.get());
-        EXPECT_EQ(C2NumbersPortTuning::output::From(outp2.get()), outp2.get());
-        EXPECT_EQ(C2NumbersStreamTuning::From(inp1.get()), nullptr);
-        EXPECT_EQ(C2NumbersStreamTuning::From(inp2.get()), nullptr);
-        EXPECT_EQ(C2NumbersStreamTuning::From(outp1.get()), nullptr);
-        EXPECT_EQ(C2NumbersStreamTuning::From(outp2.get()), nullptr);
-        EXPECT_EQ(C2NumbersStreamTuning::input::From(inp1.get()), nullptr);
-        EXPECT_EQ(C2NumbersStreamTuning::input::From(inp2.get()), nullptr);
-        EXPECT_EQ(C2NumbersStreamTuning::input::From(outp1.get()), nullptr);
-        EXPECT_EQ(C2NumbersStreamTuning::input::From(outp2.get()), nullptr);
-        EXPECT_EQ(C2NumbersStreamTuning::output::From(inp1.get()), nullptr);
-        EXPECT_EQ(C2NumbersStreamTuning::output::From(inp2.get()), nullptr);
-        EXPECT_EQ(C2NumbersStreamTuning::output::From(outp1.get()), nullptr);
-        EXPECT_EQ(C2NumbersStreamTuning::output::From(outp2.get()), nullptr);
-
-        EXPECT_EQ(*(C2Param::Copy(*inp1)), *inp1);
-        EXPECT_EQ(*(C2Param::Copy(*inp2)), *inp2);
-        EXPECT_EQ(*(C2Param::Copy(*outp1)), *outp1);
-        EXPECT_EQ(*(C2Param::Copy(*outp2)), *outp2);
-    }
-
-    std::unique_ptr<C2NumbersStreamTuning> outs1_(C2NumbersStreamTuning::AllocUnique(1, true, 1u));
-    outs1_->m.mNumbers[0] = 100;
-    std::unique_ptr<const C2NumbersStreamTuning> outs1 = std::move(outs1_);
-    std::unique_ptr<C2NumbersStreamTuning> ins1_(C2NumbersStreamTuning::AllocUnique(1, false, 1u));
-    ins1_->m.mNumbers[0] = 100;
-    std::unique_ptr<const C2NumbersStreamTuning> ins1 = std::move(ins1_);
-    std::shared_ptr<C2NumbersStreamTuning> bouts1(C2NumbersStreamTuning::AllocShared(1));
-    std::shared_ptr<C2NumbersStreamTuning> bins1(C2NumbersStreamTuning::AllocShared(1));
-    std::shared_ptr<C2NumbersStreamTuning> bins3(C2NumbersStreamTuning::AllocShared(1, false, 1u));
-    bins3->m.mNumbers[0] = 100;
-    std::unique_ptr<C2NumbersStreamTuning::input> ins2_(C2NumbersStreamTuning::input::AllocUnique(1, 1u));
-    ins2_->m.mNumbers[0] = 100;
-    std::unique_ptr<const C2NumbersStreamTuning::input> ins2 = std::move(ins2_);
-    std::shared_ptr<C2NumbersStreamTuning::input> bins2(C2NumbersStreamTuning::input::AllocShared(1));
-    std::unique_ptr<C2NumbersStreamTuning::output> outs2_(C2NumbersStreamTuning::output::AllocUnique(1, 1u));
-    outs2_->m.mNumbers[0] = 100;
-    std::unique_ptr<const C2NumbersStreamTuning::output> outs2 = std::move(outs2_);
-    std::shared_ptr<C2NumbersStreamTuning::output> bouts2(C2NumbersStreamTuning::output::AllocShared(1));
-
-    {
-        static_assert(canCallSetPort(*bins3), "should be able to");
-        static_assert(canCallSetPort(*bins1), "should be able to");
-        static_assert(!canCallSetPort(*ins1), "should not be able to (const)");
-        static_assert(!canCallSetPort(*ins2), "should not be able to (const & type)");
-        static_assert(!canCallSetPort(*bins2), "should not be able to (type)");
-
-        // flags & invariables
-        const C2NumbersStreamTuning *S[] = { outs1.get(), ins1.get(), bouts1.get() };
-        for (const auto p : S) {
-            EXPECT_EQ(12u, p->size());
-            EXPECT_FALSE(p->isVendor());
-            EXPECT_TRUE(p->isFlexible());
-            EXPECT_FALSE(p->isGlobal());
-            EXPECT_TRUE(p->forStream());
-            EXPECT_FALSE(p->forPort());
-        }
-        const C2NumbersStreamTuning::input *SI[] = { ins2.get(), bins2.get() };
-        for (const auto p : SI) {
-            EXPECT_EQ(12u, p->size());
-            EXPECT_FALSE(p->isVendor());
-            EXPECT_TRUE(p->isFlexible());
-            EXPECT_FALSE(p->isGlobal());
-            EXPECT_TRUE(p->forStream());
-            EXPECT_FALSE(p->forPort());
-        }
-        const C2NumbersStreamTuning::output *SO[] = { outs2.get(), bouts2.get() };
-        for (const auto p : SO) {
-            EXPECT_EQ(12u, p->size());
-            EXPECT_FALSE(p->isVendor());
-            EXPECT_TRUE(p->isFlexible());
-            EXPECT_FALSE(p->isGlobal());
-            EXPECT_TRUE(p->forStream());
-            EXPECT_FALSE(p->forPort());
-        }
-
-        // port specific flags & invariables
-        EXPECT_FALSE(outs1->forInput());
-        EXPECT_TRUE(outs1->forOutput());
-
-        EXPECT_TRUE(ins1->forInput());
-        EXPECT_FALSE(ins1->forOutput());
-
-        const C2NumbersStreamTuning *S2[] = { outs1.get(), ins1.get() };
-        for (const auto p : S2) {
-            EXPECT_TRUE((bool)(*p));
-            EXPECT_FALSE(!(*p));
-            EXPECT_EQ(100, p->m.mNumbers[0]);
-            EXPECT_EQ(1u, p->stream());
-        }
-        for (const auto p : SO) {
-            EXPECT_TRUE((bool)(*p));
-            EXPECT_FALSE(!(*p));
-
-            EXPECT_FALSE(p->forInput());
-            EXPECT_TRUE(p->forOutput());
-        }
-        for (const auto p : SI) {
-            EXPECT_TRUE((bool)(*p));
-            EXPECT_FALSE(!(*p));
-
-            EXPECT_TRUE(p->forInput());
-            EXPECT_FALSE(p->forOutput());
-        }
-        const C2NumbersStreamTuning *S3[] = { bouts1.get() };
-        for (const auto p : S3) {
-            EXPECT_FALSE((bool)(*p));
-            EXPECT_TRUE(!(*p));
-
-            EXPECT_FALSE(p->forInput());
-            EXPECT_FALSE(p->forOutput());
-            EXPECT_EQ(0, p->m.mNumbers[0]);
-        }
-
-        // values
-        EXPECT_EQ(100, ins2->m.mNumbers[0]);
-        EXPECT_EQ(100, outs2->m.mNumbers[0]);
-        EXPECT_EQ(0, bins1->m.mNumbers[0]);
-        EXPECT_EQ(0, bins2->m.mNumbers[0]);
-        EXPECT_EQ(0, bouts1->m.mNumbers[0]);
-        EXPECT_EQ(0, bouts2->m.mNumbers[0]);
-
-        EXPECT_EQ(1u, ins2->stream());
-        EXPECT_EQ(1u, outs2->stream());
-        EXPECT_EQ(0u, bins1->stream());
-        EXPECT_EQ(0u, bins2->stream());
-        EXPECT_EQ(0u, bouts1->stream());
-        EXPECT_EQ(0u, bouts2->stream());
-
-        EXPECT_TRUE(*ins1 != *outs1);
-        EXPECT_TRUE(*ins1 == *ins2);
-        EXPECT_TRUE(*outs1 == *outs2);
-        EXPECT_TRUE(*bins1 == *bouts1);
-        EXPECT_TRUE(*bins2 != *bouts2);
-
-        EXPECT_TRUE(*ins1 != *bins1);
-        bins1->m.mNumbers[0] = 100;
-        EXPECT_TRUE(*ins1 != *bins1);
-        bins1->setPort(false /* output */);
-        EXPECT_TRUE(*ins1 != *bins1);
-        bins1->setStream(1u);
-        EXPECT_TRUE(*ins1 == *bins1);
-
-        EXPECT_TRUE(*ins2 != *bins2);
-        bins2->m.mNumbers[0] = 100;
-        EXPECT_TRUE(*ins2 != *bins2);
-        bins2->setStream(1u);
-        EXPECT_TRUE(*ins2 == *bins2);
-
-        bins1->setPort(true /* output */);
-        EXPECT_TRUE(*outs1 == *bins1);
-
-        EXPECT_TRUE(*outs1 != *bouts1);
-        bouts1->m.mNumbers[0] = 100;
-        EXPECT_TRUE(*outs1 != *bouts1);
-        bouts1->setPort(true /* output */);
-        EXPECT_TRUE(*outs1 != *bouts1);
-        bouts1->setStream(1u);
-        EXPECT_TRUE(*outs1 == *bouts1);
-
-        EXPECT_TRUE(*outs2 != *bouts2);
-        bouts2->m.mNumbers[0] = 100;
-        EXPECT_TRUE(*outs2 != *bouts2);
-        bouts2->setStream(1u);
-        EXPECT_TRUE(*outs2 == *bouts2);
-
-        bouts1->setPort(false /* output */);
-        EXPECT_TRUE(*ins1 == *bouts1);
-
-        // index
-        EXPECT_EQ(C2Param::Type(ins1->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
-        EXPECT_EQ(C2Param::Type(ins1->type()).typeIndex(), kParamIndexNumbers);
-        EXPECT_EQ(ins1->type(), C2NumbersStreamTuning::input::PARAM_TYPE);
-
-        EXPECT_EQ(C2Param::Type(ins2->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
-        EXPECT_EQ(C2Param::Type(ins2->type()).typeIndex(), kParamIndexNumbers);
-        EXPECT_EQ(ins2->type(), C2NumbersStreamTuning::input::PARAM_TYPE);
-
-        EXPECT_EQ(C2Param::Type(outs1->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
-        EXPECT_EQ(C2Param::Type(outs1->type()).typeIndex(), kParamIndexNumbers);
-        EXPECT_EQ(outs1->type(), C2NumbersStreamTuning::output::PARAM_TYPE);
-
-        EXPECT_EQ(C2Param::Type(outs2->type()).coreIndex(), C2NumbersStruct::CORE_INDEX);
-        EXPECT_EQ(C2Param::Type(outs2->type()).typeIndex(), kParamIndexNumbers);
-        EXPECT_EQ(outs2->type(), C2NumbersStreamTuning::output::PARAM_TYPE);
-
-        C2Param::CoreIndex index = C2NumbersStreamTuning::input::PARAM_TYPE;
-        EXPECT_FALSE(index.isVendor());
-        EXPECT_TRUE(index.isFlexible());
-        EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::CoreIndex::IS_FLEX_FLAG);
-        EXPECT_EQ(index.typeIndex(), kParamIndexNumbers);
-
-        index = C2NumbersStreamTuning::output::PARAM_TYPE;
-        EXPECT_FALSE(index.isVendor());
-        EXPECT_TRUE(index.isFlexible());
-        EXPECT_EQ(index.coreIndex(), kParamIndexNumbers | C2Param::CoreIndex::IS_FLEX_FLAG);
-        EXPECT_EQ(index.typeIndex(), kParamIndexNumbers);
-
-        C2Param::Type type = C2NumbersStreamTuning::input::PARAM_TYPE;
-        EXPECT_FALSE(type.isVendor());
-        EXPECT_TRUE(type.isFlexible());
-        EXPECT_FALSE(type.isGlobal());
-        EXPECT_TRUE(type.forInput());
-        EXPECT_FALSE(type.forOutput());
-        EXPECT_TRUE(type.forStream());
-        EXPECT_FALSE(type.forPort());
-
-        type = C2NumbersStreamTuning::output::PARAM_TYPE;
-        EXPECT_FALSE(type.isVendor());
-        EXPECT_TRUE(type.isFlexible());
-        EXPECT_FALSE(type.isGlobal());
-        EXPECT_FALSE(type.forInput());
-        EXPECT_TRUE(type.forOutput());
-        EXPECT_TRUE(type.forStream());
-        EXPECT_FALSE(type.forPort());
-
-        EXPECT_EQ(C2NumbersPortTuning::From(nullptr), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::input::From(nullptr), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::output::From(nullptr), nullptr);
-        EXPECT_EQ(C2NumbersTuning::From(ins1.get()), nullptr);
-        EXPECT_EQ(C2NumbersTuning::From(ins2.get()), nullptr);
-        EXPECT_EQ(C2NumbersTuning::From(outs1.get()), nullptr);
-        EXPECT_EQ(C2NumbersTuning::From(outs2.get()), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::From(ins1.get()), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::From(ins2.get()), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::From(outs1.get()), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::From(outs2.get()), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::input::From(ins1.get()), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::input::From(ins2.get()), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::input::From(outs1.get()), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::input::From(outs2.get()), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::output::From(ins1.get()), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::output::From(ins2.get()), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::output::From(outs1.get()), nullptr);
-        EXPECT_EQ(C2NumbersPortTuning::output::From(outs2.get()), nullptr);
-        EXPECT_EQ(C2NumbersStreamTuning::From(ins1.get()), ins1.get());
-        EXPECT_EQ(C2NumbersStreamTuning::From(ins2.get()), (C2NumbersStreamTuning*)ins2.get());
-        EXPECT_EQ(C2NumbersStreamTuning::From(outs1.get()), outs1.get());
-        EXPECT_EQ(C2NumbersStreamTuning::From(outs2.get()), (C2NumbersStreamTuning*)outs2.get());
-        EXPECT_EQ(C2NumbersStreamTuning::input::From(ins1.get()), (C2NumbersStreamTuning::input*)ins1.get());
-        EXPECT_EQ(C2NumbersStreamTuning::input::From(ins2.get()), ins2.get());
-        EXPECT_EQ(C2NumbersStreamTuning::input::From(outs1.get()), nullptr);
-        EXPECT_EQ(C2NumbersStreamTuning::input::From(outs2.get()), nullptr);
-        EXPECT_EQ(C2NumbersStreamTuning::output::From(ins1.get()), nullptr);
-        EXPECT_EQ(C2NumbersStreamTuning::output::From(ins2.get()), nullptr);
-        EXPECT_EQ(C2NumbersStreamTuning::output::From(outs1.get()), (C2NumbersStreamTuning::output*)outs1.get());
-        EXPECT_EQ(C2NumbersStreamTuning::output::From(outs2.get()), outs2.get());
-
-        EXPECT_EQ(*(C2Param::Copy(*ins1)), *ins1);
-        EXPECT_EQ(*(C2Param::Copy(*ins2)), *ins2);
-        EXPECT_EQ(*(C2Param::Copy(*outs1)), *outs1);
-        EXPECT_EQ(*(C2Param::Copy(*outs2)), *outs2);
-    }
-
-    {
-        C2Int32Value int32Value(INT32_MIN);
-        static_assert(std::is_same<decltype(int32Value.value), int32_t>::value, "should be int32_t");
-        EXPECT_EQ(INT32_MIN, int32Value.value);
-        std::list<const C2FieldDescriptor> fields = int32Value.FIELD_LIST;
-        EXPECT_EQ(1u, fields.size());
-        EXPECT_EQ(FD::INT32, fields.cbegin()->type());
-        EXPECT_EQ(1u, fields.cbegin()->extent());
-        EXPECT_EQ(C2String("value"), fields.cbegin()->name());
-    }
-
-    {
-        C2Uint32Value uint32Value(UINT32_MAX);
-        static_assert(std::is_same<decltype(uint32Value.value), uint32_t>::value, "should be uint32_t");
-        EXPECT_EQ(UINT32_MAX, uint32Value.value);
-        std::list<const C2FieldDescriptor> fields = uint32Value.FIELD_LIST;
-        EXPECT_EQ(1u, fields.size());
-        EXPECT_EQ(FD::UINT32, fields.cbegin()->type());
-        EXPECT_EQ(1u, fields.cbegin()->extent());
-        EXPECT_EQ(C2String("value"), fields.cbegin()->name());
-    }
-
-    {
-        C2Int64Value int64Value(INT64_MIN);
-        static_assert(std::is_same<decltype(int64Value.value), int64_t>::value, "should be int64_t");
-        EXPECT_EQ(INT64_MIN, int64Value.value);
-        std::list<const C2FieldDescriptor> fields = int64Value.FIELD_LIST;
-        EXPECT_EQ(1u, fields.size());
-        EXPECT_EQ(FD::INT64, fields.cbegin()->type());
-        EXPECT_EQ(1u, fields.cbegin()->extent());
-        EXPECT_EQ(C2String("value"), fields.cbegin()->name());
-    }
-
-    {
-        C2Uint64Value uint64Value(UINT64_MAX);
-        static_assert(std::is_same<decltype(uint64Value.value), uint64_t>::value, "should be uint64_t");
-        EXPECT_EQ(UINT64_MAX, uint64Value.value);
-        std::list<const C2FieldDescriptor> fields = uint64Value.FIELD_LIST;
-        EXPECT_EQ(1u, fields.size());
-        EXPECT_EQ(FD::UINT64, fields.cbegin()->type());
-        EXPECT_EQ(1u, fields.cbegin()->extent());
-        EXPECT_EQ(C2String("value"), fields.cbegin()->name());
-    }
-
-    {
-        C2FloatValue floatValue(123.4f);
-        static_assert(std::is_same<decltype(floatValue.value), float>::value, "should be float");
-        EXPECT_EQ(123.4f, floatValue.value);
-        std::list<const C2FieldDescriptor> fields = floatValue.FIELD_LIST;
-        EXPECT_EQ(1u, fields.size());
-        EXPECT_EQ(FD::FLOAT, fields.cbegin()->type());
-        EXPECT_EQ(1u, fields.cbegin()->extent());
-        EXPECT_EQ(C2String("value"), fields.cbegin()->name());
-    }
-
-    {
-        uint8_t initValue[] = "ABCD";
-        typedef C2GlobalParam<C2Setting, C2BlobValue, 0> BlobSetting;
-        std::unique_ptr<BlobSetting> blobValue = BlobSetting::AllocUnique(6, C2ConstMemoryBlock<uint8_t>(initValue));
-        static_assert(std::is_same<decltype(blobValue->m.value), uint8_t[]>::value, "should be uint8_t[]");
-        EXPECT_EQ(0, memcmp(blobValue->m.value, "ABCD\0", 6));
-        EXPECT_EQ(6u, blobValue->flexCount());
-        std::list<const C2FieldDescriptor> fields = blobValue->FIELD_LIST;
-        EXPECT_EQ(1u, fields.size());
-        EXPECT_EQ(FD::BLOB, fields.cbegin()->type());
-        EXPECT_EQ(0u, fields.cbegin()->extent());
-        EXPECT_EQ(C2String("value"), fields.cbegin()->name());
-
-        blobValue = BlobSetting::AllocUnique(3, C2ConstMemoryBlock<uint8_t>(initValue));
-        EXPECT_EQ(0, memcmp(blobValue->m.value, "ABC", 3));
-        EXPECT_EQ(3u, blobValue->flexCount());
-    }
-
-    {
-        constexpr char initValue[] = "ABCD";
-        typedef C2GlobalParam<C2Setting, C2StringValue, 0> StringSetting;
-        std::unique_ptr<StringSetting> stringValue = StringSetting::AllocUnique(6, C2ConstMemoryBlock<char>(initValue));
-        stringValue = StringSetting::AllocUnique(6, initValue);
-        static_assert(std::is_same<decltype(stringValue->m.value), char[]>::value, "should be char[]");
-        EXPECT_EQ(0, memcmp(stringValue->m.value, "ABCD\0", 6));
-        EXPECT_EQ(6u, stringValue->flexCount());
-        std::list<const C2FieldDescriptor> fields = stringValue->FIELD_LIST;
-        EXPECT_EQ(1u, fields.size());
-        EXPECT_EQ(FD::STRING, fields.cbegin()->type());
-        EXPECT_EQ(0u, fields.cbegin()->extent());
-        EXPECT_EQ(C2String("value"), fields.cbegin()->name());
-
-        stringValue = StringSetting::AllocUnique(3, C2ConstMemoryBlock<char>(initValue));
-        EXPECT_EQ(0, memcmp(stringValue->m.value, "AB", 3));
-        EXPECT_EQ(3u, stringValue->flexCount());
-
-        stringValue = StringSetting::AllocUnique(11, "initValue");
-        EXPECT_EQ(0, memcmp(stringValue->m.value, "initValue\0", 11));
-        EXPECT_EQ(11u, stringValue->flexCount());
-
-        stringValue = StringSetting::AllocUnique(initValue);
-        EXPECT_EQ(0, memcmp(stringValue->m.value, "ABCD", 5));
-        EXPECT_EQ(5u, stringValue->flexCount());
-
-        stringValue = StringSetting::AllocUnique({ 'A', 'B', 'C', 'D' });
-        EXPECT_EQ(0, memcmp(stringValue->m.value, "ABC", 4));
-        EXPECT_EQ(4u, stringValue->flexCount());
-    }
-
-    {
-        uint32_t videoWidth[] = { 12u, C2NumbersStreamTuning::output::PARAM_TYPE, 100 };
-        C2Param *p1 = C2Param::From(videoWidth, sizeof(videoWidth));
-        EXPECT_NE(nullptr, p1);
-        EXPECT_EQ(12u, p1->size());
-        EXPECT_EQ(p1->type(), C2NumbersStreamTuning::output::PARAM_TYPE);
-
-        C2NumbersStreamTuning::output *vst = C2NumbersStreamTuning::output::From(p1);
-        EXPECT_NE(nullptr, vst);
-        if (vst) {
-            EXPECT_EQ(1u, vst->flexCount());
-            EXPECT_EQ(100, vst->m.mNumbers[0]);
-        }
-
-        p1 = C2Param::From(videoWidth, sizeof(videoWidth) + 2);
-        EXPECT_EQ(nullptr, p1);
-
-        p1 = C2Param::From(videoWidth, sizeof(videoWidth) - 2);
-        EXPECT_EQ(nullptr, p1);
-
-        p1 = C2Param::From(videoWidth, 3);
-        EXPECT_EQ(nullptr, p1);
-
-        p1 = C2Param::From(videoWidth, 0);
-        EXPECT_EQ(nullptr, p1);
-    }
-
-    {
-        uint32_t videoWidth[] = { 16u, C2NumbersPortTuning::input::PARAM_TYPE, 101, 102 };
-
-        C2Param *p1 = C2Param::From(videoWidth, sizeof(videoWidth));
-        EXPECT_NE(nullptr, p1);
-        EXPECT_EQ(16u, p1->size());
-        EXPECT_EQ(p1->type(), C2NumbersPortTuning::input::PARAM_TYPE);
-
-        C2NumbersPortTuning::input *vpt = C2NumbersPortTuning::input::From(p1);
-        EXPECT_NE(nullptr, vpt);
-        if (vpt) {
-            EXPECT_EQ(2u, vpt->flexCount());
-            EXPECT_EQ(101, vpt->m.mNumbers[0]);
-            EXPECT_EQ(102, vpt->m.mNumbers[1]);
-        }
-
-        p1 = C2Param::From(videoWidth, sizeof(videoWidth) + 2);
-        EXPECT_EQ(nullptr, p1);
-
-        p1 = C2Param::From(videoWidth, sizeof(videoWidth) - 2);
-        EXPECT_EQ(nullptr, p1);
-
-        p1 = C2Param::From(videoWidth, 3);
-        EXPECT_EQ(nullptr, p1);
-
-        p1 = C2Param::From(videoWidth, 0);
-        EXPECT_EQ(nullptr, p1);
-    }
-}
-
-// ***********************
-
-#include <util/C2ParamUtils.h>
-#include <C2Config.h>
-#include <C2Component.h>
-#include <unordered_map>
-
-C2ENUM(
-    MetadataType, int32_t,
-    kInvalid = -1,
-    kNone = 0,
-    kGralloc,
-    kNativeHandle,
-    kANativeWindow,
-    kCamera,
-)
-
-enum {
-    kParamIndexVideoConfig = 0x1234,
-};
-
-struct C2VideoConfigStruct {
-    int32_t width;
-    uint32_t height;
-    MetadataType metadataType;
-    int32_t supportedFormats[];
-
-    C2VideoConfigStruct() {}
-
-    DEFINE_AND_DESCRIBE_FLEX_C2STRUCT(VideoConfig, supportedFormats)
-    C2FIELD(width, "width")
-    C2FIELD(height, "height")
-    C2FIELD(metadataType, "metadata-type")
-    C2FIELD(supportedFormats, "formats")
-};
-
-typedef C2PortParam<C2Tuning, C2VideoConfigStruct> C2VideoConfigPortTuning;
-
-class MyComponentInstance : public C2ComponentInterface {
-public:
-    virtual C2String getName() const override {
-        /// \todo this seems too specific
-        return "sample.interface";
-    };
-
-    virtual c2_node_id_t getId() const override {
-        /// \todo how are these shared?
-        return 0;
-    }
-
-    virtual c2_status_t config_vb(
-            const std::vector<C2Param*> &params,
-            c2_blocking_t mayBlock,
-            std::vector<std::unique_ptr<C2SettingResult>>* const failures) override {
-        (void)params;
-        (void)failures;
-        (void)mayBlock;
-        return C2_OMITTED;
-    }
-
-    virtual c2_status_t createTunnel_sm(c2_node_id_t targetComponent) override {
-        (void)targetComponent;
-        return C2_OMITTED;
-    }
-
-    virtual c2_status_t query_vb(
-            const std::vector<C2Param*> &stackParams,
-            const std::vector<C2Param::Index> &heapParamIndices,
-            c2_blocking_t mayBlock,
-            std::vector<std::unique_ptr<C2Param>>* const heapParams) const override {
-        for (C2Param* const param : stackParams) {
-            (void)mayBlock;
-            if (!*param) { // param is already invalid - remember it
-                continue;
-            }
-
-            // note: this does not handle stream params (should use index...)
-            if (!mMyParams.count(param->index())) {
-                continue; // not my param
-            }
-
-            C2Param & myParam = mMyParams.find(param->index())->second;
-            if (myParam.size() != param->size()) { // incorrect size
-                param->invalidate();
-                continue;
-            }
-
-            param->updateFrom(myParam);
-        }
-
-        for (const C2Param::Index index : heapParamIndices) {
-            if (mMyParams.count(index)) {
-                C2Param & myParam = mMyParams.find(index)->second;
-                std::unique_ptr<C2Param> paramCopy(C2Param::Copy(myParam));
-                heapParams->push_back(std::move(paramCopy));
-            }
-        }
-
-        return C2_OK;
-    }
-
-    std::unordered_map<uint32_t, C2Param &> mMyParams;
-
-    C2ComponentDomainInfo mDomainInfo;
-
-    MyComponentInstance() {
-        mMyParams.insert({mDomainInfo.index(), mDomainInfo});
-    }
-
-    virtual c2_status_t releaseTunnel_sm(c2_node_id_t targetComponent) override {
-        (void)targetComponent;
-        return C2_OMITTED;
-    }
-
-    class MyParamReflector : public C2ParamReflector {
-        const MyComponentInstance *instance;
-
-    public:
-        MyParamReflector(const MyComponentInstance *i) : instance(i) { }
-
-        virtual std::unique_ptr<C2StructDescriptor> describe(C2Param::CoreIndex paramIndex) const override {
-            switch (paramIndex.typeIndex()) {
-            case decltype(instance->mDomainInfo)::CORE_INDEX:
-            default:
-                return std::unique_ptr<C2StructDescriptor>(new C2StructDescriptor{
-                    instance->mDomainInfo.type(),
-                    decltype(instance->mDomainInfo)::FIELD_LIST,
-                });
-            }
-            return nullptr;
-        }
-    };
-
-    virtual c2_status_t querySupportedValues_vb(
-            std::vector<C2FieldSupportedValuesQuery> &fields,
-            c2_blocking_t mayBlock) const override {
-        (void)mayBlock;
-        for (C2FieldSupportedValuesQuery &query : fields) {
-            if (query.field() == C2ParamField(&mDomainInfo, &C2ComponentDomainInfo::value)) {
-                query.values = C2FieldSupportedValues(
-                    false /* flag */,
-                    &mDomainInfo.value
-                    //,
-                    //{(int32_t)C2DomainVideo}
-                );
-                query.status = C2_OK;
-            } else {
-                query.status = C2_BAD_INDEX;
-            }
-        }
-        return C2_OK;
-    }
-
-    std::shared_ptr<C2ParamReflector> getParamReflector() const {
-        return std::shared_ptr<C2ParamReflector>(new MyParamReflector(this));
-    }
-
-    virtual c2_status_t querySupportedParams_nb(
-            std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const override {
-        params->push_back(std::make_shared<C2ParamDescriptor>(
-                true /* required */, "_domain", &mDomainInfo));
-        params->push_back(std::shared_ptr<C2ParamDescriptor>(
-                new C2ParamDescriptor(true /* required */, "_domain", &mDomainInfo)));
-        return C2_OK;
-    }
-
-    virtual ~MyComponentInstance() override = default;
-};
-
-template<typename E, bool S=std::is_enum<E>::value>
-struct getter {
-    int32_t get(const C2FieldSupportedValues::Primitive &p, int32_t*) {
-        return p.i32;
-    }
-    int64_t get(const C2FieldSupportedValues::Primitive &p, int64_t*) {
-        return p.i64;
-    }
-    uint32_t get(const C2FieldSupportedValues::Primitive &p, uint32_t*) {
-        return p.u32;
-    }
-    uint64_t get(const C2FieldSupportedValues::Primitive &p, uint64_t*) {
-        return p.u64;
-    }
-    float get(const C2FieldSupportedValues::Primitive &p, float*) {
-        return p.fp;
-    }
-};
-
-template<typename E>
-struct getter<E, true> {
-     typename std::underlying_type<E>::type get(const C2FieldSupportedValues::Primitive &p, E*) {
-         using u=typename std::underlying_type<E>::type;
-         return getter<u>().get(p, (u*)0);
-     }
-};
-
-template<typename T, bool E=std::is_enum<T>::value>
-struct lax_underlying_type {
-    typedef typename std::underlying_type<T>::type type;
-};
-
-template<typename T>
-struct lax_underlying_type<T, false> {
-    typedef T type;
-};
-
-template<typename E>
-typename lax_underlying_type<E>::type get(
-        const C2FieldSupportedValues::Primitive &p, E*) {
-    return getter<E>().get(p, (E*)0);
-}
-
-template<typename T>
-void dumpFSV(const C2FieldSupportedValues &sv, T*t) {
-    using namespace std;
-    cout << (std::is_enum<T>::value ? (std::is_signed<typename lax_underlying_type<T>::type>::value ? "i" : "u")
-             : std::is_integral<T>::value ? std::is_signed<T>::value ? "i" : "u" : "f")
-         << (8 * sizeof(T));
-    if (sv.type == sv.RANGE) {
-        cout << ".range(" << get(sv.range.min, t);
-        if (get(sv.range.step, t) != std::is_integral<T>::value) {
-            cout << ":" << get(sv.range.step, t);
-        }
-        if (get(sv.range.num, t) != 1 || get(sv.range.denom, t) != 1) {
-            cout << ":" << get(sv.range.num, t) << "/" << get(sv.range.denom, t);
-        }
-        cout << get(sv.range.max, t) << ")";
-    }
-    if (sv.values.size()) {
-        cout << (sv.type == sv.FLAGS ? ".flags(" : ".list(");
-        const char *sep = "";
-        for (const C2FieldSupportedValues::Primitive &p : sv.values) {
-            cout << sep << get(p, t);
-            sep = ",";
-        }
-        cout << ")";
-    }
-    cout << endl;
-}
-
-void dumpType(C2Param::Type type) {
-    using namespace std;
-    cout << (type.isVendor() ? "Vendor" : "C2");
-    if (type.forInput()) {
-        cout << "Input";
-    } else if (type.forOutput()) {
-        cout << "Output";
-    } else if (type.forPort() && !type.forStream()) {
-        cout << "Port";
-    }
-    if (type.forStream()) {
-        cout << "Stream";
-    }
-
-    if (type.isFlexible()) {
-        cout << "Flex";
-    }
-
-    cout << type.typeIndex();
-
-    switch (type.kind()) {
-    case C2Param::INFO: cout << "Info"; break;
-    case C2Param::SETTING: cout << "Setting"; break;
-    case C2Param::TUNING: cout << "Tuning"; break;
-    case C2Param::STRUCT: cout << "Struct"; break;
-    default: cout << "Kind" << (int32_t)type.kind(); break;
-    }
-}
-
-void dumpType(C2Param::CoreIndex type) {
-    using namespace std;
-    cout << (type.isVendor() ? "Vendor" : "C2");
-    if (type.isFlexible()) {
-        cout << "Flex";
-    }
-
-    cout << type.typeIndex() << "Struct";
-}
-
-void dumpType(FD::type_t type) {
-    using namespace std;
-    switch (type) {
-    case FD::BLOB: cout << "blob "; break;
-    case FD::FLOAT: cout << "float "; break;
-    case FD::INT32: cout << "int32_t "; break;
-    case FD::INT64: cout << "int64_t "; break;
-    case FD::UINT32: cout << "uint32_t "; break;
-    case FD::UINT64: cout << "uint64_t "; break;
-    case FD::STRING: cout << "char "; break;
-    default:
-        cout << "struct ";
-        dumpType((C2Param::Type)type);
-        break;
-    }
-}
-
-void dumpStruct(const C2StructDescriptor &sd) {
-    using namespace std;
-    cout << "struct ";
-    dumpType(sd.coreIndex());
-    cout << " {" << endl;
-    //C2FieldDescriptor &f;
-    for (const C2FieldDescriptor &f : sd) {
-        PrintTo(f, &cout);
-        cout << endl;
-
-        if (f.namedValues().size()) {
-            cout << ".named(";
-            const char *sep = "";
-            for (const FD::NamedValueType &p : f.namedValues()) {
-                cout << sep << p.first << "=";
-                switch (f.type()) {
-                case C2Value::INT32: cout << get(p.second, (int32_t *)0); break;
-                case C2Value::INT64: cout << get(p.second, (int64_t *)0); break;
-                case C2Value::UINT32: cout << get(p.second, (uint32_t *)0); break;
-                case C2Value::UINT64: cout << get(p.second, (uint64_t *)0); break;
-                case C2Value::FLOAT: cout << get(p.second, (float *)0); break;
-                default: cout << "???"; break;
-                }
-                sep = ",";
-            }
-            cout << ")";
-        }
-    }
-
-    cout << "};" << endl;
-}
-
-void dumpDesc(const C2ParamDescriptor &pd) {
-    using namespace std;
-    if (pd.isRequired()) {
-        cout << "required ";
-    }
-    if (pd.isPersistent()) {
-        cout << "persistent ";
-    }
-    cout << "struct ";
-    dumpType(C2Param::Type(pd.index().type()));
-    cout << " " << pd.name() << ";" << endl;
-}
-
-TEST_F(C2ParamTest, ReflectorTest) {
-    C2ComponentDomainInfo domainInfo;
-    std::shared_ptr<MyComponentInstance> myComp(new MyComponentInstance);
-    std::shared_ptr<C2ComponentInterface> comp = myComp;
-
-    std::unique_ptr<C2StructDescriptor> desc{
-        myComp->getParamReflector()->describe(C2ComponentDomainInfo::CORE_INDEX)};
-    dumpStruct(*desc);
-
-    std::vector<C2FieldSupportedValuesQuery> query = {
-        { C2ParamField(&domainInfo, &C2ComponentDomainInfo::value),
-          C2FieldSupportedValuesQuery::CURRENT },
-        C2FieldSupportedValuesQuery(C2ParamField(&domainInfo, &C2ComponentDomainInfo::value),
-          C2FieldSupportedValuesQuery::CURRENT),
-        C2FieldSupportedValuesQuery::Current(C2ParamField(&domainInfo, &C2ComponentDomainInfo::value)),
-    };
-
-    EXPECT_EQ(C2_OK, comp->querySupportedValues_vb(query, C2_DONT_BLOCK));
-
-    for (const C2FieldSupportedValuesQuery &q : query) {
-        dumpFSV(q.values, &domainInfo.value);
-    }
-}
-
-TEST_F(C2ParamTest, FieldSupportedValuesTest) {
-    typedef C2GlobalParam<C2Info, C2Uint32Value, 0> Uint32TestInfo;
-    Uint32TestInfo t;
-    std::vector<C2FieldSupportedValues> values;
-    values.push_back(C2FieldSupportedValues(0, 10, 1));  // min, max, step
-    values.push_back(C2FieldSupportedValues(1, 64, 2, 1));  // min, max, num, den
-    values.push_back(C2FieldSupportedValues(false, {1, 2, 3}));  // flags, std::initializer_list
-    uint32_t val[] = {1, 3, 5, 7};
-    std::vector<uint32_t> v(std::begin(val), std::end(val));
-    values.push_back(C2FieldSupportedValues(false, v));  // flags, std::vector
-
-    for (const C2FieldSupportedValues &sv : values) {
-        dumpFSV(sv, &t.value);
-    }
-}
-
-C2ENUM(Enum1, uint32_t,
-    Enum1Value1,
-    Enum1Value2,
-    Enum1Value4 = Enum1Value2 + 2,
-);
-
-C2ENUM_CUSTOM_PREFIX(Enum2, uint32_t, "Enum",
-    Enum2Value1,
-    Enum2Value2,
-    Enum2Value4 = Enum1Value2 + 2,
-);
-
-C2ENUM_CUSTOM_NAMES(Enum3, uint8_t,
-    ({ { "value1", Enum3Value1 },
-       { "value2", Enum3Value2 },
-       { "value4", Enum3Value4 },
-       { "invalid", Invalid } }),
-    Enum3Value1,
-    Enum3Value2,
-    Enum3Value4 = Enum3Value2 + 2,
-    Invalid,
-);
-
-TEST_F(C2ParamTest, EnumUtilsTest) {
-    std::vector<std::pair<C2String, Enum3>> pairs ( { { "value1", Enum3Value1 },
-      { "value2", Enum3Value2 },
-      { "value4", Enum3Value4 },
-      { "invalid", Invalid } });
-    Enum3 e3;
-    FD::namedValuesFor(e3);
-}
-
-TEST_F(C2ParamTest, ParamUtilsTest) {
-    // upper case
-    EXPECT_EQ("yes", C2ParamUtils::camelCaseToDashed("YES"));
-    EXPECT_EQ("no", C2ParamUtils::camelCaseToDashed("NO"));
-    EXPECT_EQ("yes-no", C2ParamUtils::camelCaseToDashed("YES_NO"));
-    EXPECT_EQ("yes-no", C2ParamUtils::camelCaseToDashed("YES__NO"));
-    EXPECT_EQ("a2dp", C2ParamUtils::camelCaseToDashed("A2DP"));
-    EXPECT_EQ("mp2-ts", C2ParamUtils::camelCaseToDashed("MP2_TS"));
-    EXPECT_EQ("block-2d", C2ParamUtils::camelCaseToDashed("BLOCK_2D"));
-    EXPECT_EQ("mpeg-2-ts", C2ParamUtils::camelCaseToDashed("MPEG_2_TS"));
-    EXPECT_EQ("_hidden-value", C2ParamUtils::camelCaseToDashed("_HIDDEN_VALUE"));
-    EXPECT_EQ("__hidden-value2", C2ParamUtils::camelCaseToDashed("__HIDDEN_VALUE2"));
-    EXPECT_EQ("__hidden-value-2", C2ParamUtils::camelCaseToDashed("__HIDDEN_VALUE_2"));
-
-    // camel case
-    EXPECT_EQ("yes", C2ParamUtils::camelCaseToDashed("Yes"));
-    EXPECT_EQ("no", C2ParamUtils::camelCaseToDashed("No"));
-    EXPECT_EQ("yes-no", C2ParamUtils::camelCaseToDashed("YesNo"));
-    EXPECT_EQ("yes-no", C2ParamUtils::camelCaseToDashed("Yes_No"));
-    EXPECT_EQ("mp2-ts", C2ParamUtils::camelCaseToDashed("MP2Ts"));
-    EXPECT_EQ("block-2d", C2ParamUtils::camelCaseToDashed("Block2D"));
-    EXPECT_EQ("mpeg-2-ts", C2ParamUtils::camelCaseToDashed("Mpeg2ts"));
-    EXPECT_EQ("_hidden-value", C2ParamUtils::camelCaseToDashed("_HiddenValue"));
-    EXPECT_EQ("__hidden-value-2", C2ParamUtils::camelCaseToDashed("__HiddenValue2"));
-
-    // mixed case
-    EXPECT_EQ("mp2t-s", C2ParamUtils::camelCaseToDashed("MP2T_s"));
-    EXPECT_EQ("block-2d", C2ParamUtils::camelCaseToDashed("Block_2D"));
-    EXPECT_EQ("block-2-d", C2ParamUtils::camelCaseToDashed("Block2_D"));
-    EXPECT_EQ("mpeg-2-ts", C2ParamUtils::camelCaseToDashed("Mpeg_2ts"));
-    EXPECT_EQ("mpeg-2-ts", C2ParamUtils::camelCaseToDashed("Mpeg_2_TS"));
-    EXPECT_EQ("_hidden-value", C2ParamUtils::camelCaseToDashed("_Hidden__VALUE"));
-    EXPECT_EQ("__hidden-value-2", C2ParamUtils::camelCaseToDashed("__HiddenValue_2"));
-    EXPECT_EQ("_2", C2ParamUtils::camelCaseToDashed("_2"));
-    EXPECT_EQ("__23", C2ParamUtils::camelCaseToDashed("__23"));
-}
-
-TEST_F(C2ParamTest, C2ValueTest) {
-    C2Value val;
-    int32_t i32 = -32;
-    int64_t i64 = -64;
-    uint32_t u32 = 32;
-    uint64_t u64 = 64;
-    float fp = 1.5f;
-
-    EXPECT_EQ(C2Value::NO_INIT, val.type());
-    EXPECT_EQ(false, val.get(&i32));
-    EXPECT_EQ(-32, i32);
-    EXPECT_EQ(false, val.get(&i64));
-    EXPECT_EQ(-64, i64);
-    EXPECT_EQ(false, val.get(&u32));
-    EXPECT_EQ(32u, u32);
-    EXPECT_EQ(false, val.get(&u64));
-    EXPECT_EQ(64u, u64);
-    EXPECT_EQ(false, val.get(&fp));
-    EXPECT_EQ(1.5f, fp);
-
-    val = int32_t(-3216);
-    EXPECT_EQ(C2Value::INT32, val.type());
-    EXPECT_EQ(true, val.get(&i32));
-    EXPECT_EQ(-3216, i32);
-    EXPECT_EQ(false, val.get(&i64));
-    EXPECT_EQ(-64, i64);
-    EXPECT_EQ(false, val.get(&u32));
-    EXPECT_EQ(32u, u32);
-    EXPECT_EQ(false, val.get(&u64));
-    EXPECT_EQ(64u, u64);
-    EXPECT_EQ(false, val.get(&fp));
-    EXPECT_EQ(1.5f, fp);
-
-    val = uint32_t(3216);
-    EXPECT_EQ(C2Value::UINT32, val.type());
-    EXPECT_EQ(false, val.get(&i32));
-    EXPECT_EQ(-3216, i32);
-    EXPECT_EQ(false, val.get(&i64));
-    EXPECT_EQ(-64, i64);
-    EXPECT_EQ(true, val.get(&u32));
-    EXPECT_EQ(3216u, u32);
-    EXPECT_EQ(false, val.get(&u64));
-    EXPECT_EQ(64u, u64);
-    EXPECT_EQ(false, val.get(&fp));
-    EXPECT_EQ(1.5f, fp);
-
-    val = int64_t(-6432);
-    EXPECT_EQ(C2Value::INT64, val.type());
-    EXPECT_EQ(false, val.get(&i32));
-    EXPECT_EQ(-3216, i32);
-    EXPECT_EQ(true, val.get(&i64));
-    EXPECT_EQ(-6432, i64);
-    EXPECT_EQ(false, val.get(&u32));
-    EXPECT_EQ(3216u, u32);
-    EXPECT_EQ(false, val.get(&u64));
-    EXPECT_EQ(64u, u64);
-    EXPECT_EQ(false, val.get(&fp));
-    EXPECT_EQ(1.5f, fp);
-
-    val = uint64_t(6432);
-    EXPECT_EQ(C2Value::UINT64, val.type());
-    EXPECT_EQ(false, val.get(&i32));
-    EXPECT_EQ(-3216, i32);
-    EXPECT_EQ(false, val.get(&i64));
-    EXPECT_EQ(-6432, i64);
-    EXPECT_EQ(false, val.get(&u32));
-    EXPECT_EQ(3216u, u32);
-    EXPECT_EQ(true, val.get(&u64));
-    EXPECT_EQ(6432u, u64);
-    EXPECT_EQ(false, val.get(&fp));
-    EXPECT_EQ(1.5f, fp);
-
-    val = 15.25f;
-    EXPECT_EQ(C2Value::FLOAT, val.type());
-    EXPECT_EQ(false, val.get(&i32));
-    EXPECT_EQ(-3216, i32);
-    EXPECT_EQ(false, val.get(&i64));
-    EXPECT_EQ(-6432, i64);
-    EXPECT_EQ(false, val.get(&u32));
-    EXPECT_EQ(3216u, u32);
-    EXPECT_EQ(false, val.get(&u64));
-    EXPECT_EQ(6432u, u64);
-    EXPECT_EQ(true, val.get(&fp));
-    EXPECT_EQ(15.25f, fp);
-}
-
diff --git a/media/libstagefright/codec2/tests/C2_test.cpp b/media/libstagefright/codec2/tests/C2_test.cpp
deleted file mode 100644
index 46f545f..0000000
--- a/media/libstagefright/codec2/tests/C2_test.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright 2014 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 "C2_test"
-
-#include <gtest/gtest.h>
-
-#include <C2.h>
-
-namespace android {
-
-/* ======================================= STATIC TESTS ======================================= */
-
-template<int N>
-struct c2_const_checker
-{
-    inline constexpr static int num() { return N; }
-};
-
-constexpr auto min_i32_i32 = c2_min(int32_t(1), int32_t(2));
-static_assert(std::is_same<decltype(min_i32_i32), const int32_t>::value, "should be int32_t");
-constexpr auto min_i32_i64 = c2_min(int32_t(3), int64_t(2));
-static_assert(std::is_same<decltype(min_i32_i64), const int64_t>::value, "should be int64_t");
-constexpr auto min_i8_i32 = c2_min(int8_t(0xff), int32_t(0xffffffff));
-static_assert(std::is_same<decltype(min_i8_i32), const int32_t>::value, "should be int32_t");
-
-static_assert(c2_const_checker<min_i32_i32>::num() == 1, "should be 1");
-static_assert(c2_const_checker<min_i32_i64>::num() == 2, "should be 2");
-static_assert(c2_const_checker<min_i8_i32>::num() == 0xffffffff, "should be 0xffffffff");
-
-constexpr auto min_u32_u32 = c2_min(uint32_t(1), uint32_t(2));
-static_assert(std::is_same<decltype(min_u32_u32), const uint32_t>::value, "should be uint32_t");
-constexpr auto min_u32_u64 = c2_min(uint32_t(3), uint64_t(2));
-static_assert(std::is_same<decltype(min_u32_u64), const uint32_t>::value, "should be uint32_t");
-constexpr auto min_u32_u8 = c2_min(uint32_t(0xffffffff), uint8_t(0xff));
-static_assert(std::is_same<decltype(min_u32_u8), const uint8_t>::value, "should be uint8_t");
-
-static_assert(c2_const_checker<min_u32_u32>::num() == 1, "should be 1");
-static_assert(c2_const_checker<min_u32_u64>::num() == 2, "should be 2");
-static_assert(c2_const_checker<min_u32_u8>::num() == 0xff, "should be 0xff");
-
-constexpr auto max_i32_i32 = c2_max(int32_t(1), int32_t(2));
-static_assert(std::is_same<decltype(max_i32_i32), const int32_t>::value, "should be int32_t");
-constexpr auto max_i32_i64 = c2_max(int32_t(3), int64_t(2));
-static_assert(std::is_same<decltype(max_i32_i64), const int64_t>::value, "should be int64_t");
-constexpr auto max_i8_i32 = c2_max(int8_t(0xff), int32_t(0xffffffff));
-static_assert(std::is_same<decltype(max_i8_i32), const int32_t>::value, "should be int32_t");
-
-static_assert(c2_const_checker<max_i32_i32>::num() == 2, "should be 2");
-static_assert(c2_const_checker<max_i32_i64>::num() == 3, "should be 3");
-static_assert(c2_const_checker<max_i8_i32>::num() == 0xffffffff, "should be 0xffffffff");
-
-constexpr auto max_u32_u32 = c2_max(uint32_t(1), uint32_t(2));
-static_assert(std::is_same<decltype(max_u32_u32), const uint32_t>::value, "should be uint32_t");
-constexpr auto max_u32_u64 = c2_max(uint32_t(3), uint64_t(2));
-static_assert(std::is_same<decltype(max_u32_u64), const uint64_t>::value, "should be uint64_t");
-constexpr auto max_u32_u8 = c2_max(uint32_t(0x7fffffff), uint8_t(0xff));
-static_assert(std::is_same<decltype(max_u32_u8), const uint32_t>::value, "should be uint32_t");
-
-static_assert(c2_const_checker<max_u32_u32>::num() == 2, "should be 2");
-static_assert(c2_const_checker<max_u32_u64>::num() == 3, "should be 3");
-static_assert(c2_const_checker<max_u32_u8>::num() == 0x7fffffff, "should be 0x7fffffff");
-
-/* ======================================= COUNTER TESTS ======================================= */
-
-void c2_cntr_static_test() {
-    // sanity checks for construction/assignment
-    constexpr c2_cntr32_t c32_a(123);
-    constexpr c2_cntr64_t c64_a(-456);
-    c2_cntr32_t c32_b __unused = c64_a;
-    // c32_b = 64.; // DISALLOWED
-    // c2_cntr64_t c64_b = c32_a; // DISALLOWED
-
-    // sanity checks for some constexpr operators
-    static_assert(std::is_same<decltype(c32_a + c64_a), decltype(c64_a + c32_a)>::value, "+ should result same type");
-    static_assert(c32_a + c64_a == c2_cntr32_t(-333), "123 + -456 = -333");
-    static_assert(c32_a + c32_a == c2_cntr32_t(246), "123 + 123 = 246");
-    static_assert(c64_a + c32_a == c2_cntr32_t(-333), "-456 + 123 = 579");
-    static_assert(std::is_same<decltype(c32_a + 1), decltype(1 + c32_a)>::value, "+ should result same type");
-    static_assert(c32_a + 456 == c2_cntr32_t(579), "123 + 456 = 579");
-    static_assert(456 + c64_a == c2_cntr64_t(0), "456 + -456 = 0");
-    static_assert(std::is_same<decltype(c32_a - c64_a), decltype(c64_a - c32_a)>::value, "- should result same type");
-    static_assert(c32_a - c64_a == c2_cntr32_t(579), "123 - -456 = 579");
-    static_assert(c32_a - c32_a == c2_cntr32_t(0), "123 - 123 = 0");
-    static_assert(c64_a - c32_a == c2_cntr32_t(-579), "-456 - 123 = -579");
-    static_assert(std::is_same<decltype(c32_a - 1), decltype(1 - c32_a)>::value, "- should result same type");
-    static_assert(c32_a - 456 == c2_cntr32_t(-333), "123 - 456 = -333");
-    static_assert(456 - c64_a == c2_cntr64_t(912), "456 - -456 = 912");
-    static_assert(std::is_same<decltype(c32_a * c64_a), decltype(c64_a * c32_a)>::value, "* should result same type");
-    static_assert(c32_a * c64_a == c2_cntr32_t(-56088), "123 * -456 = -56088");
-    static_assert(c32_a * c32_a == c2_cntr32_t(15129), "123 * 123 = 15129");
-    static_assert(c64_a * c32_a == c2_cntr32_t(-56088), "-456 * 123 = -56088");
-    static_assert(std::is_same<decltype(c32_a * 1), decltype(1 * c32_a)>::value, "* should result same type");
-    static_assert(c32_a * 456 == c2_cntr32_t(56088), "123 * 456 = 56088");
-    static_assert(456 * c64_a == c2_cntr64_t(-207936), "456 * -456 = -207936");
-
-    static_assert((c32_a << 26u) == c2_cntr32_t(0xEC000000), "123 << 26 = 0xEC000000");
-
-    // sanity checks for unary operators
-    static_assert(c2_cntr32_t(1) == +c2_cntr32_t(1), "1 == +1");
-    static_assert(c2_cntr32_t(1) == -c2_cntr32_t(-1), "1 == --1");
-
-    // sanity checks for comparison
-    using c8_t = c2_cntr_t<uint8_t>;
-    static_assert(c8_t(-0x80) > c8_t(0x7f), "80 > 7F");
-    static_assert(c8_t(-0x80) >= c8_t(0x7f), "80 >= 7F");
-    static_assert(c8_t(0x7f) > c8_t(0x7e), "7F > 7E");
-    static_assert(c8_t(0x7f) >= c8_t(0x7e), "7F >= 7E");
-    static_assert(!(c8_t(-0x80) > c8_t(0)), "80 !> 00");
-    static_assert(!(c8_t(-0x80) >= c8_t(0)), "80 !>= 00");
-    static_assert(!(c8_t(-0x80) > c8_t(-0x80)), "80 !> 80");
-    static_assert(c8_t(-0x80) >= c8_t(-0x80), "80 >= 80");
-
-    static_assert(c8_t(-0x80) == c8_t(0x80), "80 == 80");
-    static_assert(!(c8_t(-0x80) == c8_t(0)), "80 != 0");
-    static_assert(c8_t(-0x80) != c8_t(0x7f), "80 != 7F");
-    static_assert(!(c8_t(0x7f) != c8_t(0x7f)), "80 != 7F");
-
-    static_assert(c8_t(0x7f) < c8_t(-0x80), "7F < 80");
-    static_assert(c8_t(0x7f) <= c8_t(-0x80), "7F < 80");
-    static_assert(c8_t(0x7e) < c8_t(0x7f), "7E < 7F");
-    static_assert(c8_t(0x7e) <= c8_t(0x7f), "7E < 7F");
-    static_assert(!(c8_t(-0x40) < c8_t(0x40)), "-40 !< 40");
-    static_assert(!(c8_t(-0x40) <= c8_t(0x40)), "-40 !<= 40");
-    static_assert(!(c8_t(-0x40) < c8_t(-0x40)), "-40 !< -40");
-    static_assert(c8_t(-0x40) <= c8_t(-0x40), "-40 <= -40");
-
-    static_assert(c2_cntr32_t(-0x7fffffff - 1) > c2_cntr32_t(0x7fffffff), "80 > 7F");
-    static_assert(!(c2_cntr32_t(-0x7fffffff - 1) > c2_cntr32_t(0)), "80 !> 00");
-    static_assert(c2_cntr32_t(1) == c2_cntr32_t(c2_cntr64_t(0x100000001ul)), "1 == 1");
-}
-
-class C2Test : public ::testing::Test {
-};
-
-TEST_F(C2Test, CounterTest) {
-    c2_cntr32_t c32_a(123);
-    c2_cntr64_t c64_a(-456);
-    EXPECT_EQ(c32_a += 3, c2_cntr32_t(126));
-    EXPECT_EQ(c32_a += c64_a, c2_cntr32_t(-330));
-    EXPECT_EQ(c32_a <<= 2u, c2_cntr32_t(-1320));
-    EXPECT_EQ(c64_a *= 3, c2_cntr64_t(-1368));
-    EXPECT_EQ(c32_a -= c64_a, c2_cntr32_t(48));
-    EXPECT_EQ(c32_a -= 40, c2_cntr32_t(8));
-    EXPECT_EQ(c32_a *= c32_a, c2_cntr32_t(64));
-}
-
-} // namespace android
diff --git a/media/libstagefright/codec2/tests/vndk/C2BufferTest.cpp b/media/libstagefright/codec2/tests/vndk/C2BufferTest.cpp
deleted file mode 100644
index f389abc..0000000
--- a/media/libstagefright/codec2/tests/vndk/C2BufferTest.cpp
+++ /dev/null
@@ -1,769 +0,0 @@
-/*
- * Copyright 2017 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 <C2AllocatorIon.h>
-#include <C2AllocatorGralloc.h>
-#include <C2Buffer.h>
-#include <C2BufferPriv.h>
-#include <C2ParamDef.h>
-
-#include <system/graphics.h>
-
-namespace android {
-
-class C2BufferUtilsTest : public ::testing::Test {
-    static void StaticSegmentTest() {
-        // constructor
-        static_assert(C2Segment(123u, 456u).offset == 123, "");
-        static_assert(C2Segment(123u, 456u).size == 456, "");
-
-        // empty
-        static_assert(!C2Segment(123u, 456u).isEmpty(), "");
-        static_assert(C2Segment(123u, 0u).isEmpty(), "");
-
-        // valid
-        static_assert(C2Segment(123u, 456u).isValid(), "");
-        static_assert(C2Segment(123u, ~123u).isValid(), "");
-        static_assert(!C2Segment(123u, 1 + ~123u).isValid(), "");
-
-        // bool()
-        static_assert(C2Segment(123u, 456u), "");
-        static_assert((bool)C2Segment(123u, ~123u), "");
-        static_assert(!bool(C2Segment(123u, 1 + ~123u)), "");
-        static_assert(!bool(C2Segment(123u, 0)), "");
-
-        // !
-        static_assert(!!C2Segment(123u, 456u), "");
-        static_assert(!!C2Segment(123u, ~123u), "");
-        static_assert(!C2Segment(123u, 1 + ~123u), "");
-        static_assert(!C2Segment(123u, 0), "");
-
-        // contains
-        static_assert(C2Segment(123u, ~123u).contains(C2Segment(123u, 0)), "");
-        static_assert(!C2Segment(123u, 1 + ~123u).contains(C2Segment(123u, 0)), "");
-        static_assert(C2Segment(123u, ~123u).contains(C2Segment(123u, ~123u)), "");
-        static_assert(!C2Segment(123u, ~123u).contains(C2Segment(123u, 1 + ~123u)), "");
-        static_assert(!C2Segment(123u, 1 + ~123u).contains(C2Segment(123u, 1 + ~123u)), "");
-        static_assert(!C2Segment(123u, ~123u).contains(C2Segment(122u, 2u)), "");
-        static_assert(C2Segment(123u, ~123u).contains(C2Segment(123u, 2u)), "");
-        static_assert(C2Segment(123u, 3u).contains(C2Segment(124u, 2u)), "");
-        static_assert(!C2Segment(123u, 3u).contains(C2Segment(125u, 2u)), "");
-
-        // ==
-        static_assert(C2Segment(123u, 456u) == C2Segment(123u, 456u), "");
-        static_assert(!(C2Segment(123u, 456u) == C2Segment(123u, 457u)), "");
-        static_assert(!(C2Segment(123u, 456u) == C2Segment(123u, 455u)), "");
-        static_assert(!(C2Segment(123u, 456u) == C2Segment(122u, 456u)), "");
-        static_assert(!(C2Segment(123u, 456u) == C2Segment(124u, 456u)), "");
-        static_assert(!(C2Segment(123u, 0u) == C2Segment(124u, 0u)), "");
-        static_assert(C2Segment(123u, 0u) == C2Segment(123u, 0u), "");
-        static_assert(C2Segment(123u, 1 + ~123u) == C2Segment(124u, 1 + ~124u), "");
-
-        // !=
-        static_assert(!(C2Segment(123u, 456u) != C2Segment(123u, 456u)), "");
-        static_assert(C2Segment(123u, 456u) != C2Segment(123u, 457u), "");
-        static_assert(C2Segment(123u, 456u) != C2Segment(123u, 455u), "");
-        static_assert(C2Segment(123u, 456u) != C2Segment(122u, 456u), "");
-        static_assert(C2Segment(123u, 456u) != C2Segment(124u, 456u), "");
-        static_assert(C2Segment(123u, 0u) != C2Segment(124u, 0u), "");
-        static_assert(!(C2Segment(123u, 0u) != C2Segment(123u, 0u)), "");
-        static_assert(!(C2Segment(123u, 1 + ~123u) != C2Segment(124u, 1 + ~124u)), "");
-
-        // <=
-        static_assert(C2Segment(123u, 456u) <= C2Segment(123u, 456u), "");
-        static_assert(C2Segment(123u, 456u) <= C2Segment(123u, 457u), "");
-        static_assert(C2Segment(123u, 456u) <= C2Segment(122u, 457u), "");
-        static_assert(!(C2Segment(123u, 457u) <= C2Segment(123u, 456u)), "");
-        static_assert(!(C2Segment(122u, 457u) <= C2Segment(123u, 456u)), "");
-        static_assert(!(C2Segment(123u, 457u) <= C2Segment(124u, 457u)), "");
-        static_assert(!(C2Segment(122u, 457u) <= C2Segment(123u, 457u)), "");
-        static_assert(!(C2Segment(122u, 0u) <= C2Segment(123u, 0u)), "");
-        static_assert(C2Segment(123u, 0u) <= C2Segment(122u, 1u), "");
-        static_assert(C2Segment(122u, 0u) <= C2Segment(122u, 1u), "");
-        static_assert(!(C2Segment(122u, ~122u) <= C2Segment(122u, 1 + ~122u)), "");
-        static_assert(!(C2Segment(122u, 1 + ~122u) <= C2Segment(122u, ~122u)), "");
-        static_assert(!(C2Segment(122u, 1 + ~122u) <= C2Segment(122u, 1 + ~122u)), "");
-
-        // <
-        static_assert(!(C2Segment(123u, 456u) < C2Segment(123u, 456u)), "");
-        static_assert(C2Segment(123u, 456u) < C2Segment(123u, 457u), "");
-        static_assert(C2Segment(123u, 456u) < C2Segment(122u, 457u), "");
-        static_assert(!(C2Segment(123u, 457u) < C2Segment(123u, 456u)), "");
-        static_assert(!(C2Segment(122u, 457u) < C2Segment(123u, 456u)), "");
-        static_assert(!(C2Segment(123u, 457u) < C2Segment(124u, 457u)), "");
-        static_assert(!(C2Segment(122u, 457u) < C2Segment(123u, 457u)), "");
-        static_assert(!(C2Segment(122u, 0u) < C2Segment(123u, 0u)), "");
-        static_assert(C2Segment(123u, 0u) < C2Segment(122u, 1u), "");
-        static_assert(C2Segment(122u, 0u) < C2Segment(122u, 1u), "");
-        static_assert(!(C2Segment(122u, ~122u) < C2Segment(122u, 1 + ~122u)), "");
-        static_assert(!(C2Segment(122u, 1 + ~122u) < C2Segment(122u, ~122u)), "");
-        static_assert(!(C2Segment(122u, 1 + ~122u) < C2Segment(122u, 1 + ~122u)), "");
-
-        // <=
-        static_assert(C2Segment(123u, 456u) >= C2Segment(123u, 456u), "");
-        static_assert(C2Segment(123u, 457u) >= C2Segment(123u, 456u), "");
-        static_assert(C2Segment(122u, 457u) >= C2Segment(123u, 456u), "");
-        static_assert(!(C2Segment(123u, 456u) >= C2Segment(123u, 457u)), "");
-        static_assert(!(C2Segment(123u, 456u) >= C2Segment(122u, 457u)), "");
-        static_assert(!(C2Segment(124u, 457u) >= C2Segment(123u, 457u)), "");
-        static_assert(!(C2Segment(123u, 457u) >= C2Segment(122u, 457u)), "");
-        static_assert(!(C2Segment(123u, 0u) >= C2Segment(122u, 0u)), "");
-        static_assert(C2Segment(122u, 1u) >= C2Segment(123u, 0u), "");
-        static_assert(C2Segment(122u, 1u) >= C2Segment(122u, 0u), "");
-        static_assert(!(C2Segment(122u, 1 + ~122u) >= C2Segment(122u, ~122u)), "");
-        static_assert(!(C2Segment(122u, ~122u) >= C2Segment(122u, 1 + ~122u)), "");
-        static_assert(!(C2Segment(122u, 1 + ~122u) >= C2Segment(122u, 1 + ~122u)), "");
-
-        // <
-        static_assert(!(C2Segment(123u, 456u) > C2Segment(123u, 456u)), "");
-        static_assert(C2Segment(123u, 457u) > C2Segment(123u, 456u), "");
-        static_assert(C2Segment(122u, 457u) > C2Segment(123u, 456u), "");
-        static_assert(!(C2Segment(123u, 456u) > C2Segment(123u, 457u)), "");
-        static_assert(!(C2Segment(123u, 456u) > C2Segment(122u, 457u)), "");
-        static_assert(!(C2Segment(124u, 457u) > C2Segment(123u, 457u)), "");
-        static_assert(!(C2Segment(123u, 457u) > C2Segment(122u, 457u)), "");
-        static_assert(!(C2Segment(123u, 0u) > C2Segment(122u, 0u)), "");
-        static_assert(C2Segment(122u, 1u) > C2Segment(123u, 0u), "");
-        static_assert(C2Segment(122u, 1u) > C2Segment(122u, 0u), "");
-        static_assert(!(C2Segment(122u, 1 + ~122u) > C2Segment(122u, ~122u)), "");
-        static_assert(!(C2Segment(122u, ~122u) > C2Segment(122u, 1 + ~122u)), "");
-        static_assert(!(C2Segment(122u, 1 + ~122u) > C2Segment(122u, 1 + ~122u)), "");
-
-        // end
-        static_assert(C2Segment(123u, 456u).end() == 579u, "");
-        static_assert(C2Segment(123u, 0u).end() == 123u, "");
-        static_assert(C2Segment(123u, ~123u).end() == 0xffffffffu, "");
-        static_assert(C2Segment(123u, 1 + ~123u).end() == 0u, "");
-
-        // intersect
-        static_assert(C2Segment(123u, 456u).intersect(C2Segment(123u, 456u)) == C2Segment(123u, 456u), "");
-        static_assert(C2Segment(123u, 456u).intersect(C2Segment(123u, 460u)) == C2Segment(123u, 456u), "");
-        static_assert(C2Segment(123u, 456u).intersect(C2Segment(124u, 460u)) == C2Segment(124u, 455u), "");
-        static_assert(C2Segment(123u, 456u).intersect(C2Segment(579u, 460u)) == C2Segment(579u, 0u), "");
-        static_assert(C2Segment(123u, 456u).intersect(C2Segment(589u, 460u)) == C2Segment(589u, ~9u /* -10 */), "");
-        static_assert(C2Segment(123u, 456u).intersect(C2Segment(123u, 455u)) == C2Segment(123u, 455u), "");
-        static_assert(C2Segment(123u, 456u).intersect(C2Segment(122u, 456u)) == C2Segment(123u, 455u), "");
-        static_assert(C2Segment(123u, 456u).intersect(C2Segment(0u, 123u)) == C2Segment(123u, 0u), "");
-        static_assert(C2Segment(123u, 456u).intersect(C2Segment(0u, 0u)) == C2Segment(123u, ~122u /* -123 */), "");
-
-        // normalize (change invalid segments to empty segments)
-        static_assert(C2Segment(123u, 456u).normalize() == C2Segment(123u, 456u), "");
-        static_assert(C2Segment(123u, ~123u).normalize() == C2Segment(123u, ~123u), "");
-        static_assert(C2Segment(123u, 1 + ~123u).normalize() == C2Segment(123u, 0u), "");
-
-        // note: normalize cannot be used to make this work
-        static_assert(C2Segment(123u, 456u).intersect(C2Segment(150u, ~150u)).normalize() == C2Segment(150u, 429u), "");
-        static_assert(C2Segment(123u, 456u).intersect(C2Segment(150u, 1 + ~150u)).normalize() != C2Segment(150u, 429u), "");
-        static_assert(C2Segment(123u, 456u).intersect(C2Segment(150u, 1 + ~150u)).normalize() == C2Segment(150u, 0u), "");
-
-        // saturate (change invalid segments to full segments up to max)
-        static_assert(C2Segment(123u, 456u).saturate() == C2Segment(123u, 456u), "");
-        static_assert(C2Segment(123u, ~123u).saturate() == C2Segment(123u, ~123u), "");
-        static_assert(C2Segment(123u, 1 + ~123u).saturate() == C2Segment(123u, ~123u), "");
-
-        // note: saturate can be used to make this work but only partially
-        static_assert(C2Segment(123u, 456u).intersect(C2Segment(150u, 1 + ~150u).saturate()).normalize() == C2Segment(150u, 429u), "");
-        static_assert(C2Segment(123u, 456u).intersect(C2Segment(0u, 100u).saturate()).normalize() == C2Segment(123u, 0u), "");
-        static_assert(C2Segment(123u, 456u).intersect(C2Segment(1000u, 100u).saturate()).normalize() != C2Segment(579u, 0u), "");
-        static_assert(C2Segment(123u, 456u).intersect(C2Segment(1000u, 100u).saturate()).normalize() == C2Segment(1000u, 0u), "");
-
-    }
-
-    static void StaticLinearRangeAndCapacityTest() {
-        class TestCapacity : public _C2LinearCapacityAspect {
-            using _C2LinearCapacityAspect::_C2LinearCapacityAspect;
-            friend class C2BufferUtilsTest;
-        };
-
-        class TestRange : public _C2LinearRangeAspect {
-            using _C2LinearRangeAspect::_C2LinearRangeAspect;
-            friend class C2BufferUtilsTest;
-        };
-
-        // _C2LinearCapacityAspect
-        static_assert(TestCapacity(0u).capacity() == 0u, "");
-        constexpr TestCapacity cap(123u);
-        static_assert(TestCapacity(&cap).capacity() == 123u, "");
-        static_assert(TestCapacity(nullptr).capacity() == 0u, "");
-
-        // _C2LinearCapacityRange
-        static_assert(TestRange(&cap).capacity() == 123u, "");
-        static_assert(TestRange(&cap).offset() == 0u, "");
-        static_assert(TestRange(&cap).size() == 123u, "");
-        static_assert(TestRange(&cap).endOffset() == 123u, "");
-
-        constexpr TestRange range(&cap, 50u, 100u);
-
-        static_assert(range.capacity() == 123u, "");
-        static_assert(range.offset() == 50u, "");
-        static_assert(range.size() == 73u, "");
-        static_assert(range.endOffset() == 123u, "");
-
-        static_assert(TestRange(&cap, 20u, 30u).capacity() == 123u, "");
-        static_assert(TestRange(&cap, 20u, 30u).offset() == 20u, "");
-        static_assert(TestRange(&cap, 20u, 30u).size() == 30u, "");
-        static_assert(TestRange(&cap, 20u, 30u).endOffset() == 50u, "");
-
-        static_assert(TestRange(&cap, 200u, 30u).capacity() == 123u, "");
-        static_assert(TestRange(&cap, 200u, 30u).offset() == 123u, "");
-        static_assert(TestRange(&cap, 200u, 30u).size() == 0u, "");
-        static_assert(TestRange(&cap, 200u, 30u).endOffset() == 123u, "");
-
-    }
-
-};
-
-
-class C2BufferTest : public ::testing::Test {
-public:
-    C2BufferTest()
-        : mBlockPoolId(C2BlockPool::PLATFORM_START),
-          mLinearAllocator(std::make_shared<C2AllocatorIon>('i')),
-          mSize(0u),
-          mAddr(nullptr),
-          mGraphicAllocator(std::make_shared<C2AllocatorGralloc>('g')) {
-    }
-
-    ~C2BufferTest() = default;
-
-    void allocateLinear(size_t capacity) {
-        c2_status_t err = mLinearAllocator->newLinearAllocation(
-                capacity,
-                { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
-                &mLinearAllocation);
-        if (err != C2_OK) {
-            mLinearAllocation.reset();
-            FAIL() << "C2Allocator::newLinearAllocation() failed: " << err;
-        }
-    }
-
-    void mapLinear(size_t offset, size_t size, uint8_t **addr) {
-        ASSERT_TRUE(mLinearAllocation);
-        c2_status_t err = mLinearAllocation->map(
-                offset,
-                size,
-                { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
-                // TODO: fence
-                nullptr,
-                &mAddr);
-        if (err != C2_OK) {
-            mAddr = nullptr;
-            FAIL() << "C2LinearAllocation::map() failed: " << err;
-        }
-        ASSERT_NE(nullptr, mAddr);
-        mSize = size;
-        *addr = (uint8_t *)mAddr;
-    }
-
-    void unmapLinear() {
-        ASSERT_TRUE(mLinearAllocation);
-        ASSERT_NE(nullptr, mAddr);
-        ASSERT_NE(0u, mSize);
-
-        // TODO: fence
-        ASSERT_EQ(C2_OK, mLinearAllocation->unmap(mAddr, mSize, nullptr));
-        mSize = 0u;
-        mAddr = nullptr;
-    }
-
-    std::shared_ptr<C2BlockPool> makeLinearBlockPool() {
-        return std::make_shared<C2PooledBlockPool>(mLinearAllocator, mBlockPoolId++);
-    }
-
-    void allocateGraphic(uint32_t width, uint32_t height) {
-        c2_status_t err = mGraphicAllocator->newGraphicAllocation(
-                width,
-                height,
-                HAL_PIXEL_FORMAT_YCBCR_420_888,
-                { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
-                &mGraphicAllocation);
-        if (err != C2_OK) {
-            mGraphicAllocation.reset();
-            FAIL() << "C2Allocator::newGraphicAllocation() failed: " << err;
-        }
-    }
-
-    void mapGraphic(C2Rect rect, C2PlanarLayout *layout, uint8_t **addr) {
-        ASSERT_TRUE(mGraphicAllocation);
-        c2_status_t err = mGraphicAllocation->map(
-                rect,
-                { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
-                // TODO: fence
-                nullptr,
-                layout,
-                addr);
-        if (err != C2_OK) {
-            addr[C2PlanarLayout::PLANE_Y] = nullptr;
-            addr[C2PlanarLayout::PLANE_U] = nullptr;
-            addr[C2PlanarLayout::PLANE_V] = nullptr;
-            FAIL() << "C2GraphicAllocation::map() failed: " << err;
-        }
-        mMappedRect = rect;
-        memcpy(mAddrGraphic, addr, sizeof(uint8_t*) * C2PlanarLayout::MAX_NUM_PLANES);
-    }
-
-    void unmapGraphic() {
-        ASSERT_TRUE(mGraphicAllocation);
-
-        // TODO: fence
-        ASSERT_EQ(C2_OK, mGraphicAllocation->unmap(mAddrGraphic, mMappedRect, nullptr));
-    }
-
-    std::shared_ptr<C2BlockPool> makeGraphicBlockPool() {
-        return std::make_shared<C2BasicGraphicBlockPool>(mGraphicAllocator);
-    }
-
-private:
-    C2BlockPool::local_id_t mBlockPoolId;
-    std::shared_ptr<C2Allocator> mLinearAllocator;
-    std::shared_ptr<C2LinearAllocation> mLinearAllocation;
-    size_t mSize;
-    void *mAddr;
-    C2Rect mMappedRect;
-    uint8_t* mAddrGraphic[C2PlanarLayout::MAX_NUM_PLANES];
-
-    std::shared_ptr<C2Allocator> mGraphicAllocator;
-    std::shared_ptr<C2GraphicAllocation> mGraphicAllocation;
-};
-
-TEST_F(C2BufferTest, LinearAllocationTest) {
-    constexpr size_t kCapacity = 1024u * 1024u;
-
-    allocateLinear(kCapacity);
-
-    uint8_t *addr = nullptr;
-    mapLinear(0u, kCapacity, &addr);
-    ASSERT_NE(nullptr, addr);
-
-    for (size_t i = 0; i < kCapacity; ++i) {
-        addr[i] = i % 100u;
-    }
-
-    unmapLinear();
-    addr = nullptr;
-
-    mapLinear(kCapacity / 3, kCapacity / 3, &addr);
-    ASSERT_NE(nullptr, addr);
-    for (size_t i = 0; i < kCapacity / 3; ++i) {
-        ASSERT_EQ((i + kCapacity / 3) % 100, addr[i]) << " at i = " << i;
-    }
-}
-
-TEST_F(C2BufferTest, BlockPoolTest) {
-    constexpr size_t kCapacity = 1024u * 1024u;
-
-    std::shared_ptr<C2BlockPool> blockPool(makeLinearBlockPool());
-
-    std::shared_ptr<C2LinearBlock> block;
-    ASSERT_EQ(C2_OK, blockPool->fetchLinearBlock(
-            kCapacity,
-            { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
-            &block));
-    ASSERT_TRUE(block);
-
-    C2Acquirable<C2WriteView> writeViewHolder = block->map();
-    C2WriteView writeView = writeViewHolder.get();
-    ASSERT_EQ(C2_OK, writeView.error());
-    ASSERT_EQ(kCapacity, writeView.capacity());
-    ASSERT_EQ(0u, writeView.offset());
-    ASSERT_EQ(kCapacity, writeView.size());
-
-    uint8_t *data = writeView.data();
-    ASSERT_NE(nullptr, data);
-    for (size_t i = 0; i < writeView.size(); ++i) {
-        data[i] = i % 100u;
-    }
-
-    writeView.setOffset(kCapacity / 3);
-    data = writeView.data();
-    ASSERT_NE(nullptr, data);
-    for (size_t i = 0; i < writeView.size(); ++i) {
-        ASSERT_EQ((i + kCapacity / 3) % 100u, data[i]) << " at i = " << i
-            << "; data = " << static_cast<void *>(data);
-    }
-
-    C2Fence fence;
-    C2ConstLinearBlock constBlock = block->share(
-            kCapacity / 3, kCapacity / 3, fence);
-
-    C2Acquirable<C2ReadView> readViewHolder = constBlock.map();
-    C2ReadView readView = readViewHolder.get();
-    ASSERT_EQ(C2_OK, readView.error());
-    ASSERT_EQ(kCapacity / 3, readView.capacity());
-
-    // TODO: fence
-    const uint8_t *constData = readView.data();
-    ASSERT_NE(nullptr, constData);
-    for (size_t i = 0; i < readView.capacity(); ++i) {
-        ASSERT_EQ((i + kCapacity / 3) % 100u, constData[i]) << " at i = " << i
-                << "; data = " << static_cast<void *>(data)
-                << "; constData = " << static_cast<const void *>(constData);
-    }
-
-    readView = readView.subView(333u, 100u);
-    ASSERT_EQ(C2_OK, readView.error());
-    ASSERT_EQ(100u, readView.capacity());
-
-    constData = readView.data();
-    ASSERT_NE(nullptr, constData);
-    for (size_t i = 0; i < readView.capacity(); ++i) {
-        ASSERT_EQ((i + 333u + kCapacity / 3) % 100u, constData[i]) << " at i = " << i;
-    }
-}
-
-void fillPlane(const C2Rect rect, const C2PlaneInfo info, uint8_t *addr, uint8_t value) {
-    for (uint32_t row = 0; row < rect.height / info.rowSampling; ++row) {
-        int32_t rowOffset = (row + rect.top / info.rowSampling) * info.rowInc;
-        for (uint32_t col = 0; col < rect.width / info.colSampling; ++col) {
-            int32_t colOffset = (col + rect.left / info.colSampling) * info.colInc;
-            addr[rowOffset + colOffset] = value;
-        }
-    }
-}
-
-bool verifyPlane(const C2Rect rect, const C2PlaneInfo info, const uint8_t *addr, uint8_t value) {
-    for (uint32_t row = 0; row < rect.height / info.rowSampling; ++row) {
-        int32_t rowOffset = (row + rect.top / info.rowSampling) * info.rowInc;
-        for (uint32_t col = 0; col < rect.width / info.colSampling; ++col) {
-            int32_t colOffset = (col + rect.left / info.colSampling) * info.colInc;
-            if (addr[rowOffset + colOffset] != value) {
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-TEST_F(C2BufferTest, GraphicAllocationTest) {
-    constexpr uint32_t kWidth = 320;
-    constexpr uint32_t kHeight = 240;
-
-    allocateGraphic(kWidth, kHeight);
-
-    uint8_t *addr[C2PlanarLayout::MAX_NUM_PLANES];
-    C2Rect rect{ 0, 0, kWidth, kHeight };
-    C2PlanarLayout layout;
-    mapGraphic(rect, &layout, addr);
-    ASSERT_NE(nullptr, addr[C2PlanarLayout::PLANE_Y]);
-    ASSERT_NE(nullptr, addr[C2PlanarLayout::PLANE_U]);
-    ASSERT_NE(nullptr, addr[C2PlanarLayout::PLANE_V]);
-
-    uint8_t *y = addr[C2PlanarLayout::PLANE_Y];
-    C2PlaneInfo yInfo = layout.planes[C2PlanarLayout::PLANE_Y];
-    uint8_t *u = addr[C2PlanarLayout::PLANE_U];
-    C2PlaneInfo uInfo = layout.planes[C2PlanarLayout::PLANE_U];
-    uint8_t *v = addr[C2PlanarLayout::PLANE_V];
-    C2PlaneInfo vInfo = layout.planes[C2PlanarLayout::PLANE_V];
-
-    fillPlane(rect, yInfo, y, 0);
-    fillPlane(rect, uInfo, u, 0);
-    fillPlane(rect, vInfo, v, 0);
-    fillPlane({ kWidth / 4, kHeight / 4, kWidth / 2, kHeight / 2 }, yInfo, y, 0x12);
-    fillPlane({ kWidth / 4, kHeight / 4, kWidth / 2, kHeight / 2 }, uInfo, u, 0x34);
-    fillPlane({ kWidth / 4, kHeight / 4, kWidth / 2, kHeight / 2 }, vInfo, v, 0x56);
-
-    unmapGraphic();
-
-    mapGraphic(rect, &layout, addr);
-    ASSERT_NE(nullptr, addr[C2PlanarLayout::PLANE_Y]);
-    ASSERT_NE(nullptr, addr[C2PlanarLayout::PLANE_U]);
-    ASSERT_NE(nullptr, addr[C2PlanarLayout::PLANE_V]);
-
-    y = addr[C2PlanarLayout::PLANE_Y];
-    yInfo = layout.planes[C2PlanarLayout::PLANE_Y];
-    u = addr[C2PlanarLayout::PLANE_U];
-    uInfo = layout.planes[C2PlanarLayout::PLANE_U];
-    v = addr[C2PlanarLayout::PLANE_V];
-    vInfo = layout.planes[C2PlanarLayout::PLANE_V];
-
-    ASSERT_TRUE(verifyPlane({ kWidth / 4, kHeight / 4, kWidth / 2, kHeight / 2 }, yInfo, y, 0x12));
-    ASSERT_TRUE(verifyPlane({ kWidth / 4, kHeight / 4, kWidth / 2, kHeight / 2 }, uInfo, u, 0x34));
-    ASSERT_TRUE(verifyPlane({ kWidth / 4, kHeight / 4, kWidth / 2, kHeight / 2 }, vInfo, v, 0x56));
-    ASSERT_TRUE(verifyPlane({ 0, 0, kWidth, kHeight / 4 }, yInfo, y, 0));
-    ASSERT_TRUE(verifyPlane({ 0, 0, kWidth, kHeight / 4 }, uInfo, u, 0));
-    ASSERT_TRUE(verifyPlane({ 0, 0, kWidth, kHeight / 4 }, vInfo, v, 0));
-    ASSERT_TRUE(verifyPlane({ 0, 0, kWidth / 4, kHeight }, yInfo, y, 0));
-    ASSERT_TRUE(verifyPlane({ 0, 0, kWidth / 4, kHeight }, uInfo, u, 0));
-    ASSERT_TRUE(verifyPlane({ 0, 0, kWidth / 4, kHeight }, vInfo, v, 0));
-}
-
-TEST_F(C2BufferTest, GraphicBlockPoolTest) {
-    constexpr uint32_t kWidth = 320;
-    constexpr uint32_t kHeight = 240;
-
-    std::shared_ptr<C2BlockPool> blockPool(makeGraphicBlockPool());
-
-    std::shared_ptr<C2GraphicBlock> block;
-    ASSERT_EQ(C2_OK, blockPool->fetchGraphicBlock(
-            kWidth,
-            kHeight,
-            HAL_PIXEL_FORMAT_YCBCR_420_888,
-            { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
-            &block));
-    ASSERT_TRUE(block);
-
-    C2Acquirable<C2GraphicView> graphicViewHolder = block->map();
-    C2GraphicView graphicView = graphicViewHolder.get();
-    ASSERT_EQ(C2_OK, graphicView.error());
-    ASSERT_EQ(kWidth, graphicView.width());
-    ASSERT_EQ(kHeight, graphicView.height());
-
-    uint8_t *const *data = graphicView.data();
-    C2PlanarLayout layout = graphicView.layout();
-    ASSERT_NE(nullptr, data);
-
-    uint8_t *y = data[C2PlanarLayout::PLANE_Y];
-    C2PlaneInfo yInfo = layout.planes[C2PlanarLayout::PLANE_Y];
-    uint8_t *u = data[C2PlanarLayout::PLANE_U];
-    C2PlaneInfo uInfo = layout.planes[C2PlanarLayout::PLANE_U];
-    uint8_t *v = data[C2PlanarLayout::PLANE_V];
-    C2PlaneInfo vInfo = layout.planes[C2PlanarLayout::PLANE_V];
-
-    fillPlane({ 0, 0, kWidth, kHeight }, yInfo, y, 0);
-    fillPlane({ 0, 0, kWidth, kHeight }, uInfo, u, 0);
-    fillPlane({ 0, 0, kWidth, kHeight }, vInfo, v, 0);
-    fillPlane({ kWidth / 4, kHeight / 4, kWidth / 2, kHeight / 2 }, yInfo, y, 0x12);
-    fillPlane({ kWidth / 4, kHeight / 4, kWidth / 2, kHeight / 2 }, uInfo, u, 0x34);
-    fillPlane({ kWidth / 4, kHeight / 4, kWidth / 2, kHeight / 2 }, vInfo, v, 0x56);
-
-    C2Fence fence;
-    C2ConstGraphicBlock constBlock = block->share(
-            { 0, 0, kWidth, kHeight }, fence);
-    block.reset();
-
-    C2Acquirable<const C2GraphicView> constViewHolder = constBlock.map();
-    const C2GraphicView constGraphicView = constViewHolder.get();
-    ASSERT_EQ(C2_OK, constGraphicView.error());
-    ASSERT_EQ(kWidth, constGraphicView.width());
-    ASSERT_EQ(kHeight, constGraphicView.height());
-
-    const uint8_t *const *constData = constGraphicView.data();
-    layout = graphicView.layout();
-    ASSERT_NE(nullptr, constData);
-
-    const uint8_t *cy = constData[C2PlanarLayout::PLANE_Y];
-    yInfo = layout.planes[C2PlanarLayout::PLANE_Y];
-    const uint8_t *cu = constData[C2PlanarLayout::PLANE_U];
-    uInfo = layout.planes[C2PlanarLayout::PLANE_U];
-    const uint8_t *cv = constData[C2PlanarLayout::PLANE_V];
-    vInfo = layout.planes[C2PlanarLayout::PLANE_V];
-
-    ASSERT_TRUE(verifyPlane({ kWidth / 4, kHeight / 4, kWidth / 2, kHeight / 2 }, yInfo, cy, 0x12));
-    ASSERT_TRUE(verifyPlane({ kWidth / 4, kHeight / 4, kWidth / 2, kHeight / 2 }, uInfo, cu, 0x34));
-    ASSERT_TRUE(verifyPlane({ kWidth / 4, kHeight / 4, kWidth / 2, kHeight / 2 }, vInfo, cv, 0x56));
-    ASSERT_TRUE(verifyPlane({ 0, 0, kWidth, kHeight / 4 }, yInfo, cy, 0));
-    ASSERT_TRUE(verifyPlane({ 0, 0, kWidth, kHeight / 4 }, uInfo, cu, 0));
-    ASSERT_TRUE(verifyPlane({ 0, 0, kWidth, kHeight / 4 }, vInfo, cv, 0));
-    ASSERT_TRUE(verifyPlane({ 0, 0, kWidth / 4, kHeight }, yInfo, cy, 0));
-    ASSERT_TRUE(verifyPlane({ 0, 0, kWidth / 4, kHeight }, uInfo, cu, 0));
-    ASSERT_TRUE(verifyPlane({ 0, 0, kWidth / 4, kHeight }, vInfo, cv, 0));
-}
-
-class BufferData : public C2BufferData {
-public:
-    explicit BufferData(const std::vector<C2ConstLinearBlock> &blocks) : C2BufferData(blocks) {}
-    explicit BufferData(const std::vector<C2ConstGraphicBlock> &blocks) : C2BufferData(blocks) {}
-};
-
-class Buffer : public C2Buffer {
-public:
-    explicit Buffer(const std::vector<C2ConstLinearBlock> &blocks) : C2Buffer(blocks) {}
-    explicit Buffer(const std::vector<C2ConstGraphicBlock> &blocks) : C2Buffer(blocks) {}
-};
-
-TEST_F(C2BufferTest, BufferDataTest) {
-    std::shared_ptr<C2BlockPool> linearBlockPool(makeLinearBlockPool());
-    std::shared_ptr<C2BlockPool> graphicBlockPool(makeGraphicBlockPool());
-
-    constexpr uint32_t kWidth1 = 320;
-    constexpr uint32_t kHeight1 = 240;
-    constexpr C2Rect kCrop1(kWidth1, kHeight1);
-    constexpr uint32_t kWidth2 = 176;
-    constexpr uint32_t kHeight2 = 144;
-    constexpr C2Rect kCrop2(kWidth2, kHeight2);
-    constexpr size_t kCapacity1 = 1024u;
-    constexpr size_t kCapacity2 = 2048u;
-
-    std::shared_ptr<C2LinearBlock> linearBlock1;
-    std::shared_ptr<C2LinearBlock> linearBlock2;
-    ASSERT_EQ(C2_OK, linearBlockPool->fetchLinearBlock(
-            kCapacity1,
-            { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
-            &linearBlock1));
-    ASSERT_EQ(C2_OK, linearBlockPool->fetchLinearBlock(
-            kCapacity2,
-            { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
-            &linearBlock2));
-    std::shared_ptr<C2GraphicBlock> graphicBlock1;
-    std::shared_ptr<C2GraphicBlock> graphicBlock2;
-    ASSERT_EQ(C2_OK, graphicBlockPool->fetchGraphicBlock(
-            kWidth1,
-            kHeight1,
-            HAL_PIXEL_FORMAT_YCBCR_420_888,
-            { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
-            &graphicBlock1));
-    ASSERT_EQ(C2_OK, graphicBlockPool->fetchGraphicBlock(
-            kWidth2,
-            kHeight2,
-            HAL_PIXEL_FORMAT_YCBCR_420_888,
-            { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
-            &graphicBlock2));
-
-    std::shared_ptr<C2BufferData> data(new BufferData({ linearBlock1->share(0, kCapacity1, C2Fence()) }));
-    EXPECT_EQ(C2BufferData::LINEAR, data->type());
-    ASSERT_EQ(1u, data->linearBlocks().size());
-    EXPECT_EQ(linearBlock1->handle(), data->linearBlocks().front().handle());
-    EXPECT_TRUE(data->graphicBlocks().empty());
-
-    data.reset(new BufferData({
-        linearBlock1->share(0, kCapacity1, C2Fence()),
-        linearBlock2->share(0, kCapacity2, C2Fence()),
-    }));
-    EXPECT_EQ(C2BufferData::LINEAR_CHUNKS, data->type());
-    ASSERT_EQ(2u, data->linearBlocks().size());
-    EXPECT_EQ(linearBlock1->handle(), data->linearBlocks().front().handle());
-    EXPECT_EQ(linearBlock2->handle(), data->linearBlocks().back().handle());
-    EXPECT_TRUE(data->graphicBlocks().empty());
-
-    data.reset(new BufferData({ graphicBlock1->share(kCrop1, C2Fence()) }));
-    EXPECT_EQ(C2BufferData::GRAPHIC, data->type());
-    ASSERT_EQ(1u, data->graphicBlocks().size());
-    EXPECT_EQ(graphicBlock1->handle(), data->graphicBlocks().front().handle());
-    EXPECT_TRUE(data->linearBlocks().empty());
-
-    data.reset(new BufferData({
-        graphicBlock1->share(kCrop1, C2Fence()),
-        graphicBlock2->share(kCrop2, C2Fence()),
-    }));
-    EXPECT_EQ(C2BufferData::GRAPHIC_CHUNKS, data->type());
-    ASSERT_EQ(2u, data->graphicBlocks().size());
-    EXPECT_EQ(graphicBlock1->handle(), data->graphicBlocks().front().handle());
-    EXPECT_EQ(graphicBlock2->handle(), data->graphicBlocks().back().handle());
-    EXPECT_TRUE(data->linearBlocks().empty());
-}
-
-void DestroyCallback(const C2Buffer * /* buf */, void *arg) {
-    std::function<void(void)> *cb = (std::function<void(void)> *)arg;
-    (*cb)();
-}
-
-enum : uint32_t {
-    kParamIndexNumber1,
-    kParamIndexNumber2,
-};
-
-typedef C2GlobalParam<C2Info, C2Int32Value, kParamIndexNumber1> C2Number1Info;
-typedef C2GlobalParam<C2Info, C2Int32Value, kParamIndexNumber2> C2Number2Info;
-
-TEST_F(C2BufferTest, BufferTest) {
-    std::shared_ptr<C2BlockPool> alloc(makeLinearBlockPool());
-    constexpr size_t kCapacity = 1024u;
-    std::shared_ptr<C2LinearBlock> block;
-
-    ASSERT_EQ(C2_OK, alloc->fetchLinearBlock(
-            kCapacity,
-            { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
-            &block));
-
-    std::atomic_bool destroyed(false);
-    std::function<void(void)> arg = [&destroyed](){ destroyed = true; };
-
-    std::shared_ptr<C2Buffer> buffer(new Buffer( { block->share(0, kCapacity, C2Fence()) }));
-    ASSERT_EQ(C2_OK, buffer->registerOnDestroyNotify(&DestroyCallback, &arg));
-    EXPECT_FALSE(destroyed);
-    ASSERT_EQ(C2_DUPLICATE, buffer->registerOnDestroyNotify(&DestroyCallback, &arg));
-    buffer.reset();
-    EXPECT_TRUE(destroyed);
-
-    buffer.reset(new Buffer( { block->share(0, kCapacity, C2Fence()) }));
-    destroyed = false;
-    ASSERT_EQ(C2_OK, buffer->registerOnDestroyNotify(&DestroyCallback, &arg));
-    EXPECT_FALSE(destroyed);
-    ASSERT_EQ(C2_NOT_FOUND, buffer->unregisterOnDestroyNotify(&DestroyCallback, nullptr));
-    ASSERT_EQ(C2_OK, buffer->unregisterOnDestroyNotify(&DestroyCallback, &arg));
-    EXPECT_FALSE(destroyed);
-    ASSERT_EQ(C2_NOT_FOUND, buffer->unregisterOnDestroyNotify(&DestroyCallback, &arg));
-    buffer.reset();
-    EXPECT_FALSE(destroyed);
-
-    std::shared_ptr<C2Info> info1(new C2Number1Info(1));
-    std::shared_ptr<C2Info> info2(new C2Number2Info(2));
-    buffer.reset(new Buffer( { block->share(0, kCapacity, C2Fence()) }));
-    EXPECT_TRUE(buffer->info().empty());
-    EXPECT_FALSE(buffer->hasInfo(info1->type()));
-    EXPECT_FALSE(buffer->hasInfo(info2->type()));
-
-    ASSERT_EQ(C2_OK, buffer->setInfo(info1));
-    EXPECT_EQ(1u, buffer->info().size());
-    EXPECT_EQ(*info1, *buffer->info().front());
-    EXPECT_TRUE(buffer->hasInfo(info1->type()));
-    EXPECT_FALSE(buffer->hasInfo(info2->type()));
-
-    ASSERT_EQ(C2_OK, buffer->setInfo(info2));
-    EXPECT_EQ(2u, buffer->info().size());
-    EXPECT_TRUE(buffer->hasInfo(info1->type()));
-    EXPECT_TRUE(buffer->hasInfo(info2->type()));
-
-    std::shared_ptr<C2Info> removed = buffer->removeInfo(info1->type());
-    ASSERT_TRUE(removed);
-    EXPECT_EQ(*removed, *info1);
-    EXPECT_EQ(1u, buffer->info().size());
-    EXPECT_EQ(*info2, *buffer->info().front());
-    EXPECT_FALSE(buffer->hasInfo(info1->type()));
-    EXPECT_TRUE(buffer->hasInfo(info2->type()));
-
-    removed = buffer->removeInfo(info1->type());
-    ASSERT_FALSE(removed);
-    EXPECT_EQ(1u, buffer->info().size());
-    EXPECT_FALSE(buffer->hasInfo(info1->type()));
-    EXPECT_TRUE(buffer->hasInfo(info2->type()));
-
-    std::shared_ptr<C2Info> info3(new C2Number2Info(3));
-    ASSERT_EQ(C2_OK, buffer->setInfo(info3));
-    EXPECT_EQ(1u, buffer->info().size());
-    EXPECT_FALSE(buffer->hasInfo(info1->type()));
-    EXPECT_TRUE(buffer->hasInfo(info2->type()));
-
-    removed = buffer->removeInfo(info2->type());
-    ASSERT_TRUE(removed);
-    EXPECT_EQ(*info3, *removed);
-    EXPECT_TRUE(buffer->info().empty());
-    EXPECT_FALSE(buffer->hasInfo(info1->type()));
-    EXPECT_FALSE(buffer->hasInfo(info2->type()));
-}
-
-TEST_F(C2BufferTest, MultipleLinearMapTest) {
-    std::shared_ptr<C2BlockPool> pool(makeLinearBlockPool());
-    constexpr size_t kCapacity = 524288u;
-    for (int i = 0; i < 100; ++i) {
-        std::vector<C2WriteView> wViews;
-        std::vector<C2ReadView> rViews;
-        for (int j = 0; j < 16; ++j) {
-            std::shared_ptr<C2LinearBlock> block;
-            ASSERT_EQ(C2_OK, pool->fetchLinearBlock(
-                    kCapacity,
-                    { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE },
-                    &block));
-            wViews.push_back(block->map().get());
-            C2ConstLinearBlock cBlock = block->share(0, kCapacity / 2, C2Fence());
-            rViews.push_back(cBlock.map().get());
-        }
-    }
-}
-
-} // namespace android
diff --git a/media/libstagefright/codec2/tests/vndk/C2UtilTest.cpp b/media/libstagefright/codec2/tests/vndk/C2UtilTest.cpp
deleted file mode 100644
index 7a1374b..0000000
--- a/media/libstagefright/codec2/tests/vndk/C2UtilTest.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <util/_C2MacroUtils.h>
-
-/** \file
- * Tests for vndk/util.
- */
-
-/* --------------------------------------- _C2MacroUtils --------------------------------------- */
-
-static_assert(0 == _C2_ARGC(), "should be 0");
-static_assert(1 == _C2_ARGC(1), "should be 1");
-static_assert(2 == _C2_ARGC(1, 2), "should be 2");
-static_assert(64 == _C2_ARGC(
-        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
-        26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
-        49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64), "should be 64");
-
-static_assert(0 == _C2_ARGC(,), "should be 0");
-static_assert(1 == _C2_ARGC(1,), "should be 1");
-static_assert(2 == _C2_ARGC(1, 2,), "should be 2");
-static_assert(64 == _C2_ARGC(
-        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
-        26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
-        49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,), "should be 64");
-
diff --git a/media/libstagefright/codec2/vndk/Android.bp b/media/libstagefright/codec2/vndk/Android.bp
deleted file mode 100644
index 8966933..0000000
--- a/media/libstagefright/codec2/vndk/Android.bp
+++ /dev/null
@@ -1,68 +0,0 @@
-cc_library_headers {
-    name: "libstagefright_codec2_internal",
-
-    export_include_dirs: [
-        "internal",
-    ],
-
-    vndk: {
-        enabled: true,
-    },
-
-    // TODO: Remove this when this module is moved back to frameworks/av.
-    vendor_available: true,
-}
-
-cc_library_shared {
-    name: "libstagefright_codec2_vndk",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
-
-    srcs: [
-        "C2AllocatorIon.cpp",
-        "C2AllocatorGralloc.cpp",
-        "C2Buffer.cpp",
-        "C2Config.cpp",
-        "C2Store.cpp",
-    ],
-
-    export_include_dirs: [
-        "include",
-    ],
-
-    include_dirs: [
-        "frameworks/av/media/libstagefright/codec2/include",
-        "frameworks/av/media/libstagefright/codec2/vndk/internal",
-        "frameworks/native/include/media/hardware",
-    ],
-
-    shared_libs: [
-        "android.hardware.graphics.allocator@2.0",
-        "android.hardware.graphics.mapper@2.0",
-        "android.hardware.media.bufferpool@1.0",
-        "libbinder",
-        "libcutils",
-        "libdl",
-        "libhardware",
-        "libhidlbase",
-        "libion",
-        "libfmq",
-        "liblog",
-        "libstagefright_foundation",
-        "libstagefright_bufferpool@1.0",
-        "libui",
-        "libutils",
-    ],
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-        "-std=c++14",
-    ],
-}
-
-subdirs = [
-    "bufferpool",
-]
diff --git a/media/libstagefright/codec2/vndk/C2AllocatorGralloc.cpp b/media/libstagefright/codec2/vndk/C2AllocatorGralloc.cpp
deleted file mode 100644
index 96b52a1..0000000
--- a/media/libstagefright/codec2/vndk/C2AllocatorGralloc.cpp
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "C2AllocatorGralloc"
-#include <utils/Log.h>
-
-#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-#include <android/hardware/graphics/mapper/2.0/IMapper.h>
-#include <cutils/native_handle.h>
-#include <hardware/gralloc.h>
-
-#include <C2AllocatorGralloc.h>
-#include <C2Buffer.h>
-#include <C2PlatformSupport.h>
-
-namespace android {
-
-namespace {
-    enum : uint64_t {
-        /**
-         * Usage mask that is passed through from gralloc to Codec 2.0 usage.
-         */
-        PASSTHROUGH_USAGE_MASK =
-            ~(GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_PROTECTED)
-    };
-
-    // verify that passthrough mask is within the platform mask
-    static_assert((~C2MemoryUsage::PLATFORM_MASK & PASSTHROUGH_USAGE_MASK) == 0, "");
-}
-
-C2MemoryUsage C2AndroidMemoryUsage::FromGrallocUsage(uint64_t usage) {
-    // gralloc does not support WRITE_PROTECTED
-    return C2MemoryUsage(
-            ((usage & GRALLOC_USAGE_SW_READ_MASK) ? C2MemoryUsage::CPU_READ : 0) |
-            ((usage & GRALLOC_USAGE_SW_WRITE_MASK) ? C2MemoryUsage::CPU_WRITE : 0) |
-            ((usage & GRALLOC_USAGE_PROTECTED) ? C2MemoryUsage::READ_PROTECTED : 0) |
-            (usage & PASSTHROUGH_USAGE_MASK));
-}
-
-uint64_t C2AndroidMemoryUsage::asGrallocUsage() const {
-    // gralloc does not support WRITE_PROTECTED
-    return (((expected & C2MemoryUsage::CPU_READ) ? GRALLOC_USAGE_SW_READ_MASK : 0) |
-            ((expected & C2MemoryUsage::CPU_WRITE) ? GRALLOC_USAGE_SW_WRITE_MASK : 0) |
-            ((expected & C2MemoryUsage::READ_PROTECTED) ? GRALLOC_USAGE_PROTECTED : 0) |
-            (expected & PASSTHROUGH_USAGE_MASK));
-}
-
-using ::android::hardware::graphics::allocator::V2_0::IAllocator;
-using ::android::hardware::graphics::common::V1_0::BufferUsage;
-using ::android::hardware::graphics::common::V1_0::PixelFormat;
-using ::android::hardware::graphics::mapper::V2_0::BufferDescriptor;
-using ::android::hardware::graphics::mapper::V2_0::Error;
-using ::android::hardware::graphics::mapper::V2_0::IMapper;
-using ::android::hardware::graphics::mapper::V2_0::YCbCrLayout;
-using ::android::hardware::hidl_handle;
-using ::android::hardware::hidl_vec;
-
-namespace {
-
-struct BufferDescriptorInfo {
-    IMapper::BufferDescriptorInfo mapperInfo;
-    uint32_t stride;
-};
-
-}
-
-/* ===================================== GRALLOC ALLOCATION ==================================== */
-static c2_status_t maperr2error(Error maperr) {
-    switch (maperr) {
-        case Error::NONE:           return C2_OK;
-        case Error::BAD_DESCRIPTOR: return C2_BAD_VALUE;
-        case Error::BAD_BUFFER:     return C2_BAD_VALUE;
-        case Error::BAD_VALUE:      return C2_BAD_VALUE;
-        case Error::NO_RESOURCES:   return C2_NO_MEMORY;
-        case Error::UNSUPPORTED:    return C2_CANNOT_DO;
-    }
-    return C2_CORRUPTED;
-}
-
-static
-bool native_handle_is_invalid(const native_handle_t *const handle) {
-    // perform basic validation of a native handle
-    if (handle == nullptr) {
-        // null handle is considered valid
-        return false;
-    }
-    return ((size_t)handle->version != sizeof(native_handle_t) ||
-            handle->numFds < 0 ||
-            handle->numInts < 0 ||
-            // for sanity assume handles must occupy less memory than INT_MAX bytes
-            handle->numFds > int((INT_MAX - handle->version) / sizeof(int)) - handle->numInts);
-}
-
-class C2HandleGralloc : public C2Handle {
-private:
-    struct ExtraData {
-        uint32_t width;
-        uint32_t height;
-        uint32_t format;
-        uint32_t usage_lo;
-        uint32_t usage_hi;
-        uint32_t stride;
-        uint32_t magic;
-    };
-
-    enum {
-        NUM_INTS = sizeof(ExtraData) / sizeof(int),
-    };
-    const static uint32_t MAGIC = '\xc2gr\x00';
-
-    static
-    const ExtraData* getExtraData(const C2Handle *const handle) {
-        if (handle == nullptr
-                || native_handle_is_invalid(handle)
-                || handle->numInts < NUM_INTS) {
-            return nullptr;
-        }
-        return reinterpret_cast<const ExtraData*>(
-                &handle->data[handle->numFds + handle->numInts - NUM_INTS]);
-    }
-
-    static
-    ExtraData *getExtraData(C2Handle *const handle) {
-        return const_cast<ExtraData *>(getExtraData(const_cast<const C2Handle *const>(handle)));
-    }
-
-public:
-    static bool isValid(const C2Handle *const o) {
-        if (o == nullptr) { // null handle is always valid
-            return true;
-        }
-        const ExtraData *xd = getExtraData(o);
-        // we cannot validate width/height/format/usage without accessing gralloc driver
-        return xd != nullptr && xd->magic == MAGIC;
-    }
-
-    static C2HandleGralloc* WrapNativeHandle(
-            const native_handle_t *const handle,
-            uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride) {
-        //CHECK(handle != nullptr);
-        if (native_handle_is_invalid(handle) ||
-            handle->numInts > int((INT_MAX - handle->version) / sizeof(int)) - NUM_INTS - handle->numFds) {
-            return nullptr;
-        }
-        ExtraData xd = {
-            width, height, format, uint32_t(usage & 0xFFFFFFFF), uint32_t(usage >> 32),
-            stride, MAGIC
-        };
-        native_handle_t *res = native_handle_create(handle->numFds, handle->numInts + NUM_INTS);
-        if (res != nullptr) {
-            memcpy(&res->data, &handle->data, sizeof(int) * (handle->numFds + handle->numInts));
-            *getExtraData(res) = xd;
-        }
-        return reinterpret_cast<C2HandleGralloc *>(res);
-    }
-
-    static native_handle_t* UnwrapNativeHandle(const C2Handle *const handle) {
-        const ExtraData *xd = getExtraData(handle);
-        if (xd == nullptr || xd->magic != MAGIC) {
-            return nullptr;
-        }
-        native_handle_t *res = native_handle_create(handle->numFds, handle->numInts - NUM_INTS);
-        if (res != nullptr) {
-            memcpy(&res->data, &handle->data, sizeof(int) * (res->numFds + res->numInts));
-        }
-        return res;
-    }
-
-    static const C2HandleGralloc* Import(
-            const C2Handle *const handle,
-            uint32_t *width, uint32_t *height, uint32_t *format,
-            uint64_t *usage, uint32_t *stride) {
-        const ExtraData *xd = getExtraData(handle);
-        if (xd == nullptr) {
-            return nullptr;
-        }
-        *width = xd->width;
-        *height = xd->height;
-        *format = xd->format;
-        *usage = xd->usage_lo | (uint64_t(xd->usage_hi) << 32);
-        *stride = xd->stride;
-
-        return reinterpret_cast<const C2HandleGralloc *>(handle);
-    }
-};
-
-native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) {
-    return C2HandleGralloc::UnwrapNativeHandle(handle);
-}
-
-C2Handle *WrapNativeCodec2GrallocHandle(
-        const native_handle_t *const handle,
-        uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride) {
-    return C2HandleGralloc::WrapNativeHandle(handle, width, height, format, usage, stride);
-}
-
-class C2AllocationGralloc : public C2GraphicAllocation {
-public:
-    virtual ~C2AllocationGralloc() override;
-
-    virtual c2_status_t map(
-            C2Rect rect, C2MemoryUsage usage, C2Fence *fence,
-            C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override;
-    virtual c2_status_t unmap(
-            uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) override;
-    virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; }
-    virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; }
-    virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override;
-
-    // internal methods
-    // |handle| will be moved.
-    C2AllocationGralloc(
-              const BufferDescriptorInfo &info,
-              const sp<IMapper> &mapper,
-              hidl_handle &hidlHandle,
-              const C2HandleGralloc *const handle,
-              C2Allocator::id_t allocatorId);
-    int dup() const;
-    c2_status_t status() const;
-
-private:
-    const BufferDescriptorInfo mInfo;
-    const sp<IMapper> mMapper;
-    const hidl_handle mHidlHandle;
-    const C2HandleGralloc *mHandle;
-    buffer_handle_t mBuffer;
-    const C2HandleGralloc *mLockedHandle;
-    bool mLocked;
-    C2Allocator::id_t mAllocatorId;
-};
-
-C2AllocationGralloc::C2AllocationGralloc(
-          const BufferDescriptorInfo &info,
-          const sp<IMapper> &mapper,
-          hidl_handle &hidlHandle,
-          const C2HandleGralloc *const handle,
-          C2Allocator::id_t allocatorId)
-    : C2GraphicAllocation(info.mapperInfo.width, info.mapperInfo.height),
-      mInfo(info),
-      mMapper(mapper),
-      mHidlHandle(std::move(hidlHandle)),
-      mHandle(handle),
-      mBuffer(nullptr),
-      mLockedHandle(nullptr),
-      mLocked(false),
-      mAllocatorId(allocatorId) {
-}
-
-C2AllocationGralloc::~C2AllocationGralloc() {
-    if (!mBuffer) {
-        return;
-    }
-    if (mLocked) {
-        // implementation ignores addresss and rect
-        uint8_t* addr[C2PlanarLayout::MAX_NUM_PLANES] = {};
-        unmap(addr, C2Rect(), nullptr);
-    }
-    mMapper->freeBuffer(const_cast<native_handle_t *>(mBuffer));
-    native_handle_delete(const_cast<native_handle_t*>(
-            reinterpret_cast<const native_handle_t*>(mHandle)));
-}
-
-c2_status_t C2AllocationGralloc::map(
-        C2Rect rect, C2MemoryUsage usage, C2Fence *fence,
-        C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
-    // TODO
-    (void) fence;
-    (void) usage;
-
-    if (mBuffer && mLocked) {
-        return C2_DUPLICATE;
-    }
-    if (!layout || !addr) {
-        return C2_BAD_VALUE;
-    }
-
-    c2_status_t err = C2_OK;
-    if (!mBuffer) {
-        mMapper->importBuffer(
-                mHidlHandle, [&err, this](const auto &maperr, const auto &buffer) {
-                    err = maperr2error(maperr);
-                    if (err == C2_OK) {
-                        mBuffer = static_cast<buffer_handle_t>(buffer);
-                    }
-                });
-        if (err != C2_OK) {
-            return err;
-        }
-        if (mBuffer == nullptr) {
-            return C2_CORRUPTED;
-        }
-        mLockedHandle = C2HandleGralloc::WrapNativeHandle(
-                mBuffer, mInfo.mapperInfo.width, mInfo.mapperInfo.height,
-                (uint32_t)mInfo.mapperInfo.format, mInfo.mapperInfo.usage, mInfo.stride);
-    }
-
-    switch (mInfo.mapperInfo.format) {
-        case PixelFormat::YCBCR_420_888:
-        case PixelFormat::YV12: {
-            YCbCrLayout ycbcrLayout;
-            mMapper->lockYCbCr(
-                    const_cast<native_handle_t *>(mBuffer),
-                    BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN,
-                    { (int32_t)rect.left, (int32_t)rect.top, (int32_t)rect.width, (int32_t)rect.height },
-                    // TODO: fence
-                    hidl_handle(),
-                    [&err, &ycbcrLayout](const auto &maperr, const auto &mapLayout) {
-                        err = maperr2error(maperr);
-                        if (err == C2_OK) {
-                            ycbcrLayout = mapLayout;
-                        }
-                    });
-            if (err != C2_OK) {
-                return err;
-            }
-            addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
-            addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
-            addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
-            layout->type = C2PlanarLayout::TYPE_YUV;
-            layout->numPlanes = 3;
-            layout->rootPlanes = 3;
-            layout->planes[C2PlanarLayout::PLANE_Y] = {
-                C2PlaneInfo::CHANNEL_Y,         // channel
-                1,                              // colInc
-                (int32_t)ycbcrLayout.yStride,   // rowInc
-                1,                              // mColSampling
-                1,                              // mRowSampling
-                8,                              // allocatedDepth
-                8,                              // bitDepth
-                0,                              // rightShift
-                C2PlaneInfo::NATIVE,            // endianness
-                C2PlanarLayout::PLANE_Y,        // rootIx
-                0,                              // offset
-            };
-            layout->planes[C2PlanarLayout::PLANE_U] = {
-                C2PlaneInfo::CHANNEL_CB,          // channel
-                (int32_t)ycbcrLayout.chromaStep,  // colInc
-                (int32_t)ycbcrLayout.cStride,     // rowInc
-                2,                                // mColSampling
-                2,                                // mRowSampling
-                8,                                // allocatedDepth
-                8,                                // bitDepth
-                0,                                // rightShift
-                C2PlaneInfo::NATIVE,              // endianness
-                C2PlanarLayout::PLANE_U,          // rootIx
-                0,                                // offset
-            };
-            layout->planes[C2PlanarLayout::PLANE_V] = {
-                C2PlaneInfo::CHANNEL_CR,          // channel
-                (int32_t)ycbcrLayout.chromaStep,  // colInc
-                (int32_t)ycbcrLayout.cStride,     // rowInc
-                2,                                // mColSampling
-                2,                                // mRowSampling
-                8,                                // allocatedDepth
-                8,                                // bitDepth
-                0,                                // rightShift
-                C2PlaneInfo::NATIVE,              // endianness
-                C2PlanarLayout::PLANE_V,          // rootIx
-                0,                                // offset
-            };
-            // handle interleaved formats
-            intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U];
-            if (uvOffset > 0 && uvOffset < (intptr_t)ycbcrLayout.chromaStep) {
-                layout->rootPlanes = 2;
-                layout->planes[C2PlanarLayout::PLANE_V].rootIx = C2PlanarLayout::PLANE_U;
-                layout->planes[C2PlanarLayout::PLANE_V].offset = uvOffset;
-            } else if (uvOffset < 0 && uvOffset > -(intptr_t)ycbcrLayout.chromaStep) {
-                layout->rootPlanes = 2;
-                layout->planes[C2PlanarLayout::PLANE_U].rootIx = C2PlanarLayout::PLANE_V;
-                layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset;
-            }
-            break;
-        }
-
-        case PixelFormat::RGBA_8888:
-            // TODO: alpha channel
-            // fall-through
-        case PixelFormat::RGBX_8888: {
-            void *pointer = nullptr;
-            mMapper->lock(
-                    const_cast<native_handle_t *>(mBuffer),
-                    BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN,
-                    { (int32_t)rect.left, (int32_t)rect.top, (int32_t)rect.width, (int32_t)rect.height },
-                    // TODO: fence
-                    hidl_handle(),
-                    [&err, &pointer](const auto &maperr, const auto &mapPointer) {
-                        err = maperr2error(maperr);
-                        if (err == C2_OK) {
-                            pointer = mapPointer;
-                        }
-                    });
-            if (err != C2_OK) {
-                return err;
-            }
-            addr[C2PlanarLayout::PLANE_R] = (uint8_t *)pointer;
-            addr[C2PlanarLayout::PLANE_G] = (uint8_t *)pointer + 1;
-            addr[C2PlanarLayout::PLANE_B] = (uint8_t *)pointer + 2;
-            layout->type = C2PlanarLayout::TYPE_RGB;
-            layout->numPlanes = 3;
-            layout->rootPlanes = 1;
-            layout->planes[C2PlanarLayout::PLANE_R] = {
-                C2PlaneInfo::CHANNEL_R,         // channel
-                4,                              // colInc
-                4 * (int32_t)mInfo.stride,      // rowInc
-                1,                              // mColSampling
-                1,                              // mRowSampling
-                8,                              // allocatedDepth
-                8,                              // bitDepth
-                0,                              // rightShift
-                C2PlaneInfo::NATIVE,            // endianness
-                C2PlanarLayout::PLANE_R,        // rootIx
-                0,                              // offset
-            };
-            layout->planes[C2PlanarLayout::PLANE_G] = {
-                C2PlaneInfo::CHANNEL_G,         // channel
-                4,                              // colInc
-                4 * (int32_t)mInfo.stride,      // rowInc
-                1,                              // mColSampling
-                1,                              // mRowSampling
-                8,                              // allocatedDepth
-                8,                              // bitDepth
-                0,                              // rightShift
-                C2PlaneInfo::NATIVE,            // endianness
-                C2PlanarLayout::PLANE_R,        // rootIx
-                1,                              // offset
-            };
-            layout->planes[C2PlanarLayout::PLANE_B] = {
-                C2PlaneInfo::CHANNEL_B,         // channel
-                4,                              // colInc
-                4 * (int32_t)mInfo.stride,      // rowInc
-                1,                              // mColSampling
-                1,                              // mRowSampling
-                8,                              // allocatedDepth
-                8,                              // bitDepth
-                0,                              // rightShift
-                C2PlaneInfo::NATIVE,            // endianness
-                C2PlanarLayout::PLANE_R,        // rootIx
-                2,                              // offset
-            };
-            break;
-        }
-        default: {
-            return C2_OMITTED;
-        }
-    }
-    mLocked = true;
-
-    return C2_OK;
-}
-
-c2_status_t C2AllocationGralloc::unmap(
-        uint8_t **addr, C2Rect rect, C2Fence *fence /* nullable */) {
-    // TODO: check addr and size, use fence
-    (void)addr;
-    (void)rect;
-    c2_status_t err = C2_OK;
-    mMapper->unlock(
-            const_cast<native_handle_t *>(mBuffer),
-            [&err, &fence](const auto &maperr, const auto &releaseFence) {
-                // TODO
-                (void) fence;
-                (void) releaseFence;
-                err = maperr2error(maperr);
-                if (err == C2_OK) {
-                    // TODO: fence
-                }
-            });
-    if (err == C2_OK) {
-        mLocked = false;
-    }
-    return err;
-}
-
-bool C2AllocationGralloc::equals(const std::shared_ptr<const C2GraphicAllocation> &other) const {
-    return other && other->handle() == handle();
-}
-
-/* ===================================== GRALLOC ALLOCATOR ==================================== */
-class C2AllocatorGralloc::Impl {
-public:
-    Impl(id_t id);
-
-    id_t getId() const {
-        return mTraits->id;
-    }
-
-    C2String getName() const {
-        return mTraits->name;
-    }
-
-    std::shared_ptr<const C2Allocator::Traits> getTraits() const {
-        return mTraits;
-    }
-
-    c2_status_t newGraphicAllocation(
-            uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
-            std::shared_ptr<C2GraphicAllocation> *allocation);
-
-    c2_status_t priorGraphicAllocation(
-            const C2Handle *handle,
-            std::shared_ptr<C2GraphicAllocation> *allocation);
-
-    c2_status_t status() const { return mInit; }
-
-private:
-    std::shared_ptr<C2Allocator::Traits> mTraits;
-    c2_status_t mInit;
-    sp<IAllocator> mAllocator;
-    sp<IMapper> mMapper;
-};
-
-C2AllocatorGralloc::Impl::Impl(id_t id) : mInit(C2_OK) {
-    // TODO: get this from allocator
-    C2MemoryUsage minUsage = { 0, 0 }, maxUsage = { ~(uint64_t)0, ~(uint64_t)0 };
-    Traits traits = { "android.allocator.gralloc", id, C2Allocator::GRAPHIC, minUsage, maxUsage };
-    mTraits = std::make_shared<C2Allocator::Traits>(traits);
-
-    // gralloc allocator is a singleton, so all objects share a global service
-    mAllocator = IAllocator::getService();
-    mMapper = IMapper::getService();
-    if (mAllocator == nullptr || mMapper == nullptr) {
-        mInit = C2_CORRUPTED;
-    }
-}
-
-c2_status_t C2AllocatorGralloc::Impl::newGraphicAllocation(
-        uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
-        std::shared_ptr<C2GraphicAllocation> *allocation) {
-    // TODO: buffer usage should be determined according to |usage|
-    (void) usage;
-
-    BufferDescriptorInfo info = {
-        {
-            width,
-            height,
-            1u,  // layerCount
-            (PixelFormat)format,
-            BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN,
-        },
-        0u,  // stride placeholder
-    };
-    c2_status_t err = C2_OK;
-    BufferDescriptor desc;
-    mMapper->createDescriptor(
-            info.mapperInfo, [&err, &desc](const auto &maperr, const auto &descriptor) {
-                err = maperr2error(maperr);
-                if (err == C2_OK) {
-                    desc = descriptor;
-                }
-            });
-    if (err != C2_OK) {
-        return err;
-    }
-
-    // IAllocator shares IMapper error codes.
-    hidl_handle buffer;
-    mAllocator->allocate(
-            desc,
-            1u,
-            [&err, &buffer, &info](const auto &maperr, const auto &stride, auto &buffers) {
-                err = maperr2error(maperr);
-                if (err != C2_OK) {
-                    return;
-                }
-                if (buffers.size() != 1u) {
-                    err = C2_CORRUPTED;
-                    return;
-                }
-                info.stride = stride;
-                buffer = std::move(buffers[0]);
-            });
-    if (err != C2_OK) {
-        return err;
-    }
-
-
-    allocation->reset(new C2AllocationGralloc(
-            info, mMapper, buffer,
-            C2HandleGralloc::WrapNativeHandle(
-                    buffer.getNativeHandle(),
-                    info.mapperInfo.width, info.mapperInfo.height,
-                    (uint32_t)info.mapperInfo.format, info.mapperInfo.usage, info.stride),
-            mTraits->id));
-    return C2_OK;
-}
-
-c2_status_t C2AllocatorGralloc::Impl::priorGraphicAllocation(
-        const C2Handle *handle,
-        std::shared_ptr<C2GraphicAllocation> *allocation) {
-    BufferDescriptorInfo info;
-    info.mapperInfo.layerCount = 1u;
-    const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
-            handle,
-            &info.mapperInfo.width, &info.mapperInfo.height,
-            (uint32_t *)&info.mapperInfo.format, (uint64_t *)&info.mapperInfo.usage, &info.stride);
-    if (grallocHandle == nullptr) {
-        return C2_BAD_VALUE;
-    }
-
-    hidl_handle hidlHandle;
-    hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
-    allocation->reset(new C2AllocationGralloc(info, mMapper, hidlHandle, grallocHandle, mTraits->id));
-    return C2_OK;
-}
-
-C2AllocatorGralloc::C2AllocatorGralloc(id_t id) : mImpl(new Impl(id)) {}
-
-C2AllocatorGralloc::~C2AllocatorGralloc() { delete mImpl; }
-
-C2Allocator::id_t C2AllocatorGralloc::getId() const {
-    return mImpl->getId();
-}
-
-C2String C2AllocatorGralloc::getName() const {
-    return mImpl->getName();
-}
-
-std::shared_ptr<const C2Allocator::Traits> C2AllocatorGralloc::getTraits() const {
-    return mImpl->getTraits();
-}
-
-c2_status_t C2AllocatorGralloc::newGraphicAllocation(
-        uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
-        std::shared_ptr<C2GraphicAllocation> *allocation) {
-    return mImpl->newGraphicAllocation(width, height, format, usage, allocation);
-}
-
-c2_status_t C2AllocatorGralloc::priorGraphicAllocation(
-        const C2Handle *handle,
-        std::shared_ptr<C2GraphicAllocation> *allocation) {
-    return mImpl->priorGraphicAllocation(handle, allocation);
-}
-
-c2_status_t C2AllocatorGralloc::status() const {
-    return mImpl->status();
-}
-
-bool C2AllocatorGralloc::isValid(const C2Handle* const o) {
-    return C2HandleGralloc::isValid(o);
-}
-
-} // namespace android
diff --git a/media/libstagefright/codec2/vndk/C2AllocatorIon.cpp b/media/libstagefright/codec2/vndk/C2AllocatorIon.cpp
deleted file mode 100644
index c5fb8d9..0000000
--- a/media/libstagefright/codec2/vndk/C2AllocatorIon.cpp
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "C2AllocatorIon"
-#include <utils/Log.h>
-
-#include <list>
-
-#include <ion/ion.h>
-#include <sys/mman.h>
-#include <unistd.h>
-
-#include <C2AllocatorIon.h>
-#include <C2Buffer.h>
-#include <C2ErrnoUtils.h>
-
-namespace android {
-
-/* size_t <=> int(lo), int(hi) conversions */
-constexpr inline int size2intLo(size_t s) {
-    return int(s & 0xFFFFFFFF);
-}
-
-constexpr inline int size2intHi(size_t s) {
-    // cast to uint64_t as size_t may be 32 bits wide
-    return int((uint64_t(s) >> 32) & 0xFFFFFFFF);
-}
-
-constexpr inline size_t ints2size(int intLo, int intHi) {
-    // convert in 2 stages to 64 bits as intHi may be negative
-    return size_t(unsigned(intLo)) | size_t(uint64_t(unsigned(intHi)) << 32);
-}
-
-/* ========================================= ION HANDLE ======================================== */
-/**
- * ION handle
- *
- * There can be only a sole ion client per process, this is captured in the ion fd that is passed
- * to the constructor, but this should be managed by the ion buffer allocator/mapper.
- *
- * ion uses ion_user_handle_t for buffers. We don't store this in the native handle as
- * it requires an ion_free to decref. Instead, we share the buffer to get an fd that also holds
- * a refcount.
- *
- * This handle will not capture mapped fd-s as updating that would require a global mutex.
- */
-
-struct C2HandleIon : public C2Handle {
-    // ion handle owns ionFd(!) and bufferFd
-    C2HandleIon(int bufferFd, size_t size)
-        : C2Handle(cHeader),
-          mFds{ bufferFd },
-          mInts{ int(size & 0xFFFFFFFF), int((uint64_t(size) >> 32) & 0xFFFFFFFF), kMagic } { }
-
-    static bool isValid(const C2Handle * const o);
-
-    int bufferFd() const { return mFds.mBuffer; }
-    size_t size() const {
-        return size_t(unsigned(mInts.mSizeLo))
-                | size_t(uint64_t(unsigned(mInts.mSizeHi)) << 32);
-    }
-
-protected:
-    struct {
-        int mBuffer; // shared ion buffer
-    } mFds;
-    struct {
-        int mSizeLo; // low 32-bits of size
-        int mSizeHi; // high 32-bits of size
-        int mMagic;
-    } mInts;
-
-private:
-    typedef C2HandleIon _type;
-    enum {
-        kMagic = '\xc2io\x00',
-        numFds = sizeof(mFds) / sizeof(int),
-        numInts = sizeof(mInts) / sizeof(int),
-        version = sizeof(C2Handle)
-    };
-    //constexpr static C2Handle cHeader = { version, numFds, numInts, {} };
-    const static C2Handle cHeader;
-};
-
-const C2Handle C2HandleIon::cHeader = {
-    C2HandleIon::version,
-    C2HandleIon::numFds,
-    C2HandleIon::numInts,
-    {}
-};
-
-// static
-bool C2HandleIon::isValid(const C2Handle * const o) {
-    if (!o || memcmp(o, &cHeader, sizeof(cHeader))) {
-        return false;
-    }
-    const C2HandleIon *other = static_cast<const C2HandleIon*>(o);
-    return other->mInts.mMagic == kMagic;
-}
-
-// TODO: is the dup of an ion fd identical to ion_share?
-
-/* ======================================= ION ALLOCATION ====================================== */
-class C2AllocationIon : public C2LinearAllocation {
-public:
-    /* Interface methods */
-    virtual c2_status_t map(
-        size_t offset, size_t size, C2MemoryUsage usage, C2Fence *fence,
-        void **addr /* nonnull */) override;
-    virtual c2_status_t unmap(void *addr, size_t size, C2Fence *fenceFd) override;
-    virtual ~C2AllocationIon() override;
-    virtual const C2Handle *handle() const override;
-    virtual id_t getAllocatorId() const override;
-    virtual bool equals(const std::shared_ptr<C2LinearAllocation> &other) const override;
-
-    // internal methods
-    C2AllocationIon(int ionFd, size_t size, size_t align, unsigned heapMask, unsigned flags, C2Allocator::id_t id);
-    C2AllocationIon(int ionFd, size_t size, int shareFd, C2Allocator::id_t id);
-
-    c2_status_t status() const;
-
-protected:
-    class Impl;
-    Impl *mImpl;
-
-    // TODO: we could make this encapsulate shared_ptr and copiable
-    C2_DO_NOT_COPY(C2AllocationIon);
-};
-
-class C2AllocationIon::Impl {
-private:
-    /**
-     * Constructs an ion allocation.
-     *
-     * \note We always create an ion allocation, even if the allocation or import fails
-     * so that we can capture the error.
-     *
-     * \param ionFd     ion client (ownership transferred to created object)
-     * \param capacity  size of allocation
-     * \param bufferFd  buffer handle (ownership transferred to created object). Must be
-     *                  invalid if err is not 0.
-     * \param buffer    ion buffer user handle (ownership transferred to created object). Must be
-     *                  invalid if err is not 0.
-     * \param err       errno during buffer allocation or import
-     */
-    Impl(int ionFd, size_t capacity, int bufferFd, ion_user_handle_t buffer, C2Allocator::id_t id, int err)
-        : mIonFd(ionFd),
-          mHandle(bufferFd, capacity),
-          mBuffer(buffer),
-          mId(id),
-          mInit(c2_map_errno<ENOMEM, EACCES, EINVAL>(err)),
-          mMapFd(-1) {
-        if (mInit != C2_OK) {
-            // close ionFd now on error
-            if (mIonFd >= 0) {
-                close(mIonFd);
-                mIonFd = -1;
-            }
-            // C2_CHECK(bufferFd < 0);
-            // C2_CHECK(buffer < 0);
-        }
-    }
-
-public:
-    /**
-     * Constructs an ion allocation by importing a shared buffer fd.
-     *
-     * \param ionFd     ion client (ownership transferred to created object)
-     * \param capacity  size of allocation
-     * \param bufferFd  buffer handle (ownership transferred to created object)
-     *
-     * \return created ion allocation (implementation) which may be invalid if the
-     * import failed.
-     */
-    static Impl *Import(int ionFd, size_t capacity, int bufferFd, C2Allocator::id_t id) {
-        ion_user_handle_t buffer = -1;
-        int ret = ion_import(ionFd, bufferFd, &buffer);
-        return new Impl(ionFd, capacity, bufferFd, buffer, id, ret);
-    }
-
-    /**
-     * Constructs an ion allocation by allocating an ion buffer.
-     *
-     * \param ionFd     ion client (ownership transferred to created object)
-     * \param size      size of allocation
-     * \param align     desired alignment of allocation
-     * \param heapMask  mask of heaps considered
-     * \param flags     ion allocation flags
-     *
-     * \return created ion allocation (implementation) which may be invalid if the
-     * allocation failed.
-     */
-    static Impl *Alloc(int ionFd, size_t size, size_t align, unsigned heapMask, unsigned flags, C2Allocator::id_t id) {
-        int bufferFd = -1;
-        ion_user_handle_t buffer = -1;
-        int ret = ion_alloc(ionFd, size, align, heapMask, flags, &buffer);
-        if (ret == 0) {
-            // get buffer fd for native handle constructor
-            ret = ion_share(ionFd, buffer, &bufferFd);
-            if (ret != 0) {
-                ion_free(ionFd, buffer);
-                buffer = -1;
-            }
-        }
-        return new Impl(ionFd, size, bufferFd, buffer, id, ret);
-    }
-
-    c2_status_t map(size_t offset, size_t size, C2MemoryUsage usage, C2Fence *fence, void **addr) {
-        (void)fence; // TODO: wait for fence
-        *addr = nullptr;
-        if (!mMappings.empty()) {
-            ALOGV("multiple map");
-            // TODO: technically we should return DUPLICATE here, but our block views don't
-            // actually unmap, so we end up remapping an ion buffer multiple times.
-            //
-            // return C2_DUPLICATE;
-        }
-        if (size == 0) {
-            return C2_BAD_VALUE;
-        }
-
-        int prot = PROT_NONE;
-        int flags = MAP_PRIVATE;
-        if (usage.expected & C2MemoryUsage::CPU_READ) {
-            prot |= PROT_READ;
-        }
-        if (usage.expected & C2MemoryUsage::CPU_WRITE) {
-            prot |= PROT_WRITE;
-            flags = MAP_SHARED;
-        }
-
-        size_t alignmentBytes = offset % PAGE_SIZE;
-        size_t mapOffset = offset - alignmentBytes;
-        size_t mapSize = size + alignmentBytes;
-        Mapping map = { nullptr, alignmentBytes, mapSize };
-
-        c2_status_t err = C2_OK;
-        if (mMapFd == -1) {
-            int ret = ion_map(mIonFd, mBuffer, mapSize, prot,
-                              flags, mapOffset, (unsigned char**)&map.addr, &mMapFd);
-            if (ret) {
-                mMapFd = -1;
-                map.addr = *addr = nullptr;
-                err = c2_map_errno<EINVAL>(-ret);
-            } else {
-                *addr = (uint8_t *)map.addr + alignmentBytes;
-            }
-        } else {
-            map.addr = mmap(nullptr, mapSize, prot, flags, mMapFd, mapOffset);
-            if (map.addr == MAP_FAILED) {
-                map.addr = *addr = nullptr;
-                err = c2_map_errno<EINVAL>(errno);
-            } else {
-                *addr = (uint8_t *)map.addr + alignmentBytes;
-            }
-        }
-        if (map.addr) {
-            mMappings.push_back(map);
-        }
-        return err;
-    }
-
-    c2_status_t unmap(void *addr, size_t size, C2Fence *fence) {
-        if (mMapFd < 0 || mMappings.empty()) {
-            return C2_NOT_FOUND;
-        }
-        for (auto it = mMappings.begin(); it != mMappings.end(); ++it) {
-            if (addr != (uint8_t *)it->addr + it->alignmentBytes ||
-                    size + it->alignmentBytes != it->size) {
-                continue;
-            }
-            int err = munmap(it->addr, it->size);
-            if (err != 0) {
-                return c2_map_errno<EINVAL>(errno);
-            }
-            if (fence) {
-                *fence = C2Fence(); // not using fences
-            }
-            (void)mMappings.erase(it);
-            return C2_OK;
-        }
-        return C2_BAD_VALUE;
-    }
-
-    ~Impl() {
-        if (!mMappings.empty()) {
-            ALOGD("Dangling mappings!");
-            for (const Mapping &map : mMappings) {
-                (void)munmap(map.addr, map.size);
-            }
-        }
-        if (mMapFd >= 0) {
-            close(mMapFd);
-            mMapFd = -1;
-        }
-        if (mInit == C2_OK) {
-            (void)ion_free(mIonFd, mBuffer);
-            native_handle_close(&mHandle);
-        }
-        if (mIonFd >= 0) {
-            close(mIonFd);
-        }
-    }
-
-    c2_status_t status() const {
-        return mInit;
-    }
-
-    const C2Handle *handle() const {
-        return &mHandle;
-    }
-
-    C2Allocator::id_t getAllocatorId() const {
-        return mId;
-    }
-
-    ion_user_handle_t ionHandle() const {
-        return mBuffer;
-    }
-
-private:
-    int mIonFd;
-    C2HandleIon mHandle;
-    ion_user_handle_t mBuffer;
-    C2Allocator::id_t mId;
-    c2_status_t mInit;
-    int mMapFd; // only one for now
-    struct Mapping {
-        void *addr;
-        size_t alignmentBytes;
-        size_t size;
-    };
-    std::list<Mapping> mMappings;
-};
-
-c2_status_t C2AllocationIon::map(
-    size_t offset, size_t size, C2MemoryUsage usage, C2Fence *fence, void **addr) {
-    return mImpl->map(offset, size, usage, fence, addr);
-}
-
-c2_status_t C2AllocationIon::unmap(void *addr, size_t size, C2Fence *fence) {
-    return mImpl->unmap(addr, size, fence);
-}
-
-c2_status_t C2AllocationIon::status() const {
-    return mImpl->status();
-}
-
-C2Allocator::id_t C2AllocationIon::getAllocatorId() const {
-    return mImpl->getAllocatorId();
-}
-
-bool C2AllocationIon::equals(const std::shared_ptr<C2LinearAllocation> &other) const {
-    if (!other || other->getAllocatorId() != getAllocatorId()) {
-        return false;
-    }
-    // get user handle to compare objects
-    std::shared_ptr<C2AllocationIon> otherAsIon = std::static_pointer_cast<C2AllocationIon>(other);
-    return mImpl->ionHandle() == otherAsIon->mImpl->ionHandle();
-}
-
-const C2Handle *C2AllocationIon::handle() const {
-    return mImpl->handle();
-}
-
-C2AllocationIon::~C2AllocationIon() {
-    delete mImpl;
-}
-
-C2AllocationIon::C2AllocationIon(int ionFd, size_t size, size_t align,
-                                 unsigned heapMask, unsigned flags, C2Allocator::id_t id)
-    : C2LinearAllocation(size),
-      mImpl(Impl::Alloc(ionFd, size, align, heapMask, flags, id)) { }
-
-C2AllocationIon::C2AllocationIon(int ionFd, size_t size, int shareFd, C2Allocator::id_t id)
-    : C2LinearAllocation(size),
-      mImpl(Impl::Import(ionFd, size, shareFd, id)) { }
-
-/* ======================================= ION ALLOCATOR ====================================== */
-C2AllocatorIon::C2AllocatorIon(id_t id)
-    : mInit(C2_OK),
-      mIonFd(ion_open()) {
-    if (mIonFd < 0) {
-        switch (errno) {
-        case ENOENT:    mInit = C2_OMITTED; break;
-        default:        mInit = c2_map_errno<EACCES>(errno); break;
-        }
-    } else {
-        C2MemoryUsage minUsage = { 0, 0 }, maxUsage = { ~(uint64_t)0, ~(uint64_t)0 };
-        Traits traits = { "android.allocator.ion", id, LINEAR, minUsage, maxUsage };
-        mTraits = std::make_shared<Traits>(traits);
-    }
-}
-
-C2AllocatorIon::~C2AllocatorIon() {
-    if (mInit == C2_OK) {
-        ion_close(mIonFd);
-    }
-}
-
-C2Allocator::id_t C2AllocatorIon::getId() const {
-    return mTraits->id;
-}
-
-C2String C2AllocatorIon::getName() const {
-    return mTraits->name;
-}
-
-std::shared_ptr<const C2Allocator::Traits> C2AllocatorIon::getTraits() const {
-    return mTraits;
-}
-
-c2_status_t C2AllocatorIon::newLinearAllocation(
-        uint32_t capacity, C2MemoryUsage usage, std::shared_ptr<C2LinearAllocation> *allocation) {
-    if (allocation == nullptr) {
-        return C2_BAD_VALUE;
-    }
-
-    allocation->reset();
-    if (mInit != C2_OK) {
-        return mInit;
-    }
-
-    // get align, heapMask and flags
-    //size_t align = 1;
-    size_t align = 0;
-    unsigned heapMask = ~0;
-    unsigned flags = 0;
-    //TODO
-    (void) usage;
-#if 0
-    int err = mUsageMapper(usage, capacity, &align, &heapMask, &flags);
-    if (err < 0) {
-        return c2_map_errno<EINVAL, ENOMEM, EACCES>(-err);
-    }
-#endif
-
-    std::shared_ptr<C2AllocationIon> alloc
-        = std::make_shared<C2AllocationIon>(dup(mIonFd), capacity, align, heapMask, flags, mTraits->id);
-    c2_status_t ret = alloc->status();
-    if (ret == C2_OK) {
-        *allocation = alloc;
-    }
-    return ret;
-}
-
-c2_status_t C2AllocatorIon::priorLinearAllocation(
-        const C2Handle *handle, std::shared_ptr<C2LinearAllocation> *allocation) {
-    *allocation = nullptr;
-    if (mInit != C2_OK) {
-        return mInit;
-    }
-
-    if (!C2HandleIon::isValid(handle)) {
-        return C2_BAD_VALUE;
-    }
-
-    // TODO: get capacity and validate it
-    const C2HandleIon *h = static_cast<const C2HandleIon*>(handle);
-    std::shared_ptr<C2AllocationIon> alloc
-        = std::make_shared<C2AllocationIon>(dup(mIonFd), h->size(), h->bufferFd(), mTraits->id);
-    c2_status_t ret = alloc->status();
-    if (ret == C2_OK) {
-        *allocation = alloc;
-        native_handle_delete(const_cast<native_handle_t*>(
-                reinterpret_cast<const native_handle_t*>(handle)));
-    }
-    return ret;
-}
-
-bool C2AllocatorIon::isValid(const C2Handle* const o) {
-    return C2HandleIon::isValid(o);
-}
-
-} // namespace android
-
diff --git a/media/libstagefright/codec2/vndk/C2Buffer.cpp b/media/libstagefright/codec2/vndk/C2Buffer.cpp
deleted file mode 100644
index af2c20d..0000000
--- a/media/libstagefright/codec2/vndk/C2Buffer.cpp
+++ /dev/null
@@ -1,1069 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "C2Buffer"
-#include <utils/Log.h>
-
-#include <list>
-#include <map>
-#include <mutex>
-
-#include <C2BufferPriv.h>
-#include <C2BlockInternal.h>
-
-#include <ClientManager.h>
-
-namespace {
-
-using android::hardware::media::bufferpool::V1_0::ResultStatus;
-using android::hardware::media::bufferpool::V1_0::implementation::BufferPoolAllocation;
-using android::hardware::media::bufferpool::V1_0::implementation::BufferPoolAllocator;
-using android::hardware::media::bufferpool::V1_0::implementation::ClientManager;
-using android::hardware::media::bufferpool::V1_0::implementation::ConnectionId;
-
-// This anonymous namespace contains the helper classes that allow our implementation to create
-// block/buffer objects.
-//
-// Inherit from the parent, share with the friend.
-class ReadViewBuddy : public C2ReadView {
-    using C2ReadView::C2ReadView;
-    friend class ::C2ConstLinearBlock;
-};
-
-class WriteViewBuddy : public C2WriteView {
-    using C2WriteView::C2WriteView;
-    friend class ::C2LinearBlock;
-};
-
-class ConstLinearBlockBuddy : public C2ConstLinearBlock {
-    using C2ConstLinearBlock::C2ConstLinearBlock;
-    friend class ::C2LinearBlock;
-};
-
-class LinearBlockBuddy : public C2LinearBlock {
-    using C2LinearBlock::C2LinearBlock;
-    friend class ::C2BasicLinearBlockPool;
-};
-
-class AcquirableReadViewBuddy : public C2Acquirable<C2ReadView> {
-    using C2Acquirable::C2Acquirable;
-    friend class ::C2ConstLinearBlock;
-};
-
-class AcquirableWriteViewBuddy : public C2Acquirable<C2WriteView> {
-    using C2Acquirable::C2Acquirable;
-    friend class ::C2LinearBlock;
-};
-
-class GraphicViewBuddy : public C2GraphicView {
-    using C2GraphicView::C2GraphicView;
-    friend class ::C2ConstGraphicBlock;
-    friend class ::C2GraphicBlock;
-};
-
-class AcquirableConstGraphicViewBuddy : public C2Acquirable<const C2GraphicView> {
-    using C2Acquirable::C2Acquirable;
-    friend class ::C2ConstGraphicBlock;
-};
-
-class AcquirableGraphicViewBuddy : public C2Acquirable<C2GraphicView> {
-    using C2Acquirable::C2Acquirable;
-    friend class ::C2GraphicBlock;
-};
-
-class ConstGraphicBlockBuddy : public C2ConstGraphicBlock {
-    using C2ConstGraphicBlock::C2ConstGraphicBlock;
-    friend class ::C2GraphicBlock;
-};
-
-class GraphicBlockBuddy : public C2GraphicBlock {
-    using C2GraphicBlock::C2GraphicBlock;
-    friend class ::C2BasicGraphicBlockPool;
-};
-
-class BufferDataBuddy : public C2BufferData {
-    using C2BufferData::C2BufferData;
-    friend class ::C2Buffer;
-};
-
-}  // namespace
-
-/* ========================================== 1D BLOCK ========================================= */
-
-struct C2_HIDE _C2BlockPoolData;
-
-/**
- * This class is the base class for all 1D block and view implementations.
- *
- * This is basically just a placeholder for the underlying 1D allocation and the range of the
- * alloted portion to this block. There is also a placeholder for a blockpool data.
- */
-class C2_HIDE _C2Block1DImpl : public _C2LinearRangeAspect {
-public:
-    _C2Block1DImpl(const std::shared_ptr<C2LinearAllocation> &alloc,
-            const std::shared_ptr<_C2BlockPoolData> &poolData = nullptr,
-            size_t offset = 0, size_t size = ~(size_t)0)
-        : _C2LinearRangeAspect(alloc.get(), offset, size),
-          mAllocation(alloc),
-          mPoolData(poolData) { }
-
-    _C2Block1DImpl(const _C2Block1DImpl &other, size_t offset = 0, size_t size = ~(size_t)0)
-        : _C2LinearRangeAspect(&other, offset, size),
-          mAllocation(other.mAllocation),
-          mPoolData(other.mPoolData) { }
-
-    /** returns const pool data  */
-    std::shared_ptr<const _C2BlockPoolData> poolData() const {
-        return mPoolData;
-    }
-
-    /** returns native handle */
-    const C2Handle *handle() const {
-        return mAllocation ? mAllocation->handle() : nullptr;
-    }
-
-    /** returns the allocator's ID */
-    C2Allocator::id_t getAllocatorId() const {
-        // BAD_ID can only happen if this Impl class is initialized for a view - never for a block.
-        return mAllocation ? mAllocation->getAllocatorId() : C2Allocator::BAD_ID;
-    }
-
-    std::shared_ptr<C2LinearAllocation> getAllocation() const {
-        return mAllocation;
-    }
-
-private:
-    std::shared_ptr<C2LinearAllocation> mAllocation;
-    std::shared_ptr<_C2BlockPoolData> mPoolData;
-};
-
-/**
- * This class contains the mapped data pointer, and the potential error.
- *
- * range is the mapped range of the underlying allocation (which is part of the allotted
- * range).
- */
-class C2_HIDE _C2MappedBlock1DImpl : public _C2Block1DImpl {
-public:
-    _C2MappedBlock1DImpl(const _C2Block1DImpl &block, uint8_t *data,
-                         size_t offset = 0, size_t size = ~(size_t)0)
-        : _C2Block1DImpl(block, offset, size), mData(data), mError(C2_OK) { }
-
-    _C2MappedBlock1DImpl(c2_status_t error)
-        : _C2Block1DImpl(nullptr), mData(nullptr), mError(error) {
-        // CHECK(error != C2_OK);
-    }
-
-    const uint8_t *data() const {
-        return mData;
-    }
-
-    uint8_t *data() {
-        return mData;
-    }
-
-    c2_status_t error() const {
-        return mError;
-    }
-
-private:
-    uint8_t *mData;
-    c2_status_t mError;
-};
-
-/**
- * Block implementation.
- */
-class C2Block1D::Impl : public _C2Block1DImpl {
-    using _C2Block1DImpl::_C2Block1DImpl;
-};
-
-const C2Handle *C2Block1D::handle() const {
-    return mImpl->handle();
-};
-
-C2Allocator::id_t C2Block1D::getAllocatorId() const {
-    return mImpl->getAllocatorId();
-};
-
-C2Block1D::C2Block1D(std::shared_ptr<Impl> impl, const _C2LinearRangeAspect &range)
-    // always clamp subrange to parent (impl) range for safety
-    : _C2LinearRangeAspect(impl.get(), range.offset(), range.size()), mImpl(impl) {
-}
-
-/**
- * Read view implementation.
- *
- * range of Impl is the mapped range of the underlying allocation (which is part of the allotted
- * range). range of View is 0 to capacity() (not represented as an actual range). This maps to a
- * subrange of Impl range starting at mImpl->offset() + _mOffset.
- */
-class C2ReadView::Impl : public _C2MappedBlock1DImpl {
-    using _C2MappedBlock1DImpl::_C2MappedBlock1DImpl;
-};
-
-C2ReadView::C2ReadView(std::shared_ptr<Impl> impl, uint32_t offset, uint32_t size)
-    : _C2LinearCapacityAspect(C2LinearCapacity(impl->size()).range(offset, size).size()),
-      mImpl(impl),
-      mOffset(C2LinearCapacity(impl->size()).range(offset, size).offset()) { }
-
-C2ReadView::C2ReadView(c2_status_t error)
-    : _C2LinearCapacityAspect(0u), mImpl(std::make_shared<Impl>(error)), mOffset(0u) {
-    // CHECK(error != C2_OK);
-}
-
-const uint8_t *C2ReadView::data() const {
-    return mImpl->error() ? nullptr : mImpl->data() + mOffset;
-}
-
-c2_status_t C2ReadView::error() const {
-    return mImpl->error();
-}
-
-C2ReadView C2ReadView::subView(size_t offset, size_t size) const {
-    C2LinearRange subRange(*this, offset, size);
-    return C2ReadView(mImpl, mOffset + subRange.offset(), subRange.size());
-}
-
-/**
- * Write view implementation.
- */
-class C2WriteView::Impl : public _C2MappedBlock1DImpl {
-    using _C2MappedBlock1DImpl::_C2MappedBlock1DImpl;
-};
-
-C2WriteView::C2WriteView(std::shared_ptr<Impl> impl)
-// UGLY: _C2LinearRangeAspect requires a bona-fide object for capacity to prevent spoofing, so
-// this is what we have to do.
-// TODO: use childRange
-    : _C2EditableLinearRangeAspect(std::make_unique<C2LinearCapacity>(impl->size()).get()), mImpl(impl) { }
-
-C2WriteView::C2WriteView(c2_status_t error)
-    : _C2EditableLinearRangeAspect(nullptr), mImpl(std::make_shared<Impl>(error)) {}
-
-uint8_t *C2WriteView::base() { return mImpl->data(); }
-
-uint8_t *C2WriteView::data() { return mImpl->data() + offset(); }
-
-c2_status_t C2WriteView::error() const { return mImpl->error(); }
-
-/**
- * Const linear block implementation.
- */
-C2ConstLinearBlock::C2ConstLinearBlock(std::shared_ptr<Impl> impl, const _C2LinearRangeAspect &range, C2Fence fence)
-    : C2Block1D(impl, range), mFence(fence) { }
-
-C2Acquirable<C2ReadView> C2ConstLinearBlock::map() const {
-    void *base = nullptr;
-    uint32_t len = size();
-    c2_status_t error = mImpl->getAllocation()->map(
-            offset(), len, { C2MemoryUsage::CPU_READ, 0 }, nullptr, &base);
-    // TODO: wait on fence
-    if (error == C2_OK) {
-        std::shared_ptr<ReadViewBuddy::Impl> rvi = std::shared_ptr<ReadViewBuddy::Impl>(
-                new ReadViewBuddy::Impl(*mImpl, (uint8_t *)base, offset(), len),
-                [base, len](ReadViewBuddy::Impl *i) {
-                    (void)i->getAllocation()->unmap(base, len, nullptr);
-                    delete i;
-        });
-        return AcquirableReadViewBuddy(error, C2Fence(), ReadViewBuddy(rvi, 0, len));
-    } else {
-        return AcquirableReadViewBuddy(error, C2Fence(), ReadViewBuddy(error));
-    }
-}
-
-C2ConstLinearBlock C2ConstLinearBlock::subBlock(size_t offset_, size_t size_) const {
-    C2LinearRange subRange(*mImpl, offset_, size_);
-    return C2ConstLinearBlock(mImpl, subRange, mFence);
-}
-
-/**
- * Linear block implementation.
- */
-C2LinearBlock::C2LinearBlock(std::shared_ptr<Impl> impl, const _C2LinearRangeAspect &range)
-    : C2Block1D(impl, range) { }
-
-C2Acquirable<C2WriteView> C2LinearBlock::map() {
-    void *base = nullptr;
-    uint32_t len = size();
-    c2_status_t error = mImpl->getAllocation()->map(
-            offset(), len, { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE }, nullptr, &base);
-    // TODO: wait on fence
-    if (error == C2_OK) {
-        std::shared_ptr<WriteViewBuddy::Impl> rvi = std::shared_ptr<WriteViewBuddy::Impl>(
-                new WriteViewBuddy::Impl(*mImpl, (uint8_t *)base, 0, len),
-                [base, len](WriteViewBuddy::Impl *i) {
-                    (void)i->getAllocation()->unmap(base, len, nullptr);
-                    delete i;
-        });
-        return AcquirableWriteViewBuddy(error, C2Fence(), WriteViewBuddy(rvi));
-    } else {
-        return AcquirableWriteViewBuddy(error, C2Fence(), WriteViewBuddy(error));
-    }
-}
-
-C2ConstLinearBlock C2LinearBlock::share(size_t offset_, size_t size_, C2Fence fence) {
-    return ConstLinearBlockBuddy(mImpl, C2LinearRange(*this, offset_, size_), fence);
-}
-
-C2BasicLinearBlockPool::C2BasicLinearBlockPool(
-        const std::shared_ptr<C2Allocator> &allocator)
-  : mAllocator(allocator) { }
-
-c2_status_t C2BasicLinearBlockPool::fetchLinearBlock(
-        uint32_t capacity,
-        C2MemoryUsage usage,
-        std::shared_ptr<C2LinearBlock> *block /* nonnull */) {
-    block->reset();
-
-    std::shared_ptr<C2LinearAllocation> alloc;
-    c2_status_t err = mAllocator->newLinearAllocation(capacity, usage, &alloc);
-    if (err != C2_OK) {
-        return err;
-    }
-
-    *block = _C2BlockFactory::CreateLinearBlock(alloc);
-
-    return C2_OK;
-}
-
-std::shared_ptr<C2LinearBlock> _C2BlockFactory::CreateLinearBlock(
-        const std::shared_ptr<C2LinearAllocation> &alloc,
-        const std::shared_ptr<_C2BlockPoolData> &data, size_t offset, size_t size) {
-    std::shared_ptr<C2Block1D::Impl> impl =
-        std::make_shared<C2Block1D::Impl>(alloc, data, offset, size);
-    return std::shared_ptr<C2LinearBlock>(new C2LinearBlock(impl, *impl));
-}
-
-/**
- * Wrapped C2Allocator which is injected to buffer pool on behalf of
- * C2BlockPool.
- */
-class _C2BufferPoolAllocator : public BufferPoolAllocator {
-public:
-    _C2BufferPoolAllocator(const std::shared_ptr<C2Allocator> &allocator)
-        : mAllocator(allocator) {}
-
-    ~_C2BufferPoolAllocator() override {}
-
-    ResultStatus allocate(const std::vector<uint8_t> &params,
-                          std::shared_ptr<BufferPoolAllocation> *alloc) override;
-
-    bool compatible(const std::vector<uint8_t> &newParams,
-                    const std::vector<uint8_t> &oldParams) override;
-
-    // Methods for codec2 component (C2BlockPool).
-    /**
-     * Transforms linear allocation parameters for C2Allocator to parameters
-     * for buffer pool.
-     *
-     * @param capacity      size of linear allocation
-     * @param usage         memory usage pattern for linear allocation
-     * @param params        allocation parameters for buffer pool
-     */
-    void getLinearParams(uint32_t capacity, C2MemoryUsage usage,
-                         std::vector<uint8_t> *params);
-
-    /**
-     * Transforms graphic allocation parameters for C2Allocator to parameters
-     * for buffer pool.
-     *
-     * @param width         width of graphic allocation
-     * @param height        height of graphic allocation
-     * @param format        color format of graphic allocation
-     * @param params        allocation parameter for buffer pool
-     */
-    void getGraphicParams(uint32_t width, uint32_t height,
-                          uint32_t format, C2MemoryUsage usage,
-                          std::vector<uint8_t> *params);
-
-    /**
-     * Transforms an existing native handle to an C2LinearAllcation.
-     * Wrapper to C2Allocator#priorLinearAllocation
-     */
-    c2_status_t priorLinearAllocation(
-            const C2Handle *handle,
-            std::shared_ptr<C2LinearAllocation> *c2Allocation);
-
-    /**
-     * Transforms an existing native handle to an C2GraphicAllcation.
-     * Wrapper to C2Allocator#priorGraphicAllocation
-     */
-    c2_status_t priorGraphicAllocation(
-            const C2Handle *handle,
-            std::shared_ptr<C2GraphicAllocation> *c2Allocation);
-
-private:
-    static constexpr int kMaxIntParams = 5; // large enough number;
-
-    enum AllocType : uint8_t {
-        ALLOC_NONE = 0,
-
-        ALLOC_LINEAR,
-        ALLOC_GRAPHIC,
-    };
-
-    union AllocParams {
-        struct {
-            AllocType allocType;
-            C2MemoryUsage usage;
-            uint32_t params[kMaxIntParams];
-        } data;
-        uint8_t array[0];
-
-        AllocParams() : data{ALLOC_NONE, {0, 0}, {0}} {}
-        AllocParams(C2MemoryUsage usage, uint32_t capacity)
-            : data{ALLOC_LINEAR, usage, {[0] = capacity}} {}
-        AllocParams(
-                C2MemoryUsage usage,
-                uint32_t width, uint32_t height, uint32_t format)
-                : data{ALLOC_GRAPHIC, usage, {width, height, format}} {}
-    };
-
-    const std::shared_ptr<C2Allocator> mAllocator;
-};
-
-struct LinearAllocationDtor {
-    LinearAllocationDtor(const std::shared_ptr<C2LinearAllocation> &alloc)
-        : mAllocation(alloc) {}
-
-    void operator()(BufferPoolAllocation *poolAlloc) { delete poolAlloc; }
-
-    const std::shared_ptr<C2LinearAllocation> mAllocation;
-};
-
-ResultStatus _C2BufferPoolAllocator::allocate(
-        const std::vector<uint8_t>  &params,
-        std::shared_ptr<BufferPoolAllocation> *alloc) {
-    AllocParams c2Params;
-    memcpy(&c2Params, params.data(), std::min(sizeof(AllocParams), params.size()));
-    std::shared_ptr<C2LinearAllocation> c2Linear;
-    c2_status_t status = C2_BAD_VALUE;
-    switch(c2Params.data.allocType) {
-        case ALLOC_NONE:
-            break;
-        case ALLOC_LINEAR:
-            status = mAllocator->newLinearAllocation(
-                    c2Params.data.params[0], c2Params.data.usage, &c2Linear);
-            if (status == C2_OK && c2Linear) {
-                BufferPoolAllocation *ptr = new BufferPoolAllocation(c2Linear->handle());
-                if (ptr) {
-                    *alloc = std::shared_ptr<BufferPoolAllocation>(
-                            ptr, LinearAllocationDtor(c2Linear));
-                    if (*alloc) {
-                        return ResultStatus::OK;
-                    }
-                    delete ptr;
-                }
-                return ResultStatus::NO_MEMORY;
-            }
-            break;
-        case ALLOC_GRAPHIC:
-            // TODO
-            break;
-        default:
-            break;
-    }
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-bool _C2BufferPoolAllocator::compatible(
-        const std::vector<uint8_t>  &newParams,
-        const std::vector<uint8_t>  &oldParams) {
-    size_t newSize = newParams.size();
-    size_t oldSize = oldParams.size();
-
-    // TODO: support not exact matching. e.g) newCapacity < oldCapacity
-    if (newSize == oldSize) {
-        for (size_t i = 0; i < newSize; ++i) {
-            if (newParams[i] != oldParams[i]) {
-                return false;
-            }
-        }
-        return true;
-    }
-    return false;
-}
-
-void _C2BufferPoolAllocator::getLinearParams(
-        uint32_t capacity, C2MemoryUsage usage, std::vector<uint8_t> *params) {
-    AllocParams c2Params(usage, capacity);
-    params->assign(c2Params.array, c2Params.array + sizeof(AllocParams));
-}
-
-void _C2BufferPoolAllocator::getGraphicParams(
-        uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
-        std::vector<uint8_t> *params) {
-    AllocParams c2Params(usage, width, height, format);
-    params->assign(c2Params.array, c2Params.array + sizeof(AllocParams));
-}
-
-c2_status_t _C2BufferPoolAllocator::priorLinearAllocation(
-        const C2Handle *handle,
-        std::shared_ptr<C2LinearAllocation> *c2Allocation) {
-    return mAllocator->priorLinearAllocation(handle, c2Allocation);
-}
-
-c2_status_t _C2BufferPoolAllocator::priorGraphicAllocation(
-        const C2Handle *handle,
-        std::shared_ptr<C2GraphicAllocation> *c2Allocation) {
-    return mAllocator->priorGraphicAllocation(handle, c2Allocation);
-}
-
-class C2PooledBlockPool::Impl {
-public:
-    Impl(const std::shared_ptr<C2Allocator> &allocator)
-            : mInit(C2_OK),
-              mBufferPoolManager(ClientManager::getInstance()),
-              mAllocator(std::make_shared<_C2BufferPoolAllocator>(allocator)) {
-        if (mAllocator && mBufferPoolManager) {
-            if (mBufferPoolManager->create(
-                    mAllocator, &mConnectionId) == ResultStatus::OK) {
-                return;
-            }
-        }
-        mInit = C2_NO_INIT;
-    }
-
-    ~Impl() {
-        if (mInit == C2_OK) {
-            mBufferPoolManager->close(mConnectionId);
-        }
-    }
-
-    c2_status_t fetchLinearBlock(
-            uint32_t capacity, C2MemoryUsage usage,
-            std::shared_ptr<C2LinearBlock> *block /* nonnull */) {
-        block->reset();
-        if (mInit != C2_OK) {
-            return mInit;
-        }
-        std::vector<uint8_t> params;
-        mAllocator->getLinearParams(capacity, usage, &params);
-        std::shared_ptr<_C2BlockPoolData> poolData;
-        ResultStatus status = mBufferPoolManager->allocate(
-                mConnectionId, params, &poolData);
-        if (status == ResultStatus::OK) {
-            std::shared_ptr<C2LinearAllocation> alloc;
-            c2_status_t err = mAllocator->priorLinearAllocation(
-                    poolData->mHandle, &alloc);
-            if (err == C2_OK && poolData && alloc) {
-                *block = _C2BlockFactory::CreateLinearBlock(
-                        alloc, poolData, 0, capacity);
-                if (*block) {
-                    return C2_OK;
-                }
-            }
-            return C2_NO_MEMORY;
-        }
-        if (status == ResultStatus::NO_MEMORY) {
-            return C2_NO_MEMORY;
-        }
-        return C2_CORRUPTED;
-    }
-
-private:
-    c2_status_t mInit;
-    const android::sp<ClientManager> mBufferPoolManager;
-    ConnectionId mConnectionId; // locally
-    const std::shared_ptr<_C2BufferPoolAllocator> mAllocator;
-};
-
-C2PooledBlockPool::C2PooledBlockPool(
-        const std::shared_ptr<C2Allocator> &allocator, const local_id_t localId)
-        : mAllocator(allocator), mLocalId(localId), mImpl(new Impl(allocator)) {}
-
-C2PooledBlockPool::~C2PooledBlockPool() {
-}
-
-c2_status_t C2PooledBlockPool::fetchLinearBlock(
-        uint32_t capacity,
-        C2MemoryUsage usage,
-        std::shared_ptr<C2LinearBlock> *block /* nonnull */) {
-    if (mImpl) {
-        return mImpl->fetchLinearBlock(capacity, usage, block);
-    }
-    return C2_CORRUPTED;
-}
-
-/* ========================================== 2D BLOCK ========================================= */
-
-/**
- * Implementation that is shared between all 2D blocks and views.
- *
- * For blocks' Impl's crop is always the allotted crop, even if it is a sub block.
- *
- * For views' Impl's crop is the mapped portion - which for now is always the
- * allotted crop.
- */
-class C2_HIDE _C2Block2DImpl : public _C2PlanarSectionAspect {
-public:
-    /**
-     * Impl's crop is always the or part of the allotted crop of the allocation.
-     */
-    _C2Block2DImpl(const std::shared_ptr<C2GraphicAllocation> &alloc,
-            const std::shared_ptr<_C2BlockPoolData> &poolData = nullptr,
-            const C2Rect &allottedCrop = C2Rect(~0u, ~0u))
-        : _C2PlanarSectionAspect(alloc.get(), allottedCrop),
-          mAllocation(alloc),
-          mPoolData(poolData) { }
-
-    /** returns const pool data  */
-    std::shared_ptr<const _C2BlockPoolData> poolData() const {
-        return mPoolData;
-    }
-
-    /** returns native handle */
-    const C2Handle *handle() const {
-        return mAllocation ? mAllocation->handle() : nullptr;
-    }
-
-    /** returns the allocator's ID */
-    C2Allocator::id_t getAllocatorId() const {
-        // BAD_ID can only happen if this Impl class is initialized for a view - never for a block.
-        return mAllocation ? mAllocation->getAllocatorId() : C2Allocator::BAD_ID;
-    }
-
-    std::shared_ptr<C2GraphicAllocation> getAllocation() const {
-        return mAllocation;
-    }
-
-private:
-    std::shared_ptr<C2GraphicAllocation> mAllocation;
-    std::shared_ptr<_C2BlockPoolData> mPoolData;
-};
-
-class C2_HIDE _C2MappingBlock2DImpl
-    : public _C2Block2DImpl, public std::enable_shared_from_this<_C2MappingBlock2DImpl> {
-public:
-    using _C2Block2DImpl::_C2Block2DImpl;
-
-    /**
-     * This class contains the mapped data pointer, and the potential error.
-     */
-    struct Mapped {
-    private:
-        friend class _C2MappingBlock2DImpl;
-
-        Mapped(const std::shared_ptr<_C2Block2DImpl> &impl, bool writable, C2Fence *fence __unused)
-            : mImpl(impl), mWritable(writable) {
-            memset(mData, 0, sizeof(mData));
-            const C2Rect crop = mImpl->crop();
-            // gralloc requires mapping the whole region of interest as we cannot
-            // map multiple regions
-            mError = mImpl->getAllocation()->map(
-                    crop,
-                    { C2MemoryUsage::CPU_READ, writable ? C2MemoryUsage::CPU_WRITE : 0 },
-                    nullptr,
-                    &mLayout,
-                    mData);
-            if (mError != C2_OK) {
-                memset(&mLayout, 0, sizeof(mLayout));
-                memset(mData, 0, sizeof(mData));
-                memset(mOffsetData, 0, sizeof(mData));
-            } else {
-                // TODO: validate plane layout and
-                // adjust data pointers to the crop region's top left corner.
-                // fail if it is not on a subsampling boundary
-                for (size_t planeIx = 0; planeIx < mLayout.numPlanes; ++planeIx) {
-                    const uint32_t colSampling = mLayout.planes[planeIx].colSampling;
-                    const uint32_t rowSampling = mLayout.planes[planeIx].rowSampling;
-                    if (crop.left % colSampling || crop.right() % colSampling
-                            || crop.top % rowSampling || crop.bottom() % rowSampling) {
-                        // cannot calculate data pointer
-                        mImpl->getAllocation()->unmap(mData, crop, nullptr);
-                        memset(&mLayout, 0, sizeof(mLayout));
-                        memset(mData, 0, sizeof(mData));
-                        memset(mOffsetData, 0, sizeof(mData));
-                        mError = C2_BAD_VALUE;
-                        return;
-                    }
-                    mOffsetData[planeIx] =
-                        mData[planeIx] + (ssize_t)crop.left * mLayout.planes[planeIx].colInc
-                                + (ssize_t)crop.top * mLayout.planes[planeIx].rowInc;
-                }
-            }
-        }
-
-        explicit Mapped(c2_status_t error)
-            : mImpl(nullptr), mWritable(false), mError(error) {
-            // CHECK(error != C2_OK);
-            memset(&mLayout, 0, sizeof(mLayout));
-            memset(mData, 0, sizeof(mData));
-            memset(mOffsetData, 0, sizeof(mData));
-        }
-
-    public:
-        ~Mapped() {
-            if (mData[0] != nullptr) {
-                mImpl->getAllocation()->unmap(mData, mImpl->crop(), nullptr);
-            }
-        }
-
-        /** returns mapping status */
-        c2_status_t error() const { return mError; }
-
-        /** returns data pointer */
-        uint8_t *const *data() const { return mOffsetData; }
-
-        /** returns the plane layout */
-        C2PlanarLayout layout() const { return mLayout; }
-
-        /** returns whether the mapping is writable */
-        bool writable() const { return mWritable; }
-
-    private:
-        const std::shared_ptr<_C2Block2DImpl> mImpl;
-        bool mWritable;
-        c2_status_t mError;
-        uint8_t *mData[C2PlanarLayout::MAX_NUM_PLANES];
-        uint8_t *mOffsetData[C2PlanarLayout::MAX_NUM_PLANES];
-        C2PlanarLayout mLayout;
-    };
-
-    /**
-     * Maps the allotted region.
-     *
-     * If already mapped and it is currently in use, returns the existing mapping.
-     * If fence is provided, an acquire fence is stored there.
-     */
-    std::shared_ptr<Mapped> map(bool writable, C2Fence *fence) {
-        std::lock_guard<std::mutex> lock(mMappedLock);
-        std::shared_ptr<Mapped> existing = mMapped.lock();
-        if (!existing) {
-            existing = std::shared_ptr<Mapped>(new Mapped(shared_from_this(), writable, fence));
-            mMapped = existing;
-        } else {
-            // if we mapped the region read-only, we cannot remap it read-write
-            if (writable && !existing->writable()) {
-                existing = std::shared_ptr<Mapped>(new Mapped(C2_CANNOT_DO));
-            }
-            if (fence != nullptr) {
-                *fence = C2Fence();
-            }
-        }
-        return existing;
-    }
-
-private:
-    std::weak_ptr<Mapped> mMapped;
-    std::mutex mMappedLock;
-};
-
-class C2_HIDE _C2MappedBlock2DImpl : public _C2Block2DImpl {
-public:
-    _C2MappedBlock2DImpl(const _C2Block2DImpl &impl,
-                         std::shared_ptr<_C2MappingBlock2DImpl::Mapped> mapping)
-        : _C2Block2DImpl(impl), mMapping(mapping) {
-    }
-
-    std::shared_ptr<_C2MappingBlock2DImpl::Mapped> mapping() const { return mMapping; }
-
-private:
-    std::shared_ptr<_C2MappingBlock2DImpl::Mapped> mMapping;
-};
-
-/**
- * Block implementation.
- */
-class C2Block2D::Impl : public _C2MappingBlock2DImpl {
-    using _C2MappingBlock2DImpl::_C2MappingBlock2DImpl;
-};
-
-const C2Handle *C2Block2D::handle() const {
-    return mImpl->handle();
-}
-
-C2Allocator::id_t C2Block2D::getAllocatorId() const {
-    return mImpl->getAllocatorId();
-}
-
-C2Block2D::C2Block2D(std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section)
-    // always clamp subsection to parent (impl) crop for safety
-    : _C2PlanarSectionAspect(impl.get(), section.crop()), mImpl(impl) {
-}
-
-/**
- * Graphic view implementation.
- *
- * range of Impl is the mapped range of the underlying allocation. range of View is the current
- * crop.
- */
-class C2GraphicView::Impl : public _C2MappedBlock2DImpl {
-    using _C2MappedBlock2DImpl::_C2MappedBlock2DImpl;
-};
-
-C2GraphicView::C2GraphicView(std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section)
-    : _C2EditablePlanarSectionAspect(impl.get(), section.crop()), mImpl(impl) {
-}
-
-const uint8_t *const *C2GraphicView::data() const {
-    return mImpl->mapping()->data();
-}
-
-uint8_t *const *C2GraphicView::data() {
-    return mImpl->mapping()->data();
-}
-
-const C2PlanarLayout C2GraphicView::layout() const {
-    return mImpl->mapping()->layout();
-}
-
-const C2GraphicView C2GraphicView::subView(const C2Rect &rect) const {
-    return C2GraphicView(mImpl, C2PlanarSection(*mImpl, rect));
-}
-
-C2GraphicView C2GraphicView::subView(const C2Rect &rect) {
-    return C2GraphicView(mImpl, C2PlanarSection(*mImpl, rect));
-}
-
-c2_status_t C2GraphicView::error() const {
-    return mImpl->mapping()->error();
-}
-
-/**
- * Const graphic block implementation.
- */
-C2ConstGraphicBlock::C2ConstGraphicBlock(
-        std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section, C2Fence fence)
-    : C2Block2D(impl, section), mFence(fence) { }
-
-C2Acquirable<const C2GraphicView> C2ConstGraphicBlock::map() const {
-    C2Fence fence;
-    std::shared_ptr<_C2MappingBlock2DImpl::Mapped> mapping =
-        mImpl->map(false /* writable */, &fence);
-    std::shared_ptr<GraphicViewBuddy::Impl> gvi =
-        std::shared_ptr<GraphicViewBuddy::Impl>(new GraphicViewBuddy::Impl(*mImpl, mapping));
-    return AcquirableConstGraphicViewBuddy(
-            mapping->error(), fence, GraphicViewBuddy(gvi, C2PlanarSection(*mImpl, crop())));
-}
-
-C2ConstGraphicBlock C2ConstGraphicBlock::subBlock(const C2Rect &rect) const {
-    return C2ConstGraphicBlock(mImpl, C2PlanarSection(*mImpl, crop().intersect(rect)), mFence);
-}
-
-/**
- * Graphic block implementation.
- */
-C2GraphicBlock::C2GraphicBlock(
-    std::shared_ptr<Impl> impl, const _C2PlanarSectionAspect &section)
-    : C2Block2D(impl, section) { }
-
-C2Acquirable<C2GraphicView> C2GraphicBlock::map() {
-    C2Fence fence;
-    std::shared_ptr<_C2MappingBlock2DImpl::Mapped> mapping =
-        mImpl->map(true /* writable */, &fence);
-    std::shared_ptr<GraphicViewBuddy::Impl> gvi =
-        std::shared_ptr<GraphicViewBuddy::Impl>(new GraphicViewBuddy::Impl(*mImpl, mapping));
-    return AcquirableGraphicViewBuddy(
-            mapping->error(), fence, GraphicViewBuddy(gvi, C2PlanarSection(*mImpl, crop())));
-}
-
-C2ConstGraphicBlock C2GraphicBlock::share(const C2Rect &crop, C2Fence fence) {
-    return ConstGraphicBlockBuddy(mImpl, C2PlanarSection(*mImpl, crop), fence);
-}
-
-/**
- * Basic block pool implementations.
- */
-C2BasicGraphicBlockPool::C2BasicGraphicBlockPool(
-        const std::shared_ptr<C2Allocator> &allocator)
-  : mAllocator(allocator) {}
-
-c2_status_t C2BasicGraphicBlockPool::fetchGraphicBlock(
-        uint32_t width,
-        uint32_t height,
-        uint32_t format,
-        C2MemoryUsage usage,
-        std::shared_ptr<C2GraphicBlock> *block /* nonnull */) {
-    block->reset();
-
-    std::shared_ptr<C2GraphicAllocation> alloc;
-    c2_status_t err = mAllocator->newGraphicAllocation(width, height, format, usage, &alloc);
-    if (err != C2_OK) {
-        return err;
-    }
-
-    *block = _C2BlockFactory::CreateGraphicBlock(alloc);
-
-    return C2_OK;
-}
-
-std::shared_ptr<C2GraphicBlock> _C2BlockFactory::CreateGraphicBlock(
-        const std::shared_ptr<C2GraphicAllocation> &alloc,
-        const std::shared_ptr<_C2BlockPoolData> &data, const C2Rect &allottedCrop) {
-    std::shared_ptr<C2Block2D::Impl> impl =
-        std::make_shared<C2Block2D::Impl>(alloc, data, allottedCrop);
-    return std::shared_ptr<C2GraphicBlock>(new C2GraphicBlock(impl, *impl));
-}
-
-/* ========================================== BUFFER ========================================= */
-
-class C2BufferData::Impl {
-public:
-    explicit Impl(const std::vector<C2ConstLinearBlock> &blocks)
-        : mType(blocks.size() == 1 ? LINEAR : LINEAR_CHUNKS),
-          mLinearBlocks(blocks) {
-    }
-
-    explicit Impl(const std::vector<C2ConstGraphicBlock> &blocks)
-        : mType(blocks.size() == 1 ? GRAPHIC : GRAPHIC_CHUNKS),
-          mGraphicBlocks(blocks) {
-    }
-
-    Type type() const { return mType; }
-    const std::vector<C2ConstLinearBlock> &linearBlocks() const { return mLinearBlocks; }
-    const std::vector<C2ConstGraphicBlock> &graphicBlocks() const { return mGraphicBlocks; }
-
-private:
-    Type mType;
-    std::vector<C2ConstLinearBlock> mLinearBlocks;
-    std::vector<C2ConstGraphicBlock> mGraphicBlocks;
-};
-
-C2BufferData::C2BufferData(const std::vector<C2ConstLinearBlock> &blocks) : mImpl(new Impl(blocks)) {}
-C2BufferData::C2BufferData(const std::vector<C2ConstGraphicBlock> &blocks) : mImpl(new Impl(blocks)) {}
-
-C2BufferData::Type C2BufferData::type() const { return mImpl->type(); }
-
-const std::vector<C2ConstLinearBlock> C2BufferData::linearBlocks() const {
-    return mImpl->linearBlocks();
-}
-
-const std::vector<C2ConstGraphicBlock> C2BufferData::graphicBlocks() const {
-    return mImpl->graphicBlocks();
-}
-
-class C2Buffer::Impl {
-public:
-    Impl(C2Buffer *thiz, const std::vector<C2ConstLinearBlock> &blocks)
-        : mThis(thiz), mData(blocks) {}
-    Impl(C2Buffer *thiz, const std::vector<C2ConstGraphicBlock> &blocks)
-        : mThis(thiz), mData(blocks) {}
-
-    ~Impl() {
-        for (const auto &pair : mNotify) {
-            pair.first(mThis, pair.second);
-        }
-    }
-
-    const C2BufferData &data() const { return mData; }
-
-    c2_status_t registerOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
-        auto it = std::find_if(
-                mNotify.begin(), mNotify.end(),
-                [onDestroyNotify, arg] (const auto &pair) {
-                    return pair.first == onDestroyNotify && pair.second == arg;
-                });
-        if (it != mNotify.end()) {
-            return C2_DUPLICATE;
-        }
-        mNotify.emplace_back(onDestroyNotify, arg);
-        return C2_OK;
-    }
-
-    c2_status_t unregisterOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
-        auto it = std::find_if(
-                mNotify.begin(), mNotify.end(),
-                [onDestroyNotify, arg] (const auto &pair) {
-                    return pair.first == onDestroyNotify && pair.second == arg;
-                });
-        if (it == mNotify.end()) {
-            return C2_NOT_FOUND;
-        }
-        mNotify.erase(it);
-        return C2_OK;
-    }
-
-    std::vector<std::shared_ptr<const C2Info>> info() const {
-        std::vector<std::shared_ptr<const C2Info>> result(mInfos.size());
-        std::transform(
-                mInfos.begin(), mInfos.end(), result.begin(),
-                [] (const auto &elem) { return elem.second; });
-        return result;
-    }
-
-    c2_status_t setInfo(const std::shared_ptr<C2Info> &info) {
-        // To "update" you need to erase the existing one if any, and then insert.
-        (void) mInfos.erase(info->type());
-        (void) mInfos.insert({ info->type(), info });
-        return C2_OK;
-    }
-
-    bool hasInfo(C2Param::Type index) const {
-        return mInfos.count(index.type()) > 0;
-    }
-
-    std::shared_ptr<C2Info> removeInfo(C2Param::Type index) {
-        auto it = mInfos.find(index.type());
-        if (it == mInfos.end()) {
-            return nullptr;
-        }
-        std::shared_ptr<C2Info> ret = it->second;
-        (void) mInfos.erase(it);
-        return ret;
-    }
-
-private:
-    C2Buffer * const mThis;
-    BufferDataBuddy mData;
-    std::map<C2Param::Type, std::shared_ptr<C2Info>> mInfos;
-    std::list<std::pair<OnDestroyNotify, void *>> mNotify;
-};
-
-C2Buffer::C2Buffer(const std::vector<C2ConstLinearBlock> &blocks)
-    : mImpl(new Impl(this, blocks)) {}
-
-C2Buffer::C2Buffer(const std::vector<C2ConstGraphicBlock> &blocks)
-    : mImpl(new Impl(this, blocks)) {}
-
-const C2BufferData C2Buffer::data() const { return mImpl->data(); }
-
-c2_status_t C2Buffer::registerOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
-    return mImpl->registerOnDestroyNotify(onDestroyNotify, arg);
-}
-
-c2_status_t C2Buffer::unregisterOnDestroyNotify(OnDestroyNotify onDestroyNotify, void *arg) {
-    return mImpl->unregisterOnDestroyNotify(onDestroyNotify, arg);
-}
-
-const std::vector<std::shared_ptr<const C2Info>> C2Buffer::info() const {
-    return mImpl->info();
-}
-
-c2_status_t C2Buffer::setInfo(const std::shared_ptr<C2Info> &info) {
-    return mImpl->setInfo(info);
-}
-
-bool C2Buffer::hasInfo(C2Param::Type index) const {
-    return mImpl->hasInfo(index);
-}
-
-std::shared_ptr<C2Info> C2Buffer::removeInfo(C2Param::Type index) {
-    return mImpl->removeInfo(index);
-}
-
-// static
-std::shared_ptr<C2Buffer> C2Buffer::CreateLinearBuffer(const C2ConstLinearBlock &block) {
-    return std::shared_ptr<C2Buffer>(new C2Buffer({ block }));
-}
-
-// static
-std::shared_ptr<C2Buffer> C2Buffer::CreateGraphicBuffer(const C2ConstGraphicBlock &block) {
-    return std::shared_ptr<C2Buffer>(new C2Buffer({ block }));
-}
-
diff --git a/media/libstagefright/codec2/vndk/C2Config.cpp b/media/libstagefright/codec2/vndk/C2Config.cpp
deleted file mode 100644
index 6acf524..0000000
--- a/media/libstagefright/codec2/vndk/C2Config.cpp
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2017 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 "C2Config"
-
-/**
- * Define and initialize global config field descriptors in this cpp file
- */
-#define __C2_GENERATE_GLOBAL_VARS__
-#include <C2Config.h>
diff --git a/media/libstagefright/codec2/vndk/C2Store.cpp b/media/libstagefright/codec2/vndk/C2Store.cpp
deleted file mode 100644
index 6f752ae..0000000
--- a/media/libstagefright/codec2/vndk/C2Store.cpp
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- * Copyright (C) 2017 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 <C2AllocatorGralloc.h>
-#include <C2AllocatorIon.h>
-#include <C2BufferPriv.h>
-#include <C2Component.h>
-#include <C2PlatformSupport.h>
-
-#define LOG_TAG "C2Store"
-#define LOG_NDEBUG 0
-#include <utils/Log.h>
-
-#include <dlfcn.h>
-
-#include <map>
-#include <memory>
-#include <mutex>
-
-namespace android {
-
-/**
- * The platform allocator store provides basic allocator-types for the framework based on ion and
- * gralloc. Allocators are not meant to be updatable.
- *
- * \todo Provide allocator based on ashmem
- * \todo Move ion allocation into its HIDL or provide some mapping from memory usage to ion flags
- * \todo Make this allocator store extendable
- */
-class C2PlatformAllocatorStoreImpl : public C2PlatformAllocatorStore {
-public:
-    C2PlatformAllocatorStoreImpl(
-        /* ionmapper */
-    );
-
-    virtual c2_status_t fetchAllocator(
-            id_t id, std::shared_ptr<C2Allocator> *const allocator) override;
-
-    virtual std::vector<std::shared_ptr<const C2Allocator::Traits>> listAllocators_nb()
-            const override {
-        return std::vector<std::shared_ptr<const C2Allocator::Traits>>(); /// \todo
-    }
-
-    virtual C2String getName() const override {
-        return "android.allocator-store";
-    }
-
-private:
-    /// returns a shared-singleton ion allocator
-    std::shared_ptr<C2Allocator> fetchIonAllocator();
-
-    /// returns a shared-singleton gralloc allocator
-    std::shared_ptr<C2Allocator> fetchGrallocAllocator();
-};
-
-C2PlatformAllocatorStoreImpl::C2PlatformAllocatorStoreImpl() {
-}
-
-c2_status_t C2PlatformAllocatorStoreImpl::fetchAllocator(
-        id_t id, std::shared_ptr<C2Allocator> *const allocator) {
-    allocator->reset();
-    switch (id) {
-    // TODO: should we implement a generic registry for all, and use that?
-    case C2PlatformAllocatorStore::ION:
-    case C2AllocatorStore::DEFAULT_LINEAR:
-        *allocator = fetchIonAllocator();
-        break;
-
-    case C2PlatformAllocatorStore::GRALLOC:
-    case C2AllocatorStore::DEFAULT_GRAPHIC:
-        *allocator = fetchGrallocAllocator();
-        break;
-
-    default:
-        return C2_NOT_FOUND;
-    }
-    if (*allocator == nullptr) {
-        return C2_NO_MEMORY;
-    }
-    return C2_OK;
-}
-
-std::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchIonAllocator() {
-    static std::mutex mutex;
-    static std::weak_ptr<C2Allocator> ionAllocator;
-    std::lock_guard<std::mutex> lock(mutex);
-    std::shared_ptr<C2Allocator> allocator = ionAllocator.lock();
-    if (allocator == nullptr) {
-        allocator = std::make_shared<C2AllocatorIon>(C2PlatformAllocatorStore::ION);
-        ionAllocator = allocator;
-    }
-    return allocator;
-}
-
-std::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchGrallocAllocator() {
-    static std::mutex mutex;
-    static std::weak_ptr<C2Allocator> grallocAllocator;
-    std::lock_guard<std::mutex> lock(mutex);
-    std::shared_ptr<C2Allocator> allocator = grallocAllocator.lock();
-    if (allocator == nullptr) {
-        allocator = std::make_shared<C2AllocatorGralloc>(C2PlatformAllocatorStore::GRALLOC);
-        grallocAllocator = allocator;
-    }
-    return allocator;
-}
-
-std::shared_ptr<C2AllocatorStore> GetCodec2PlatformAllocatorStore() {
-    return std::make_shared<C2PlatformAllocatorStoreImpl>();
-}
-
-c2_status_t GetCodec2BlockPool(
-        C2BlockPool::local_id_t id, std::shared_ptr<const C2Component> component,
-        std::shared_ptr<C2BlockPool> *pool) {
-    pool->reset();
-    if (!component) {
-        return C2_BAD_VALUE;
-    }
-    // TODO support pre-registered block pools
-    std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore();
-    std::shared_ptr<C2Allocator> allocator;
-    c2_status_t res = C2_NOT_FOUND;
-
-    switch (id) {
-    case C2BlockPool::BASIC_LINEAR:
-        res = allocatorStore->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &allocator);
-        if (res == C2_OK) {
-            *pool = std::make_shared<C2BasicLinearBlockPool>(allocator);
-        }
-        break;
-    case C2BlockPool::BASIC_GRAPHIC:
-        res = allocatorStore->fetchAllocator(C2AllocatorStore::DEFAULT_GRAPHIC, &allocator);
-        if (res == C2_OK) {
-            *pool = std::make_shared<C2BasicGraphicBlockPool>(allocator);
-        }
-        break;
-    default:
-        break;
-    }
-    return res;
-}
-
-c2_status_t CreateCodec2BlockPool(
-        C2PlatformAllocatorStore::id_t allocatorId,
-        std::shared_ptr<const C2Component> component,
-        std::shared_ptr<C2BlockPool> *pool) {
-    pool->reset();
-    if (!component) {
-        return C2_BAD_VALUE;
-    }
-    // TODO: support caching block pool along with GetCodec2BlockPool.
-    static std::atomic_int sBlockPoolId(C2BlockPool::PLATFORM_START);
-    std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore();
-    std::shared_ptr<C2Allocator> allocator;
-    c2_status_t res = C2_NOT_FOUND;
-
-    switch (allocatorId) {
-    case C2PlatformAllocatorStore::ION:
-        res = allocatorStore->fetchAllocator(C2AllocatorStore::DEFAULT_LINEAR, &allocator);
-        if (res == C2_OK) {
-            *pool = std::make_shared<C2PooledBlockPool>(allocator, sBlockPoolId++);
-            if (!*pool) {
-                res = C2_NO_MEMORY;
-            }
-        }
-        break;
-    case C2PlatformAllocatorStore::GRALLOC:
-        // TODO: support gralloc
-        break;
-    default:
-        break;
-    }
-    return res;
-}
-
-class C2PlatformComponentStore : public C2ComponentStore {
-public:
-    virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() override;
-    virtual std::shared_ptr<C2ParamReflector> getParamReflector() const override;
-    virtual C2String getName() const override;
-    virtual c2_status_t querySupportedValues_sm(
-            std::vector<C2FieldSupportedValuesQuery> &fields) const override;
-    virtual c2_status_t querySupportedParams_nb(
-            std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const override;
-    virtual c2_status_t query_sm(
-            const std::vector<C2Param*> &stackParams,
-            const std::vector<C2Param::Index> &heapParamIndices,
-            std::vector<std::unique_ptr<C2Param>> *const heapParams) const override;
-    virtual c2_status_t createInterface(
-            C2String name, std::shared_ptr<C2ComponentInterface> *const interface) override;
-    virtual c2_status_t createComponent(
-            C2String name, std::shared_ptr<C2Component> *const component) override;
-    virtual c2_status_t copyBuffer(
-            std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) override;
-    virtual c2_status_t config_sm(
-            const std::vector<C2Param*> &params,
-            std::vector<std::unique_ptr<C2SettingResult>> *const failures) override;
-    C2PlatformComponentStore();
-
-    virtual ~C2PlatformComponentStore() override = default;
-
-private:
-
-    /**
-     * An object encapsulating a loaded component module.
-     *
-     * \todo provide a way to add traits to known components here to avoid loading the .so-s
-     * for listComponents
-     */
-    struct ComponentModule : public C2ComponentFactory,
-            public std::enable_shared_from_this<ComponentModule> {
-        virtual c2_status_t createComponent(
-                c2_node_id_t id, std::shared_ptr<C2Component> *component,
-                ComponentDeleter deleter = std::default_delete<C2Component>()) override;
-        virtual c2_status_t createInterface(
-                c2_node_id_t id, std::shared_ptr<C2ComponentInterface> *interface,
-                InterfaceDeleter deleter = std::default_delete<C2ComponentInterface>()) override;
-
-        /**
-         * \returns the traits of the component in this module.
-         */
-        std::shared_ptr<const C2Component::Traits> getTraits();
-
-        /**
-         * Creates an uninitialized component module.
-         *
-         * \param name[in]  component name.
-         *
-         * \note Only used by ComponentLoader.
-         */
-        ComponentModule()
-            : mInit(C2_NO_INIT),
-              mLibHandle(nullptr),
-              createFactory(nullptr),
-              destroyFactory(nullptr),
-              mComponentFactory(nullptr) {
-        }
-
-        /**
-         * Initializes a component module with a given library path. Must be called exactly once.
-         *
-         * \note Only used by ComponentLoader.
-         *
-         * \param libPath[in] library path (or name)
-         *
-         * \retval C2_OK        the component module has been successfully loaded
-         * \retval C2_NO_MEMORY not enough memory to loading the component module
-         * \retval C2_NOT_FOUND could not locate the component module
-         * \retval C2_CORRUPTED the component module could not be loaded (unexpected)
-         * \retval C2_REFUSED   permission denied to load the component module (unexpected)
-         * \retval C2_TIMED_OUT could not load the module within the time limit (unexpected)
-         */
-        c2_status_t init(std::string libPath);
-
-        virtual ~ComponentModule() override;
-
-    protected:
-        std::recursive_mutex mLock; ///< lock protecting mTraits
-        std::shared_ptr<C2Component::Traits> mTraits; ///< cached component traits
-
-        c2_status_t mInit; ///< initialization result
-
-        void *mLibHandle; ///< loaded library handle
-        C2ComponentFactory::CreateCodec2FactoryFunc createFactory; ///< loaded create function
-        C2ComponentFactory::DestroyCodec2FactoryFunc destroyFactory; ///< loaded destroy function
-        C2ComponentFactory *mComponentFactory; ///< loaded/created component factory
-    };
-
-    /**
-     * An object encapsulating a loadable component module.
-     *
-     * \todo make this also work for enumerations
-     */
-    struct ComponentLoader {
-        /**
-         * Load the component module.
-         *
-         * This method simply returns the component module if it is already currently loaded, or
-         * attempts to load it if it is not.
-         *
-         * \param module[out] pointer to the shared pointer where the loaded module shall be stored.
-         *                    This will be nullptr on error.
-         *
-         * \retval C2_OK        the component module has been successfully loaded
-         * \retval C2_NO_MEMORY not enough memory to loading the component module
-         * \retval C2_NOT_FOUND could not locate the component module
-         * \retval C2_CORRUPTED the component module could not be loaded
-         * \retval C2_REFUSED   permission denied to load the component module
-         */
-        c2_status_t fetchModule(std::shared_ptr<ComponentModule> *module) {
-            c2_status_t res = C2_OK;
-            std::lock_guard<std::mutex> lock(mMutex);
-            std::shared_ptr<ComponentModule> localModule = mModule.lock();
-            if (localModule == nullptr) {
-                localModule = std::make_shared<ComponentModule>();
-                res = localModule->init(mLibPath);
-                if (res == C2_OK) {
-                    mModule = localModule;
-                }
-            }
-            *module = localModule;
-            return res;
-        }
-
-        /**
-         * Creates a component loader for a specific library path (or name).
-         */
-        ComponentLoader(std::string libPath)
-            : mLibPath(libPath) {}
-
-    private:
-        std::mutex mMutex; ///< mutex guarding the module
-        std::weak_ptr<ComponentModule> mModule; ///< weak reference to the loaded module
-        std::string mLibPath; ///< library path (or name)
-    };
-
-    /**
-     * Retrieves the component loader for a component.
-     *
-     * \return a non-ref-holding pointer to the component loader.
-     *
-     * \retval C2_OK        the component loader has been successfully retrieved
-     * \retval C2_NO_MEMORY not enough memory to locate the component loader
-     * \retval C2_NOT_FOUND could not locate the component to be loaded
-     * \retval C2_CORRUPTED the component loader could not be identified due to some modules being
-     *                      corrupted (this can happen if the name does not refer to an already
-     *                      identified component but some components could not be loaded due to
-     *                      bad library)
-     * \retval C2_REFUSED   permission denied to find the component loader for the named component
-     *                      (this can happen if the name does not refer to an already identified
-     *                      component but some components could not be loaded due to lack of
-     *                      permissions)
-     */
-    c2_status_t findComponent(C2String name, ComponentLoader **loader);
-
-    std::map<C2String, ComponentLoader> mComponents; ///< list of components
-};
-
-c2_status_t C2PlatformComponentStore::ComponentModule::init(std::string libPath) {
-    ALOGV("in %s", __func__);
-    ALOGV("loading dll");
-    mLibHandle = dlopen(libPath.c_str(), RTLD_NOW|RTLD_NODELETE);
-    if (mLibHandle == nullptr) {
-        // could be access/symbol or simply not being there
-        ALOGD("could not dlopen %s: %s", libPath.c_str(), dlerror());
-        mInit = C2_CORRUPTED;
-    } else {
-        createFactory =
-            (C2ComponentFactory::CreateCodec2FactoryFunc)dlsym(mLibHandle, "CreateCodec2Factory");
-        destroyFactory =
-            (C2ComponentFactory::DestroyCodec2FactoryFunc)dlsym(mLibHandle, "DestroyCodec2Factory");
-
-        mComponentFactory = createFactory();
-        if (mComponentFactory == nullptr) {
-            ALOGD("could not create factory in %s", libPath.c_str());
-            mInit = C2_NO_MEMORY;
-        } else {
-            mInit = C2_OK;
-        }
-    }
-    return mInit;
-}
-
-C2PlatformComponentStore::ComponentModule::~ComponentModule() {
-    ALOGV("in %s", __func__);
-    if (destroyFactory && mComponentFactory) {
-        destroyFactory(mComponentFactory);
-    }
-    if (mLibHandle) {
-        ALOGV("unloading dll");
-        dlclose(mLibHandle);
-    }
-}
-
-c2_status_t C2PlatformComponentStore::ComponentModule::createInterface(
-        c2_node_id_t id, std::shared_ptr<C2ComponentInterface> *interface,
-        std::function<void(::C2ComponentInterface*)> deleter) {
-    interface->reset();
-    if (mInit != C2_OK) {
-        return mInit;
-    }
-    std::shared_ptr<ComponentModule> module = shared_from_this();
-    c2_status_t res = mComponentFactory->createInterface(
-            id, interface, [module, deleter](C2ComponentInterface *p) mutable {
-                // capture module so that we ensure we still have it while deleting interface
-                deleter(p); // delete interface first
-                module.reset(); // remove module ref (not technically needed)
-    });
-    return res;
-}
-
-c2_status_t C2PlatformComponentStore::ComponentModule::createComponent(
-        c2_node_id_t id, std::shared_ptr<C2Component> *component,
-        std::function<void(::C2Component*)> deleter) {
-    component->reset();
-    if (mInit != C2_OK) {
-        return mInit;
-    }
-    std::shared_ptr<ComponentModule> module = shared_from_this();
-    c2_status_t res = mComponentFactory->createComponent(
-            id, component, [module, deleter](C2Component *p) mutable {
-                // capture module so that we ensure we still have it while deleting component
-                deleter(p); // delete component first
-                module.reset(); // remove module ref (not technically needed)
-    });
-    return res;
-}
-
-std::shared_ptr<const C2Component::Traits> C2PlatformComponentStore::ComponentModule::getTraits() {
-    std::unique_lock<std::recursive_mutex> lock(mLock);
-    if (!mTraits) {
-        std::shared_ptr<C2ComponentInterface> intf;
-        c2_status_t res = createInterface(0, &intf);
-        if (res != C2_OK) {
-            ALOGD("failed to create interface: %d", res);
-            return nullptr;
-        }
-
-        std::shared_ptr<C2Component::Traits> traits(new (std::nothrow) C2Component::Traits);
-        if (traits) {
-            traits->name = intf->getName();
-            // TODO: get this from interface properly.
-            bool encoder = (traits->name.find("encoder") != std::string::npos);
-            uint32_t mediaTypeIndex = encoder ? C2PortMimeConfig::output::PARAM_TYPE
-                    : C2PortMimeConfig::input::PARAM_TYPE;
-            std::vector<std::unique_ptr<C2Param>> params;
-            res = intf->query_vb({}, { mediaTypeIndex }, C2_MAY_BLOCK, &params);
-            if (res != C2_OK) {
-                ALOGD("failed to query interface: %d", res);
-                return nullptr;
-            }
-            if (params.size() != 1u) {
-                ALOGD("failed to query interface: unexpected vector size: %zu", params.size());
-                return nullptr;
-            }
-            C2PortMimeConfig *mediaTypeConfig = (C2PortMimeConfig *)(params[0].get());
-            if (mediaTypeConfig == nullptr) {
-                ALOGD("failed to query media type");
-                return nullptr;
-            }
-            traits->mediaType = mediaTypeConfig->m.value;
-            // TODO: get this properly.
-            traits->rank = 0x200;
-        }
-
-        mTraits = traits;
-    }
-    return mTraits;
-}
-
-C2PlatformComponentStore::C2PlatformComponentStore() {
-    // TODO: move this also into a .so so it can be updated
-    mComponents.emplace("c2.google.avc.decoder", "libstagefright_soft_c2avcdec.so");
-    mComponents.emplace("c2.google.avc.encoder", "libstagefright_soft_c2avcenc.so");
-    mComponents.emplace("c2.google.aac.decoder", "libstagefright_soft_c2aacdec.so");
-    mComponents.emplace("c2.google.aac.encoder", "libstagefright_soft_c2aacenc.so");
-    mComponents.emplace("c2.google.amrnb.decoder", "libstagefright_soft_c2amrnbdec.so");
-    mComponents.emplace("c2.google.amrnb.encoder", "libstagefright_soft_c2amrnbenc.so");
-    mComponents.emplace("c2.google.amrwb.decoder", "libstagefright_soft_c2amrwbdec.so");
-    mComponents.emplace("c2.google.amrwb.encoder", "libstagefright_soft_c2amrwbenc.so");
-    mComponents.emplace("c2.google.hevc.decoder", "libstagefright_soft_c2hevcdec.so");
-    mComponents.emplace("c2.google.g711.alaw.decoder", "libstagefright_soft_c2g711alawdec.so");
-    mComponents.emplace("c2.google.g711.mlaw.decoder", "libstagefright_soft_c2g711mlawdec.so");
-    mComponents.emplace("c2.google.mpeg2.decoder", "libstagefright_soft_c2mpeg2dec.so");
-    mComponents.emplace("c2.google.h263.decoder", "libstagefright_soft_c2h263dec.so");
-    mComponents.emplace("c2.google.h263.encoder", "libstagefright_soft_c2h263enc.so");
-    mComponents.emplace("c2.google.mpeg4.decoder", "libstagefright_soft_c2mpeg4dec.so");
-    mComponents.emplace("c2.google.mpeg4.encoder", "libstagefright_soft_c2mpeg4enc.so");
-    mComponents.emplace("c2.google.mp3.decoder", "libstagefright_soft_c2mp3dec.so");
-    mComponents.emplace("c2.google.vorbis.decoder", "libstagefright_soft_c2vorbisdec.so");
-    mComponents.emplace("c2.google.opus.decoder", "libstagefright_soft_c2opusdec.so");
-    mComponents.emplace("c2.google.vp8.decoder", "libstagefright_soft_c2vp8dec.so");
-    mComponents.emplace("c2.google.vp9.decoder", "libstagefright_soft_c2vp9dec.so");
-    mComponents.emplace("c2.google.vp8.encoder", "libstagefright_soft_c2vp8enc.so");
-    mComponents.emplace("c2.google.vp9.encoder", "libstagefright_soft_c2vp9enc.so");
-    mComponents.emplace("c2.google.raw.decoder", "libstagefright_soft_c2rawdec.so");
-    mComponents.emplace("c2.google.flac.decoder", "libstagefright_soft_c2flacdec.so");
-    mComponents.emplace("c2.google.flac.encoder", "libstagefright_soft_c2flacenc.so");
-    mComponents.emplace("c2.google.gsm.decoder", "libstagefright_soft_c2gsmdec.so");
-}
-
-c2_status_t C2PlatformComponentStore::copyBuffer(
-        std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) {
-    (void)src;
-    (void)dst;
-    return C2_OMITTED;
-}
-
-c2_status_t C2PlatformComponentStore::query_sm(
-        const std::vector<C2Param*> &stackParams,
-        const std::vector<C2Param::Index> &heapParamIndices,
-        std::vector<std::unique_ptr<C2Param>> *const heapParams) const {
-    // there are no supported configs
-    (void)heapParams;
-    return stackParams.empty() && heapParamIndices.empty() ? C2_OK : C2_BAD_INDEX;
-}
-
-c2_status_t C2PlatformComponentStore::config_sm(
-        const std::vector<C2Param*> &params,
-        std::vector<std::unique_ptr<C2SettingResult>> *const failures) {
-    // there are no supported configs
-    (void)failures;
-    return params.empty() ? C2_OK : C2_BAD_INDEX;
-}
-
-std::vector<std::shared_ptr<const C2Component::Traits>> C2PlatformComponentStore::listComponents() {
-    // This method SHALL return within 500ms.
-    std::vector<std::shared_ptr<const C2Component::Traits>> list;
-    for (auto &it : mComponents) {
-        ComponentLoader &loader = it.second;
-        std::shared_ptr<ComponentModule> module;
-        c2_status_t res = loader.fetchModule(&module);
-        if (res == C2_OK) {
-            std::shared_ptr<const C2Component::Traits> traits = module->getTraits();
-            if (traits) {
-                list.push_back(traits);
-            }
-        }
-    }
-    return list;
-}
-
-c2_status_t C2PlatformComponentStore::findComponent(C2String name, ComponentLoader **loader) {
-    *loader = nullptr;
-    auto pos = mComponents.find(name);
-    // TODO: check aliases
-    if (pos == mComponents.end()) {
-        return C2_NOT_FOUND;
-    }
-    *loader = &pos->second;
-    return C2_OK;
-}
-
-c2_status_t C2PlatformComponentStore::createComponent(
-        C2String name, std::shared_ptr<C2Component> *const component) {
-    // This method SHALL return within 100ms.
-    component->reset();
-    ComponentLoader *loader;
-    c2_status_t res = findComponent(name, &loader);
-    if (res == C2_OK) {
-        std::shared_ptr<ComponentModule> module;
-        res = loader->fetchModule(&module);
-        if (res == C2_OK) {
-            // TODO: get a unique node ID
-            res = module->createComponent(0, component);
-        }
-    }
-    return res;
-}
-
-c2_status_t C2PlatformComponentStore::createInterface(
-        C2String name, std::shared_ptr<C2ComponentInterface> *const interface) {
-    // This method SHALL return within 100ms.
-    interface->reset();
-    ComponentLoader *loader;
-    c2_status_t res = findComponent(name, &loader);
-    if (res == C2_OK) {
-        std::shared_ptr<ComponentModule> module;
-        res = loader->fetchModule(&module);
-        if (res == C2_OK) {
-            // TODO: get a unique node ID
-            res = module->createInterface(0, interface);
-        }
-    }
-    return res;
-}
-
-c2_status_t C2PlatformComponentStore::querySupportedParams_nb(
-        std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
-    // there are no supported config params
-    (void)params;
-    return C2_OK;
-}
-
-c2_status_t C2PlatformComponentStore::querySupportedValues_sm(
-        std::vector<C2FieldSupportedValuesQuery> &fields) const {
-    // there are no supported config params
-    return fields.empty() ? C2_OK : C2_BAD_INDEX;
-}
-
-C2String C2PlatformComponentStore::getName() const {
-    return "android.componentStore.platform";
-}
-
-std::shared_ptr<C2ParamReflector> C2PlatformComponentStore::getParamReflector() const {
-    // TODO
-    return nullptr;
-}
-
-std::shared_ptr<C2ComponentStore> GetCodec2PlatformComponentStore() {
-    static std::mutex mutex;
-    static std::weak_ptr<C2ComponentStore> platformStore;
-    std::lock_guard<std::mutex> lock(mutex);
-    std::shared_ptr<C2ComponentStore> store = platformStore.lock();
-    if (store == nullptr) {
-        store = std::make_shared<C2PlatformComponentStore>();
-        platformStore = store;
-    }
-    return store;
-}
-
-} // namespace android
diff --git a/media/libstagefright/codec2/vndk/bufferpool/Accessor.cpp b/media/libstagefright/codec2/vndk/bufferpool/Accessor.cpp
deleted file mode 100644
index 1b1b9be..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/Accessor.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2018 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 "Accessor.h"
-#include "AccessorImpl.h"
-#include "Connection.h"
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V1_0 {
-namespace implementation {
-
-// Methods from ::android::hardware::media::bufferpool::V1_0::IAccessor follow.
-Return<void> Accessor::connect(connect_cb _hidl_cb) {
-    sp<Connection> connection;
-    ConnectionId connectionId;
-    const QueueDescriptor* fmqDesc;
-
-    ResultStatus status = connect(&connection, &connectionId, &fmqDesc);
-    if (status == ResultStatus::OK) {
-        _hidl_cb(status, connection, connectionId, *fmqDesc);
-    } else {
-        _hidl_cb(status, nullptr, -1LL,
-                 android::hardware::MQDescriptorSync<BufferStatusMessage>(
-                         std::vector<android::hardware::GrantorDescriptor>(),
-                         nullptr /* nhandle */, 0 /* size */));
-    }
-    return Void();
-}
-
-Accessor::Accessor(const std::shared_ptr<BufferPoolAllocator> &allocator)
-    : mImpl(new Impl(allocator)) {}
-
-Accessor::~Accessor() {
-}
-
-bool Accessor::isValid() {
-    return (bool)mImpl;
-}
-
-ResultStatus Accessor::allocate(
-        ConnectionId connectionId,
-        const std::vector<uint8_t> &params,
-        BufferId *bufferId, const native_handle_t** handle) {
-    if (mImpl) {
-        return mImpl->allocate(connectionId, params, bufferId, handle);
-    }
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-ResultStatus Accessor::fetch(
-        ConnectionId connectionId, TransactionId transactionId,
-        BufferId bufferId, const native_handle_t** handle) {
-    if (mImpl) {
-        return mImpl->fetch(connectionId, transactionId, bufferId, handle);
-    }
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-ResultStatus Accessor::connect(
-        sp<Connection> *connection, ConnectionId *pConnectionId,
-        const QueueDescriptor** fmqDescPtr) {
-    if (mImpl) {
-        return mImpl->connect(this, connection, pConnectionId, fmqDescPtr);
-    }
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-ResultStatus Accessor::close(ConnectionId connectionId) {
-    if (mImpl) {
-        return mImpl->close(connectionId);
-    }
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-//IAccessor* HIDL_FETCH_IAccessor(const char* /* name */) {
-//    return new Accessor();
-//}
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
diff --git a/media/libstagefright/codec2/vndk/bufferpool/Accessor.h b/media/libstagefright/codec2/vndk/bufferpool/Accessor.h
deleted file mode 100644
index ad42245..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/Accessor.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2018 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_HARDWARE_MEDIA_BUFFERPOOL_V1_0_ACCESSOR_H
-#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_ACCESSOR_H
-
-#include <android/hardware/media/bufferpool/1.0/IAccessor.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-#include <BufferPoolTypes.h>
-#include "BufferStatus.h"
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
-
-struct Connection;
-
-/**
- * A buffer pool accessor which enables a buffer pool to communicate with buffer
- * pool clients. 1:1 correspondense holds between a buffer pool and an accessor.
- */
-struct Accessor : public IAccessor {
-    // Methods from ::android::hardware::media::bufferpool::V1_0::IAccessor follow.
-    Return<void> connect(connect_cb _hidl_cb) override;
-
-    /**
-     * Creates a buffer pool accessor which uses the specified allocator.
-     *
-     * @param allocator buffer allocator.
-     */
-    explicit Accessor(const std::shared_ptr<BufferPoolAllocator> &allocator);
-
-    /** Destructs a buffer pool accessor. */
-    ~Accessor();
-
-    /** Returns whether the accessor is valid. */
-    bool isValid();
-
-    /** Allocates a buffer form a buffer pool.
-     *
-     * @param connectionId  the connection id of the client.
-     * @param params        the allocation parameters.
-     * @param bufferId      the id of the allocated buffer.
-     * @param handle        the native handle of the allocated buffer.
-     *
-     * @return OK when a buffer is successfully allocated.
-     *         NO_MEMORY when there is no memory.
-     *         CRITICAL_ERROR otherwise.
-     */
-    ResultStatus allocate(
-            ConnectionId connectionId,
-            const std::vector<uint8_t>& params,
-            BufferId *bufferId,
-            const native_handle_t** handle);
-
-    /**
-     * Fetches a buffer for the specified transaction.
-     *
-     * @param connectionId  the id of receiving connection(client).
-     * @param transactionId the id of the transfer transaction.
-     * @param bufferId      the id of the buffer to be fetched.
-     * @param handle        the native handle of the fetched buffer.
-     *
-     * @return OK when a buffer is successfully fetched.
-     *         NO_MEMORY when there is no memory.
-     *         CRITICAL_ERROR otherwise.
-     */
-    ResultStatus fetch(
-            ConnectionId connectionId,
-            TransactionId transactionId,
-            BufferId bufferId,
-            const native_handle_t** handle);
-
-    /**
-     * Makes a connection to the buffer pool. The buffer pool client uses the
-     * created connection in order to communicate with the buffer pool. An
-     * FMQ for buffer status message is also created for the client.
-     *
-     * @param connection    created connection
-     * @param pConnectionId the id of the created connection
-     * @param fmqDescPtr    FMQ descriptor for shared buffer status message
-     *                      queue between a buffer pool and the client.
-     *
-     * @return OK when a connection is successfully made.
-     *         NO_MEMORY when there is no memory.
-     *         CRITICAL_ERROR otherwise.
-     */
-    ResultStatus connect(
-            sp<Connection> *connection, ConnectionId *pConnectionId,
-            const QueueDescriptor** fmqDescPtr);
-
-    /**
-     * Closes the specified connection to the client.
-     *
-     * @param connectionId  the id of the connection.
-     *
-     * @return OK when the connection is closed.
-     *         CRITICAL_ERROR otherwise.
-     */
-    ResultStatus close(ConnectionId connectionId);
-
-private:
-    class Impl;
-    std::unique_ptr<Impl> mImpl;
-};
-
-// FIXME: most likely delete, this is only for passthrough implementations
-// extern "C" IAccessor* HIDL_FETCH_IAccessor(const char* name);
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_ACCESSOR_H
diff --git a/media/libstagefright/codec2/vndk/bufferpool/AccessorImpl.cpp b/media/libstagefright/codec2/vndk/bufferpool/AccessorImpl.cpp
deleted file mode 100644
index 32d76c0..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/AccessorImpl.cpp
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * Copyright (C) 2018 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_TAG "bufferpool"
-//#define LOG_NDEBUG 0
-
-#include <inttypes.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-#include <utils/Log.h>
-#include "AccessorImpl.h"
-#include "Connection.h"
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V1_0 {
-namespace implementation {
-
-// Buffer structure in bufferpool process
-struct InternalBuffer {
-    BufferId mId;
-    size_t mOwnerCount;
-    size_t mTransactionCount;
-    const std::shared_ptr<BufferPoolAllocation> mAllocation;
-    const std::vector<uint8_t> mConfig;
-
-    InternalBuffer(
-            BufferId id,
-            const std::shared_ptr<BufferPoolAllocation> &alloc,
-            const std::vector<uint8_t> &allocConfig)
-            : mId(id), mOwnerCount(0), mTransactionCount(0),
-            mAllocation(alloc), mConfig(allocConfig) {}
-
-    const native_handle_t *handle() {
-        return mAllocation->handle();
-    }
-};
-
-struct TransactionStatus {
-    TransactionId mId;
-    BufferId mBufferId;
-    ConnectionId mSender;
-    ConnectionId mReceiver;
-    BufferStatus mStatus;
-    int64_t mTimestampUs;
-    bool mSenderValidated;
-
-    TransactionStatus(const BufferStatusMessage &message, int64_t timestampUs) {
-        mId = message.transactionId;
-        mBufferId = message.bufferId;
-        mStatus = message.newStatus;
-        mTimestampUs = timestampUs;
-        if (mStatus == BufferStatus::TRANSFER_TO) {
-            mSender = message.connectionId;
-            mReceiver = message.targetConnectionId;
-            mSenderValidated = true;
-        } else {
-            mSender = -1LL;
-            mReceiver = message.connectionId;
-            mSenderValidated = false;
-        }
-    }
-};
-
-// Helper template methods for handling map of set.
-template<class T, class U>
-bool insert(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
-    auto iter = mapOfSet->find(key);
-    if (iter == mapOfSet->end()) {
-        std::set<U> valueSet{value};
-        mapOfSet->insert(std::make_pair(key, valueSet));
-        return true;
-    } else if (iter->second.find(value)  == iter->second.end()) {
-        iter->second.insert(value);
-        return true;
-    }
-    return false;
-}
-
-template<class T, class U>
-bool erase(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
-    bool ret = false;
-    auto iter = mapOfSet->find(key);
-    if (iter != mapOfSet->end()) {
-        if (iter->second.erase(value) > 0) {
-            ret = true;
-        }
-        if (iter->second.size() == 0) {
-            mapOfSet->erase(iter);
-        }
-    }
-    return ret;
-}
-
-template<class T, class U>
-bool contains(std::map<T, std::set<U>> *mapOfSet, T key, U value) {
-    auto iter = mapOfSet->find(key);
-    if (iter != mapOfSet->end()) {
-        auto setIter = iter->second.find(value);
-        return setIter != iter->second.end();
-    }
-    return false;
-}
-
-
-int32_t Accessor::Impl::sPid = getpid();
-uint32_t Accessor::Impl::sSeqId = time(NULL);
-
-Accessor::Impl::Impl(
-        const std::shared_ptr<BufferPoolAllocator> &allocator)
-        : mAllocator(allocator) {}
-
-Accessor::Impl::~Impl() {
-}
-
-ResultStatus Accessor::Impl::connect(
-        const sp<Accessor> &accessor, sp<Connection> *connection,
-        ConnectionId *pConnectionId, const QueueDescriptor** fmqDescPtr) {
-    sp<Connection> newConnection = new Connection();
-    ResultStatus status = ResultStatus::CRITICAL_ERROR;
-    if (newConnection) {
-        std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
-        ConnectionId id = (int64_t)sPid << 32 | sSeqId;
-        status = mBufferPool.mObserver.open(id, fmqDescPtr);
-        if (status == ResultStatus::OK) {
-            newConnection->initialize(accessor, id);
-            *connection = newConnection;
-            *pConnectionId = id;
-            ++sSeqId;
-        }
-    }
-    return status;
-}
-
-ResultStatus Accessor::Impl::close(ConnectionId connectionId) {
-    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
-    mBufferPool.processStatusMessages();
-    mBufferPool.handleClose(connectionId);
-    mBufferPool.mObserver.close(connectionId);
-    return ResultStatus::OK;
-}
-
-ResultStatus Accessor::Impl::allocate(
-        ConnectionId connectionId, const std::vector<uint8_t>& params,
-        BufferId *bufferId, const native_handle_t** handle) {
-    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
-    mBufferPool.processStatusMessages();
-    ResultStatus status = ResultStatus::OK;
-    if (!mBufferPool.getFreeBuffer(mAllocator, params, bufferId, handle)) {
-        status = mBufferPool.getNewBuffer(mAllocator, params, bufferId, handle);
-        ALOGV("create a buffer %d : %u %p",
-              status == ResultStatus::OK, *bufferId, *handle);
-    }
-    if (status == ResultStatus::OK) {
-        // TODO: handle ownBuffer failure
-        mBufferPool.handleOwnBuffer(connectionId, *bufferId);
-    }
-    return status;
-}
-
-ResultStatus Accessor::Impl::fetch(
-        ConnectionId connectionId, TransactionId transactionId,
-        BufferId bufferId, const native_handle_t** handle) {
-    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
-    mBufferPool.processStatusMessages();
-    auto found = mBufferPool.mTransactions.find(transactionId);
-    if (found != mBufferPool.mTransactions.end() &&
-            contains(&mBufferPool.mPendingTransactions,
-                     connectionId, transactionId)) {
-        if (found->second->mSenderValidated &&
-                found->second->mStatus == BufferStatus::TRANSFER_FROM &&
-                found->second->mBufferId == bufferId) {
-            found->second->mStatus = BufferStatus::TRANSFER_FETCH;
-            auto bufferIt = mBufferPool.mBuffers.find(bufferId);
-            if (bufferIt != mBufferPool.mBuffers.end()) {
-                *handle = bufferIt->second->handle();
-                return ResultStatus::OK;
-            }
-        }
-    }
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-void Accessor::Impl::sync() {
-    // TODO: periodic jobs
-    // transaction timeout, buffer cacheing TTL handling
-    std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
-    mBufferPool.processStatusMessages();
-}
-
-Accessor::Impl::Impl::BufferPool::BufferPool()
-        : mTimestampUs(getTimestampNow()), mSeq(0) {}
-
-bool Accessor::Impl::BufferPool::handleOwnBuffer(
-        ConnectionId connectionId, BufferId bufferId) {
-
-    bool added = insert(&mUsingBuffers, connectionId, bufferId);
-    if (added) {
-        auto iter = mBuffers.find(bufferId);
-        iter->second->mOwnerCount++;
-    }
-    insert(&mUsingConnections, bufferId, connectionId);
-    return added;
-}
-
-bool Accessor::Impl::BufferPool::handleReleaseBuffer(
-        ConnectionId connectionId, BufferId bufferId) {
-    bool deleted = erase(&mUsingBuffers, connectionId, bufferId);
-    if (deleted) {
-        auto iter = mBuffers.find(bufferId);
-        iter->second->mOwnerCount--;
-        if (iter->second->mOwnerCount == 0 &&
-                iter->second->mTransactionCount == 0) {
-            mFreeBuffers.insert(bufferId);
-        }
-    }
-    erase(&mUsingConnections, bufferId, connectionId);
-    ALOGV("release buffer %u : %d", bufferId, deleted);
-    return deleted;
-}
-
-bool Accessor::Impl::BufferPool::handleTransferTo(const BufferStatusMessage &message) {
-    auto completed = mCompletedTransactions.find(
-            message.transactionId);
-    if (completed != mCompletedTransactions.end()) {
-        // already completed
-        mCompletedTransactions.erase(completed);
-        return true;
-    }
-    // the buffer should exist and be owned.
-    auto bufferIter = mBuffers.find(message.bufferId);
-    if (bufferIter == mBuffers.end() ||
-            !contains(&mUsingBuffers, message.connectionId, message.bufferId)) {
-        return false;
-    }
-    auto found = mTransactions.find(message.transactionId);
-    if (found != mTransactions.end()) {
-        // transfer_from was received earlier.
-        found->second->mSender = message.connectionId;
-        found->second->mSenderValidated = true;
-        return true;
-    }
-    // TODO: verify there is target connection Id
-    mTransactions.insert(std::make_pair(
-            message.transactionId,
-            std::make_unique<TransactionStatus>(message, mTimestampUs)));
-    insert(&mPendingTransactions, message.targetConnectionId,
-           message.transactionId);
-    bufferIter->second->mTransactionCount++;
-    return true;
-}
-
-bool Accessor::Impl::BufferPool::handleTransferFrom(const BufferStatusMessage &message) {
-    auto found = mTransactions.find(message.transactionId);
-    if (found == mTransactions.end()) {
-        // TODO: is it feasible to check ownership here?
-        mTransactions.insert(std::make_pair(
-                message.transactionId,
-                std::make_unique<TransactionStatus>(message, mTimestampUs)));
-        insert(&mPendingTransactions, message.connectionId,
-               message.transactionId);
-        auto bufferIter = mBuffers.find(message.bufferId);
-        bufferIter->second->mTransactionCount++;
-    } else {
-        if (message.connectionId == found->second->mReceiver) {
-            found->second->mStatus = BufferStatus::TRANSFER_FROM;
-        }
-    }
-    return true;
-}
-
-bool Accessor::Impl::BufferPool::handleTransferResult(const BufferStatusMessage &message) {
-    auto found = mTransactions.find(message.transactionId);
-    if (found != mTransactions.end()) {
-        bool deleted = erase(&mPendingTransactions, message.connectionId,
-                             message.transactionId);
-        if (deleted) {
-            if (!found->second->mSenderValidated) {
-                mCompletedTransactions.insert(message.transactionId);
-            }
-            auto bufferIter = mBuffers.find(message.bufferId);
-            if (message.newStatus == BufferStatus::TRANSFER_OK) {
-                handleOwnBuffer(message.connectionId, message.bufferId);
-            }
-            bufferIter->second->mTransactionCount--;
-            if (bufferIter->second->mOwnerCount == 0
-                && bufferIter->second->mTransactionCount == 0) {
-                mFreeBuffers.insert(message.bufferId);
-            }
-        }
-        ALOGV("transfer finished %" PRIu64 " %u - %d", message.transactionId,
-              message.bufferId, deleted);
-        return deleted;
-    }
-    ALOGV("transfer not found %" PRIu64 " %u", message.transactionId,
-          message.bufferId);
-    return false;
-}
-
-void Accessor::Impl::BufferPool::processStatusMessages() {
-    std::vector<BufferStatusMessage> messages;
-    mObserver.getBufferStatusChanges(messages);
-    mTimestampUs = getTimestampNow();
-    for (BufferStatusMessage& message: messages) {
-        bool ret = false;
-        switch (message.newStatus) {
-            case BufferStatus::NOT_USED:
-                ret = handleReleaseBuffer(
-                        message.connectionId, message.bufferId);
-                break;
-            case BufferStatus::USED:
-                // not happening
-                break;
-            case BufferStatus::TRANSFER_TO:
-                ret = handleTransferTo(message);
-                break;
-            case BufferStatus::TRANSFER_FROM:
-                ret = handleTransferFrom(message);
-                break;
-            case BufferStatus::TRANSFER_TIMEOUT:
-                // TODO
-                break;
-            case BufferStatus::TRANSFER_LOST:
-                // TODO
-                break;
-            case BufferStatus::TRANSFER_FETCH:
-                // not happening
-                break;
-            case BufferStatus::TRANSFER_OK:
-            case BufferStatus::TRANSFER_ERROR:
-                ret = handleTransferResult(message);
-                break;
-        }
-        if (ret == false) {
-            ALOGW("buffer status message processing failure - message : %d "
-                  "connection : %" PRId64,
-                  message.newStatus, message.connectionId);
-        }
-    }
-    messages.clear();
-}
-
-bool Accessor::Impl::BufferPool::handleClose(ConnectionId connectionId) {
-    // Cleaning buffers
-    auto buffers = mUsingBuffers.find(connectionId);
-    if (buffers != mUsingBuffers.end()) {
-        for (const BufferId& bufferId : buffers->second) {
-            bool deleted = erase(&mUsingConnections, bufferId, connectionId);
-            if (deleted) {
-                auto bufferIter = mBuffers.find(bufferId);
-                bufferIter->second->mOwnerCount--;
-                if (bufferIter->second->mOwnerCount == 0 &&
-                        bufferIter->second->mTransactionCount == 0) {
-                    // TODO: handle freebuffer insert fail
-                    mFreeBuffers.insert(bufferId);
-                }
-            }
-        }
-        mUsingBuffers.erase(buffers);
-    }
-
-    // Cleaning transactions
-    auto pending = mPendingTransactions.find(connectionId);
-    if (pending != mPendingTransactions.end()) {
-        for (const TransactionId& transactionId : pending->second) {
-            auto iter = mTransactions.find(transactionId);
-            if (iter != mTransactions.end()) {
-                if (!iter->second->mSenderValidated) {
-                    mCompletedTransactions.insert(transactionId);
-                }
-                BufferId bufferId = iter->second->mBufferId;
-                auto bufferIter = mBuffers.find(bufferId);
-                bufferIter->second->mTransactionCount--;
-                if (bufferIter->second->mOwnerCount == 0 &&
-                    bufferIter->second->mTransactionCount == 0) {
-                    // TODO: handle freebuffer insert fail
-                    mFreeBuffers.insert(bufferId);
-                }
-                mTransactions.erase(iter);
-            }
-        }
-    }
-    return true;
-}
-
-bool Accessor::Impl::BufferPool::getFreeBuffer(
-        const std::shared_ptr<BufferPoolAllocator> &allocator,
-        const std::vector<uint8_t> &params, BufferId *pId,
-        const native_handle_t** handle) {
-    auto bufferIt = mFreeBuffers.begin();
-    for (;bufferIt != mFreeBuffers.end(); ++bufferIt) {
-        BufferId bufferId = *bufferIt;
-        if (allocator->compatible(params, mBuffers[bufferId]->mConfig)) {
-            break;
-        }
-    }
-    if (bufferIt != mFreeBuffers.end()) {
-        BufferId id = *bufferIt;
-        mFreeBuffers.erase(bufferIt);
-        *handle = mBuffers[id]->handle();
-        *pId = id;
-        ALOGV("recycle a buffer %u %p", id, *handle);
-        return true;
-    }
-    return false;
-}
-
-ResultStatus Accessor::Impl::BufferPool::getNewBuffer(
-        const std::shared_ptr<BufferPoolAllocator> &allocator,
-        const std::vector<uint8_t> &params, BufferId *pId,
-        const native_handle_t** handle) {
-    std::shared_ptr<BufferPoolAllocation> alloc;
-    ResultStatus status = allocator->allocate(params, &alloc);
-
-    if (status == ResultStatus::OK) {
-        BufferId bufferId = mSeq++;
-        std::unique_ptr<InternalBuffer> buffer =
-                std::make_unique<InternalBuffer>(
-                        bufferId, alloc, params);
-        if (buffer) {
-            auto res = mBuffers.insert(std::make_pair(
-                    bufferId, std::move(buffer)));
-            if (res.second) {
-                *handle = alloc->handle();
-                *pId = bufferId;
-                return ResultStatus::OK;
-            }
-        }
-        return ResultStatus::NO_MEMORY;
-    }
-    return status;
-}
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
diff --git a/media/libstagefright/codec2/vndk/bufferpool/AccessorImpl.h b/media/libstagefright/codec2/vndk/bufferpool/AccessorImpl.h
deleted file mode 100644
index 1260550..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/AccessorImpl.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2018 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_HARDWARE_MEDIA_BUFFERPOOL_V1_0_ACCESSORIMPL_H
-#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_ACCESSORIMPL_H
-
-#include <map>
-#include <set>
-#include "Accessor.h"
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V1_0 {
-namespace implementation {
-
-struct InternalBuffer;
-struct TransactionStatus;
-
-/**
- * An implementation of a buffer pool accessor(or a buffer pool implementation.) */
-class Accessor::Impl {
-public:
-    Impl(const std::shared_ptr<BufferPoolAllocator> &allocator);
-
-    ~Impl();
-
-    ResultStatus connect(
-            const sp<Accessor> &accessor, sp<Connection> *connection,
-            ConnectionId *pConnectionId, const QueueDescriptor** fmqDescPtr);
-
-    ResultStatus close(ConnectionId connectionId);
-
-    ResultStatus allocate(ConnectionId connectionId,
-                          const std::vector<uint8_t>& params,
-                          BufferId *bufferId,
-                          const native_handle_t** handle);
-
-    ResultStatus fetch(ConnectionId connectionId,
-                       TransactionId transactionId,
-                       BufferId bufferId,
-                       const native_handle_t** handle);
-
-    /** Processes pending buffer status messages */
-    void sync();
-
-private:
-    // ConnectionId = pid : (timestamp_created + seqId)
-    // in order to guarantee uniqueness for each connection
-    static uint32_t sSeqId;
-    static int32_t sPid;
-
-    const std::shared_ptr<BufferPoolAllocator> mAllocator;
-
-    /**
-     * Buffer pool implementation.
-     *
-     * Handles buffer status messages. Handles buffer allocation/recycling.
-     * Handles buffer transfer between buffer pool clients.
-     */
-    struct BufferPool {
-    private:
-        std::mutex mMutex;
-        int64_t mTimestampUs;
-        BufferId mSeq;
-        BufferStatusObserver mObserver;
-
-        std::map<ConnectionId, std::set<BufferId>> mUsingBuffers;
-        std::map<BufferId, std::set<ConnectionId>> mUsingConnections;
-
-        std::map<ConnectionId, std::set<TransactionId>> mPendingTransactions;
-        // Transactions completed before TRANSFER_TO message arrival.
-        // Fetch does not occur for the transactions.
-        // Only transaction id is kept for the transactions in short duration.
-        std::set<TransactionId> mCompletedTransactions;
-        // Currently active(pending) transations' status & information.
-        std::map<TransactionId, std::unique_ptr<TransactionStatus>>
-                mTransactions;
-
-        std::map<BufferId, std::unique_ptr<InternalBuffer>> mBuffers;
-        std::set<BufferId> mFreeBuffers;
-
-    public:
-        /** Creates a buffer pool. */
-        BufferPool();
-
-        /**
-         * Processes all pending buffer status messages, and returns the result.
-         * Each status message is handled by methods with 'handle' prefix.
-         */
-        void processStatusMessages();
-
-        /**
-         * Handles a buffer being owned by a connection.
-         *
-         * @param connectionId  the id of the buffer owning connection.
-         * @param bufferId      the id of the buffer.
-         *
-         * @return {@code true} when the buffer is owned,
-         *         {@code false} otherwise.
-         */
-        bool handleOwnBuffer(ConnectionId connectionId, BufferId bufferId);
-
-        /**
-         * Handles a buffer being released by a connection.
-         *
-         * @param connectionId  the id of the buffer owning connection.
-         * @param bufferId      the id of the buffer.
-         *
-         * @return {@code true} when the buffer ownership is released,
-         *         {@code false} otherwise.
-         */
-        bool handleReleaseBuffer(ConnectionId connectionId, BufferId bufferId);
-
-        /**
-         * Handles a transfer transaction start message from the sender.
-         *
-         * @param message   a buffer status message for the transaction.
-         *
-         * @result {@code true} when transfer_to message is acknowledged,
-         *         {@code false} otherwise.
-         */
-        bool handleTransferTo(const BufferStatusMessage &message);
-
-        /**
-         * Handles a transfer transaction being acked by the receiver.
-         *
-         * @param message   a buffer status message for the transaction.
-         *
-         * @result {@code true} when transfer_from message is acknowledged,
-         *         {@code false} otherwise.
-         */
-        bool handleTransferFrom(const BufferStatusMessage &message);
-
-        /**
-         * Handles a transfer transaction result message from the receiver.
-         *
-         * @param message   a buffer status message for the transaction.
-         *
-         * @result {@code true} when the exisitng transaction is finished,
-         *         {@code false} otherwise.
-         */
-        bool handleTransferResult(const BufferStatusMessage &message);
-
-        /**
-         * Handles a connection being closed, and returns the result. All the
-         * buffers and transactions owned by the connection will be cleaned up.
-         * The related FMQ will be cleaned up too.
-         *
-         * @param connectionId  the id of the connection.
-         *
-         * @result {@code true} when the connection existed,
-         *         {@code false} otherwise.
-         */
-        bool handleClose(ConnectionId connectionId);
-
-        /**
-         * Recycles a existing free buffer if it is possible.
-         *
-         * @param allocator the buffer allocator
-         * @param params    the allocation parameters.
-         * @param pId       the id of the recycled buffer.
-         * @param handle    the native handle of the recycled buffer.
-         *
-         * @return {@code true} when a buffer is recycled, {@code false}
-         *         otherwise.
-         */
-        bool getFreeBuffer(
-                const std::shared_ptr<BufferPoolAllocator> &allocator,
-                const std::vector<uint8_t> &params,
-                BufferId *pId, const native_handle_t **handle);
-
-        /**
-         * Creates a new buffer.
-         *
-         * @param allocator the buffer allocator
-         * @param params    the allocator parameters
-         * @param pId       the buffer id for the newly allocated buffer.
-         * @param handle    the native handle for the newly allocated buffer.
-         *
-         * @return OK when an allocation is successfully allocated.
-         *         NO_MEMORY when there is no memory.
-         *         CRITICAL_ERROR otherwise.
-         */
-        ResultStatus getNewBuffer(
-                const std::shared_ptr<BufferPoolAllocator> &allocator,
-                const std::vector<uint8_t> &params, BufferId *pId,
-                const native_handle_t **handle);
-
-        friend class Accessor::Impl;
-    } mBufferPool;
-};
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace ufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_ACCESSORIMPL_H
diff --git a/media/libstagefright/codec2/vndk/bufferpool/Android.bp b/media/libstagefright/codec2/vndk/bufferpool/Android.bp
deleted file mode 100644
index 1ea1f35..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/Android.bp
+++ /dev/null
@@ -1,30 +0,0 @@
-cc_library {
-    name: "libstagefright_bufferpool@1.0",
-    vendor_available: true,
-    vndk: {
-        enabled: true,
-    },
-    srcs: [
-        "Accessor.cpp",
-        "AccessorImpl.cpp",
-        "BufferPoolClient.cpp",
-        "BufferStatus.cpp",
-        "ClientManager.cpp",
-        "Connection.cpp",
-    ],
-    export_include_dirs: [
-        "include",
-    ],
-    include_dirs: [
-        "frameworks/av/media/libstagefright/codec2/vndk/bufferpool/include",
-    ],
-    shared_libs: [
-        "libcutils",
-        "libfmq",
-        "libhidlbase",
-        "libhidltransport",
-        "liblog",
-        "libutils",
-        "android.hardware.media.bufferpool@1.0",
-    ],
-}
diff --git a/media/libstagefright/codec2/vndk/bufferpool/BufferPoolClient.cpp b/media/libstagefright/codec2/vndk/bufferpool/BufferPoolClient.cpp
deleted file mode 100644
index dda8e39..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/BufferPoolClient.cpp
+++ /dev/null
@@ -1,574 +0,0 @@
-/*
- * Copyright (C) 2018 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_TAG "bufferpool"
-//#define LOG_NDEBUG 0
-
-#include <inttypes.h>
-#include <thread>
-#include <utils/Log.h>
-#include "BufferPoolClient.h"
-#include "Connection.h"
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V1_0 {
-namespace implementation {
-
-static constexpr int64_t kReceiveTimeoutUs = 5000; // 5ms
-static constexpr int kPostMaxRetry = 3;
-static constexpr int kCacheTtlUs = 500000; // TODO: tune
-
-class BufferPoolClient::Impl
-        : public std::enable_shared_from_this<BufferPoolClient::Impl> {
-public:
-    explicit Impl(const sp<Accessor> &accessor);
-
-    explicit Impl(const sp<IAccessor> &accessor);
-
-    bool isValid() {
-        return mValid;
-    }
-
-    ConnectionId getConnectionId() {
-        return mConnectionId;
-    }
-
-    sp<IAccessor> &getAccessor() {
-        return mAccessor;
-    }
-
-    ResultStatus allocate(const std::vector<uint8_t> &params,
-                         std::shared_ptr<_C2BlockPoolData> *buffer);
-
-    ResultStatus receive(
-            TransactionId transactionId, BufferId bufferId,
-            int64_t timestampUs, std::shared_ptr<_C2BlockPoolData> *buffer);
-
-    void postBufferRelease(BufferId bufferId);
-
-    bool postSend(
-            BufferId bufferId, ConnectionId receiver,
-            TransactionId *transactionId, int64_t *timestampUs);
-private:
-
-    bool postReceive(
-            BufferId bufferId, TransactionId transactionId,
-            int64_t timestampUs);
-
-    bool postReceiveResult(
-            BufferId bufferId, TransactionId transactionId, bool result);
-
-    bool syncReleased();
-
-    ResultStatus allocateBufferHandle(
-            const std::vector<uint8_t>& params, BufferId *bufferId,
-            native_handle_t **handle);
-
-    ResultStatus fetchBufferHandle(
-            TransactionId transactionId, BufferId bufferId,
-            native_handle_t **handle);
-
-
-    struct BlockPoolDataDtor;
-    struct ClientBuffer;
-
-    bool mLocal;
-    bool mValid;
-    sp<IAccessor> mAccessor;
-    sp<Connection> mLocalConnection;
-    sp<IConnection> mRemoteConnection;
-    uint32_t mSeqId;
-    ConnectionId mConnectionId;
-
-    // CachedBuffers
-    struct {
-        std::mutex mLock;
-        bool creating;
-        std::condition_variable mCreateCv;
-        std::map<BufferId, std::unique_ptr<ClientBuffer>> mBuffers;
-    } mCache;
-
-    // FMQ - release notifier
-    struct {
-        std::mutex mLock;
-        // TODO: use only one list?(using one list may dealy sending messages?)
-        std::list<BufferId> mReleasingIds;
-        std::list<BufferId> mReleasedIds;
-        std::unique_ptr<BufferStatusChannel> mStatusChannel;
-    } mReleasing;
-};
-
-struct BufferPoolClient::Impl::BlockPoolDataDtor {
-    BlockPoolDataDtor(const std::shared_ptr<BufferPoolClient::Impl> &impl)
-            : mImpl(impl) {}
-
-    void operator()(_C2BlockPoolData *buffer) {
-        BufferId id = buffer->mId;
-        delete buffer;
-
-        auto impl = mImpl.lock();
-        if (impl && impl->isValid()) {
-            impl->postBufferRelease(id);
-        }
-    }
-    const std::weak_ptr<BufferPoolClient::Impl> mImpl;
-};
-
-struct BufferPoolClient::Impl::ClientBuffer {
-private:
-    bool mInvalidated; // TODO: implement
-    int64_t mExpireUs;
-    bool mHasCache;
-    BufferId mId;
-    native_handle_t *mHandle;
-    std::weak_ptr<_C2BlockPoolData> mCache;
-
-    void updateExpire() {
-        mExpireUs = getTimestampNow() + kCacheTtlUs;
-    }
-
-public:
-    ClientBuffer(BufferId id, native_handle_t *handle)
-            : mInvalidated(false), mHasCache(false), mId(id), mHandle(handle) {
-        (void)mInvalidated;
-        mExpireUs = getTimestampNow() + kCacheTtlUs;
-    }
-
-    ~ClientBuffer() {
-        if (mHandle) {
-            native_handle_close(mHandle);
-            native_handle_delete(mHandle);
-        }
-    }
-
-    bool expire() const {
-        int64_t now = getTimestampNow();
-        return now >= mExpireUs;
-    }
-
-    bool hasCache() const {
-        return mHasCache;
-    }
-
-    std::shared_ptr<_C2BlockPoolData> fetchCache() {
-        if (mHasCache) {
-            std::shared_ptr<_C2BlockPoolData> cache = mCache.lock();
-            if (cache) {
-                updateExpire();
-            }
-            return cache;
-        }
-        return nullptr;
-    }
-
-    std::shared_ptr<_C2BlockPoolData> createCache(
-            const std::shared_ptr<BufferPoolClient::Impl> &impl) {
-        if (!mHasCache) {
-            // Allocates a raw ptr in order to avoid sending #postBufferRelease
-            // from deleter, in case of native_handle_clone failure.
-            _C2BlockPoolData *ptr = new _C2BlockPoolData(
-                    mId, native_handle_clone(mHandle));
-            if (ptr && ptr->mHandle != NULL) {
-                std::shared_ptr<_C2BlockPoolData>
-                        cache(ptr, BlockPoolDataDtor(impl));
-                if (cache) {
-                    mCache = cache;
-                    mHasCache = true;
-                    updateExpire();
-                    return cache;
-                }
-            }
-            if (ptr) {
-                delete ptr;
-            }
-        }
-        return nullptr;
-    }
-
-    bool onCacheRelease() {
-        if (mHasCache) {
-            // TODO: verify mCache is not valid;
-            mHasCache = false;
-            return true;
-        }
-        return false;
-    }
-};
-
-BufferPoolClient::Impl::Impl(const sp<Accessor> &accessor)
-    : mLocal(true), mAccessor(accessor), mSeqId(0) {
-    mValid = false;
-    const QueueDescriptor *fmqDesc;
-    ResultStatus status = accessor->connect(
-            &mLocalConnection, &mConnectionId, &fmqDesc);
-    if (status == ResultStatus::OK) {
-        mReleasing.mStatusChannel =
-                std::make_unique<BufferStatusChannel>(*fmqDesc);
-        mValid = mReleasing.mStatusChannel &&
-                mReleasing.mStatusChannel->isValid();
-    }
-}
-
-BufferPoolClient::Impl::Impl(const sp<IAccessor> &accessor)
-    : mLocal(false), mAccessor(accessor), mSeqId(0) {
-    mValid = false;
-    bool& valid = mValid;
-    sp<IConnection>& outConnection = mRemoteConnection;
-    ConnectionId& id = mConnectionId;
-    std::unique_ptr<BufferStatusChannel>& outChannel =
-            mReleasing.mStatusChannel;
-    accessor->connect(
-            [&valid, &outConnection, &id, &outChannel]
-            (ResultStatus status, sp<IConnection> connection,
-             ConnectionId connectionId, const QueueDescriptor& desc) {
-                if (status == ResultStatus::OK) {
-                    outConnection = connection;
-                    id = connectionId;
-                    outChannel = std::make_unique<BufferStatusChannel>(desc);
-                    if (outChannel && outChannel->isValid()) {
-                        valid = true;
-                    }
-                }
-            });
-}
-
-ResultStatus BufferPoolClient::Impl::allocate(
-        const std::vector<uint8_t> &params,
-        std::shared_ptr<_C2BlockPoolData> *buffer) {
-    if (!mLocal || !mLocalConnection || !mValid) {
-        return ResultStatus::CRITICAL_ERROR;
-    }
-    BufferId bufferId;
-    native_handle_t *handle = NULL;
-    buffer->reset();
-    ResultStatus status = allocateBufferHandle(params, &bufferId, &handle);
-    if (status == ResultStatus::OK) {
-        if (handle) {
-            std::unique_lock<std::mutex> lock(mCache.mLock);
-            syncReleased();
-            auto cacheIt = mCache.mBuffers.find(bufferId);
-            if (cacheIt != mCache.mBuffers.end()) {
-                // TODO: verify it is recycled. (not having active ref)
-                mCache.mBuffers.erase(cacheIt);
-            }
-            auto clientBuffer = std::make_unique<ClientBuffer>(
-                    bufferId, handle);
-            if (clientBuffer) {
-                auto result = mCache.mBuffers.insert(std::make_pair(
-                        bufferId, std::move(clientBuffer)));
-                if (result.second) {
-                    *buffer = result.first->second->createCache(
-                            shared_from_this());
-                }
-            }
-        }
-        if (!*buffer) {
-            ALOGV("client cache creation failure %d: %" PRId64,
-                  handle != NULL, mConnectionId);
-            status = ResultStatus::NO_MEMORY;
-            postBufferRelease(bufferId);
-        }
-    }
-    return status;
-}
-
-ResultStatus BufferPoolClient::Impl::receive(
-        TransactionId transactionId, BufferId bufferId, int64_t timestampUs,
-        std::shared_ptr<_C2BlockPoolData> *buffer) {
-    if (!mValid) {
-        return ResultStatus::CRITICAL_ERROR;
-    }
-    if (timestampUs != 0) {
-        timestampUs += kReceiveTimeoutUs;
-    }
-    if (!postReceive(bufferId, transactionId, timestampUs)) {
-        return ResultStatus::CRITICAL_ERROR;
-    }
-    ResultStatus status = ResultStatus::CRITICAL_ERROR;
-    buffer->reset();
-    while(1) {
-        std::unique_lock<std::mutex> lock(mCache.mLock);
-        syncReleased();
-        auto cacheIt = mCache.mBuffers.find(bufferId);
-        if (cacheIt != mCache.mBuffers.end()) {
-            if (cacheIt->second->hasCache()) {
-                *buffer = cacheIt->second->fetchCache();
-                if (!*buffer) {
-                    // check transfer time_out
-                    lock.unlock();
-                    std::this_thread::yield();
-                    continue;
-                }
-                ALOGV("client receive from reference %" PRId64, mConnectionId);
-                break;
-            } else {
-                *buffer = cacheIt->second->createCache(shared_from_this());
-                ALOGV("client receive from cache %" PRId64, mConnectionId);
-                break;
-            }
-        } else {
-            if (!mCache.creating) {
-                mCache.creating = true;
-                lock.unlock();
-                native_handle_t* handle = NULL;
-                status = fetchBufferHandle(transactionId, bufferId, &handle);
-                lock.lock();
-                if (status == ResultStatus::OK) {
-                    if (handle) {
-                        auto clientBuffer = std::make_unique<ClientBuffer>(
-                                bufferId, handle);
-                        if (clientBuffer) {
-                            auto result = mCache.mBuffers.insert(
-                                    std::make_pair(bufferId, std::move(
-                                            clientBuffer)));
-                            if (result.second) {
-                                *buffer = result.first->second->createCache(
-                                        shared_from_this());
-                            }
-                        }
-                    }
-                    if (!*buffer) {
-                        status = ResultStatus::NO_MEMORY;
-                    }
-                }
-                mCache.creating = false;
-                lock.unlock();
-                mCache.mCreateCv.notify_all();
-                break;
-            }
-            mCache.mCreateCv.wait(lock);
-        }
-    }
-    bool posted = postReceiveResult(bufferId, transactionId,
-                                      *buffer ? true : false);
-    ALOGV("client receive %" PRId64 " - %u : %s (%d)", mConnectionId, bufferId,
-          *buffer ? "ok" : "fail", posted);
-    if (*buffer) {
-        if (!posted) {
-            buffer->reset();
-            return ResultStatus::CRITICAL_ERROR;
-        }
-        return ResultStatus::OK;
-    }
-    return status;
-}
-
-
-void BufferPoolClient::Impl::postBufferRelease(BufferId bufferId) {
-    std::lock_guard<std::mutex> lock(mReleasing.mLock);
-    mReleasing.mReleasingIds.push_back(bufferId);
-    mReleasing.mStatusChannel->postBufferRelease(
-            mConnectionId, mReleasing.mReleasingIds, mReleasing.mReleasedIds);
-}
-
-// TODO: revise ad-hoc posting data structure
-bool BufferPoolClient::Impl::postSend(
-        BufferId bufferId, ConnectionId receiver,
-        TransactionId *transactionId, int64_t *timestampUs) {
-    std::lock_guard<std::mutex> lock(mReleasing.mLock);
-    *timestampUs = getTimestampNow();
-    *transactionId = (mConnectionId << 32) | mSeqId++;
-    // TODO: retry, add timeout, target?
-    return  mReleasing.mStatusChannel->postBufferStatusMessage(
-            *transactionId, bufferId, BufferStatus::TRANSFER_TO, mConnectionId,
-            receiver, mReleasing.mReleasingIds, mReleasing.mReleasedIds);
-}
-
-bool BufferPoolClient::Impl::postReceive(
-        BufferId bufferId, TransactionId transactionId, int64_t timestampUs) {
-    for (int i = 0; i < kPostMaxRetry; ++i) {
-        std::unique_lock<std::mutex> lock(mReleasing.mLock);
-        int64_t now = getTimestampNow();
-        if (timestampUs == 0 || now < timestampUs) {
-            bool result = mReleasing.mStatusChannel->postBufferStatusMessage(
-                    transactionId, bufferId, BufferStatus::TRANSFER_FROM,
-                    mConnectionId, -1, mReleasing.mReleasingIds,
-                    mReleasing.mReleasedIds);
-            if (result) {
-                return true;
-            }
-            lock.unlock();
-            std::this_thread::yield();
-        } else {
-            mReleasing.mStatusChannel->postBufferStatusMessage(
-                    transactionId, bufferId, BufferStatus::TRANSFER_TIMEOUT,
-                    mConnectionId, -1, mReleasing.mReleasingIds,
-                    mReleasing.mReleasedIds);
-            return false;
-        }
-    }
-    return false;
-}
-
-bool BufferPoolClient::Impl::postReceiveResult(
-        BufferId bufferId, TransactionId transactionId, bool result) {
-    std::lock_guard<std::mutex> lock(mReleasing.mLock);
-    // TODO: retry, add timeout
-    return mReleasing.mStatusChannel->postBufferStatusMessage(
-            transactionId, bufferId,
-            result ? BufferStatus::TRANSFER_OK : BufferStatus::TRANSFER_ERROR,
-            mConnectionId, -1, mReleasing.mReleasingIds,
-            mReleasing.mReleasedIds);
-}
-
-// should have mCache.mLock
-bool BufferPoolClient::Impl::syncReleased() {
-    std::lock_guard<std::mutex> lock(mReleasing.mLock);
-    if (mReleasing.mReleasingIds.size() > 0) {
-        mReleasing.mStatusChannel->postBufferRelease(
-                mConnectionId, mReleasing.mReleasingIds,
-                mReleasing.mReleasedIds);
-    }
-    if (mReleasing.mReleasedIds.size() > 0) {
-        for (BufferId& id: mReleasing.mReleasedIds) {
-            ALOGV("client release buffer %" PRId64 " - %u", mConnectionId, id);
-            auto found = mCache.mBuffers.find(id);
-            if (found != mCache.mBuffers.end()) {
-                if (!found->second->onCacheRelease()) {
-                    // should not happen!
-                    ALOGW("client %" PRId64 "cache release status inconsitent!",
-                          mConnectionId);
-                }
-                if (found->second->expire()) {
-                    ALOGV("client evict buffer from cache %" PRId64 " - %u",
-                          mConnectionId, id);
-                    mCache.mBuffers.erase(found);
-                }
-            } else {
-                // should not happen!
-                ALOGW("client %" PRId64 "cache status inconsitent!",
-                      mConnectionId);
-            }
-        }
-        mReleasing.mReleasedIds.clear();
-        return true;
-    }
-    return false;
-}
-
-ResultStatus BufferPoolClient::Impl::allocateBufferHandle(
-        const std::vector<uint8_t>& params, BufferId *bufferId,
-        native_handle_t** handle) {
-    if (mLocalConnection) {
-        const native_handle_t* allocHandle = NULL;
-        ResultStatus status = mLocalConnection->allocate(
-                params, bufferId, &allocHandle);
-        if (status == ResultStatus::OK) {
-            *handle = native_handle_clone(allocHandle);
-        }
-        ALOGV("client allocate result %" PRId64 "%d : %u clone %p",
-              mConnectionId, status == ResultStatus::OK,
-              *handle ? *bufferId : 0 , *handle);
-        return status;
-    }
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-ResultStatus BufferPoolClient::Impl::fetchBufferHandle(
-        TransactionId transactionId, BufferId bufferId,
-        native_handle_t **handle) {
-    sp<IConnection> connection;
-    if (mLocal) {
-        connection = mLocalConnection;
-    } else {
-        connection = mRemoteConnection;
-    }
-    ResultStatus status;
-    connection->fetch(
-            transactionId, bufferId,
-            [&status, &handle]
-            (ResultStatus outStatus, Buffer outBuffer) {
-                status = outStatus;
-                if (status == ResultStatus::OK) {
-                    *handle = native_handle_clone(
-                            outBuffer.buffer.getNativeHandle());
-                }
-            });
-    return status;
-}
-
-
-BufferPoolClient::BufferPoolClient(const sp<Accessor> &accessor) {
-    mImpl = std::make_shared<Impl>(accessor);
-}
-
-BufferPoolClient::BufferPoolClient(const sp<IAccessor> &accessor) {
-    mImpl = std::make_shared<Impl>(accessor);
-}
-
-BufferPoolClient::~BufferPoolClient() {
-    // TODO: how to handle orphaned buffers?
-}
-
-bool BufferPoolClient::isValid() {
-    return mImpl && mImpl->isValid();
-}
-
-ConnectionId BufferPoolClient::getConnectionId() {
-    if (isValid()) {
-        return mImpl->getConnectionId();
-    }
-    return -1;
-}
-
-ResultStatus BufferPoolClient::getAccessor(sp<IAccessor> *accessor) {
-    if (isValid()) {
-        *accessor = mImpl->getAccessor();
-        return ResultStatus::OK;
-    }
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-ResultStatus BufferPoolClient::allocate(
-        const std::vector<uint8_t> &params,
-        std::shared_ptr<_C2BlockPoolData> *buffer) {
-    if (isValid()) {
-        return mImpl->allocate(params, buffer);
-    }
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-ResultStatus BufferPoolClient::receive(
-        TransactionId transactionId, BufferId bufferId, int64_t timestampUs,
-        std::shared_ptr<_C2BlockPoolData> *buffer) {
-    if (isValid()) {
-        return mImpl->receive(transactionId, bufferId, timestampUs, buffer);
-    }
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-ResultStatus BufferPoolClient::postSend(
-        ConnectionId receiverId,
-        const std::shared_ptr<_C2BlockPoolData> &buffer,
-        TransactionId *transactionId,
-        int64_t *timestampUs) {
-    if (isValid()) {
-        bool result = mImpl->postSend(
-                buffer->mId, receiverId, transactionId, timestampUs);
-        return result ? ResultStatus::OK : ResultStatus::CRITICAL_ERROR;
-    }
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
diff --git a/media/libstagefright/codec2/vndk/bufferpool/BufferPoolClient.h b/media/libstagefright/codec2/vndk/bufferpool/BufferPoolClient.h
deleted file mode 100644
index a6111b5..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/BufferPoolClient.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2018 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_HARDWARE_MEDIA_BUFFERPOOL_V1_0_BUFFERPOOLCLIENT_H
-#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_BUFFERPOOLCLIENT_H
-
-#include <memory>
-#include <cutils/native_handle.h>
-#include <android/hardware/media/bufferpool/1.0/IAccessor.h>
-#include <android/hardware/media/bufferpool/1.0/IConnection.h>
-#include <BufferPoolTypes.h>
-#include "Accessor.h"
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::hardware::media::bufferpool::V1_0::IAccessor;
-using ::android::hardware::media::bufferpool::V1_0::IConnection;
-using ::android::hardware::media::bufferpool::V1_0::ResultStatus;
-using ::android::sp;
-
-/**
- * A buffer pool client for a buffer pool. For a specific buffer pool, at most
- * one buffer pool client exists per process. This class will not be exposed
- * outside. A buffer pool client will be used via ClientManager.
- */
-class BufferPoolClient {
-public:
-    /**
-     * Creates a buffer pool client from a local buffer pool
-     * (via ClientManager#create).
-     */
-    explicit BufferPoolClient(const sp<Accessor> &accessor);
-
-    /**
-     * Creates a buffer pool client from a remote buffer pool
-     * (via ClientManager#registerSender).
-     * Note: A buffer pool client created with remote buffer pool cannot
-     * allocate a buffer.
-     */
-    explicit BufferPoolClient(const sp<IAccessor> &accessor);
-
-    /** Destructs a buffer pool client. */
-    ~BufferPoolClient();
-
-private:
-    bool isValid();
-
-    ConnectionId getConnectionId();
-
-    ResultStatus getAccessor(sp<IAccessor> *accessor);
-
-    ResultStatus allocate(const std::vector<uint8_t> &params,
-                          std::shared_ptr<_C2BlockPoolData> *buffer);
-
-    ResultStatus receive(TransactionId transactionId,
-                         BufferId bufferId,
-                         int64_t timestampUs,
-                         std::shared_ptr<_C2BlockPoolData> *buffer);
-
-    ResultStatus postSend(ConnectionId receiver,
-                          const std::shared_ptr<_C2BlockPoolData> &buffer,
-                          TransactionId *transactionId,
-                          int64_t *timestampUs);
-
-    class Impl;
-    std::shared_ptr<Impl> mImpl;
-
-    friend struct ClientManager;
-};
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_BUFFERPOOLCLIENT_H
diff --git a/media/libstagefright/codec2/vndk/bufferpool/BufferStatus.cpp b/media/libstagefright/codec2/vndk/bufferpool/BufferStatus.cpp
deleted file mode 100644
index 4fc88c6..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/BufferStatus.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2018 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_TAG "bufferpool"
-//#define LOG_NDEBUG 0
-
-#include <inttypes.h>
-#include <time.h>
-#include "BufferStatus.h"
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V1_0 {
-namespace implementation {
-
-int64_t getTimestampNow() {
-    int64_t stamp;
-    struct timespec ts;
-    // TODO: CLOCK_MONOTONIC_COARSE?
-    clock_gettime(CLOCK_MONOTONIC, &ts);
-    stamp = ts.tv_nsec / 1000;
-    stamp += (ts.tv_sec * 1000000LL);
-    return stamp;
-}
-
-static constexpr int kNumElementsInQueue = 1024*16;
-
-ResultStatus BufferStatusObserver::open(
-        ConnectionId id, const QueueDescriptor** fmqDescPtr) {
-    if (mBufferStatusQueues.find(id) != mBufferStatusQueues.end()) {
-        // TODO: id collision log?
-        return ResultStatus::CRITICAL_ERROR;
-    }
-    std::unique_ptr<BufferStatusQueue> queue =
-            std::make_unique<BufferStatusQueue>(kNumElementsInQueue);
-    if (!queue || queue->isValid() == false) {
-        *fmqDescPtr = NULL;
-        return ResultStatus::NO_MEMORY;
-    } else {
-        *fmqDescPtr = queue->getDesc();
-    }
-    auto result = mBufferStatusQueues.insert(
-            std::make_pair(id, std::move(queue)));
-    if (!result.second) {
-        *fmqDescPtr = NULL;
-        return ResultStatus::NO_MEMORY;
-    }
-    return ResultStatus::OK;
-}
-
-ResultStatus BufferStatusObserver::close(ConnectionId id) {
-    if (mBufferStatusQueues.find(id) == mBufferStatusQueues.end()) {
-        return ResultStatus::CRITICAL_ERROR;
-    }
-    mBufferStatusQueues.erase(id);
-    return ResultStatus::OK;
-}
-
-void BufferStatusObserver::getBufferStatusChanges(std::vector<BufferStatusMessage> &messages) {
-    for (auto it = mBufferStatusQueues.begin(); it != mBufferStatusQueues.end(); ++it) {
-        BufferStatusMessage message;
-        size_t avail = it->second->availableToRead();
-        while (avail > 0) {
-            if (!it->second->read(&message, 1)) {
-                // Since avaliable # of reads are already confiremd,
-                // this should not happen.
-                // TODO: error handling (supurious client?)
-                ALOGW("FMQ message cannot be read from %" PRId64, it->first);
-                return;
-            }
-            message.connectionId = it->first;
-            messages.push_back(message);
-            --avail;
-        }
-    }
-}
-
-BufferStatusChannel::BufferStatusChannel(
-        const QueueDescriptor &fmqDesc) {
-    std::unique_ptr<BufferStatusQueue> queue =
-            std::make_unique<BufferStatusQueue>(fmqDesc);
-    if (!queue || queue->isValid() == false) {
-        mValid = false;
-        return;
-    }
-    mValid  = true;
-    mBufferStatusQueue = std::move(queue);
-}
-
-bool BufferStatusChannel::isValid() {
-    return mValid;
-}
-
-void BufferStatusChannel::postBufferRelease(
-        ConnectionId connectionId,
-        std::list<BufferId> &pending, std::list<BufferId> &posted) {
-    if (mValid && pending.size() > 0) {
-        size_t avail = mBufferStatusQueue->availableToWrite();
-        avail = std::min(avail, pending.size());
-        BufferStatusMessage message;
-        for (size_t i = 0 ; i < avail; ++i) {
-            BufferId id = pending.front();
-            message.newStatus = BufferStatus::NOT_USED;
-            message.bufferId = id;
-            message.connectionId = connectionId;
-            if (!mBufferStatusQueue->write(&message, 1)) {
-                // Since avaliable # of writes are already confiremd,
-                // this should not happen.
-                // TODO: error handing?
-                ALOGW("FMQ message cannot be sent from %" PRId64, connectionId);
-                return;
-            }
-            pending.pop_front();
-            posted.push_back(id);
-        }
-    }
-}
-
-bool BufferStatusChannel::postBufferStatusMessage(
-        TransactionId transactionId, BufferId bufferId,
-        BufferStatus status, ConnectionId connectionId, ConnectionId targetId,
-        std::list<BufferId> &pending, std::list<BufferId> &posted) {
-    if (mValid) {
-        size_t avail = mBufferStatusQueue->availableToWrite();
-        size_t numPending = pending.size();
-        if (avail >= numPending + 1) {
-            BufferStatusMessage release, message;
-            for (size_t i = 0; i < numPending; ++i) {
-                BufferId id = pending.front();
-                release.newStatus = BufferStatus::NOT_USED;
-                release.bufferId = id;
-                release.connectionId = connectionId;
-                if (!mBufferStatusQueue->write(&release, 1)) {
-                    // Since avaliable # of writes are already confiremd,
-                    // this should not happen.
-                    // TODO: error handling?
-                    ALOGW("FMQ message cannot be sent from %" PRId64,
-                          connectionId);
-                    return false;
-                }
-                pending.pop_front();
-                posted.push_back(id);
-            }
-            message.transactionId = transactionId;
-            message.bufferId = bufferId;
-            message.newStatus = status;
-            message.connectionId = connectionId;
-            message.targetConnectionId = targetId;
-            // TODO : timesatamp
-            message.timestampUs = 0;
-            if (!mBufferStatusQueue->write(&message, 1)) {
-                // Since avaliable # of writes are already confiremd,
-                // this should not happen.
-                ALOGW("FMQ message cannot be sent from %" PRId64, connectionId);
-                return false;
-            }
-            return true;
-        }
-    }
-    return false;
-}
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
diff --git a/media/libstagefright/codec2/vndk/bufferpool/BufferStatus.h b/media/libstagefright/codec2/vndk/bufferpool/BufferStatus.h
deleted file mode 100644
index 82303cb..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/BufferStatus.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2018 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_HARDWARE_MEDIA_BUFFERPOOL_V1_0_BUFFERSTATUS_H
-#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_BUFFERSTATUS_H
-
-#include <android/hardware/media/bufferpool/1.0/types.h>
-#include <fmq/MessageQueue.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-#include <memory>
-#include <mutex>
-#include <vector>
-#include <list>
-#include <BufferPoolTypes.h>
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V1_0 {
-namespace implementation {
-
-/** Returns monotonic timestamp in Us since fixed point in time. */
-int64_t getTimestampNow();
-
-/**
- * A collection of FMQ for a buffer pool. buffer ownership/status change
- * messages are sent via the FMQs from the clients.
- */
-class BufferStatusObserver {
-private:
-    std::map<ConnectionId, std::unique_ptr<BufferStatusQueue>>
-            mBufferStatusQueues;
-
-public:
-    /** Creates an FMQ for the specified connection(client).
-     *
-     * @param connectionId  connection Id of the specified client.
-     * @param fmqDescPtr    double ptr of created FMQ's descriptor.
-     *
-     * @return OK if FMQ is created successfully.
-     *         NO_MEMORY when there is no memory.
-     *         CRITICAL_ERROR otherwise.
-     */
-    ResultStatus open(ConnectionId id, const QueueDescriptor** fmqDescPtr);
-
-    /** Closes an FMQ for the specified connection(client).
-     *
-     * @param connectionId  connection Id of the specified client.
-     *
-     * @return OK if the specified connection is closed successfully.
-     *         CRITICAL_ERROR otherwise.
-     */
-    ResultStatus close(ConnectionId id);
-
-    /** Retrieves all pending FMQ buffer status messages from clients.
-     *
-     * @param messages  retrieved pending messages.
-     */
-    void getBufferStatusChanges(std::vector<BufferStatusMessage> &messages);
-};
-
-/**
- * An FMQ for a buffer pool client. buffer ownership/status change messages
- * are sent via the fmq to the buffer pool.
- */
-class BufferStatusChannel {
-private:
-    bool mValid;
-    std::unique_ptr<BufferStatusQueue> mBufferStatusQueue;
-
-public:
-    /**
-     * Connects to an FMQ from a descriptor of the created FMQ.
-     *
-     * @param fmqDesc   Descriptor of the created FMQ.
-     */
-    BufferStatusChannel(const QueueDescriptor &fmqDesc);
-
-    /** Returns whether the FMQ is connected successfully. */
-    bool isValid();
-
-    /**
-     * Posts a buffer release message to the buffer pool.
-     *
-     * @param connectionId  connection Id of the client.
-     * @param pending       currently pending buffer release messages.
-     * @param posted        posted buffer release messages.
-     */
-    void postBufferRelease(
-            ConnectionId connectionId,
-            std::list<BufferId> &pending, std::list<BufferId> &posted);
-
-    /**
-     * Posts a buffer status message regarding the specified buffer
-     * transfer transaction.
-     *
-     * @param transactionId Id of the specified transaction.
-     * @param bufferId      buffer Id of the specified transaction.
-     * @param status        new status of the buffer.
-     * @param connectionId  connection Id of the client.
-     * @param targetId      connection Id of the receiver(only when the sender
-     *                      posts a status message).
-     * @param pending       currently pending buffer release messages.
-     * @param posted        posted buffer release messages.
-     *
-     * @return {@code true} when the specified message is posted,
-     *         {@code false} otherwise.
-     */
-    bool postBufferStatusMessage(
-            TransactionId transactionId,
-            BufferId bufferId,
-            BufferStatus status,
-            ConnectionId connectionId,
-            ConnectionId targetId,
-            std::list<BufferId> &pending, std::list<BufferId> &posted);
-};
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_BUFFERSTATUS_H
diff --git a/media/libstagefright/codec2/vndk/bufferpool/ClientManager.cpp b/media/libstagefright/codec2/vndk/bufferpool/ClientManager.cpp
deleted file mode 100644
index 89aee8b..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/ClientManager.cpp
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright (C) 2018 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 <ClientManager.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-#include "BufferPoolClient.h"
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V1_0 {
-namespace implementation {
-
-static constexpr int64_t kRegisterTimeoutUs = 500000; // 0.5 sec
-
-class ClientManager::Impl {
-public:
-    Impl();
-
-    ResultStatus registerSender(const sp<IAccessor> &accessor,
-                                ConnectionId *pConnectionId);
-
-    ResultStatus create(const std::shared_ptr<BufferPoolAllocator> &allocator,
-                        ConnectionId *pConnectionId);
-
-    ResultStatus close(ConnectionId connectionId);
-
-    ResultStatus allocate(ConnectionId connectionId,
-                          const std::vector<uint8_t> &params,
-                          std::shared_ptr<_C2BlockPoolData> *buffer);
-
-    ResultStatus receive(ConnectionId connectionId,
-                         TransactionId transactionId,
-                         BufferId bufferId,
-                         int64_t timestampUs,
-                         std::shared_ptr<_C2BlockPoolData> *buffer);
-
-    ResultStatus postSend(ConnectionId connectionId,
-                          ConnectionId receiverId,
-                          const std::shared_ptr<_C2BlockPoolData> &buffer,
-                          TransactionId *transactionId,
-                          int64_t *timestampUs);
-
-    ResultStatus getAccessor(ConnectionId connectionId,
-                             sp<IAccessor> *accessor);
-
-private:
-    // In order to prevent deadlock between multiple locks,
-    // Always lock ClientCache.lock before locking ActiveClients.lock.
-    struct ClientCache {
-        // This lock is held for brief duration.
-        // Blocking operation is not performed holding the lock.
-        std::mutex mMutex;
-        std::map<const wp<IAccessor>, const std::weak_ptr<BufferPoolClient>>
-                mClients;
-        std::condition_variable mConnectCv;
-        bool mConnecting;
-
-        ClientCache() : mConnecting(false) {}
-    } mCache;
-
-    // Active clients which can be retrieved via ConnectionId
-    struct ActiveClients {
-        // This lock is held for brief duration.
-        // Blocking operation is not performed holding the lock.
-        std::mutex mMutex;
-        std::map<ConnectionId, const std::shared_ptr<BufferPoolClient>>
-                mClients;
-    } mActive;
-
-};
-
-ClientManager::Impl::Impl() {}
-
-ResultStatus ClientManager::Impl::registerSender(
-        const sp<IAccessor> &accessor, ConnectionId *pConnectionId) {
-    int64_t timeoutUs = getTimestampNow() + kRegisterTimeoutUs;
-    do {
-        std::unique_lock<std::mutex> lock(mCache.mMutex);
-        auto it = mCache.mClients.find(accessor);
-        if (it != mCache.mClients.end()) {
-            const std::shared_ptr<BufferPoolClient> client = it->second.lock();
-            if (client) {
-                *pConnectionId = client->getConnectionId();
-                return ResultStatus::ALREADY_EXISTS;
-            }
-            mCache.mClients.erase(it);
-        }
-        if (!mCache.mConnecting) {
-            mCache.mConnecting = true;
-            lock.unlock();
-            ResultStatus result = ResultStatus::OK;
-            const std::shared_ptr<BufferPoolClient> client =
-                    std::make_shared<BufferPoolClient>(accessor);
-            lock.lock();
-            if (!client) {
-                result = ResultStatus::NO_MEMORY;
-            } else if (!client->isValid()) {
-                result = ResultStatus::CRITICAL_ERROR;
-            }
-            if (result == ResultStatus::OK) {
-                // TODO: handle insert fail. (malloc fail)
-                const std::weak_ptr<BufferPoolClient> wclient = client;
-                mCache.mClients.insert(std::make_pair(accessor, wclient));
-                ConnectionId conId = client->getConnectionId();
-                {
-                    std::lock_guard<std::mutex> lock(mActive.mMutex);
-                    mActive.mClients.insert(std::make_pair(conId, client));
-                }
-                *pConnectionId = conId;
-            }
-            mCache.mConnecting = false;
-            lock.unlock();
-            mCache.mConnectCv.notify_all();
-            return result;
-        }
-        mCache.mConnectCv.wait_for(
-                lock, std::chrono::microseconds(kRegisterTimeoutUs));
-    } while (getTimestampNow() < timeoutUs);
-    // TODO: return timeout error
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-ResultStatus ClientManager::Impl::create(
-        const std::shared_ptr<BufferPoolAllocator> &allocator,
-        ConnectionId *pConnectionId) {
-    const sp<Accessor> accessor = new Accessor(allocator);
-    if (!accessor || !accessor->isValid()) {
-        return ResultStatus::CRITICAL_ERROR;
-    }
-    std::shared_ptr<BufferPoolClient> client =
-            std::make_shared<BufferPoolClient>(accessor);
-    if (!client || !client->isValid()) {
-        return ResultStatus::CRITICAL_ERROR;
-    }
-    {
-        // TODO: handle insert fail. (malloc fail)
-        std::lock_guard<std::mutex> lock(mCache.mMutex);
-        const wp<Accessor> waccessor = accessor;
-        const std::weak_ptr<BufferPoolClient> wclient = client;
-        mCache.mClients.insert(std::make_pair(waccessor, wclient));
-        ConnectionId conId = client->getConnectionId();
-        {
-            std::lock_guard<std::mutex> lock(mActive.mMutex);
-            mActive.mClients.insert(std::make_pair(conId, client));
-        }
-        *pConnectionId = conId;
-    }
-    return ResultStatus::OK;
-}
-
-ResultStatus ClientManager::Impl::close(ConnectionId connectionId) {
-    std::lock_guard<std::mutex> lock1(mCache.mMutex);
-    std::lock_guard<std::mutex> lock2(mActive.mMutex);
-    auto it = mActive.mClients.find(connectionId);
-    if (it != mActive.mClients.end()) {
-        sp<IAccessor> accessor;
-        if (it->second->getAccessor(&accessor) == ResultStatus::OK) {
-            mCache.mClients.erase(accessor);
-        }
-        mActive.mClients.erase(connectionId);
-        return ResultStatus::OK;
-    }
-    return ResultStatus::NOT_FOUND;
-}
-
-ResultStatus ClientManager::Impl::allocate(
-        ConnectionId connectionId, const std::vector<uint8_t> &params,
-        std::shared_ptr<_C2BlockPoolData> *buffer) {
-    std::shared_ptr<BufferPoolClient> client;
-    {
-        std::lock_guard<std::mutex> lock(mActive.mMutex);
-        auto it = mActive.mClients.find(connectionId);
-        if (it == mActive.mClients.end()) {
-            return ResultStatus::NOT_FOUND;
-        }
-        client = it->second;
-    }
-    return client->allocate(params, buffer);
-}
-
-ResultStatus ClientManager::Impl::receive(
-        ConnectionId connectionId, TransactionId transactionId,
-        BufferId bufferId, int64_t timestampUs,
-        std::shared_ptr<_C2BlockPoolData> *buffer) {
-    std::shared_ptr<BufferPoolClient> client;
-    {
-        std::lock_guard<std::mutex> lock(mActive.mMutex);
-        auto it = mActive.mClients.find(connectionId);
-        if (it == mActive.mClients.end()) {
-            return ResultStatus::NOT_FOUND;
-        }
-        client = it->second;
-    }
-    return client->receive(transactionId, bufferId, timestampUs, buffer);
-}
-
-ResultStatus ClientManager::Impl::postSend(
-        ConnectionId connectionId, ConnectionId receiverId,
-        const std::shared_ptr<_C2BlockPoolData> &buffer,
-        TransactionId *transactionId, int64_t *timestampUs) {
-    std::shared_ptr<BufferPoolClient> client;
-    {
-        std::lock_guard<std::mutex> lock(mActive.mMutex);
-        auto it = mActive.mClients.find(connectionId);
-        if (it == mActive.mClients.end()) {
-            return ResultStatus::NOT_FOUND;
-        }
-        client = it->second;
-    }
-    return client->postSend(receiverId, buffer, transactionId, timestampUs);
-}
-
-ResultStatus ClientManager::Impl::getAccessor(
-        ConnectionId connectionId, sp<IAccessor> *accessor) {
-    std::shared_ptr<BufferPoolClient> client;
-    {
-        std::lock_guard<std::mutex> lock(mActive.mMutex);
-        auto it = mActive.mClients.find(connectionId);
-        if (it == mActive.mClients.end()) {
-            return ResultStatus::NOT_FOUND;
-        }
-        client = it->second;
-    }
-    return client->getAccessor(accessor);
-}
-
-// Methods from ::android::hardware::media::bufferpool::V1_0::IClientManager follow.
-Return<void> ClientManager::registerSender(const sp<::android::hardware::media::bufferpool::V1_0::IAccessor>& bufferPool, registerSender_cb _hidl_cb) {
-    if (mImpl) {
-        ConnectionId connectionId = -1;
-        ResultStatus status = mImpl->registerSender(bufferPool, &connectionId);
-        _hidl_cb(status, connectionId);
-    } else {
-        _hidl_cb(ResultStatus::CRITICAL_ERROR, -1);
-    }
-    return Void();
-}
-
-// Methods for local use.
-sp<ClientManager> ClientManager::sInstance;
-std::mutex ClientManager::sInstanceLock;
-
-sp<ClientManager> ClientManager::getInstance() {
-    std::lock_guard<std::mutex> lock(sInstanceLock);
-    if (!sInstance) {
-        sInstance = new ClientManager();
-    }
-    return sInstance;
-}
-
-ClientManager::ClientManager() : mImpl(new Impl()) {}
-
-ClientManager::~ClientManager() {
-}
-
-ResultStatus ClientManager::create(
-        const std::shared_ptr<BufferPoolAllocator> &allocator,
-        ConnectionId *pConnectionId) {
-    if (mImpl) {
-        return mImpl->create(allocator, pConnectionId);
-    }
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-ResultStatus ClientManager::close(ConnectionId connectionId) {
-    if (mImpl) {
-        return mImpl->close(connectionId);
-    }
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-ResultStatus ClientManager::allocate(
-        ConnectionId connectionId, const std::vector<uint8_t> &params,
-        std::shared_ptr<_C2BlockPoolData> *buffer) {
-    if (mImpl) {
-        return mImpl->allocate(connectionId, params, buffer);
-    }
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-ResultStatus ClientManager::receive(
-        ConnectionId connectionId, TransactionId transactionId,
-        BufferId bufferId, int64_t timestampUs,
-        std::shared_ptr<_C2BlockPoolData> *buffer) {
-    if (mImpl) {
-        return mImpl->receive(connectionId, transactionId, bufferId,
-                              timestampUs, buffer);
-    }
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-ResultStatus ClientManager::postSend(
-        ConnectionId connectionId, ConnectionId receiverId,
-        const std::shared_ptr<_C2BlockPoolData> &buffer,
-        TransactionId *transactionId, int64_t* timestampUs) {
-    if (mImpl) {
-        return mImpl->postSend(connectionId, receiverId, buffer,
-                               transactionId, timestampUs);
-    }
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-ResultStatus ClientManager::getAccessor(
-        ConnectionId connectionId, sp<IAccessor> *accessor) {
-    if (mImpl) {
-        return mImpl->getAccessor(connectionId, accessor);
-    }
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-//IClientManager* HIDL_FETCH_IClientManager(const char* /* name */) {
-//    return new ClientManager();
-//}
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
diff --git a/media/libstagefright/codec2/vndk/bufferpool/Connection.cpp b/media/libstagefright/codec2/vndk/bufferpool/Connection.cpp
deleted file mode 100644
index 7b385b8..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/Connection.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2018 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 "Connection.h"
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V1_0 {
-namespace implementation {
-
-// Methods from ::android::hardware::media::bufferpool::V1_0::IConnection follow.
-Return<void> Connection::fetch(uint64_t transactionId, uint32_t bufferId, fetch_cb _hidl_cb) {
-    ResultStatus status = ResultStatus::CRITICAL_ERROR;
-    if (mInitialized && mAccessor) {
-        const native_handle_t *handle = NULL;
-        status = mAccessor->fetch(
-                mConnectionId, transactionId, bufferId, &handle);
-        if (status == ResultStatus::OK) {
-            _hidl_cb(status, Buffer{bufferId, handle});
-            return Void();
-        }
-    }
-    _hidl_cb(status, Buffer{0, nullptr});
-    return Void();
-}
-
-Connection::Connection() : mInitialized(false), mConnectionId(-1LL) {}
-
-Connection::~Connection() {
-    if (mInitialized && mAccessor) {
-        mAccessor->close(mConnectionId);
-    }
-}
-
-void Connection::initialize(
-        const sp<Accessor>& accessor, ConnectionId connectionId) {
-    if (!mInitialized) {
-        mAccessor = accessor;
-        mConnectionId = connectionId;
-        mInitialized = true;
-    }
-}
-
-ResultStatus Connection::allocate(
-        const std::vector<uint8_t> &params, BufferId *bufferId,
-        const native_handle_t **handle) {
-    if (mInitialized && mAccessor) {
-        return mAccessor->allocate(mConnectionId, params, bufferId, handle);
-    }
-    return ResultStatus::CRITICAL_ERROR;
-}
-
-
-// Methods from ::android::hidl::base::V1_0::IBase follow.
-
-//IConnection* HIDL_FETCH_IConnection(const char* /* name */) {
-//    return new Connection();
-//}
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
diff --git a/media/libstagefright/codec2/vndk/bufferpool/Connection.h b/media/libstagefright/codec2/vndk/bufferpool/Connection.h
deleted file mode 100644
index 47ddbcb..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/Connection.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2018 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_HARDWARE_MEDIA_BUFFERPOOL_V1_0_CONNECTION_H
-#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_CONNECTION_H
-
-#include <android/hardware/media/bufferpool/1.0/IConnection.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-#include <BufferPoolTypes.h>
-#include "Accessor.h"
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::media::bufferpool::V1_0::implementation::Accessor;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
-
-struct Connection : public IConnection {
-    // Methods from ::android::hardware::media::bufferpool::V1_0::IConnection follow.
-    Return<void> fetch(uint64_t transactionId, uint32_t bufferId, fetch_cb _hidl_cb) override;
-
-    /**
-     * Allocates a buffer using the specified parameters. Recycles a buffer if
-     * it is possible. The returned buffer can be transferred to other remote
-     * clients(Connection).
-     *
-     * @param params    allocation parameters.
-     * @param bufferId  Id of the allocated buffer.
-     * @param handle    native handle of the allocated buffer.
-     *
-     * @return OK if a buffer is successfully allocated.
-     *         NO_MEMORY when there is no memory.
-     *         CRITICAL_ERROR otherwise.
-     */
-    ResultStatus allocate(const std::vector<uint8_t> &params,
-                          BufferId *bufferId, const native_handle_t **handle);
-
-    /** Destructs a connection. */
-    ~Connection();
-
-    /** Creates a connection. */
-    Connection();
-
-    /**
-     * Initializes with the specified buffer pool and the connection id.
-     * The connection id should be unique in the whole system.
-     *
-     * @param accessor      the specified buffer pool.
-     * @param connectionId  Id.
-     */
-    void initialize(const sp<Accessor> &accessor, ConnectionId connectionId);
-
-private:
-    bool mInitialized;
-    sp<Accessor> mAccessor;
-    ConnectionId mConnectionId;
-};
-
-// FIXME: most likely delete, this is only for passthrough implementations
-// extern "C" IConnection* HIDL_FETCH_IConnection(const char* name);
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_CONNECTION_H
diff --git a/media/libstagefright/codec2/vndk/bufferpool/include/BufferPoolTypes.h b/media/libstagefright/codec2/vndk/bufferpool/include/BufferPoolTypes.h
deleted file mode 100644
index 7f4223c..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/include/BufferPoolTypes.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2018 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_HARDWARE_MEDIA_BUFFERPOOL_V1_0_BUFFERPOOLTYPES_H
-#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_BUFFERPOOLTYPES_H
-
-#include <android/hardware/media/bufferpool/1.0/types.h>
-#include <cutils/native_handle.h>
-#include <fmq/MessageQueue.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-
-struct __attribute__((visibility("hidden"))) _C2BlockPoolData {
-    uint32_t mId; //BufferId
-    // Handle should be copied to somewhere else, and should be managed there.
-    native_handle_t *mHandle;
-
-    _C2BlockPoolData() : mId(0), mHandle(NULL) {}
-
-    _C2BlockPoolData(uint32_t id, native_handle_t *handle)
-            : mId(id), mHandle(handle) {}
-
-    ~_C2BlockPoolData() {
-    }
-};
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::hardware::kSynchronizedReadWrite;
-
-typedef uint32_t BufferId;
-typedef uint64_t TransactionId;
-typedef int64_t ConnectionId;
-
-typedef android::hardware::MessageQueue<BufferStatusMessage, kSynchronizedReadWrite> BufferStatusQueue;
-typedef BufferStatusQueue::Descriptor QueueDescriptor;
-
-/**
- * Allocation wrapper class for buffer pool.
- */
-struct BufferPoolAllocation {
-    const native_handle_t *mHandle;
-
-    const native_handle_t *handle() {
-        return mHandle;
-    }
-
-    BufferPoolAllocation(const native_handle_t *handle) : mHandle(handle) {}
-
-    ~BufferPoolAllocation() {};
-};
-
-/**
- * Allocator wrapper class for buffer pool.
- */
-class BufferPoolAllocator {
-public:
-
-    /**
-     * Allocate an allocation(buffer) for bufer pool.
-     *
-     * @param params    allocation parameters
-     * @param alloc     created allocation
-     *
-     * @return OK when an allocation is created successfully.
-     */
-    virtual ResultStatus allocate(
-            const std::vector<uint8_t> &params,
-            std::shared_ptr<BufferPoolAllocation> *alloc) = 0;
-
-    /**
-     * Returns whether allocation parameters of an old allocation are
-     * compatible with new allocation parameters.
-     */
-    virtual bool compatible(const std::vector<uint8_t> &newParams,
-                            const std::vector<uint8_t> &oldParams) = 0;
-
-protected:
-    BufferPoolAllocator() = default;
-
-    virtual ~BufferPoolAllocator() = default;
-};
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_BUFFERPOOLTYPES_H
diff --git a/media/libstagefright/codec2/vndk/bufferpool/include/ClientManager.h b/media/libstagefright/codec2/vndk/bufferpool/include/ClientManager.h
deleted file mode 100644
index f91f46b..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/include/ClientManager.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (C) 2018 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_HARDWARE_MEDIA_BUFFERPOOL_V1_0_CLIENTMANAGER_H
-#define ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_CLIENTMANAGER_H
-
-#include <android/hardware/media/bufferpool/1.0/IClientManager.h>
-#include <hidl/MQDescriptor.h>
-#include <hidl/Status.h>
-#include <memory>
-#include <BufferPoolTypes.h>
-
-namespace android {
-namespace hardware {
-namespace media {
-namespace bufferpool {
-namespace V1_0 {
-namespace implementation {
-
-using ::android::hardware::hidl_array;
-using ::android::hardware::hidl_memory;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::media::bufferpool::V1_0::IAccessor;
-using ::android::hardware::media::bufferpool::V1_0::ResultStatus;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::sp;
-
-struct ClientManager : public IClientManager {
-    // Methods from ::android::hardware::media::bufferpool::V1_0::IClientManager follow.
-    Return<void> registerSender(const sp<::android::hardware::media::bufferpool::V1_0::IAccessor>& bufferPool, registerSender_cb _hidl_cb) override;
-
-    /** Gets an instance. */
-    static sp<ClientManager> getInstance();
-
-    /**
-     * Creates a local connection with a newly created buffer pool.
-     *
-     * @param allocator     for new buffer allocation.
-     * @param pConnectionId Id of the created connection. This is
-     *                      system-wide unique.
-     *
-     * @return OK when a buffer pool and a local connection is successfully
-     *         created.
-     *         NO_MEMORY when there is no memory.
-     *         CRITICAL_ERROR otherwise.
-     */
-    ResultStatus create(const std::shared_ptr<BufferPoolAllocator> &allocator,
-                        ConnectionId *pConnectionId);
-
-    /**
-     * Closes the specified connection.
-     *
-     * @param connectionId  The id of the connection.
-     *
-     * @return OK when the connection is closed.
-     *         NOT_FOUND when the specified connection was not found.
-     *         CRITICAL_ERROR otherwise.
-     */
-    ResultStatus close(ConnectionId connectionId);
-
-    /**
-     * Allocates a buffer from the specified connection.
-     *
-     * @param connectionId  The id of the connection.
-     * @param params        The allocation parameters.
-     * @param buffer        The allocated buffer.
-     *
-     * @return OK when a buffer was allocated successfully.
-     *         NOT_FOUND when the specified connection was not found.
-     *         NO_MEMORY when there is no memory.
-     *         CRITICAL_ERROR otherwise.
-     */
-    ResultStatus allocate(ConnectionId connectionId,
-                          const std::vector<uint8_t> &params,
-                          std::shared_ptr<_C2BlockPoolData> *buffer);
-
-    /**
-     * Receives a buffer for the transaction.
-     *
-     * @param connectionId  The id of the receiving connection.
-     * @param transactionId The id for the transaction.
-     * @param bufferId      The id for the buffer.
-     * @param timestampUs   The timestamp of the buffer is being sent.
-     * @param buffer        The received buffer.
-     *
-     * @return OK when a buffer was received successfully.
-     *         NOT_FOUND when the specified connection was not found.
-     *         NO_MEMORY when there is no memory.
-     *         CRITICAL_ERROR otherwise.
-     */
-    ResultStatus receive(ConnectionId connectionId,
-                         TransactionId transactionId,
-                         BufferId bufferId,
-                         int64_t timestampUs,
-                         std::shared_ptr<_C2BlockPoolData> *buffer);
-
-    /**
-     * Posts a buffer transfer transaction to the buffer pool. Sends a buffer
-     * to other remote clients(connection) after this call has been succeeded.
-     *
-     * @param connectionId  The id of the sending connection.
-     * @param receiverId    The id of the receiving connection.
-     * @param buffer        to transfer
-     * @param transactionId Id of the transfer transaction.
-     * @param timestampUs   The timestamp of the buffer transaction is being
-     *                      posted.
-     *
-     * @return OK when a buffer transaction was posted successfully.
-     *         NOT_FOUND when the sending connection was not found.
-     *         CRITICAL_ERROR otherwise.
-     */
-    ResultStatus postSend(ConnectionId connectionId,
-                          ConnectionId receiverId,
-                          const std::shared_ptr<_C2BlockPoolData> &buffer,
-                          TransactionId *transactionId,
-                          int64_t *timestampUs);
-
-    /** Gets a buffer pool for the specified connection.
-     *
-     * @param connectionId  The id of the connection.
-     * @param accessor      The buffer pool for the specified connection.
-     * @return OK when a buffer pool was found for the connection.
-     *         NOT_FOUND when the specified connection was not found.
-     *         CRITICAL_ERROR otherwise.
-     */
-    ResultStatus getAccessor(ConnectionId connectionId,
-                             sp<IAccessor> *accessor);
-
-    /** Destructs the manager of buffer pool clients.  */
-    ~ClientManager();
-private:
-    static sp<ClientManager> sInstance;
-    static std::mutex sInstanceLock;
-
-    class Impl;
-    const std::unique_ptr<Impl> mImpl;
-
-    ClientManager();
-};
-
-// FIXME: most likely delete, this is only for passthrough implementations
-// extern "C" IClientManager* HIDL_FETCH_IClientManager(const char* name);
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace bufferpool
-}  // namespace media
-}  // namespace hardware
-}  // namespace android
-
-#endif  // ANDROID_HARDWARE_MEDIA_BUFFERPOOL_V1_0_CLIENTMANAGER_H
diff --git a/media/libstagefright/codec2/vndk/bufferpool/vts/Android.bp b/media/libstagefright/codec2/vndk/bufferpool/vts/Android.bp
deleted file mode 100644
index 62286f3..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/vts/Android.bp
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-cc_test {
-    name: "VtsVndkHidlBufferpoolV1_0TargetSingleTest",
-    defaults: ["VtsHalTargetTestDefaults"],
-    srcs: [
-        "allocator.cpp",
-        "single.cpp",
-    ],
-    static_libs: [
-        "android.hardware.media.bufferpool@1.0",
-        "libion",
-        "libstagefright_bufferpool@1.0",
-    ],
-    shared_libs: [
-        "libfmq",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-    ],
-    compile_multilib: "both",
-}
-
-cc_test {
-    name: "VtsVndkHidlBufferpoolV1_0TargetMultiTest",
-    defaults: ["VtsHalTargetTestDefaults"],
-    srcs: [
-        "allocator.cpp",
-        "multi.cpp",
-    ],
-    static_libs: [
-        "android.hardware.media.bufferpool@1.0",
-        "libion",
-        "libstagefright_bufferpool@1.0",
-    ],
-    shared_libs: [
-        "libfmq",
-        "libstagefright_codec2",
-        "libstagefright_codec2_vndk",
-    ],
-    compile_multilib: "both",
-}
diff --git a/media/libstagefright/codec2/vndk/bufferpool/vts/OWNERS b/media/libstagefright/codec2/vndk/bufferpool/vts/OWNERS
deleted file mode 100644
index 4c3f7a1..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/vts/OWNERS
+++ /dev/null
@@ -1,7 +0,0 @@
-# Media team
-taklee@google.com
-lajos@google.com
-
-# VTS team
-yim@google.com
-zhuoyao@google.com
diff --git a/media/libstagefright/codec2/vndk/bufferpool/vts/allocator.cpp b/media/libstagefright/codec2/vndk/bufferpool/vts/allocator.cpp
deleted file mode 100644
index 230ee3f..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/vts/allocator.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2018 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 <C2Buffer.h>
-#include "allocator.h"
-
-union Params {
-  struct {
-    uint32_t capacity;
-    C2MemoryUsage usage;
-  } data;
-  uint8_t array[0];
-  Params() : data{0, {0, 0}} {}
-  Params(uint32_t size)
-      : data{size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE}} {}
-};
-
-struct AllocationDtor {
-  AllocationDtor(const std::shared_ptr<C2LinearAllocation> &alloc)
-      : mAlloc(alloc) {}
-
-  void operator()(BufferPoolAllocation *poolAlloc) { delete poolAlloc; }
-
-  const std::shared_ptr<C2LinearAllocation> mAlloc;
-};
-
-ResultStatus VtsBufferPoolAllocator::allocate(
-    const std::vector<uint8_t> &params,
-    std::shared_ptr<BufferPoolAllocation> *alloc) {
-  Params ionParams;
-  memcpy(&ionParams, params.data(), std::min(sizeof(Params), params.size()));
-
-  std::shared_ptr<C2LinearAllocation> linearAlloc;
-  c2_status_t status = mAllocator->newLinearAllocation(
-      ionParams.data.capacity, ionParams.data.usage, &linearAlloc);
-  if (status == C2_OK && linearAlloc) {
-    BufferPoolAllocation *ptr = new BufferPoolAllocation(linearAlloc->handle());
-    if (ptr) {
-      *alloc = std::shared_ptr<BufferPoolAllocation>(
-          ptr, AllocationDtor(linearAlloc));
-      if (*alloc) {
-        return ResultStatus::OK;
-      }
-      delete ptr;
-      return ResultStatus::NO_MEMORY;
-    }
-  }
-  return ResultStatus::CRITICAL_ERROR;
-}
-
-bool VtsBufferPoolAllocator::compatible(const std::vector<uint8_t> &newParams,
-                                        const std::vector<uint8_t> &oldParams) {
-  size_t newSize = newParams.size();
-  size_t oldSize = oldParams.size();
-  if (newSize == oldSize) {
-    for (size_t i = 0; i < newSize; ++i) {
-      if (newParams[i] != oldParams[i]) {
-        return false;
-      }
-    }
-    return true;
-  }
-  return false;
-}
-
-void getVtsAllocatorParams(std::vector<uint8_t> *params) {
-  constexpr static int kAllocationSize = 1024 * 10;
-  Params ionParams(kAllocationSize);
-
-  params->assign(ionParams.array, ionParams.array + sizeof(ionParams));
-}
diff --git a/media/libstagefright/codec2/vndk/bufferpool/vts/allocator.h b/media/libstagefright/codec2/vndk/bufferpool/vts/allocator.h
deleted file mode 100644
index 2fbb7fb..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/vts/allocator.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2018 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 VTS_VNDK_HIDL_BUFFERPOOL_V1_0_ALLOCATOR_H
-#define VTS_VNDK_HIDL_BUFFERPOOL_V1_0_ALLOCATOR_H
-
-#include <BufferPoolTypes.h>
-
-using android::hardware::media::bufferpool::V1_0::ResultStatus;
-using android::hardware::media::bufferpool::V1_0::implementation::
-    BufferPoolAllocation;
-using android::hardware::media::bufferpool::V1_0::implementation::
-    BufferPoolAllocator;
-
-// buffer allocator for the tests
-class VtsBufferPoolAllocator : public BufferPoolAllocator {
- public:
-  VtsBufferPoolAllocator(const std::shared_ptr<C2Allocator> &allocator)
-      : mAllocator(allocator) {}
-
-  ~VtsBufferPoolAllocator() override {}
-
-  ResultStatus allocate(const std::vector<uint8_t> &params,
-                        std::shared_ptr<BufferPoolAllocation> *alloc) override;
-
-  bool compatible(const std::vector<uint8_t> &newParams,
-                  const std::vector<uint8_t> &oldParams) override;
-
- private:
-  const std::shared_ptr<C2Allocator> mAllocator;
-};
-
-// retrieve buffer allocator paramters
-void getVtsAllocatorParams(std::vector<uint8_t> *params);
-
-#endif  // VTS_VNDK_HIDL_BUFFERPOOL_V1_0_ALLOCATOR_H
diff --git a/media/libstagefright/codec2/vndk/bufferpool/vts/multi.cpp b/media/libstagefright/codec2/vndk/bufferpool/vts/multi.cpp
deleted file mode 100644
index 35127b8..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/vts/multi.cpp
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Copyright (C) 2018 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_TAG "buffferpool_unit_test"
-
-#include <gtest/gtest.h>
-
-#include <C2AllocatorIon.h>
-#include <C2Buffer.h>
-#include <C2PlatformSupport.h>
-#include <ClientManager.h>
-#include <android-base/logging.h>
-#include <binder/ProcessState.h>
-#include <hidl/HidlSupport.h>
-#include <hidl/HidlTransportSupport.h>
-#include <hidl/LegacySupport.h>
-#include <hidl/Status.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <iostream>
-#include <memory>
-#include <vector>
-#include "allocator.h"
-
-using android::C2AllocatorIon;
-using android::C2PlatformAllocatorStore;
-using android::hardware::configureRpcThreadpool;
-using android::hardware::hidl_handle;
-using android::hardware::media::bufferpool::V1_0::IAccessor;
-using android::hardware::media::bufferpool::V1_0::IClientManager;
-using android::hardware::media::bufferpool::V1_0::ResultStatus;
-using android::hardware::media::bufferpool::V1_0::implementation::BufferId;
-using android::hardware::media::bufferpool::V1_0::implementation::ClientManager;
-using android::hardware::media::bufferpool::V1_0::implementation::ConnectionId;
-using android::hardware::media::bufferpool::V1_0::implementation::TransactionId;
-
-namespace {
-
-// communication message types between processes.
-enum PipeCommand : int32_t {
-    INIT_OK = 0,
-    INIT_ERROR,
-    SEND,
-    RECEIVE_OK,
-    RECEIVE_ERROR,
-};
-
-// communication message between processes.
-union PipeMessage {
-    struct  {
-        int32_t command;
-        BufferId bufferId;
-        ConnectionId connectionId;
-        TransactionId transactionId;
-        int64_t  timestampUs;
-    } data;
-    char array[0];
-};
-
-// media.bufferpool test setup
-class BufferpoolMultiTest : public ::testing::Test {
- public:
-  virtual void SetUp() override {
-    ResultStatus status;
-    mReceiverPid = -1;
-
-    ASSERT_TRUE(pipe(mCommandPipeFds) == 0);
-    ASSERT_TRUE(pipe(mResultPipeFds) == 0);
-
-    mReceiverPid = fork();
-    ASSERT_TRUE(mReceiverPid >= 0);
-
-    if (mReceiverPid == 0) {
-       doReceiver();
-       return;
-    }
-
-    mManager = ClientManager::getInstance();
-    ASSERT_NE(mManager, nullptr);
-
-    std::shared_ptr<C2Allocator> allocator =
-        std::make_shared<C2AllocatorIon>(C2PlatformAllocatorStore::ION);
-    ASSERT_TRUE((bool)allocator);
-
-    mAllocator = std::make_shared<VtsBufferPoolAllocator>(allocator);
-    ASSERT_TRUE((bool)mAllocator);
-
-    status = mManager->create(mAllocator, &mConnectionId);
-    ASSERT_TRUE(status == ResultStatus::OK);
-
-    status = mManager->getAccessor(mConnectionId, &mAccessor);
-    ASSERT_TRUE(status == ResultStatus::OK && (bool)mAccessor);
-  }
-
-  virtual void TearDown() override {
-      if (mReceiverPid > 0) {
-          kill(mReceiverPid, SIGKILL);
-          int wstatus;
-          wait(&wstatus);
-      }
-  }
-
- protected:
-  static void description(const std::string& description) {
-    RecordProperty("description", description);
-  }
-
-  android::sp<ClientManager> mManager;
-  android::sp<IAccessor> mAccessor;
-  std::shared_ptr<BufferPoolAllocator> mAllocator;
-  ConnectionId mConnectionId;
-  pid_t mReceiverPid;
-  int mCommandPipeFds[2];
-  int mResultPipeFds[2];
-
-  bool sendMessage(int *pipes, const PipeMessage &message) {
-    int ret = write(pipes[1], message.array, sizeof(PipeMessage));
-    return ret == sizeof(PipeMessage);
-  }
-
-  bool receiveMessage(int *pipes, PipeMessage *message) {
-    int ret = read(pipes[0], message->array, sizeof(PipeMessage));
-    return ret == sizeof(PipeMessage);
-  }
-
-  void doReceiver() {
-    configureRpcThreadpool(1, false);
-    PipeMessage message;
-    mManager = ClientManager::getInstance();
-    if (!mManager) {
-      message.data.command = PipeCommand::INIT_ERROR;
-      sendMessage(mResultPipeFds, message);
-      return;
-    }
-    android::status_t status = mManager->registerAsService();
-    if (status != android::OK) {
-      message.data.command = PipeCommand::INIT_ERROR;
-      sendMessage(mResultPipeFds, message);
-      return;
-    }
-    message.data.command = PipeCommand::INIT_OK;
-    sendMessage(mResultPipeFds, message);
-
-    receiveMessage(mCommandPipeFds, &message);
-    {
-      std::shared_ptr<_C2BlockPoolData> rbuffer;
-      ResultStatus status = mManager->receive(
-          message.data.connectionId, message.data.transactionId,
-          message.data.bufferId, message.data.timestampUs, &rbuffer);
-      if (status != ResultStatus::OK) {
-        message.data.command = PipeCommand::RECEIVE_ERROR;
-        sendMessage(mResultPipeFds, message);
-        return;
-      }
-    }
-    message.data.command = PipeCommand::RECEIVE_OK;
-    sendMessage(mResultPipeFds, message);
-    while(1); // An easy way to ignore gtest behaviour.
-  }
-};
-
-// Buffer transfer test between processes.
-TEST_F(BufferpoolMultiTest, TransferBuffer) {
-  ResultStatus status;
-  PipeMessage message;
-
-  ASSERT_TRUE(receiveMessage(mResultPipeFds, &message));
-
-  android::sp<IClientManager> receiver = IClientManager::getService();
-  ConnectionId receiverId;
-  ASSERT_TRUE((bool)receiver);
-
-  receiver->registerSender(
-      mAccessor, [&status, &receiverId]
-      (ResultStatus outStatus, ConnectionId outId) {
-        status = outStatus;
-        receiverId = outId;
-      });
-  ASSERT_TRUE(status == ResultStatus::OK);
-  {
-    std::shared_ptr<_C2BlockPoolData> sbuffer;
-    TransactionId transactionId;
-    int64_t postUs;
-    std::vector<uint8_t> vecParams;
-
-    getVtsAllocatorParams(&vecParams);
-    status = mManager->allocate(mConnectionId, vecParams, &sbuffer);
-    ASSERT_TRUE(status == ResultStatus::OK);
-
-    status = mManager->postSend(mConnectionId, receiverId, sbuffer,
-                               &transactionId, &postUs);
-    ASSERT_TRUE(status == ResultStatus::OK);
-
-    message.data.command = PipeCommand::SEND;
-    message.data.bufferId = sbuffer->mId;
-    message.data.connectionId = receiverId;
-    message.data.transactionId = transactionId;
-    message.data.timestampUs = postUs;
-    sendMessage(mCommandPipeFds, message);
-  }
-  EXPECT_TRUE(receiveMessage(mResultPipeFds, &message));
-}
-
-}  // anonymous namespace
-
-int main(int argc, char** argv) {
-  setenv("TREBLE_TESTING_OVERRIDE", "true", true);
-  ::testing::InitGoogleTest(&argc, argv);
-  int status = RUN_ALL_TESTS();
-  LOG(INFO) << "Test result = " << status;
-  return status;
-}
diff --git a/media/libstagefright/codec2/vndk/bufferpool/vts/single.cpp b/media/libstagefright/codec2/vndk/bufferpool/vts/single.cpp
deleted file mode 100644
index c8878f3..0000000
--- a/media/libstagefright/codec2/vndk/bufferpool/vts/single.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2018 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_TAG "buffferpool_unit_test"
-
-#include <gtest/gtest.h>
-
-#include <C2AllocatorIon.h>
-#include <C2Buffer.h>
-#include <C2PlatformSupport.h>
-#include <ClientManager.h>
-#include <android-base/logging.h>
-#include <binder/ProcessState.h>
-#include <hidl/HidlSupport.h>
-#include <hidl/HidlTransportSupport.h>
-#include <hidl/LegacySupport.h>
-#include <hidl/Status.h>
-#include <unistd.h>
-#include <iostream>
-#include <memory>
-#include <vector>
-#include "allocator.h"
-
-using android::C2AllocatorIon;
-using android::C2PlatformAllocatorStore;
-using android::hardware::hidl_handle;
-using android::hardware::media::bufferpool::V1_0::IAccessor;
-using android::hardware::media::bufferpool::V1_0::ResultStatus;
-using android::hardware::media::bufferpool::V1_0::implementation::BufferId;
-using android::hardware::media::bufferpool::V1_0::implementation::ClientManager;
-using android::hardware::media::bufferpool::V1_0::implementation::ConnectionId;
-using android::hardware::media::bufferpool::V1_0::implementation::TransactionId;
-
-namespace {
-
-// Number of iteration for buffer allocation test.
-constexpr static int kNumAllocationTest = 3;
-
-// Number of iteration for buffer recycling test.
-constexpr static int kNumRecycleTest = 3;
-
-// media.bufferpool test setup
-class BufferpoolSingleTest : public ::testing::Test {
- public:
-  virtual void SetUp() override {
-    ResultStatus status;
-
-    mManager = ClientManager::getInstance();
-    ASSERT_NE(mManager, nullptr);
-
-    std::shared_ptr<C2Allocator> allocator =
-        std::make_shared<C2AllocatorIon>(C2PlatformAllocatorStore::ION);
-    ASSERT_TRUE((bool)allocator);
-
-    mAllocator = std::make_shared<VtsBufferPoolAllocator>(allocator);
-    ASSERT_TRUE((bool)mAllocator);
-
-    status = mManager->create(mAllocator, &mConnectionId);
-    ASSERT_TRUE(status == ResultStatus::OK);
-
-    status = mManager->getAccessor(mConnectionId, &mAccessor);
-    ASSERT_TRUE(status == ResultStatus::OK && (bool)mAccessor);
-
-    ConnectionId& receiverId = mReceiverId;
-    mManager->registerSender(
-        mAccessor,
-        [&status, &receiverId](ResultStatus hidlStatus, ConnectionId hidlId) {
-          status = hidlStatus;
-          receiverId = hidlId;
-        });
-    ASSERT_TRUE(status == ResultStatus::ALREADY_EXISTS &&
-                receiverId == mConnectionId);
-  }
-
- protected:
-  static void description(const std::string& description) {
-    RecordProperty("description", description);
-  }
-
-  android::sp<ClientManager> mManager;
-  android::sp<IAccessor> mAccessor;
-  std::shared_ptr<BufferPoolAllocator> mAllocator;
-  ConnectionId mConnectionId;
-  ConnectionId mReceiverId;
-
-};
-
-// Buffer allocation test.
-// Check whether each buffer allocation is done successfully with
-// unique buffer id.
-TEST_F(BufferpoolSingleTest, AllocateBuffer) {
-  ResultStatus status;
-  std::vector<uint8_t> vecParams;
-  getVtsAllocatorParams(&vecParams);
-
-  std::shared_ptr<_C2BlockPoolData> buffer[kNumAllocationTest];
-  for (int i = 0; i < kNumAllocationTest; ++i) {
-    status = mManager->allocate(mConnectionId, vecParams, &buffer[i]);
-    ASSERT_TRUE(status == ResultStatus::OK);
-  }
-  for (int i = 0; i < kNumAllocationTest; ++i) {
-    for (int j = i + 1; j < kNumAllocationTest; ++j) {
-      ASSERT_TRUE(buffer[i]->mId != buffer[j]->mId);
-    }
-  }
-  EXPECT_TRUE(kNumAllocationTest > 1);
-}
-
-// Buffer recycle test.
-// Check whether de-allocated buffers are recycled.
-TEST_F(BufferpoolSingleTest, RecycleBuffer) {
-  ResultStatus status;
-  std::vector<uint8_t> vecParams;
-  getVtsAllocatorParams(&vecParams);
-
-  BufferId bid[kNumRecycleTest];
-  for (int i = 0; i < kNumRecycleTest; ++i) {
-    std::shared_ptr<_C2BlockPoolData> buffer;
-    status = mManager->allocate(mConnectionId, vecParams, &buffer);
-    ASSERT_TRUE(status == ResultStatus::OK);
-    bid[i] = buffer->mId;
-  }
-  for (int i = 1; i < kNumRecycleTest; ++i) {
-    ASSERT_TRUE(bid[i - 1] == bid[i]);
-  }
-  EXPECT_TRUE(kNumRecycleTest > 1);
-}
-
-// Buffer transfer test.
-// Check whether buffer is transferred to another client successfully.
-TEST_F(BufferpoolSingleTest, TransferBuffer) {
-  ResultStatus status;
-  std::vector<uint8_t> vecParams;
-  getVtsAllocatorParams(&vecParams);
-  std::shared_ptr<_C2BlockPoolData> sbuffer, rbuffer;
-
-  TransactionId transactionId;
-  int64_t postUs;
-
-  status = mManager->allocate(mConnectionId, vecParams, &sbuffer);
-  ASSERT_TRUE(status == ResultStatus::OK);
-  status = mManager->postSend(mConnectionId, mReceiverId, sbuffer,
-                              &transactionId, &postUs);
-  ASSERT_TRUE(status == ResultStatus::OK);
-  status = mManager->receive(mReceiverId, transactionId, sbuffer->mId, postUs,
-                             &rbuffer);
-  EXPECT_TRUE(status == ResultStatus::OK);
-}
-
-}  // anonymous namespace
-
-int main(int argc, char** argv) {
-  ::testing::InitGoogleTest(&argc, argv);
-  int status = RUN_ALL_TESTS();
-  LOG(INFO) << "Test result = " << status;
-  return status;
-}
diff --git a/media/libstagefright/codec2/vndk/include/C2AllocatorGralloc.h b/media/libstagefright/codec2/vndk/include/C2AllocatorGralloc.h
deleted file mode 100644
index 8d28192..0000000
--- a/media/libstagefright/codec2/vndk/include/C2AllocatorGralloc.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef STAGEFRIGHT_CODEC2_ALLOCATOR_GRALLOC_H_
-#define STAGEFRIGHT_CODEC2_ALLOCATOR_GRALLOC_H_
-
-#include <functional>
-
-#include <C2Buffer.h>
-
-namespace android {
-
-/**
- * Unwrap the native handle from a Codec2 handle allocated by C2AllocatorGralloc.
- *
- * @param handle a handle allocated by C2AllocatorGralloc. This includes handles returned for a
- * graphic block allocation handle returned.
- *
- * @return a new NON-OWNING native handle that must be deleted using native_handle_delete.
- */
-native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle);
-
-/**
- * Wrap the gralloc handle and metadata into Codec2 handle recognized by
- * C2AllocatorGralloc.
- *
- * @return a new NON-OWNING C2Handle that must be deleted using native_handle_delete.
- */
-C2Handle *WrapNativeCodec2GrallocHandle(
-        const native_handle_t *const handle,
-        uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride);
-
-class C2AllocatorGralloc : public C2Allocator {
-public:
-    virtual id_t getId() const override;
-
-    virtual C2String getName() const override;
-
-    virtual std::shared_ptr<const Traits> getTraits() const override;
-
-    virtual c2_status_t newGraphicAllocation(
-            uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
-            std::shared_ptr<C2GraphicAllocation> *allocation) override;
-
-    virtual c2_status_t priorGraphicAllocation(
-            const C2Handle *handle,
-            std::shared_ptr<C2GraphicAllocation> *allocation) override;
-
-    C2AllocatorGralloc(id_t id);
-
-    c2_status_t status() const;
-
-    virtual ~C2AllocatorGralloc() override;
-
-    static bool isValid(const C2Handle* const o);
-
-private:
-    class Impl;
-    Impl *mImpl;
-};
-
-} // namespace android
-
-#endif // STAGEFRIGHT_CODEC2_ALLOCATOR_GRALLOC_H_
diff --git a/media/libstagefright/codec2/vndk/include/C2AllocatorIon.h b/media/libstagefright/codec2/vndk/include/C2AllocatorIon.h
deleted file mode 100644
index 8c0992e..0000000
--- a/media/libstagefright/codec2/vndk/include/C2AllocatorIon.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef STAGEFRIGHT_CODEC2_ALLOCATOR_ION_H_
-#define STAGEFRIGHT_CODEC2_ALLOCATOR_ION_H_
-
-#include <functional>
-
-#include <C2Buffer.h>
-
-namespace android {
-
-class C2AllocatorIon : public C2Allocator {
-public:
-    // (usage, capacity) => (align, heapMask, flags)
-    typedef std::function<int (C2MemoryUsage, size_t,
-                      /* => */ size_t*, unsigned*, unsigned*)> usage_mapper_fn;
-
-    virtual id_t getId() const override;
-
-    virtual C2String getName() const override;
-
-    virtual std::shared_ptr<const Traits> getTraits() const override;
-
-    virtual c2_status_t newLinearAllocation(
-            uint32_t capacity, C2MemoryUsage usage,
-            std::shared_ptr<C2LinearAllocation> *allocation) override;
-
-    virtual c2_status_t priorLinearAllocation(
-            const C2Handle *handle,
-            std::shared_ptr<C2LinearAllocation> *allocation) override;
-
-    C2AllocatorIon(id_t id);
-
-    virtual c2_status_t status() const { return mInit; }
-
-    virtual ~C2AllocatorIon() override;
-
-    static bool isValid(const C2Handle* const o);
-
-private:
-    std::shared_ptr<const Traits> mTraits;
-    c2_status_t mInit;
-    int mIonFd;
-    usage_mapper_fn mUsageMapper;
-};
-
-} // namespace android
-
-#endif // STAGEFRIGHT_CODEC2_ALLOCATOR_ION_H_
diff --git a/media/libstagefright/codec2/vndk/include/C2BufferPriv.h b/media/libstagefright/codec2/vndk/include/C2BufferPriv.h
deleted file mode 100644
index 211c13a..0000000
--- a/media/libstagefright/codec2/vndk/include/C2BufferPriv.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef STAGEFRIGHT_CODEC2_BUFFER_PRIV_H_
-#define STAGEFRIGHT_CODEC2_BUFFER_PRIV_H_
-
-#include <functional>
-
-#include <C2Buffer.h>
-
-class C2BasicLinearBlockPool : public C2BlockPool {
-public:
-    explicit C2BasicLinearBlockPool(const std::shared_ptr<C2Allocator> &allocator);
-
-    virtual ~C2BasicLinearBlockPool() override = default;
-
-    virtual C2Allocator::id_t getAllocatorId() const override {
-        return mAllocator->getId();
-    }
-
-    virtual local_id_t getLocalId() const override {
-        return BASIC_LINEAR;
-    }
-
-    virtual c2_status_t fetchLinearBlock(
-            uint32_t capacity,
-            C2MemoryUsage usage,
-            std::shared_ptr<C2LinearBlock> *block /* nonnull */) override;
-
-    // TODO: fetchCircularBlock
-
-private:
-    const std::shared_ptr<C2Allocator> mAllocator;
-};
-
-class C2BasicGraphicBlockPool : public C2BlockPool {
-public:
-    explicit C2BasicGraphicBlockPool(const std::shared_ptr<C2Allocator> &allocator);
-
-    virtual ~C2BasicGraphicBlockPool() override = default;
-
-    virtual C2Allocator::id_t getAllocatorId() const override {
-        return mAllocator->getId();
-    }
-
-    virtual local_id_t getLocalId() const override {
-        return BASIC_GRAPHIC;
-    }
-
-    virtual c2_status_t fetchGraphicBlock(
-            uint32_t width,
-            uint32_t height,
-            uint32_t format,
-            C2MemoryUsage usage,
-            std::shared_ptr<C2GraphicBlock> *block /* nonnull */) override;
-
-private:
-    const std::shared_ptr<C2Allocator> mAllocator;
-};
-
-class C2PooledBlockPool : public C2BlockPool {
-public:
-    C2PooledBlockPool(const std::shared_ptr<C2Allocator> &allocator, const local_id_t localId);
-
-    virtual ~C2PooledBlockPool() override;
-
-    virtual C2Allocator::id_t getAllocatorId() const override {
-        return mAllocator->getId();
-    }
-
-    virtual local_id_t getLocalId() const override {
-        return mLocalId;
-    }
-
-    virtual c2_status_t fetchLinearBlock(
-            uint32_t capacity,
-            C2MemoryUsage usage,
-            std::shared_ptr<C2LinearBlock> *block /* nonnull */) override;
-
-    // TODO: fetchGraphicBlock, fetchCircularBlock
-private:
-    const std::shared_ptr<C2Allocator> mAllocator;
-    const local_id_t mLocalId;
-
-    class Impl;
-    std::unique_ptr<Impl> mImpl;
-};
-
-#endif // STAGEFRIGHT_CODEC2_BUFFER_PRIV_H_
diff --git a/media/libstagefright/codec2/vndk/include/C2ComponentFactory.h b/media/libstagefright/codec2/vndk/include/C2ComponentFactory.h
deleted file mode 100644
index f6d8b98..0000000
--- a/media/libstagefright/codec2/vndk/include/C2ComponentFactory.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2018 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 STAGEFRIGHT_CODEC2_COMPONENT_FACTORY_H_
-#define STAGEFRIGHT_CODEC2_COMPONENT_FACTORY_H_
-
-#include <C2Component.h>
-
-#include <functional>
-#include <memory>
-
-/**
- * Component factory object that enables to create a component and/or interface from a dynamically
- * linked library. This is needed because the component/interfaces are managed objects, but we
- * cannot safely create a managed object and pass it in C.
- *
- * Components/interfaces typically inherit from std::enable_shared_from_this, but C requires
- * passing simple pointer, and shared_ptr constructor needs to know the class to be constructed
- * derives from enable_shared_from_this.
- *
- */
-class C2ComponentFactory {
-public:
-    typedef std::function<void(::C2Component*)> ComponentDeleter;
-    typedef std::function<void(::C2ComponentInterface*)> InterfaceDeleter;
-
-    /**
-     * Creates a component.
-     *
-     * This method SHALL return within 100ms.
-     *
-     * \param id        component ID for the created component
-     * \param component shared pointer where the created component is stored. Cleared on
-     *                  failure and updated on success.
-     *
-     * \retval C2_OK        the component was created successfully
-     * \retval C2_TIMED_OUT could not create the component within the time limit (unexpected)
-     * \retval C2_CORRUPTED some unknown error prevented the creation of the component (unexpected)
-     *
-     * \retval C2_NO_MEMORY not enough memory to create the component
-     */
-    virtual c2_status_t createComponent(
-            c2_node_id_t id, std::shared_ptr<C2Component>* const component,
-            ComponentDeleter deleter = std::default_delete<C2Component>()) = 0;
-
-    /**
-     * Creates a component interface.
-     *
-     * This method SHALL return within 100ms.
-     *
-     * \param id        component interface ID for the created interface
-     * \param interface shared pointer where the created interface is stored. Cleared on
-     *                  failure and updated on success.
-     *
-     * \retval C2_OK        the component interface was created successfully
-     * \retval C2_TIMED_OUT could not create the component interface within the time limit
-     *                      (unexpected)
-     * \retval C2_CORRUPTED some unknown error prevented the creation of the component interface
-     *                      (unexpected)
-     *
-     * \retval C2_NO_MEMORY not enough memory to create the component interface
-     */
-    virtual c2_status_t createInterface(
-            c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface,
-            InterfaceDeleter deleter = std::default_delete<C2ComponentInterface>()) = 0;
-
-    virtual ~C2ComponentFactory() = default;
-
-    typedef ::C2ComponentFactory* (*CreateCodec2FactoryFunc)(void);
-    typedef void (*DestroyCodec2FactoryFunc)(::C2ComponentFactory*);
-};
-
-
-#endif // STAGEFRIGHT_CODEC2_COMPONENT_FACTORY_H_
diff --git a/media/libstagefright/codec2/vndk/include/C2ErrnoUtils.h b/media/libstagefright/codec2/vndk/include/C2ErrnoUtils.h
deleted file mode 100644
index 5b995f6..0000000
--- a/media/libstagefright/codec2/vndk/include/C2ErrnoUtils.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef STAGEFRIGHT_CODEC2_ERRNO_UTILS_H_
-#define STAGEFRIGHT_CODEC2_ERRNO_UTILS_H_
-
-#include <errno.h>
-#include <C2.h>
-
-// standard ERRNO mappings
-template<int N> constexpr c2_status_t _c2_errno2status_impl();
-template<> constexpr c2_status_t _c2_errno2status_impl<0>()       { return C2_OK; }
-template<> constexpr c2_status_t _c2_errno2status_impl<EINVAL>()  { return C2_BAD_VALUE; }
-template<> constexpr c2_status_t _c2_errno2status_impl<EACCES>()  { return C2_REFUSED; }
-template<> constexpr c2_status_t _c2_errno2status_impl<EPERM>()   { return C2_REFUSED; }
-template<> constexpr c2_status_t _c2_errno2status_impl<ENOMEM>()  { return C2_NO_MEMORY; }
-
-// map standard errno-s to the equivalent c2_status_t
-template<int... N> struct _c2_map_errno_impl;
-template<int E, int ... N> struct _c2_map_errno_impl<E, N...> {
-    static c2_status_t map(int result) {
-        if (result == E) {
-            return _c2_errno2status_impl <E>();
-        } else {
-            return _c2_map_errno_impl<N...>::map(result);
-        }
-    }
-};
-template<> struct _c2_map_errno_impl<> {
-    static c2_status_t map(int result) {
-        return result == 0 ? C2_OK : C2_CORRUPTED;
-    }
-};
-
-template<int... N>
-c2_status_t c2_map_errno(int result) {
-    return _c2_map_errno_impl<N...>::map(result);
-}
-
-#endif // STAGEFRIGHT_CODEC2_ERRNO_UTILS_H_
-
diff --git a/media/libstagefright/codec2/vndk/include/C2PlatformSupport.h b/media/libstagefright/codec2/vndk/include/C2PlatformSupport.h
deleted file mode 100644
index 211ee0c..0000000
--- a/media/libstagefright/codec2/vndk/include/C2PlatformSupport.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2017 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 STAGEFRIGHT_CODEC2_PLATFORM_SUPPORT_H_
-#define STAGEFRIGHT_CODEC2_PLATFORM_SUPPORT_H_
-
-#include <C2Component.h>
-#include <C2ComponentFactory.h>
-
-#include <memory>
-
-namespace android {
-
-/**
- * Returns the platform allocator store.
- * \retval nullptr if the platform allocator store could not be obtained
- */
-std::shared_ptr<C2AllocatorStore> GetCodec2PlatformAllocatorStore();
-
-/**
- * Platform allocator store IDs
- */
-class C2PlatformAllocatorStore : public C2AllocatorStore {
-public:
-    enum : id_t {
-        /**
-         * ID of the ion backed platform allocator.
-         *
-         * C2Handle consists of:
-         *   fd  shared ion buffer handle
-         *   int size (lo 32 bits)
-         *   int size (hi 32 bits)
-         *   int magic '\xc2io\x00'
-         */
-        ION = PLATFORM_START,
-
-        /**
-         * ID of the gralloc backed platform allocator.
-         *
-         * C2Handle layout is not public. Use C2AllocatorGralloc::UnwrapNativeCodec2GrallocHandle
-         * to get the underlying gralloc handle from a C2Handle, and WrapNativeCodec2GrallocHandle
-         * to create a C2Handle from a gralloc handle - for C2Allocator::priorAllocation.
-         */
-        GRALLOC,
-    };
-};
-
-/**
- * Retrieves a block pool for a component.
- *
- * \param id        the local ID of the block pool
- * \param component the component using the block pool (must be non-null)
- * \param pool      pointer to where the obtained block pool shall be stored on success. nullptr
- *                  will be stored here on failure
- *
- * \retval C2_OK        the operation was successful
- * \retval C2_BAD_VALUE the component is null
- * \retval C2_NOT_FOUND if the block pool does not exist
- * \retval C2_NO_MEMORY not enough memory to fetch the block pool (this return value is only
- *                      possible for basic pools)
- * \retval C2_TIMED_OUT the operation timed out (this return value is only possible for basic pools)
- * \retval C2_REFUSED   no permission to complete any required allocation (this return value is only
- *                      possible for basic pools)
- * \retval C2_CORRUPTED some unknown, unrecoverable error occured during operation (unexpected,
- *                      this return value is only possible for basic pools)
- */
-c2_status_t GetCodec2BlockPool(
-        C2BlockPool::local_id_t id, std::shared_ptr<const C2Component> component,
-        std::shared_ptr<C2BlockPool> *pool);
-
-/**
- * Creates a block pool.
- * \param allocatorId  the allocator ID which is used to allocate blocks
- * \param component     the component using the block pool (must be non-null)
- * \param pool          pointer to where the created block pool shall be store on success.
- *                      nullptr will be stored here on failure
- *
- * \retval C2_OK        the operation was successful
- * \retval C2_BAD_VALUE the component is null
- * \retval C2_NOT_FOUND if the allocator does not exist
- * \retval C2_NO_MEMORY not enough memory to create a block pool
- */
-c2_status_t CreateCodec2BlockPool(
-        C2PlatformAllocatorStore::id_t allocatorId,
-        std::shared_ptr<const C2Component> component,
-        std::shared_ptr<C2BlockPool> *pool);
-
-/**
- * Returns the platform component store.
- * \retval nullptr if the platform component store could not be obtained
- */
-std::shared_ptr<C2ComponentStore> GetCodec2PlatformComponentStore();
-
-} // namespace android
-
-#endif // STAGEFRIGHT_CODEC2_PLATFORM_SUPPORT_H_
diff --git a/media/libstagefright/codec2/vndk/include/util/C2ParamUtils.h b/media/libstagefright/codec2/vndk/include/util/C2ParamUtils.h
deleted file mode 100644
index 710e74b..0000000
--- a/media/libstagefright/codec2/vndk/include/util/C2ParamUtils.h
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef C2UTILS_PARAM_UTILS_H_
-#define C2UTILS_PARAM_UTILS_H_
-
-#include <C2Param.h>
-#include <util/_C2MacroUtils.h>
-
-#include <iostream>
-#include <list>
-#include <utility>
-#include <vector>
-
-/** \file
- * Utilities for parameter handling to be used by Codec2 implementations.
- */
-
-/// \cond INTERNAL
-
-/* ---------------------------- UTILITIES FOR ENUMERATION REFLECTION ---------------------------- */
-
-/**
- * Utility class that allows ignoring enum value assignment (e.g. both '(_C2EnumConst)kValue = x'
- * and '(_C2EnumConst)kValue' will eval to kValue.
- */
-template<typename T>
-class _C2EnumConst {
-public:
-    // implicit conversion from T
-    inline _C2EnumConst(T value) : _mValue(value) {}
-    // implicit conversion to T
-    inline operator T() { return _mValue; }
-    // implicit conversion to C2Value::Primitive
-    inline operator C2Value::Primitive() { return (T)_mValue; }
-    // ignore assignment and return T here to avoid implicit conversion to T later
-    inline T &operator =(T value __unused) { return _mValue; }
-private:
-    T _mValue;
-};
-
-/// mapper to get name of enum
-/// \note this will contain any initialization, which we will remove when converting to lower-case
-#define _C2_GET_ENUM_NAME(x, y) #x
-/// mapper to get value of enum
-#define _C2_GET_ENUM_VALUE(x, type) (_C2EnumConst<type>)x
-
-/// \endcond
-
-#undef DEFINE_C2_ENUM_VALUE_AUTO_HELPER
-#define DEFINE_C2_ENUM_VALUE_AUTO_HELPER(name, type, prefix, ...) \
-template<> C2FieldDescriptor::NamedValuesType C2FieldDescriptor::namedValuesFor(const name &r __unused) { \
-    return C2ParamUtils::sanitizeEnumValues( \
-            std::vector<C2Value::Primitive> { _C2_MAP(_C2_GET_ENUM_VALUE, type, __VA_ARGS__) }, \
-            { _C2_MAP(_C2_GET_ENUM_NAME, type, __VA_ARGS__) }, \
-            prefix); \
-}
-
-#undef DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER
-#define DEFINE_C2_ENUM_VALUE_CUSTOM_HELPER(name, type, names, ...) \
-template<> C2FieldDescriptor::NamedValuesType C2FieldDescriptor::namedValuesFor(const name &r __unused) { \
-    return C2ParamUtils::customEnumValues( \
-            std::vector<std::pair<C2StringLiteral, name>> names); \
-}
-
-
-class C2ParamUtils {
-private:
-    static size_t countLeadingUnderscores(C2StringLiteral a) {
-        size_t i = 0;
-        while (a[i] == '_') {
-            ++i;
-        }
-        return i;
-    }
-
-    static size_t countMatching(C2StringLiteral a, const C2String &b) {
-        for (size_t i = 0; i < b.size(); ++i) {
-            if (!a[i] || a[i] != b[i]) {
-                return i;
-            }
-        }
-        return b.size();
-    }
-
-    // ABCDef => abc-def
-    // ABCD2ef => abcd2-ef // 0
-    // ABCD2Ef => ancd2-ef // -1
-    // AbcDef => abc-def // -1
-    // Abc2Def => abc-2def
-    // Abc2def => abc-2-def
-    // _Yo => _yo
-    // _yo => _yo
-    // C2_yo => c2-yo
-    // C2__yo => c2-yo
-
-    static C2String camelCaseToDashed(C2String name) {
-        enum {
-            kNone = '.',
-            kLower = 'a',
-            kUpper = 'A',
-            kDigit = '1',
-            kDash = '-',
-            kUnderscore = '_',
-        } type = kNone;
-        size_t word_start = 0;
-        for (size_t ix = 0; ix < name.size(); ++ix) {
-            /* std::cout << name.substr(0, word_start) << "|"
-                    << name.substr(word_start, ix - word_start) << "["
-                    << name.substr(ix, 1) << "]" << name.substr(ix + 1)
-                    << ": " << (char)type << std::endl; */
-            if (isupper(name[ix])) {
-                if (type == kLower) {
-                    name.insert(ix++, 1, '-');
-                    word_start = ix;
-                }
-                name[ix] = tolower(name[ix]);
-                type = kUpper;
-            } else if (islower(name[ix])) {
-                if (type == kDigit && ix > 0) {
-                    name.insert(ix++, 1, '-');
-                    word_start = ix;
-                } else if (type == kUpper && ix > word_start + 1) {
-                    name.insert(ix++ - 1, 1, '-');
-                    word_start = ix - 1;
-                }
-                type = kLower;
-            } else if (isdigit(name[ix])) {
-                if (type == kLower) {
-                    name.insert(ix++, 1, '-');
-                    word_start = ix;
-                }
-                type = kDigit;
-            } else if (name[ix] == '_') {
-                if (type == kDash) {
-                    name.erase(ix--, 1);
-                } else if (type != kNone && type != kUnderscore) {
-                    name[ix] = '-';
-                    type = kDash;
-                    word_start = ix + 1;
-                } else {
-                    type = kUnderscore;
-                    word_start = ix + 1;
-                }
-            } else {
-                name.resize(ix);
-            }
-        }
-        // std::cout << "=> " << name << std::endl;
-        return name;
-    }
-
-    static std::vector<C2String> sanitizeEnumValueNames(
-            const std::vector<C2StringLiteral> names,
-            C2StringLiteral _prefix = NULL) {
-        std::vector<C2String> sanitizedNames;
-        C2String prefix;
-        size_t extraUnderscores = 0;
-        bool first = true;
-        if (_prefix) {
-            extraUnderscores = countLeadingUnderscores(_prefix);
-            prefix = _prefix + extraUnderscores;
-            first = false;
-            // std::cout << "prefix:" << prefix << ", underscores:" << extraUnderscores << std::endl;
-        }
-
-        // calculate prefix and minimum leading underscores
-        for (C2StringLiteral s : names) {
-            // std::cout << s << std::endl;
-            size_t underscores = countLeadingUnderscores(s);
-            if (first) {
-                extraUnderscores = underscores;
-                prefix = s + underscores;
-                first = false;
-            } else {
-                size_t matching = countMatching(
-                    s + underscores,
-                    prefix);
-                prefix.resize(matching);
-                extraUnderscores = std::min(underscores, extraUnderscores);
-            }
-            // std::cout << "prefix:" << prefix << ", underscores:" << extraUnderscores << std::endl;
-            if (prefix.size() == 0 && extraUnderscores == 0) {
-                break;
-            }
-        }
-
-        // we swallow the first underscore after upper case prefixes
-        bool upperCasePrefix = true;
-        for (size_t i = 0; i < prefix.size(); ++i) {
-            if (islower(prefix[i])) {
-                upperCasePrefix = false;
-                break;
-            }
-        }
-
-        for (C2StringLiteral s : names) {
-            size_t underscores = countLeadingUnderscores(s);
-            C2String sanitized = C2String(s, underscores - extraUnderscores);
-            sanitized.append(s + prefix.size() + underscores +
-                        (upperCasePrefix && s[prefix.size() + underscores] == '_'));
-            sanitizedNames.push_back(camelCaseToDashed(sanitized));
-        }
-
-        for (C2String s : sanitizedNames) {
-            std::cout << s << std::endl;
-        }
-
-        return sanitizedNames;
-    }
-
-    friend class C2ParamTest_ParamUtilsTest_Test;
-
-public:
-    static std::vector<C2String> parseEnumValuesFromString(C2StringLiteral value) {
-        std::vector<C2String> foundNames;
-        size_t pos = 0, len = strlen(value);
-        do {
-            size_t endPos = strcspn(value + pos, " ,=") + pos;
-            if (endPos > pos) {
-                foundNames.emplace_back(value + pos, endPos - pos);
-            }
-            if (value[endPos] && value[endPos] != ',') {
-                endPos += strcspn(value + endPos, ",");
-            }
-            pos = strspn(value + endPos, " ,") + endPos;
-        } while (pos < len);
-        return foundNames;
-    }
-
-    template<typename T>
-    static C2FieldDescriptor::NamedValuesType sanitizeEnumValues(
-            std::vector<T> values,
-            std::vector<C2StringLiteral> names,
-            C2StringLiteral prefix = NULL) {
-        C2FieldDescriptor::NamedValuesType namedValues;
-        std::vector<C2String> sanitizedNames = sanitizeEnumValueNames(names, prefix);
-        for (size_t i = 0; i < values.size() && i < sanitizedNames.size(); ++i) {
-            namedValues.emplace_back(sanitizedNames[i], values[i]);
-        }
-        return namedValues;
-    }
-
-    template<typename E>
-    static C2FieldDescriptor::NamedValuesType customEnumValues(
-            std::vector<std::pair<C2StringLiteral, E>> items) {
-        C2FieldDescriptor::NamedValuesType namedValues;
-        for (auto &item : items) {
-            namedValues.emplace_back(item.first, item.second);
-        }
-        return namedValues;
-    }
-
-    /// safe(r) parsing from parameter blob
-    static
-    C2Param *ParseFirst(const uint8_t *blob, size_t size) {
-        // _mSize must fit into size, but really C2Param must also to be a valid param
-        if (size < sizeof(C2Param)) {
-            return nullptr;
-        }
-        // _mSize must match length
-        C2Param *param = (C2Param*)blob;
-        if (param->size() > size) {
-            return nullptr;
-        }
-        return param;
-    }
-};
-
-/* ---------------------------- UTILITIES FOR PARAMETER REFLECTION ---------------------------- */
-
-/* ======================== UTILITY TEMPLATES FOR PARAMETER REFLECTION ======================== */
-
-#if 1
-template<typename... Params>
-class C2_HIDE _C2Tuple { };
-
-C2_HIDE
-void addC2Params(std::list<const C2FieldDescriptor> &, _C2Tuple<> *) {
-}
-
-template<typename T, typename... Params>
-C2_HIDE
-void addC2Params(std::list<const C2FieldDescriptor> &fields, _C2Tuple<T, Params...> *)
-{
-    //C2Param::CodeIndex index = T::CORE_INDEX;
-    //(void)index;
-    fields.insert(fields.end(), T::FIELD_LIST);
-    addC2Params(fields, (_C2Tuple<Params...> *)nullptr);
-}
-
-template<typename... Params>
-C2_HIDE
-std::list<const C2FieldDescriptor> describeC2Params() {
-    std::list<const C2FieldDescriptor> fields;
-    addC2Params(fields, (_C2Tuple<Params...> *)nullptr);
-    return fields;
-}
-
-#endif
-
-/* ---------------------------- UTILITIES FOR ENUMERATION REFLECTION ---------------------------- */
-
-#endif  // C2UTILS_PARAM_UTILS_H_
-
diff --git a/media/libstagefright/codec2/vndk/include/util/_C2MacroUtils.h b/media/libstagefright/codec2/vndk/include/util/_C2MacroUtils.h
deleted file mode 100644
index 04e9ba5..0000000
--- a/media/libstagefright/codec2/vndk/include/util/_C2MacroUtils.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef C2UTILS_MACRO_UTILS_H_
-#define C2UTILS_MACRO_UTILS_H_
-
-/** \file
- * Macro utilities for the utils library used by Codec2 implementations.
- */
-
-/// \if 0
-
-/* --------------------------------- VARIABLE ARGUMENT COUNTING --------------------------------- */
-
-// remove empty arguments - _C2_ARG() expands to '', while _C2_ARG(x) expands to ', x'
-// _C2_ARGn(...) does the same for n arguments
-#define _C2_ARG(...) , ##__VA_ARGS__
-#define _C2_ARG2(_1, _2) _C2_ARG(_1) _C2_ARG(_2)
-#define _C2_ARG4(_1, _2, _3, _4) _C2_ARG2(_1, _2) _C2_ARG2(_3, _4)
-#define _C2_ARG8(_1, _2, _3, _4, _5, _6, _7, _8) _C2_ARG4(_1, _2, _3, _4) _C2_ARG4(_5, _6, _7, _8)
-#define _C2_ARG16(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
-        _C2_ARG8(_1, _2, _3, _4, _5, _6, _7, _8) _C2_ARG8(_9, _10, _11, _12, _13, _14, _15, _16)
-
-// return the 65th argument
-#define _C2_ARGC_3(_, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, \
-        _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, \
-        _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, \
-        _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, ...) _64
-
-/// \endif
-
-/**
- * Returns the number of arguments.
- */
-// We do this by prepending 1 and appending 65 designed values such that the 65th element
-// will be the number of arguments.
-#define _C2_ARGC(...) _C2_ARGC_1(0, ##__VA_ARGS__, \
-        64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, \
-        42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \
-        20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
-
-/// \if 0
-
-// step 1. remove empty arguments - this is needed to allow trailing comma in enum definitions
-// (NOTE: we don't know which argument will have this trailing comma so we have to try all)
-#define _C2_ARGC_1(_, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, \
-        _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, \
-        _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, \
-        _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, ...) \
-    _C2_ARGC_2(_ _C2_ARG(_0) \
-    _C2_ARG16(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
-    _C2_ARG16(_17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32) \
-    _C2_ARG16(_33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48) \
-    _C2_ARG16(_49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64), \
-    ##__VA_ARGS__)
-
-// step 2. this is needed as removed arguments cannot be passed directly as empty into a macro
-#define _C2_ARGC_2(...) _C2_ARGC_3(__VA_ARGS__)
-
-/// \endif
-
-/* -------------------------------- VARIABLE ARGUMENT CONVERSION -------------------------------- */
-
-/// \if 0
-
-// macros that convert _1, _2, _3, ... to fn(_1, arg), fn(_2, arg), fn(_3, arg), ...
-#define _C2_MAP_64(fn, arg, head, ...) fn(head, arg), _C2_MAP_63(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_63(fn, arg, head, ...) fn(head, arg), _C2_MAP_62(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_62(fn, arg, head, ...) fn(head, arg), _C2_MAP_61(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_61(fn, arg, head, ...) fn(head, arg), _C2_MAP_60(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_60(fn, arg, head, ...) fn(head, arg), _C2_MAP_59(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_59(fn, arg, head, ...) fn(head, arg), _C2_MAP_58(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_58(fn, arg, head, ...) fn(head, arg), _C2_MAP_57(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_57(fn, arg, head, ...) fn(head, arg), _C2_MAP_56(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_56(fn, arg, head, ...) fn(head, arg), _C2_MAP_55(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_55(fn, arg, head, ...) fn(head, arg), _C2_MAP_54(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_54(fn, arg, head, ...) fn(head, arg), _C2_MAP_53(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_53(fn, arg, head, ...) fn(head, arg), _C2_MAP_52(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_52(fn, arg, head, ...) fn(head, arg), _C2_MAP_51(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_51(fn, arg, head, ...) fn(head, arg), _C2_MAP_50(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_50(fn, arg, head, ...) fn(head, arg), _C2_MAP_49(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_49(fn, arg, head, ...) fn(head, arg), _C2_MAP_48(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_48(fn, arg, head, ...) fn(head, arg), _C2_MAP_47(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_47(fn, arg, head, ...) fn(head, arg), _C2_MAP_46(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_46(fn, arg, head, ...) fn(head, arg), _C2_MAP_45(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_45(fn, arg, head, ...) fn(head, arg), _C2_MAP_44(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_44(fn, arg, head, ...) fn(head, arg), _C2_MAP_43(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_43(fn, arg, head, ...) fn(head, arg), _C2_MAP_42(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_42(fn, arg, head, ...) fn(head, arg), _C2_MAP_41(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_41(fn, arg, head, ...) fn(head, arg), _C2_MAP_40(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_40(fn, arg, head, ...) fn(head, arg), _C2_MAP_39(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_39(fn, arg, head, ...) fn(head, arg), _C2_MAP_38(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_38(fn, arg, head, ...) fn(head, arg), _C2_MAP_37(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_37(fn, arg, head, ...) fn(head, arg), _C2_MAP_36(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_36(fn, arg, head, ...) fn(head, arg), _C2_MAP_35(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_35(fn, arg, head, ...) fn(head, arg), _C2_MAP_34(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_34(fn, arg, head, ...) fn(head, arg), _C2_MAP_33(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_33(fn, arg, head, ...) fn(head, arg), _C2_MAP_32(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_32(fn, arg, head, ...) fn(head, arg), _C2_MAP_31(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_31(fn, arg, head, ...) fn(head, arg), _C2_MAP_30(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_30(fn, arg, head, ...) fn(head, arg), _C2_MAP_29(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_29(fn, arg, head, ...) fn(head, arg), _C2_MAP_28(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_28(fn, arg, head, ...) fn(head, arg), _C2_MAP_27(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_27(fn, arg, head, ...) fn(head, arg), _C2_MAP_26(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_26(fn, arg, head, ...) fn(head, arg), _C2_MAP_25(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_25(fn, arg, head, ...) fn(head, arg), _C2_MAP_24(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_24(fn, arg, head, ...) fn(head, arg), _C2_MAP_23(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_23(fn, arg, head, ...) fn(head, arg), _C2_MAP_22(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_22(fn, arg, head, ...) fn(head, arg), _C2_MAP_21(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_21(fn, arg, head, ...) fn(head, arg), _C2_MAP_20(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_20(fn, arg, head, ...) fn(head, arg), _C2_MAP_19(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_19(fn, arg, head, ...) fn(head, arg), _C2_MAP_18(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_18(fn, arg, head, ...) fn(head, arg), _C2_MAP_17(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_17(fn, arg, head, ...) fn(head, arg), _C2_MAP_16(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_16(fn, arg, head, ...) fn(head, arg), _C2_MAP_15(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_15(fn, arg, head, ...) fn(head, arg), _C2_MAP_14(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_14(fn, arg, head, ...) fn(head, arg), _C2_MAP_13(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_13(fn, arg, head, ...) fn(head, arg), _C2_MAP_12(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_12(fn, arg, head, ...) fn(head, arg), _C2_MAP_11(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_11(fn, arg, head, ...) fn(head, arg), _C2_MAP_10(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_10(fn, arg, head, ...) fn(head, arg), _C2_MAP_9(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_9(fn, arg, head, ...) fn(head, arg), _C2_MAP_8(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_8(fn, arg, head, ...) fn(head, arg), _C2_MAP_7(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_7(fn, arg, head, ...) fn(head, arg), _C2_MAP_6(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_6(fn, arg, head, ...) fn(head, arg), _C2_MAP_5(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_5(fn, arg, head, ...) fn(head, arg), _C2_MAP_4(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_4(fn, arg, head, ...) fn(head, arg), _C2_MAP_3(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_3(fn, arg, head, ...) fn(head, arg), _C2_MAP_2(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_2(fn, arg, head, ...) fn(head, arg), _C2_MAP_1(fn, arg, ##__VA_ARGS__)
-#define _C2_MAP_1(fn, arg, head, ...) fn(head, arg)
-
-/// \endif
-
-/**
- * Maps each argument using another macro x -> fn(x, arg)
- */
-// use wrapper to call the proper mapper based on the number of arguments
-#define _C2_MAP(fn, arg, ...) _C2_MAP__(_C2_ARGC(__VA_ARGS__), fn, arg, ##__VA_ARGS__)
-
-/// \if 0
-
-// evaluate _n so it becomes a number
-#define _C2_MAP__(_n, fn, arg, ...) _C2_MAP_(_n, fn, arg, __VA_ARGS__)
-// call the proper mapper
-#define _C2_MAP_(_n, fn, arg, ...) _C2_MAP_##_n (fn, arg, __VA_ARGS__)
-
-/// \endif
-
-#endif  // C2UTILS_MACRO_UTILS_H_
diff --git a/media/libstagefright/codec2/vndk/internal/C2BlockInternal.h b/media/libstagefright/codec2/vndk/internal/C2BlockInternal.h
deleted file mode 100644
index ff67788..0000000
--- a/media/libstagefright/codec2/vndk/internal/C2BlockInternal.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2018 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_STAGEFRIGHT_C2BLOCK_INTERNAL_H_
-#define ANDROID_STAGEFRIGHT_C2BLOCK_INTERNAL_H_
-
-#include <C2Buffer.h>
-
-struct _C2BlockPoolData;
-
-/**
- * Internal only interface for creating blocks by block pool/buffer passing implementations.
- *
- * \todo this must be hidden
- */
-struct _C2BlockFactory {
-    /**
-     * Create a linear block from an allocation for an allotted range.
-     *
-     * @param alloc parent allocation
-     * @param data  blockpool data
-     * @param offset allotted range offset
-     * @param size  allotted size
-     *
-     * @return shared pointer to the linear block. nullptr if there was not enough memory to
-     *         create this block.
-     */
-    static
-    std::shared_ptr<C2LinearBlock> CreateLinearBlock(
-            const std::shared_ptr<C2LinearAllocation> &alloc,
-            const std::shared_ptr<_C2BlockPoolData> &data = nullptr,
-            size_t offset = 0,
-            size_t size = ~(size_t)0);
-
-    /**
-     * Create a graphic block from an allocation for an allotted section.
-     *
-     * @param alloc parent allocation
-     * @param data  blockpool data
-     * @param crop  allotted crop region
-     *
-     * @return shared pointer to the graphic block. nullptr if there was not enough memory to
-     *         create this block.
-     */
-    static
-    std::shared_ptr<C2GraphicBlock> CreateGraphicBlock(
-            const std::shared_ptr<C2GraphicAllocation> &alloc,
-            const std::shared_ptr<_C2BlockPoolData> &data = nullptr,
-            const C2Rect &allottedCrop = C2Rect(~0u, ~0u));
-};
-
-#endif // ANDROID_STAGEFRIGHT_C2BLOCK_INTERNAL_H_
-
diff --git a/media/libstagefright/codec2/vndk/internal/C2ParamInternal.h b/media/libstagefright/codec2/vndk/internal/C2ParamInternal.h
deleted file mode 100644
index ba7c5d5..0000000
--- a/media/libstagefright/codec2/vndk/internal/C2ParamInternal.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2018 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_STAGEFRIGHT_C2PARAM_INTERNAL_H_
-#define ANDROID_STAGEFRIGHT_C2PARAM_INTERNAL_H_
-
-#include <C2Param.h>
-
-struct C2_HIDE _C2ParamInspector {
-    inline static uint32_t GetOffset(const C2FieldDescriptor &fd) {
-        return fd._mFieldId._mOffset;
-    }
-
-    inline static uint32_t GetSize(const C2FieldDescriptor &fd) {
-        return fd._mFieldId._mSize;
-    }
-
-    inline static uint32_t GetIndex(const C2ParamField &pf) {
-        return pf._mIndex;
-    }
-
-    inline static uint32_t GetOffset(const C2ParamField &pf) {
-        return pf._mFieldId._mOffset;
-    }
-
-    inline static uint32_t GetSize(const C2ParamField &pf) {
-        return pf._mFieldId._mSize;
-    }
-
-    inline static uint32_t GetAttrib(const C2ParamDescriptor &pd) {
-        return pd._mAttrib;
-    }
-
-    inline static
-    C2ParamField CreateParamField(C2Param::Index index, uint32_t offset, uint32_t size) {
-        return C2ParamField(index, offset, size);
-    }
-
-    inline static
-    C2ParamField CreateParamField(C2Param::Index index, _C2FieldId field) {
-        return C2ParamField(index, field._mOffset, field._mSize);
-    }
-
-    // expose attributes
-    typedef C2ParamDescriptor::attrib_t attrib_t;
-};
-
-#endif // ANDROID_STAGEFRIGHT_C2PARAM_INTERNAL_H_
-
diff --git a/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp b/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp
index d0b72b7..2c0f224 100644
--- a/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp
+++ b/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp
@@ -45,9 +45,11 @@
         OMX_COMPONENTTYPE **component)
     : SimpleSoftOMXComponent(name, callbacks, appData, component),
       mFLACDecoder(NULL),
-      mHasStreamInfo(false),
       mInputBufferCount(0),
+      mHasStreamInfo(false),
       mSignalledError(false),
+      mSawInputEOS(false),
+      mFinishedDecoder(false),
       mOutputPortSettingsChange(NONE) {
     ALOGV("ctor:");
     memset(&mStreamInfo, 0, sizeof(mStreamInfo));
@@ -292,7 +294,6 @@
 }
 
 void SoftFlacDecoder::onQueueFilled(OMX_U32 /* portIndex */) {
-    ALOGV("onQueueFilled:");
     if (mSignalledError || mOutputPortSettingsChange != NONE) {
         return;
     }
@@ -300,96 +301,114 @@
     List<BufferInfo *> &inQueue = getPortQueue(0);
     List<BufferInfo *> &outQueue = getPortQueue(1);
 
-    while (!inQueue.empty() && !outQueue.empty()) {
-        BufferInfo *inInfo = *inQueue.begin();
-        OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+    ALOGV("onQueueFilled %d/%d:", inQueue.empty(), outQueue.empty());
+    while ((!inQueue.empty() || mSawInputEOS) && !outQueue.empty() && !mFinishedDecoder) {
         BufferInfo *outInfo = *outQueue.begin();
         OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
-        uint8_t* inBuffer = inHeader->pBuffer + inHeader->nOffset;
-        uint32_t inBufferLength = inHeader->nFilledLen;
-        bool endOfInput = (inHeader->nFlags & OMX_BUFFERFLAG_EOS) != 0;
+        short *outBuffer = reinterpret_cast<short *>(outHeader->pBuffer + outHeader->nOffset);
+        size_t outBufferSize = outHeader->nAllocLen - outHeader->nOffset;
+        int64_t timeStamp = 0;
 
-        if (inHeader->nFilledLen == 0) {
-            if (endOfInput) {
-                outHeader->nFilledLen = 0;
-                outHeader->nFlags = OMX_BUFFERFLAG_EOS;
-                outInfo->mOwnedByUs = false;
-                outQueue.erase(outQueue.begin());
-                notifyFillBufferDone(outHeader);
-            } else {
-                ALOGE("onQueueFilled: emptyInputBuffer received");
+        if (!inQueue.empty()) {
+            BufferInfo *inInfo = *inQueue.begin();
+            OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+            uint8_t* inBuffer = inHeader->pBuffer + inHeader->nOffset;
+            uint32_t inBufferLength = inHeader->nFilledLen;
+            ALOGV("input: %u bytes", inBufferLength);
+            if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+                ALOGV("saw EOS");
+                mSawInputEOS = true;
+                if (mInputBufferCount == 0 && inHeader->nFilledLen == 0) {
+                    // first buffer was empty and EOS: signal EOS on output and return
+                    ALOGV("empty first EOS");
+                    outHeader->nFilledLen = 0;
+                    outHeader->nTimeStamp = inHeader->nTimeStamp;
+                    outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+                    outInfo->mOwnedByUs = false;
+                    outQueue.erase(outQueue.begin());
+                    notifyFillBufferDone(outHeader);
+                    mFinishedDecoder = true;
+                    inInfo->mOwnedByUs = false;
+                    inQueue.erase(inQueue.begin());
+                    notifyEmptyBufferDone(inHeader);
+                    return;
+                }
             }
-            inInfo->mOwnedByUs = false;
-            inQueue.erase(inQueue.begin());
-            notifyEmptyBufferDone(inHeader);
-            return;
-        }
-        if (mInputBufferCount == 0 && !(inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
-            ALOGE("onQueueFilled: first buffer should have OMX_BUFFERFLAG_CODECCONFIG set");
-            inHeader->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
-        }
-        if ((inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != 0) {
-            status_t decoderErr = mFLACDecoder->parseMetadata(inBuffer, inBufferLength);
-            mInputBufferCount++;
 
-            if (decoderErr != OK && decoderErr != WOULD_BLOCK) {
-                ALOGE("onQueueFilled: FLACDecoder parseMetaData returns error %d", decoderErr);
+            if (mInputBufferCount == 0 && !(inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
+                ALOGE("onQueueFilled: first buffer should have OMX_BUFFERFLAG_CODECCONFIG set");
+                inHeader->nFlags |= OMX_BUFFERFLAG_CODECCONFIG;
+            }
+            if ((inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) != 0) {
+                ALOGV("received config buffer of size %u", inBufferLength);
+                status_t decoderErr = mFLACDecoder->parseMetadata(inBuffer, inBufferLength);
+                mInputBufferCount++;
+
+                if (decoderErr != OK && decoderErr != WOULD_BLOCK) {
+                    ALOGE("onQueueFilled: FLACDecoder parseMetaData returns error %d", decoderErr);
+                    mSignalledError = true;
+                    notify(OMX_EventError, OMX_ErrorStreamCorrupt, decoderErr, NULL);
+                    return;
+                }
+
+                inInfo->mOwnedByUs = false;
+                inQueue.erase(inQueue.begin());
+                notifyEmptyBufferDone(inHeader);
+
+                if (decoderErr == WOULD_BLOCK) {
+                    continue;
+                }
+                mStreamInfo = mFLACDecoder->getStreamInfo();
+                mHasStreamInfo = true;
+
+                // Only send out port settings changed event if both sample rate
+                // and numChannels are valid.
+                if (mStreamInfo.sample_rate && mStreamInfo.channels) {
+                    ALOGD("onQueueFilled: initially configuring decoder: %d Hz, %d channels",
+                        mStreamInfo.sample_rate, mStreamInfo.channels);
+
+                    notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
+                    mOutputPortSettingsChange = AWAITING_DISABLED;
+                }
+                return;
+            }
+
+            status_t decoderErr = mFLACDecoder->decodeOneFrame(
+                    inBuffer, inBufferLength, outBuffer, &outBufferSize);
+            if (decoderErr != OK) {
+                ALOGE("onQueueFilled: FLACDecoder decodeOneFrame returns error %d", decoderErr);
                 mSignalledError = true;
                 notify(OMX_EventError, OMX_ErrorStreamCorrupt, decoderErr, NULL);
                 return;
             }
 
+            mInputBufferCount++;
+            timeStamp = inHeader->nTimeStamp;
             inInfo->mOwnedByUs = false;
             inQueue.erase(inQueue.begin());
             notifyEmptyBufferDone(inHeader);
 
-            if (decoderErr == WOULD_BLOCK) {
+            if (outBufferSize == 0) {
+                ALOGV("no output, trying again");
                 continue;
             }
-            mStreamInfo = mFLACDecoder->getStreamInfo();
-            mHasStreamInfo = true;
-
-            // Only send out port settings changed event if both sample rate
-            // and numChannels are valid.
-            if (mStreamInfo.sample_rate && mStreamInfo.channels) {
-                ALOGD("onQueueFilled: initially configuring decoder: %d Hz, %d channels",
-                    mStreamInfo.sample_rate, mStreamInfo.channels);
-
-                notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
-                mOutputPortSettingsChange = AWAITING_DISABLED;
+        } else if (mSawInputEOS) {
+            status_t decoderErr = mFLACDecoder->decodeOneFrame(NULL, 0, outBuffer, &outBufferSize);
+            mFinishedDecoder = true;
+            if (decoderErr != OK) {
+                ALOGE("onQueueFilled: FLACDecoder finish returns error %d", decoderErr);
+                mSignalledError = true;
+                notify(OMX_EventError, OMX_ErrorStreamCorrupt, decoderErr, NULL);
+                return;
             }
-            return;
-        }
-
-        short *outBuffer =
-                reinterpret_cast<short *>(outHeader->pBuffer + outHeader->nOffset);
-        size_t outBufferSize = outHeader->nAllocLen - outHeader->nOffset;
-
-        status_t decoderErr = mFLACDecoder->decodeOneFrame(
-                inBuffer, inBufferLength, outBuffer, &outBufferSize);
-        if (decoderErr != OK) {
-            ALOGE("onQueueFilled: FLACDecoder decodeOneFrame returns error %d", decoderErr);
-            mSignalledError = true;
-            notify(OMX_EventError, OMX_ErrorStreamCorrupt, decoderErr, NULL);
-            return;
-        }
-
-        mInputBufferCount++;
-        int64_t ts = inHeader->nTimeStamp;
-        inInfo->mOwnedByUs = false;
-        inQueue.erase(inQueue.begin());
-        notifyEmptyBufferDone(inHeader);
-
-        if (endOfInput) {
             outHeader->nFlags = OMX_BUFFERFLAG_EOS;
-        } else if (outBufferSize == 0) {
-            continue;
         } else {
-            outHeader->nFlags = 0;
+            // no more input buffers at this time, loop and see if there is more output
+            continue;
         }
 
         outHeader->nFilledLen = outBufferSize;
-        outHeader->nTimeStamp = ts;
+        outHeader->nTimeStamp = timeStamp;
 
         outInfo->mOwnedByUs = false;
         outQueue.erase(outQueue.begin());
@@ -406,9 +425,12 @@
 
 void SoftFlacDecoder::drainDecoder() {
     mFLACDecoder->flush();
+    mSawInputEOS = false;
+    mFinishedDecoder = false;
 }
 
 void SoftFlacDecoder::onReset() {
+    ALOGV("onReset");
     drainDecoder();
 
     memset(&mStreamInfo, 0, sizeof(mStreamInfo));
diff --git a/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.h b/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.h
index 0f17ed8..b63f7ad 100644
--- a/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.h
+++ b/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.h
@@ -52,9 +52,11 @@
 
     FLACDecoder *mFLACDecoder;
     FLAC__StreamMetadata_StreamInfo mStreamInfo;
-    bool mHasStreamInfo;
     size_t mInputBufferCount;
+    bool mHasStreamInfo;
     bool mSignalledError;
+    bool mSawInputEOS;
+    bool mFinishedDecoder;
 
     enum {
         NONE,
diff --git a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
index 56d2d69..fdc8975 100644
--- a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
+++ b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
@@ -56,12 +56,13 @@
       mCompressionLevel(FLAC_COMPRESSION_LEVEL_DEFAULT),
       mEncoderWriteData(false),
       mEncoderReturnedEncodedData(false),
+      mSawInputEOS(false),
+      mSentOutputEOS(false),
       mEncoderReturnedNbBytes(0),
-      mInputBufferPcm32(NULL)
-#ifdef WRITE_FLAC_HEADER_IN_FIRST_BUFFER
-      , mHeaderOffset(0)
-      , mWroteHeader(false)
-#endif
+      mInputBufferPcm32(NULL),
+      mHeaderOffset(0),
+      mHeaderComplete(false),
+      mWroteHeader(false)
 {
     ALOGV("SoftFlacEncoder::SoftFlacEncoder(name=%s)", name);
     initPorts();
@@ -354,55 +355,55 @@
     List<BufferInfo *> &inQueue = getPortQueue(0);
     List<BufferInfo *> &outQueue = getPortQueue(1);
 
-    while (!inQueue.empty() && !outQueue.empty()) {
-        BufferInfo *inInfo = *inQueue.begin();
-        OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+    FLAC__bool ok = true;
+
+    while ((!inQueue.empty() || mSawInputEOS) && !outQueue.empty() && !mSentOutputEOS) {
+        if (!inQueue.empty()) {
+            BufferInfo *inInfo = *inQueue.begin();
+            OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+
+            if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+                ALOGV("saw EOS on buffer of size %u", inHeader->nFilledLen);
+                mSawInputEOS = true;
+            }
+
+            if (inHeader->nFilledLen > kMaxInputBufferSize) {
+                ALOGE("input buffer too large (%d).", inHeader->nFilledLen);
+                mSignalledError = true;
+                notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+                return;
+            }
+
+            assert(mNumChannels != 0);
+            mEncoderWriteData = true;
+            mEncoderReturnedEncodedData = false;
+            mEncoderReturnedNbBytes = 0;
+            mCurrentInputTimeStamp = inHeader->nTimeStamp;
+
+            const unsigned nbInputFrames = inHeader->nFilledLen / (2 * mNumChannels);
+            const unsigned nbInputSamples = inHeader->nFilledLen / 2;
+            const OMX_S16 * const pcm16 = reinterpret_cast<OMX_S16 *>(inHeader->pBuffer);
+
+            CHECK_LE(nbInputSamples, 2 * kMaxNumSamplesPerFrame);
+            for (unsigned i=0 ; i < nbInputSamples ; i++) {
+                mInputBufferPcm32[i] = (FLAC__int32) pcm16[i];
+            }
+            ALOGV(" about to encode %u samples per channel", nbInputFrames);
+            ok = FLAC__stream_encoder_process_interleaved(
+                            mFlacStreamEncoder,
+                            mInputBufferPcm32,
+                            nbInputFrames /*samples per channel*/ );
+
+            inInfo->mOwnedByUs = false;
+            inQueue.erase(inQueue.begin());
+            inInfo = NULL;
+            notifyEmptyBufferDone(inHeader);
+            inHeader = NULL;
+        }
 
         BufferInfo *outInfo = *outQueue.begin();
         OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
 
-        if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
-            inQueue.erase(inQueue.begin());
-            inInfo->mOwnedByUs = false;
-            notifyEmptyBufferDone(inHeader);
-
-            outHeader->nFilledLen = 0;
-            outHeader->nFlags = OMX_BUFFERFLAG_EOS;
-
-            outQueue.erase(outQueue.begin());
-            outInfo->mOwnedByUs = false;
-            notifyFillBufferDone(outHeader);
-
-            return;
-        }
-
-        if (inHeader->nFilledLen > kMaxInputBufferSize) {
-            ALOGE("input buffer too large (%d).", inHeader->nFilledLen);
-            mSignalledError = true;
-            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
-            return;
-        }
-
-        assert(mNumChannels != 0);
-        mEncoderWriteData = true;
-        mEncoderReturnedEncodedData = false;
-        mEncoderReturnedNbBytes = 0;
-        mCurrentInputTimeStamp = inHeader->nTimeStamp;
-
-        const unsigned nbInputFrames = inHeader->nFilledLen / (2 * mNumChannels);
-        const unsigned nbInputSamples = inHeader->nFilledLen / 2;
-        const OMX_S16 * const pcm16 = reinterpret_cast<OMX_S16 *>(inHeader->pBuffer);
-
-        CHECK_LE(nbInputSamples, 2 * kMaxNumSamplesPerFrame);
-        for (unsigned i=0 ; i < nbInputSamples ; i++) {
-            mInputBufferPcm32[i] = (FLAC__int32) pcm16[i];
-        }
-        ALOGV(" about to encode %u samples per channel", nbInputFrames);
-        FLAC__bool ok = FLAC__stream_encoder_process_interleaved(
-                        mFlacStreamEncoder,
-                        mInputBufferPcm32,
-                        nbInputFrames /*samples per channel*/ );
-
         if (ok) {
             if (mEncoderReturnedEncodedData && (mEncoderReturnedNbBytes != 0)) {
                 ALOGV(" dequeueing buffer on output port after writing data");
@@ -414,6 +415,21 @@
                 mEncoderReturnedEncodedData = false;
             } else {
                 ALOGV(" encoder process_interleaved returned without data to write");
+                if (mSawInputEOS) {
+                    ALOGV("finishing encoder");
+                    mSentOutputEOS = true;
+                    FLAC__stream_encoder_finish(mFlacStreamEncoder);
+                    if (mEncoderReturnedEncodedData && (mEncoderReturnedNbBytes != 0)) {
+                        ALOGV(" dequeueing residual buffer on output port after writing data");
+                        outInfo->mOwnedByUs = false;
+                        outQueue.erase(outQueue.begin());
+                        outInfo = NULL;
+                        outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+                        notifyFillBufferDone(outHeader);
+                        outHeader = NULL;
+                        mEncoderReturnedEncodedData = false;
+                    }
+                }
             }
         } else {
             ALOGE(" error encountered during encoding");
@@ -422,11 +438,6 @@
             return;
         }
 
-        inInfo->mOwnedByUs = false;
-        inQueue.erase(inQueue.begin());
-        inInfo = NULL;
-        notifyEmptyBufferDone(inHeader);
-        inHeader = NULL;
     }
 }
 
@@ -438,16 +449,22 @@
     ALOGV("SoftFlacEncoder::onEncodedFlacAvailable(bytes=%zu, samples=%u, curr_frame=%u)",
             bytes, samples, current_frame);
 
-#ifdef WRITE_FLAC_HEADER_IN_FIRST_BUFFER
     if (samples == 0) {
-        ALOGI(" saving %zu bytes of header", bytes);
-        memcpy(mHeader + mHeaderOffset, buffer, bytes);
-        mHeaderOffset += bytes;// will contain header size when finished receiving header
+        ALOGV("saving %zu bytes of header", bytes);
+        if (mHeaderOffset + bytes > sizeof(mHeader) || mHeaderComplete) {
+            ALOGW("header is too big, or header already received");
+            mSignalledError = true;
+            notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+        } else {
+            memcpy(mHeader + mHeaderOffset, buffer, bytes);
+            mHeaderOffset += bytes;// will contain header size when finished receiving header
+            if (buffer[0] & 0x80) {
+                mHeaderComplete = true;
+            }
+        }
         return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
     }
 
-#endif
-
     if ((samples == 0) || !mEncoderWriteData) {
         // called by the encoder because there's header data to save, but it's not the role
         // of this component (unless WRITE_FLAC_HEADER_IN_FIRST_BUFFER is defined)
@@ -460,16 +477,23 @@
     BufferInfo *outInfo = *outQueue.begin();
     OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
 
-#ifdef WRITE_FLAC_HEADER_IN_FIRST_BUFFER
-    if (!mWroteHeader) {
-        ALOGI(" writing %d bytes of header on output port", mHeaderOffset);
+    if (mHeaderComplete && !mWroteHeader) {
+        ALOGV(" writing %d bytes of header on output port", mHeaderOffset);
         memcpy(outHeader->pBuffer + outHeader->nOffset + outHeader->nFilledLen,
                 mHeader, mHeaderOffset);
         outHeader->nFilledLen += mHeaderOffset;
-        outHeader->nOffset    += mHeaderOffset;
         mWroteHeader = true;
+        outInfo->mOwnedByUs = false;
+        outQueue.erase(outQueue.begin());
+        outHeader->nFlags = OMX_BUFFERFLAG_CODECCONFIG;
+        notifyFillBufferDone(outHeader);
+        outInfo = NULL;
+        outHeader = NULL;
+        // get the next buffer for the rest of the data
+        CHECK(!outQueue.empty());
+        outInfo = *outQueue.begin();
+        outHeader = outInfo->mHeader;
     }
-#endif
 
     // write encoded data
     ALOGV(" writing %zu bytes of encoded data on output port", bytes);
diff --git a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.h b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.h
index f4f0655..64a6b1e 100644
--- a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.h
+++ b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.h
@@ -22,10 +22,6 @@
 
 #include "FLAC/stream_encoder.h"
 
-// use this symbol to have the first output buffer start with FLAC frame header so a dump of
-// all the output buffers can be opened as a .flac file
-//#define WRITE_FLAC_HEADER_IN_FIRST_BUFFER
-
 namespace android {
 
 struct SoftFlacEncoder : public SimpleSoftOMXComponent {
@@ -62,6 +58,8 @@
     // should the data received by the callback be written to the output port
     bool        mEncoderWriteData;
     bool        mEncoderReturnedEncodedData;
+    bool        mSawInputEOS;
+    bool        mSentOutputEOS;
     size_t      mEncoderReturnedNbBytes;
     OMX_TICKS  mCurrentInputTimeStamp;
 
@@ -85,11 +83,10 @@
     // before passing the input data to the encoder
     FLAC__int32* mInputBufferPcm32;
 
-#ifdef WRITE_FLAC_HEADER_IN_FIRST_BUFFER
     unsigned mHeaderOffset;
+    bool mHeaderComplete;
     bool mWroteHeader;
     char mHeader[128];
-#endif
 
     DISALLOW_EVIL_CONSTRUCTORS(SoftFlacEncoder);
 };
diff --git a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
index 103fc22..bb7d361 100644
--- a/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
+++ b/media/libstagefright/codecs/hevcdec/SoftHEVC.cpp
@@ -48,7 +48,8 @@
         (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_NUM_CORES
 
 static const CodecProfileLevel kProfileLevels[] = {
-    { OMX_VIDEO_HEVCProfileMain, OMX_VIDEO_HEVCMainTierLevel51 },
+    { OMX_VIDEO_HEVCProfileMain,      OMX_VIDEO_HEVCMainTierLevel51 },
+    { OMX_VIDEO_HEVCProfileMainStill, OMX_VIDEO_HEVCMainTierLevel51 },
 };
 
 SoftHEVC::SoftHEVC(
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.h b/media/libstagefright/codecs/on2/dec/SoftVPX.h
index 9ac2791..b62b526 100644
--- a/media/libstagefright/codecs/on2/dec/SoftVPX.h
+++ b/media/libstagefright/codecs/on2/dec/SoftVPX.h
@@ -44,7 +44,7 @@
 
 private:
     enum {
-        kNumBuffers = 16
+        kNumBuffers = 10
     };
 
     enum {
diff --git a/media/libstagefright/colorconversion/ColorConverter.cpp b/media/libstagefright/colorconversion/ColorConverter.cpp
index eae73fc..1b38852 100644
--- a/media/libstagefright/colorconversion/ColorConverter.cpp
+++ b/media/libstagefright/colorconversion/ColorConverter.cpp
@@ -818,7 +818,8 @@
     uint16_t *dst_ptr = (uint16_t *)dst.mBits
         + dst.mCropTop * dst.mWidth + dst.mCropLeft;
 
-    const uint8_t *src_y = (const uint8_t *)src.mBits;
+    const uint8_t *src_y =
+        (const uint8_t *)src.mBits + src.mCropTop * src.mWidth + src.mCropLeft;
 
     const uint8_t *src_u =
         (const uint8_t *)src_y + src.mWidth * (src.mHeight - src.mCropTop / 2);
diff --git a/media/libstagefright/flac/dec/FLACDecoder.cpp b/media/libstagefright/flac/dec/FLACDecoder.cpp
index e0e9211..a2b6ab7 100644
--- a/media/libstagefright/flac/dec/FLACDecoder.cpp
+++ b/media/libstagefright/flac/dec/FLACDecoder.cpp
@@ -423,22 +423,16 @@
         short *outBuffer, size_t *outBufferLen) {
     ALOGV("decodeOneFrame: input size(%zu)", inBufferLen);
 
-    if (inBufferLen == 0) {
-        ALOGV("decodeOneFrame: no input data");
-        if (outBufferLen) {
-            *outBufferLen = 0;
-        }
-        return OK;
-    }
-
     if (!mStreamInfoValid) {
         ALOGW("decodeOneFrame: no streaminfo metadata block");
     }
 
-    status_t err = addDataToBuffer(inBuffer, inBufferLen);
-    if (err != OK) {
-        ALOGW("decodeOneFrame: addDataToBuffer returns error %d", err);
-        return err;
+    if (inBufferLen != 0) {
+        status_t err = addDataToBuffer(inBuffer, inBufferLen);
+        if (err != OK) {
+            ALOGW("decodeOneFrame: addDataToBuffer returns error %d", err);
+            return err;
+        }
     }
 
     mWriteRequested = true;
diff --git a/media/libstagefright/foundation/AMessage.cpp b/media/libstagefright/foundation/AMessage.cpp
index f55de64..3b84018 100644
--- a/media/libstagefright/foundation/AMessage.cpp
+++ b/media/libstagefright/foundation/AMessage.cpp
@@ -944,4 +944,47 @@
     return mItems[index].mName;
 }
 
+status_t AMessage::setEntryNameAt(size_t index, const char *name) {
+    if (index >= mNumItems) {
+        return BAD_INDEX;
+    }
+    if (name == nullptr) {
+        return BAD_VALUE;
+    }
+    if (!strcmp(name, mItems[index].mName)) {
+        return OK; // name has not changed
+    }
+    size_t len = strlen(name);
+    if (findItemIndex(name, len) < mNumItems) {
+        return ALREADY_EXISTS;
+    }
+    delete[] mItems[index].mName;
+    mItems[index].mName = nullptr;
+    mItems[index].setName(name, len);
+    return OK;
+}
+
+status_t AMessage::removeEntryAt(size_t index) {
+    if (index >= mNumItems) {
+        return BAD_INDEX;
+    }
+    // delete entry data and objects
+    --mNumItems;
+    delete[] mItems[index].mName;
+    mItems[index].mName = nullptr;
+    freeItemValue(&mItems[index]);
+
+    // swap entry with last entry and clear last entry's data
+    if (index < mNumItems) {
+        mItems[index] = mItems[mNumItems];
+        mItems[mNumItems].mName = nullptr;
+        mItems[mNumItems].mType = kTypeInt32;
+    }
+    return OK;
+}
+
+size_t AMessage::findEntryByName(const char *name) const {
+    return name == nullptr ? countEntries() : findItemIndex(name, strlen(name));
+}
+
 }  // namespace android
diff --git a/media/libstagefright/foundation/Android.bp b/media/libstagefright/foundation/Android.bp
index b343c16..f663542 100644
--- a/media/libstagefright/foundation/Android.bp
+++ b/media/libstagefright/foundation/Android.bp
@@ -24,10 +24,12 @@
     header_libs: [
         "libhardware_headers",
         "libstagefright_foundation_headers",
+        "media_plugin_headers",
     ],
 
     export_header_lib_headers: [
         "libstagefright_foundation_headers",
+        "media_plugin_headers",
     ],
 
     export_shared_lib_headers: [
diff --git a/media/libstagefright/foundation/include/media/stagefright/foundation/AMessage.h b/media/libstagefright/foundation/include/media/stagefright/foundation/AMessage.h
index 8580eb5..d90a0de 100644
--- a/media/libstagefright/foundation/include/media/stagefright/foundation/AMessage.h
+++ b/media/libstagefright/foundation/include/media/stagefright/foundation/AMessage.h
@@ -183,6 +183,36 @@
     size_t countEntries() const;
     const char *getEntryNameAt(size_t index, Type *type) const;
 
+    /**
+     * Finds an entry by name and returns its index.
+     *
+     * \retval countEntries() if the entry is not found.
+     */
+    size_t findEntryByName(const char *name) const;
+
+    /**
+     * Sets the name of an entry based on index.
+     *
+     * \param index index of the entry
+     * \param name (new) name of the entry
+     *
+     * \retval OK the name was set successfully
+     * \retval BAD_INDEX invalid index
+     * \retval BAD_VALUE name is invalid (null)
+     * \retval ALREADY_EXISTS name is already used by another entry
+     */
+    status_t setEntryNameAt(size_t index, const char *name);
+
+    /**
+     * Removes an entry based on index.
+     *
+     * \param index index of the entry
+     *
+     * \retval OK the entry was removed successfully
+     * \retval BAD_INDEX invalid index
+     */
+    status_t removeEntryAt(size_t index);
+
 protected:
     virtual ~AMessage();
 
diff --git a/media/libstagefright/include/media/stagefright/ACodec.h b/media/libstagefright/include/media/stagefright/ACodec.h
index 1a5304b..64caeed 100644
--- a/media/libstagefright/include/media/stagefright/ACodec.h
+++ b/media/libstagefright/include/media/stagefright/ACodec.h
@@ -493,7 +493,8 @@
     status_t setupHEVCEncoderParameters(const sp<AMessage> &msg, sp<AMessage> &outputFormat);
     status_t setupVPXEncoderParameters(const sp<AMessage> &msg, sp<AMessage> &outputFormat);
 
-    status_t verifySupportForProfileAndLevel(int32_t profile, int32_t level);
+    status_t verifySupportForProfileAndLevel(
+            OMX_U32 portIndex, int32_t profile, int32_t level);
 
     status_t configureImageGrid(const sp<AMessage> &msg, sp<AMessage> &outputFormat);
     status_t configureBitrate(
diff --git a/media/libstagefright/include/media/stagefright/MediaClock.h b/media/libstagefright/include/media/stagefright/MediaClock.h
index 7511913..3ddeb82 100644
--- a/media/libstagefright/include/media/stagefright/MediaClock.h
+++ b/media/libstagefright/include/media/stagefright/MediaClock.h
@@ -66,6 +66,8 @@
     // mediaTimeUs + (adjustRealUs / playbackRate)
     void addTimer(const sp<AMessage> &notify, int64_t mediaTimeUs, int64_t adjustRealUs = 0);
 
+    void setNotificationMessage(const sp<AMessage> &msg);
+
     void reset();
 
 protected:
@@ -92,6 +94,11 @@
 
     void processTimers_l();
 
+    void updateAnchorTimesAndPlaybackRate_l(
+            int64_t anchorTimeMediaUs, int64_t anchorTimeRealUs , float playbackRate);
+
+    void notifyDiscontinuity_l();
+
     sp<ALooper> mLooper;
     mutable Mutex mLock;
 
@@ -104,6 +111,7 @@
 
     int32_t mGeneration;
     std::list<Timer> mTimers;
+    sp<AMessage> mNotify;
 
     DISALLOW_EVIL_CONSTRUCTORS(MediaClock);
 };
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index ef8de1f..48a1224 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -320,7 +320,9 @@
 
     MediaAnalyticsItem *mAnalyticsItem;
     void initAnalyticsItem();
+    void updateAnalyticsItem();
     void flushAnalyticsItem();
+    void updateEphemeralAnalytics(MediaAnalyticsItem *item);
 
     sp<AMessage> mOutputFormat;
     sp<AMessage> mInputFormat;
@@ -441,6 +443,63 @@
 
     void onReleaseCrypto(const sp<AMessage>& msg);
 
+    // managing time-of-flight aka latency
+    typedef struct {
+            int64_t presentationUs;
+            int64_t startedNs;
+    } BufferFlightTiming_t;
+    std::deque<BufferFlightTiming_t> mBuffersInFlight;
+    Mutex mLatencyLock;
+    int64_t mLatencyUnknown;    // buffers for which we couldn't calculate latency
+
+    void statsBufferSent(int64_t presentationUs);
+    void statsBufferReceived(int64_t presentationUs);
+
+    enum {
+        // the default shape of our latency histogram buckets
+        // XXX: should these be configurable in some way?
+        kLatencyHistBuckets = 20,
+        kLatencyHistWidth = 2000,
+        kLatencyHistFloor = 2000,
+
+        // how many samples are in the 'recent latency' histogram
+        // 300 frames = 5 sec @ 60fps or ~12 sec @ 24fps
+        kRecentLatencyFrames = 300,
+
+        // how we initialize mRecentSamples
+        kRecentSampleInvalid = -1,
+    };
+
+    int64_t mRecentSamples[kRecentLatencyFrames];
+    int mRecentHead;
+    Mutex mRecentLock;
+
+    class Histogram {
+      public:
+        Histogram() : mFloor(0), mWidth(0), mBelow(0), mAbove(0),
+                      mMin(INT64_MAX), mMax(INT64_MIN), mSum(0), mCount(0),
+                      mBucketCount(0), mBuckets(NULL) {};
+        ~Histogram() { clear(); };
+        void clear() { if (mBuckets != NULL) free(mBuckets); mBuckets = NULL; };
+        bool setup(int nbuckets, int64_t width, int64_t floor = 0);
+        void insert(int64_t sample);
+        int64_t getMin() const { return mMin; }
+        int64_t getMax() const { return mMax; }
+        int64_t getCount() const { return mCount; }
+        int64_t getSum() const { return mSum; }
+        int64_t getAvg() const { return mSum / (mCount == 0 ? 1 : mCount); }
+        std::string emit();
+      private:
+        int64_t mFloor, mCeiling, mWidth;
+        int64_t mBelow, mAbove;
+        int64_t mMin, mMax, mSum, mCount;
+
+        int mBucketCount;
+        int64_t *mBuckets;
+    };
+
+    Histogram mLatencyHist;
+
     DISALLOW_EVIL_CONSTRUCTORS(MediaCodec);
 };
 
diff --git a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
index 8ef7620..cd0f75c 100644
--- a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
@@ -563,6 +563,10 @@
             DescribeColorAspectsParams* colorAspectsParams =
                     (DescribeColorAspectsParams *)params;
 
+            if (!isValidOMXParam(colorAspectsParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
             if (colorAspectsParams->nPortIndex != kOutputPortIndex) {
                 return OMX_ErrorBadParameter;
             }
@@ -584,6 +588,10 @@
             DescribeHDRStaticInfoParams* hdrStaticInfoParams =
                     (DescribeHDRStaticInfoParams *)params;
 
+            if (!isValidOMXParam(hdrStaticInfoParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
             if (hdrStaticInfoParams->nPortIndex != kOutputPortIndex) {
                 return OMX_ErrorBadPortIndex;
             }
@@ -635,15 +643,17 @@
             const DescribeHDRStaticInfoParams* hdrStaticInfoParams =
                     (DescribeHDRStaticInfoParams *)params;
 
+            if (!isValidOMXParam(hdrStaticInfoParams)) {
+                return OMX_ErrorBadParameter;
+            }
+
             if (hdrStaticInfoParams->nPortIndex != kOutputPortIndex) {
                 return OMX_ErrorBadPortIndex;
             }
 
-            if (hdrStaticInfoParams != NULL) {
-                mOutputFormat = OMX_COLOR_FormatYUV420Planar16;
-                mHdrStaticInfo = hdrStaticInfoParams->sInfo;
-                updatePortDefinitions(false);
-            }
+            mOutputFormat = OMX_COLOR_FormatYUV420Planar16;
+            mHdrStaticInfo = hdrStaticInfoParams->sInfo;
+            updatePortDefinitions(false);
 
             return OMX_ErrorNone;
         }
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
index 903a2b6..a9fce55 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
@@ -20,6 +20,7 @@
 #include <vector>
 #include <list>
 
+#include <cinttypes>
 #include <unistd.h>
 
 #include <hidl/MQDescriptor.h>
@@ -35,6 +36,7 @@
 #include <media/OMXFenceParcelable.h>
 #include <media/OMXBuffer.h>
 #include <media/hardware/VideoAPI.h>
+#include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/bqhelper/Conversion.h>
 
 #include <android/hidl/memory/1.0/IMemory.h>
@@ -141,6 +143,37 @@
  */
 
 /**
+ * \brief Convert `Status` to `status_t`. This is for legacy binder calls.
+ *
+ * \param[in] t The source `Status`.
+ * \return the corresponding `status_t`.
+ */
+// convert: Status -> status_t
+inline status_t toStatusT(Status const& t) {
+    switch (t) {
+    case Status::NO_ERROR:
+    case Status::NAME_NOT_FOUND:
+    case Status::WOULD_BLOCK:
+    case Status::NO_MEMORY:
+    case Status::ALREADY_EXISTS:
+    case Status::NO_INIT:
+    case Status::BAD_VALUE:
+    case Status::DEAD_OBJECT:
+    case Status::INVALID_OPERATION:
+    case Status::TIMED_OUT:
+    case Status::ERROR_UNSUPPORTED:
+    case Status::UNKNOWN_ERROR:
+    case Status::RELEASE_ALL_BUFFERS:
+        return static_cast<status_t>(t);
+    case Status::BUFFER_NEEDS_REALLOCATION:
+        return NOT_ENOUGH_DATA;
+    default:
+        ALOGW("Unrecognized status value: %" PRId32, static_cast<int32_t>(t));
+        return static_cast<status_t>(t);
+    }
+}
+
+/**
  * \brief Convert `Return<Status>` to `status_t`. This is for legacy binder
  * calls.
  *
@@ -157,18 +190,7 @@
  */
 // convert: Status -> status_t
 inline status_t toStatusT(Return<Status> const& t) {
-    return t.isOk() ? static_cast<status_t>(static_cast<Status>(t)) : UNKNOWN_ERROR;
-}
-
-/**
- * \brief Convert `Status` to `status_t`. This is for legacy binder calls.
- *
- * \param[in] t The source `Status`.
- * \return the corresponding `status_t`.
- */
-// convert: Status -> status_t
-inline status_t toStatusT(Status const& t) {
-    return static_cast<status_t>(t);
+    return t.isOk() ? toStatusT(static_cast<Status>(t)) : UNKNOWN_ERROR;
 }
 
 /**
@@ -179,7 +201,28 @@
  */
 // convert: status_t -> Status
 inline Status toStatus(status_t l) {
-    return static_cast<Status>(l);
+    switch (l) {
+    case NO_ERROR:
+    case NAME_NOT_FOUND:
+    case WOULD_BLOCK:
+    case NO_MEMORY:
+    case ALREADY_EXISTS:
+    case NO_INIT:
+    case BAD_VALUE:
+    case DEAD_OBJECT:
+    case INVALID_OPERATION:
+    case TIMED_OUT:
+    case ERROR_UNSUPPORTED:
+    case UNKNOWN_ERROR:
+    case IGraphicBufferProducer::RELEASE_ALL_BUFFERS:
+    case IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION:
+        return static_cast<Status>(l);
+    case NOT_ENOUGH_DATA:
+        return Status::BUFFER_NEEDS_REALLOCATION;
+    default:
+        ALOGW("Unrecognized status value: %" PRId32, static_cast<int32_t>(l));
+        return static_cast<Status>(l);
+    }
 }
 
 /**
diff --git a/media/mtp/Android.bp b/media/mtp/Android.bp
index acea373..2cf9b82 100644
--- a/media/mtp/Android.bp
+++ b/media/mtp/Android.bp
@@ -49,7 +49,6 @@
     shared_libs: [
         "libasyncio",
         "libbase",
-        "libutils",
         "liblog",
         "libusbhost",
     ],
diff --git a/media/mtp/IMtpDatabase.h b/media/mtp/IMtpDatabase.h
index d09a984..1245092 100644
--- a/media/mtp/IMtpDatabase.h
+++ b/media/mtp/IMtpDatabase.h
@@ -24,6 +24,7 @@
 class MtpDataPacket;
 class MtpProperty;
 class MtpObjectInfo;
+class MtpStringBuffer;
 
 class IMtpDatabase {
 public:
@@ -86,7 +87,7 @@
     virtual void*                   getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) = 0;
 
     virtual MtpResponseCode         getObjectFilePath(MtpObjectHandle handle,
-                                            MtpString& outFilePath,
+                                            MtpStringBuffer& outFilePath,
                                             int64_t& outFileLength,
                                             MtpObjectFormat& outFormat) = 0;
 
diff --git a/media/mtp/IMtpHandle.h b/media/mtp/IMtpHandle.h
index c65bdd0..fd14b18 100644
--- a/media/mtp/IMtpHandle.h
+++ b/media/mtp/IMtpHandle.h
@@ -32,8 +32,7 @@
     virtual int sendEvent(mtp_event me) = 0;
 
     // Return 0 if operation is successful, or -1 else
-    virtual int start() = 0;
-    virtual int configure(bool ptp) = 0;
+    virtual int start(bool ptp) = 0;
 
     virtual void close() = 0;
 
diff --git a/media/mtp/MtpDataPacket.cpp b/media/mtp/MtpDataPacket.cpp
index d1c71d7..992dc9a 100644
--- a/media/mtp/MtpDataPacket.cpp
+++ b/media/mtp/MtpDataPacket.cpp
@@ -19,6 +19,7 @@
 #include "MtpDataPacket.h"
 
 #include <algorithm>
+#include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <sys/types.h>
@@ -129,7 +130,7 @@
             delete result;
             return NULL;
         }
-        result->push(value);
+        result->push_back(value);
     }
     return result;
 }
@@ -145,7 +146,7 @@
             delete result;
             return NULL;
         }
-        result->push(value);
+        result->push_back(value);
     }
     return result;
 }
@@ -161,7 +162,7 @@
             delete result;
             return NULL;
         }
-        result->push(value);
+        result->push_back(value);
     }
     return result;
 }
@@ -177,7 +178,7 @@
             delete result;
             return NULL;
         }
-        result->push(value);
+        result->push_back(value);
     }
     return result;
 }
@@ -193,7 +194,7 @@
             delete result;
             return NULL;
         }
-        result->push(value);
+        result->push_back(value);
     }
     return result;
 }
@@ -209,7 +210,7 @@
             delete result;
             return NULL;
         }
-        result->push(value);
+        result->push_back(value);
     }
     return result;
 }
@@ -225,7 +226,7 @@
             delete result;
             return NULL;
         }
-        result->push(value);
+        result->push_back(value);
     }
     return result;
 }
@@ -241,7 +242,7 @@
             delete result;
             return NULL;
         }
-        result->push(value);
+        result->push_back(value);
     }
     return result;
 }
diff --git a/media/mtp/MtpDebug.h b/media/mtp/MtpDebug.h
index 5b53e31..8d48273 100644
--- a/media/mtp/MtpDebug.h
+++ b/media/mtp/MtpDebug.h
@@ -18,10 +18,10 @@
 #define _MTP_DEBUG_H
 
 // #define LOG_NDEBUG 0
-#include <utils/Log.h>
-
 #include "MtpTypes.h"
 
+#include <log/log.h>
+
 namespace android {
 
 class MtpDebug {
diff --git a/media/mtp/MtpDescriptors.cpp b/media/mtp/MtpDescriptors.cpp
index d9b6060..4a336c8 100644
--- a/media/mtp/MtpDescriptors.cpp
+++ b/media/mtp/MtpDescriptors.cpp
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+#include <android-base/logging.h>
+#include <sys/types.h>
+
 #include "MtpDescriptors.h"
 
 namespace android {
@@ -257,4 +260,24 @@
     .hs_descs = ptp_hs_descriptors,
 };
 
+bool writeDescriptors(int fd, bool ptp) {
+    ssize_t ret = TEMP_FAILURE_RETRY(write(fd,
+                &(ptp ? ptp_desc_v2 : mtp_desc_v2), sizeof(desc_v2)));
+    if (ret < 0) {
+        PLOG(ERROR) << fd << "Switching to V1 descriptor format";
+        ret = TEMP_FAILURE_RETRY(write(fd,
+                    &(ptp ? ptp_desc_v1 : mtp_desc_v1), sizeof(desc_v1)));
+        if (ret < 0) {
+            PLOG(ERROR) << fd << "Writing descriptors failed";
+            return false;
+        }
+    }
+    ret = TEMP_FAILURE_RETRY(write(fd, &mtp_strings, sizeof(mtp_strings)));
+    if (ret < 0) {
+        PLOG(ERROR) << fd << "Writing strings failed";
+        return false;
+    }
+    return true;
+}
+
 }; // namespace android
diff --git a/media/mtp/MtpDescriptors.h b/media/mtp/MtpDescriptors.h
index cfc3930..d600a24 100644
--- a/media/mtp/MtpDescriptors.h
+++ b/media/mtp/MtpDescriptors.h
@@ -23,6 +23,16 @@
 
 namespace android {
 
+constexpr char FFS_MTP_EP0[] = "/dev/usb-ffs/mtp/ep0";
+constexpr char FFS_MTP_EP_IN[] = "/dev/usb-ffs/mtp/ep1";
+constexpr char FFS_MTP_EP_OUT[] = "/dev/usb-ffs/mtp/ep2";
+constexpr char FFS_MTP_EP_INTR[] = "/dev/usb-ffs/mtp/ep3";
+
+constexpr char FFS_PTP_EP0[] = "/dev/usb-ffs/ptp/ep0";
+constexpr char FFS_PTP_EP_IN[] = "/dev/usb-ffs/ptp/ep1";
+constexpr char FFS_PTP_EP_OUT[] = "/dev/usb-ffs/ptp/ep2";
+constexpr char FFS_PTP_EP_INTR[] = "/dev/usb-ffs/ptp/ep3";
+
 constexpr int MAX_PACKET_SIZE_FS = 64;
 constexpr int MAX_PACKET_SIZE_HS = 512;
 constexpr int MAX_PACKET_SIZE_SS = 1024;
@@ -91,6 +101,8 @@
 extern const struct desc_v1 ptp_desc_v1;
 extern const struct functionfs_strings mtp_strings;
 
+bool writeDescriptors(int fd, bool ptp);
+
 }; // namespace android
 
 #endif // MTP_DESCRIPTORS_H
diff --git a/media/mtp/MtpDevHandle.cpp b/media/mtp/MtpDevHandle.cpp
index 6aa57ac..e8bdf80 100644
--- a/media/mtp/MtpDevHandle.cpp
+++ b/media/mtp/MtpDevHandle.cpp
@@ -60,7 +60,7 @@
     return ioctl(mFd, MTP_SEND_EVENT, reinterpret_cast<unsigned long>(&me));
 }
 
-int MtpDevHandle::start() {
+int MtpDevHandle::start(bool /* ptp */) {
     mFd.reset(TEMP_FAILURE_RETRY(open(mtp_dev_path, O_RDWR)));
     if (mFd == -1) return -1;
     return 0;
@@ -70,9 +70,4 @@
     mFd.reset();
 }
 
-int MtpDevHandle::configure(bool) {
-    // Nothing to do, driver can configure itself
-    return 0;
-}
-
 } // namespace android
diff --git a/media/mtp/MtpDevHandle.h b/media/mtp/MtpDevHandle.h
index b0480ed..740ac85 100644
--- a/media/mtp/MtpDevHandle.h
+++ b/media/mtp/MtpDevHandle.h
@@ -36,10 +36,8 @@
     int sendFile(mtp_file_range mfr);
     int sendEvent(mtp_event me);
 
-    int start();
+    int start(bool ptp);
     void close();
-
-    int configure(bool ptp);
 };
 
 } // namespace android
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index 0bf7854..993797a 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -262,7 +262,7 @@
                 MtpDeviceProperty propCode = (*mDeviceInfo->mDeviceProperties)[i];
                 MtpProperty* property = getDevicePropDesc(propCode);
                 if (property)
-                    mDeviceProperties.push(property);
+                    mDeviceProperties.push_back(property);
             }
         }
     }
@@ -327,7 +327,7 @@
 }
 
 bool MtpDevice::openSession() {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mSessionID = 0;
     mTransactionID = 0;
@@ -353,7 +353,7 @@
 }
 
 MtpDeviceInfo* MtpDevice::getDeviceInfo() {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     if (!sendRequest(MTP_OPERATION_GET_DEVICE_INFO))
@@ -372,7 +372,7 @@
 }
 
 MtpStorageIDList* MtpDevice::getStorageIDs() {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     if (!sendRequest(MTP_OPERATION_GET_STORAGE_IDS))
@@ -387,7 +387,7 @@
 }
 
 MtpStorageInfo* MtpDevice::getStorageInfo(MtpStorageID storageID) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, storageID);
@@ -408,7 +408,7 @@
 
 MtpObjectHandleList* MtpDevice::getObjectHandles(MtpStorageID storageID,
             MtpObjectFormat format, MtpObjectHandle parent) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, storageID);
@@ -426,7 +426,7 @@
 }
 
 MtpObjectInfo* MtpDevice::getObjectInfo(MtpObjectHandle handle) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     // FIXME - we might want to add some caching here
 
@@ -448,7 +448,7 @@
 }
 
 void* MtpDevice::getThumbnail(MtpObjectHandle handle, int& outLength) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, handle);
@@ -463,7 +463,7 @@
 }
 
 MtpObjectHandle MtpDevice::sendObjectInfo(MtpObjectInfo* info) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     MtpObjectHandle parent = info->mParent;
@@ -517,7 +517,7 @@
 }
 
 bool MtpDevice::sendObject(MtpObjectHandle handle, int size, int srcFD) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     if (mLastSendObjectInfoTransactionID + 1 != mTransactionID ||
             mLastSendObjectInfoObjectHandle != handle) {
@@ -537,7 +537,7 @@
 }
 
 bool MtpDevice::deleteObject(MtpObjectHandle handle) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, handle);
@@ -572,7 +572,7 @@
 }
 
 MtpObjectPropertyList* MtpDevice::getObjectPropsSupported(MtpObjectFormat format) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, format);
@@ -589,7 +589,7 @@
 }
 
 MtpProperty* MtpDevice::getDevicePropDesc(MtpDeviceProperty code) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, code);
@@ -609,7 +609,7 @@
 }
 
 MtpProperty* MtpDevice::getObjectPropDesc(MtpObjectProperty code, MtpObjectFormat format) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, code);
@@ -633,7 +633,7 @@
     if (property == nullptr)
         return false;
 
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, handle);
@@ -684,7 +684,7 @@
                                    ReadObjectCallback callback,
                                    const uint32_t* expectedLength,
                                    void* clientData) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, handle);
@@ -806,7 +806,7 @@
                                   uint32_t *writtenSize,
                                   ReadObjectCallback callback,
                                   void* clientData) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, handle);
@@ -828,7 +828,7 @@
                                     uint32_t *writtenSize,
                                     ReadObjectCallback callback,
                                     void* clientData) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     mRequest.reset();
     mRequest.setParameter(1, handle);
@@ -908,7 +908,7 @@
 }
 
 int MtpDevice::submitEventRequest() {
-    if (mEventMutex.tryLock()) {
+    if (!mEventMutex.try_lock()) {
         // An event is being reaped on another thread.
         return -1;
     }
@@ -916,7 +916,7 @@
         // An event request was submitted, but no reapEventRequest called so far.
         return -1;
     }
-    Mutex::Autolock autoLock(mEventMutexForInterrupt);
+    std::lock_guard<std::mutex> lg(mEventMutexForInterrupt);
     mEventPacket.sendRequest(mRequestIntr);
     const int currentHandle = ++mCurrentEventHandle;
     mProcessingEvent = true;
@@ -925,7 +925,7 @@
 }
 
 int MtpDevice::reapEventRequest(int handle, uint32_t (*parameters)[3]) {
-    Mutex::Autolock autoLock(mEventMutex);
+    std::lock_guard<std::mutex> lg(mEventMutex);
     if (!mProcessingEvent || mCurrentEventHandle != handle || !parameters) {
         return -1;
     }
@@ -940,7 +940,7 @@
 }
 
 void MtpDevice::discardEventRequest(int handle) {
-    Mutex::Autolock autoLock(mEventMutexForInterrupt);
+    std::lock_guard<std::mutex> lg(mEventMutexForInterrupt);
     if (mCurrentEventHandle != handle) {
         return;
     }
diff --git a/media/mtp/MtpDevice.h b/media/mtp/MtpDevice.h
index a9a3e0e..8cf9e5e 100644
--- a/media/mtp/MtpDevice.h
+++ b/media/mtp/MtpDevice.h
@@ -23,7 +23,7 @@
 #include "MtpResponsePacket.h"
 #include "MtpTypes.h"
 
-#include <utils/threads.h>
+#include <mutex>
 
 struct usb_device;
 struct usb_request;
@@ -67,9 +67,9 @@
     MtpObjectHandle         mLastSendObjectInfoObjectHandle;
 
     // to ensure only one MTP transaction at a time
-    Mutex                   mMutex;
-    Mutex                   mEventMutex;
-    Mutex                   mEventMutexForInterrupt;
+    std::mutex              mMutex;
+    std::mutex              mEventMutex;
+    std::mutex              mEventMutexForInterrupt;
 
     // Remember the device's packet division mode.
     UrbPacketDivisionMode   mPacketDivisionMode;
diff --git a/media/mtp/MtpEventPacket.h b/media/mtp/MtpEventPacket.h
index 3f3b6a3..94d6ebf 100644
--- a/media/mtp/MtpEventPacket.h
+++ b/media/mtp/MtpEventPacket.h
@@ -20,6 +20,8 @@
 #include "MtpPacket.h"
 #include "mtp.h"
 
+#include <errno.h>
+
 class IMtpHandle;
 
 namespace android {
diff --git a/media/mtp/MtpFfsCompatHandle.cpp b/media/mtp/MtpFfsCompatHandle.cpp
index 3dd73f3..d2b342c 100644
--- a/media/mtp/MtpFfsCompatHandle.cpp
+++ b/media/mtp/MtpFfsCompatHandle.cpp
@@ -61,7 +61,8 @@
 
 namespace android {
 
-MtpFfsCompatHandle::MtpFfsCompatHandle() :
+MtpFfsCompatHandle::MtpFfsCompatHandle(int controlFd) :
+    MtpFfsHandle(controlFd),
     mMaxWrite(USB_FFS_MAX_WRITE),
     mMaxRead(USB_FFS_MAX_READ) {}
 
@@ -108,10 +109,8 @@
     return ret;
 }
 
-int MtpFfsCompatHandle::start() {
-    mLock.lock();
-
-    if (!openEndpoints())
+int MtpFfsCompatHandle::start(bool ptp) {
+    if (!openEndpoints(ptp))
         return -1;
 
     for (unsigned i = 0; i < NUM_IO_BUFS; i++) {
diff --git a/media/mtp/MtpFfsCompatHandle.h b/media/mtp/MtpFfsCompatHandle.h
index cd61482..5982d60 100644
--- a/media/mtp/MtpFfsCompatHandle.h
+++ b/media/mtp/MtpFfsCompatHandle.h
@@ -42,9 +42,9 @@
      * Open ffs endpoints and allocate necessary kernel and user memory.
      * Will sleep until endpoints are enabled, for up to 1 second.
      */
-    int start() override;
+    int start(bool ptp) override;
 
-    MtpFfsCompatHandle();
+    MtpFfsCompatHandle(int controlFd);
     ~MtpFfsCompatHandle();
 };
 
diff --git a/media/mtp/MtpFfsHandle.cpp b/media/mtp/MtpFfsHandle.cpp
index 217e0c9..952b907 100644
--- a/media/mtp/MtpFfsHandle.cpp
+++ b/media/mtp/MtpFfsHandle.cpp
@@ -39,10 +39,6 @@
 
 namespace {
 
-constexpr char FFS_MTP_EP_IN[] = "/dev/usb-ffs/mtp/ep1";
-constexpr char FFS_MTP_EP_OUT[] = "/dev/usb-ffs/mtp/ep2";
-constexpr char FFS_MTP_EP_INTR[] = "/dev/usb-ffs/mtp/ep3";
-
 constexpr unsigned AIO_BUFS_MAX = 128;
 constexpr unsigned AIO_BUF_LEN = 16384;
 
@@ -73,7 +69,9 @@
     }
 }
 
-MtpFfsHandle::MtpFfsHandle() {}
+MtpFfsHandle::MtpFfsHandle(int controlFd) {
+    mControl.reset(controlFd);
+}
 
 MtpFfsHandle::~MtpFfsHandle() {}
 
@@ -83,27 +81,27 @@
     mBulkOut.reset();
 }
 
-bool MtpFfsHandle::openEndpoints() {
+bool MtpFfsHandle::openEndpoints(bool ptp) {
     if (mBulkIn < 0) {
-        mBulkIn.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_IN, O_RDWR)));
+        mBulkIn.reset(TEMP_FAILURE_RETRY(open(ptp ? FFS_PTP_EP_IN : FFS_MTP_EP_IN, O_RDWR)));
         if (mBulkIn < 0) {
-            PLOG(ERROR) << FFS_MTP_EP_IN << ": cannot open bulk in ep";
+            PLOG(ERROR) << (ptp ? FFS_PTP_EP_IN : FFS_MTP_EP_IN) << ": cannot open bulk in ep";
             return false;
         }
     }
 
     if (mBulkOut < 0) {
-        mBulkOut.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_OUT, O_RDWR)));
+        mBulkOut.reset(TEMP_FAILURE_RETRY(open(ptp ? FFS_PTP_EP_OUT : FFS_MTP_EP_OUT, O_RDWR)));
         if (mBulkOut < 0) {
-            PLOG(ERROR) << FFS_MTP_EP_OUT << ": cannot open bulk out ep";
+            PLOG(ERROR) << (ptp ? FFS_PTP_EP_OUT : FFS_MTP_EP_OUT) << ": cannot open bulk out ep";
             return false;
         }
     }
 
     if (mIntr < 0) {
-        mIntr.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP_INTR, O_RDWR)));
+        mIntr.reset(TEMP_FAILURE_RETRY(open(ptp ? FFS_PTP_EP_INTR : FFS_MTP_EP_INTR, O_RDWR)));
         if (mIntr < 0) {
-            PLOG(ERROR) << FFS_MTP_EP_INTR << ": cannot open intr ep";
+            PLOG(ERROR) << (ptp ? FFS_PTP_EP_INTR : FFS_MTP_EP_INTR) << ": cannot open intr ep";
             return false;
         }
     }
@@ -121,39 +119,8 @@
         PLOG(ERROR) << "Failed to fadvise";
 }
 
-bool MtpFfsHandle::initFunctionfs() {
-    if (mControl < 0) { // might have already done this before
-        mControl.reset(TEMP_FAILURE_RETRY(open(FFS_MTP_EP0, O_RDWR)));
-        if (mControl < 0) {
-            PLOG(ERROR) << FFS_MTP_EP0 << ": cannot open control endpoint";
-            return false;
-        }
-        if (!writeDescriptors()) {
-            closeConfig();
-            return false;
-        }
-    }
-    return true;
-}
-
-bool MtpFfsHandle::writeDescriptors() {
-    ssize_t ret = TEMP_FAILURE_RETRY(::write(mControl,
-                &(mPtp ? ptp_desc_v2 : mtp_desc_v2), sizeof(desc_v2)));
-    if (ret < 0) {
-        PLOG(ERROR) << FFS_MTP_EP0 << "Switching to V1 descriptor format";
-        ret = TEMP_FAILURE_RETRY(::write(mControl,
-                    &(mPtp ? ptp_desc_v1 : mtp_desc_v1), sizeof(desc_v1)));
-        if (ret < 0) {
-            PLOG(ERROR) << FFS_MTP_EP0 << "Writing descriptors failed";
-            return false;
-        }
-    }
-    ret = TEMP_FAILURE_RETRY(::write(mControl, &mtp_strings, sizeof(mtp_strings)));
-    if (ret < 0) {
-        PLOG(ERROR) << FFS_MTP_EP0 << "Writing strings failed";
-        return false;
-    }
-    return true;
+bool MtpFfsHandle::writeDescriptors(bool ptp) {
+    return ::android::writeDescriptors(mControl, ptp);
 }
 
 void MtpFfsHandle::closeConfig() {
@@ -197,11 +164,9 @@
         switch (event->type) {
         case FUNCTIONFS_BIND:
         case FUNCTIONFS_ENABLE:
-        case FUNCTIONFS_RESUME:
             ret = 0;
             errno = 0;
             break;
-        case FUNCTIONFS_SUSPEND:
         case FUNCTIONFS_UNBIND:
         case FUNCTIONFS_DISABLE:
             errno = ESHUTDOWN;
@@ -211,6 +176,9 @@
             if (handleControlRequest(&event->u.setup) == -1)
                 ret = -1;
             break;
+        case FUNCTIONFS_SUSPEND:
+        case FUNCTIONFS_RESUME:
+            break;
         default:
             LOG(ERROR) << "Mtp Event " << event->type << " (unknown)";
         }
@@ -277,10 +245,8 @@
     return 0;
 }
 
-int MtpFfsHandle::start() {
-    mLock.lock();
-
-    if (!openEndpoints())
+int MtpFfsHandle::start(bool ptp) {
+    if (!openEndpoints(ptp))
         return -1;
 
     for (unsigned i = 0; i < NUM_IO_BUFS; i++) {
@@ -309,33 +275,10 @@
     return 0;
 }
 
-int MtpFfsHandle::configure(bool usePtp) {
-    // Wait till previous server invocation has closed
-    if (!mLock.try_lock_for(std::chrono::milliseconds(300))) {
-        LOG(ERROR) << "MtpServer was unable to get configure lock";
-        return -1;
-    }
-    int ret = 0;
-
-    // If ptp is changed, the configuration must be rewritten
-    if (mPtp != usePtp) {
-        closeEndpoints();
-        closeConfig();
-    }
-    mPtp = usePtp;
-
-    if (!initFunctionfs()) {
-        ret = -1;
-    }
-
-    mLock.unlock();
-    return ret;
-}
-
 void MtpFfsHandle::close() {
     io_destroy(mCtx);
     closeEndpoints();
-    mLock.unlock();
+    closeConfig();
 }
 
 int MtpFfsHandle::waitEvents(struct io_buffer *buf, int min_events, struct io_event *events,
diff --git a/media/mtp/MtpFfsHandle.h b/media/mtp/MtpFfsHandle.h
index 2347000..24a8bd5 100644
--- a/media/mtp/MtpFfsHandle.h
+++ b/media/mtp/MtpFfsHandle.h
@@ -29,8 +29,6 @@
 
 namespace android {
 
-constexpr char FFS_MTP_EP0[] = "/dev/usb-ffs/mtp/ep0";
-
 constexpr int NUM_IO_BUFS = 2;
 
 struct io_buffer {
@@ -42,14 +40,10 @@
 };
 
 template <class T> class MtpFfsHandleTest;
-template <class T> class MtpFfsHandleTest_testControl_Test;
 
 class MtpFfsHandle : public IMtpHandle {
     template <class T> friend class MtpFfsHandleTest;
-    template <class T> friend class MtpFfsHandleTest_testControl_Test;
 protected:
-    bool initFunctionfs();
-    bool writeDescriptors();
     void closeConfig();
     void closeEndpoints();
     void advise(int fd);
@@ -58,15 +52,12 @@
     int handleEvent();
     void cancelTransaction();
     void doSendEvent(mtp_event me);
-    bool openEndpoints();
+    bool openEndpoints(bool ptp);
 
     static int getPacketSize(int ffs_fd);
 
-    bool mPtp;
     bool mCanceled;
 
-    std::timed_mutex mLock; // protects configure() vs main loop
-
     android::base::unique_fd mControl;
     // "in" from the host's perspective => sink for mtp server
     android::base::unique_fd mBulkIn;
@@ -99,12 +90,12 @@
     int sendFile(mtp_file_range mfr) override;
     int sendEvent(mtp_event me) override;
 
-    int start() override;
+    int start(bool ptp) override;
     void close() override;
 
-    int configure(bool ptp) override;
+    bool writeDescriptors(bool ptp);
 
-    MtpFfsHandle();
+    MtpFfsHandle(int controlFd);
     ~MtpFfsHandle();
 };
 
diff --git a/media/mtp/MtpPacket.h b/media/mtp/MtpPacket.h
index d47c91d..9842b28 100644
--- a/media/mtp/MtpPacket.h
+++ b/media/mtp/MtpPacket.h
@@ -19,6 +19,7 @@
 
 #include <android-base/macros.h>
 
+#include "MtpDebug.h"
 #include "MtpTypes.h"
 
 struct usb_device;
diff --git a/media/mtp/MtpProperty.cpp b/media/mtp/MtpProperty.cpp
index 039e4f5..5c02a0d 100644
--- a/media/mtp/MtpProperty.cpp
+++ b/media/mtp/MtpProperty.cpp
@@ -18,6 +18,10 @@
 
 #include <inttypes.h>
 #include <cutils/compiler.h>
+#include <iomanip>
+#include <sstream>
+#include <string>
+
 #include "MtpDataPacket.h"
 #include "MtpDebug.h"
 #include "MtpProperty.h"
@@ -336,7 +340,7 @@
 }
 
 void MtpProperty::print() {
-    MtpString buffer;
+    std::string buffer;
     bool deviceProp = isDeviceProperty();
     if (deviceProp)
         ALOGI("    %s (%04X)", MtpDebug::getDevicePropCodeName(mCode), mCode);
@@ -346,11 +350,11 @@
     ALOGI("    writeable %s", (mWriteable ? "true" : "false"));
     buffer = "    default value: ";
     print(mDefaultValue, buffer);
-    ALOGI("%s", (const char *)buffer);
+    ALOGI("%s", buffer.c_str());
     if (deviceProp) {
         buffer = "    current value: ";
         print(mCurrentValue, buffer);
-        ALOGI("%s", (const char *)buffer);
+        ALOGI("%s", buffer.c_str());
     }
     switch (mFormFlag) {
         case kFormNone:
@@ -363,7 +367,7 @@
             buffer += ", ";
             print(mStepSize, buffer);
             buffer += ")";
-            ALOGI("%s", (const char *)buffer);
+            ALOGI("%s", buffer.c_str());
             break;
         case kFormEnum:
             buffer = "    Enum { ";
@@ -372,7 +376,7 @@
                 buffer += " ";
             }
             buffer += "}";
-            ALOGI("%s", (const char *)buffer);
+            ALOGI("%s", buffer.c_str());
             break;
         case kFormDateTime:
             ALOGI("    DateTime\n");
@@ -383,42 +387,47 @@
     }
 }
 
-void MtpProperty::print(MtpPropertyValue& value, MtpString& buffer) {
+void MtpProperty::print(MtpPropertyValue& value, std::string& buffer) {
+    std::ostringstream s;
     switch (mType) {
         case MTP_TYPE_INT8:
-            buffer.appendFormat("%d", value.u.i8);
+            buffer += std::to_string(value.u.i8);
             break;
         case MTP_TYPE_UINT8:
-            buffer.appendFormat("%d", value.u.u8);
+            buffer += std::to_string(value.u.u8);
             break;
         case MTP_TYPE_INT16:
-            buffer.appendFormat("%d", value.u.i16);
+            buffer += std::to_string(value.u.i16);
             break;
         case MTP_TYPE_UINT16:
-            buffer.appendFormat("%d", value.u.u16);
+            buffer += std::to_string(value.u.u16);
             break;
         case MTP_TYPE_INT32:
-            buffer.appendFormat("%d", value.u.i32);
+            buffer += std::to_string(value.u.i32);
             break;
         case MTP_TYPE_UINT32:
-            buffer.appendFormat("%d", value.u.u32);
+            buffer += std::to_string(value.u.u32);
             break;
         case MTP_TYPE_INT64:
-            buffer.appendFormat("%" PRId64, value.u.i64);
+            buffer += std::to_string(value.u.i64);
             break;
         case MTP_TYPE_UINT64:
-            buffer.appendFormat("%" PRIu64, value.u.u64);
+            buffer += std::to_string(value.u.u64);
             break;
         case MTP_TYPE_INT128:
-            buffer.appendFormat("%08X%08X%08X%08X", value.u.i128[0], value.u.i128[1],
-                    value.u.i128[2], value.u.i128[3]);
+            for (auto i : value.u.i128) {
+                s << std::hex << std::setfill('0') << std::uppercase << i;
+            }
+            buffer += s.str();
             break;
         case MTP_TYPE_UINT128:
-            buffer.appendFormat("%08X%08X%08X%08X", value.u.u128[0], value.u.u128[1],
-                    value.u.u128[2], value.u.u128[3]);
+            for (auto i : value.u.u128) {
+                s << std::hex << std::setfill('0') << std::uppercase << i;
+            }
+            buffer += s.str();
             break;
         case MTP_TYPE_STR:
-            buffer.appendFormat("%s", value.str);
+            buffer += value.str;
             break;
         default:
             ALOGE("unsupported type for MtpProperty::print\n");
diff --git a/media/mtp/MtpProperty.h b/media/mtp/MtpProperty.h
index 03c08e1..bfd5f7f 100644
--- a/media/mtp/MtpProperty.h
+++ b/media/mtp/MtpProperty.h
@@ -19,6 +19,8 @@
 
 #include "MtpTypes.h"
 
+#include <string>
+
 namespace android {
 
 class MtpDataPacket;
@@ -97,7 +99,6 @@
     void                setFormDateTime();
 
     void                print();
-    void                print(MtpPropertyValue& value, MtpString& buffer);
 
     inline bool         isDeviceProperty() const {
                             return (   ((mCode & 0xF000) == 0x5000)
@@ -110,6 +111,7 @@
     MtpPropertyValue*   readArrayValues(MtpDataPacket& packet, uint32_t& length);
     void                writeArrayValues(MtpDataPacket& packet,
                                             MtpPropertyValue* values, uint32_t length);
+    void                print(MtpPropertyValue& value, std::string& buffer);
 };
 
 }; // namespace android
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index cfda0a6..86d59dd 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -33,6 +33,7 @@
 
 #include "MtpDebug.h"
 #include "IMtpDatabase.h"
+#include "MtpDescriptors.h"
 #include "MtpDevHandle.h"
 #include "MtpFfsCompatHandle.h"
 #include "MtpFfsHandle.h"
@@ -100,11 +101,11 @@
     MTP_EVENT_DEVICE_PROP_CHANGED,
 };
 
-MtpServer::MtpServer(IMtpDatabase* database, bool ptp,
-                    const MtpString& deviceInfoManufacturer,
-                    const MtpString& deviceInfoModel,
-                    const MtpString& deviceInfoDeviceVersion,
-                    const MtpString& deviceInfoSerialNumber)
+MtpServer::MtpServer(IMtpDatabase* database, int controlFd, bool ptp,
+                    const char *deviceInfoManufacturer,
+                    const char *deviceInfoModel,
+                    const char *deviceInfoDeviceVersion,
+                    const char *deviceInfoSerialNumber)
     :   mDatabase(database),
         mPtp(ptp),
         mDeviceInfoManufacturer(deviceInfoManufacturer),
@@ -118,39 +119,27 @@
         mSendObjectFileSize(0),
         mSendObjectModifiedTime(0)
 {
+    bool ffs_ok = access(FFS_MTP_EP0, W_OK) == 0;
+    if (ffs_ok) {
+        bool aio_compat = android::base::GetBoolProperty("sys.usb.ffs.aio_compat", false);
+        mHandle = aio_compat ? new MtpFfsCompatHandle(controlFd) : new MtpFfsHandle(controlFd);
+    } else {
+        mHandle = new MtpDevHandle();
+    }
 }
 
 MtpServer::~MtpServer() {
 }
 
-IMtpHandle* MtpServer::sHandle = nullptr;
-
-int MtpServer::configure(bool usePtp) {
-    bool ffs_ok = access(FFS_MTP_EP0, W_OK) == 0;
-    if (sHandle == nullptr) {
-        if (ffs_ok) {
-            bool aio_compat = android::base::GetBoolProperty("sys.usb.ffs.aio_compat", false);
-            sHandle = aio_compat ? new MtpFfsCompatHandle() : new MtpFfsHandle();
-        } else {
-            sHandle = new MtpDevHandle();
-        }
-    }
-
-    int ret = sHandle->configure(usePtp);
-    if (ret) ALOGE("Failed to configure MTP driver!");
-    android::base::SetProperty("sys.usb.ffs.mtp.ready", "1");
-    return ret;
-}
-
 void MtpServer::addStorage(MtpStorage* storage) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
-    mStorages.push(storage);
+    mStorages.push_back(storage);
     sendStoreAdded(storage->getStorageID());
 }
 
 void MtpServer::removeStorage(MtpStorage* storage) {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
     auto iter = std::find(mStorages.begin(), mStorages.end(), storage);
     if (iter != mStorages.end()) {
         sendStoreRemoved(storage->getStorageID());
@@ -175,19 +164,14 @@
 }
 
 void MtpServer::run() {
-    if (!sHandle) {
-        ALOGE("MtpServer was never configured!");
-        return;
-    }
-
-    if (sHandle->start()) {
+    if (mHandle->start(mPtp)) {
         ALOGE("Failed to start usb driver!");
-        sHandle->close();
+        mHandle->close();
         return;
     }
 
     while (1) {
-        int ret = mRequest.read(sHandle);
+        int ret = mRequest.read(mHandle);
         if (ret < 0) {
             ALOGE("request read returned %d, errno: %d", ret, errno);
             if (errno == ECANCELED) {
@@ -206,7 +190,7 @@
                     || operation == MTP_OPERATION_SET_OBJECT_PROP_VALUE
                     || operation == MTP_OPERATION_SET_DEVICE_PROP_VALUE);
         if (dataIn) {
-            int ret = mData.read(sHandle);
+            int ret = mData.read(mHandle);
             if (ret < 0) {
                 ALOGE("data read returned %d, errno: %d", ret, errno);
                 if (errno == ECANCELED) {
@@ -225,7 +209,7 @@
                 mData.setOperationCode(operation);
                 mData.setTransactionID(transaction);
                 ALOGV("sending data:");
-                ret = mData.write(sHandle);
+                ret = mData.write(mHandle);
                 if (ret < 0) {
                     ALOGE("request write returned %d, errno: %d", ret, errno);
                     if (errno == ECANCELED) {
@@ -238,7 +222,7 @@
 
             mResponse.setTransactionID(transaction);
             ALOGV("sending response %04X", mResponse.getResponseCode());
-            ret = mResponse.write(sHandle);
+            ret = mResponse.write(mHandle);
             const int savedErrno = errno;
             if (ret < 0) {
                 ALOGE("request write returned %d, errno: %d", ret, errno);
@@ -262,7 +246,7 @@
     }
     mObjectEditList.clear();
 
-    sHandle->close();
+    mHandle->close();
 }
 
 void MtpServer::sendObjectAdded(MtpObjectHandle handle) {
@@ -295,15 +279,15 @@
         mEvent.setEventCode(code);
         mEvent.setTransactionID(mRequest.getTransactionID());
         mEvent.setParameter(1, param1);
-        if (mEvent.write(sHandle))
+        if (mEvent.write(mHandle))
             ALOGE("Mtp send event failed: %s", strerror(errno));
     }
 }
 
-void MtpServer::addEditObject(MtpObjectHandle handle, MtpString& path,
+void MtpServer::addEditObject(MtpObjectHandle handle, MtpStringBuffer& path,
         uint64_t size, MtpObjectFormat format, int fd) {
     ObjectEdit*  edit = new ObjectEdit(handle, path, size, format, fd);
-    mObjectEditList.add(edit);
+    mObjectEditList.push_back(edit);
 }
 
 MtpServer::ObjectEdit* MtpServer::getEditObject(MtpObjectHandle handle) {
@@ -321,7 +305,7 @@
         ObjectEdit* edit = mObjectEditList[i];
         if (edit->mHandle == handle) {
             delete edit;
-            mObjectEditList.removeAt(i);
+            mObjectEditList.erase(mObjectEditList.begin() + i);
             return;
         }
     }
@@ -334,7 +318,7 @@
 
 
 bool MtpServer::handleRequest() {
-    Mutex::Autolock autoLock(mMutex);
+    std::lock_guard<std::mutex> lg(mMutex);
 
     MtpOperationCode operation = mRequest.getOperationCode();
     MtpResponseCode response;
@@ -785,7 +769,7 @@
     if (mRequest.getParameterCount() < 1)
         return MTP_RESPONSE_INVALID_PARAMETER;
     MtpObjectHandle handle = mRequest.getParameter(1);
-    MtpString pathBuf;
+    MtpStringBuffer pathBuf;
     int64_t fileLength;
     MtpObjectFormat format;
     int result = mDatabase->getObjectFilePath(handle, pathBuf, fileLength, format);
@@ -806,7 +790,7 @@
     mfr.transaction_id = mRequest.getTransactionID();
 
     // then transfer the file
-    int ret = sHandle->sendFile(mfr);
+    int ret = mHandle->sendFile(mfr);
     if (ret < 0) {
         ALOGE("Mtp send file got error %s", strerror(errno));
         if (errno == ECANCELED) {
@@ -839,7 +823,7 @@
         // send data
         mData.setOperationCode(mRequest.getOperationCode());
         mData.setTransactionID(mRequest.getTransactionID());
-        mData.writeData(sHandle, thumb, thumbSize);
+        mData.writeData(mHandle, thumb, thumbSize);
         free(thumb);
         return MTP_RESPONSE_OK;
     } else {
@@ -871,7 +855,7 @@
         // standard GetPartialObject
         length = mRequest.getParameter(3);
     }
-    MtpString pathBuf;
+    MtpStringBuffer pathBuf;
     int64_t fileLength;
     MtpObjectFormat format;
     int result = mDatabase->getObjectFilePath(handle, pathBuf, fileLength, format);
@@ -894,7 +878,7 @@
     mResponse.setParameter(1, length);
 
     // transfer the file
-    int ret = sHandle->sendFile(mfr);
+    int ret = mHandle->sendFile(mfr);
     ALOGV("MTP_SEND_FILE_WITH_HEADER returned %d\n", ret);
     result = MTP_RESPONSE_OK;
     if (ret < 0) {
@@ -908,7 +892,7 @@
 }
 
 MtpResponseCode MtpServer::doSendObjectInfo() {
-    MtpString path;
+    MtpStringBuffer path;
     uint16_t temp16;
     uint32_t temp32;
 
@@ -922,7 +906,7 @@
 
     // special case the root
     if (parent == MTP_PARENT_ROOT) {
-        path = storage->getPath();
+        path.set(storage->getPath());
         parent = 0;
     } else {
         int64_t length;
@@ -954,7 +938,7 @@
     if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER;  // sequence number
     MtpStringBuffer name, created, modified;
     if (!mData.getString(name)) return MTP_RESPONSE_INVALID_PARAMETER;    // file name
-    if (name.getCharCount() == 0) {
+    if (name.isEmpty()) {
         ALOGE("empty name");
         return MTP_RESPONSE_INVALID_PARAMETER;
     }
@@ -968,8 +952,8 @@
         modifiedTime = 0;
 
     if (path[path.size() - 1] != '/')
-        path += "/";
-    path += (const char *)name;
+        path.append("/");
+    path.append(name);
 
     // check space first
     if (mSendObjectFileSize > storage->getFreeSpace())
@@ -1022,10 +1006,10 @@
     MtpObjectHandle parent = mRequest.getParameter(3);
     if (!storage)
         return MTP_RESPONSE_INVALID_STORAGE_ID;
-    MtpString path;
+    MtpStringBuffer path;
     MtpResponseCode result;
 
-    MtpString fromPath;
+    MtpStringBuffer fromPath;
     int64_t fileLength;
     MtpObjectFormat format;
     MtpObjectInfo info(objectHandle);
@@ -1038,7 +1022,7 @@
 
     // special case the root
     if (parent == 0) {
-        path = storage->getPath();
+        path.set(storage->getPath());
     } else {
         int64_t parentLength;
         MtpObjectFormat parentFormat;
@@ -1050,8 +1034,8 @@
     }
 
     if (path[path.size() - 1] != '/')
-        path += "/";
-    path += info.mName;
+        path.append("/");
+    path.append(info.mName);
 
     result = mDatabase->beginMoveObject(objectHandle, parent, storageID);
     if (result != MTP_RESPONSE_OK)
@@ -1101,9 +1085,9 @@
     MtpObjectHandle parent = mRequest.getParameter(3);
     if (!storage)
         return MTP_RESPONSE_INVALID_STORAGE_ID;
-    MtpString path;
+    MtpStringBuffer path;
 
-    MtpString fromPath;
+    MtpStringBuffer fromPath;
     int64_t fileLength;
     MtpObjectFormat format;
     MtpObjectInfo info(objectHandle);
@@ -1116,7 +1100,7 @@
 
     // special case the root
     if (parent == 0) {
-        path = storage->getPath();
+        path.set(storage->getPath());
     } else {
         int64_t parentLength;
         MtpObjectFormat parentFormat;
@@ -1132,8 +1116,8 @@
         return MTP_RESPONSE_STORAGE_FULL;
 
     if (path[path.size() - 1] != '/')
-        path += "/";
-    path += info.mName;
+        path.append("/");
+    path.append(info.mName);
 
     MtpObjectHandle handle = mDatabase->beginCopyObject(objectHandle, parent, storageID);
     if (handle == kInvalidObjectHandle) {
@@ -1176,7 +1160,7 @@
     }
 
     // read the header, and possibly some data
-    ret = mData.read(sHandle);
+    ret = mData.read(mHandle);
     if (ret < MTP_CONTAINER_HEADER_SIZE) {
         result = MTP_RESPONSE_GENERAL_ERROR;
         goto done;
@@ -1224,7 +1208,7 @@
         mfr.transaction_id = 0;
 
         // transfer the file
-        ret = sHandle->receiveFile(mfr, mfr.length == 0 &&
+        ret = mHandle->receiveFile(mfr, mfr.length == 0 &&
                 initialData == MTP_BUFFER_SIZE - MTP_CONTAINER_HEADER_SIZE);
         if ((ret < 0) && (errno == ECANCELED)) {
             isCanceled = true;
@@ -1280,7 +1264,7 @@
     // FIXME - support deleting all objects if handle is 0xFFFFFFFF
     // FIXME - implement deleting objects by format
 
-    MtpString filePath;
+    MtpStringBuffer filePath;
     int64_t fileLength;
     int result = mDatabase->getObjectFilePath(handle, filePath, fileLength, format);
     if (result != MTP_RESPONSE_OK)
@@ -1353,7 +1337,7 @@
     ALOGV("receiving partial %s %" PRIu64 " %" PRIu32, filePath, offset, length);
 
     // read the header, and possibly some data
-    int ret = mData.read(sHandle);
+    int ret = mData.read(mHandle);
     if (ret < MTP_CONTAINER_HEADER_SIZE)
         return MTP_RESPONSE_GENERAL_ERROR;
     int initialData = ret - MTP_CONTAINER_HEADER_SIZE;
@@ -1376,7 +1360,7 @@
         mfr.transaction_id = 0;
 
         // transfer the file
-        ret = sHandle->receiveFile(mfr, mfr.length == 0 &&
+        ret = mHandle->receiveFile(mfr, mfr.length == 0 &&
                 initialData == MTP_BUFFER_SIZE - MTP_CONTAINER_HEADER_SIZE);
         if ((ret < 0) && (errno == ECANCELED)) {
             isCanceled = true;
@@ -1430,7 +1414,7 @@
         return MTP_RESPONSE_GENERAL_ERROR;
     }
 
-    MtpString path;
+    MtpStringBuffer path;
     int64_t fileLength;
     MtpObjectFormat format;
     int result = mDatabase->getObjectFilePath(handle, path, fileLength, format);
diff --git a/media/mtp/MtpServer.h b/media/mtp/MtpServer.h
index af371eb..f6939d7 100644
--- a/media/mtp/MtpServer.h
+++ b/media/mtp/MtpServer.h
@@ -21,14 +21,14 @@
 #include "MtpDataPacket.h"
 #include "MtpResponsePacket.h"
 #include "MtpEventPacket.h"
+#include "MtpStringBuffer.h"
 #include "mtp.h"
 #include "MtpUtils.h"
 #include "IMtpHandle.h"
 
-#include <utils/threads.h>
-#include <queue>
 #include <memory>
 #include <mutex>
+#include <queue>
 
 namespace android {
 
@@ -44,13 +44,13 @@
     bool                mPtp;
 
     // Manufacturer to report in DeviceInfo
-    MtpString           mDeviceInfoManufacturer;
+    MtpStringBuffer     mDeviceInfoManufacturer;
     // Model to report in DeviceInfo
-    MtpString           mDeviceInfoModel;
+    MtpStringBuffer     mDeviceInfoModel;
     // Device version to report in DeviceInfo
-    MtpString           mDeviceInfoDeviceVersion;
+    MtpStringBuffer     mDeviceInfoDeviceVersion;
     // Serial number to report in DeviceInfo
-    MtpString           mDeviceInfoSerialNumber;
+    MtpStringBuffer     mDeviceInfoSerialNumber;
 
     // current session ID
     MtpSessionID        mSessionID;
@@ -65,23 +65,23 @@
 
     MtpStorageList      mStorages;
 
-    static IMtpHandle*  sHandle;
+    IMtpHandle*         mHandle;
 
     // handle for new object, set by SendObjectInfo and used by SendObject
     MtpObjectHandle     mSendObjectHandle;
     MtpObjectFormat     mSendObjectFormat;
-    MtpString           mSendObjectFilePath;
+    MtpStringBuffer     mSendObjectFilePath;
     size_t              mSendObjectFileSize;
     time_t              mSendObjectModifiedTime;
 
-    Mutex               mMutex;
+    std::mutex          mMutex;
 
     // represents an MTP object that is being edited using the android extensions
     // for direct editing (BeginEditObject, SendPartialObject, TruncateObject and EndEditObject)
     class ObjectEdit {
         public:
         MtpObjectHandle     mHandle;
-        MtpString           mPath;
+        MtpStringBuffer           mPath;
         uint64_t            mSize;
         MtpObjectFormat     mFormat;
         int                 mFD;
@@ -95,14 +95,14 @@
             close(mFD);
         }
     };
-    Vector<ObjectEdit*>  mObjectEditList;
+    std::vector<ObjectEdit*>  mObjectEditList;
 
 public:
-                        MtpServer(IMtpDatabase* database, bool ptp,
-                                    const MtpString& deviceInfoManufacturer,
-                                    const MtpString& deviceInfoModel,
-                                    const MtpString& deviceInfoDeviceVersion,
-                                    const MtpString& deviceInfoSerialNumber);
+                        MtpServer(IMtpDatabase* database, int controlFd, bool ptp,
+                                    const char *deviceInfoManufacturer,
+                                    const char *deviceInfoModel,
+                                    const char *deviceInfoDeviceVersion,
+                                    const char *deviceInfoSerialNumber);
     virtual             ~MtpServer();
 
     MtpStorage*         getStorage(MtpStorageID id);
@@ -111,7 +111,6 @@
     void                addStorage(MtpStorage* storage);
     void                removeStorage(MtpStorage* storage);
 
-    static int          configure(bool usePtp);
     void                run();
 
     void                sendObjectAdded(MtpObjectHandle handle);
@@ -123,7 +122,7 @@
     void                sendStoreRemoved(MtpStorageID id);
     void                sendEvent(MtpEventCode code, uint32_t param1);
 
-    void                addEditObject(MtpObjectHandle handle, MtpString& path,
+    void                addEditObject(MtpObjectHandle handle, MtpStringBuffer& path,
                                 uint64_t size, MtpObjectFormat format, int fd);
     ObjectEdit*         getEditObject(MtpObjectHandle handle);
     void                removeEditObject(MtpObjectHandle handle);
diff --git a/media/mtp/MtpStorage.h b/media/mtp/MtpStorage.h
index cb7e333..e9518dd 100644
--- a/media/mtp/MtpStorage.h
+++ b/media/mtp/MtpStorage.h
@@ -17,6 +17,7 @@
 #ifndef _MTP_STORAGE_H
 #define _MTP_STORAGE_H
 
+#include "MtpStringBuffer.h"
 #include "MtpTypes.h"
 #include "mtp.h"
 
@@ -28,8 +29,8 @@
 
 private:
     MtpStorageID            mStorageID;
-    MtpString               mFilePath;
-    MtpString               mDescription;
+    MtpStringBuffer         mFilePath;
+    MtpStringBuffer         mDescription;
     uint64_t                mMaxCapacity;
     uint64_t                mMaxFileSize;
     bool                    mRemovable;
diff --git a/media/mtp/MtpStringBuffer.cpp b/media/mtp/MtpStringBuffer.cpp
index df04694..cd379bf 100644
--- a/media/mtp/MtpStringBuffer.cpp
+++ b/media/mtp/MtpStringBuffer.cpp
@@ -16,168 +16,97 @@
 
 #define LOG_TAG "MtpStringBuffer"
 
-#include <string.h>
+#include <codecvt>
+#include <locale>
+#include <string>
+#include <vector>
 
 #include "MtpDataPacket.h"
 #include "MtpStringBuffer.h"
 
-namespace android {
+namespace {
 
-MtpStringBuffer::MtpStringBuffer()
-    :   mCharCount(0),
-        mByteCount(1)
-{
-    mBuffer[0] = 0;
+std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> gConvert;
+
+static std::string utf16ToUtf8(std::u16string input_str) {
+    return gConvert.to_bytes(input_str);
 }
 
+static std::u16string utf8ToUtf16(std::string input_str) {
+    return gConvert.from_bytes(input_str);
+}
+
+} // namespace
+
+namespace android {
+
 MtpStringBuffer::MtpStringBuffer(const char* src)
-    :   mCharCount(0),
-        mByteCount(1)
 {
     set(src);
 }
 
 MtpStringBuffer::MtpStringBuffer(const uint16_t* src)
-    :   mCharCount(0),
-        mByteCount(1)
 {
     set(src);
 }
 
 MtpStringBuffer::MtpStringBuffer(const MtpStringBuffer& src)
-    :   mCharCount(src.mCharCount),
-        mByteCount(src.mByteCount)
 {
-    memcpy(mBuffer, src.mBuffer, mByteCount);
-}
-
-
-MtpStringBuffer::~MtpStringBuffer() {
+    mString = src.mString;
 }
 
 void MtpStringBuffer::set(const char* src) {
-    // count the characters
-    int count = 0;
-    char ch;
-    char* dest = (char*)mBuffer;
-
-    while ((ch = *src++) != 0 && count < MTP_STRING_MAX_CHARACTER_NUMBER) {
-        if ((ch & 0x80) == 0) {
-            // single byte character
-            *dest++ = ch;
-        } else if ((ch & 0xE0) == 0xC0) {
-            // two byte character
-            char ch1 = *src++;
-            if (! ch1) {
-                // last character was truncated, so ignore last byte
-                break;
-            }
-
-            *dest++ = ch;
-            *dest++ = ch1;
-        } else if ((ch & 0xF0) == 0xE0) {
-            // 3 byte char
-            char ch1 = *src++;
-            if (! ch1) {
-                // last character was truncated, so ignore last byte
-                break;
-            }
-            char ch2 = *src++;
-            if (! ch2) {
-                // last character was truncated, so ignore last byte
-                break;
-            }
-
-            *dest++ = ch;
-            *dest++ = ch1;
-            *dest++ = ch2;
-        }
-        count++;
-    }
-
-    *dest++ = 0;
-    mByteCount = dest - (char*)mBuffer;
-    mCharCount = count;
+    mString = std::string(src);
 }
 
 void MtpStringBuffer::set(const uint16_t* src) {
-    int count = 0;
-    uint16_t ch;
-    uint8_t* dest = mBuffer;
-
-    while ((ch = *src++) != 0 && count < MTP_STRING_MAX_CHARACTER_NUMBER) {
-        if (ch >= 0x0800) {
-            *dest++ = (uint8_t)(0xE0 | (ch >> 12));
-            *dest++ = (uint8_t)(0x80 | ((ch >> 6) & 0x3F));
-            *dest++ = (uint8_t)(0x80 | (ch & 0x3F));
-        } else if (ch >= 0x80) {
-            *dest++ = (uint8_t)(0xC0 | (ch >> 6));
-            *dest++ = (uint8_t)(0x80 | (ch & 0x3F));
-        } else {
-            *dest++ = ch;
-        }
-        count++;
-    }
-    *dest++ = 0;
-    mCharCount = count;
-    mByteCount = dest - mBuffer;
+    mString = utf16ToUtf8(std::u16string((const char16_t*)src));
 }
 
 bool MtpStringBuffer::readFromPacket(MtpDataPacket* packet) {
     uint8_t count;
     if (!packet->getUInt8(count))
         return false;
+    if (count == 0)
+        return true;
 
-    uint8_t* dest = mBuffer;
+    std::vector<char16_t> buffer(count);
     for (int i = 0; i < count; i++) {
         uint16_t ch;
-
         if (!packet->getUInt16(ch))
             return false;
-        if (ch >= 0x0800) {
-            *dest++ = (uint8_t)(0xE0 | (ch >> 12));
-            *dest++ = (uint8_t)(0x80 | ((ch >> 6) & 0x3F));
-            *dest++ = (uint8_t)(0x80 | (ch & 0x3F));
-        } else if (ch >= 0x80) {
-            *dest++ = (uint8_t)(0xC0 | (ch >> 6));
-            *dest++ = (uint8_t)(0x80 | (ch & 0x3F));
-        } else {
-            *dest++ = ch;
-        }
+        buffer[i] = ch;
     }
-    *dest++ = 0;
-    mCharCount = count;
-    mByteCount = dest - mBuffer;
+    if (buffer[count-1] != '\0') {
+        ALOGE("Mtp string not null terminated\n");
+        return false;
+    }
+    mString = utf16ToUtf8(std::u16string(buffer.data()));
     return true;
 }
 
 void MtpStringBuffer::writeToPacket(MtpDataPacket* packet) const {
-    int count = mCharCount;
-    const uint8_t* src = mBuffer;
-    packet->putUInt8(count > 0 ? count + 1 : 0);
+    std::u16string src16 = utf8ToUtf16(mString);
+    int count = src16.length();
 
-    // expand utf8 to 16 bit chars
-    for (int i = 0; i < count; i++) {
-        uint16_t ch;
-        uint16_t ch1 = *src++;
-        if ((ch1 & 0x80) == 0) {
-            // single byte character
-            ch = ch1;
-        } else if ((ch1 & 0xE0) == 0xC0) {
-            // two byte character
-            uint16_t ch2 = *src++;
-            ch = ((ch1 & 0x1F) << 6) | (ch2 & 0x3F);
-        } else {
-            // three byte character
-            uint16_t ch2 = *src++;
-            uint16_t ch3 = *src++;
-            ch = ((ch1 & 0x0F) << 12) | ((ch2 & 0x3F) << 6) | (ch3 & 0x3F);
+    if (count == 0) {
+        packet->putUInt8(0);
+        return;
+    }
+    packet->putUInt8(std::min(count + 1, MTP_STRING_MAX_CHARACTER_NUMBER));
+
+    int i = 0;
+    for (char16_t &c : src16) {
+        if (i == MTP_STRING_MAX_CHARACTER_NUMBER - 1) {
+            // Leave a slot for null termination.
+            ALOGI("Mtp truncating long string\n");
+            break;
         }
-        packet->putUInt16(ch);
+        packet->putUInt16(c);
+        i++;
     }
     // only terminate with zero if string is not empty
-    if (count > 0)
-        packet->putUInt16(0);
+    packet->putUInt16(0);
 }
 
 }  // namespace android
diff --git a/media/mtp/MtpStringBuffer.h b/media/mtp/MtpStringBuffer.h
index bcf2a48..4cec58a 100644
--- a/media/mtp/MtpStringBuffer.h
+++ b/media/mtp/MtpStringBuffer.h
@@ -17,7 +17,9 @@
 #ifndef _MTP_STRING_BUFFER_H
 #define _MTP_STRING_BUFFER_H
 
+#include <log/log.h>
 #include <stdint.h>
+#include <string>
 
 // Max Character number of a MTP String
 #define MTP_STRING_MAX_CHARACTER_NUMBER             255
@@ -30,31 +32,39 @@
 class MtpStringBuffer {
 
 private:
-    // mBuffer contains string in UTF8 format
-    // maximum 3 bytes/character, with 1 extra for zero termination
-    uint8_t         mBuffer[MTP_STRING_MAX_CHARACTER_NUMBER * 3 + 1];
-    int             mCharCount;
-    int             mByteCount;
+    std::string     mString;
 
 public:
-                    MtpStringBuffer();
+                    MtpStringBuffer() {};
+                    ~MtpStringBuffer() {};
+
     explicit        MtpStringBuffer(const char* src);
     explicit        MtpStringBuffer(const uint16_t* src);
                     MtpStringBuffer(const MtpStringBuffer& src);
-    virtual         ~MtpStringBuffer();
 
     void            set(const char* src);
     void            set(const uint16_t* src);
 
+    inline void     append(const char* other);
+    inline void     append(MtpStringBuffer &other);
+
     bool            readFromPacket(MtpDataPacket* packet);
     void            writeToPacket(MtpDataPacket* packet) const;
 
-    inline int      getCharCount() const { return mCharCount; }
-    inline int      getByteCount() const { return mByteCount; }
+    inline bool     isEmpty() const { return mString.empty(); }
+    inline int      size() const { return mString.length(); }
 
-	inline operator const char*() const { return (const char *)mBuffer; }
+    inline operator const char*() const { return mString.c_str(); }
 };
 
+inline void MtpStringBuffer::append(const char* other) {
+    mString += other;
+}
+
+inline void MtpStringBuffer::append(MtpStringBuffer &other) {
+    mString += other.mString;
+}
+
 }; // namespace android
 
 #endif // _MTP_STRING_BUFFER_H
diff --git a/media/mtp/MtpTypes.h b/media/mtp/MtpTypes.h
index c749c66..e6ac23c 100644
--- a/media/mtp/MtpTypes.h
+++ b/media/mtp/MtpTypes.h
@@ -18,8 +18,7 @@
 #define _MTP_TYPES_H
 
 #include <stdint.h>
-#include "utils/String8.h"
-#include "utils/Vector.h"
+#include <vector>
 
 namespace android {
 
@@ -51,18 +50,18 @@
 class MtpDevice;
 class MtpProperty;
 
-typedef Vector<MtpStorage *> MtpStorageList;
-typedef Vector<MtpDevice*> MtpDeviceList;
-typedef Vector<MtpProperty*> MtpPropertyList;
+typedef std::vector<MtpStorage *> MtpStorageList;
+typedef std::vector<MtpDevice*> MtpDeviceList;
+typedef std::vector<MtpProperty*> MtpPropertyList;
 
-typedef Vector<uint8_t> UInt8List;
-typedef Vector<uint16_t> UInt16List;
-typedef Vector<uint32_t> UInt32List;
-typedef Vector<uint64_t> UInt64List;
-typedef Vector<int8_t> Int8List;
-typedef Vector<int16_t> Int16List;
-typedef Vector<int32_t> Int32List;
-typedef Vector<int64_t> Int64List;
+typedef std::vector<uint8_t> UInt8List;
+typedef std::vector<uint16_t> UInt16List;
+typedef std::vector<uint32_t> UInt32List;
+typedef std::vector<uint64_t> UInt64List;
+typedef std::vector<int8_t> Int8List;
+typedef std::vector<int16_t> Int16List;
+typedef std::vector<int32_t> Int32List;
+typedef std::vector<int64_t> Int64List;
 
 typedef UInt16List MtpObjectPropertyList;
 typedef UInt16List MtpDevicePropertyList;
@@ -71,8 +70,6 @@
 typedef UInt16List MtpObjectPropertyList;
 typedef UInt32List MtpStorageIDList;
 
-typedef String8    MtpString;
-
 enum UrbPacketDivisionMode {
     // First packet only contains a header.
     FIRST_PACKET_ONLY_HEADER,
diff --git a/media/mtp/tests/MtpFfsHandle_test.cpp b/media/mtp/tests/MtpFfsHandle_test.cpp
index 9c916b7..d11fe07 100644
--- a/media/mtp/tests/MtpFfsHandle_test.cpp
+++ b/media/mtp/tests/MtpFfsHandle_test.cpp
@@ -23,7 +23,7 @@
 #include <random>
 #include <string>
 #include <unistd.h>
-#include <utils/Log.h>
+#include <log/log.h>
 
 #include "MtpDescriptors.h"
 #include "MtpFfsHandle.h"
@@ -64,7 +64,7 @@
 
     MtpFfsHandleTest() {
         int fd[2];
-        handle = std::make_unique<T>();
+        handle = std::make_unique<T>(-1);
 
         EXPECT_EQ(pipe(fd), 0);
         control.reset(fd[0]);
@@ -84,7 +84,7 @@
         intr.reset(fd[0]);
         handle->mIntr.reset(fd[1]);
 
-        EXPECT_EQ(handle->start(), 0);
+        EXPECT_EQ(handle->start(false), 0);
     }
 
     ~MtpFfsHandleTest() {
@@ -95,8 +95,8 @@
 typedef ::testing::Types<MtpFfsHandle, MtpFfsCompatHandle> mtpHandles;
 TYPED_TEST_CASE(MtpFfsHandleTest, mtpHandles);
 
-TYPED_TEST(MtpFfsHandleTest, testControl) {
-    EXPECT_TRUE(this->handle->writeDescriptors());
+TYPED_TEST(MtpFfsHandleTest, testMtpControl) {
+    EXPECT_TRUE(this->handle->writeDescriptors(false));
     struct desc_v2 desc;
     struct functionfs_strings strings;
     EXPECT_EQ(read(this->control, &desc, sizeof(desc)), (long)sizeof(desc));
@@ -105,6 +105,16 @@
     EXPECT_TRUE(std::memcmp(&strings, &mtp_strings, sizeof(strings)) == 0);
 }
 
+TYPED_TEST(MtpFfsHandleTest, testPtpControl) {
+    EXPECT_TRUE(this->handle->writeDescriptors(true));
+    struct desc_v2 desc;
+    struct functionfs_strings strings;
+    EXPECT_EQ(read(this->control, &desc, sizeof(desc)), (long)sizeof(desc));
+    EXPECT_EQ(read(this->control, &strings, sizeof(strings)), (long)sizeof(strings));
+    EXPECT_TRUE(std::memcmp(&desc, &ptp_desc_v2, sizeof(desc)) == 0);
+    EXPECT_TRUE(std::memcmp(&strings, &mtp_strings, sizeof(strings)) == 0);
+}
+
 TYPED_TEST(MtpFfsHandleTest, testRead) {
     EXPECT_EQ(write(this->bulk_out, dummyDataStr.c_str(), TEST_PACKET_SIZE), TEST_PACKET_SIZE);
     char buf[TEST_PACKET_SIZE + 1];
diff --git a/media/mtp/tests/PosixAsyncIO_test.cpp b/media/mtp/tests/PosixAsyncIO_test.cpp
index 63b9a35..9e337aa 100644
--- a/media/mtp/tests/PosixAsyncIO_test.cpp
+++ b/media/mtp/tests/PosixAsyncIO_test.cpp
@@ -20,7 +20,7 @@
 #include <gtest/gtest.h>
 #include <string>
 #include <unistd.h>
-#include <utils/Log.h>
+#include <log/log.h>
 
 #include "PosixAsyncIO.h"
 
diff --git a/media/ndk/include/media/NdkImage.h b/media/ndk/include/media/NdkImage.h
index 99cf5d5..19df760 100644
--- a/media/ndk/include/media/NdkImage.h
+++ b/media/ndk/include/media/NdkImage.h
@@ -72,14 +72,15 @@
     AIMAGE_FORMAT_RGBA_8888         = 0x1,
 
     /**
-     * 32 bits RGBX format, 8 bits for each of the four channels.
+     * 32 bits RGBX format, 8 bits for each of the four channels.  The values
+     * of the alpha channel bits are ignored (image is assumed to be opaque).
      *
      * <p>
      * Corresponding formats:
      * <ul>
      * <li>AHardwareBuffer: AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM</li>
      * <li>Vulkan: VK_FORMAT_R8G8B8A8_UNORM</li>
-     * <li>OpenGL ES: GL_RGBA8</li>
+     * <li>OpenGL ES: GL_RGB8</li>
      * </ul>
      * </p>
      *
@@ -717,7 +718,7 @@
 
 #if __ANDROID_API__ >= 26
 
-/*
+/**
  * Return the image back the the system and delete the AImage object from memory asynchronously.
  *
  * <p>Similar to {@link AImage_delete}, do NOT use the image pointer after this method returns.
@@ -746,8 +747,9 @@
  * AHardwareBuffer_acquire} to acquire an extra reference, and call {@link AHardwareBuffer_release}
  * once it has finished using it in order to properly deallocate the underlying memory managed by
  * {@link AHardwareBuffer}. If the caller has acquired extra reference on an {@link AHardwareBuffer}
- * returned from this function, it must also listen to {@link onBufferFreed} callback to be
- * notified when the buffer is no longer used by {@link AImageReader}.</p>
+ * returned from this function, it must also register a listener using the function
+ * {@link AImageReader_setBufferRemovedListener} to be notified when the buffer is no longer used
+ * by {@link AImageReader}.</p>
  *
  * @param image the {@link AImage} of interest.
  * @param outBuffer The memory area pointed to by buffer will contain the acquired AHardwareBuffer
diff --git a/media/ndk/include/media/NdkImageReader.h b/media/ndk/include/media/NdkImageReader.h
index e3b99d0..571410b 100644
--- a/media/ndk/include/media/NdkImageReader.h
+++ b/media/ndk/include/media/NdkImageReader.h
@@ -256,7 +256,7 @@
 
 
 /**
- * The definition of {@link AImageReader} new image available callback.
+ * Signature of the callback which is called when a new image is available from {@link AImageReader}.
  *
  * @param context The optional application context provided by user in
  *                {@link AImageReader_setImageListener}.
@@ -265,11 +265,11 @@
 typedef void (*AImageReader_ImageCallback)(void* context, AImageReader* reader);
 
 typedef struct AImageReader_ImageListener {
-    /// optional application context.
+    /// Optional application context passed as the first parameter of the callback.
     void*                      context;
 
     /**
-     * This callback is called when there is a new image available for in the image reader's queue.
+     * This callback is called when there is a new image available in the image reader's queue.
      *
      * <p>The callback happens on one dedicated thread per {@link AImageReader} instance. It is okay
      * to use AImageReader_* and AImage_* methods within the callback. Note that it is possible that
@@ -285,11 +285,11 @@
 /**
  * Set the onImageAvailable listener of this image reader.
  *
- * <p>Note that calling this method will replace previously registered listeners.</p>
+ * Calling this method will replace previously registered listeners.
  *
  * @param reader The image reader of interest.
- * @param listener the {@link AImageReader_ImageListener} to be registered. Set this to NULL if
- *                 application no longer needs to listen to new images.
+ * @param listener The {@link AImageReader_ImageListener} to be registered. Set this to NULL if
+ *                 the application no longer needs to listen to new images.
  *
  * @return <ul>
  *         <li>{@link AMEDIA_OK} if the method call succeeds.</li>
@@ -406,7 +406,7 @@
 media_status_t AImageReader_acquireLatestImageAsync(
         AImageReader* reader, /*out*/AImage** image, /*out*/int* acquireFenceFd);
 /**
- * The definition of {@link AImageReader} buffer removed callback.
+ * Signature of the callback which is called when {@link AImageReader} is about to remove a buffer.
  *
  * @param context The optional application context provided by user in
  *                {@link AImageReader_setBufferRemovedListener}.
@@ -418,7 +418,7 @@
         AHardwareBuffer* buffer);
 
 typedef struct AImageReader_BufferRemovedListener {
-    /// optional application context.
+    /// Optional application context passed as the first parameter of the callback.
     void*                      context;
 
     /**
diff --git a/media/ndk/libmediandk.map.txt b/media/ndk/libmediandk.map.txt
index 94d1e9f..fb56694 100644
--- a/media/ndk/libmediandk.map.txt
+++ b/media/ndk/libmediandk.map.txt
@@ -49,10 +49,8 @@
     AMEDIAFORMAT_KEY_DURATION; # var
     AMEDIAFORMAT_KEY_FLAC_COMPRESSION_LEVEL; # var
     AMEDIAFORMAT_KEY_FRAME_RATE; # var
-    AMEDIAFORMAT_KEY_GRID_COLS; # var introduced=28
-    AMEDIAFORMAT_KEY_GRID_HEIGHT; # var introduced=28
+    AMEDIAFORMAT_KEY_GRID_COLUMNS; # var introduced=28
     AMEDIAFORMAT_KEY_GRID_ROWS; # var introduced=28
-    AMEDIAFORMAT_KEY_GRID_WIDTH; # var introduced=28
     AMEDIAFORMAT_KEY_HDR_STATIC_INFO; # var introduced=28
     AMEDIAFORMAT_KEY_HEIGHT; # var
     AMEDIAFORMAT_KEY_INTRA_REFRESH_PERIOD; # var introduced=28
@@ -79,6 +77,8 @@
     AMEDIAFORMAT_KEY_SLICE_HEIGHT; # var introduced=28
     AMEDIAFORMAT_KEY_STRIDE; # var
     AMEDIAFORMAT_KEY_TEMPORAL_LAYERING; # var introduced=28
+    AMEDIAFORMAT_KEY_TILE_HEIGHT; # var introduced=28
+    AMEDIAFORMAT_KEY_TILE_WIDTH; # var introduced=28
     AMEDIAFORMAT_KEY_TRACK_ID; # var introduced=28
     AMEDIAFORMAT_KEY_WIDTH; # var
     AMediaCodecActionCode_isRecoverable; # introduced=28
diff --git a/packages/MediaComponents/res/drawable/custom_progress_thumb.xml b/packages/MediaComponents/res/drawable/custom_progress_thumb.xml
index 2e247f2..1a35970 100644
--- a/packages/MediaComponents/res/drawable/custom_progress_thumb.xml
+++ b/packages/MediaComponents/res/drawable/custom_progress_thumb.xml
@@ -17,6 +17,6 @@
     android:shape="oval" >
     <solid android:color="#ffffff" />
     <size
-        android:height="12dp"
-        android:width="12dp" />
+        android:height="@dimen/mcv2_custom_progress_thumb_size"
+        android:width="@dimen/mcv2_custom_progress_thumb_size" />
 </shape>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/drawable/ic_default_album_image.xml b/packages/MediaComponents/res/drawable/ic_default_album_image.xml
new file mode 100644
index 0000000..1cee643
--- /dev/null
+++ b/packages/MediaComponents/res/drawable/ic_default_album_image.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="512dp"
+    android:height="512dp"
+    android:viewportWidth="512"
+    android:viewportHeight="512">
+
+    <path
+        android:fillColor="#616161"
+        android:pathData="M 0 0 H 512 V 512 H 0 V 0 Z" />
+    <path
+        android:fillColor="#525252"
+        android:pathData="M256,151v123.14c-6.88-4.02-14.82-6.48-23.33-6.48 c-25.78,0-46.67,20.88-46.67,46.67c0,25.78,20.88,46.67,46.67,46.67s46.67-20.88,46.67-46.67V197.67H326V151H256z" />
+</vector>
diff --git a/packages/MediaComponents/res/layout/embedded_music.xml b/packages/MediaComponents/res/layout/embedded_music.xml
new file mode 100644
index 0000000..3e4d365
--- /dev/null
+++ b/packages/MediaComponents/res/layout/embedded_music.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2018 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="0.25"/>
+
+    <ImageView
+        android:id="@+id/album"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="0.5"
+        android:scaleType="fitCenter"
+        android:src="@drawable/ic_default_album_image" />
+
+    <View
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="0.25"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/layout/full_landscape_music.xml b/packages/MediaComponents/res/layout/full_landscape_music.xml
new file mode 100644
index 0000000..8ce7058
--- /dev/null
+++ b/packages/MediaComponents/res/layout/full_landscape_music.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2018 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="#B300FF00"
+    android:orientation="horizontal">
+
+    <LinearLayout
+        android:id="@+id/music_image"
+        style="@style/FullMusicLandscape.Image">
+
+        <ImageView
+            android:id="@+id/album"
+            android:layout_width="@dimen/mcv2_full_album_image_landscape_size"
+            android:layout_height="@dimen/mcv2_full_album_image_landscape_size"
+            android:src="@drawable/ic_default_album_image"/>
+    </LinearLayout>
+
+    <LinearLayout
+        android:id="@+id/music_text"
+        style="@style/FullMusicLandscape.Text">
+
+        <TextView
+            android:id="@+id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/mcv2_music_title_unknown_text"
+            android:textSize="20sp"
+            android:textStyle="bold"
+            android:textColor="#FFFFFF" />
+        <TextView
+            android:id="@+id/artist"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/mcv2_music_artist_unknown_text"
+            android:textSize="16sp"
+            android:textColor="#BBBBBB" />
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/layout/full_portrait_music.xml b/packages/MediaComponents/res/layout/full_portrait_music.xml
new file mode 100644
index 0000000..75f1bb3
--- /dev/null
+++ b/packages/MediaComponents/res/layout/full_portrait_music.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2018 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:id="@+id/music_image"
+        style="@style/FullMusicPortrait.Image">
+
+        <ImageView
+            android:id="@+id/album"
+            android:layout_width="@dimen/mcv2_full_album_image_portrait_size"
+            android:layout_height="@dimen/mcv2_full_album_image_portrait_size"
+            android:src="@drawable/ic_default_album_image"/>
+    </LinearLayout>
+
+    <LinearLayout
+        android:id="@+id/music_text"
+        style="@style/FullMusicPortrait.Text">
+
+        <TextView
+            android:id="@+id/title"
+            android:layout_width="@dimen/mcv2_full_album_image_portrait_size"
+            android:layout_height="wrap_content"
+            android:text="@string/mcv2_music_title_unknown_text"
+            android:textSize="20sp"
+            android:textStyle="bold"
+            android:textColor="#FFFFFF" />
+        <TextView
+            android:id="@+id/artist"
+            android:layout_width="@dimen/mcv2_full_album_image_portrait_size"
+            android:layout_height="wrap_content"
+            android:text="@string/mcv2_music_artist_unknown_text"
+            android:textSize="16sp"
+            android:textColor="#BBBBBB" />
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/layout/full_transport_controls.xml b/packages/MediaComponents/res/layout/full_transport_controls.xml
index dd41a1f..0914785 100644
--- a/packages/MediaComponents/res/layout/full_transport_controls.xml
+++ b/packages/MediaComponents/res/layout/full_transport_controls.xml
@@ -28,4 +28,4 @@
     <ImageButton android:id="@+id/pause" style="@style/FullTransportControlsButton.Pause" />
     <ImageButton android:id="@+id/ffwd" style="@style/FullTransportControlsButton.Ffwd" />
     <ImageButton android:id="@+id/next" style="@style/FullTransportControlsButton.Next" />
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/packages/MediaComponents/res/layout/media_controller.xml b/packages/MediaComponents/res/layout/media_controller.xml
index c5fbee8..4658f04 100644
--- a/packages/MediaComponents/res/layout/media_controller.xml
+++ b/packages/MediaComponents/res/layout/media_controller.xml
@@ -17,14 +17,12 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="#55000000"
     android:orientation="vertical"
     android:layoutDirection="ltr">
 
     <RelativeLayout
         android:id="@+id/title_bar"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
+        android:background="@layout/title_bar_gradient"
         style="@style/TitleBar">
 
         <LinearLayout
@@ -105,6 +103,7 @@
                 android:id="@+id/cast"
                 android:layout_centerVertical="true"
                 android:visibility="gone"
+                android:contentDescription="@string/mr_button_content_description"
                 style="@style/TitleBarButton" />
         </LinearLayout>
 
@@ -115,21 +114,51 @@
         android:layout_width="match_parent"
         android:layout_height="0dp"
         android:layout_weight="1"
-        android:gravity="center">
+        android:gravity="center"
+        android:orientation="vertical">
     </LinearLayout>
 
-    <SeekBar
-        android:id="@+id/mediacontroller_progress"
+    <LinearLayout
+        android:id="@+id/minimal_extra_view"
         android:layout_width="match_parent"
-        android:layout_height="12dp"
-        android:maxHeight="2dp"
-        android:minHeight="2dp"
-        android:padding="0dp"/>
+        android:layout_height="wrap_content"
+        android:gravity="right">
+
+        <ImageButton
+            android:id="@+id/fullscreen"
+            android:gravity="right"
+            style="@style/BottomBarButton.FullScreen" />
+    </LinearLayout>
 
     <RelativeLayout
         android:layout_width="match_parent"
+        android:layout_height="@dimen/mcv2_custom_progress_thumb_size">
+
+        <SeekBar
+            android:id="@+id/progress"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/mcv2_custom_progress_thumb_size"
+            android:contentDescription="@string/mcv2_seek_bar_desc"
+            android:padding="0dp"
+            android:maxHeight="@dimen/mcv2_custom_progress_max_size"
+            android:minHeight="@dimen/mcv2_custom_progress_max_size"
+            android:elevation="10dp"/>
+
+        <View
+            android:id="@+id/progress_buffer"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/mcv2_buffer_view_height"
+            android:layout_alignParentBottom="true"
+            android:background="@color/bottom_bar_background"
+            android:elevation="0dp"/>
+    </RelativeLayout>
+
+    <RelativeLayout
+        android:id="@+id/bottom_bar"
+        android:layout_width="match_parent"
         android:layout_height="44dp"
-        android:orientation="horizontal">
+        android:orientation="horizontal"
+        android:background="@color/bottom_bar_background">
 
         <LinearLayout
             android:id="@+id/bottom_bar_left"
@@ -233,4 +262,4 @@
             </LinearLayout>
         </LinearLayout>
     </RelativeLayout>
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/packages/MediaComponents/res/layout/minimal_transport_controls.xml b/packages/MediaComponents/res/layout/minimal_transport_controls.xml
index 9ca3721..800c80b 100644
--- a/packages/MediaComponents/res/layout/minimal_transport_controls.xml
+++ b/packages/MediaComponents/res/layout/minimal_transport_controls.xml
@@ -18,8 +18,7 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:gravity="center"
-    android:orientation="horizontal"
-    android:visibility="visible">
+    android:orientation="horizontal">
 
-    <ImageButton android:id="@+id/pause" style="@style/MinimalTransportControlsButton.Pause" />
+    <ImageButton android:id="@+id/pause" style="@style/MinimalTransportControlsButton" />
 </LinearLayout>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/layout/title_bar_gradient.xml b/packages/MediaComponents/res/layout/title_bar_gradient.xml
new file mode 100644
index 0000000..ab1fc6e
--- /dev/null
+++ b/packages/MediaComponents/res/layout/title_bar_gradient.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2018 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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <gradient
+        android:startColor="@color/title_bar_gradient_start"
+        android:endColor="@color/title_bar_gradient_end"
+        android:angle="-270" />
+</shape>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/values/colors.xml b/packages/MediaComponents/res/values/colors.xml
index 6a65ef5..e7bc299 100644
--- a/packages/MediaComponents/res/values/colors.xml
+++ b/packages/MediaComponents/res/values/colors.xml
@@ -19,4 +19,7 @@
     <color name="white">#ffffff</color>
     <color name="white_opacity_70">#B3ffffff</color>
     <color name="black_opacity_70">#B3000000</color>
+    <color name="title_bar_gradient_start">#50000000</color>
+    <color name="title_bar_gradient_end">#00000000</color>
+    <color name="bottom_bar_background">#40202020</color>
 </resources>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/values/dimens.xml b/packages/MediaComponents/res/values/dimens.xml
index 8d72d40..2d7b022 100644
--- a/packages/MediaComponents/res/values/dimens.xml
+++ b/packages/MediaComponents/res/values/dimens.xml
@@ -62,5 +62,11 @@
     <dimen name="mcv2_minimal_icon_size">24dp</dimen>
     <dimen name="mcv2_icon_margin">10dp</dimen>
 
+    <dimen name="mcv2_full_album_image_portrait_size">232dp</dimen>
+    <dimen name="mcv2_full_album_image_landscape_size">176dp</dimen>
+
+    <dimen name="mcv2_custom_progress_max_size">2dp</dimen>
+    <dimen name="mcv2_custom_progress_thumb_size">12dp</dimen>
+    <dimen name="mcv2_buffer_view_height">5dp</dimen>
     <!-- TODO: adjust bottom bar view -->
 </resources>
diff --git a/packages/MediaComponents/res/values/strings.xml b/packages/MediaComponents/res/values/strings.xml
index 69e9dff..2597a3b 100644
--- a/packages/MediaComponents/res/values/strings.xml
+++ b/packages/MediaComponents/res/values/strings.xml
@@ -84,10 +84,6 @@
     <!-- Placeholder text indicating that the user is currently casting screen. [CHAR LIMIT=50] -->
     <string name="mr_controller_casting_screen">Casting screen</string>
 
-    <string name="lockscreen_pause_button_content_description">Pause</string>
-    <string name="lockscreen_play_button_content_description">Play</string>
-    <string name="lockscreen_replay_button_content_description">Replay</string>
-
     <!-- Text for error alert when a video container is not valid for progressive download/playback. -->
     <string name="VideoView2_error_text_invalid_progressive_playback">This video isn\'t valid for streaming to this device.</string>
     <!-- Text for error alert when a video cannot be played. It can be used by any app. -->
@@ -133,4 +129,29 @@
     <string name="MediaControlView2_audio_track_number_text">
         Track <xliff:g id="audio_number" example="1">%1$s</xliff:g>
     </string>
+    <!-- Text for displaying unknown song title. -->
+    <string name="mcv2_music_title_unknown_text">Song title unknown</string>
+    <!-- Text for displaying unknown artist name. -->
+    <string name="mcv2_music_artist_unknown_text">Artist unknown</string>
+
+    <!--Content Descriptions -->
+    <string name="mcv2_back_button_desc">Back</string>
+    <string name="mcv2_overflow_left_button_desc">See more buttons</string>
+    <string name="mcv2_overflow_right_button_desc">Back to previous button list</string>
+    <string name="mcv2_seek_bar_desc">Playback progress</string>
+    <string name="mcv2_settings_button_desc">Settings</string>
+    <string name="mcv2_video_quality_button_desc">Video Quality Selection</string>
+    <string name="mcv2_cc_is_on">Subtitle is on. Click to hide it.</string>
+    <string name="mcv2_cc_is_off">Subtitle is off. Click to show it.</string>
+    <string name="mcv2_replay_button_desc">Replay</string>
+    <string name="mcv2_play_button_desc">Play</string>
+    <string name="mcv2_pause_button_desc">Pause</string>
+    <string name="mcv2_previous_button_desc">Previous media</string>
+    <string name="mcv2_next_button_desc">Next media</string>
+    <string name="mcv2_rewind_button_desc">Rewind by 10 seconds</string>
+    <string name="mcv2_ffwd_button_desc">Go forward by 30 seconds</string>
+    <string name="mcv2_launch_button_desc">Launch Link</string>
+    <string name="mcv2_muted_button_desc">Muted. Click to unmute</string>
+    <string name="mcv2_unmuted_button_desc">Click to Mute</string>
+    <string name="mcv2_full_screen_button_desc">Full screen</string>
 </resources>
diff --git a/packages/MediaComponents/res/values/style.xml b/packages/MediaComponents/res/values/style.xml
index b1da137..5b9a8ee 100644
--- a/packages/MediaComponents/res/values/style.xml
+++ b/packages/MediaComponents/res/values/style.xml
@@ -10,30 +10,35 @@
         <item name="android:src">@drawable/ic_skip_previous</item>
         <item name="android:layout_width">@dimen/mcv2_full_icon_size</item>
         <item name="android:layout_height">@dimen/mcv2_full_icon_size</item>
+        <item name="android:contentDescription">@string/mcv2_previous_button_desc</item>
     </style>
 
     <style name="FullTransportControlsButton.Next">
         <item name="android:src">@drawable/ic_skip_next</item>
         <item name="android:layout_width">@dimen/mcv2_full_icon_size</item>
         <item name="android:layout_height">@dimen/mcv2_full_icon_size</item>
+        <item name="android:contentDescription">@string/mcv2_next_button_desc</item>
     </style>
 
     <style name="FullTransportControlsButton.Pause">
         <item name="android:src">@drawable/ic_pause_circle_filled</item>
         <item name="android:layout_width">@dimen/mcv2_pause_icon_size</item>
         <item name="android:layout_height">@dimen/mcv2_pause_icon_size</item>
+        <item name="android:contentDescription">@string/mcv2_pause_button_desc</item>
     </style>
 
     <style name="FullTransportControlsButton.Ffwd">
         <item name="android:src">@drawable/ic_forward_30</item>
         <item name="android:layout_width">@dimen/mcv2_full_icon_size</item>
         <item name="android:layout_height">@dimen/mcv2_full_icon_size</item>
+        <item name="android:contentDescription">@string/mcv2_ffwd_button_desc</item>
     </style>
 
     <style name="FullTransportControlsButton.Rew">
         <item name="android:src">@drawable/ic_rewind_10</item>
         <item name="android:layout_width">@dimen/mcv2_full_icon_size</item>
         <item name="android:layout_height">@dimen/mcv2_full_icon_size</item>
+        <item name="android:contentDescription">@string/mcv2_rewind_button_desc</item>
     </style>
 
     <style name="EmbeddedTransportControlsButton">
@@ -46,45 +51,52 @@
         <item name="android:src">@drawable/ic_skip_previous</item>
         <item name="android:layout_width">@dimen/mcv2_embedded_icon_size</item>
         <item name="android:layout_height">@dimen/mcv2_embedded_icon_size</item>
+        <item name="android:contentDescription">@string/mcv2_previous_button_desc</item>
     </style>
 
     <style name="EmbeddedTransportControlsButton.Next">
         <item name="android:src">@drawable/ic_skip_next</item>
         <item name="android:layout_width">@dimen/mcv2_embedded_icon_size</item>
         <item name="android:layout_height">@dimen/mcv2_embedded_icon_size</item>
+        <item name="android:contentDescription">@string/mcv2_next_button_desc</item>
     </style>
 
     <style name="EmbeddedTransportControlsButton.Pause">
         <item name="android:src">@drawable/ic_pause_circle_filled</item>
         <item name="android:layout_width">@dimen/mcv2_pause_icon_size</item>
         <item name="android:layout_height">@dimen/mcv2_pause_icon_size</item>
+        <item name="android:contentDescription">@string/mcv2_pause_button_desc</item>
     </style>
 
     <style name="EmbeddedTransportControlsButton.Ffwd">
         <item name="android:src">@drawable/ic_forward_30</item>
         <item name="android:layout_width">@dimen/mcv2_embedded_icon_size</item>
         <item name="android:layout_height">@dimen/mcv2_embedded_icon_size</item>
+        <item name="android:contentDescription">@string/mcv2_ffwd_button_desc</item>
     </style>
 
     <style name="EmbeddedTransportControlsButton.Rew">
         <item name="android:src">@drawable/ic_rewind_10</item>
         <item name="android:layout_width">@dimen/mcv2_embedded_icon_size</item>
         <item name="android:layout_height">@dimen/mcv2_embedded_icon_size</item>
+        <item name="android:contentDescription">@string/mcv2_rewind_button_desc</item>
     </style>
 
     <style name="MinimalTransportControlsButton">
         <item name="android:background">@null</item>
+        <item name="android:layout_width">@dimen/mcv2_pause_icon_size</item>
+        <item name="android:layout_height">@dimen/mcv2_pause_icon_size</item>
+        <item name="android:layout_margin">@dimen/mcv2_icon_margin</item>
         <item name="android:scaleType">fitXY</item>
-    </style>
-
-    <style name="MinimalTransportControlsButton.Pause">
         <item name="android:src">@drawable/ic_pause_circle_filled</item>
-        <item name="android:layout_width">@dimen/mcv2_minimal_icon_size</item>
-        <item name="android:layout_height">@dimen/mcv2_minimal_icon_size</item>
+        <item name="android:contentDescription">@string/mcv2_pause_button_desc</item>
     </style>
 
     <style name="TitleBar">
+        <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">46dp</item>
+        <item name="android:paddingStart">5dp</item>
+        <item name="android:paddingEnd">5dp</item>
     </style>
 
     <style name="TitleBarButton">
@@ -95,10 +107,12 @@
 
     <style name="TitleBarButton.Back">
         <item name="android:src">@drawable/ic_arrow_back</item>
+        <item name="android:contentDescription">@string/mcv2_back_button_desc</item>
     </style>
 
     <style name="TitleBarButton.Launch">
         <item name="android:src">@drawable/ic_launch</item>
+        <item name="android:contentDescription">@string/mcv2_launch_button_desc</item>
     </style>
 
     <style name="TimeText">
@@ -137,29 +151,71 @@
 
     <style name="BottomBarButton.CC">
         <item name="android:src">@drawable/ic_subtitle_off</item>
+        <item name="android:contentDescription">@string/mcv2_cc_is_off</item>
     </style>
 
     <style name="BottomBarButton.FullScreen">
         <item name="android:src">@drawable/ic_fullscreen</item>
+        <item name="android:contentDescription">@string/mcv2_full_screen_button_desc</item>
     </style>
 
     <style name="BottomBarButton.OverflowRight">
         <item name="android:src">@drawable/ic_chevron_right</item>
+        <item name="android:contentDescription">@string/mcv2_overflow_right_button_desc</item>
     </style>
 
     <style name="BottomBarButton.OverflowLeft">
         <item name="android:src">@drawable/ic_chevron_left</item>
+        <item name="android:contentDescription">@string/mcv2_overflow_left_button_desc</item>
     </style>
 
     <style name="BottomBarButton.Settings">
         <item name="android:src">@drawable/ic_settings</item>
+        <item name="android:contentDescription">@string/mcv2_settings_button_desc</item>
     </style>
 
     <style name="BottomBarButton.Mute">
         <item name="android:src">@drawable/ic_unmute</item>
+        <item name="android:contentDescription">@string/mcv2_unmuted_button_desc</item>
     </style>
 
     <style name="BottomBarButton.VideoQuality">
-        <item name="android:src">@drawable/ic_high_quality</item>
+      <item name="android:src">@drawable/ic_high_quality</item>
+      <item name="android:contentDescription">@string/mcv2_video_quality_button_desc</item>
+    </style>
+
+    <style name="FullMusicPortrait">
+        <item name="android:layout_height">0dp</item>
+    </style>
+
+    <style name="FullMusicPortrait.Image">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_weight">0.6</item>
+        <item name="android:gravity">center</item>
+    </style>
+
+    <style name="FullMusicPortrait.Text">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_weight">0.4</item>
+        <item name="android:gravity">top|center</item>
+        <item name="android:orientation">vertical</item>
+    </style>
+
+    <style name="FullMusicLandscape">
+        <item name="android:layout_width">0dp</item>
+    </style>
+
+    <style name="FullMusicLandscape.Image">
+        <item name="android:layout_height">match_parent</item>
+        <item name="android:layout_weight">0.35</item>
+        <item name="android:gravity">center|right</item>
+    </style>
+
+    <style name="FullMusicLandscape.Text">
+        <item name="android:layout_height">match_parent</item>
+        <item name="android:layout_weight">0.65</item>
+        <item name="android:layout_marginLeft">24dp</item>
+        <item name="android:gravity">center|left</item>
+        <item name="android:orientation">vertical</item>
     </style>
 </resources>
diff --git a/packages/MediaComponents/src/com/android/media/MediaController2Impl.java b/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
index 0091816..249365a 100644
--- a/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaController2Impl.java
@@ -16,20 +16,20 @@
 
 package com.android.media;
 
-import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_SET_VOLUME;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_ADD_ITEM;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_REMOVE_ITEM;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_REPLACE_ITEM;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_SET_LIST;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_SET_LIST_METADATA;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_SET_REPEAT_MODE;
-import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_SET_SHUFFLE_MODE;
-import static android.media.MediaSession2.COMMAND_CODE_PLAY_FROM_MEDIA_ID;
-import static android.media.MediaSession2.COMMAND_CODE_PLAY_FROM_SEARCH;
-import static android.media.MediaSession2.COMMAND_CODE_PLAY_FROM_URI;
-import static android.media.MediaSession2.COMMAND_CODE_PREPARE_FROM_MEDIA_ID;
-import static android.media.MediaSession2.COMMAND_CODE_PREPARE_FROM_SEARCH;
-import static android.media.MediaSession2.COMMAND_CODE_PREPARE_FROM_URI;
+import static android.media.SessionCommand2.COMMAND_CODE_SET_VOLUME;
+import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_ADD_ITEM;
+import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_REMOVE_ITEM;
+import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_REPLACE_ITEM;
+import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_LIST;
+import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_LIST_METADATA;
+import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_REPEAT_MODE;
+import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_SHUFFLE_MODE;
+import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_MEDIA_ID;
+import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_SEARCH;
+import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_URI;
+import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_MEDIA_ID;
+import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_SEARCH;
+import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_URI;
 
 import android.app.PendingIntent;
 import android.content.ComponentName;
@@ -44,10 +44,9 @@
 import android.media.MediaMetadata2;
 import android.media.MediaPlaylistAgent.RepeatMode;
 import android.media.MediaPlaylistAgent.ShuffleMode;
-import android.media.MediaSession2;
-import android.media.MediaSession2.Command;
+import android.media.SessionCommand2;
 import android.media.MediaSession2.CommandButton;
-import android.media.MediaSession2.CommandGroup;
+import android.media.SessionCommandGroup2;
 import android.media.MediaSessionService2;
 import android.media.Rating2;
 import android.media.SessionToken2;
@@ -108,7 +107,7 @@
     @GuardedBy("mLock")
     private PendingIntent mSessionActivity;
     @GuardedBy("mLock")
-    private CommandGroup mAllowedCommands;
+    private SessionCommandGroup2 mAllowedCommands;
 
     // Assignment should be used with the lock hold, but should be used without a lock to prevent
     // potential deadlock.
@@ -297,7 +296,7 @@
     }
 
     // Returns session binder if the controller can send the command.
-    IMediaSession2 getSessionBinderIfAble(Command command) {
+    IMediaSession2 getSessionBinderIfAble(SessionCommand2 command) {
         synchronized (mLock) {
             if (!mAllowedCommands.hasCommand(command)) {
                 Log.w(TAG, "Controller isn't allowed to call command, command=" + command);
@@ -326,17 +325,17 @@
 
     @Override
     public void play_impl() {
-        sendTransportControlCommand(MediaSession2.COMMAND_CODE_PLAYBACK_PLAY);
+        sendTransportControlCommand(SessionCommand2.COMMAND_CODE_PLAYBACK_PLAY);
     }
 
     @Override
     public void pause_impl() {
-        sendTransportControlCommand(MediaSession2.COMMAND_CODE_PLAYBACK_PAUSE);
+        sendTransportControlCommand(SessionCommand2.COMMAND_CODE_PLAYBACK_PAUSE);
     }
 
     @Override
     public void stop_impl() {
-        sendTransportControlCommand(MediaSession2.COMMAND_CODE_PLAYBACK_STOP);
+        sendTransportControlCommand(SessionCommand2.COMMAND_CODE_PLAYBACK_STOP);
     }
 
     @Override
@@ -409,7 +408,7 @@
     @Override
     public void setVolumeTo_impl(int value, int flags) {
         // TODO(hdmoon): sanity check
-        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_PLAYBACK_SET_VOLUME);
+        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_SET_VOLUME);
         if (binder != null) {
             try {
                 binder.setVolumeTo(mControllerStub, value, flags);
@@ -424,7 +423,7 @@
     @Override
     public void adjustVolume_impl(int direction, int flags) {
         // TODO(hdmoon): sanity check
-        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_PLAYBACK_SET_VOLUME);
+        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_SET_VOLUME);
         if (binder != null) {
             try {
                 binder.adjustVolume(mControllerStub, direction, flags);
@@ -438,7 +437,7 @@
 
     @Override
     public void prepareFromUri_impl(Uri uri, Bundle extras) {
-        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_PREPARE_FROM_URI);
+        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_SESSION_PREPARE_FROM_URI);
         if (uri == null) {
             throw new IllegalArgumentException("uri shouldn't be null");
         }
@@ -455,7 +454,8 @@
 
     @Override
     public void prepareFromSearch_impl(String query, Bundle extras) {
-        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_PREPARE_FROM_SEARCH);
+        final IMediaSession2 binder = getSessionBinderIfAble(
+                COMMAND_CODE_SESSION_PREPARE_FROM_SEARCH);
         if (TextUtils.isEmpty(query)) {
             throw new IllegalArgumentException("query shouldn't be empty");
         }
@@ -472,7 +472,8 @@
 
     @Override
     public void prepareFromMediaId_impl(String mediaId, Bundle extras) {
-        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_PREPARE_FROM_MEDIA_ID);
+        final IMediaSession2 binder = getSessionBinderIfAble(
+                COMMAND_CODE_SESSION_PREPARE_FROM_MEDIA_ID);
         if (mediaId == null) {
             throw new IllegalArgumentException("mediaId shouldn't be null");
         }
@@ -489,7 +490,7 @@
 
     @Override
     public void playFromUri_impl(Uri uri, Bundle extras) {
-        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_PLAY_FROM_URI);
+        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_SESSION_PLAY_FROM_URI);
         if (uri == null) {
             throw new IllegalArgumentException("uri shouldn't be null");
         }
@@ -506,7 +507,7 @@
 
     @Override
     public void playFromSearch_impl(String query, Bundle extras) {
-        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_PLAY_FROM_SEARCH);
+        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_SESSION_PLAY_FROM_SEARCH);
         if (TextUtils.isEmpty(query)) {
             throw new IllegalArgumentException("query shouldn't be empty");
         }
@@ -523,7 +524,8 @@
 
     @Override
     public void playFromMediaId_impl(String mediaId, Bundle extras) {
-        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_PLAY_FROM_MEDIA_ID);
+        final IMediaSession2 binder = getSessionBinderIfAble(
+                COMMAND_CODE_SESSION_PLAY_FROM_MEDIA_ID);
         if (mediaId == null) {
             throw new IllegalArgumentException("mediaId shouldn't be null");
         }
@@ -560,7 +562,7 @@
     }
 
     @Override
-    public void sendCustomCommand_impl(Command command, Bundle args, ResultReceiver cb) {
+    public void sendCustomCommand_impl(SessionCommand2 command, Bundle args, ResultReceiver cb) {
         if (command == null) {
             throw new IllegalArgumentException("command shouldn't be null");
         }
@@ -630,17 +632,19 @@
 
     @Override
     public void prepare_impl() {
-        sendTransportControlCommand(MediaSession2.COMMAND_CODE_PLAYBACK_PREPARE);
+        sendTransportControlCommand(SessionCommand2.COMMAND_CODE_PLAYBACK_PREPARE);
     }
 
     @Override
     public void fastForward_impl() {
-        sendTransportControlCommand(MediaSession2.COMMAND_CODE_PLAYBACK_FAST_FORWARD);
+        // TODO(jaewan): Implement this. Note that fast forward isn't a transport command anymore
+        //sendTransportControlCommand(MediaSession2.COMMAND_CODE_SESSION_FAST_FORWARD);
     }
 
     @Override
     public void rewind_impl() {
-        sendTransportControlCommand(MediaSession2.COMMAND_CODE_PLAYBACK_REWIND);
+        // TODO(jaewan): Implement this. Note that rewind isn't a transport command anymore
+        //sendTransportControlCommand(MediaSession2.COMMAND_CODE_SESSION_REWIND);
     }
 
     @Override
@@ -650,7 +654,7 @@
         }
         Bundle args = new Bundle();
         args.putLong(MediaSession2Stub.ARGUMENT_KEY_POSITION, pos);
-        sendTransportControlCommand(MediaSession2.COMMAND_CODE_PLAYBACK_SEEK_TO, args);
+        sendTransportControlCommand(SessionCommand2.COMMAND_CODE_PLAYBACK_SEEK_TO, args);
     }
 
     @Override
@@ -764,7 +768,7 @@
     }
 
     @Override
-    public long getPosition_impl() {
+    public long getCurrentPosition_impl() {
         synchronized (mLock) {
             long timeDiff = System.currentTimeMillis() - mPositionEventTimeMs;
             long expectedPosition = mPositionMs + (long) (mPlaybackSpeed * timeDiff);
@@ -804,6 +808,7 @@
         });
     }
 
+    // TODO(jaewan): Rename to seek completed
     void pushPositionChanges(final long eventTimeMs, final long positionMs) {
         synchronized (mLock) {
             mPositionEventTimeMs = eventTimeMs;
@@ -813,7 +818,7 @@
             if (!mInstance.isConnected()) {
                 return;
             }
-            mCallback.onPositionChanged(mInstance, eventTimeMs, positionMs);
+            mCallback.onSeekCompleted(mInstance, positionMs);
         });
     }
 
@@ -837,7 +842,8 @@
             if (!mInstance.isConnected()) {
                 return;
             }
-            mCallback.onBufferedPositionChanged(mInstance, bufferedPositionMs);
+            // TODO(jaewan): Fix this -- it's now buffered state
+            //mCallback.onBufferedPositionChanged(mInstance, bufferedPositionMs);
         });
     }
 
@@ -862,8 +868,7 @@
             if (!mInstance.isConnected()) {
                 return;
             }
-            // TODO(jaewan): Fix public API not to take playlistAgent.
-            mCallback.onPlaylistChanged(mInstance, null, playlist, metadata);
+            mCallback.onPlaylistChanged(mInstance, playlist, metadata);
         });
     }
 
@@ -875,8 +880,7 @@
             if (!mInstance.isConnected()) {
                 return;
             }
-            // TODO(jaewan): Fix public API not to take playlistAgent.
-            mCallback.onPlaylistMetadataChanged(mInstance, null, metadata);
+            mCallback.onPlaylistMetadataChanged(mInstance, metadata);
         });
     }
 
@@ -888,8 +892,7 @@
             if (!mInstance.isConnected()) {
                 return;
             }
-            // TODO(jaewan): Fix public API not to take playlistAgent.
-            mCallback.onShuffleModeChanged(mInstance, null, shuffleMode);
+            mCallback.onShuffleModeChanged(mInstance, shuffleMode);
         });
     }
 
@@ -901,8 +904,7 @@
             if (!mInstance.isConnected()) {
                 return;
             }
-            // TODO(jaewan): Fix public API not to take playlistAgent.
-            mCallback.onRepeatModeChanged(mInstance, null, repeatMode);
+            mCallback.onRepeatModeChanged(mInstance, repeatMode);
         });
     }
 
@@ -917,7 +919,7 @@
 
     // Should be used without a lock to prevent potential deadlock.
     void onConnectedNotLocked(IMediaSession2 sessionBinder,
-            final CommandGroup allowedCommands,
+            final SessionCommandGroup2 allowedCommands,
             final int playerState,
             final long positionEventTimeMs,
             final long positionMs,
@@ -989,7 +991,7 @@
         }
     }
 
-    void onCustomCommand(final Command command, final Bundle args,
+    void onCustomCommand(final SessionCommand2 command, final Bundle args,
             final ResultReceiver receiver) {
         if (DEBUG) {
             Log.d(TAG, "onCustomCommand cmd=" + command);
@@ -1000,7 +1002,7 @@
         });
     }
 
-    void onAllowedCommandsChanged(final CommandGroup commands) {
+    void onAllowedCommandsChanged(final SessionCommandGroup2 commands) {
         mCallbackExecutor.execute(() -> {
             mCallback.onAllowedCommandsChanged(mInstance, commands);
         });
@@ -1062,7 +1064,6 @@
         private static final String KEY_AUDIO_ATTRIBUTES =
                 "android.media.playbackinfo_impl.audio_attrs";
 
-        private final Context mContext;
         private final PlaybackInfo mInstance;
 
         private final int mPlaybackType;
@@ -1071,9 +1072,8 @@
         private final int mCurrentVolume;
         private final AudioAttributes mAudioAttrs;
 
-        private PlaybackInfoImpl(Context context, int playbackType, AudioAttributes attrs,
-                int controlType, int max, int current) {
-            mContext = context;
+        private PlaybackInfoImpl(int playbackType, AudioAttributes attrs, int controlType,
+                int max, int current) {
             mPlaybackType = playbackType;
             mAudioAttrs = attrs;
             mControlType = controlType;
@@ -1107,11 +1107,11 @@
             return mCurrentVolume;
         }
 
-        public PlaybackInfo getInstance() {
+        PlaybackInfo getInstance() {
             return mInstance;
         }
 
-        public Bundle toBundle() {
+        Bundle toBundle() {
             Bundle bundle = new Bundle();
             bundle.putInt(KEY_PLAYBACK_TYPE, mPlaybackType);
             bundle.putInt(KEY_CONTROL_TYPE, mControlType);
@@ -1121,13 +1121,13 @@
             return bundle;
         }
 
-        public static PlaybackInfo createPlaybackInfo(Context context, int playbackType,
-                AudioAttributes attrs, int controlType, int max, int current) {
-            return new PlaybackInfoImpl(context, playbackType, attrs, controlType, max, current)
+        static PlaybackInfo createPlaybackInfo(int playbackType, AudioAttributes attrs,
+                int controlType, int max, int current) {
+            return new PlaybackInfoImpl(playbackType, attrs, controlType, max, current)
                     .getInstance();
         }
 
-        public static PlaybackInfo fromBundle(Context context, Bundle bundle) {
+        static PlaybackInfo fromBundle(Bundle bundle) {
             if (bundle == null) {
                 return null;
             }
@@ -1137,8 +1137,7 @@
             final int currentVolume = bundle.getInt(KEY_CURRENT_VOLUME);
             final AudioAttributes attrs = bundle.getParcelable(KEY_AUDIO_ATTRIBUTES);
 
-            return createPlaybackInfo(
-                    context, volumeType, attrs, volumeControl, maxVolume, currentVolume);
+            return createPlaybackInfo(volumeType, attrs, volumeControl, maxVolume, currentVolume);
         }
     }
 }
diff --git a/packages/MediaComponents/src/com/android/media/MediaController2Stub.java b/packages/MediaComponents/src/com/android/media/MediaController2Stub.java
index 721c963..2cfc5df 100644
--- a/packages/MediaComponents/src/com/android/media/MediaController2Stub.java
+++ b/packages/MediaComponents/src/com/android/media/MediaController2Stub.java
@@ -21,9 +21,9 @@
 import android.media.MediaController2;
 import android.media.MediaItem2;
 import android.media.MediaMetadata2;
-import android.media.MediaSession2.Command;
+import android.media.SessionCommand2;
 import android.media.MediaSession2.CommandButton;
-import android.media.MediaSession2.CommandGroup;
+import android.media.SessionCommandGroup2;
 import android.os.Bundle;
 import android.os.ResultReceiver;
 import android.text.TextUtils;
@@ -141,15 +141,14 @@
         }
         List<MediaItem2> playlist = new ArrayList<>();
         for (Bundle bundle : playlistBundle) {
-            MediaItem2 item = MediaItem2.fromBundle(controller.getContext(), bundle);
+            MediaItem2 item = MediaItem2.fromBundle(bundle);
             if (item == null) {
                 Log.w(TAG, "onPlaylistChanged(): Ignoring null item in playlist");
             } else {
                 playlist.add(item);
             }
         }
-        MediaMetadata2 metadata =
-                MediaMetadata2.fromBundle(controller.getContext(), metadataBundle);
+        MediaMetadata2 metadata = MediaMetadata2.fromBundle(metadataBundle);
         controller.pushPlaylistChanges(playlist, metadata);
     }
 
@@ -162,8 +161,7 @@
             Log.w(TAG, "Don't fail silently here. Highly likely a bug");
             return;
         }
-        MediaMetadata2 metadata =
-                MediaMetadata2.fromBundle(controller.getContext(), metadataBundle);
+        MediaMetadata2 metadata = MediaMetadata2.fromBundle(metadataBundle);
         controller.pushPlaylistMetadataChanges(metadata);
     }
 
@@ -191,14 +189,12 @@
             Log.w(TAG, "Don't fail silently here. Highly likely a bug");
             return;
         }
-        MediaController2.PlaybackInfo info =
-                PlaybackInfoImpl.fromBundle(controller.getContext(), playbackInfo);
+        MediaController2.PlaybackInfo info = PlaybackInfoImpl.fromBundle(playbackInfo);
         if (info == null) {
             Log.w(TAG, "onPlaybackInfoChanged(): Ignoring null playbackInfo");
             return;
         }
-        controller.pushPlaybackInfoChanges(
-                PlaybackInfoImpl.fromBundle(controller.getContext(), playbackInfo));
+        controller.pushPlaybackInfoChanges(info);
     }
 
     @Override
@@ -242,16 +238,16 @@
         if (itemBundleList != null) {
             itemList = new ArrayList<>();
             for (int i = 0; i < itemBundleList.size(); i++) {
-                MediaItem2 item = MediaItem2.fromBundle(context, itemBundleList.get(i));
+                MediaItem2 item = MediaItem2.fromBundle(itemBundleList.get(i));
                 if (item != null) {
                     itemList.add(item);
                 }
             }
         }
         controller.onConnectedNotLocked(sessionBinder,
-                CommandGroup.fromBundle(context, commandGroup),
+                SessionCommandGroup2.fromBundle(commandGroup),
                 playerState, positionEventTimeMs, positionMs, playbackSpeed, bufferedPositionMs,
-                PlaybackInfoImpl.fromBundle(context, playbackInfo), repeatMode, shuffleMode,
+                PlaybackInfoImpl.fromBundle(playbackInfo), repeatMode, shuffleMode,
                 itemList, sessionActivity);
     }
 
@@ -286,8 +282,7 @@
         }
         List<CommandButton> layout = new ArrayList<>();
         for (int i = 0; i < commandButtonlist.size(); i++) {
-            CommandButton button = CommandButtonImpl.fromBundle(
-                    controller.getContext(), commandButtonlist.get(i));
+            CommandButton button = CommandButtonImpl.fromBundle(commandButtonlist.get(i));
             if (button != null) {
                 layout.add(button);
             }
@@ -308,7 +303,7 @@
             // TODO(jaewan): Revisit here. Could be a bug
             return;
         }
-        CommandGroup commands = CommandGroup.fromBundle(controller.getContext(), commandsBundle);
+        SessionCommandGroup2 commands = SessionCommandGroup2.fromBundle(commandsBundle);
         if (commands == null) {
             Log.w(TAG, "onAllowedCommandsChanged(): Ignoring null commands");
             return;
@@ -325,7 +320,7 @@
             Log.w(TAG, "Don't fail silently here. Highly likely a bug");
             return;
         }
-        Command command = Command.fromBundle(controller.getContext(), commandBundle);
+        SessionCommand2 command = SessionCommand2.fromBundle(commandBundle);
         if (command == null) {
             Log.w(TAG, "onCustomCommand(): Ignoring null command");
             return;
@@ -371,8 +366,7 @@
             // TODO(jaewan): Revisit here. Could be a bug
             return;
         }
-        browser.onGetItemDone(mediaId,
-                MediaItem2Impl.fromBundle(browser.getContext(), itemBundle));
+        browser.onGetItemDone(mediaId, MediaItem2.fromBundle(itemBundle));
     }
 
     @Override
@@ -398,7 +392,7 @@
         if (itemBundleList != null) {
             result = new ArrayList<>();
             for (Bundle bundle : itemBundleList) {
-                result.add(MediaItem2.fromBundle(browser.getContext(), bundle));
+                result.add(MediaItem2.fromBundle(bundle));
             }
         }
         browser.onGetChildrenDone(parentId, page, pageSize, result, extras);
@@ -448,7 +442,7 @@
         if (itemBundleList != null) {
             result = new ArrayList<>();
             for (Bundle bundle : itemBundleList) {
-                result.add(MediaItem2.fromBundle(browser.getContext(), bundle));
+                result.add(MediaItem2.fromBundle(bundle));
             }
         }
         browser.onGetSearchResultDone(query, page, pageSize, result, extras);
diff --git a/packages/MediaComponents/src/com/android/media/MediaItem2Impl.java b/packages/MediaComponents/src/com/android/media/MediaItem2Impl.java
index c95b43f..910a0f1 100644
--- a/packages/MediaComponents/src/com/android/media/MediaItem2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaItem2Impl.java
@@ -21,7 +21,6 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.content.Context;
 import android.media.DataSourceDesc;
 import android.media.MediaItem2;
 import android.media.MediaItem2.Builder;
@@ -39,7 +38,6 @@
     private static final String KEY_METADATA = "android.media.mediaitem2.metadata";
     private static final String KEY_UUID = "android.media.mediaitem2.uuid";
 
-    private final Context mContext;
     private final MediaItem2 mInstance;
     private final String mId;
     private final int mFlags;
@@ -48,14 +46,13 @@
     private DataSourceDesc mDataSourceDesc;
 
     // From the public API
-    public MediaItem2Impl(@NonNull Context context, @NonNull String mediaId,
-            @Nullable DataSourceDesc dsd, @Nullable MediaMetadata2 metadata, @Flags int flags) {
-        this(context, mediaId, dsd, metadata, flags, null);
+    public MediaItem2Impl(@NonNull String mediaId, @Nullable DataSourceDesc dsd,
+            @Nullable MediaMetadata2 metadata, @Flags int flags) {
+        this(mediaId, dsd, metadata, flags, null);
     }
 
-    private MediaItem2Impl(@NonNull Context context, @NonNull String mediaId,
-            @Nullable DataSourceDesc dsd, @Nullable MediaMetadata2 metadata, @Flags int flags,
-            @Nullable UUID uuid) {
+    private MediaItem2Impl(@NonNull String mediaId, @Nullable DataSourceDesc dsd,
+            @Nullable MediaMetadata2 metadata, @Flags int flags, @Nullable UUID uuid) {
         if (mediaId == null) {
             throw new IllegalArgumentException("mediaId shouldn't be null");
         }
@@ -63,7 +60,6 @@
             throw new IllegalArgumentException("metadata's id should be matched with the mediaid");
         }
 
-        mContext = context;
         mId = mediaId;
         mDataSourceDesc = dsd;
         mMetadata = metadata;
@@ -101,16 +97,15 @@
     /**
      * Create a MediaItem2 from the {@link Bundle}.
      *
-     * @param context A context.
      * @param bundle The bundle which was published by {@link MediaItem2#toBundle()}.
      * @return The newly created MediaItem2
      */
-    public static MediaItem2 fromBundle(@NonNull Context context, @NonNull Bundle bundle) {
+    public static MediaItem2 fromBundle_impl(@NonNull Bundle bundle) {
         if (bundle == null) {
             return null;
         }
         final String uuidString = bundle.getString(KEY_UUID);
-        return fromBundle(context, bundle, UUID.fromString(uuidString));
+        return fromBundle(bundle, UUID.fromString(uuidString));
     }
 
     /**
@@ -118,22 +113,19 @@
      * If {@link UUID}
      * can be null for creating new.
      *
-     * @param context A context.
      * @param bundle The bundle which was published by {@link MediaItem2#toBundle()}.
      * @param uuid A {@link UUID} to override. Can be {@link null} for override.
      * @return The newly created MediaItem2
      */
-    static MediaItem2 fromBundle(@NonNull Context context, @NonNull Bundle bundle,
-            @Nullable UUID uuid) {
+    static MediaItem2 fromBundle(@NonNull Bundle bundle, @Nullable UUID uuid) {
         if (bundle == null) {
             return null;
         }
         final String id = bundle.getString(KEY_ID);
         final Bundle metadataBundle = bundle.getBundle(KEY_METADATA);
-        final MediaMetadata2 metadata = metadataBundle != null
-                ? MediaMetadata2.fromBundle(context, metadataBundle) : null;
+        final MediaMetadata2 metadata = MediaMetadata2.fromBundle(metadataBundle);
         final int flags = bundle.getInt(KEY_FLAGS);
-        return new MediaItem2Impl(context, id, null, metadata, flags, uuid).getInstance();
+        return new MediaItem2Impl(id, null, metadata, flags, uuid).getInstance();
     }
 
     private MediaItem2 getInstance() {
@@ -188,15 +180,13 @@
     }
 
     public static class BuilderImpl implements MediaItem2Provider.BuilderProvider {
-        private Context mContext;
         private Builder mInstance;
         private @Flags int mFlags;
         private String mMediaId;
         private MediaMetadata2 mMetadata;
         private DataSourceDesc mDataSourceDesc;
 
-        public BuilderImpl(Context context, Builder instance, int flags) {
-            mContext = context;
+        public BuilderImpl(Builder instance, int flags) {
             mInstance = instance;
             mFlags = flags;
         }
@@ -227,8 +217,7 @@
                 //  TODO(jaewan): Double check if its sufficient (e.g. Use UUID instead?)
                 id = (mMediaId != null) ? mMediaId : toString();
             }
-            return new MediaItem2Impl(mContext, id, mDataSourceDesc, mMetadata, mFlags)
-                    .getInstance();
+            return new MediaItem2Impl(id, mDataSourceDesc, mMetadata, mFlags).getInstance();
         }
     }
 }
diff --git a/packages/MediaComponents/src/com/android/media/MediaLibraryService2Impl.java b/packages/MediaComponents/src/com/android/media/MediaLibraryService2Impl.java
index b3512cc..cf34cd4 100644
--- a/packages/MediaComponents/src/com/android/media/MediaLibraryService2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaLibraryService2Impl.java
@@ -151,8 +151,7 @@
         private final String mRootId;
         private final Bundle mExtras;
 
-        public LibraryRootImpl(Context context, LibraryRoot instance, String rootId,
-                Bundle extras) {
+        public LibraryRootImpl(LibraryRoot instance, String rootId, Bundle extras) {
             if (rootId == null) {
                 throw new IllegalArgumentException("rootId shouldn't be null.");
             }
diff --git a/packages/MediaComponents/src/com/android/media/MediaMetadata2Impl.java b/packages/MediaComponents/src/com/android/media/MediaMetadata2Impl.java
index 286f5ee..cf1c532 100644
--- a/packages/MediaComponents/src/com/android/media/MediaMetadata2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaMetadata2Impl.java
@@ -19,7 +19,6 @@
 import static android.media.MediaMetadata2.*;
 
 import android.annotation.Nullable;
-import android.content.Context;
 import android.graphics.Bitmap;
 import android.media.MediaMetadata2;
 import android.media.MediaMetadata2.BitmapKey;
@@ -78,8 +77,6 @@
         METADATA_KEYS_TYPE.put(METADATA_KEY_MEDIA_URI, METADATA_TYPE_TEXT);
         METADATA_KEYS_TYPE.put(METADATA_KEY_ADVERTISEMENT, METADATA_TYPE_LONG);
         METADATA_KEYS_TYPE.put(METADATA_KEY_DOWNLOAD_STATUS, METADATA_TYPE_LONG);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_RADIO_FREQUENCY, METADATA_TYPE_FLOAT);
-        METADATA_KEYS_TYPE.put(METADATA_KEY_RADIO_CALLSIGN, METADATA_TYPE_TEXT);
     }
 
     private static final @TextKey
@@ -107,12 +104,10 @@
             METADATA_KEY_ALBUM_ART_URI
     };
 
-    private final Context mContext;
     private final MediaMetadata2 mInstance;
     private final Bundle mBundle;
 
-    public MediaMetadata2Impl(Context context, Bundle bundle) {
-        mContext = context;
+    public MediaMetadata2Impl(Bundle bundle) {
         mInstance = new MediaMetadata2(this);
         mBundle = bundle;
     }
@@ -170,7 +165,7 @@
         // TODO(jaewan): Add backward compatibility
         Rating2 rating = null;
         try {
-            rating = Rating2.fromBundle(mContext, mBundle.getBundle(key));
+            rating = Rating2.fromBundle(mBundle.getBundle(key));
         } catch (Exception e) {
             // ignore, value was not a rating
             Log.w(TAG, "Failed to retrieve a key as Rating.", e);
@@ -227,33 +222,28 @@
         return mBundle;
     }
 
-    public static MediaMetadata2 fromBundle(Context context, Bundle bundle) {
-        return (bundle == null) ? null : new MediaMetadata2Impl(context, bundle).getInstance();
+    public static MediaMetadata2 fromBundle_impl(Bundle bundle) {
+        return (bundle == null) ? null : new MediaMetadata2Impl(bundle).getInstance();
     }
 
     public static final class BuilderImpl implements MediaMetadata2Provider.BuilderProvider {
-        private final Context mContext;
         private final MediaMetadata2.Builder mInstance;
         private final Bundle mBundle;
 
-        public BuilderImpl(Context context, MediaMetadata2.Builder instance) {
-            mContext = context;
+        public BuilderImpl(MediaMetadata2.Builder instance) {
             mInstance = instance;
             mBundle = new Bundle();
         }
 
-        public BuilderImpl(Context context, MediaMetadata2.Builder instance,
-                MediaMetadata2 source) {
+        public BuilderImpl(MediaMetadata2.Builder instance, MediaMetadata2 source) {
             if (source == null) {
                 throw new IllegalArgumentException("source shouldn't be null");
             }
-            mContext = context;
             mInstance = instance;
             mBundle = new Bundle(source.toBundle());
         }
 
-        public BuilderImpl(Context context, int maxBitmapSize) {
-            mContext = context;
+        public BuilderImpl(int maxBitmapSize) {
             mInstance = new MediaMetadata2.Builder(this);
             mBundle = new Bundle();
 
@@ -366,7 +356,7 @@
 
         @Override
         public MediaMetadata2 build_impl() {
-            return new MediaMetadata2Impl(mContext, mBundle).getInstance();
+            return new MediaMetadata2Impl(mBundle).getInstance();
         }
 
         private Bitmap scaleBitmap(Bitmap bmp, int maxSize) {
diff --git a/packages/MediaComponents/src/com/android/media/MediaPlaylistAgentImpl.java b/packages/MediaComponents/src/com/android/media/MediaPlaylistAgentImpl.java
index ab6b167..dfd4e1a 100644
--- a/packages/MediaComponents/src/com/android/media/MediaPlaylistAgentImpl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaPlaylistAgentImpl.java
@@ -19,7 +19,6 @@
 import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.content.Context;
 import android.media.DataSourceDesc;
 import android.media.MediaItem2;
 import android.media.MediaMetadata2;
@@ -37,15 +36,13 @@
 public class MediaPlaylistAgentImpl implements MediaPlaylistAgentProvider {
     private static final String TAG = "MediaPlaylistAgent";
 
-    private final Context mContext;
     private final MediaPlaylistAgent mInstance;
 
     private final Object mLock = new Object();
     @GuardedBy("mLock")
     private final ArrayMap<PlaylistEventCallback, Executor> mCallbacks = new ArrayMap<>();
 
-    public MediaPlaylistAgentImpl(Context context, MediaPlaylistAgent instance) {
-        mContext = context;
+    public MediaPlaylistAgentImpl(MediaPlaylistAgent instance) {
         mInstance = instance;
     }
 
diff --git a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java b/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
index 89c29e6..4ec6042 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSession2Impl.java
@@ -16,7 +16,7 @@
 
 package com.android.media;
 
-import static android.media.MediaSession2.COMMAND_CODE_CUSTOM;
+import static android.media.SessionCommand2.COMMAND_CODE_CUSTOM;
 import static android.media.SessionToken2.TYPE_LIBRARY_SERVICE;
 import static android.media.SessionToken2.TYPE_SESSION;
 import static android.media.SessionToken2.TYPE_SESSION_SERVICE;
@@ -44,9 +44,9 @@
 import android.media.MediaPlaylistAgent.PlaylistEventCallback;
 import android.media.MediaSession2;
 import android.media.MediaSession2.Builder;
-import android.media.MediaSession2.Command;
+import android.media.SessionCommand2;
 import android.media.MediaSession2.CommandButton;
-import android.media.MediaSession2.CommandGroup;
+import android.media.SessionCommandGroup2;
 import android.media.MediaSession2.ControllerInfo;
 import android.media.MediaSession2.OnDataSourceMissingHelper;
 import android.media.MediaSession2.SessionCallback;
@@ -68,8 +68,10 @@
 import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.NoSuchElementException;
+import java.util.Set;
 import java.util.concurrent.Executor;
 
 public class MediaSession2Impl implements MediaSession2Provider {
@@ -156,13 +158,13 @@
             throw new IllegalArgumentException("Ambiguous session type. Multiple"
                     + " session services define the same id=" + id);
         } else if (libraryService != null) {
-            mSessionToken = new SessionToken2Impl(context, Process.myUid(), TYPE_LIBRARY_SERVICE,
+            mSessionToken = new SessionToken2Impl(Process.myUid(), TYPE_LIBRARY_SERVICE,
                     mContext.getPackageName(), libraryService, id, mSessionStub).getInstance();
         } else if (sessionService != null) {
-            mSessionToken = new SessionToken2Impl(context, Process.myUid(), TYPE_SESSION_SERVICE,
+            mSessionToken = new SessionToken2Impl(Process.myUid(), TYPE_SESSION_SERVICE,
                     mContext.getPackageName(), sessionService, id, mSessionStub).getInstance();
         } else {
-            mSessionToken = new SessionToken2Impl(context, Process.myUid(), TYPE_SESSION,
+            mSessionToken = new SessionToken2Impl(Process.myUid(), TYPE_SESSION,
                     mContext.getPackageName(), null, id, mSessionStub).getInstance();
         }
 
@@ -230,7 +232,7 @@
             oldAgent = mPlaylistAgent;
             mPlayer = player;
             if (agent == null) {
-                mSessionPlaylistAgent = new SessionPlaylistAgent(mContext, this, mPlayer);
+                mSessionPlaylistAgent = new SessionPlaylistAgent(this, mPlayer);
                 if (mDsmHelper != null) {
                     mSessionPlaylistAgent.setOnDataSourceMissingHelper(mDsmHelper);
                 }
@@ -278,7 +280,6 @@
                 }
             }
             info = MediaController2Impl.PlaybackInfoImpl.createPlaybackInfo(
-                    mContext,
                     PlaybackInfo.PLAYBACK_TYPE_LOCAL,
                     attrs,
                     mAudioManager.isVolumeFixed()
@@ -288,7 +289,6 @@
                     mAudioManager.getStreamVolume(stream));
         } else {
             info = MediaController2Impl.PlaybackInfoImpl.createPlaybackInfo(
-                    mContext,
                     PlaybackInfo.PLAYBACK_TYPE_REMOTE /* ControlType */,
                     attrs,
                     volumeProvider.getControlType(),
@@ -444,7 +444,7 @@
 
     @Override
     public void setAllowedCommands_impl(@NonNull ControllerInfo controller,
-            @NonNull CommandGroup commands) {
+            @NonNull SessionCommandGroup2 commands) {
         if (controller == null) {
             throw new IllegalArgumentException("controller shouldn't be null");
         }
@@ -455,8 +455,8 @@
     }
 
     @Override
-    public void sendCustomCommand_impl(@NonNull ControllerInfo controller, @NonNull Command command,
-            Bundle args, ResultReceiver receiver) {
+    public void sendCustomCommand_impl(@NonNull ControllerInfo controller,
+            @NonNull SessionCommand2 command, Bundle args, ResultReceiver receiver) {
         if (controller == null) {
             throw new IllegalArgumentException("controller shouldn't be null");
         }
@@ -467,7 +467,7 @@
     }
 
     @Override
-    public void sendCustomCommand_impl(@NonNull Command command, Bundle args) {
+    public void sendCustomCommand_impl(@NonNull SessionCommand2 command, Bundle args) {
         if (command == null) {
             throw new IllegalArgumentException("command shouldn't be null");
         }
@@ -625,28 +625,6 @@
     }
 
     @Override
-    public void fastForward_impl() {
-        ensureCallingThread();
-        final MediaPlayerBase player = mPlayer;
-        if (player != null) {
-            player.fastForward();
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-    }
-
-    @Override
-    public void rewind_impl() {
-        ensureCallingThread();
-        final MediaPlayerBase player = mPlayer;
-        if (player != null) {
-            player.rewind();
-        } else if (DEBUG) {
-            Log.d(TAG, "API calls after the close()", new IllegalStateException());
-        }
-    }
-
-    @Override
     public void seekTo_impl(long pos) {
         ensureCallingThread();
         final MediaPlayerBase player = mPlayer;
@@ -669,7 +647,7 @@
     }
 
     @Override
-    public long getPosition_impl() {
+    public long getCurrentPosition_impl() {
         final MediaPlayerBase player = mPlayer;
         if (player != null) {
             return mPlayer.getCurrentPosition();
@@ -1002,20 +980,21 @@
         private static final String KEY_COMMAND_EXTRAS
                 = "android.media.media_session2.command.extras";
 
-        private final Command mInstance;
+        private final SessionCommand2 mInstance;
         private final int mCommandCode;
         // Nonnull if it's custom command
         private final String mCustomCommand;
         private final Bundle mExtras;
 
-        public CommandImpl(Command instance, int commandCode) {
+        public CommandImpl(SessionCommand2 instance, int commandCode) {
             mInstance = instance;
             mCommandCode = commandCode;
             mCustomCommand = null;
             mExtras = null;
         }
 
-        public CommandImpl(Command instance, @NonNull String action, @Nullable Bundle extras) {
+        public CommandImpl(SessionCommand2 instance, @NonNull String action,
+                @Nullable Bundle extras) {
             if (action == null) {
                 throw new IllegalArgumentException("action shouldn't be null");
             }
@@ -1055,19 +1034,19 @@
         /**
          * @return a new Command instance from the Bundle
          */
-        public static Command fromBundle_impl(Context context, @NonNull Bundle command) {
+        public static SessionCommand2 fromBundle_impl(@NonNull Bundle command) {
             if (command == null) {
                 throw new IllegalArgumentException("command shouldn't be null");
             }
             int code = command.getInt(KEY_COMMAND_CODE);
             if (code != COMMAND_CODE_CUSTOM) {
-                return new Command(context, code);
+                return new SessionCommand2(code);
             } else {
                 String customCommand = command.getString(KEY_COMMAND_CUSTOM_COMMAND);
                 if (customCommand == null) {
                     return null;
                 }
-                return new Command(context, customCommand, command.getBundle(KEY_COMMAND_EXTRAS));
+                return new SessionCommand2(customCommand, command.getBundle(KEY_COMMAND_EXTRAS));
             }
         }
 
@@ -1077,8 +1056,7 @@
                 return false;
             }
             CommandImpl other = (CommandImpl) obj;
-            // TODO(jaewan): Should we also compare contents in bundle?
-            //               It may not be possible if the bundle contains private class.
+            // TODO(jaewan): Compare Commands with the generated UUID, as we're doing for the MI2.
             return mCommandCode == other.mCommandCode
                     && TextUtils.equals(mCustomCommand, other.mCustomCommand);
         }
@@ -1092,7 +1070,7 @@
     }
 
     /**
-     * Represent set of {@link Command}.
+     * Represent set of {@link SessionCommand2}.
      */
     public static class CommandGroupImpl implements CommandGroupProvider {
         private static final String KEY_COMMANDS =
@@ -1107,25 +1085,22 @@
         // Prefix for command codes that will be sent directly to the MediaPlaylistAgent
         private static final String PREFIX_COMMAND_CODE_PLAYLIST = "COMMAND_CODE_PLAYLIST_";
 
-        private List<Command> mCommands = new ArrayList<>();
-        private final Context mContext;
-        private final CommandGroup mInstance;
+        private Set<SessionCommand2> mCommands = new HashSet<>();
+        private final SessionCommandGroup2 mInstance;
 
-        public CommandGroupImpl(Context context, CommandGroup instance, Object other) {
-            mContext = context;
+        public CommandGroupImpl(SessionCommandGroup2 instance, Object other) {
             mInstance = instance;
             if (other != null && other instanceof CommandGroupImpl) {
                 mCommands.addAll(((CommandGroupImpl) other).mCommands);
             }
         }
 
-        public CommandGroupImpl(Context context) {
-            mContext = context;
-            mInstance = new CommandGroup(this);
+        public CommandGroupImpl() {
+            mInstance = new SessionCommandGroup2(this);
         }
 
         @Override
-        public void addCommand_impl(@NonNull Command command) {
+        public void addCommand_impl(@NonNull SessionCommand2 command) {
             if (command == null) {
                 throw new IllegalArgumentException("command shouldn't be null");
             }
@@ -1137,11 +1112,11 @@
             addCommandsWithPrefix(PREFIX_COMMAND_CODE);
         }
 
-        public void addAllPlaybackCommands() {
+        void addAllPlaybackCommands() {
             addCommandsWithPrefix(PREFIX_COMMAND_CODE_PLAYBACK);
         }
 
-        public void addAllPlaylistCommands() {
+        void addAllPlaylistCommands() {
             addCommandsWithPrefix(PREFIX_COMMAND_CODE_PLAYLIST);
         }
 
@@ -1152,7 +1127,7 @@
                 for (int i = 0; i < fields.length; i++) {
                     if (fields[i].getName().startsWith(prefix)) {
                         try {
-                            mCommands.add(new Command(mContext, fields[i].getInt(null)));
+                            mCommands.add(new SessionCommand2(fields[i].getInt(null)));
                         } catch (IllegalAccessException e) {
                             Log.w(TAG, "Unexpected " + fields[i] + " in MediaSession2");
                         }
@@ -1162,7 +1137,7 @@
         }
 
         @Override
-        public void removeCommand_impl(@NonNull Command command) {
+        public void removeCommand_impl(@NonNull SessionCommand2 command) {
             if (command == null) {
                 throw new IllegalArgumentException("command shouldn't be null");
             }
@@ -1170,7 +1145,7 @@
         }
 
         @Override
-        public boolean hasCommand_impl(@NonNull Command command) {
+        public boolean hasCommand_impl(@NonNull SessionCommand2 command) {
             if (command == null) {
                 throw new IllegalArgumentException("command shouldn't be null");
             }
@@ -1182,8 +1157,8 @@
             if (code == COMMAND_CODE_CUSTOM) {
                 throw new IllegalArgumentException("Use hasCommand(Command) for custom command");
             }
-            for (int i = 0; i < mCommands.size(); i++) {
-                if (mCommands.get(i).getCommandCode() == code) {
+            for (SessionCommand2 command : mCommands) {
+                if (command.getCommandCode() == code) {
                     return true;
                 }
             }
@@ -1191,12 +1166,12 @@
         }
 
         @Override
-        public List<Command> getCommands_impl() {
+        public Set<SessionCommand2> getCommands_impl() {
             return getCommands();
         }
 
-        public List<Command> getCommands() {
-            return Collections.unmodifiableList(mCommands);
+        public Set<SessionCommand2> getCommands() {
+            return Collections.unmodifiableSet(mCommands);
         }
 
         /**
@@ -1206,8 +1181,8 @@
         @Override
         public Bundle toBundle_impl() {
             ArrayList<Bundle> list = new ArrayList<>();
-            for (int i = 0; i < mCommands.size(); i++) {
-                list.add(mCommands.get(i).toBundle());
+            for (SessionCommand2 command : mCommands) {
+                list.add(command.toBundle());
             }
             Bundle bundle = new Bundle();
             bundle.putParcelableArrayList(KEY_COMMANDS, list);
@@ -1218,7 +1193,7 @@
          * @return new instance of CommandGroup from the bundle
          * @hide
          */
-        public static @Nullable CommandGroup fromBundle_impl(Context context, Bundle commands) {
+        public static @Nullable SessionCommandGroup2 fromBundle_impl(Bundle commands) {
             if (commands == null) {
                 return null;
             }
@@ -1226,14 +1201,14 @@
             if (list == null) {
                 return null;
             }
-            CommandGroup commandGroup = new CommandGroup(context);
+            SessionCommandGroup2 commandGroup = new SessionCommandGroup2();
             for (int i = 0; i < list.size(); i++) {
                 Parcelable parcelable = list.get(i);
                 if (!(parcelable instanceof Bundle)) {
                     continue;
                 }
                 Bundle commandBundle = (Bundle) parcelable;
-                Command command = Command.fromBundle(context, commandBundle);
+                SessionCommand2 command = SessionCommand2.fromBundle(commandBundle);
                 if (command != null) {
                     commandGroup.addCommand(command);
                 }
@@ -1267,7 +1242,8 @@
             // Ask server whether the controller is trusted.
             // App cannot know this because apps cannot query enabled notification listener for
             // another package, but system server can do.
-            mIsTrusted = manager.isTrusted(packageName, pid, uid);
+            mIsTrusted = manager.isTrustedForMediaControl(
+                    new MediaSessionManager.RemoteUserInfo(packageName, pid, uid));
         }
 
         @Override
@@ -1318,19 +1294,19 @@
             return mControllerBinder.asBinder().equals(other.mControllerBinder.asBinder());
         }
 
-        public ControllerInfo getInstance() {
+        ControllerInfo getInstance() {
             return mInstance;
         }
 
-        public IBinder getId() {
+        IBinder getId() {
             return mControllerBinder.asBinder();
         }
 
-        public IMediaController2 getControllerBinder() {
+        IMediaController2 getControllerBinder() {
             return mControllerBinder;
         }
 
-        public static ControllerInfoImpl from(ControllerInfo controller) {
+        static ControllerInfoImpl from(ControllerInfo controller) {
             return (ControllerInfoImpl) controller.getProvider();
         }
     }
@@ -1348,13 +1324,13 @@
                 = "android.media.media_session2.command_button.enabled";
 
         private final CommandButton mInstance;
-        private Command mCommand;
+        private SessionCommand2 mCommand;
         private int mIconResId;
         private String mDisplayName;
         private Bundle mExtras;
         private boolean mEnabled;
 
-        public CommandButtonImpl(Context context, @Nullable Command command, int iconResId,
+        public CommandButtonImpl(@Nullable SessionCommand2 command, int iconResId,
                 @Nullable String displayName, Bundle extras, boolean enabled) {
             mCommand = command;
             mIconResId = iconResId;
@@ -1365,7 +1341,8 @@
         }
 
         @Override
-        public @Nullable Command getCommand_impl() {
+        public @Nullable
+        SessionCommand2 getCommand_impl() {
             return mCommand;
         }
 
@@ -1389,7 +1366,7 @@
             return mEnabled;
         }
 
-        public @NonNull Bundle toBundle() {
+        @NonNull Bundle toBundle() {
             Bundle bundle = new Bundle();
             bundle.putBundle(KEY_COMMAND, mCommand.toBundle());
             bundle.putInt(KEY_ICON_RES_ID, mIconResId);
@@ -1399,12 +1376,12 @@
             return bundle;
         }
 
-        public static @Nullable CommandButton fromBundle(Context context, Bundle bundle) {
+        static @Nullable CommandButton fromBundle(Bundle bundle) {
             if (bundle == null) {
                 return null;
             }
-            CommandButton.Builder builder = new CommandButton.Builder(context);
-            builder.setCommand(Command.fromBundle(context, bundle.getBundle(KEY_COMMAND)));
+            CommandButton.Builder builder = new CommandButton.Builder();
+            builder.setCommand(SessionCommand2.fromBundle(bundle.getBundle(KEY_COMMAND)));
             builder.setIconResId(bundle.getInt(KEY_ICON_RES_ID, 0));
             builder.setDisplayName(bundle.getString(KEY_DISPLAY_NAME));
             builder.setExtras(bundle.getBundle(KEY_EXTRAS));
@@ -1421,22 +1398,20 @@
          * Builder for {@link CommandButton}.
          */
         public static class BuilderImpl implements CommandButtonProvider.BuilderProvider {
-            private final Context mContext;
             private final CommandButton.Builder mInstance;
-            private Command mCommand;
+            private SessionCommand2 mCommand;
             private int mIconResId;
             private String mDisplayName;
             private Bundle mExtras;
             private boolean mEnabled;
 
-            public BuilderImpl(Context context, CommandButton.Builder instance) {
-                mContext = context;
+            public BuilderImpl(CommandButton.Builder instance) {
                 mInstance = instance;
                 mEnabled = true;
             }
 
             @Override
-            public CommandButton.Builder setCommand_impl(Command command) {
+            public CommandButton.Builder setCommand_impl(SessionCommand2 command) {
                 mCommand = command;
                 return mInstance;
             }
@@ -1476,8 +1451,8 @@
                     throw new IllegalStateException("Custom commands needs icon and"
                             + " and name to display");
                 }
-                return new CommandButtonImpl(
-                        mContext, mCommand, mIconResId, mDisplayName, mExtras, mEnabled).mInstance;
+                return new CommandButtonImpl(mCommand, mIconResId, mDisplayName, mExtras, mEnabled)
+                        .mInstance;
             }
         }
     }
@@ -1571,7 +1546,7 @@
                 mCallbackExecutor = mContext.getMainExecutor();
             }
             if (mCallback == null) {
-                mCallback = new SessionCallback(mContext) {};
+                mCallback = new SessionCallback() {};
             }
             return new MediaSession2Impl(mContext, mPlayer, mId, mPlaylistAgent,
                     mVolumeProvider, mSessionActivity, mCallbackExecutor, mCallback).getInstance();
diff --git a/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java b/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
index caf834a..ec657d7 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSession2Stub.java
@@ -22,10 +22,9 @@
 import android.media.MediaItem2;
 import android.media.MediaLibraryService2.LibraryRoot;
 import android.media.MediaMetadata2;
-import android.media.MediaSession2;
-import android.media.MediaSession2.Command;
+import android.media.SessionCommand2;
 import android.media.MediaSession2.CommandButton;
-import android.media.MediaSession2.CommandGroup;
+import android.media.SessionCommandGroup2;
 import android.media.MediaSession2.ControllerInfo;
 import android.media.Rating2;
 import android.media.VolumeProvider2;
@@ -64,7 +63,8 @@
     private static final String TAG = "MediaSession2Stub";
     private static final boolean DEBUG = true; // TODO(jaewan): Rename.
 
-    private static final SparseArray<Command> sCommandsForOnCommandRequest = new SparseArray<>();
+    private static final SparseArray<SessionCommand2> sCommandsForOnCommandRequest =
+            new SparseArray<>();
 
     private final Object mLock = new Object();
     private final WeakReference<MediaSession2Impl> mSession;
@@ -74,7 +74,8 @@
     @GuardedBy("mLock")
     private final Set<IBinder> mConnectingControllers = new HashSet<>();
     @GuardedBy("mLock")
-    private final ArrayMap<ControllerInfo, CommandGroup> mAllowedCommandGroupMap = new ArrayMap<>();
+    private final ArrayMap<ControllerInfo, SessionCommandGroup2> mAllowedCommandGroupMap =
+            new ArrayMap<>();
     @GuardedBy("mLock")
     private final ArrayMap<ControllerInfo, Set<String>> mSubscriptions = new ArrayMap<>();
 
@@ -83,12 +84,11 @@
 
         synchronized (sCommandsForOnCommandRequest) {
             if (sCommandsForOnCommandRequest.size() == 0) {
-                CommandGroupImpl group = new CommandGroupImpl(session.getContext());
+                CommandGroupImpl group = new CommandGroupImpl();
                 group.addAllPlaybackCommands();
                 group.addAllPlaylistCommands();
-                List<Command> commands = group.getCommands();
-                for (int i = 0; i < commands.size(); i++) {
-                    Command command = commands.get(i);
+                Set<SessionCommand2> commands = group.getCommands();
+                for (SessionCommand2 command : commands) {
                     sCommandsForOnCommandRequest.append(command.getCommandCode(), command);
                 }
             }
@@ -148,7 +148,7 @@
             if (controllerInfo == null) {
                 return null;
             }
-            CommandGroup allowedCommands = mAllowedCommandGroupMap.get(controllerInfo);
+            SessionCommandGroup2 allowedCommands = mAllowedCommandGroupMap.get(controllerInfo);
             if (allowedCommands == null) {
                 Log.w(TAG, "Controller with null allowed commands. Ignoring",
                         new IllegalStateException());
@@ -165,13 +165,13 @@
     }
 
     // Get controller if the command from caller to session is able to be handled.
-    private ControllerInfo getControllerIfAble(IMediaController2 caller, Command command) {
+    private ControllerInfo getControllerIfAble(IMediaController2 caller, SessionCommand2 command) {
         synchronized (mLock) {
             final ControllerInfo controllerInfo = getControllerIfAble(caller);
             if (controllerInfo == null) {
                 return null;
             }
-            CommandGroup allowedCommands = mAllowedCommandGroupMap.get(controllerInfo);
+            SessionCommandGroup2 allowedCommands = mAllowedCommandGroupMap.get(controllerInfo);
             if (allowedCommands == null) {
                 Log.w(TAG, "Controller with null allowed commands. Ignoring",
                         new IllegalStateException());
@@ -211,7 +211,7 @@
     private IMediaController2 getControllerBinderIfAble(ControllerInfo controller,
             int commandCode) {
         synchronized (mLock) {
-            CommandGroup allowedCommands = mAllowedCommandGroupMap.get(controller);
+            SessionCommandGroup2 allowedCommands = mAllowedCommandGroupMap.get(controller);
             if (allowedCommands == null) {
                 Log.w(TAG, "Controller with null allowed commands. Ignoring");
                 return null;
@@ -237,7 +237,7 @@
             if (getControllerIfAble(caller, commandCode) == null) {
                 return;
             }
-            Command command = sCommandsForOnCommandRequest.get(commandCode);
+            SessionCommand2 command = sCommandsForOnCommandRequest.get(commandCode);
             if (command != null) {
                 boolean accepted = session.getCallback().onCommandRequest(session.getInstance(),
                         controller, command);
@@ -257,13 +257,14 @@
     private void onBrowserCommand(@NonNull IMediaController2 caller,
             @NonNull LibrarySessionRunnable runnable) {
         final MediaLibrarySessionImpl session = getLibrarySession();
-        final ControllerInfo controller =
-                getControllerIfAble(caller, MediaSession2.COMMAND_CODE_BROWSER);
+        // TODO(jaewan): Consider command code
+        final ControllerInfo controller = getControllerIfAble(caller);
         if (session == null || controller == null) {
             return;
         }
         session.getCallbackExecutor().execute(() -> {
-            if (getControllerIfAble(caller, MediaSession2.COMMAND_CODE_BROWSER) == null) {
+            // TODO(jaewan): Consider command code
+            if (getControllerIfAble(caller) == null) {
                 return;
             }
             runnable.run(session, controller);
@@ -360,7 +361,7 @@
                 // instead of pending them.
                 mConnectingControllers.add(ControllerInfoImpl.from(controllerInfo).getId());
             }
-            CommandGroup allowedCommands = session.getCallback().onConnect(
+            SessionCommandGroup2 allowedCommands = session.getCallback().onConnect(
                     session.getInstance(), controllerInfo);
             // Don't reject connection for the request from trusted app.
             // Otherwise server will fail to retrieve session's information to dispatch
@@ -374,7 +375,7 @@
                 }
                 if (allowedCommands == null) {
                     // For trusted apps, send non-null allowed commands to keep connection.
-                    allowedCommands = new CommandGroup(context);
+                    allowedCommands = new SessionCommandGroup2();
                 }
                 synchronized (mLock) {
                     mConnectingControllers.remove(controllerImpl.getId());
@@ -389,7 +390,7 @@
                 //       use thread poll for incoming calls.
                 final int playerState = session.getInstance().getPlayerState();
                 final long positionEventTimeMs = System.currentTimeMillis();
-                final long positionMs = session.getInstance().getPosition();
+                final long positionMs = session.getInstance().getCurrentPosition();
                 final float playbackSpeed = session.getInstance().getPlaybackSpeed();
                 final long bufferedPositionMs = session.getInstance().getBufferedPosition();
                 final Bundle playbackInfoBundle = ((MediaController2Impl.PlaybackInfoImpl)
@@ -398,7 +399,7 @@
                 final int shuffleMode = session.getInstance().getShuffleMode();
                 final PendingIntent sessionActivity = session.getSessionActivity();
                 final List<MediaItem2> playlist =
-                        allowedCommands.hasCommand(MediaSession2.COMMAND_CODE_PLAYLIST_GET_LIST)
+                        allowedCommands.hasCommand(SessionCommand2.COMMAND_CODE_PLAYLIST_GET_LIST)
                                 ? session.getInstance().getPlaylist() : null;
                 final List<Bundle> playlistBundle;
                 if (playlist != null) {
@@ -456,27 +457,29 @@
     @Override
     public void setVolumeTo(final IMediaController2 caller, final int value, final int flags)
             throws RuntimeException {
-        onCommand(caller, MediaSession2.COMMAND_CODE_PLAYBACK_SET_VOLUME, (session, controller) -> {
-            VolumeProvider2 volumeProvider = session.getVolumeProvider();
-            if (volumeProvider == null) {
-                // TODO(jaewan): Set local stream volume
-            } else {
-                volumeProvider.onSetVolumeTo(value);
-            }
-        });
+        onCommand(caller, SessionCommand2.COMMAND_CODE_SET_VOLUME,
+                (session, controller) -> {
+                    VolumeProvider2 volumeProvider = session.getVolumeProvider();
+                    if (volumeProvider == null) {
+                        // TODO(jaewan): Set local stream volume
+                    } else {
+                        volumeProvider.onSetVolumeTo(value);
+                    }
+                });
     }
 
     @Override
     public void adjustVolume(IMediaController2 caller, int direction, int flags)
             throws RuntimeException {
-        onCommand(caller, MediaSession2.COMMAND_CODE_PLAYBACK_SET_VOLUME, (session, controller) -> {
-            VolumeProvider2 volumeProvider = session.getVolumeProvider();
-            if (volumeProvider == null) {
-                // TODO(jaewan): Adjust local stream volume
-            } else {
-                volumeProvider.onAdjustVolume(direction);
-            }
-        });
+        onCommand(caller, SessionCommand2.COMMAND_CODE_SET_VOLUME,
+                (session, controller) -> {
+                    VolumeProvider2 volumeProvider = session.getVolumeProvider();
+                    if (volumeProvider == null) {
+                        // TODO(jaewan): Adjust local stream volume
+                    } else {
+                        volumeProvider.onAdjustVolume(direction);
+                    }
+                });
     }
 
     @Override
@@ -484,25 +487,19 @@
             int commandCode, Bundle args) throws RuntimeException {
         onCommand(caller, commandCode, (session, controller) -> {
             switch (commandCode) {
-                case MediaSession2.COMMAND_CODE_PLAYBACK_PLAY:
+                case SessionCommand2.COMMAND_CODE_PLAYBACK_PLAY:
                     session.getInstance().play();
                     break;
-                case MediaSession2.COMMAND_CODE_PLAYBACK_PAUSE:
+                case SessionCommand2.COMMAND_CODE_PLAYBACK_PAUSE:
                     session.getInstance().pause();
                     break;
-                case MediaSession2.COMMAND_CODE_PLAYBACK_STOP:
+                case SessionCommand2.COMMAND_CODE_PLAYBACK_STOP:
                     session.getInstance().stop();
                     break;
-                case MediaSession2.COMMAND_CODE_PLAYBACK_PREPARE:
+                case SessionCommand2.COMMAND_CODE_PLAYBACK_PREPARE:
                     session.getInstance().prepare();
                     break;
-                case MediaSession2.COMMAND_CODE_PLAYBACK_FAST_FORWARD:
-                    session.getInstance().fastForward();
-                    break;
-                case MediaSession2.COMMAND_CODE_PLAYBACK_REWIND:
-                    session.getInstance().rewind();
-                    break;
-                case MediaSession2.COMMAND_CODE_PLAYBACK_SEEK_TO:
+                case SessionCommand2.COMMAND_CODE_PLAYBACK_SEEK_TO:
                     session.getInstance().seekTo(args.getLong(ARGUMENT_KEY_POSITION));
                     break;
                 default:
@@ -518,7 +515,7 @@
         if (session == null) {
             return;
         }
-        final Command command = Command.fromBundle(session.getContext(), commandBundle);
+        final SessionCommand2 command = SessionCommand2.fromBundle(commandBundle);
         if (command == null) {
             Log.w(TAG, "sendCustomCommand(): Ignoring null command from "
                     + getControllerIfAble(caller));
@@ -540,32 +537,35 @@
     @Override
     public void prepareFromUri(final IMediaController2 caller, final Uri uri,
             final Bundle extras) {
-        onCommand(caller, MediaSession2.COMMAND_CODE_PREPARE_FROM_URI, (session, controller) -> {
-            if (uri == null) {
-                Log.w(TAG, "prepareFromUri(): Ignoring null uri from " + controller);
-                return;
-            }
-            session.getCallback().onPrepareFromUri(session.getInstance(), controller, uri, extras);
-        });
+        onCommand(caller, SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_URI,
+                (session, controller) -> {
+                    if (uri == null) {
+                        Log.w(TAG, "prepareFromUri(): Ignoring null uri from " + controller);
+                        return;
+                    }
+                    session.getCallback().onPrepareFromUri(session.getInstance(), controller, uri,
+                            extras);
+                });
     }
 
     @Override
     public void prepareFromSearch(final IMediaController2 caller, final String query,
             final Bundle extras) {
-        onCommand(caller, MediaSession2.COMMAND_CODE_PREPARE_FROM_SEARCH, (session, controller) -> {
-            if (TextUtils.isEmpty(query)) {
-                Log.w(TAG, "prepareFromSearch(): Ignoring empty query from " + controller);
-                return;
-            }
-            session.getCallback().onPrepareFromSearch(session.getInstance(),
-                    controller, query, extras);
-        });
+        onCommand(caller, SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_SEARCH,
+                (session, controller) -> {
+                    if (TextUtils.isEmpty(query)) {
+                        Log.w(TAG, "prepareFromSearch(): Ignoring empty query from " + controller);
+                        return;
+                    }
+                    session.getCallback().onPrepareFromSearch(session.getInstance(),
+                            controller, query, extras);
+                });
     }
 
     @Override
     public void prepareFromMediaId(final IMediaController2 caller, final String mediaId,
             final Bundle extras) {
-        onCommand(caller, MediaSession2.COMMAND_CODE_PREPARE_FROM_MEDIA_ID,
+        onCommand(caller, SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_MEDIA_ID,
                 (session, controller) -> {
             if (mediaId == null) {
                 Log.w(TAG, "prepareFromMediaId(): Ignoring null mediaId from " + controller);
@@ -579,70 +579,75 @@
     @Override
     public void playFromUri(final IMediaController2 caller, final Uri uri,
             final Bundle extras) {
-        onCommand(caller, MediaSession2.COMMAND_CODE_PLAY_FROM_URI, (session, controller) -> {
-            if (uri == null) {
-                Log.w(TAG, "playFromUri(): Ignoring null uri from " + controller);
-                return;
-            }
-            session.getCallback().onPlayFromUri(session.getInstance(), controller, uri, extras);
-        });
+        onCommand(caller, SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_URI,
+                (session, controller) -> {
+                    if (uri == null) {
+                        Log.w(TAG, "playFromUri(): Ignoring null uri from " + controller);
+                        return;
+                    }
+                    session.getCallback().onPlayFromUri(session.getInstance(), controller, uri,
+                            extras);
+                });
     }
 
     @Override
     public void playFromSearch(final IMediaController2 caller, final String query,
             final Bundle extras) {
-        onCommand(caller, MediaSession2.COMMAND_CODE_PLAY_FROM_SEARCH, (session, controller) -> {
-            if (TextUtils.isEmpty(query)) {
-                Log.w(TAG, "playFromSearch(): Ignoring empty query from " + controller);
-                return;
-            }
-            session.getCallback().onPlayFromSearch(session.getInstance(),
-                    controller, query, extras);
-        });
+        onCommand(caller, SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_SEARCH,
+                (session, controller) -> {
+                    if (TextUtils.isEmpty(query)) {
+                        Log.w(TAG, "playFromSearch(): Ignoring empty query from " + controller);
+                        return;
+                    }
+                    session.getCallback().onPlayFromSearch(session.getInstance(),
+                            controller, query, extras);
+                });
     }
 
     @Override
     public void playFromMediaId(final IMediaController2 caller, final String mediaId,
             final Bundle extras) {
-        onCommand(caller, MediaSession2.COMMAND_CODE_PLAY_FROM_MEDIA_ID, (session, controller) -> {
-            if (mediaId == null) {
-                Log.w(TAG, "playFromMediaId(): Ignoring null mediaId from " + controller);
-                return;
-            }
-            session.getCallback().onPlayFromMediaId(session.getInstance(),
-                    controller, mediaId, extras);
-        });
+        onCommand(caller, SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_MEDIA_ID,
+                (session, controller) -> {
+                    if (mediaId == null) {
+                        Log.w(TAG, "playFromMediaId(): Ignoring null mediaId from " + controller);
+                        return;
+                    }
+                    session.getCallback().onPlayFromMediaId(session.getInstance(), controller,
+                            mediaId, extras);
+                });
     }
 
     @Override
     public void setRating(final IMediaController2 caller, final String mediaId,
             final Bundle ratingBundle) {
-        // TODO(jaewan): Define COMMAND_CODE_SET_RATING
-        onCommand(caller, MediaSession2.COMMAND_CODE_SET_RATING, (session, controller) -> {
-            if (mediaId == null) {
-                Log.w(TAG, "setRating(): Ignoring null mediaId from " + controller);
-                return;
-            }
-            if (ratingBundle == null) {
-                Log.w(TAG, "setRating(): Ignoring null ratingBundle from " + controller);
-                return;
-            }
-            Rating2 rating = Rating2Impl.fromBundle(session.getContext(), ratingBundle);
-            if (rating == null) {
-                if (ratingBundle == null) {
-                    Log.w(TAG, "setRating(): Ignoring null rating from " + controller);
-                    return;
-                }
-                return;
-            }
-            session.getCallback().onSetRating(session.getInstance(), controller, mediaId, rating);
-        });
+        onCommand(caller, SessionCommand2.COMMAND_CODE_SESSION_SET_RATING,
+                (session, controller) -> {
+                    if (mediaId == null) {
+                        Log.w(TAG, "setRating(): Ignoring null mediaId from " + controller);
+                        return;
+                    }
+                    if (ratingBundle == null) {
+                        Log.w(TAG, "setRating(): Ignoring null ratingBundle from " + controller);
+                        return;
+                    }
+                    Rating2 rating = Rating2.fromBundle(ratingBundle);
+                    if (rating == null) {
+                        if (ratingBundle == null) {
+                            Log.w(TAG, "setRating(): Ignoring null rating from " + controller);
+                            return;
+                        }
+                        return;
+                    }
+                    session.getCallback().onSetRating(session.getInstance(), controller, mediaId,
+                            rating);
+                });
     }
 
     @Override
     public void setPlaylist(final IMediaController2 caller, final List<Bundle> playlist,
             final Bundle metadata) {
-        onCommand(caller, MediaSession2.COMMAND_CODE_PLAYLIST_SET_LIST, (session, controller) -> {
+        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_SET_LIST, (session, controller) -> {
             if (playlist == null) {
                 Log.w(TAG, "setPlaylist(): Ignoring null playlist from " + controller);
                 return;
@@ -650,41 +655,39 @@
             List<MediaItem2> list = new ArrayList<>();
             for (int i = 0; i < playlist.size(); i++) {
                 // Recreates UUID in the playlist
-                MediaItem2 item = MediaItem2Impl.fromBundle(
-                        session.getContext(), playlist.get(i), null);
+                MediaItem2 item = MediaItem2Impl.fromBundle(playlist.get(i), null);
                 if (item != null) {
                     list.add(item);
                 }
             }
-            session.getInstance().setPlaylist(list,
-                    MediaMetadata2.fromBundle(session.getContext(), metadata));
+            session.getInstance().setPlaylist(list, MediaMetadata2.fromBundle(metadata));
         });
     }
 
     @Override
     public void updatePlaylistMetadata(final IMediaController2 caller, final Bundle metadata) {
-        onCommand(caller, MediaSession2.COMMAND_CODE_PLAYLIST_SET_LIST_METADATA,
+        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_SET_LIST_METADATA,
                 (session, controller) -> {
-            session.getInstance().updatePlaylistMetadata(
-                    MediaMetadata2.fromBundle(session.getContext(), metadata));
+            session.getInstance().updatePlaylistMetadata(MediaMetadata2.fromBundle(metadata));
         });
     }
 
     @Override
     public void addPlaylistItem(IMediaController2 caller, int index, Bundle mediaItem) {
-        onCommand(caller, MediaSession2.COMMAND_CODE_PLAYLIST_ADD_ITEM, (session, controller) -> {
-            // Resets the UUID from the incoming media id, so controller may reuse a media item
-            // multiple times for addPlaylistItem.
-            session.getInstance().addPlaylistItem(index,
-                    MediaItem2Impl.fromBundle(session.getContext(), mediaItem, null));
-        });
+        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_ADD_ITEM,
+                (session, controller) -> {
+                    // Resets the UUID from the incoming media id, so controller may reuse a media
+                    // item multiple times for addPlaylistItem.
+                    session.getInstance().addPlaylistItem(index,
+                            MediaItem2Impl.fromBundle(mediaItem, null));
+                });
     }
 
     @Override
     public void removePlaylistItem(IMediaController2 caller, Bundle mediaItem) {
-        onCommand(caller, MediaSession2.COMMAND_CODE_PLAYLIST_REMOVE_ITEM,
+        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_REMOVE_ITEM,
                 (session, controller) -> {
-            MediaItem2 item = MediaItem2.fromBundle(session.getContext(), mediaItem);
+            MediaItem2 item = MediaItem2.fromBundle(mediaItem);
             // Note: MediaItem2 has hidden UUID to identify it across the processes.
             session.getInstance().removePlaylistItem(item);
         });
@@ -692,32 +695,31 @@
 
     @Override
     public void replacePlaylistItem(IMediaController2 caller, int index, Bundle mediaItem) {
-        onCommand(caller, MediaSession2.COMMAND_CODE_PLAYLIST_REPLACE_ITEM,
+        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_REPLACE_ITEM,
                 (session, controller) -> {
                     // Resets the UUID from the incoming media id, so controller may reuse a media
                     // item multiple times for replacePlaylistItem.
                     session.getInstance().replacePlaylistItem(index,
-                            MediaItem2Impl.fromBundle(session.getContext(), mediaItem, null));
+                            MediaItem2Impl.fromBundle(mediaItem, null));
                 });
     }
 
     @Override
     public void skipToPlaylistItem(IMediaController2 caller, Bundle mediaItem) {
-        onCommand(caller, MediaSession2.COMMAND_CODE_PLAYLIST_SKIP_TO_PLAYLIST_ITEM,
+        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_SKIP_TO_PLAYLIST_ITEM,
                 (session, controller) -> {
                     if (mediaItem == null) {
                         Log.w(TAG, "skipToPlaylistItem(): Ignoring null mediaItem from "
                                 + controller);
                     }
                     // Note: MediaItem2 has hidden UUID to identify it across the processes.
-                    session.getInstance().skipToPlaylistItem(
-                            MediaItem2.fromBundle(session.getContext(), mediaItem));
+                    session.getInstance().skipToPlaylistItem(MediaItem2.fromBundle(mediaItem));
                 });
     }
 
     @Override
     public void skipToPreviousItem(IMediaController2 caller) {
-        onCommand(caller, MediaSession2.COMMAND_CODE_PLAYBACK_SKIP_PREV_ITEM,
+        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_SKIP_PREV_ITEM,
                 (session, controller) -> {
                     session.getInstance().skipToPreviousItem();
                 });
@@ -725,7 +727,7 @@
 
     @Override
     public void skipToNextItem(IMediaController2 caller) {
-        onCommand(caller, MediaSession2.COMMAND_CODE_PLAYBACK_SKIP_NEXT_ITEM,
+        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_SKIP_NEXT_ITEM,
                 (session, controller) -> {
                     session.getInstance().skipToNextItem();
                 });
@@ -733,7 +735,7 @@
 
     @Override
     public void setRepeatMode(IMediaController2 caller, int repeatMode) {
-        onCommand(caller, MediaSession2.COMMAND_CODE_PLAYLIST_SET_REPEAT_MODE,
+        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_SET_REPEAT_MODE,
                 (session, controller) -> {
                     session.getInstance().setRepeatMode(repeatMode);
                 });
@@ -741,7 +743,7 @@
 
     @Override
     public void setShuffleMode(IMediaController2 caller, int shuffleMode) {
-        onCommand(caller, MediaSession2.COMMAND_CODE_PLAYLIST_SET_SHUFFLE_MODE,
+        onCommand(caller, SessionCommand2.COMMAND_CODE_PLAYLIST_SET_SHUFFLE_MODE,
                 (session, controller) -> {
                     session.getInstance().setShuffleMode(shuffleMode);
                 });
@@ -924,6 +926,7 @@
         });
     }
 
+    // TODO(jaewan): Rename
     public void notifyPositionChangedNotLocked(long eventTimeMs, long positionMs) {
         notifyAll((controller, iController) -> {
             iController.onPositionChanged(eventTimeMs, positionMs);
@@ -973,10 +976,10 @@
         final Bundle metadataBundle = (metadata == null) ? null : metadata.toBundle();
         notifyAll((controller, iController) -> {
             if (getControllerBinderIfAble(controller,
-                    MediaSession2.COMMAND_CODE_PLAYLIST_GET_LIST) != null) {
+                    SessionCommand2.COMMAND_CODE_PLAYLIST_GET_LIST) != null) {
                 iController.onPlaylistChanged(bundleList, metadataBundle);
             } else if (getControllerBinderIfAble(controller,
-                    MediaSession2.COMMAND_CODE_PLAYLIST_GET_LIST_METADATA) != null) {
+                    SessionCommand2.COMMAND_CODE_PLAYLIST_GET_LIST_METADATA) != null) {
                 iController.onPlaylistMetadataChanged(metadataBundle);
             }
         });
@@ -984,7 +987,7 @@
 
     public void notifyPlaylistMetadataChangedNotLocked(MediaMetadata2 metadata) {
         final Bundle metadataBundle = (metadata == null) ? null : metadata.toBundle();
-        notifyAll(MediaSession2.COMMAND_CODE_PLAYLIST_GET_LIST_METADATA,
+        notifyAll(SessionCommand2.COMMAND_CODE_PLAYLIST_GET_LIST_METADATA,
                 (unused, iController) -> {
                     iController.onPlaylistMetadataChanged(metadataBundle);
                 });
@@ -1010,7 +1013,7 @@
         });
     }
 
-    public void setAllowedCommands(ControllerInfo controller, CommandGroup commands) {
+    public void setAllowedCommands(ControllerInfo controller, SessionCommandGroup2 commands) {
         synchronized (mLock) {
             mAllowedCommandGroupMap.put(controller, commands);
         }
@@ -1019,7 +1022,7 @@
         });
     }
 
-    public void sendCustomCommand(ControllerInfo controller, Command command, Bundle args,
+    public void sendCustomCommand(ControllerInfo controller, SessionCommand2 command, Bundle args,
             ResultReceiver receiver) {
         if (receiver != null && controller == null) {
             throw new IllegalArgumentException("Controller shouldn't be null if result receiver is"
@@ -1034,7 +1037,7 @@
         });
     }
 
-    public void sendCustomCommand(Command command, Bundle args) {
+    public void sendCustomCommand(SessionCommand2 command, Bundle args) {
         if (command == null) {
             throw new IllegalArgumentException("command shouldn't be null");
         }
diff --git a/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java b/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java
index a0123b5..c33eb65 100644
--- a/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/MediaSessionService2Impl.java
@@ -147,8 +147,8 @@
         private int mNotificationId;
         private Notification mNotification;
 
-        public MediaNotificationImpl(Context context, MediaNotification instance,
-                int notificationId, Notification notification) {
+        public MediaNotificationImpl(MediaNotification instance, int notificationId,
+                Notification notification) {
             if (notification == null) {
                 throw new IllegalArgumentException("notification shouldn't be null");
             }
diff --git a/packages/MediaComponents/src/com/android/media/Rating2Impl.java b/packages/MediaComponents/src/com/android/media/Rating2Impl.java
index 68e104a..d558129 100644
--- a/packages/MediaComponents/src/com/android/media/Rating2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/Rating2Impl.java
@@ -39,7 +39,7 @@
     private final int mRatingStyle;
     private final float mRatingValue;
 
-    private Rating2Impl(Context context, @Style int ratingStyle, float rating) {
+    private Rating2Impl(@Style int ratingStyle, float rating) {
         mRatingStyle = ratingStyle;
         mRatingValue = rating;
         mInstance = new Rating2(this);
@@ -66,16 +66,15 @@
         return Objects.hash(mRatingStyle, mRatingValue);
     }
 
-    public Rating2 getInstance() {
+    Rating2 getInstance() {
         return mInstance;
     }
 
-    public static Rating2 fromBundle(Context context, Bundle bundle) {
+    public static Rating2 fromBundle_impl(Bundle bundle) {
         if (bundle == null) {
             return null;
         }
-        return new Rating2Impl(context, bundle.getInt(KEY_STYLE), bundle.getFloat(KEY_VALUE))
-                .getInstance();
+        return new Rating2Impl(bundle.getInt(KEY_STYLE), bundle.getFloat(KEY_VALUE)).getInstance();
     }
 
     public Bundle toBundle_impl() {
@@ -85,7 +84,7 @@
         return bundle;
     }
 
-    public static Rating2 newUnratedRating(Context context, @Style int ratingStyle) {
+    public static Rating2 newUnratedRating_impl(@Style int ratingStyle) {
         switch(ratingStyle) {
             case RATING_HEART:
             case RATING_THUMB_UP_DOWN:
@@ -93,22 +92,21 @@
             case RATING_4_STARS:
             case RATING_5_STARS:
             case RATING_PERCENTAGE:
-                return new Rating2Impl(context, ratingStyle, RATING_NOT_RATED).getInstance();
+                return new Rating2Impl(ratingStyle, RATING_NOT_RATED).getInstance();
             default:
                 return null;
         }
     }
 
-    public static Rating2 newHeartRating(Context context, boolean hasHeart) {
-        return new Rating2Impl(context, RATING_HEART, hasHeart ? 1.0f : 0.0f).getInstance();
+    public static Rating2 newHeartRating_impl(boolean hasHeart) {
+        return new Rating2Impl(RATING_HEART, hasHeart ? 1.0f : 0.0f).getInstance();
     }
 
-    public static Rating2 newThumbRating(Context context, boolean thumbIsUp) {
-        return new Rating2Impl(context, RATING_THUMB_UP_DOWN, thumbIsUp ? 1.0f : 0.0f)
-                .getInstance();
+    public static Rating2 newThumbRating_impl(boolean thumbIsUp) {
+        return new Rating2Impl(RATING_THUMB_UP_DOWN, thumbIsUp ? 1.0f : 0.0f).getInstance();
     }
 
-    public static Rating2 newStarRating(Context context, int starRatingStyle, float starRating) {
+    public static Rating2 newStarRating_impl(int starRatingStyle, float starRating) {
         float maxRating = RATING_NOT_RATED;
         switch(starRatingStyle) {
             case RATING_3_STARS:
@@ -128,15 +126,15 @@
             Log.e(TAG, "Trying to set out of range star-based rating");
             return null;
         }
-        return new Rating2Impl(context, starRatingStyle, starRating).getInstance();
+        return new Rating2Impl(starRatingStyle, starRating).getInstance();
     }
 
-    public static Rating2 newPercentageRating(Context context, float percent) {
+    public static Rating2 newPercentageRating_impl(float percent) {
         if ((percent < 0.0f) || (percent > 100.0f)) {
             Log.e(TAG, "Invalid percentage-based rating value");
             return null;
         } else {
-            return new Rating2Impl(context, RATING_PERCENTAGE, percent).getInstance();
+            return new Rating2Impl(RATING_PERCENTAGE, percent).getInstance();
         }
     }
 
diff --git a/packages/MediaComponents/src/com/android/media/SessionPlaylistAgent.java b/packages/MediaComponents/src/com/android/media/SessionPlaylistAgent.java
index 693e137..1c570aa 100644
--- a/packages/MediaComponents/src/com/android/media/SessionPlaylistAgent.java
+++ b/packages/MediaComponents/src/com/android/media/SessionPlaylistAgent.java
@@ -18,11 +18,11 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.content.Context;
 import android.media.DataSourceDesc;
 import android.media.MediaItem2;
 import android.media.MediaMetadata2;
 import android.media.MediaPlayerBase;
+import android.media.MediaPlayerBase.PlayerEventCallback;
 import android.media.MediaPlaylistAgent;
 import android.media.MediaSession2.OnDataSourceMissingHelper;
 import android.util.ArrayMap;
@@ -47,8 +47,8 @@
 
     private final Object mLock = new Object();
     private final MediaSession2Impl mSessionImpl;
+    private final MyPlayerEventCallback mPlayerCallback;
 
-    // TODO: Set data sources properly into mPlayer (b/74090741)
     @GuardedBy("mLock")
     private MediaPlayerBase mPlayer;
     @GuardedBy("mLock")
@@ -69,6 +69,22 @@
     @GuardedBy("mLock")
     private PlayItem mCurrent;
 
+    // Called on session callback executor.
+    private class MyPlayerEventCallback extends PlayerEventCallback {
+        public void onCurrentDataSourceChanged(@NonNull MediaPlayerBase mpb,
+                @Nullable DataSourceDesc dsd) {
+            if (mPlayer != mpb) {
+                return;
+            }
+            synchronized (mLock) {
+                if (dsd == null && mCurrent != null) {
+                    mCurrent = getNextValidPlayItemLocked(mCurrent.shuffledIdx, 1);
+                    updateCurrentIfNeededLocked();
+                }
+            }
+        }
+    }
+
     private class PlayItem {
         int shuffledIdx;
         DataSourceDesc dsd;
@@ -116,9 +132,8 @@
         }
     }
 
-    public SessionPlaylistAgent(@NonNull Context context, @NonNull MediaSession2Impl sessionImpl,
+    public SessionPlaylistAgent(@NonNull MediaSession2Impl sessionImpl,
             @NonNull MediaPlayerBase player) {
-        super(context);
         if (sessionImpl == null) {
             throw new IllegalArgumentException("sessionImpl shouldn't be null");
         }
@@ -127,14 +142,23 @@
         }
         mSessionImpl = sessionImpl;
         mPlayer = player;
+        mPlayerCallback = new MyPlayerEventCallback();
+        mPlayer.registerPlayerEventCallback(mSessionImpl.getCallbackExecutor(), mPlayerCallback);
     }
 
-    public void setPlayer(MediaPlayerBase player) {
+    public void setPlayer(@NonNull MediaPlayerBase player) {
         if (player == null) {
             throw new IllegalArgumentException("player shouldn't be null");
         }
         synchronized (mLock) {
+            if (player == mPlayer) {
+                return;
+            }
+            mPlayer.unregisterPlayerEventCallback(mPlayerCallback);
             mPlayer = player;
+            mPlayer.registerPlayerEventCallback(
+                    mSessionImpl.getCallbackExecutor(), mPlayerCallback);
+            updatePlayerDataSourceLocked();
         }
     }
 
@@ -172,6 +196,7 @@
 
             mMetadata = metadata;
             mCurrent = getNextValidPlayItemLocked(END_OF_PLAYLIST, 1);
+            updatePlayerDataSourceLocked();
         }
         notifyPlaylistChanged();
     }
@@ -210,6 +235,7 @@
             }
             if (!hasValidItem()) {
                 mCurrent = getNextValidPlayItemLocked(END_OF_PLAYLIST, 1);
+                updatePlayerDataSourceLocked();
             } else {
                 updateCurrentIfNeededLocked();
             }
@@ -249,6 +275,7 @@
             mPlaylist.set(index, item);
             if (!hasValidItem()) {
                 mCurrent = getNextValidPlayItemLocked(END_OF_PLAYLIST, 1);
+                updatePlayerDataSourceLocked();
             } else {
                 updateCurrentIfNeededLocked();
             }
@@ -291,7 +318,7 @@
     @Override
     public void skipToNextItem() {
         synchronized (mLock) {
-            if (!hasValidItem()) {
+            if (!hasValidItem() || mCurrent == mEopPlayItem) {
                 return;
             }
             PlayItem next = getNextValidPlayItemLocked(mCurrent.shuffledIdx, 1);
@@ -318,6 +345,23 @@
                 return;
             }
             mRepeatMode = repeatMode;
+            switch (repeatMode) {
+                case MediaPlaylistAgent.REPEAT_MODE_ONE:
+                    if (mCurrent != null && mCurrent != mEopPlayItem) {
+                        mPlayer.loopCurrent(true);
+                    }
+                    break;
+                case MediaPlaylistAgent.REPEAT_MODE_ALL:
+                case MediaPlaylistAgent.REPEAT_MODE_GROUP:
+                    if (mCurrent == mEopPlayItem) {
+                        mCurrent = getNextValidPlayItemLocked(END_OF_PLAYLIST, 1);
+                        updatePlayerDataSourceLocked();
+                    }
+                    // pass through
+                case MediaPlaylistAgent.REPEAT_MODE_NONE:
+                    mPlayer.loopCurrent(false);
+                    break;
+            }
         }
         notifyRepeatModeChanged();
     }
@@ -339,6 +383,7 @@
             }
             mShuffleMode = shuffleMode;
             applyShuffleModeLocked();
+            updateCurrentIfNeededLocked();
         }
         notifyShuffleModeChanged();
     }
@@ -373,6 +418,7 @@
         return dsd;
     }
 
+    // TODO: consider to call updateCurrentIfNeededLocked inside (b/74090741)
     private PlayItem getNextValidPlayItemLocked(int curShuffledIdx, int direction) {
         int size = mPlaylist.size();
         if (curShuffledIdx == END_OF_PLAYLIST) {
@@ -414,9 +460,21 @@
                 mCurrent = getNextValidPlayItemLocked(mCurrent.shuffledIdx, 1);
             }
         }
+        updatePlayerDataSourceLocked();
         return;
     }
 
+    private void updatePlayerDataSourceLocked() {
+        if (mCurrent == null || mCurrent == mEopPlayItem) {
+            return;
+        }
+        if (mPlayer.getCurrentDataSource() != mCurrent.dsd) {
+            mPlayer.setDataSource(mCurrent.dsd);
+            mPlayer.loopCurrent(mRepeatMode == MediaPlaylistAgent.REPEAT_MODE_ONE);
+        }
+        // TODO: Call setNextDataSource (b/74090741)
+    }
+
     private void applyShuffleModeLocked() {
         mShuffledList.clear();
         mShuffledList.addAll(mPlaylist);
diff --git a/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java b/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java
index 723622e..a5cf8c4 100644
--- a/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/SessionToken2Impl.java
@@ -98,8 +98,8 @@
         mSessionBinder = null;
     }
 
-    public SessionToken2Impl(Context context, int uid, int type,
-            String packageName, String serviceName, String id, IMediaSession2 sessionBinder) {
+    SessionToken2Impl(int uid, int type, String packageName, String serviceName, String id,
+            IMediaSession2 sessionBinder) {
         // TODO(jaewan): Add sanity check (b/73863865)
         mUid = uid;
         mType = type;
@@ -168,15 +168,15 @@
         return mType;
     }
 
-    public String getServiceName() {
+    String getServiceName() {
         return mServiceName;
     }
 
-    public IMediaSession2 getSessionBinder() {
+    IMediaSession2 getSessionBinder() {
         return mSessionBinder;
     }
 
-    public static SessionToken2 fromBundle_impl(Context context, Bundle bundle) {
+    public static SessionToken2 fromBundle_impl(Bundle bundle) {
         if (bundle == null) {
             return null;
         }
@@ -207,7 +207,7 @@
         if (TextUtils.isEmpty(packageName) || id == null) {
             throw new IllegalArgumentException("Package name nor ID cannot be null.");
         }
-        return new SessionToken2Impl(context, uid, type, packageName, serviceName, id,
+        return new SessionToken2Impl(uid, type, packageName, serviceName, id,
                 sessionBinder != null ? IMediaSession2.Stub.asInterface(sessionBinder) : null)
                 .getInstance();
     }
@@ -254,7 +254,7 @@
                 + " service=" + mServiceName + " binder=" + mSessionBinder + "}";
     }
 
-    public static SessionToken2Impl from(SessionToken2 token) {
+    static SessionToken2Impl from(SessionToken2 token) {
         return ((SessionToken2Impl) token.getProvider());
     }
 }
diff --git a/packages/MediaComponents/src/com/android/media/VolumeProvider2Impl.java b/packages/MediaComponents/src/com/android/media/VolumeProvider2Impl.java
index 156bcae..bf22e1b 100644
--- a/packages/MediaComponents/src/com/android/media/VolumeProvider2Impl.java
+++ b/packages/MediaComponents/src/com/android/media/VolumeProvider2Impl.java
@@ -19,13 +19,10 @@
 import static android.media.VolumeProvider2.VOLUME_CONTROL_FIXED;
 import static android.media.VolumeProvider2.VOLUME_CONTROL_RELATIVE;
 
-import android.content.Context;
 import android.media.VolumeProvider2;
 import android.media.update.VolumeProvider2Provider;
 
 public class VolumeProvider2Impl implements VolumeProvider2Provider {
-
-    private final Context mContext;
     private final VolumeProvider2 mInstance;
     private final int mControlType;
     private final int mMaxVolume;
@@ -33,7 +30,7 @@
     private int mCurrentVolume;
     private Callback mCallback;
 
-    public VolumeProvider2Impl(Context context, VolumeProvider2 instance,
+    public VolumeProvider2Impl(VolumeProvider2 instance,
             @VolumeProvider2.ControlType int controlType, int maxVolume, int currentVolume) {
         if (controlType != VOLUME_CONTROL_FIXED && controlType != VOLUME_CONTROL_RELATIVE
                 && controlType != VOLUME_CONTROL_ABSOLUTE) {
@@ -47,7 +44,6 @@
             throw new IllegalArgumentException("currentVolume shouldn't be greater than maxVolume"
                     + ", maxVolume=" + maxVolume + ", currentVolume=" + currentVolume);
         }
-        mContext = context;
         mInstance = instance;
         mControlType = controlType;
         mMaxVolume = maxVolume;
diff --git a/packages/MediaComponents/src/com/android/media/update/ApiFactory.java b/packages/MediaComponents/src/com/android/media/update/ApiFactory.java
index 05a54d5..d7be549 100644
--- a/packages/MediaComponents/src/com/android/media/update/ApiFactory.java
+++ b/packages/MediaComponents/src/com/android/media/update/ApiFactory.java
@@ -31,8 +31,8 @@
 import android.media.MediaMetadata2;
 import android.media.MediaPlaylistAgent;
 import android.media.MediaSession2;
-import android.media.MediaSession2.Command;
-import android.media.MediaSession2.CommandGroup;
+import android.media.SessionCommand2;
+import android.media.SessionCommandGroup2;
 import android.media.MediaSession2.ControllerInfo;
 import android.media.MediaSession2.SessionCallback;
 import android.media.MediaSessionService2;
@@ -85,7 +85,7 @@
 public final class ApiFactory implements StaticProvider {
     private ApiFactory() { }
 
-    public static ApiFactory initialize(ApplicationInfo updatableInfo) {
+    public static StaticProvider initialize(ApplicationInfo updatableInfo) {
         ApiHelper.initialize(updatableInfo);
         return new ApiFactory();
     }
@@ -105,7 +105,7 @@
 
     @Override
     public MediaSession2Provider.CommandProvider createMediaSession2Command(
-            Command instance, int commandCode, String action, Bundle extra) {
+            SessionCommand2 instance, int commandCode, String action, Bundle extra) {
         if (action == null && extra == null) {
             return new MediaSession2Impl.CommandImpl(instance, commandCode);
         }
@@ -113,20 +113,20 @@
     }
 
     @Override
-    public Command fromBundle_MediaSession2Command(Context context, Bundle command) {
-        return MediaSession2Impl.CommandImpl.fromBundle_impl(context, command);
+    public SessionCommand2 fromBundle_MediaSession2Command(Bundle command) {
+        return MediaSession2Impl.CommandImpl.fromBundle_impl(command);
     }
 
     @Override
     public MediaSession2Provider.CommandGroupProvider createMediaSession2CommandGroup(
-            Context context, CommandGroup instance, CommandGroup other) {
-        return new MediaSession2Impl.CommandGroupImpl(context, instance,
+            SessionCommandGroup2 instance, SessionCommandGroup2 other) {
+        return new MediaSession2Impl.CommandGroupImpl(instance,
                 (other == null) ? null : other.getProvider());
     }
 
     @Override
-    public CommandGroup fromBundle_MediaSession2CommandGroup(Context context, Bundle commands) {
-        return MediaSession2Impl.CommandGroupImpl.fromBundle_impl(context, commands);
+    public SessionCommandGroup2 fromBundle_MediaSession2CommandGroup(Bundle commands) {
+        return MediaSession2Impl.CommandGroupImpl.fromBundle_impl(commands);
     }
 
     @Override
@@ -138,9 +138,9 @@
     }
 
     @Override
-    public BuilderProvider createMediaSession2CommandButtonBuilder(Context context,
+    public BuilderProvider createMediaSession2CommandButtonBuilder(
             MediaSession2.CommandButton.Builder instance) {
-        return new MediaSession2Impl.CommandButtonImpl.BuilderImpl(context, instance);
+        return new MediaSession2Impl.CommandButtonImpl.BuilderImpl(instance);
     }
 
     public BuilderBaseProvider<MediaSession2, SessionCallback> createMediaSession2Builder(
@@ -149,21 +149,19 @@
     }
 
     @Override
-    public MediaSessionService2Provider createMediaSessionService2(
-            MediaSessionService2 instance) {
+    public MediaSessionService2Provider createMediaSessionService2(MediaSessionService2 instance) {
         return new MediaSessionService2Impl(instance);
     }
 
     @Override
-    public MediaNotificationProvider createMediaSessionService2MediaNotification(Context context,
+    public MediaNotificationProvider createMediaSessionService2MediaNotification(
             MediaNotification instance, int notificationId, Notification notification) {
         return new MediaSessionService2Impl.MediaNotificationImpl(
-                context, instance, notificationId, notification);
+                instance, notificationId, notification);
     }
 
     @Override
-    public MediaSessionService2Provider createMediaLibraryService2(
-            MediaLibraryService2 instance) {
+    public MediaSessionService2Provider createMediaLibraryService2(MediaLibraryService2 instance) {
         return new MediaLibraryService2Impl(instance);
     }
 
@@ -177,9 +175,9 @@
     }
 
     @Override
-    public LibraryRootProvider createMediaLibraryService2LibraryRoot(Context context,
+    public LibraryRootProvider createMediaLibraryService2LibraryRoot(
             LibraryRoot instance, String rootId, Bundle extras) {
-        return new LibraryRootImpl(context, instance, rootId, extras);
+        return new LibraryRootImpl(instance, rootId, extras);
     }
 
     @Override
@@ -203,77 +201,76 @@
     }
 
     @Override
-    public SessionToken2 fromBundle_SessionToken2(Context context, Bundle bundle) {
-        return SessionToken2Impl.fromBundle_impl(context, bundle);
+    public SessionToken2 fromBundle_SessionToken2(Bundle bundle) {
+        return SessionToken2Impl.fromBundle_impl(bundle);
     }
 
     @Override
-    public MediaItem2Provider.BuilderProvider createMediaItem2Builder(
-            Context context, MediaItem2.Builder instance, int flags) {
-        return new MediaItem2Impl.BuilderImpl(context, instance, flags);
+    public MediaItem2Provider.BuilderProvider createMediaItem2Builder(MediaItem2.Builder instance,
+            int flags) {
+        return new MediaItem2Impl.BuilderImpl(instance, flags);
     }
 
     @Override
-    public MediaItem2 fromBundle_MediaItem2(Context context, Bundle bundle) {
-        return MediaItem2Impl.fromBundle(context, bundle);
+    public MediaItem2 fromBundle_MediaItem2(Bundle bundle) {
+        return MediaItem2Impl.fromBundle_impl(bundle);
     }
 
     @Override
-    public VolumeProvider2Provider createVolumeProvider2(Context context, VolumeProvider2 instance,
-            int controlType, int maxVolume, int currentVolume) {
-        return new VolumeProvider2Impl(context, instance, controlType, maxVolume, currentVolume);
+    public VolumeProvider2Provider createVolumeProvider2(VolumeProvider2 instance, int controlType,
+            int maxVolume, int currentVolume) {
+        return new VolumeProvider2Impl(instance, controlType, maxVolume, currentVolume);
     }
 
     @Override
-    public MediaMetadata2 fromBundle_MediaMetadata2(Context context, Bundle bundle) {
-        return MediaMetadata2Impl.fromBundle(context, bundle);
+    public MediaMetadata2 fromBundle_MediaMetadata2(Bundle bundle) {
+        return MediaMetadata2Impl.fromBundle_impl(bundle);
     }
 
     @Override
     public MediaMetadata2Provider.BuilderProvider createMediaMetadata2Builder(
-            Context context, MediaMetadata2.Builder instance) {
-        return new MediaMetadata2Impl.BuilderImpl(context, instance);
+            MediaMetadata2.Builder instance) {
+        return new MediaMetadata2Impl.BuilderImpl(instance);
     }
 
     @Override
     public MediaMetadata2Provider.BuilderProvider createMediaMetadata2Builder(
-            Context context, MediaMetadata2.Builder instance, MediaMetadata2 source) {
-        return new MediaMetadata2Impl.BuilderImpl(context, instance, source);
+            MediaMetadata2.Builder instance, MediaMetadata2 source) {
+        return new MediaMetadata2Impl.BuilderImpl(instance, source);
     }
 
     @Override
-    public Rating2 fromBundle_Rating2(Context context, Bundle bundle) {
-        return Rating2Impl.fromBundle(context, bundle);
+    public Rating2 fromBundle_Rating2(Bundle bundle) {
+        return Rating2Impl.fromBundle_impl(bundle);
     }
 
     @Override
-    public Rating2 newUnratedRating_Rating2(Context context, int ratingStyle) {
-        return Rating2Impl.newUnratedRating(context, ratingStyle);
+    public Rating2 newUnratedRating_Rating2(int ratingStyle) {
+        return Rating2Impl.newUnratedRating_impl(ratingStyle);
     }
 
     @Override
-    public Rating2 newHeartRating_Rating2(Context context, boolean hasHeart) {
-        return Rating2Impl.newHeartRating(context, hasHeart);
+    public Rating2 newHeartRating_Rating2(boolean hasHeart) {
+        return Rating2Impl.newHeartRating_impl(hasHeart);
     }
 
     @Override
-    public Rating2 newThumbRating_Rating2(Context context, boolean thumbIsUp) {
-        return Rating2Impl.newThumbRating(context, thumbIsUp);
+    public Rating2 newThumbRating_Rating2(boolean thumbIsUp) {
+        return Rating2Impl.newThumbRating_impl(thumbIsUp);
     }
 
     @Override
-    public Rating2 newStarRating_Rating2(Context context, int starRatingStyle, float starRating) {
-        return Rating2Impl.newStarRating(context, starRatingStyle, starRating);
+    public Rating2 newStarRating_Rating2(int starRatingStyle, float starRating) {
+        return Rating2Impl.newStarRating_impl(starRatingStyle, starRating);
     }
 
     @Override
-    public Rating2 newPercentageRating_Rating2(Context context, float percent) {
-        return Rating2Impl.newPercentageRating(context, percent);
+    public Rating2 newPercentageRating_Rating2(float percent) {
+        return Rating2Impl.newPercentageRating_impl(percent);
     }
 
     @Override
-    public MediaPlaylistAgentProvider createMediaPlaylistAgent(Context context,
-            MediaPlaylistAgent instance) {
-        return new MediaPlaylistAgentImpl(context, instance);
+    public MediaPlaylistAgentProvider createMediaPlaylistAgent(MediaPlaylistAgent instance) {
+        return new MediaPlaylistAgentImpl(instance);
     }
 }
diff --git a/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java b/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
index 9ae75b0..3aff150 100644
--- a/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
+++ b/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
@@ -16,7 +16,9 @@
 
 package com.android.widget;
 
+import android.content.Context;
 import android.content.res.Resources;
+import android.graphics.Point;
 import android.media.MediaMetadata;
 import android.media.session.MediaController;
 import android.media.session.PlaybackState;
@@ -31,6 +33,7 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.WindowManager;
 import android.widget.AdapterView;
 import android.widget.BaseAdapter;
 import android.widget.Button;
@@ -102,6 +105,10 @@
     private static final int SETTINGS_MODE_MAIN = 5;
     private static final int PLAYBACK_SPEED_1x_INDEX = 3;
 
+    private static final int MEDIA_TYPE_DEFAULT = 0;
+    private static final int MEDIA_TYPE_MUSIC = 1;
+    private static final int MEDIA_TYPE_ADVERTISEMENT = 2;
+
     private static final int SIZE_TYPE_EMBEDDED = 0;
     private static final int SIZE_TYPE_FULL = 1;
     // TODO: add support for Minimal size type.
@@ -123,6 +130,7 @@
     private int mDuration;
     private int mPrevState;
     private int mPrevWidth;
+    private int mPrevHeight;
     private int mOriginalLeftBarWidth;
     private int mVideoTrackCount;
     private int mAudioTrackCount;
@@ -137,8 +145,8 @@
     private int mEmbeddedSettingsItemHeight;
     private int mFullSettingsItemHeight;
     private int mSettingsWindowMargin;
+    private int mMediaType;
     private int mSizeType;
-    private int mOrientation;
     private long mPlaybackActions;
     private boolean mDragging;
     private boolean mIsFullScreen;
@@ -148,9 +156,10 @@
     private boolean mSeekAvailable;
     private boolean mIsAdvertisement;
     private boolean mIsMute;
+    private boolean mNeedUXUpdate;
 
     // Relating to Title Bar View
-    private View mRoot;
+    private ViewGroup mRoot;
     private View mTitleBar;
     private TextView mTitleView;
     private View mAdExternalLink;
@@ -167,8 +176,15 @@
     private ImageButton mNextButton;
     private ImageButton mPrevButton;
 
+    // Relating to Minimal Extra View
+    private LinearLayout mMinimalExtraView;
+
     // Relating to Progress Bar View
     private ProgressBar mProgress;
+    private View mProgressBuffer;
+
+    // Relating to Bottom Bar View
+    private ViewGroup mBottomBar;
 
     // Relating to Bottom Bar Left View
     private ViewGroup mBottomBarLeftView;
@@ -207,10 +223,6 @@
     private List<String> mPlaybackSpeedTextList;
     private List<Float> mPlaybackSpeedList;
 
-    private CharSequence mPlayDescription;
-    private CharSequence mPauseDescription;
-    private CharSequence mReplayDescription;
-
     public MediaControlView2Impl(MediaControlView2 instance,
             ViewGroupProvider superProvider, ViewGroupProvider privateProvider) {
         super(instance, superProvider, privateProvider);
@@ -338,28 +350,63 @@
     public void onMeasure_impl(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure_impl(widthMeasureSpec, heightMeasureSpec);
 
-        if (mPrevWidth != mInstance.getMeasuredWidth()) {
-            int currWidth = mInstance.getMeasuredWidth();
+        // Update layout when this view's width changes in order to avoid any UI overlap between
+        // transport controls.
+        if (mPrevWidth != mInstance.getMeasuredWidth()
+                || mPrevHeight != mInstance.getMeasuredHeight() || mNeedUXUpdate) {
+            // Dismiss SettingsWindow if it is showing.
+            mSettingsWindow.dismiss();
 
-            int iconSize = mResources.getDimensionPixelSize(R.dimen.mcv2_full_icon_size);
-            int marginSize = mResources.getDimensionPixelSize(R.dimen.mcv2_icon_margin);
-            int bottomBarRightWidthMax = iconSize * 4 + marginSize * 8;
-
-            int fullWidth = mTransportControls.getWidth() + mTimeView.getWidth()
-                    + bottomBarRightWidthMax;
             // These views may not have been initialized yet.
             if (mTransportControls.getWidth() == 0 || mTimeView.getWidth() == 0) {
                 return;
             }
-            if (mSizeType == SIZE_TYPE_EMBEDDED && fullWidth <= currWidth) {
-                updateLayoutForSizeChange(SIZE_TYPE_FULL);
-            } else if (mSizeType == SIZE_TYPE_FULL && fullWidth > currWidth) {
-                updateLayoutForSizeChange(SIZE_TYPE_EMBEDDED);
+
+            int currWidth = mInstance.getMeasuredWidth();
+            int currHeight = mInstance.getMeasuredHeight();
+            WindowManager manager = (WindowManager) mInstance.getContext().getApplicationContext()
+                    .getSystemService(Context.WINDOW_SERVICE);
+            Point screenSize = new Point();
+            manager.getDefaultDisplay().getSize(screenSize);
+            int screenWidth = screenSize.x;
+            int screenHeight = screenSize.y;
+            int fullIconSize = mResources.getDimensionPixelSize(R.dimen.mcv2_full_icon_size);
+            int embeddedIconSize = mResources.getDimensionPixelSize(
+                    R.dimen.mcv2_embedded_icon_size);
+            int marginSize = mResources.getDimensionPixelSize(R.dimen.mcv2_icon_margin);
+
+            // TODO: add support for Advertisement Mode.
+            if (mMediaType == MEDIA_TYPE_DEFAULT) {
+                // Max number of icons inside BottomBarRightView for Music mode is 4.
+                int maxIconCount = 4;
+                updateLayout(maxIconCount, fullIconSize, embeddedIconSize, marginSize, currWidth,
+                        currHeight, screenWidth, screenHeight);
+            } else if (mMediaType == MEDIA_TYPE_MUSIC) {
+                if (mNeedUXUpdate) {
+                    // One-time operation for Music media type
+                    mBasicControls.removeView(mMuteButton);
+                    mExtraControls.addView(mMuteButton, 0);
+                    mVideoQualityButton.setVisibility(View.GONE);
+                    if (mFfwdButton != null) {
+                        mFfwdButton.setVisibility(View.GONE);
+                    }
+                    if (mRewButton != null) {
+                        mRewButton.setVisibility(View.GONE);
+                    }
+                }
+                mNeedUXUpdate = false;
+
+                // Max number of icons inside BottomBarRightView for Music mode is 3.
+                int maxIconCount = 3;
+                updateLayout(maxIconCount, fullIconSize, embeddedIconSize, marginSize, currWidth,
+                        currHeight, screenWidth, screenHeight);
             }
-            // Dismiss SettingsWindow if it is showing.
-            mSettingsWindow.dismiss();
             mPrevWidth = currWidth;
+            mPrevHeight = currHeight;
         }
+        // TODO: move this to a different location.
+        // Update title bar parameters in order to avoid overlap between title view and the right
+        // side of the title bar.
         updateTitleBarLayout();
     }
 
@@ -472,19 +519,14 @@
      * @return The controller view.
      * @hide This doesn't work as advertised
      */
-    protected View makeControllerView() {
-        View root = ApiHelper.inflateLibLayout(mInstance.getContext(), R.layout.media_controller);
+    protected ViewGroup makeControllerView() {
+        ViewGroup root = (ViewGroup) ApiHelper.inflateLibLayout(mInstance.getContext(),
+                R.layout.media_controller);
         initControllerView(root);
         return root;
     }
 
-    private void initControllerView(View v) {
-        mPlayDescription = mResources.getText(R.string.lockscreen_play_button_content_description);
-        mPauseDescription =
-                mResources.getText(R.string.lockscreen_pause_button_content_description);
-        mReplayDescription =
-                mResources.getText(R.string.lockscreen_replay_button_content_description);
-
+    private void initControllerView(ViewGroup v) {
         // Relating to Title Bar View
         mTitleBar = v.findViewById(R.id.title_bar);
         mTitleView = v.findViewById(R.id.title_text);
@@ -492,6 +534,7 @@
         mBackButton = v.findViewById(R.id.back);
         if (mBackButton != null) {
             mBackButton.setOnClickListener(mBackListener);
+            mBackButton.setVisibility(View.GONE);
         }
         mRouteButton = v.findViewById(R.id.cast);
 
@@ -500,8 +543,18 @@
         mTransportControls = inflateTransportControls(R.layout.embedded_transport_controls);
         mCenterView.addView(mTransportControls);
 
+        // Relating to Minimal Extra View
+        mMinimalExtraView = (LinearLayout) v.findViewById(R.id.minimal_extra_view);
+        LinearLayout.LayoutParams params =
+                (LinearLayout.LayoutParams) mMinimalExtraView.getLayoutParams();
+        int iconSize = mResources.getDimensionPixelSize(R.dimen.mcv2_embedded_icon_size);
+        int marginSize = mResources.getDimensionPixelSize(R.dimen.mcv2_icon_margin);
+        params.setMargins(0, (iconSize + marginSize * 2) * (-1), 0, 0);
+        mMinimalExtraView.setLayoutParams(params);
+        mMinimalExtraView.setVisibility(View.GONE);
+
         // Relating to Progress Bar View
-        mProgress = v.findViewById(R.id.mediacontroller_progress);
+        mProgress = v.findViewById(R.id.progress);
         if (mProgress != null) {
             if (mProgress instanceof SeekBar) {
                 SeekBar seeker = (SeekBar) mProgress;
@@ -511,6 +564,10 @@
             }
             mProgress.setMax(MAX_PROGRESS);
         }
+        mProgressBuffer = v.findViewById(R.id.progress_buffer);
+
+        // Relating to Bottom Bar View
+        mBottomBar = v.findViewById(R.id.bottom_bar);
 
         // Relating to Bottom Bar Left View
         mBottomBarLeftView = v.findViewById(R.id.bottom_bar_left);
@@ -707,12 +764,14 @@
             mControls.pause();
             mPlayPauseButton.setImageDrawable(
                     mResources.getDrawable(R.drawable.ic_play_circle_filled, null));
-            mPlayPauseButton.setContentDescription(mPlayDescription);
+            mPlayPauseButton.setContentDescription(
+                    mResources.getString(R.string.mcv2_play_button_desc));
         } else {
             mControls.play();
             mPlayPauseButton.setImageDrawable(
                     mResources.getDrawable(R.drawable.ic_pause_circle_filled, null));
-            mPlayPauseButton.setContentDescription(mPauseDescription);
+            mPlayPauseButton.setContentDescription(
+                    mResources.getString(R.string.mcv2_pause_button_desc));
         }
     }
 
@@ -748,7 +807,8 @@
             if (mIsStopped) {
                 mPlayPauseButton.setImageDrawable(
                         mResources.getDrawable(R.drawable.ic_play_circle_filled, null));
-                mPlayPauseButton.setContentDescription(mPlayDescription);
+                mPlayPauseButton.setContentDescription(
+                        mResources.getString(R.string.mcv2_play_button_desc));
                 mIsStopped = false;
             }
         }
@@ -764,11 +824,11 @@
                 return;
             }
             if (mDuration > 0) {
-                int newPosition = (int) (((long) mDuration * progress) / MAX_PROGRESS);
-                mControls.seekTo(newPosition);
+                int position = (int) (((long) mDuration * progress) / MAX_PROGRESS);
+                mControls.seekTo(position);
 
                 if (mCurrentTime != null) {
-                    mCurrentTime.setText(stringForTime(newPosition));
+                    mCurrentTime.setText(stringForTime(position));
                 }
             }
         }
@@ -869,7 +929,7 @@
             }
             Bundle args = new Bundle();
             args.putBoolean(ARGUMENT_KEY_FULLSCREEN, isEnteringFullScreen);
-            mController.sendCommand(MediaControlView2Impl.COMMAND_SET_FULLSCREEN, args, null);
+            mController.sendCommand(COMMAND_SET_FULLSCREEN, args, null);
 
             mIsFullScreen = isEnteringFullScreen;
         }
@@ -897,11 +957,15 @@
             if (!mIsMute) {
                 mMuteButton.setImageDrawable(
                         mResources.getDrawable(R.drawable.ic_mute, null));
+                mMuteButton.setContentDescription(
+                        mResources.getString(R.string.mcv2_muted_button_desc));
                 mIsMute = true;
                 mController.sendCommand(COMMAND_MUTE, null, null);
             } else {
                 mMuteButton.setImageDrawable(
                         mResources.getDrawable(R.drawable.ic_unmute, null));
+                mMuteButton.setContentDescription(
+                        mResources.getString(R.string.mcv2_unmuted_button_desc));
                 mIsMute = false;
                 mController.sendCommand(COMMAND_UNMUTE, null, null);
             }
@@ -975,12 +1039,16 @@
                                     MediaControlView2Impl.COMMAND_SHOW_SUBTITLE, extra, null);
                             mSubtitleButton.setImageDrawable(
                                     mResources.getDrawable(R.drawable.ic_subtitle_on, null));
+                            mSubtitleButton.setContentDescription(
+                                    mResources.getString(R.string.mcv2_cc_is_on));
                             mSubtitleIsEnabled = true;
                         } else {
                             mController.sendCommand(
                                     MediaControlView2Impl.COMMAND_HIDE_SUBTITLE, null, null);
                             mSubtitleButton.setImageDrawable(
                                     mResources.getDrawable(R.drawable.ic_subtitle_off, null));
+                            mSubtitleButton.setContentDescription(
+                                    mResources.getString(R.string.mcv2_cc_is_off));
 
                             mSubtitleIsEnabled = false;
                         }
@@ -1039,6 +1107,34 @@
         }
     }
 
+    private void updateAudioMetadata() {
+        if (mMediaType != MEDIA_TYPE_MUSIC) {
+            return;
+        }
+
+        if (mMetadata != null) {
+            String titleText = "";
+            String artistText = "";
+            if (mMetadata.containsKey(MediaMetadata.METADATA_KEY_TITLE)) {
+                titleText = mMetadata.getString(MediaMetadata.METADATA_KEY_TITLE);
+            } else {
+                titleText = mResources.getString(R.string.mcv2_music_title_unknown_text);
+            }
+
+            if (mMetadata.containsKey(MediaMetadata.METADATA_KEY_ARTIST)) {
+                artistText = mMetadata.getString(MediaMetadata.METADATA_KEY_ARTIST);
+            } else {
+                artistText = mResources.getString(R.string.mcv2_music_artist_unknown_text);
+            }
+
+            // Update title for Embedded size type
+            mTitleView.setText(titleText + " - " + artistText);
+
+            // Set to true to update layout inside onMeasure()
+            mNeedUXUpdate = true;
+        }
+    }
+
     private void updateLayout() {
         if (mIsAdvertisement) {
             mRewButton.setVisibility(View.GONE);
@@ -1070,47 +1166,154 @@
         }
     }
 
+    private void updateLayout(int maxIconCount, int fullIconSize, int embeddedIconSize,
+             int marginSize, int currWidth, int currHeight, int screenWidth, int screenHeight) {
+        int fullBottomBarRightWidthMax = fullIconSize * maxIconCount
+                + marginSize * (maxIconCount * 2);
+        int embeddedBottomBarRightWidthMax = embeddedIconSize * maxIconCount
+                + marginSize * (maxIconCount * 2);
+        int fullWidth = mTransportControls.getWidth() + mTimeView.getWidth()
+                + fullBottomBarRightWidthMax;
+        int embeddedWidth = mTimeView.getWidth() + embeddedBottomBarRightWidthMax;
+        int screenMaxLength = Math.max(screenWidth, screenHeight);
+
+        if (fullWidth > screenMaxLength) {
+            // TODO: screen may be smaller than the length needed for Full size.
+        }
+
+        boolean isFullSize = (mMediaType == MEDIA_TYPE_DEFAULT) ? (currWidth == screenMaxLength) :
+                (currWidth == screenWidth && currHeight == screenHeight);
+
+        if (isFullSize) {
+            if (mSizeType != SIZE_TYPE_FULL) {
+                updateLayoutForSizeChange(SIZE_TYPE_FULL);
+                if (mMediaType == MEDIA_TYPE_MUSIC) {
+                    mTitleView.setVisibility(View.GONE);
+                }
+            }
+        } else if (embeddedWidth <= currWidth) {
+            if (mSizeType != SIZE_TYPE_EMBEDDED) {
+                updateLayoutForSizeChange(SIZE_TYPE_EMBEDDED);
+                if (mMediaType == MEDIA_TYPE_MUSIC) {
+                    mTitleView.setVisibility(View.VISIBLE);
+                }
+            }
+        } else {
+            if (mSizeType != SIZE_TYPE_MINIMAL) {
+                updateLayoutForSizeChange(SIZE_TYPE_MINIMAL);
+                if (mMediaType == MEDIA_TYPE_MUSIC) {
+                    mTitleView.setVisibility(View.GONE);
+                }
+            }
+        }
+    }
+
     private void updateLayoutForSizeChange(int sizeType) {
         mSizeType = sizeType;
-        RelativeLayout.LayoutParams params =
+        RelativeLayout.LayoutParams timeViewParams =
                 (RelativeLayout.LayoutParams) mTimeView.getLayoutParams();
+        SeekBar seeker = (SeekBar) mProgress;
         switch (mSizeType) {
             case SIZE_TYPE_EMBEDDED:
+                // Relating to Title Bar
+                mTitleBar.setVisibility(View.VISIBLE);
+                mBackButton.setVisibility(View.GONE);
+
+                // Relating to Full Screen Button
+                mMinimalExtraView.setVisibility(View.GONE);
+                mFullScreenButton = mBottomBarRightView.findViewById(R.id.fullscreen);
+                mFullScreenButton.setOnClickListener(mFullScreenListener);
+
+                // Relating to Center View
+                mCenterView.removeAllViews();
                 mBottomBarLeftView.removeView(mTransportControls);
                 mBottomBarLeftView.setVisibility(View.GONE);
                 mTransportControls = inflateTransportControls(R.layout.embedded_transport_controls);
-                mCenterView.addView(mTransportControls, 0);
+                mCenterView.addView(mTransportControls);
 
-                if (params.getRule(RelativeLayout.LEFT_OF) != 0) {
-                    params.removeRule(RelativeLayout.LEFT_OF);
-                    params.addRule(RelativeLayout.RIGHT_OF, R.id.bottom_bar_left);
+                // Relating to Progress Bar
+                seeker.setThumb(mResources.getDrawable(R.drawable.custom_progress_thumb));
+                mProgressBuffer.setVisibility(View.VISIBLE);
+
+                // Relating to Bottom Bar
+                mBottomBar.setVisibility(View.VISIBLE);
+                if (timeViewParams.getRule(RelativeLayout.LEFT_OF) != 0) {
+                    timeViewParams.removeRule(RelativeLayout.LEFT_OF);
+                    timeViewParams.addRule(RelativeLayout.RIGHT_OF, R.id.bottom_bar_left);
                 }
                 break;
             case SIZE_TYPE_FULL:
-                mCenterView.removeView(mTransportControls);
+                // Relating to Title Bar
+                mTitleBar.setVisibility(View.VISIBLE);
+                mBackButton.setVisibility(View.VISIBLE);
+
+                // Relating to Full Screen Button
+                mMinimalExtraView.setVisibility(View.GONE);
+                mFullScreenButton = mBottomBarRightView.findViewById(R.id.fullscreen);
+                mFullScreenButton.setOnClickListener(mFullScreenListener);
+
+                // Relating to Center View
+                mCenterView.removeAllViews();
+                mBottomBarLeftView.removeView(mTransportControls);
                 mTransportControls = inflateTransportControls(R.layout.full_transport_controls);
                 mBottomBarLeftView.addView(mTransportControls, 0);
                 mBottomBarLeftView.setVisibility(View.VISIBLE);
 
-                if (params.getRule(RelativeLayout.RIGHT_OF) != 0) {
-                    params.removeRule(RelativeLayout.RIGHT_OF);
-                    params.addRule(RelativeLayout.LEFT_OF, R.id.bottom_bar_right);
+                // Relating to Progress Bar
+                seeker.setThumb(mResources.getDrawable(R.drawable.custom_progress_thumb));
+                mProgressBuffer.setVisibility(View.VISIBLE);
+
+                // Relating to Bottom Bar
+                mBottomBar.setVisibility(View.VISIBLE);
+                if (timeViewParams.getRule(RelativeLayout.RIGHT_OF) != 0) {
+                    timeViewParams.removeRule(RelativeLayout.RIGHT_OF);
+                    timeViewParams.addRule(RelativeLayout.LEFT_OF, R.id.bottom_bar_right);
                 }
                 break;
             case SIZE_TYPE_MINIMAL:
-                // TODO: implement
+                // Relating to Title Bar
+                mTitleBar.setVisibility(View.GONE);
+                mBackButton.setVisibility(View.GONE);
+
+                // Relating to Full Screen Button
+                mMinimalExtraView.setVisibility(View.VISIBLE);
+                mFullScreenButton = mMinimalExtraView.findViewById(R.id.fullscreen);
+                mFullScreenButton.setOnClickListener(mFullScreenListener);
+
+                // Relating to Center View
+                mCenterView.removeAllViews();
+                mBottomBarLeftView.removeView(mTransportControls);
+                mTransportControls = inflateTransportControls(R.layout.minimal_transport_controls);
+                mCenterView.addView(mTransportControls);
+
+                // Relating to Progress Bar
+                seeker.setThumb(null);
+                mProgressBuffer.setVisibility(View.GONE);
+
+                // Relating to Bottom Bar
+                mBottomBar.setVisibility(View.GONE);
                 break;
         }
-        mTimeView.setLayoutParams(params);
+        mTimeView.setLayoutParams(timeViewParams);
 
         if (isPlaying()) {
             mPlayPauseButton.setImageDrawable(
                     mResources.getDrawable(R.drawable.ic_pause_circle_filled, null));
-            mPlayPauseButton.setContentDescription(mPauseDescription);
+            mPlayPauseButton.setContentDescription(
+                    mResources.getString(R.string.mcv2_pause_button_desc));
         } else {
             mPlayPauseButton.setImageDrawable(
                     mResources.getDrawable(R.drawable.ic_play_circle_filled, null));
-            mPlayPauseButton.setContentDescription(mPlayDescription);
+            mPlayPauseButton.setContentDescription(
+                    mResources.getString(R.string.mcv2_play_button_desc));
+        }
+
+        if (mIsFullScreen) {
+            mFullScreenButton.setImageDrawable(
+                    mResources.getDrawable(R.drawable.ic_fullscreen_exit, null));
+        } else {
+            mFullScreenButton.setImageDrawable(
+                    mResources.getDrawable(R.drawable.ic_fullscreen, null));
         }
     }
 
@@ -1124,10 +1327,16 @@
         mFfwdButton = v.findViewById(R.id.ffwd);
         if (mFfwdButton != null) {
             mFfwdButton.setOnClickListener(mFfwdListener);
+            if (mMediaType == MEDIA_TYPE_MUSIC) {
+                mFfwdButton.setVisibility(View.GONE);
+            }
         }
         mRewButton = v.findViewById(R.id.rew);
         if (mRewButton != null) {
             mRewButton.setOnClickListener(mRewListener);
+            if (mMediaType == MEDIA_TYPE_MUSIC) {
+                mRewButton.setVisibility(View.GONE);
+            }
         }
         // TODO: Add support for Next and Previous buttons
         mNextButton = v.findViewById(R.id.next);
@@ -1218,19 +1427,22 @@
                     case PlaybackState.STATE_PLAYING:
                         mPlayPauseButton.setImageDrawable(
                                 mResources.getDrawable(R.drawable.ic_pause_circle_filled, null));
-                        mPlayPauseButton.setContentDescription(mPauseDescription);
+                        mPlayPauseButton.setContentDescription(
+                                mResources.getString(R.string.mcv2_pause_button_desc));
                         mInstance.removeCallbacks(mUpdateProgress);
                         mInstance.post(mUpdateProgress);
                         break;
                     case PlaybackState.STATE_PAUSED:
                         mPlayPauseButton.setImageDrawable(
                                 mResources.getDrawable(R.drawable.ic_play_circle_filled, null));
-                        mPlayPauseButton.setContentDescription(mPlayDescription);
+                        mPlayPauseButton.setContentDescription(
+                                mResources.getString(R.string.mcv2_play_button_desc));
                         break;
                     case PlaybackState.STATE_STOPPED:
                         mPlayPauseButton.setImageDrawable(
                                 mResources.getDrawable(R.drawable.ic_replay_circle_filled, null));
-                        mPlayPauseButton.setContentDescription(mReplayDescription);
+                        mPlayPauseButton.setContentDescription(
+                                mResources.getString(R.string.mcv2_replay_button_desc));
                         mIsStopped = true;
                         break;
                     default:
@@ -1244,11 +1456,17 @@
                 if ((newActions & PlaybackState.ACTION_PAUSE) != 0) {
                     mPlayPauseButton.setVisibility(View.VISIBLE);
                 }
-                if ((newActions & PlaybackState.ACTION_REWIND) != 0) {
-                    mRewButton.setVisibility(View.VISIBLE);
+                if ((newActions & PlaybackState.ACTION_REWIND) != 0
+                        && mMediaType != MEDIA_TYPE_MUSIC) {
+                    if (mRewButton != null) {
+                        mRewButton.setVisibility(View.VISIBLE);
+                    }
                 }
-                if ((newActions & PlaybackState.ACTION_FAST_FORWARD) != 0) {
-                    mFfwdButton.setVisibility(View.VISIBLE);
+                if ((newActions & PlaybackState.ACTION_FAST_FORWARD) != 0
+                        && mMediaType != MEDIA_TYPE_MUSIC) {
+                    if (mFfwdButton != null) {
+                        mFfwdButton.setVisibility(View.VISIBLE);
+                    }
                 }
                 if ((newActions & PlaybackState.ACTION_SEEK_TO) != 0) {
                     mSeekAvailable = true;
@@ -1289,6 +1507,7 @@
             mMetadata = metadata;
             updateDuration();
             updateTitle();
+            updateAudioMetadata();
         }
 
         @Override
@@ -1315,6 +1534,9 @@
                         mAudioTrackList.add(mResources.getString(
                                 R.string.MediaControlView2_audio_track_none_text));
                     }
+                    if (mVideoTrackCount == 0 && mAudioTrackCount > 0) {
+                        mMediaType = MEDIA_TYPE_MUSIC;
+                    }
 
                     mSubtitleTrackCount = extras.getInt(KEY_SUBTITLE_TRACK_COUNT);
                     mSubtitleDescriptionsList = new ArrayList<String>();
diff --git a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
index 46ae359..97279d6 100644
--- a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
+++ b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
@@ -17,6 +17,13 @@
 package com.android.widget;
 
 import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Point;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
 import android.media.AudioAttributes;
 import android.media.AudioFocusRequest;
 import android.media.AudioManager;
@@ -29,6 +36,7 @@
 import android.media.SubtitleData;
 import android.media.MediaItem2;
 import android.media.MediaMetadata2;
+import android.media.MediaMetadataRetriever;
 import android.media.Metadata;
 import android.media.PlaybackParams;
 import android.media.TimedText;
@@ -45,19 +53,26 @@
 import android.os.ResultReceiver;
 import android.support.annotation.Nullable;
 import android.util.AttributeSet;
+import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.Pair;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup.LayoutParams;
+import android.view.WindowManager;
 import android.view.accessibility.AccessibilityManager;
+import android.widget.ImageView;
 import android.widget.MediaControlView2;
+import android.widget.TextView;
 import android.widget.VideoView2;
 
+import com.android.internal.graphics.palette.Palette;
 import com.android.media.RoutePlayer;
 import com.android.media.subtitle.ClosedCaptionRenderer;
 import com.android.media.subtitle.SubtitleController;
 import com.android.media.subtitle.SubtitleTrack;
+import com.android.media.update.ApiHelper;
+import com.android.media.update.R;
 import com.android.support.mediarouter.media.MediaItemStatus;
 import com.android.support.mediarouter.media.MediaControlIntent;
 import com.android.support.mediarouter.media.MediaRouter;
@@ -87,6 +102,11 @@
     private static final int INVALID_TRACK_INDEX = -1;
     private static final float INVALID_SPEED = 0f;
 
+    private static final int SIZE_TYPE_EMBEDDED = 0;
+    private static final int SIZE_TYPE_FULL = 1;
+    // TODO: add support for Minimal size type.
+    private static final int SIZE_TYPE_MINIMAL = 2;
+
     private AccessibilityManager mAccessibilityManager;
     private AudioManager mAudioManager;
     private AudioAttributes mAudioAttributes;
@@ -107,10 +127,24 @@
     private MediaController mMediaController;
     private Metadata mMetadata;
     private MediaMetadata2 mMediaMetadata;
+    private MediaMetadataRetriever mRetriever;
     private boolean mNeedUpdateMediaType;
     private Bundle mMediaTypeData;
     private String mTitle;
 
+    // TODO: move music view inside SurfaceView/TextureView or implement VideoViewInterface.
+    private WindowManager mManager;
+    private Resources mResources;
+    private View mMusicView;
+    private Drawable mMusicAlbumDrawable;
+    private String mMusicTitleText;
+    private String mMusicArtistText;
+    private boolean mIsMusicMediaType;
+    private int mPrevWidth;
+    private int mPrevHeight;
+    private int mDominantColor;
+    private int mSizeType;
+
     private PlaybackState.Builder mStateBuilder;
     private List<PlaybackState.CustomAction> mCustomActionList;
     private int mTargetState = STATE_IDLE;
@@ -250,19 +284,11 @@
         mSurfaceView.setLayoutParams(params);
         mTextureView.setSurfaceListener(this);
         mSurfaceView.setSurfaceListener(this);
-
-        // TODO: Choose TextureView when SurfaceView cannot be created.
-        // Choose surface view by default
-        mTextureView.setVisibility(View.GONE);
-        mSurfaceView.setVisibility(View.VISIBLE);
         mInstance.addView(mTextureView);
         mInstance.addView(mSurfaceView);
-        mCurrentView = mSurfaceView;
 
-        LayoutParams subtitleParams = new LayoutParams(LayoutParams.MATCH_PARENT,
-                LayoutParams.MATCH_PARENT);
         mSubtitleView = new SubtitleView(mInstance.getContext());
-        mSubtitleView.setLayoutParams(subtitleParams);
+        mSubtitleView.setLayoutParams(params);
         mSubtitleView.setBackgroundColor(0);
         mInstance.addView(mSubtitleView);
 
@@ -277,16 +303,22 @@
                 "http://schemas.android.com/apk/res/android",
                 "enableSubtitle", false);
 
+        // TODO: Choose TextureView when SurfaceView cannot be created.
+        // Choose surface view by default
         int viewType = (attrs == null) ? VideoView2.VIEW_TYPE_SURFACEVIEW
                 : attrs.getAttributeIntValue(
                 "http://schemas.android.com/apk/res/android",
-                "viewType", 0);
-        if (viewType == 0) {
+                "viewType", VideoView2.VIEW_TYPE_SURFACEVIEW);
+        if (viewType == VideoView2.VIEW_TYPE_SURFACEVIEW) {
             Log.d(TAG, "viewType attribute is surfaceView.");
-            // TODO: implement
-        } else if (viewType == 1) {
+            mTextureView.setVisibility(View.GONE);
+            mSurfaceView.setVisibility(View.VISIBLE);
+            mCurrentView = mSurfaceView;
+        } else if (viewType == VideoView2.VIEW_TYPE_TEXTUREVIEW) {
             Log.d(TAG, "viewType attribute is textureView.");
-            // TODO: implement
+            mTextureView.setVisibility(View.VISIBLE);
+            mSurfaceView.setVisibility(View.GONE);
+            mCurrentView = mTextureView;
         }
 
         MediaRouteSelector.Builder builder = new MediaRouteSelector.Builder();
@@ -492,6 +524,14 @@
         // TODO: remove this after moving MediaSession creating code inside initializing VideoView2
         if (mCurrentState == STATE_PREPARED) {
             extractTracks();
+            extractMetadata();
+            extractAudioMetadata();
+            if (mNeedUpdateMediaType) {
+                mMediaSession.sendSessionEvent(
+                        MediaControlView2Impl.EVENT_UPDATE_MEDIA_TYPE_STATUS,
+                        mMediaTypeData);
+                mNeedUpdateMediaType = false;
+            }
         }
     }
 
@@ -516,7 +556,9 @@
                     + ", mTargetState=" + mTargetState);
         }
         if (ev.getAction() == MotionEvent.ACTION_UP && mMediaControlView != null) {
-            toggleMediaControlViewVisibility();
+            if (!mIsMusicMediaType || mSizeType != SIZE_TYPE_FULL) {
+                toggleMediaControlViewVisibility();
+            }
         }
 
         return super.onTouchEvent_impl(ev);
@@ -525,7 +567,9 @@
     @Override
     public boolean onTrackballEvent_impl(MotionEvent ev) {
         if (ev.getAction() == MotionEvent.ACTION_UP && mMediaControlView != null) {
-            toggleMediaControlViewVisibility();
+            if (!mIsMusicMediaType || mSizeType != SIZE_TYPE_FULL) {
+                toggleMediaControlViewVisibility();
+            }
         }
 
         return super.onTrackballEvent_impl(ev);
@@ -537,6 +581,48 @@
         return super.dispatchTouchEvent_impl(ev);
     }
 
+    @Override
+    public void onMeasure_impl(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure_impl(widthMeasureSpec, heightMeasureSpec);
+
+        if (mIsMusicMediaType) {
+            if (mPrevWidth != mInstance.getMeasuredWidth()
+                    || mPrevHeight != mInstance.getMeasuredHeight()) {
+                int currWidth = mInstance.getMeasuredWidth();
+                int currHeight = mInstance.getMeasuredHeight();
+                Point screenSize = new Point();
+                mManager.getDefaultDisplay().getSize(screenSize);
+                int screenWidth = screenSize.x;
+                int screenHeight = screenSize.y;
+
+                if (currWidth == screenWidth && currHeight == screenHeight) {
+                    int orientation = retrieveOrientation();
+                    if (orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
+                        inflateMusicView(R.layout.full_landscape_music);
+                    } else {
+                        inflateMusicView(R.layout.full_portrait_music);
+                    }
+
+                    if (mSizeType != SIZE_TYPE_FULL) {
+                        mSizeType = SIZE_TYPE_FULL;
+                        // Remove existing mFadeOut callback
+                        mMediaControlView.removeCallbacks(mFadeOut);
+                        mMediaControlView.setVisibility(View.VISIBLE);
+                    }
+                } else {
+                    if (mSizeType != SIZE_TYPE_EMBEDDED) {
+                        mSizeType = SIZE_TYPE_EMBEDDED;
+                        inflateMusicView(R.layout.embedded_music);
+                        // Add new mFadeOut callback
+                        mMediaControlView.postDelayed(mFadeOut, mShowControllerIntervalMs);
+                    }
+                }
+                mPrevWidth = currWidth;
+                mPrevHeight = currHeight;
+            }
+        }
+    }
+
     ///////////////////////////////////////////////////
     // Implements VideoViewInterface.SurfaceListener
     ///////////////////////////////////////////////////
@@ -663,6 +749,8 @@
             if (scheme != null && scheme.equals("file")) {
                 mTitle = uri.getLastPathSegment();
             }
+            mRetriever = new MediaMetadataRetriever();
+            mRetriever.setDataSource(mInstance.getContext(), uri);
 
             if (DEBUG) {
                 Log.d(TAG, "openVideo(). mCurrentState=" + mCurrentState
@@ -798,7 +886,8 @@
 
     private void showController() {
         // TODO: Decide what to show when the state is not in playback state
-        if (mMediaControlView == null || !isInPlaybackState()) {
+        if (mMediaControlView == null || !isInPlaybackState()
+                || (mIsMusicMediaType && mSizeType == SIZE_TYPE_FULL)) {
             return;
         }
         mMediaControlView.removeCallbacks(mFadeOut);
@@ -898,6 +987,9 @@
         if (mAudioTrackIndices.size() > 0) {
             mSelectedAudioTrackIndex = 0;
         }
+        if (mVideoTrackIndices.size() == 0 && mAudioTrackIndices.size() > 0) {
+            mIsMusicMediaType = true;
+        }
 
         Bundle data = new Bundle();
         data.putInt(MediaControlView2Impl.KEY_VIDEO_TRACK_COUNT, mVideoTrackIndices.size());
@@ -909,6 +1001,110 @@
         mMediaSession.sendSessionEvent(MediaControlView2Impl.EVENT_UPDATE_TRACK_STATUS, data);
     }
 
+    private void extractMetadata() {
+        // Get and set duration and title values as MediaMetadata for MediaControlView2
+        MediaMetadata.Builder builder = new MediaMetadata.Builder();
+        if (mMetadata != null && mMetadata.has(Metadata.TITLE)) {
+            mTitle = mMetadata.getString(Metadata.TITLE);
+        }
+        builder.putString(MediaMetadata.METADATA_KEY_TITLE, mTitle);
+        builder.putLong(
+                MediaMetadata.METADATA_KEY_DURATION, mMediaPlayer.getDuration());
+
+        if (mMediaSession != null) {
+            mMediaSession.setMetadata(builder.build());
+        }
+    }
+
+    private void extractAudioMetadata() {
+        if (!mIsMusicMediaType) {
+            return;
+        }
+
+        mResources = ApiHelper.getLibResources(mInstance.getContext());
+        mManager = (WindowManager) mInstance.getContext().getApplicationContext()
+                .getSystemService(Context.WINDOW_SERVICE);
+
+        byte[] album = mRetriever.getEmbeddedPicture();
+        if (album != null) {
+            Bitmap bitmap = BitmapFactory.decodeByteArray(album, 0, album.length);
+            mMusicAlbumDrawable = new BitmapDrawable(bitmap);
+
+            // TODO: replace with visualizer
+            Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
+                public void onGenerated(Palette palette) {
+                    // TODO: add dominant color for default album image.
+                    mDominantColor = palette.getDominantColor(0);
+                    if (mMusicView != null) {
+                        mMusicView.setBackgroundColor(mDominantColor);
+                    }
+                }
+            });
+        } else {
+            mMusicAlbumDrawable = mResources.getDrawable(R.drawable.ic_default_album_image);
+        }
+
+        String title = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
+        if (title != null) {
+            mMusicTitleText = title;
+        } else {
+            mMusicTitleText = mResources.getString(R.string.mcv2_music_title_unknown_text);
+        }
+
+        String artist = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
+        if (artist != null) {
+            mMusicArtistText = artist;
+        } else {
+            mMusicArtistText = mResources.getString(R.string.mcv2_music_artist_unknown_text);
+        }
+
+        // Send title and artist string to MediaControlView2
+        MediaMetadata.Builder builder = new MediaMetadata.Builder();
+        builder.putString(MediaMetadata.METADATA_KEY_TITLE, mMusicTitleText);
+        builder.putString(MediaMetadata.METADATA_KEY_ARTIST, mMusicArtistText);
+        mMediaSession.setMetadata(builder.build());
+
+        // Display Embedded mode as default
+        mInstance.removeView(mSurfaceView);
+        mInstance.removeView(mTextureView);
+        inflateMusicView(R.layout.embedded_music);
+    }
+
+    private int retrieveOrientation() {
+        DisplayMetrics dm = Resources.getSystem().getDisplayMetrics();
+        int width = dm.widthPixels;
+        int height = dm.heightPixels;
+
+        return (height > width) ?
+                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT :
+                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+    }
+
+    private void inflateMusicView(int layoutId) {
+        mInstance.removeView(mMusicView);
+
+        View v = ApiHelper.inflateLibLayout(mInstance.getContext(), layoutId);
+        v.setBackgroundColor(mDominantColor);
+
+        ImageView albumView = v.findViewById(R.id.album);
+        if (albumView != null) {
+            albumView.setImageDrawable(mMusicAlbumDrawable);
+        }
+
+        TextView titleView = v.findViewById(R.id.title);
+        if (titleView != null) {
+            titleView.setText(mMusicTitleText);
+        }
+
+        TextView artistView = v.findViewById(R.id.artist);
+        if (artistView != null) {
+            artistView.setText(mMusicArtistText);
+        }
+
+        mMusicView = v;
+        mInstance.addView(mMusicView, 0);
+    }
+
     OnSubtitleDataListener mSubtitleListener =
             new OnSubtitleDataListener() {
                 @Override
@@ -994,6 +1190,14 @@
                     }
                 }
 
+                @Override
+                public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what,
+                        int status) {
+                    if (what == MediaPlayer2.CALL_COMPLETED_SEEK_TO && status == 0) {
+                        updatePlaybackState();
+                    }
+                }
+
                 private void onPrepared(MediaPlayer2 mp, DataSourceDesc dsd) {
                     if (DEBUG) {
                         Log.d(TAG, "OnPreparedListener(). mCurrentState=" + mCurrentState
@@ -1007,6 +1211,8 @@
                     // TODO: create MediaSession when initializing VideoView2
                     if (mMediaSession != null) {
                         extractTracks();
+                        extractMetadata();
+                        extractAudioMetadata();
                     }
 
                     if (mMediaControlView != null) {
@@ -1046,27 +1252,6 @@
                             mMediaController.getTransportControls().play();
                         }
                     }
-                    // Get and set duration and title values as MediaMetadata for MediaControlView2
-                    MediaMetadata.Builder builder = new MediaMetadata.Builder();
-                    if (mMetadata != null && mMetadata.has(Metadata.TITLE)) {
-                        mTitle = mMetadata.getString(Metadata.TITLE);
-                    }
-                    builder.putString(MediaMetadata.METADATA_KEY_TITLE, mTitle);
-                    builder.putLong(
-                            MediaMetadata.METADATA_KEY_DURATION, mMediaPlayer.getDuration());
-
-                    if (mMediaSession != null) {
-                        mMediaSession.setMetadata(builder.build());
-
-                        // TODO: merge this code with the above code when integrating with
-                        // MediaSession2.
-                        if (mNeedUpdateMediaType) {
-                            mMediaSession.sendSessionEvent(
-                                    MediaControlView2Impl.EVENT_UPDATE_MEDIA_TYPE_STATUS,
-                                    mMediaTypeData);
-                            mNeedUpdateMediaType = false;
-                        }
-                    }
                 }
 
                 private void onCompletion(MediaPlayer2 mp, DataSourceDesc dsd) {
@@ -1153,7 +1338,7 @@
 
         @Override
         public void onPlay() {
-            if (isInPlaybackState() && mCurrentView.hasAvailableSurface()) {
+            if (isInPlaybackState() && (mCurrentView.hasAvailableSurface() || mIsMusicMediaType)) {
                 if (isRemotePlayback()) {
                     mRoutePlayer.onPlay();
                 } else {
@@ -1200,7 +1385,6 @@
                 } else {
                     mMediaPlayer.seekTo(pos, MediaPlayer2.SEEK_PREVIOUS_SYNC);
                     mSeekWhenPrepared = 0;
-                    updatePlaybackState();
                 }
             } else {
                 mSeekWhenPrepared = pos;
diff --git a/packages/MediaComponents/tests/src/com/android/media/SessionPlaylistAgentTest.java b/packages/MediaComponents/tests/src/com/android/media/SessionPlaylistAgentTest.java
index ca941ab..beb0848 100644
--- a/packages/MediaComponents/tests/src/com/android/media/SessionPlaylistAgentTest.java
+++ b/packages/MediaComponents/tests/src/com/android/media/SessionPlaylistAgentTest.java
@@ -24,6 +24,7 @@
 import android.media.MediaItem2;
 import android.media.MediaMetadata2;
 import android.media.MediaPlayerBase;
+import android.media.MediaPlayerBase.PlayerEventCallback;
 import android.media.MediaPlaylistAgent;
 import android.media.MediaSession2;
 import android.media.MediaSession2.OnDataSourceMissingHelper;
@@ -35,6 +36,7 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Matchers;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -56,6 +58,7 @@
     private Context mContext;
     private MediaSession2Impl mSessionImpl;
     private MediaPlayerBase mPlayer;
+    private PlayerEventCallback mPlayerEventCallback;
     private SessionPlaylistAgent mAgent;
     private OnDataSourceMissingHelper mDataSourceHelper;
     private MyPlaylistEventCallback mEventCallback;
@@ -229,9 +232,15 @@
         };
 
         mPlayer = mock(MockPlayer.class);
+        doAnswer(invocation -> {
+            Object[] args = invocation.getArguments();
+            mPlayerEventCallback = (PlayerEventCallback) args[1];
+            return null;
+        }).when(mPlayer).registerPlayerEventCallback(Matchers.any(), Matchers.any());
+
         mSessionImpl = mock(MediaSession2Impl.class);
         mDataSourceHelper = new MyDataSourceHelper();
-        mAgent = new SessionPlaylistAgent(mContext, mSessionImpl, mPlayer);
+        mAgent = new SessionPlaylistAgent(mSessionImpl, mPlayer);
         mAgent.setOnDataSourceMissingHelper(mDataSourceHelper);
         mEventCallback = new MyPlaylistEventCallback(mWaitLock);
         mAgent.registerPlaylistEventCallback(mHandlerExecutor, mEventCallback);
@@ -567,6 +576,33 @@
         assertEquals(SessionPlaylistAgent.END_OF_PLAYLIST, mAgent.getCurShuffledIndex());
     }
 
+    @Test
+    public void testPlaylistAfterOnCurrentDataSourceChanged() throws Exception {
+        int listSize = 2;
+        verify(mPlayer).registerPlayerEventCallback(Matchers.any(), Matchers.any());
+
+        createAndSetPlaylist(listSize);
+        assertEquals(0, mAgent.getCurShuffledIndex());
+
+        mPlayerEventCallback.onCurrentDataSourceChanged(mPlayer, null);
+        assertEquals(1, mAgent.getCurShuffledIndex());
+        mPlayerEventCallback.onCurrentDataSourceChanged(mPlayer, null);
+        assertEquals(SessionPlaylistAgent.END_OF_PLAYLIST, mAgent.getCurShuffledIndex());
+
+        mAgent.skipToNextItem();
+        assertEquals(SessionPlaylistAgent.END_OF_PLAYLIST, mAgent.getCurShuffledIndex());
+
+        mAgent.setRepeatMode(MediaPlaylistAgent.REPEAT_MODE_ONE);
+        assertEquals(SessionPlaylistAgent.END_OF_PLAYLIST, mAgent.getCurShuffledIndex());
+
+        mAgent.setRepeatMode(MediaPlaylistAgent.REPEAT_MODE_ALL);
+        assertEquals(0, mAgent.getCurShuffledIndex());
+        mPlayerEventCallback.onCurrentDataSourceChanged(mPlayer, null);
+        assertEquals(1, mAgent.getCurShuffledIndex());
+        mPlayerEventCallback.onCurrentDataSourceChanged(mPlayer, null);
+        assertEquals(0, mAgent.getCurShuffledIndex());
+    }
+
     private List<MediaItem2> createAndSetPlaylist(int listSize) throws Exception {
         List<MediaItem2> items = new ArrayList<>();
         for (int i = 0; i < listSize; ++i) {
@@ -593,13 +629,13 @@
     }
 
     private MediaItem2 generateMediaItemWithoutDataSourceDesc(int key) {
-        return new MediaItem2.Builder(mContext, 0)
+        return new MediaItem2.Builder(0)
                 .setMediaId("TEST_MEDIA_ID_WITHOUT_DSD_" + key)
                 .build();
     }
 
     private MediaItem2 generateMediaItem(int key) {
-        return new MediaItem2.Builder(mContext, 0)
+        return new MediaItem2.Builder(0)
                 .setMediaId("TEST_MEDIA_ID_" + key)
                 .build();
     }
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index ea06b6c..b38d37f 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -753,8 +753,8 @@
         output.notificationFrameCount = input.notificationFrameCount;
         output.flags = input.flags;
 
-        track = thread->createTrack_l(client, streamType, &output.sampleRate, input.config.format,
-                                      input.config.channel_mask,
+        track = thread->createTrack_l(client, streamType, input.attr, &output.sampleRate,
+                                      input.config.format, input.config.channel_mask,
                                       &output.frameCount, &output.notificationFrameCount,
                                       input.notificationsPerBuffer, input.speed,
                                       input.sharedBuffer, sessionId, &output.flags,
@@ -1673,7 +1673,7 @@
         output.frameCount = input.frameCount;
         output.notificationFrameCount = input.notificationFrameCount;
 
-        recordTrack = thread->createRecordTrack_l(client, &output.sampleRate,
+        recordTrack = thread->createRecordTrack_l(client, input.attr, &output.sampleRate,
                                                   input.config.format, input.config.channel_mask,
                                                   &output.frameCount, sessionId,
                                                   &output.notificationFrameCount,
@@ -1962,39 +1962,10 @@
 
 status_t AudioFlinger::getMicrophones(std::vector<media::MicrophoneInfo> *microphones)
 {
-    // Fake data
-    size_t fakeNum = 2;
-    audio_devices_t fakeTypes[] = { AUDIO_DEVICE_IN_BUILTIN_MIC, AUDIO_DEVICE_IN_BACK_MIC };
-    for (size_t i = 0; i < fakeNum; i++) {
-        struct audio_microphone_characteristic_t characteristics;
-        sprintf(characteristics.device_id, "microphone:%zu", i);
-        characteristics.device = fakeTypes[i];
-        sprintf(characteristics.address, "");
-        characteristics.location = AUDIO_MICROPHONE_LOCATION_MAINBODY;
-        characteristics.group = 0;
-        characteristics.index_in_the_group = i;
-        characteristics.sensitivity = 1.0f;
-        characteristics.max_spl = 100.0f;
-        characteristics.min_spl = 0.0f;
-        characteristics.directionality = AUDIO_MICROPHONE_DIRECTIONALITY_OMNI;
-        characteristics.num_frequency_responses = 5 - i;
-        for (size_t j = 0; j < characteristics.num_frequency_responses; j++) {
-            characteristics.frequency_responses[0][j] = 100.0f - j;
-            characteristics.frequency_responses[1][j] = 100.0f + j;
-        }
-        for (size_t j = 0; j < AUDIO_CHANNEL_COUNT_MAX; j++) {
-            characteristics.channel_mapping[j] = AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
-        }
-        characteristics.geometric_location.x = 0.1f;
-        characteristics.geometric_location.y = 0.2f;
-        characteristics.geometric_location.z = 0.3f;
-        characteristics.orientation.x = 0.0f;
-        characteristics.orientation.y = 1.0f;
-        characteristics.orientation.z = 0.0f;
-        media::MicrophoneInfo microphoneInfo = media::MicrophoneInfo(characteristics);
-        microphones->push_back(microphoneInfo);
-    }
-    return NO_ERROR;
+    AutoMutex lock(mHardwareLock);
+    sp<DeviceHalInterface> dev = mPrimaryHardwareDev->hwDevice();
+    status_t status = dev->getMicrophones(microphones);
+    return status;
 }
 
 // setAudioHwSyncForSession_l() must be called with AudioFlinger::mLock held
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 979290f..dcf223c 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -591,6 +591,7 @@
 
 #ifdef MULTICHANNEL_EFFECT_CHAIN
     if (status != NO_ERROR &&
+            thread->isOutput() &&
             (mConfig.inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO
                     || mConfig.outputCfg.channels != AUDIO_CHANNEL_OUT_STEREO)) {
         // Older effects may require exact STEREO position mask.
diff --git a/services/audioflinger/MmapTracks.h b/services/audioflinger/MmapTracks.h
index 366a164..a210a1b 100644
--- a/services/audioflinger/MmapTracks.h
+++ b/services/audioflinger/MmapTracks.h
@@ -23,6 +23,7 @@
 class MmapTrack : public TrackBase {
 public:
                 MmapTrack(ThreadBase *thread,
+                            const audio_attributes_t& attr,
                             uint32_t sampleRate,
                             audio_format_t format,
                             audio_channel_mask_t channelMask,
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 6454be5..ea01a25 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -25,6 +25,7 @@
                         Track(  PlaybackThread *thread,
                                 const sp<Client>& client,
                                 audio_stream_type_t streamType,
+                                const audio_attributes_t& attr,
                                 uint32_t sampleRate,
                                 audio_format_t format,
                                 audio_channel_mask_t channelMask,
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index 1733ef5..2b993ee 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -24,6 +24,7 @@
 public:
                         RecordTrack(RecordThread *thread,
                                 const sp<Client>& client,
+                                const audio_attributes_t& attr,
                                 uint32_t sampleRate,
                                 audio_format_t format,
                                 audio_channel_mask_t channelMask,
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 62e9fe7..adeef31 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -57,6 +57,7 @@
 #include <powermanager/PowerManager.h>
 
 #include <media/audiohal/EffectsFactoryHalInterface.h>
+#include <media/audiohal/StreamHalInterface.h>
 
 #include "AudioFlinger.h"
 #include "FastMixer.h"
@@ -1554,6 +1555,7 @@
     mActiveTracksGeneration++;
     mLatestActiveTrack = track;
     ++mBatteryCounter[track->uid()].second;
+    mHasChanged = true;
     return mActiveTracks.add(track);
 }
 
@@ -1568,6 +1570,7 @@
     mActiveTracksGeneration++;
     --mBatteryCounter[track->uid()].second;
     // mLatestActiveTrack is not cleared even if is the same as track.
+    mHasChanged = true;
     return index;
 }
 
@@ -1578,6 +1581,7 @@
         logTrack("clear", track);
     }
     mLastActiveTracksGeneration = mActiveTracksGeneration;
+    if (!mActiveTracks.empty()) { mHasChanged = true; }
     mActiveTracks.clear();
     mLatestActiveTrack.clear();
     mBatteryCounter.clear();
@@ -1615,6 +1619,13 @@
 }
 
 template <typename T>
+bool AudioFlinger::ThreadBase::ActiveTracks<T>::readAndClearHasChanged() {
+    const bool hasChanged = mHasChanged;
+    mHasChanged = false;
+    return hasChanged;
+}
+
+template <typename T>
 void AudioFlinger::ThreadBase::ActiveTracks<T>::logTrack(
         const char *funcName, const sp<T> &track) const {
     if (mLocalLog != nullptr) {
@@ -1847,6 +1858,7 @@
 sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrack_l(
         const sp<AudioFlinger::Client>& client,
         audio_stream_type_t streamType,
+        const audio_attributes_t& attr,
         uint32_t *pSampleRate,
         audio_format_t format,
         audio_channel_mask_t channelMask,
@@ -2125,7 +2137,7 @@
             }
         }
 
-        track = new Track(this, client, streamType, sampleRate, format,
+        track = new Track(this, client, streamType, attr, sampleRate, format,
                           channelMask, frameCount,
                           nullptr /* buffer */, (size_t)0 /* bufferSize */, sharedBuffer,
                           sessionId, uid, *flags, TrackBase::TYPE_DEFAULT, portId);
@@ -2609,6 +2621,28 @@
     }
 }
 
+void AudioFlinger::PlaybackThread::updateMetadata_l()
+{
+    // TODO: add volume support
+    if (mOutput == nullptr || mOutput->stream == nullptr ||
+            !mActiveTracks.readAndClearHasChanged()) {
+        return;
+    }
+    StreamOutHalInterface::SourceMetadata metadata;
+    for (const sp<Track> &track : mActiveTracks) {
+        // No track is invalid as this is called after prepareTrack_l in the same critical section
+        if (track->isOutputTrack()) {
+            // TODO: OutputTrack (used for duplication) are currently not supported
+            continue;
+        }
+        metadata.tracks.push_back({
+                .usage = track->attributes().usage,
+                .content_type = track->attributes().content_type,
+                .gain = 1,
+        });
+    }
+    mOutput->stream->updateSourceMetadata(metadata);
+}
 
 status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames)
 {
@@ -3306,6 +3340,8 @@
 
             mActiveTracks.updatePowerState(this);
 
+            updateMetadata_l();
+
             // prevent any changes in effect chain list and in each effect chain
             // during mixing and effect process as the audio buffers could be deleted
             // or modified if an effect is created or deleted
@@ -4757,6 +4793,18 @@
         track->reset();
     }
 
+    // Track destruction may occur outside of threadLoop once it is removed from active tracks.
+    // Ensure the AudioMixer doesn't have a raw "buffer provider" pointer to the track if
+    // it ceases to be active, to allow safe removal from the AudioMixer at the start
+    // of prepareTracks_l(); this releases any outstanding buffer back to the track.
+    // See also the implementation of destroyTrack_l().
+    for (const auto &track : *tracksToRemove) {
+        const int name = track->name();
+        if (mAudioMixer->exists(name)) { // Normal tracks here, fast tracks in FastMixer.
+            mAudioMixer->setBufferProvider(name, nullptr /* bufferProvider */);
+        }
+    }
+
     // remove all the tracks that need to be...
     removeTracks_l(*tracksToRemove);
 
@@ -6117,6 +6165,16 @@
     return true;
 }
 
+void AudioFlinger::DuplicatingThread::updateMetadata_l()
+{
+    // TODO: The duplicated track metadata needs to be pushed to downstream
+    // but this information can be read at any time by the downstream threads.
+    // Taking the lock of any downstream threads is no possible due to cross deadlock risks
+    // (eg: during effect move).
+    // A lock-free structure needs to be used to shared the metadata, probably an atomic
+    // pointer to a metadata vector in each output tracks.
+}
+
 uint32_t AudioFlinger::DuplicatingThread::activeSleepTimeUs() const
 {
     return (mWaitTimeMs * 1000) / 2;
@@ -6444,6 +6502,8 @@
 
             mActiveTracks.updatePowerState(this);
 
+            updateMetadata_l();
+
             if (allStopped) {
                 standbyIfNotAlreadyInStandby();
             }
@@ -6808,6 +6868,7 @@
 // RecordThread::createRecordTrack_l() must be called with AudioFlinger::mLock held
 sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createRecordTrack_l(
         const sp<AudioFlinger::Client>& client,
+        const audio_attributes_t& attr,
         uint32_t *pSampleRate,
         audio_format_t format,
         audio_channel_mask_t channelMask,
@@ -6941,7 +7002,7 @@
     { // scope for mLock
         Mutex::Autolock _l(mLock);
 
-        track = new RecordTrack(this, client, sampleRate,
+        track = new RecordTrack(this, client, attr, sampleRate,
                       format, channelMask, frameCount,
                       nullptr /* buffer */, (size_t)0 /* bufferSize */, sessionId, uid,
                       *flags, TrackBase::TYPE_DEFAULT, portId);
@@ -7129,42 +7190,25 @@
 {
     ALOGV("RecordThread::getActiveMicrophones");
     AutoMutex _l(mLock);
-    // Fake data
-    struct audio_microphone_characteristic_t characteristic;
-    sprintf(characteristic.device_id, "builtin_mic");
-    characteristic.device = AUDIO_DEVICE_IN_BUILTIN_MIC;
-    sprintf(characteristic.address, "");
-    characteristic.location = AUDIO_MICROPHONE_LOCATION_MAINBODY;
-    characteristic.group = 0;
-    characteristic.index_in_the_group = 0;
-    characteristic.sensitivity = 1.0f;
-    characteristic.max_spl = 100.0f;
-    characteristic.min_spl = 0.0f;
-    characteristic.directionality = AUDIO_MICROPHONE_DIRECTIONALITY_OMNI;
-    characteristic.num_frequency_responses = 5;
-    for (size_t i = 0; i < characteristic.num_frequency_responses; i++) {
-        characteristic.frequency_responses[0][i] = 100.0f - i;
-        characteristic.frequency_responses[1][i] = 100.0f + i;
+    status_t status = mInput->stream->getActiveMicrophones(activeMicrophones);
+    return status;
+}
+
+void AudioFlinger::RecordThread::updateMetadata_l()
+{
+    if (mInput == nullptr || mInput->stream == nullptr ||
+            !mActiveTracks.readAndClearHasChanged()) {
+        return;
     }
-    for (size_t i = 0; i < AUDIO_CHANNEL_COUNT_MAX; i++) {
-        characteristic.channel_mapping[i] = AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
+    StreamInHalInterface::SinkMetadata metadata;
+    for (const sp<RecordTrack> &track : mActiveTracks) {
+        // No track is invalid as this is called after prepareTrack_l in the same critical section
+        metadata.tracks.push_back({
+                .source = track->attributes().source,
+                .gain = 1, // capture tracks do not have volumes
+        });
     }
-    audio_microphone_channel_mapping_t channel_mappings[] = {
-        AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT,
-        AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED,
-    };
-    for (size_t i = 0; i < mChannelCount; i++) {
-        characteristic.channel_mapping[i] = channel_mappings[i % 2];
-    }
-    characteristic.geometric_location.x = 0.1f;
-    characteristic.geometric_location.y = 0.2f;
-    characteristic.geometric_location.z = 0.3f;
-    characteristic.orientation.x = 0.0f;
-    characteristic.orientation.y = 1.0f;
-    characteristic.orientation.z = 0.0f;
-    media::MicrophoneInfo microphoneInfo = media::MicrophoneInfo(characteristic);
-    activeMicrophones->push_back(microphoneInfo);
-    return NO_ERROR;
+    mInput->stream->updateSinkMetadata(metadata);
 }
 
 // destroyTrack_l() must be called with ThreadBase::mLock held
@@ -7994,7 +8038,8 @@
         return PERMISSION_DENIED;
     }
 
-    sp<MmapTrack> track = new MmapTrack(this, mSampleRate, mFormat, mChannelMask, mSessionId,
+    // Given that MmapThread::mAttr is mutable, should a MmapTrack have attributes ?
+    sp<MmapTrack> track = new MmapTrack(this, mAttr, mSampleRate, mFormat, mChannelMask, mSessionId,
                                         client.clientUid, client.clientPid, portId);
 
     mActiveTracks.add(track);
@@ -8130,6 +8175,8 @@
 
         mActiveTracks.updatePowerState(this);
 
+        updateMetadata_l();
+
         lockEffectChains_l(effectChains);
         for (size_t i = 0; i < effectChains.size(); i ++) {
             effectChains[i]->process_l();
@@ -8677,6 +8724,24 @@
     }
 }
 
+void AudioFlinger::MmapPlaybackThread::updateMetadata_l()
+{
+    if (mOutput == nullptr || mOutput->stream == nullptr ||
+            !mActiveTracks.readAndClearHasChanged()) {
+        return;
+    }
+    StreamOutHalInterface::SourceMetadata metadata;
+    for (const sp<MmapTrack> &track : mActiveTracks) {
+        // No track is invalid as this is called after prepareTrack_l in the same critical section
+        metadata.tracks.push_back({
+                .usage = track->attributes().usage,
+                .content_type = track->attributes().content_type,
+                .gain = mHalVolFloat, // TODO: propagate from aaudio pre-mix volume
+        });
+    }
+    mOutput->stream->updateSourceMetadata(metadata);
+}
+
 void AudioFlinger::MmapPlaybackThread::checkSilentMode_l()
 {
     if (!mMasterMute) {
@@ -8721,4 +8786,22 @@
     mInput = NULL;
     return input;
 }
+
+void AudioFlinger::MmapCaptureThread::updateMetadata_l()
+{
+    if (mInput == nullptr || mInput->stream == nullptr ||
+            !mActiveTracks.readAndClearHasChanged()) {
+        return;
+    }
+    StreamInHalInterface::SinkMetadata metadata;
+    for (const sp<MmapTrack> &track : mActiveTracks) {
+        // No track is invalid as this is called after prepareTrack_l in the same critical section
+        metadata.tracks.push_back({
+                .source = track->attributes().source,
+                .gain = 1, // capture tracks do not have volumes
+        });
+    }
+    mInput->stream->updateSinkMetadata(metadata);
+}
+
 } // namespace android
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 7cd46a7..bb81224 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -425,6 +425,9 @@
                 // check if some effects must be suspended when an effect chain is added
                 void checkSuspendOnAddEffectChain_l(const sp<EffectChain>& chain);
 
+                // sends the metadata of the active tracks to the HAL
+    virtual     void        updateMetadata_l() = 0;
+
                 String16 getWakeLockTag();
 
     virtual     void        preExit() { }
@@ -563,6 +566,10 @@
                     // periodically called in the threadLoop() to update power state uids.
                     void            updatePowerState(sp<ThreadBase> thread, bool force = false);
 
+                    /** @return true if the active tracks have changed since the last time
+                     *          this function was called or the vector was created. */
+                    bool            readAndClearHasChanged();
+
                 private:
                     void            logTrack(const char *funcName, const sp<T> &track) const;
 
@@ -581,6 +588,8 @@
                     int                 mLastActiveTracksGeneration;
                     wp<T>               mLatestActiveTrack; // latest track added to ActiveTracks
                     SimpleLog * const   mLocalLog;
+                    // If the active tracks have changed since last call to readAndClearHasChanged
+                    bool                mHasChanged = false;
                 };
 
                 SimpleLog mLocalLog;
@@ -706,6 +715,7 @@
                 sp<Track>   createTrack_l(
                                 const sp<AudioFlinger::Client>& client,
                                 audio_stream_type_t streamType,
+                                const audio_attributes_t& attr,
                                 uint32_t *sampleRate,
                                 audio_format_t format,
                                 audio_channel_mask_t channelMask,
@@ -917,6 +927,7 @@
     void        removeTrack_l(const sp<Track>& track);
 
     void        readOutputParameters_l();
+    void        updateMetadata_l() override;
 
     virtual void dumpInternals(int fd, const Vector<String16>& args);
     void        dumpTracks(int fd, const Vector<String16>& args);
@@ -1275,6 +1286,8 @@
                 void        addOutputTrack(MixerThread* thread);
                 void        removeOutputTrack(MixerThread* thread);
                 uint32_t    waitTimeMs() const { return mWaitTimeMs; }
+
+                void        updateMetadata_l() override;
 protected:
     virtual     uint32_t    activeSleepTimeUs() const;
 
@@ -1387,6 +1400,7 @@
 
             sp<AudioFlinger::RecordThread::RecordTrack>  createRecordTrack_l(
                     const sp<AudioFlinger::Client>& client,
+                    const audio_attributes_t& attr,
                     uint32_t *pSampleRate,
                     audio_format_t format,
                     audio_channel_mask_t channelMask,
@@ -1461,6 +1475,8 @@
 
             status_t    getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones);
 
+            void        updateMetadata_l() override;
+
 private:
             // Enter standby if not already in standby, and set mStandby flag
             void    standbyIfNotAlreadyInStandby();
@@ -1658,6 +1674,8 @@
 
     virtual     bool        isOutput() const override { return true; }
 
+                void        updateMetadata_l() override;
+
 protected:
 
                 audio_stream_type_t         mStreamType;
@@ -1684,6 +1702,8 @@
 
     virtual     bool           isOutput() const override { return false; }
 
+                void           updateMetadata_l() override;
+
 protected:
 
                 AudioStreamIn*  mInput;
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index a7e966f..ccfb69f 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -61,6 +61,7 @@
 
                         TrackBase(ThreadBase *thread,
                                 const sp<Client>& client,
+                                const audio_attributes_t& mAttr,
                                 uint32_t sampleRate,
                                 audio_format_t format,
                                 audio_channel_mask_t channelMask,
@@ -97,6 +98,7 @@
     virtual void        invalidate() { mIsInvalid = true; }
             bool        isInvalid() const { return mIsInvalid; }
 
+    audio_attributes_t  attributes() const { return mAttr; }
 
 protected:
     DISALLOW_COPY_AND_ASSIGN(TrackBase);
@@ -188,6 +190,7 @@
     size_t              mBufferSize; // size of mBuffer in bytes
     // we don't really need a lock for these
     track_state         mState;
+    const audio_attributes_t mAttr;
     const uint32_t      mSampleRate;    // initial sample rate only; for tracks which
                         // support dynamic rates, the current value is in control block
     const audio_format_t mFormat;
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 9b93939..236412b 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -63,6 +63,7 @@
 AudioFlinger::ThreadBase::TrackBase::TrackBase(
             ThreadBase *thread,
             const sp<Client>& client,
+            const audio_attributes_t& attr,
             uint32_t sampleRate,
             audio_format_t format,
             audio_channel_mask_t channelMask,
@@ -81,6 +82,7 @@
         mCblk(NULL),
         // mBuffer, mBufferSize
         mState(IDLE),
+        mAttr(attr),
         mSampleRate(sampleRate),
         mFormat(format),
         mChannelMask(channelMask),
@@ -372,6 +374,7 @@
             PlaybackThread *thread,
             const sp<Client>& client,
             audio_stream_type_t streamType,
+            const audio_attributes_t& attr,
             uint32_t sampleRate,
             audio_format_t format,
             audio_channel_mask_t channelMask,
@@ -384,7 +387,7 @@
             audio_output_flags_t flags,
             track_type type,
             audio_port_handle_t portId)
-    :   TrackBase(thread, client, sampleRate, format, channelMask, frameCount,
+    :   TrackBase(thread, client, attr, sampleRate, format, channelMask, frameCount,
                   (sharedBuffer != 0) ? sharedBuffer->pointer() : buffer,
                   (sharedBuffer != 0) ? sharedBuffer->size() : bufferSize,
                   sessionId, uid, true /*isOut*/,
@@ -761,6 +764,12 @@
                 mState = state;
             }
         }
+
+        if (status == NO_ERROR || status == ALREADY_EXISTS) {
+            // for streaming tracks, remove the buffer read stop limit.
+            mAudioTrackServerProxy->start();
+        }
+
         // track was already in the active list, not a problem
         if (status == ALREADY_EXISTS) {
             status = NO_ERROR;
@@ -1259,6 +1268,7 @@
             size_t frameCount,
             uid_t uid)
     :   Track(playbackThread, NULL, AUDIO_STREAM_PATCH,
+              audio_attributes_t{} /* currently unused for output track */,
               sampleRate, format, channelMask, frameCount,
               nullptr /* buffer */, (size_t)0 /* bufferSize */, nullptr /* sharedBuffer */,
               AUDIO_SESSION_NONE, uid, AUDIO_OUTPUT_FLAG_NONE,
@@ -1461,6 +1471,7 @@
                                                      size_t bufferSize,
                                                      audio_output_flags_t flags)
     :   Track(playbackThread, NULL, streamType,
+              audio_attributes_t{} /* currently unused for patch track */,
               sampleRate, format, channelMask, frameCount,
               buffer, bufferSize, nullptr /* sharedBuffer */,
               AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
@@ -1595,6 +1606,7 @@
 AudioFlinger::RecordThread::RecordTrack::RecordTrack(
             RecordThread *thread,
             const sp<Client>& client,
+            const audio_attributes_t& attr,
             uint32_t sampleRate,
             audio_format_t format,
             audio_channel_mask_t channelMask,
@@ -1606,7 +1618,7 @@
             audio_input_flags_t flags,
             track_type type,
             audio_port_handle_t portId)
-    :   TrackBase(thread, client, sampleRate, format,
+    :   TrackBase(thread, client, attr, sampleRate, format,
                   channelMask, frameCount, buffer, bufferSize, sessionId, uid, false /*isOut*/,
                   (type == TYPE_DEFAULT) ?
                           ((flags & AUDIO_INPUT_FLAG_FAST) ? ALLOC_PIPE : ALLOC_CBLK) :
@@ -1821,7 +1833,9 @@
                                                      void *buffer,
                                                      size_t bufferSize,
                                                      audio_input_flags_t flags)
-    :   RecordTrack(recordThread, NULL, sampleRate, format, channelMask, frameCount,
+    :   RecordTrack(recordThread, NULL,
+                audio_attributes_t{} /* currently unused for patch track */,
+                sampleRate, format, channelMask, frameCount,
                 buffer, bufferSize, AUDIO_SESSION_NONE, getuid(), flags, TYPE_PATCH),
                 mProxy(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true))
 {
@@ -1882,6 +1896,7 @@
 
 
 AudioFlinger::MmapThread::MmapTrack::MmapTrack(ThreadBase *thread,
+        const audio_attributes_t& attr,
         uint32_t sampleRate,
         audio_format_t format,
         audio_channel_mask_t channelMask,
@@ -1889,7 +1904,7 @@
         uid_t uid,
         pid_t pid,
         audio_port_handle_t portId)
-    :   TrackBase(thread, NULL, sampleRate, format,
+    :   TrackBase(thread, NULL, attr, sampleRate, format,
                   channelMask, (size_t)0 /* frameCount */,
                   nullptr /* buffer */, (size_t)0 /* bufferSize */,
                   sessionId, uid, false /* isOut */,
diff --git a/services/audiopolicy/common/include/Volume.h b/services/audiopolicy/common/include/Volume.h
index 4862684..fc012a2 100644
--- a/services/audiopolicy/common/include/Volume.h
+++ b/services/audiopolicy/common/include/Volume.h
@@ -38,6 +38,7 @@
     DEVICE_CATEGORY_SPEAKER,
     DEVICE_CATEGORY_EARPIECE,
     DEVICE_CATEGORY_EXT_MEDIA,
+    DEVICE_CATEGORY_HEARING_AID,
     DEVICE_CATEGORY_CNT
 };
 
@@ -125,8 +126,9 @@
         case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
         case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
         case AUDIO_DEVICE_OUT_USB_HEADSET:
-        case AUDIO_DEVICE_OUT_HEARING_AID:
             return DEVICE_CATEGORY_HEADSET;
+        case AUDIO_DEVICE_OUT_HEARING_AID:
+            return DEVICE_CATEGORY_HEARING_AID;
         case AUDIO_DEVICE_OUT_LINE:
         case AUDIO_DEVICE_OUT_AUX_DIGITAL:
         case AUDIO_DEVICE_OUT_USB_DEVICE:
diff --git a/services/audiopolicy/common/managerdefinitions/include/Gains.h b/services/audiopolicy/common/managerdefinitions/include/Gains.h
index 8332af9..cb229a4 100644
--- a/services/audiopolicy/common/managerdefinitions/include/Gains.h
+++ b/services/audiopolicy/common/managerdefinitions/include/Gains.h
@@ -52,6 +52,7 @@
     static const VolumeCurvePoint sLinearVolumeCurve[Volume::VOLCNT];
     static const VolumeCurvePoint sSilentVolumeCurve[Volume::VOLCNT];
     static const VolumeCurvePoint sFullScaleVolumeCurve[Volume::VOLCNT];
+    static const VolumeCurvePoint sHearingAidVolumeCurve[Volume::VOLCNT];
     // default volume curves per stream and device category. See initializeVolumeCurves()
     static const VolumeCurvePoint *sVolumeProfiles[AUDIO_STREAM_CNT][DEVICE_CATEGORY_CNT];
 };
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
index 094ff65..d85562e 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp
@@ -391,6 +391,7 @@
     mSamplingRate = 0;
     mChannelMask = AUDIO_CHANNEL_NONE;
     mFormat = AUDIO_FORMAT_INVALID;
+    memset(&mGain, 0, sizeof(struct audio_gain_config));
     mGain.index = -1;
 }
 
diff --git a/services/audiopolicy/common/managerdefinitions/src/Gains.cpp b/services/audiopolicy/common/managerdefinitions/src/Gains.cpp
index b2dafdd..6407a17 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Gains.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Gains.cpp
@@ -113,86 +113,104 @@
     {0, 0.0f}, {1, 0.0f}, {2, 0.0f}, {100, 0.0f}
 };
 
+const VolumeCurvePoint
+Gains::sHearingAidVolumeCurve[Volume::VOLCNT] = {
+    {1, -128.0f}, {20, -80.0f}, {60, -40.0f}, {100, 0.0f}
+};
+
 const VolumeCurvePoint *Gains::sVolumeProfiles[AUDIO_STREAM_CNT]
                                                   [DEVICE_CATEGORY_CNT] = {
     { // AUDIO_STREAM_VOICE_CALL
         Gains::sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET
         Gains::sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER
         Gains::sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        Gains::sDefaultMediaVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sHearingAidVolumeCurve     // DEVICE_CATEGORY_HEARING_AID
     },
     { // AUDIO_STREAM_SYSTEM
         Gains::sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
         Gains::sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
         Gains::sDefaultSystemVolumeCurve,  // DEVICE_CATEGORY_EARPIECE
-        Gains::sExtMediaSystemVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sExtMediaSystemVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sHearingAidVolumeCurve       // DEVICE_CATEGORY_HEARING_AID
     },
     { // AUDIO_STREAM_RING
         Gains::sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
         Gains::sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
         Gains::sDefaultVolumeCurve,  // DEVICE_CATEGORY_EARPIECE
-        Gains::sExtMediaSystemVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sExtMediaSystemVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sHearingAidVolumeCurve // DEVICE_CATEGORY_HEARING_AID
     },
     { // AUDIO_STREAM_MUSIC
         Gains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET
         Gains::sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER
         Gains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        Gains::sDefaultMediaVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sHearingAidVolumeCurve     // DEVICE_CATEGORY_HEARING_AID
     },
     { // AUDIO_STREAM_ALARM
         Gains::sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
         Gains::sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
         Gains::sDefaultVolumeCurve,  // DEVICE_CATEGORY_EARPIECE
-        Gains::sExtMediaSystemVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sExtMediaSystemVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sHearingAidVolumeCurve // DEVICE_CATEGORY_HEARING_AID
     },
     { // AUDIO_STREAM_NOTIFICATION
         Gains::sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
         Gains::sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
         Gains::sDefaultVolumeCurve,  // DEVICE_CATEGORY_EARPIECE
-        Gains::sExtMediaSystemVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sExtMediaSystemVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sHearingAidVolumeCurve // DEVICE_CATEGORY_HEARING_AID
     },
     { // AUDIO_STREAM_BLUETOOTH_SCO
         Gains::sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET
         Gains::sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER
         Gains::sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        Gains::sDefaultMediaVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sHearingAidVolumeCurve      // DEVICE_CATEGORY_HEARING_AID
     },
     { // AUDIO_STREAM_ENFORCED_AUDIBLE
         Gains::sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
         Gains::sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
         Gains::sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        Gains::sExtMediaSystemVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sExtMediaSystemVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sHearingAidVolumeCurve       // DEVICE_CATEGORY_HEARING_AID
     },
     {  // AUDIO_STREAM_DTMF
         Gains::sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
         Gains::sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
         Gains::sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        Gains::sExtMediaSystemVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sExtMediaSystemVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sHearingAidVolumeCurve       // DEVICE_CATEGORY_HEARING_AID
     },
     { // AUDIO_STREAM_TTS
       // "Transmitted Through Speaker": always silent except on DEVICE_CATEGORY_SPEAKER
         Gains::sSilentVolumeCurve,    // DEVICE_CATEGORY_HEADSET
         Gains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_SPEAKER
         Gains::sSilentVolumeCurve,    // DEVICE_CATEGORY_EARPIECE
-        Gains::sSilentVolumeCurve     // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sSilentVolumeCurve,    // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sHearingAidVolumeCurve  // DEVICE_CATEGORY_HEARING_AID
     },
     { // AUDIO_STREAM_ACCESSIBILITY
         Gains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET
         Gains::sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER
         Gains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        Gains::sDefaultMediaVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sHearingAidVolumeCurve     // DEVICE_CATEGORY_HEARING_AID
     },
     { // AUDIO_STREAM_REROUTING
         Gains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_HEADSET
         Gains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_SPEAKER
         Gains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        Gains::sFullScaleVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sFullScaleVolumeCurve  // DEVICE_CATEGORY_HEARING_AID
     },
     { // AUDIO_STREAM_PATCH
         Gains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_HEADSET
         Gains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_SPEAKER
         Gains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_EARPIECE
-        Gains::sFullScaleVolumeCurve  // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sFullScaleVolumeCurve, // DEVICE_CATEGORY_EXT_MEDIA
+        Gains::sFullScaleVolumeCurve  // DEVICE_CATEGORY_HEARING_AID
     },
 };
 
diff --git a/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp b/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp
index 7273d0d..6f48eae 100644
--- a/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp
@@ -29,6 +29,7 @@
     MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_SPEAKER),
     MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_EARPIECE),
     MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_EXT_MEDIA),
+    MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_HEARING_AID),
     TERMINATOR
 };
 
diff --git a/services/audiopolicy/config/audio_policy_volumes.xml b/services/audiopolicy/config/audio_policy_volumes.xml
index 43a47b0..ec64a7c 100644
--- a/services/audiopolicy/config/audio_policy_volumes.xml
+++ b/services/audiopolicy/config/audio_policy_volumes.xml
@@ -43,6 +43,8 @@
     </volume>
     <volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
                                              ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+    <volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
+                                             ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_HEADSET">
         <point>1,-3000</point>
         <point>33,-2600</point>
@@ -55,6 +57,8 @@
                                          ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
                                          ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+    <volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
+                                         ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_HEADSET"
                                        ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_SPEAKER">
@@ -67,6 +71,8 @@
                                        ref="DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
                                        ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+    <volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
+                                       ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_HEADSET"
                                         ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_SPEAKER"
@@ -75,18 +81,22 @@
                                         ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
                                         ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+    <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
+                                        ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_HEADSET"
-                                        ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
+                                        ref="DEFAULT_NON_MUTABLE_HEADSET_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_SPEAKER">
-        <point>1,-2970</point>
+        <point>0,-2970</point>
         <point>33,-2010</point>
         <point>66,-1020</point>
         <point>100,0</point>
     </volume>
     <volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_EARPIECE"
-                                        ref="DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE"/>
+                                        ref="DEFAULT_NON_MUTABLE_EARPIECE_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
-                                        ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+                                        ref="DEFAULT_NON_MUTABLE_EXT_VOLUME_CURVE"/>
+    <volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
+                                        ref="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_HEADSET"
                                                ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_SPEAKER">
@@ -99,6 +109,8 @@
                                                ref="DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
                                                ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+    <volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
+                                               ref="DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_HEADSET">
         <point>0,-4200</point>
         <point>33,-2800</point>
@@ -119,6 +131,8 @@
     </volume>
     <volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
                                                 ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+    <volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
+                                                ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_HEADSET">
         <point>1,-3000</point>
         <point>33,-2600</point>
@@ -131,6 +145,8 @@
                                                    ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
                                                    ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+    <volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
+                                                   ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_HEADSET">
         <point>1,-3000</point>
         <point>33,-2600</point>
@@ -143,6 +159,8 @@
                                        ref="DEFAULT_SYSTEM_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
                                        ref="DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE"/>
+    <volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
+                                       ref="DEFAULT_HEARING_AID_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_HEADSET"
                                       ref="SILENT_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_SPEAKER"
@@ -151,14 +169,18 @@
                                       ref="SILENT_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
                                       ref="SILENT_VOLUME_CURVE"/>
+    <volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
+                                      ref="SILENT_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_HEADSET"
-                                                ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+                                                ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_SPEAKER"
-                                                ref="DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE"/>
+                                                ref="DEFAULT_NON_MUTABLE_SPEAKER_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_EARPIECE"
-                                                ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+                                                ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
-                                                ref="DEFAULT_MEDIA_VOLUME_CURVE"/>
+                                                ref="DEFAULT_NON_MUTABLE_VOLUME_CURVE"/>
+    <volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
+                                                ref="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_HEADSET"
                                             ref="FULL_SCALE_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_SPEAKER"
@@ -167,6 +189,8 @@
                                             ref="FULL_SCALE_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
                                             ref="FULL_SCALE_VOLUME_CURVE"/>
+    <volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
+                                            ref="FULL_SCALE_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_HEADSET"
                                         ref="FULL_SCALE_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_SPEAKER"
@@ -175,5 +199,7 @@
                                         ref="FULL_SCALE_VOLUME_CURVE"/>
     <volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"
                                         ref="FULL_SCALE_VOLUME_CURVE"/>
+    <volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_HEARING_AID"
+                                        ref="FULL_SCALE_VOLUME_CURVE"/>
 </volumes>
 
diff --git a/services/audiopolicy/config/default_volume_tables.xml b/services/audiopolicy/config/default_volume_tables.xml
index 9a22b1d..207be41 100644
--- a/services/audiopolicy/config/default_volume_tables.xml
+++ b/services/audiopolicy/config/default_volume_tables.xml
@@ -67,4 +67,63 @@
         <point>60,-2100</point>
         <point>100,-1000</point>
     </reference>
+    <reference name="DEFAULT_HEARING_AID_VOLUME_CURVE">
+    <!-- Default Hearing Aid Volume Curve -->
+        <point>1,-12700</point>
+        <point>20,-8000</point>
+        <point>60,-4000</point>
+        <point>100,0</point>
+    </reference>
+    <!-- **************************************************************** -->
+    <!-- Non-mutable default volume curves:                               -->
+    <!--     * first point is always for index 0                          -->
+    <!--     * attenuation is small enough that stream can still be heard -->
+    <reference name="DEFAULT_NON_MUTABLE_VOLUME_CURVE">
+    <!-- Default non-mutable reference Volume Curve -->
+    <!--        based on DEFAULT_MEDIA_VOLUME_CURVE -->
+        <point>0,-5800</point>
+        <point>20,-4000</point>
+        <point>60,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_NON_MUTABLE_HEADSET_VOLUME_CURVE">
+    <!--Default non-mutable Volume Curve for headset -->
+    <!--    based on DEFAULT_DEVICE_CATEGORY_HEADSET_VOLUME_CURVE -->
+        <point>0,-4950</point>
+        <point>33,-3350</point>
+        <point>66,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_NON_MUTABLE_SPEAKER_VOLUME_CURVE">
+    <!-- Default non-mutable Speaker Volume Curve -->
+    <!--    based on DEFAULT_DEVICE_CATEGORY_SPEAKER_VOLUME_CURVE -->
+        <point>0,-5800</point>
+        <point>20,-4000</point>
+        <point>60,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_NON_MUTABLE_EARPIECE_VOLUME_CURVE">
+    <!--Default non-mutable Volume Curve -->
+    <!--    based on DEFAULT_DEVICE_CATEGORY_EARPIECE_VOLUME_CURVE -->
+        <point>0,-4950</point>
+        <point>33,-3350</point>
+        <point>66,-1700</point>
+        <point>100,0</point>
+    </reference>
+    <reference name="DEFAULT_NON_MUTABLE_EXT_VOLUME_CURVE">
+    <!-- Default non-mutable Ext Media System Volume Curve -->
+    <!--     based on DEFAULT_DEVICE_CATEGORY_EXT_MEDIA_VOLUME_CURVE -->
+        <point>0,-5800</point>
+        <point>20,-4000</point>
+        <point>60,-2100</point>
+        <point>100,-1000</point>
+    </reference>
+    <reference name="DEFAULT_NON_MUTABLE_HEARING_AID_VOLUME_CURVE">
+    <!-- Default non-mutable Hearing Aid Volume Curve -->
+    <!--     based on DEFAULT_HEARING_AID_VOLUME_CURVE -->
+        <point>0,-12700</point>
+        <point>20,-8000</point>
+        <point>60,-4000</point>
+        <point>100,0</point>
+    </reference>
 </volumes>
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index be7f7ec..08bcf4d 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -266,7 +266,7 @@
         break;
 
     case STRATEGY_SONIFICATION_RESPECTFUL:
-        if (isInCall()) {
+        if (isInCall() || outputs.isStreamActiveLocally(AUDIO_STREAM_VOICE_CALL)) {
             device = getDeviceForStrategyInt(
                     STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs,
                     outputDeviceTypesToIgnore);
@@ -409,7 +409,7 @@
 
         // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
         // handleIncallSonification().
-        if (isInCall()) {
+        if (isInCall() || outputs.isStreamActiveLocally(AUDIO_STREAM_VOICE_CALL)) {
             device = getDeviceForStrategyInt(
                     STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs,
                     outputDeviceTypesToIgnore);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 73d92ac..29ec961 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -2141,6 +2141,7 @@
         }
         inputDesc->close();
     }
+    mInputRoutes.clear();
     mInputs.clear();
     SoundTrigger::setCaptureState(false);
     nextAudioPortGeneration();
@@ -3777,6 +3778,16 @@
         ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->type());
         status = NO_INIT;
     }
+    // If microphones address is empty, set it according to device type
+    for (size_t i = 0; i  < mAvailableInputDevices.size(); i++) {
+        if (mAvailableInputDevices[i]->mAddress.isEmpty()) {
+            if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
+                mAvailableInputDevices[i]->mAddress = String8(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
+            } else if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
+                mAvailableInputDevices[i]->mAddress = String8(AUDIO_BACK_MICROPHONE_ADDRESS);
+            }
+        }
+    }
 
     if (mPrimaryOutput == 0) {
         ALOGE("Failed to open primary output");
@@ -5106,7 +5117,8 @@
     }
 
     // in-call: always cap earpiece volume by voice volume + some low headroom
-    if ((stream != AUDIO_STREAM_VOICE_CALL) && (device & AUDIO_DEVICE_OUT_EARPIECE) && isInCall()) {
+    if ((stream != AUDIO_STREAM_VOICE_CALL) && (device & AUDIO_DEVICE_OUT_EARPIECE) &&
+            (isInCall() || mOutputs.isStreamActiveLocally(AUDIO_STREAM_VOICE_CALL))) {
         switch (stream) {
         case AUDIO_STREAM_SYSTEM:
         case AUDIO_STREAM_RING:
@@ -5116,8 +5128,11 @@
         case AUDIO_STREAM_ENFORCED_AUDIBLE:
         case AUDIO_STREAM_DTMF:
         case AUDIO_STREAM_ACCESSIBILITY: {
-            const float maxVoiceVolDb = computeVolume(AUDIO_STREAM_VOICE_CALL, index, device)
-                    + IN_CALL_EARPIECE_HEADROOM_DB;
+            int voiceVolumeIndex =
+                mVolumeCurves->getVolumeIndex(AUDIO_STREAM_VOICE_CALL, AUDIO_DEVICE_OUT_EARPIECE);
+            const float maxVoiceVolDb =
+                computeVolume(AUDIO_STREAM_VOICE_CALL, voiceVolumeIndex, AUDIO_DEVICE_OUT_EARPIECE)
+                + IN_CALL_EARPIECE_HEADROOM_DB;
             if (volumeDB > maxVoiceVolDb) {
                 ALOGV("computeVolume() stream %d at vol=%f overriden by stream %d at vol=%f",
                         stream, volumeDB, AUDIO_STREAM_VOICE_CALL, maxVoiceVolDb);
@@ -5141,7 +5156,8 @@
             AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
             AUDIO_DEVICE_OUT_WIRED_HEADSET |
             AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
-            AUDIO_DEVICE_OUT_USB_HEADSET)) &&
+            AUDIO_DEVICE_OUT_USB_HEADSET |
+            AUDIO_DEVICE_OUT_HEARING_AID)) &&
         ((stream_strategy == STRATEGY_SONIFICATION)
                 || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL)
                 || (stream == AUDIO_STREAM_SYSTEM)
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 90a5a0f..082923a 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -273,7 +273,7 @@
 void AudioPolicyService::NotificationClient::onDynamicPolicyMixStateUpdate(
         const String8& regId, int32_t state)
 {
-    if (mAudioPolicyServiceClient != 0 && mUid < AID_APP_START) {
+    if (mAudioPolicyServiceClient != 0 && (mUid % AID_USER_OFFSET) < AID_APP_START) {
         mAudioPolicyServiceClient->onDynamicPolicyMixStateUpdate(regId, state);
     }
 }
@@ -283,7 +283,7 @@
         const audio_config_base_t *clientConfig, const audio_config_base_t *deviceConfig,
         audio_patch_handle_t patchHandle)
 {
-    if (mAudioPolicyServiceClient != 0 && mUid < AID_APP_START) {
+    if (mAudioPolicyServiceClient != 0 && (mUid % AID_USER_OFFSET) < AID_APP_START) {
         mAudioPolicyServiceClient->onRecordingConfigurationUpdate(event, clientInfo,
                 clientConfig, deviceConfig, patchHandle);
     }
@@ -505,91 +505,129 @@
             | ActivityManager::UID_OBSERVER_ACTIVE,
             ActivityManager::PROCESS_STATE_UNKNOWN,
             String16("audioserver"));
+    status_t res = am.linkToDeath(this);
+    if (!res) {
+        Mutex::Autolock _l(mLock);
+        mObserverRegistered = true;
+    } else {
+        ALOGE("UidPolicy::registerSelf linkToDeath failed: %d", res);
+        am.unregisterUidObserver(this);
+    }
 }
 
 void AudioPolicyService::UidPolicy::unregisterSelf() {
     ActivityManager am;
+    am.unlinkToDeath(this);
     am.unregisterUidObserver(this);
+    Mutex::Autolock _l(mLock);
+    mObserverRegistered = false;
 }
 
-void AudioPolicyService::UidPolicy::onUidGone(uid_t uid, __unused bool disabled) {
-    onUidIdle(uid, disabled);
-}
-
-void AudioPolicyService::UidPolicy::onUidActive(uid_t uid) {
-    {
-        Mutex::Autolock _l(mUidLock);
-        mActiveUids.insert(uid);
-    }
-    sp<AudioPolicyService> service = mService.promote();
-    if (service != nullptr) {
-        service->setRecordSilenced(uid, false);
-    }
-}
-
-void AudioPolicyService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) {
-    bool deleted = false;
-    {
-        Mutex::Autolock _l(mUidLock);
-        if (mActiveUids.erase(uid) > 0) {
-            deleted = true;
-        }
-    }
-    if (deleted) {
-        sp<AudioPolicyService> service = mService.promote();
-        if (service != nullptr) {
-            service->setRecordSilenced(uid, true);
-        }
-    }
-}
-
-void AudioPolicyService::UidPolicy::addOverrideUid(uid_t uid, bool active) {
-    updateOverrideUid(uid, active, true);
-}
-
-void AudioPolicyService::UidPolicy::removeOverrideUid(uid_t uid) {
-    updateOverrideUid(uid, false, false);
-}
-
-void AudioPolicyService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) {
-    bool wasActive = false;
-    bool isActive = false;
-    {
-        Mutex::Autolock _l(mUidLock);
-        wasActive = isUidActiveLocked(uid);
-        mOverrideUids.erase(uid);
-        if (insert) {
-            mOverrideUids.insert(std::pair<uid_t, bool>(uid, active));
-        }
-        isActive = isUidActiveLocked(uid);
-    }
-    if (wasActive != isActive) {
-        sp<AudioPolicyService> service = mService.promote();
-        if (service != nullptr) {
-            service->setRecordSilenced(uid, !isActive);
-        }
-    }
+void AudioPolicyService::UidPolicy::binderDied(__unused const wp<IBinder> &who) {
+    Mutex::Autolock _l(mLock);
+    mCachedUids.clear();
+    mObserverRegistered = false;
 }
 
 bool AudioPolicyService::UidPolicy::isUidActive(uid_t uid) {
-    // Non-app UIDs are considered always active
-    if (uid < FIRST_APPLICATION_UID) {
-        return true;
+    if (isServiceUid(uid)) return true;
+    bool needToReregister = false;
+    {
+        Mutex::Autolock _l(mLock);
+        needToReregister = !mObserverRegistered;
     }
-    Mutex::Autolock _l(mUidLock);
-    return isUidActiveLocked(uid);
+    if (needToReregister) {
+        // Looks like ActivityManager has died previously, attempt to re-register.
+        registerSelf();
+    }
+    {
+        Mutex::Autolock _l(mLock);
+        auto overrideIter = mOverrideUids.find(uid);
+        if (overrideIter != mOverrideUids.end()) {
+            return overrideIter->second;
+        }
+        // In an absense of the ActivityManager, assume everything to be active.
+        if (!mObserverRegistered) return true;
+        auto cacheIter = mCachedUids.find(uid);
+        if (cacheIter != mCachedUids.end()) {
+            return cacheIter->second;
+        }
+    }
+    ActivityManager am;
+    bool active = am.isUidActive(uid, String16("audioserver"));
+    {
+        Mutex::Autolock _l(mLock);
+        mCachedUids.insert(std::pair<uid_t, bool>(uid, active));
+    }
+    return active;
 }
 
-bool AudioPolicyService::UidPolicy::isUidActiveLocked(uid_t uid) {
-    // Non-app UIDs are considered always active
-    if (uid < FIRST_APPLICATION_UID) {
-        return true;
+void AudioPolicyService::UidPolicy::onUidActive(uid_t uid) {
+    updateUidCache(uid, true, true);
+}
+
+void AudioPolicyService::UidPolicy::onUidGone(uid_t uid, __unused bool disabled) {
+    updateUidCache(uid, false, false);
+}
+
+void AudioPolicyService::UidPolicy::onUidIdle(uid_t uid, __unused bool disabled) {
+    updateUidCache(uid, false, true);
+}
+
+bool AudioPolicyService::UidPolicy::isServiceUid(uid_t uid) const {
+    return uid % AID_USER_OFFSET < AID_APP_START;
+}
+
+void AudioPolicyService::UidPolicy::notifyService(uid_t uid, bool active) {
+    sp<AudioPolicyService> service = mService.promote();
+    if (service != nullptr) {
+        service->setRecordSilenced(uid, !active);
     }
-    auto it = mOverrideUids.find(uid);
-    if (it != mOverrideUids.end()) {
-        return it->second;
+}
+
+void AudioPolicyService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) {
+    if (isServiceUid(uid)) return;
+    bool wasOverridden = false, wasActive = false;
+    {
+        Mutex::Autolock _l(mLock);
+        updateUidLocked(&mOverrideUids, uid, active, insert, &wasOverridden, &wasActive);
     }
-    return mActiveUids.find(uid) != mActiveUids.end();
+    if (!wasOverridden && insert) {
+        notifyService(uid, active);  // Started to override.
+    } else if (wasOverridden && !insert) {
+        notifyService(uid, isUidActive(uid));  // Override ceased, notify with ground truth.
+    } else if (wasActive != active) {
+        notifyService(uid, active);  // Override updated.
+    }
+}
+
+void AudioPolicyService::UidPolicy::updateUidCache(uid_t uid, bool active, bool insert) {
+    if (isServiceUid(uid)) return;
+    bool wasActive = false;
+    {
+        Mutex::Autolock _l(mLock);
+        updateUidLocked(&mCachedUids, uid, active, insert, nullptr, &wasActive);
+        // Do not notify service if currently overridden.
+        if (mOverrideUids.find(uid) != mOverrideUids.end()) return;
+    }
+    bool nowActive = active && insert;
+    if (wasActive != nowActive) notifyService(uid, nowActive);
+}
+
+void AudioPolicyService::UidPolicy::updateUidLocked(std::unordered_map<uid_t, bool> *uids,
+        uid_t uid, bool active, bool insert, bool *wasThere, bool *wasActive) {
+    auto it = uids->find(uid);
+    if (it != uids->end()) {
+        if (wasThere != nullptr) *wasThere = true;
+        if (wasActive != nullptr) *wasActive = it->second;
+        if (insert) {
+            it->second = active;
+        } else {
+            uids->erase(it);
+        }
+    } else if (insert) {
+        uids->insert(std::pair<uid_t, bool>(uid, active));
+    }
 }
 
 // -----------  AudioPolicyService::AudioCommandThread implementation ----------
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index bfa3ef4..b3bc12b 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -35,7 +35,6 @@
 #include "managerdefault/AudioPolicyManager.h"
 
 #include <unordered_map>
-#include <unordered_set>
 
 namespace android {
 
@@ -264,31 +263,40 @@
     // transparently handles recording while the UID transitions between idle/active state
     // avoiding to get stuck in a state receiving non-empty buffers while idle or in a state
     // receiving empty buffers while active.
-    class UidPolicy : public BnUidObserver {
+    class UidPolicy : public BnUidObserver, public virtual IBinder::DeathRecipient {
     public:
         explicit UidPolicy(wp<AudioPolicyService> service)
-                : mService(service) {}
+                : mService(service), mObserverRegistered(false) {}
 
         void registerSelf();
         void unregisterSelf();
 
+        // IBinder::DeathRecipient implementation
+        void binderDied(const wp<IBinder> &who) override;
+
         bool isUidActive(uid_t uid);
 
-        void onUidGone(uid_t uid, bool disabled);
-        void onUidActive(uid_t uid);
-        void onUidIdle(uid_t uid, bool disabled);
+        // BnUidObserver implementation
+        void onUidActive(uid_t uid) override;
+        void onUidGone(uid_t uid, bool disabled) override;
+        void onUidIdle(uid_t uid, bool disabled) override;
 
-        void addOverrideUid(uid_t uid, bool active);
-        void removeOverrideUid(uid_t uid);
+        void addOverrideUid(uid_t uid, bool active) { updateOverrideUid(uid, active, true); }
+        void removeOverrideUid(uid_t uid) { updateOverrideUid(uid, false, false); }
 
     private:
-        bool isUidActiveLocked(uid_t uid);
+        bool isServiceUid(uid_t uid) const;
+        void notifyService(uid_t uid, bool active);
         void updateOverrideUid(uid_t uid, bool active, bool insert);
+        void updateUidCache(uid_t uid, bool active, bool insert);
+        void updateUidLocked(std::unordered_map<uid_t, bool> *uids,
+                uid_t uid, bool active, bool insert, bool *wasThere, bool *wasActive);
 
-        Mutex mUidLock;
         wp<AudioPolicyService> mService;
-        std::unordered_set<uid_t> mActiveUids;
+        Mutex mLock;
+        bool mObserverRegistered;
         std::unordered_map<uid_t, bool> mOverrideUids;
+        std::unordered_map<uid_t, bool> mCachedUids;
     };
 
     // Thread used for tone playback and to send audio config commands to audio flinger
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index fb9b0ba..714d50f 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -904,7 +904,7 @@
     }
 
     // Make sure the UID is in an active state to use the camera
-    if (!mUidPolicy->isUidActive(callingUid)) {
+    if (!mUidPolicy->isUidActive(callingUid, String16(clientName8))) {
         ALOGE("Access Denial: can't use the camera from an idle UID pid=%d, uid=%d",
             clientPid, clientUid);
         return STATUS_ERROR_FMT(ERROR_DISABLED,
@@ -1999,14 +1999,17 @@
 // A reference count is kept to determine when we will actually release the
 // media players.
 
-MediaPlayer* CameraService::newMediaPlayer(const char *file) {
-    MediaPlayer* mp = new MediaPlayer();
-    if (mp->setDataSource(NULL /* httpService */, file, NULL) == NO_ERROR) {
+sp<MediaPlayer> CameraService::newMediaPlayer(const char *file) {
+    sp<MediaPlayer> mp = new MediaPlayer();
+    status_t error;
+    if ((error = mp->setDataSource(NULL /* httpService */, file, NULL)) == NO_ERROR) {
         mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
-        mp->prepare();
-    } else {
+        error = mp->prepare();
+    }
+    if (error != NO_ERROR) {
         ALOGE("Failed to load CameraService sounds: %s", file);
-        delete mp;
+        mp->disconnect();
+        mp.clear();
         return nullptr;
     }
     return mp;
@@ -2420,12 +2423,12 @@
     }
 }
 
-bool CameraService::UidPolicy::isUidActive(uid_t uid) {
+bool CameraService::UidPolicy::isUidActive(uid_t uid, String16 callingPackage) {
     Mutex::Autolock _l(mUidLock);
-    return isUidActiveLocked(uid);
+    return isUidActiveLocked(uid, callingPackage);
 }
 
-bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid) {
+bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid, String16 callingPackage) {
     // Non-app UIDs are considered always active
     // If activity manager is unreachable, assume everything is active
     if (uid < FIRST_APPLICATION_UID || !mRegistered) {
@@ -2435,15 +2438,31 @@
     if (it != mOverrideUids.end()) {
         return it->second;
     }
-    return mActiveUids.find(uid) != mActiveUids.end();
+    bool active = mActiveUids.find(uid) != mActiveUids.end();
+    if (!active) {
+        // We want active UIDs to always access camera with their first attempt since
+        // there is no guarantee the app is robustly written and would retry getting
+        // the camera on failure. The inverse case is not a problem as we would take
+        // camera away soon once we get the callback that the uid is no longer active.
+        ActivityManager am;
+        // Okay to access with a lock held as UID changes are dispatched without
+        // a lock and we are a higher level component.
+        active = am.isUidActive(uid, callingPackage);
+        if (active) {
+            // Now that we found out the UID is actually active, cache that
+            mActiveUids.insert(uid);
+        }
+    }
+    return active;
 }
 
-void CameraService::UidPolicy::UidPolicy::addOverrideUid(uid_t uid, bool active) {
-    updateOverrideUid(uid, active, true);
+void CameraService::UidPolicy::UidPolicy::addOverrideUid(uid_t uid,
+        String16 callingPackage, bool active) {
+    updateOverrideUid(uid, callingPackage, active, true);
 }
 
-void CameraService::UidPolicy::removeOverrideUid(uid_t uid) {
-    updateOverrideUid(uid, false, false);
+void CameraService::UidPolicy::removeOverrideUid(uid_t uid, String16 callingPackage) {
+    updateOverrideUid(uid, callingPackage, false, false);
 }
 
 void CameraService::UidPolicy::binderDied(const wp<IBinder>& /*who*/) {
@@ -2453,17 +2472,18 @@
     mActiveUids.clear();
 }
 
-void CameraService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) {
+void CameraService::UidPolicy::updateOverrideUid(uid_t uid, String16 callingPackage,
+        bool active, bool insert) {
     bool wasActive = false;
     bool isActive = false;
     {
         Mutex::Autolock _l(mUidLock);
-        wasActive = isUidActiveLocked(uid);
+        wasActive = isUidActiveLocked(uid, callingPackage);
         mOverrideUids.erase(uid);
         if (insert) {
             mOverrideUids.insert(std::pair<uid_t, bool>(uid, active));
         }
-        isActive = isUidActiveLocked(uid);
+        isActive = isUidActiveLocked(uid, callingPackage);
     }
     if (wasActive != isActive && !isActive) {
         sp<CameraService> service = mService.promote();
@@ -2996,7 +3016,7 @@
         ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string());
         return BAD_VALUE;
     }
-    mUidPolicy->addOverrideUid(uid, active);
+    mUidPolicy->addOverrideUid(uid, args[1], active);
     return NO_ERROR;
 }
 
@@ -3008,7 +3028,7 @@
         dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
         return BAD_VALUE;
     }
-    mUidPolicy->removeOverrideUid(uid);
+    mUidPolicy->removeOverrideUid(uid, args[1]);
     return NO_ERROR;
 }
 
@@ -3020,7 +3040,7 @@
         dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
         return BAD_VALUE;
     }
-    if (mUidPolicy->isUidActive(uid)) {
+    if (mUidPolicy->isUidActive(uid, args[1])) {
         return dprintf(out, "active\n");
     } else {
         return dprintf(out, "idle\n");
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 86a2b81..8d4bcdb 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -526,20 +526,20 @@
         void registerSelf();
         void unregisterSelf();
 
-        bool isUidActive(uid_t uid);
+        bool isUidActive(uid_t uid, String16 callingPackage);
 
         void onUidGone(uid_t uid, bool disabled);
         void onUidActive(uid_t uid);
         void onUidIdle(uid_t uid, bool disabled);
 
-        void addOverrideUid(uid_t uid, bool active);
-        void removeOverrideUid(uid_t uid);
+        void addOverrideUid(uid_t uid, String16 callingPackage, bool active);
+        void removeOverrideUid(uid_t uid, String16 callingPackage);
 
         // IBinder::DeathRecipient implementation
         virtual void binderDied(const wp<IBinder> &who);
     private:
-        bool isUidActiveLocked(uid_t uid);
-        void updateOverrideUid(uid_t uid, bool active, bool insert);
+        bool isUidActiveLocked(uid_t uid, String16 callingPackage);
+        void updateOverrideUid(uid_t uid, String16 callingPackage, bool active, bool insert);
 
         Mutex mUidLock;
         bool mRegistered;
@@ -736,7 +736,7 @@
     std::vector<std::string> mNormalDeviceIds;
 
     // sounds
-    MediaPlayer*        newMediaPlayer(const char *file);
+    sp<MediaPlayer>     newMediaPlayer(const char *file);
 
     Mutex               mSoundLock;
     sp<MediaPlayer>     mSoundPlayer[NUM_SOUNDS];
diff --git a/services/codec2/Android.bp b/services/codec2/Android.bp
deleted file mode 100644
index 4cfca1d..0000000
--- a/services/codec2/Android.bp
+++ /dev/null
@@ -1,101 +0,0 @@
-cc_binary {
-    name: "vendor.google.media.c2@1.0-service",
-    defaults: ["hidl_defaults"],
-    soc_specific: true,
-    relative_install_path: "hw",
-    srcs: [
-        "vendor.cpp",
-    ],
-
-    init_rc: ["vendor.google.media.c2@1.0-service.rc"],
-
-    shared_libs: [
-        "vendor.google.media.c2@1.0",
-        "libavservices_minijail_vendor",
-        "libhidlbase",
-        "libhidltransport",
-        "libhwbinder",
-        "liblog",
-        "libstagefright_codec2_hidl@1.0",
-        "libstagefright_codec2_vndk",
-        "libutils",
-    ],
-
-    arch: {
-        arm: {
-            required: ["codec2.vendor.base.policy"],
-        },
-        x86: {
-            required: ["codec2.vendor.base.policy"],
-        },
-    },
-
-    compile_multilib: "32",
-}
-
-cc_binary {
-    name: "vendor.google.media.c2@1.0-service-system",
-    defaults: ["hidl_defaults"],
-    relative_install_path: "hw",
-    srcs: [
-        "system.cpp",
-    ],
-
-    init_rc: ["vendor.google.media.c2@1.0-service-system.rc"],
-
-    shared_libs: [
-        "vendor.google.media.c2@1.0",
-        "libavservices_minijail",
-        "libcutils",
-        "libhidlbase",
-        "libhidltransport",
-        "libhwbinder",
-        "liblog",
-        "libstagefright_codec2_hidl@1.0",
-        "libstagefright_codec2_vndk",
-        "libutils",
-        "libv4l2_c2componentstore",
-    ],
-
-    arch: {
-        arm: {
-            required: ["codec2.system.base.policy"],
-        },
-        x86: {
-            required: ["codec2.system.base.policy"],
-        },
-    },
-
-    required: [
-        "libstagefright_soft_c2avcdec",
-        "libstagefright_soft_c2avcenc",
-        "libstagefright_soft_c2aacdec",
-        "libstagefright_soft_c2aacenc",
-        "libstagefright_soft_c2amrnbdec",
-       	"libstagefright_soft_c2amrnbenc",
-       	"libstagefright_soft_c2amrwbdec",
-       	"libstagefright_soft_c2amrwbenc",
-       	"libstagefright_soft_c2hevcdec",
-       	"libstagefright_soft_c2g711alawdec",
-       	"libstagefright_soft_c2g711mlawdec",
-       	"libstagefright_soft_c2mpeg2dec",
-       	"libstagefright_soft_c2h263dec",
-       	"libstagefright_soft_c2h263enc",
-       	"libstagefright_soft_c2mpeg4dec",
-       	"libstagefright_soft_c2mpeg4enc",
-       	"libstagefright_soft_c2mp3dec",
-       	"libstagefright_soft_c2vorbisdec",
-       	"libstagefright_soft_c2opusdec",
-       	"libstagefright_soft_c2vp8dec",
-       	"libstagefright_soft_c2vp9dec",
-       	"libstagefright_soft_c2vp8enc",
-       	"libstagefright_soft_c2vp9enc",
-       	"libstagefright_soft_c2rawdec",
-       	"libstagefright_soft_c2flacdec",
-       	"libstagefright_soft_c2flacenc",
-       	"libstagefright_soft_c2gsmdec",
-    ],
-
-    compile_multilib: "32",
-}
-
diff --git a/services/codec2/Android.mk b/services/codec2/Android.mk
deleted file mode 100644
index fa49875..0000000
--- a/services/codec2/Android.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-# vendor service seccomp policy
-ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), x86 x86_64 arm arm64))
-include $(CLEAR_VARS)
-LOCAL_MODULE := codec2.vendor.base.policy
-LOCAL_VENDOR_MODULE := true
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/seccomp_policy
-LOCAL_REQUIRED_MODULES := crash_dump.policy
-ifdef TARGET_2ND_ARCH
-    ifneq ($(TARGET_TRANSLATE_2ND_ARCH),true)
-        LOCAL_SRC_FILES := seccomp_policy/codec2.vendor.base-$(TARGET_2ND_ARCH).policy
-    else
-        LOCAL_SRC_FILES := seccomp_policy/codec2.vendor.base-$(TARGET_ARCH).policy
-    endif
-else
-    LOCAL_SRC_FILES := seccomp_policy/codec2.vendor.base-$(TARGET_ARCH).policy
-endif
-include $(BUILD_PREBUILT)
-endif
-
-# system service seccomp policy
-ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), x86 x86_64 arm arm64))
-include $(CLEAR_VARS)
-LOCAL_MODULE := codec2.system.base.policy
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/seccomp_policy
-LOCAL_REQUIRED_MODULES := crash_dump.policy
-ifdef TARGET_2ND_ARCH
-    ifneq ($(TARGET_TRANSLATE_2ND_ARCH),true)
-        LOCAL_SRC_FILES := seccomp_policy/codec2.system.base-$(TARGET_2ND_ARCH).policy
-    else
-        LOCAL_SRC_FILES := seccomp_policy/codec2.system.base-$(TARGET_ARCH).policy
-    endif
-else
-    LOCAL_SRC_FILES := seccomp_policy/codec2.system.base-$(TARGET_ARCH).policy
-endif
-include $(BUILD_PREBUILT)
-endif
-
-include $(call all-makefiles-under, $(LOCAL_PATH))
-
diff --git a/services/codec2/seccomp_policy/codec2.system.base-arm.policy b/services/codec2/seccomp_policy/codec2.system.base-arm.policy
deleted file mode 100644
index d5871d1..0000000
--- a/services/codec2/seccomp_policy/codec2.system.base-arm.policy
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2018 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.
-
-# Organized by frequency of systemcall - in descending order for
-# best performance.
-futex: 1
-ioctl: 1
-write: 1
-prctl: 1
-clock_gettime: 1
-getpriority: 1
-read: 1
-close: 1
-writev: 1
-dup: 1
-ppoll: 1
-mmap2: 1
-getrandom: 1
-
-# mremap: Ensure |flags| are (MREMAP_MAYMOVE | MREMAP_FIXED) TODO: Once minijail
-# parser support for '<' is in this needs to be modified to also prevent
-# |old_address| and |new_address| from touching the exception vector page, which
-# on ARM is statically loaded at 0xffff 0000. See
-# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
-# for more details.
-mremap: arg3 == 3
-munmap: 1
-mprotect: 1
-madvise: 1
-openat: 1
-sigaltstack: 1
-clone: 1
-setpriority: 1
-getuid32: 1
-fstat64: 1
-fstatfs64: 1
-pread64: 1
-faccessat: 1
-readlinkat: 1
-exit: 1
-rt_sigprocmask: 1
-set_tid_address: 1
-restart_syscall: 1
-exit_group: 1
-rt_sigreturn: 1
-pipe2: 1
-gettimeofday: 1
-sched_yield: 1
-nanosleep: 1
-lseek: 1
-_llseek: 1
-sched_get_priority_max: 1
-sched_get_priority_min: 1
-statfs64: 1
-sched_setscheduler: 1
-fstatat64: 1
-ugetrlimit: 1
-getdents64: 1
-getrandom: 1
-
-@include /system/etc/seccomp_policy/crash_dump.arm.policy
-
diff --git a/services/codec2/seccomp_policy/codec2.system.base-x86.policy b/services/codec2/seccomp_policy/codec2.system.base-x86.policy
deleted file mode 100644
index 20c7625..0000000
--- a/services/codec2/seccomp_policy/codec2.system.base-x86.policy
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (C) 2018 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.
-
-read: 1
-mprotect: 1
-prctl: 1
-openat: 1
-getuid32: 1
-writev: 1
-ioctl: 1
-close: 1
-mmap2: 1
-fstat64: 1
-madvise: 1
-fstatat64: 1
-futex: 1
-munmap: 1
-faccessat: 1
-_llseek: 1
-lseek: 1
-clone: 1
-sigaltstack: 1
-setpriority: 1
-restart_syscall: 1
-exit: 1
-exit_group: 1
-rt_sigreturn: 1
-ugetrlimit: 1
-readlinkat: 1
-_llseek: 1
-fstatfs64: 1
-pread64: 1
-mremap: 1
-dup: 1
-set_tid_address: 1
-write: 1
-nanosleep: 1
-
-# Required by AddressSanitizer
-gettid: 1
-sched_yield: 1
-getpid: 1
-gettid: 1
-
-@include /system/etc/seccomp_policy/crash_dump.x86.policy
-
diff --git a/services/codec2/seccomp_policy/codec2.vendor.base-arm.policy b/services/codec2/seccomp_policy/codec2.vendor.base-arm.policy
deleted file mode 100644
index d5871d1..0000000
--- a/services/codec2/seccomp_policy/codec2.vendor.base-arm.policy
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright (C) 2018 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.
-
-# Organized by frequency of systemcall - in descending order for
-# best performance.
-futex: 1
-ioctl: 1
-write: 1
-prctl: 1
-clock_gettime: 1
-getpriority: 1
-read: 1
-close: 1
-writev: 1
-dup: 1
-ppoll: 1
-mmap2: 1
-getrandom: 1
-
-# mremap: Ensure |flags| are (MREMAP_MAYMOVE | MREMAP_FIXED) TODO: Once minijail
-# parser support for '<' is in this needs to be modified to also prevent
-# |old_address| and |new_address| from touching the exception vector page, which
-# on ARM is statically loaded at 0xffff 0000. See
-# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Babfeega.html
-# for more details.
-mremap: arg3 == 3
-munmap: 1
-mprotect: 1
-madvise: 1
-openat: 1
-sigaltstack: 1
-clone: 1
-setpriority: 1
-getuid32: 1
-fstat64: 1
-fstatfs64: 1
-pread64: 1
-faccessat: 1
-readlinkat: 1
-exit: 1
-rt_sigprocmask: 1
-set_tid_address: 1
-restart_syscall: 1
-exit_group: 1
-rt_sigreturn: 1
-pipe2: 1
-gettimeofday: 1
-sched_yield: 1
-nanosleep: 1
-lseek: 1
-_llseek: 1
-sched_get_priority_max: 1
-sched_get_priority_min: 1
-statfs64: 1
-sched_setscheduler: 1
-fstatat64: 1
-ugetrlimit: 1
-getdents64: 1
-getrandom: 1
-
-@include /system/etc/seccomp_policy/crash_dump.arm.policy
-
diff --git a/services/codec2/seccomp_policy/codec2.vendor.base-x86.policy b/services/codec2/seccomp_policy/codec2.vendor.base-x86.policy
deleted file mode 100644
index 20c7625..0000000
--- a/services/codec2/seccomp_policy/codec2.vendor.base-x86.policy
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (C) 2018 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.
-
-read: 1
-mprotect: 1
-prctl: 1
-openat: 1
-getuid32: 1
-writev: 1
-ioctl: 1
-close: 1
-mmap2: 1
-fstat64: 1
-madvise: 1
-fstatat64: 1
-futex: 1
-munmap: 1
-faccessat: 1
-_llseek: 1
-lseek: 1
-clone: 1
-sigaltstack: 1
-setpriority: 1
-restart_syscall: 1
-exit: 1
-exit_group: 1
-rt_sigreturn: 1
-ugetrlimit: 1
-readlinkat: 1
-_llseek: 1
-fstatfs64: 1
-pread64: 1
-mremap: 1
-dup: 1
-set_tid_address: 1
-write: 1
-nanosleep: 1
-
-# Required by AddressSanitizer
-gettid: 1
-sched_yield: 1
-getpid: 1
-gettid: 1
-
-@include /system/etc/seccomp_policy/crash_dump.x86.policy
-
diff --git a/services/codec2/system.cpp b/services/codec2/system.cpp
deleted file mode 100644
index d6ec644..0000000
--- a/services/codec2/system.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright 2018 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 "vendor.google.media.c2@1.0-service"
-
-#include <C2PlatformSupport.h>
-#include <C2V4l2Support.h>
-#include <cutils/properties.h>
-
-#include <codec2/hidl/1.0/ComponentStore.h>
-#include <hidl/HidlTransportSupport.h>
-#include <minijail.h>
-
-// TODO: Remove this once "setenv()" call is removed.
-#include <stdlib.h>
-
-// This is created by module "codec2.system.base.policy". This can be modified.
-static constexpr char kBaseSeccompPolicyPath[] =
-        "/system/etc/seccomp_policy/codec2.system.base.policy";
-
-// Additional device-specific seccomp permissions can be added in this file.
-static constexpr char kExtSeccompPolicyPath[] =
-        "/system/etc/seccomp_policy/codec2.system.ext.policy";
-
-int main(int /* argc */, char** /* argv */) {
-    ALOGD("vendor.google.media.c2@1.0-service-system starting...");
-
-    // TODO: Remove this when all the build settings and sepolicies are in place.
-    setenv("TREBLE_TESTING_OVERRIDE", "true", true);
-
-    signal(SIGPIPE, SIG_IGN);
-    android::SetUpMinijail(kBaseSeccompPolicyPath, kExtSeccompPolicyPath);
-
-    // Extra threads may be needed to handle a stacked IPC sequence that
-    // contains alternating binder and hwbinder calls. (See b/35283480.)
-    android::hardware::configureRpcThreadpool(8, true /* callerWillJoin */);
-
-    // Create IComponentStore service.
-    {
-        using namespace ::vendor::google::media::c2::V1_0;
-        android::sp<IComponentStore> store =
-                new implementation::ComponentStore(
-                android::GetCodec2PlatformComponentStore());
-        if (store == nullptr) {
-            ALOGE("Cannot create Codec2's IComponentStore system service.");
-        } else {
-            if (store->registerAsService("system") != android::OK) {
-                ALOGE("Cannot register Codec2's "
-                        "IComponentStore system service.");
-            } else {
-                ALOGI("Codec2's IComponentStore system service created.");
-            }
-        }
-
-        // To enable the v4l2 service, set this sysprop and add "v4l2" instance
-        // to the system manifest file.
-        if (property_get_bool("debug.stagefright.ccodec_v4l2", false)) {
-            store = new implementation::ComponentStore(
-                    android::GetCodec2VDAComponentStore());
-            if (store == nullptr) {
-                ALOGE("Cannot create Codec2's IComponentStore V4L2 service.");
-            } else {
-                if (store->registerAsService("v4l2") != android::OK) {
-                    ALOGE("Cannot register Codec2's "
-                            "IComponentStore V4L2 service.");
-                } else {
-                    ALOGI("Codec2's IComponentStore V4L2 service created.");
-                }
-            }
-        }
-    }
-
-    android::hardware::joinRpcThreadpool();
-    return 0;
-}
-
diff --git a/services/codec2/vendor.cpp b/services/codec2/vendor.cpp
deleted file mode 100644
index 60b51e2..0000000
--- a/services/codec2/vendor.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2018 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 "vendor.google.media.c2@1.0-service"
-
-#include <codec2/hidl/1.0/ComponentStore.h>
-#include <hidl/HidlTransportSupport.h>
-#include <minijail.h>
-
-#include <C2Component.h>
-
-// TODO: Remove this once "setenv()" call is removed.
-#include <stdlib.h>
-
-// This is created by module "codec2.vendor.base.policy". This can be modified.
-static constexpr char kBaseSeccompPolicyPath[] =
-        "/vendor/etc/seccomp_policy/codec2.vendor.base.policy";
-
-// Additional device-specific seccomp permissions can be added in this file.
-static constexpr char kExtSeccompPolicyPath[] =
-        "/vendor/etc/seccomp_policy/codec2.vendor.ext.policy";
-
-// TODO: Replace with a valid C2ComponentStore implementation.
-class DummyC2Store : public C2ComponentStore {
-public:
-    DummyC2Store() = default;
-
-    virtual ~DummyC2Store() override = default;
-
-    virtual C2String getName() const override {
-        return "default";
-    }
-
-    virtual c2_status_t createComponent(
-            C2String /*name*/,
-            std::shared_ptr<C2Component>* const /*component*/) override {
-        return C2_NOT_FOUND;
-    }
-
-    virtual c2_status_t createInterface(
-            C2String /* name */,
-            std::shared_ptr<C2ComponentInterface>* const /* interface */) override {
-        return C2_NOT_FOUND;
-    }
-
-    virtual std::vector<std::shared_ptr<const C2Component::Traits>>
-            listComponents() override {
-        return {};
-    }
-
-    virtual c2_status_t copyBuffer(
-            std::shared_ptr<C2GraphicBuffer> /* src */,
-            std::shared_ptr<C2GraphicBuffer> /* dst */) override {
-        return C2_OMITTED;
-    }
-
-    virtual c2_status_t query_sm(
-        const std::vector<C2Param*>& /* stackParams */,
-        const std::vector<C2Param::Index>& /* heapParamIndices */,
-        std::vector<std::unique_ptr<C2Param>>* const /* heapParams */) const override {
-        return C2_OMITTED;
-    }
-
-    virtual c2_status_t config_sm(
-            const std::vector<C2Param*>& /* params */,
-            std::vector<std::unique_ptr<C2SettingResult>>* const /* failures */) override {
-        return C2_OMITTED;
-    }
-
-    virtual std::shared_ptr<C2ParamReflector> getParamReflector() const override {
-        return nullptr;
-    }
-
-    virtual c2_status_t querySupportedParams_nb(
-            std::vector<std::shared_ptr<C2ParamDescriptor>>* const /* params */) const override {
-        return C2_OMITTED;
-    }
-
-    virtual c2_status_t querySupportedValues_sm(
-            std::vector<C2FieldSupportedValuesQuery>& /* fields */) const override {
-        return C2_OMITTED;
-    }
-};
-
-int main(int /* argc */, char** /* argv */) {
-    ALOGD("vendor.google.media.c2@1.0-service starting...");
-
-    // TODO: Remove this when all the build settings and sepolicies are in place.
-    setenv("TREBLE_TESTING_OVERRIDE", "true", true);
-
-    signal(SIGPIPE, SIG_IGN);
-    android::SetUpMinijail(kBaseSeccompPolicyPath, kExtSeccompPolicyPath);
-
-    // Extra threads may be needed to handle a stacked IPC sequence that
-    // contains alternating binder and hwbinder calls. (See b/35283480.)
-    android::hardware::configureRpcThreadpool(8, true /* callerWillJoin */);
-
-    // Create IComponentStore service.
-    {
-        using namespace ::vendor::google::media::c2::V1_0;
-        android::sp<IComponentStore> store =
-                new implementation::ComponentStore(
-                // TODO: Replace this with a valid C2ComponentStore
-                // implementation.
-                std::make_shared<DummyC2Store>());
-        if (store == nullptr) {
-            ALOGE("Cannot create Codec2's IComponentStore service.");
-        } else {
-            if (store->registerAsService("default") != android::OK) {
-                ALOGE("Cannot register Codec2's "
-                        "IComponentStore service.");
-            } else {
-                ALOGI("Codec2's IComponentStore service created.");
-            }
-        }
-    }
-
-    android::hardware::joinRpcThreadpool();
-    return 0;
-}
-
diff --git a/services/codec2/vendor.google.media.c2@1.0-service-system.rc b/services/codec2/vendor.google.media.c2@1.0-service-system.rc
deleted file mode 100644
index 0577a1d..0000000
--- a/services/codec2/vendor.google.media.c2@1.0-service-system.rc
+++ /dev/null
@@ -1,7 +0,0 @@
-service vendor-google-media-c2-system-hal-1-0 /system/bin/hw/vendor.google.media.c2@1.0-service-system
-    class hal
-    user media
-    group mediadrm drmrpc
-    ioprio rt 4
-    writepid /dev/cpuset/foreground/tasks
-
diff --git a/services/codec2/vendor.google.media.c2@1.0-service.rc b/services/codec2/vendor.google.media.c2@1.0-service.rc
deleted file mode 100644
index 3e7e0a6..0000000
--- a/services/codec2/vendor.google.media.c2@1.0-service.rc
+++ /dev/null
@@ -1,7 +0,0 @@
-service vendor-google-media-c2-hal-1-0 /vendor/bin/hw/vendor.google.media.c2@1.0-service
-    class hal
-    user media
-    group mediadrm drmrpc
-    ioprio rt 4
-    writepid /dev/cpuset/foreground/tasks
-
diff --git a/services/oboeservice/AAudioEndpointManager.cpp b/services/oboeservice/AAudioEndpointManager.cpp
index 7b8d817..11fd9f6 100644
--- a/services/oboeservice/AAudioEndpointManager.cpp
+++ b/services/oboeservice/AAudioEndpointManager.cpp
@@ -201,14 +201,14 @@
         if (endpoint.get() != nullptr) {
             aaudio_result_t result = endpoint->open(request);
             if (result != AAUDIO_OK) {
-                ALOGE("openSharedEndpoint(), open failed");
+                ALOGE("%s(), open failed", __func__);
                 endpoint.clear();
             } else {
                 mSharedStreams.push_back(endpoint);
             }
         }
-        ALOGD("openSharedEndpoint(), created %p, requested device = %d, dir = %d",
-              endpoint.get(), configuration.getDeviceId(), (int)direction);
+        ALOGD("%s(), created endpoint %p, requested device = %d, dir = %d",
+              __func__, endpoint.get(), configuration.getDeviceId(), (int)direction);
         IPCThreadState::self()->restoreCallingIdentity(token);
     }
 
@@ -244,8 +244,8 @@
                 mExclusiveStreams.end());
 
         serviceEndpoint->close();
-        ALOGD("closeExclusiveEndpoint() %p for device %d",
-              serviceEndpoint.get(), serviceEndpoint->getDeviceId());
+        ALOGD("%s() %p for device %d",
+              __func__, serviceEndpoint.get(), serviceEndpoint->getDeviceId());
     }
 }
 
@@ -266,7 +266,7 @@
                 mSharedStreams.end());
 
         serviceEndpoint->close();
-        ALOGD("closeSharedEndpoint() %p for device %d",
-              serviceEndpoint.get(), serviceEndpoint->getDeviceId());
+        ALOGD("%s() %p for device %d",
+              __func__, serviceEndpoint.get(), serviceEndpoint->getDeviceId());
     }
 }
diff --git a/services/oboeservice/AAudioService.cpp b/services/oboeservice/AAudioService.cpp
index c708fee..ad5bb3a 100644
--- a/services/oboeservice/AAudioService.cpp
+++ b/services/oboeservice/AAudioService.cpp
@@ -165,7 +165,6 @@
 }
 
 aaudio_result_t AAudioService::closeStream(aaudio_handle_t streamHandle) {
-    ALOGD("closeStream(0x%08X)", streamHandle);
     // Check permission and ownership first.
     sp<AAudioServiceStreamBase> serviceStream = convertHandleToServiceStream(streamHandle);
     if (serviceStream.get() == nullptr) {
diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp
index 33439fc..96e621a 100644
--- a/services/oboeservice/AAudioServiceEndpoint.cpp
+++ b/services/oboeservice/AAudioServiceEndpoint.cpp
@@ -39,7 +39,7 @@
 using namespace aaudio;   // TODO just import names needed
 
 AAudioServiceEndpoint::~AAudioServiceEndpoint() {
-    ALOGD("AAudioServiceEndpoint::~AAudioServiceEndpoint() destroying endpoint %p", this);
+    ALOGD("%s(%p) destroyed", __func__, this);
 }
 
 std::string AAudioServiceEndpoint::dump() const {
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index db01c88..52990da 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -98,8 +98,8 @@
             .flags = AUDIO_FLAG_LOW_LATENCY,
             .tags = ""
     };
-    ALOGV("open() MMAP attributes.usage = %d, content_type = %d, source = %d",
-          attributes.usage, attributes.content_type, attributes.source);
+    ALOGD("%s(%p) MMAP attributes.usage = %d, content_type = %d, source = %d",
+          __func__, this, attributes.usage, attributes.content_type, attributes.source);
 
     mMmapClient.clientUid = request.getUserId();
     mMmapClient.clientPid = request.getProcessId();
@@ -135,7 +135,7 @@
         mHardwareTimeOffsetNanos = INPUT_ESTIMATED_HARDWARE_OFFSET_NANOS; // frames at ADC earlier
 
     } else {
-        ALOGE("openMmapStream - invalid direction = %d", direction);
+        ALOGE("%s() invalid direction = %d", __func__, direction);
         return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
     }
 
@@ -157,20 +157,20 @@
                                                           this, // callback
                                                           mMmapStream,
                                                           &mPortHandle);
-    ALOGD("open() mMapClient.uid = %d, pid = %d => portHandle = %d\n",
-          mMmapClient.clientUid,  mMmapClient.clientPid, mPortHandle);
+    ALOGD("%s() mMapClient.uid = %d, pid = %d => portHandle = %d\n",
+          __func__, mMmapClient.clientUid,  mMmapClient.clientPid, mPortHandle);
     if (status != OK) {
-        ALOGE("openMmapStream returned status %d", status);
+        ALOGE("%s() openMmapStream() returned status %d",  __func__, status);
         return AAUDIO_ERROR_UNAVAILABLE;
     }
 
     if (deviceId == AAUDIO_UNSPECIFIED) {
-        ALOGW("open() - openMmapStream() failed to set deviceId");
+        ALOGW("%s() openMmapStream() failed to set deviceId", __func__);
     }
     setDeviceId(deviceId);
 
     if (sessionId == AUDIO_SESSION_ALLOCATE) {
-        ALOGW("open() - openMmapStream() failed to set sessionId");
+        ALOGW("%s() - openMmapStream() failed to set sessionId", __func__);
     }
 
     aaudio_session_id_t actualSessionId =
@@ -178,7 +178,7 @@
             ? AAUDIO_SESSION_ID_NONE
             : (aaudio_session_id_t) sessionId;
     setSessionId(actualSessionId);
-    ALOGD("open() deviceId = %d, sessionId = %d", getDeviceId(), getSessionId());
+    ALOGD("%s() deviceId = %d, sessionId = %d", __func__, getDeviceId(), getSessionId());
 
     // Create MMAP/NOIRQ buffer.
     int32_t minSizeFrames = getBufferCapacity();
@@ -187,14 +187,14 @@
     }
     status = mMmapStream->createMmapBuffer(minSizeFrames, &mMmapBufferinfo);
     if (status != OK) {
-        ALOGE("open() - createMmapBuffer() failed with status %d %s",
-              status, strerror(-status));
+        ALOGE("%s() - createMmapBuffer() failed with status %d %s",
+              __func__, status, strerror(-status));
         result = AAUDIO_ERROR_UNAVAILABLE;
         goto error;
     } else {
-        ALOGD("createMmapBuffer status = %d, buffer_size = %d, burst_size %d"
+        ALOGD("%s() createMmapBuffer() returned = %d, buffer_size = %d, burst_size %d"
                       ", Sharable FD: %s",
-              status,
+              __func__, status,
               abs(mMmapBufferinfo.buffer_size_frames),
               mMmapBufferinfo.burst_size_frames,
               mMmapBufferinfo.buffer_size_frames < 0 ? "Yes" : "No");
@@ -214,7 +214,7 @@
             // Fallback is handled by caller but indicate what is possible in case
             // this is used in the future
             setSharingMode(AAUDIO_SHARING_MODE_SHARED);
-            ALOGW("open() - exclusive FD cannot be used by client");
+            ALOGW("%s() - exclusive FD cannot be used by client", __func__);
             result = AAUDIO_ERROR_UNAVAILABLE;
             goto error;
         }
@@ -229,7 +229,7 @@
     // Assume that AudioFlinger will close the original shared_memory_fd.
     mAudioDataFileDescriptor.reset(dup(mMmapBufferinfo.shared_memory_fd));
     if (mAudioDataFileDescriptor.get() == -1) {
-        ALOGE("open() - could not dup shared_memory_fd");
+        ALOGE("%s() - could not dup shared_memory_fd", __func__);
         result = AAUDIO_ERROR_INTERNAL;
         goto error;
     }
@@ -247,12 +247,12 @@
         burstMicros = mFramesPerBurst * static_cast<int64_t>(1000000) / getSampleRate();
     } while (burstMicros < burstMinMicros);
 
-    ALOGD("open() original burst = %d, minMicros = %d, to burst = %d\n",
-          mMmapBufferinfo.burst_size_frames, burstMinMicros, mFramesPerBurst);
+    ALOGD("%s() original burst = %d, minMicros = %d, to burst = %d\n",
+          __func__, mMmapBufferinfo.burst_size_frames, burstMinMicros, mFramesPerBurst);
 
-    ALOGD("open() actual rate = %d, channels = %d"
+    ALOGD("%s() actual rate = %d, channels = %d"
           ", deviceId = %d, capacity = %d\n",
-          getSampleRate(), getSamplesPerFrame(), deviceId, getBufferCapacity());
+          __func__, getSampleRate(), getSamplesPerFrame(), deviceId, getBufferCapacity());
 
     return result;
 
@@ -262,9 +262,8 @@
 }
 
 aaudio_result_t AAudioServiceEndpointMMAP::close() {
-
     if (mMmapStream != 0) {
-        ALOGD("close() clear() endpoint");
+        ALOGD("%s() clear() endpoint", __func__);
         // Needs to be explicitly cleared or CTS will fail but it is not clear why.
         mMmapStream.clear();
         // Apparently the above close is asynchronous. An attempt to open a new device
@@ -299,20 +298,18 @@
 aaudio_result_t AAudioServiceEndpointMMAP::startClient(const android::AudioClient& client,
                                                        audio_port_handle_t *clientHandle) {
     if (mMmapStream == nullptr) return AAUDIO_ERROR_NULL;
-    ALOGD("startClient(%p(uid=%d, pid=%d))",
-          &client, client.clientUid, client.clientPid);
+    ALOGV("%s(%p(uid=%d, pid=%d))", __func__, &client, client.clientUid, client.clientPid);
     audio_port_handle_t originalHandle =  *clientHandle;
     status_t status = mMmapStream->start(client, clientHandle);
     aaudio_result_t result = AAudioConvert_androidToAAudioResult(status);
-    ALOGD("startClient() , %d => %d returns %d",
-          originalHandle, *clientHandle, result);
+    ALOGV("%s() , %d => %d returns %d", __func__, originalHandle, *clientHandle, result);
     return result;
 }
 
 aaudio_result_t AAudioServiceEndpointMMAP::stopClient(audio_port_handle_t clientHandle) {
     if (mMmapStream == nullptr) return AAUDIO_ERROR_NULL;
     aaudio_result_t result = AAudioConvert_androidToAAudioResult(mMmapStream->stop(clientHandle));
-    ALOGD("stopClient(%d) returns %d", clientHandle, result);
+    ALOGV("%s(%d) returns %d", __func__, clientHandle, result);
     return result;
 }
 
@@ -324,13 +321,13 @@
         return AAUDIO_ERROR_NULL;
     }
     status_t status = mMmapStream->getMmapPosition(&position);
-    ALOGV("getFreeRunningPosition() status= %d, pos = %d, nanos = %lld\n",
-          status, position.position_frames, (long long) position.time_nanoseconds);
+    ALOGV("%s() status= %d, pos = %d, nanos = %lld\n",
+          __func__, status, position.position_frames, (long long) position.time_nanoseconds);
     aaudio_result_t result = AAudioConvert_androidToAAudioResult(status);
     if (result == AAUDIO_ERROR_UNAVAILABLE) {
-        ALOGW("sendCurrentTimestamp(): getMmapPosition() has no position data available");
+        ALOGW("%s(): getMmapPosition() has no position data available", __func__);
     } else if (result != AAUDIO_OK) {
-        ALOGE("sendCurrentTimestamp(): getMmapPosition() returned status %d", status);
+        ALOGE("%s(): getMmapPosition() returned status %d", __func__, status);
     } else {
         // Convert 32-bit position to 64-bit position.
         mFramesTransferred.update32(position.position_frames);
@@ -347,15 +344,16 @@
 
 
 void AAudioServiceEndpointMMAP::onTearDown() {
-    ALOGD("onTearDown() called");
+    ALOGD("%s(%p) called", __func__, this);
     disconnectRegisteredStreams();
 };
 
 void AAudioServiceEndpointMMAP::onVolumeChanged(audio_channel_mask_t channels,
                                               android::Vector<float> values) {
-    // TODO do we really need a different volume for each channel?
+    // TODO Do we really need a different volume for each channel?
+    // We get called with an array filled with a single value!
     float volume = values[0];
-    ALOGD("onVolumeChanged() volume[0] = %f", volume);
+    ALOGD("%s(%p) volume[0] = %f", __func__, this, volume);
     std::lock_guard<std::mutex> lock(mLockStreams);
     for(const auto stream : mRegisteredStreams) {
         stream->onVolumeChanged(volume);
@@ -363,8 +361,7 @@
 };
 
 void AAudioServiceEndpointMMAP::onRoutingChanged(audio_port_handle_t deviceId) {
-    ALOGD("onRoutingChanged() called with dev %d, old = %d",
-          deviceId, getDeviceId());
+    ALOGD("%s(%p) called with dev %d, old = %d", __func__, this, deviceId, getDeviceId());
     if (getDeviceId() != AUDIO_PORT_HANDLE_NONE  && getDeviceId() != deviceId) {
         disconnectRegisteredStreams();
     }
diff --git a/services/oboeservice/AAudioServiceEndpointPlay.cpp b/services/oboeservice/AAudioServiceEndpointPlay.cpp
index 2601f3f..a274466 100644
--- a/services/oboeservice/AAudioServiceEndpointPlay.cpp
+++ b/services/oboeservice/AAudioServiceEndpointPlay.cpp
@@ -43,10 +43,12 @@
 
 AAudioServiceEndpointPlay::AAudioServiceEndpointPlay(AAudioService &audioService)
         : mStreamInternalPlay(audioService, true) {
+    ALOGD("%s(%p) created", __func__, this);
     mStreamInternal = &mStreamInternalPlay;
 }
 
 AAudioServiceEndpointPlay::~AAudioServiceEndpointPlay() {
+    ALOGD("%s(%p) destroyed", __func__, this);
 }
 
 aaudio_result_t AAudioServiceEndpointPlay::open(const aaudio::AAudioStreamRequest &request) {
@@ -68,6 +70,7 @@
 
 // Mix data from each application stream and write result to the shared MMAP stream.
 void *AAudioServiceEndpointPlay::callbackLoop() {
+    ALOGD("%s() entering >>>>>>>>>>>>>>> MIXER", __func__);
     aaudio_result_t result = AAUDIO_OK;
     int64_t timeoutNanos = getStreamInternal()->calculateReasonableTimeout();
 
@@ -152,5 +155,7 @@
         }
     }
 
+    ALOGD("%s() exiting, enabled = %d, state = %d, result = %d <<<<<<<<<<<<< MIXER",
+          __func__, mCallbackEnabled.load(), getStreamInternal()->getState(), result);
     return NULL; // TODO review
 }
diff --git a/services/oboeservice/AAudioServiceEndpointShared.cpp b/services/oboeservice/AAudioServiceEndpointShared.cpp
index 584efe5..f08a52f 100644
--- a/services/oboeservice/AAudioServiceEndpointShared.cpp
+++ b/services/oboeservice/AAudioServiceEndpointShared.cpp
@@ -89,18 +89,22 @@
 }
 
 // Glue between C and C++ callbacks.
-static void *aaudio_endpoint_thread_proc(void *context) {
-    AAudioServiceEndpointShared *endpoint = (AAudioServiceEndpointShared *) context;
-    if (endpoint != NULL) {
-        void *result = endpoint->callbackLoop();
-        // Close now so that the HW resource is freed and we can open a new device.
-        if (!endpoint->isConnected()) {
-            endpoint->close();
-        }
-        return result;
-    } else {
-        return NULL;
+static void *aaudio_endpoint_thread_proc(void *arg) {
+    assert(arg != nullptr);
+
+    // The caller passed in a smart pointer to prevent the endpoint from getting deleted
+    // while the thread was launching.
+    sp<AAudioServiceEndpointShared> *endpointForThread =
+            static_cast<sp<AAudioServiceEndpointShared> *>(arg);
+    sp<AAudioServiceEndpointShared> endpoint = *endpointForThread;
+    delete endpointForThread; // Just use scoped smart pointer. Don't need this anymore.
+    void *result = endpoint->callbackLoop();
+    // Close now so that the HW resource is freed and we can open a new device.
+    if (!endpoint->isConnected()) {
+        endpoint->close();
     }
+
+    return result;
 }
 
 aaudio_result_t aaudio::AAudioServiceEndpointShared::startSharingThread_l() {
@@ -109,7 +113,16 @@
                           * AAUDIO_NANOS_PER_SECOND
                           / getSampleRate();
     mCallbackEnabled.store(true);
-    return getStreamInternal()->createThread(periodNanos, aaudio_endpoint_thread_proc, this);
+    // Pass a smart pointer so the thread can hold a reference.
+    sp<AAudioServiceEndpointShared> *endpointForThread = new sp<AAudioServiceEndpointShared>(this);
+    aaudio_result_t result = getStreamInternal()->createThread(periodNanos,
+                                                               aaudio_endpoint_thread_proc,
+                                                               endpointForThread);
+    if (result != AAUDIO_OK) {
+        // The thread can't delete it so we have to do it here.
+        delete endpointForThread;
+    }
+    return result;
 }
 
 aaudio_result_t aaudio::AAudioServiceEndpointShared::stopSharingThread() {
diff --git a/services/oboeservice/AAudioServiceEndpointShared.h b/services/oboeservice/AAudioServiceEndpointShared.h
index 74cd817..227250c 100644
--- a/services/oboeservice/AAudioServiceEndpointShared.h
+++ b/services/oboeservice/AAudioServiceEndpointShared.h
@@ -54,12 +54,13 @@
 
     virtual void            *callbackLoop() = 0;
 
+
+protected:
+
     AudioStreamInternal *getStreamInternal() const {
         return mStreamInternal;
     };
 
-protected:
-
     aaudio_result_t          startSharingThread_l();
 
     aaudio_result_t          stopSharingThread();
diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp
index e8c9e41..18f14ee 100644
--- a/services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/services/oboeservice/AAudioServiceStreamBase.cpp
@@ -93,7 +93,7 @@
     {
         std::lock_guard<std::mutex> lock(mUpMessageQueueLock);
         if (mUpMessageQueue != nullptr) {
-            ALOGE("open() called twice");
+            ALOGE("%s() called twice", __func__);
             return AAUDIO_ERROR_INVALID_STATE;
         }
 
@@ -108,7 +108,7 @@
                                                          request,
                                                          sharingMode);
         if (mServiceEndpoint == nullptr) {
-            ALOGE("open() openEndpoint() failed");
+            ALOGE("%s() openEndpoint() failed", __func__);
             result = AAUDIO_ERROR_UNAVAILABLE;
             goto error;
         }
@@ -167,7 +167,7 @@
     }
 
     if (mServiceEndpoint == nullptr) {
-        ALOGE("start() missing endpoint");
+        ALOGE("%s() missing endpoint", __func__);
         result = AAUDIO_ERROR_INVALID_STATE;
         goto error;
     }
@@ -201,7 +201,7 @@
         return result;
     }
     if (mServiceEndpoint == nullptr) {
-        ALOGE("pause() missing endpoint");
+        ALOGE("%s() missing endpoint", __func__);
         return AAUDIO_ERROR_INVALID_STATE;
     }
 
@@ -217,7 +217,7 @@
 
     result = mServiceEndpoint->stopStream(this, mClientHandle);
     if (result != AAUDIO_OK) {
-        ALOGE("pause() mServiceEndpoint returned %d", result);
+        ALOGE("%s() mServiceEndpoint returned %d, %s", __func__, result, getTypeText());
         disconnect(); // TODO should we return or pause Base first?
     }
 
@@ -233,7 +233,7 @@
     }
 
     if (mServiceEndpoint == nullptr) {
-        ALOGE("stop() missing endpoint");
+        ALOGE("%s() missing endpoint", __func__);
         return AAUDIO_ERROR_INVALID_STATE;
     }
 
@@ -251,7 +251,7 @@
     // TODO wait for data to be played out
     result = mServiceEndpoint->stopStream(this, mClientHandle);
     if (result != AAUDIO_OK) {
-        ALOGE("stop() mServiceEndpoint returned %d", result);
+        ALOGE("%s() mServiceEndpoint returned %d, %s", __func__, result, getTypeText());
         disconnect();
         // TODO what to do with result here?
     }
@@ -284,7 +284,7 @@
 
 // implement Runnable, periodically send timestamps to client
 void AAudioServiceStreamBase::run() {
-    ALOGD("run() entering ----------------");
+    ALOGD("%s() %s entering >>>>>>>>>>>>>> TIMESTAMPS", __func__, getTypeText());
     TimestampScheduler timestampScheduler;
     timestampScheduler.setBurstPeriod(mFramesPerBurst, getSampleRate());
     timestampScheduler.start(AudioClock::getNanoseconds());
@@ -302,7 +302,7 @@
             AudioClock::sleepUntilNanoTime(nextTime);
         }
     }
-    ALOGD("run() exiting ----------------");
+    ALOGD("%s() %s exiting <<<<<<<<<<<<<< TIMESTAMPS", __func__, getTypeText());
 }
 
 void AAudioServiceStreamBase::disconnect() {
@@ -333,12 +333,12 @@
 aaudio_result_t AAudioServiceStreamBase::writeUpMessageQueue(AAudioServiceMessage *command) {
     std::lock_guard<std::mutex> lock(mUpMessageQueueLock);
     if (mUpMessageQueue == nullptr) {
-        ALOGE("writeUpMessageQueue(): mUpMessageQueue null! - stream not open");
+        ALOGE("%s(): mUpMessageQueue null! - stream not open", __func__);
         return AAUDIO_ERROR_NULL;
     }
     int32_t count = mUpMessageQueue->getFifoBuffer()->write(command, 1);
     if (count != 1) {
-        ALOGE("writeUpMessageQueue(): Queue full. Did client die?");
+        ALOGE("%s(): Queue full. Did client die? %s", __func__, getTypeText());
         return AAUDIO_ERROR_WOULD_BLOCK;
     } else {
         return AAUDIO_OK;
@@ -355,7 +355,7 @@
     aaudio_result_t result = getFreeRunningPosition(&command.timestamp.position,
                                                     &command.timestamp.timestamp);
     if (result == AAUDIO_OK) {
-        ALOGV("sendCurrentTimestamp() SERVICE  %8lld at %lld",
+        ALOGV("%s() SERVICE  %8lld at %lld", __func__,
               (long long) command.timestamp.position,
               (long long) command.timestamp.timestamp);
         command.what = AAudioServiceMessage::code::TIMESTAMP_SERVICE;
@@ -366,7 +366,7 @@
             result = getHardwareTimestamp(&command.timestamp.position,
                                           &command.timestamp.timestamp);
             if (result == AAUDIO_OK) {
-                ALOGV("sendCurrentTimestamp() HARDWARE %8lld at %lld",
+                ALOGV("%s() HARDWARE %8lld at %lld", __func__,
                       (long long) command.timestamp.position,
                       (long long) command.timestamp.timestamp);
                 command.what = AAudioServiceMessage::code::TIMESTAMP_HARDWARE;
@@ -389,7 +389,7 @@
     {
         std::lock_guard<std::mutex> lock(mUpMessageQueueLock);
         if (mUpMessageQueue == nullptr) {
-            ALOGE("getDescription(): mUpMessageQueue null! - stream not open");
+            ALOGE("%s(): mUpMessageQueue null! - stream not open", __func__);
             return AAUDIO_ERROR_NULL;
         }
         // Gather information on the message queue.
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index 5f5bb98..3720596 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -55,7 +55,7 @@
     , public Runnable  {
 
 public:
-    AAudioServiceStreamBase(android::AAudioService &aAudioService);
+    explicit AAudioServiceStreamBase(android::AAudioService &aAudioService);
 
     virtual ~AAudioServiceStreamBase();
 
@@ -219,6 +219,8 @@
         mCloseNeeded.store(needed);
     }
 
+    virtual const char *getTypeText() const { return "Base"; }
+
 protected:
 
     /**
diff --git a/services/oboeservice/AAudioServiceStreamMMAP.h b/services/oboeservice/AAudioServiceStreamMMAP.h
index e2415d0..1509f7d 100644
--- a/services/oboeservice/AAudioServiceStreamMMAP.h
+++ b/services/oboeservice/AAudioServiceStreamMMAP.h
@@ -69,9 +69,7 @@
 
     aaudio_result_t close() override;
 
-    /**
-     * Send a MMAP/NOIRQ buffer timestamp to the client.
-     */
+    const char *getTypeText() const override { return "MMAP"; }
 
 protected:
 
diff --git a/services/oboeservice/AAudioServiceStreamShared.h b/services/oboeservice/AAudioServiceStreamShared.h
index 3b12e61..61769b5 100644
--- a/services/oboeservice/AAudioServiceStreamShared.h
+++ b/services/oboeservice/AAudioServiceStreamShared.h
@@ -43,7 +43,7 @@
 class AAudioServiceStreamShared : public AAudioServiceStreamBase {
 
 public:
-    AAudioServiceStreamShared(android::AAudioService &aAudioService);
+    explicit AAudioServiceStreamShared(android::AAudioService &aAudioService);
     virtual ~AAudioServiceStreamShared() = default;
 
     static std::string dumpHeader();
@@ -87,6 +87,8 @@
         return mXRunCount.load();
     }
 
+    const char *getTypeText() const override { return "Shared"; }
+
 protected:
 
     aaudio_result_t getAudioDataDescription(AudioEndpointParcelable &parcelable) override;
diff --git a/services/oboeservice/AAudioThread.h b/services/oboeservice/AAudioThread.h
index ffc9b7b..dcce68a 100644
--- a/services/oboeservice/AAudioThread.h
+++ b/services/oboeservice/AAudioThread.h
@@ -44,7 +44,7 @@
 public:
     AAudioThread();
 
-    AAudioThread(const char *prefix);
+    explicit AAudioThread(const char *prefix);
 
     virtual ~AAudioThread() = default;