Merge "Update clearkey plugin to drm HAL v1.3"
diff --git a/apex/testing/Android.bp b/apex/testing/Android.bp
index 701ced7..477c371 100644
--- a/apex/testing/Android.bp
+++ b/apex/testing/Android.bp
@@ -15,7 +15,7 @@
 apex {
     name: "test_com.android.media",
     manifest: "test_manifest.json",
-    file_contexts: "com.android.media",
+    file_contexts: ":com.android.media-file_contexts",
     defaults: ["com.android.media-defaults"],
     installable: false,
 }
@@ -23,7 +23,7 @@
 apex {
     name: "test_com.android.media.swcodec",
     manifest: "test_manifest_codec.json",
-    file_contexts: "com.android.media.swcodec",
+    file_contexts: ":com.android.media.swcodec-file_contexts",
     defaults: ["com.android.media.swcodec-defaults"],
     installable: false,
 }
diff --git a/camera/ndk/impl/ACameraManager.cpp b/camera/ndk/impl/ACameraManager.cpp
index 8eb030a..7a0f63b 100644
--- a/camera/ndk/impl/ACameraManager.cpp
+++ b/camera/ndk/impl/ACameraManager.cpp
@@ -76,6 +76,10 @@
 
 sp<hardware::ICameraService> CameraManagerGlobal::getCameraService() {
     Mutex::Autolock _l(mLock);
+    return getCameraServiceLocked();
+}
+
+sp<hardware::ICameraService> CameraManagerGlobal::getCameraServiceLocked() {
     if (mCameraService.get() == nullptr) {
         if (isCameraServiceDisabled()) {
             return mCameraService;
@@ -216,8 +220,12 @@
     if (pair.second) {
         for (auto& pair : mDeviceStatusMap) {
             const String8& cameraId = pair.first;
-            int32_t status = pair.second;
-
+            int32_t status = pair.second.status;
+            // Don't send initial callbacks for camera ids which don't support
+            // camera2
+            if (!pair.second.supportsHAL3) {
+                continue;
+            }
             sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
             ACameraManager_AvailabilityCallback cb = isStatusAvailable(status) ?
                     callback->onCameraAvailable : callback->onCameraUnavailable;
@@ -236,20 +244,32 @@
     mCallbacks.erase(cb);
 }
 
+bool CameraManagerGlobal::supportsCamera2ApiLocked(const String8 &cameraId) {
+    bool camera2Support = false;
+    auto cs = getCameraServiceLocked();
+    binder::Status serviceRet =
+        cs->supportsCameraApi(String16(cameraId),
+                hardware::ICameraService::API_VERSION_2, &camera2Support);
+    if (!serviceRet.isOk()) {
+        ALOGE("%s: supportsCameraApi2Locked() call failed for cameraId  %s",
+                __FUNCTION__, cameraId.c_str());
+        return false;
+    }
+    return camera2Support;
+}
+
 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);
-
+    // Needed to make sure we're connected to cameraservice
+    getCameraServiceLocked();
     for(auto& deviceStatus : mDeviceStatusMap) {
-        if (deviceStatus.second == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
-                deviceStatus.second == hardware::ICameraServiceListener::STATUS_ENUMERATING) {
+        if (deviceStatus.second.status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT ||
+                deviceStatus.second.status ==
+                        hardware::ICameraServiceListener::STATUS_ENUMERATING) {
             continue;
         }
-        bool camera2Support = false;
-        binder::Status serviceRet = cs->supportsCameraApi(String16(deviceStatus.first),
-                hardware::ICameraService::API_VERSION_2, &camera2Support);
-        if (!serviceRet.isOk() || !camera2Support) {
+        if (!deviceStatus.second.supportsHAL3) {
             continue;
         }
         cameraIds->push_back(deviceStatus.first);
@@ -377,7 +397,7 @@
     bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
     int32_t oldStatus = firstStatus ?
             status : // first status
-            mDeviceStatusMap[cameraId];
+            mDeviceStatusMap[cameraId].status;
 
     if (!firstStatus &&
             isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
@@ -385,16 +405,19 @@
         return;
     }
 
+    bool supportsHAL3 = supportsCamera2ApiLocked(cameraId);
     // Iterate through all registered callbacks
-    mDeviceStatusMap[cameraId] = status;
-    for (auto cb : mCallbacks) {
-        sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
-        ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
-                cb.mAvailable : cb.mUnavailable;
-        msg->setPointer(kCallbackFpKey, (void *) cbFp);
-        msg->setPointer(kContextKey, cb.mContext);
-        msg->setString(kCameraIdKey, AString(cameraId));
-        msg->post();
+    mDeviceStatusMap[cameraId] = StatusAndHAL3Support(status, supportsHAL3);
+    if (supportsHAL3) {
+        for (auto cb : mCallbacks) {
+            sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
+            ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
+                    cb.mAvailable : cb.mUnavailable;
+            msg->setPointer(kCallbackFpKey, (void *) cbFp);
+            msg->setPointer(kContextKey, cb.mContext);
+            msg->setString(kCameraIdKey, AString(cameraId));
+            msg->post();
+        }
     }
     if (status == hardware::ICameraServiceListener::STATUS_NOT_PRESENT) {
         mDeviceStatusMap.erase(cameraId);
diff --git a/camera/ndk/impl/ACameraManager.h b/camera/ndk/impl/ACameraManager.h
index 8c1da36..e945ba0 100644
--- a/camera/ndk/impl/ACameraManager.h
+++ b/camera/ndk/impl/ACameraManager.h
@@ -66,9 +66,9 @@
 
   private:
     sp<hardware::ICameraService> mCameraService;
-    const int          kCameraServicePollDelay = 500000; // 0.5s
-    const char*        kCameraServiceName      = "media.camera";
-    Mutex              mLock;
+    const int                    kCameraServicePollDelay = 500000; // 0.5s
+    const char*                  kCameraServiceName      = "media.camera";
+    Mutex                        mLock;
 
     class DeathNotifier : public IBinder::DeathRecipient {
       public:
@@ -156,12 +156,14 @@
     sp<CallbackHandler> mHandler;
     sp<ALooper>         mCbLooper; // Looper thread where callbacks actually happen on
 
+    sp<hardware::ICameraService> getCameraServiceLocked();
     void onCameraAccessPrioritiesChanged();
     void onStatusChanged(int32_t status, const String8& cameraId);
     void onStatusChangedLocked(int32_t status, const String8& cameraId);
     // Utils for status
     static bool validStatus(int32_t status);
     static bool isStatusAvailable(int32_t status);
+    bool supportsCamera2ApiLocked(const String8 &cameraId);
 
     // The sort logic must match the logic in
     // libcameraservice/common/CameraProviderManager.cpp::getAPI1CompatibleCameraDeviceIds
@@ -184,8 +186,16 @@
         }
     };
 
+    struct StatusAndHAL3Support {
+        int32_t status = hardware::ICameraServiceListener::STATUS_NOT_PRESENT;
+        bool supportsHAL3 = false;
+        StatusAndHAL3Support(int32_t st, bool HAL3support):
+                status(st), supportsHAL3(HAL3support) { };
+        StatusAndHAL3Support() = default;
+    };
+
     // Map camera_id -> status
-    std::map<String8, int32_t, CameraIdComparator> mDeviceStatusMap;
+    std::map<String8, StatusAndHAL3Support, CameraIdComparator> mDeviceStatusMap;
 
     // For the singleton instance
     static Mutex sLock;
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 34a2f69..6b1b475 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -37,7 +37,6 @@
     ],
 
     shared_libs: [
-        "libbinder",
         "libbinder_ndk",
         "libcutils",
         "libdl",
@@ -95,8 +94,6 @@
         "android.hardware.drm@1.0",
         "android.hardware.drm@1.1",
         "android.hardware.drm@1.2",
-        "libbinder",
-        "libhidlbase",
         "liblog",
         "libmediametrics",
         "libprotobuf-cpp-lite",
@@ -134,8 +131,6 @@
         "android.hardware.drm@1.1",
         "android.hardware.drm@1.2",
         "libbase",
-        "libbinder",
-        "libhidlbase",
         "liblog",
         "libmediametrics",
         "libprotobuf-cpp-full",
@@ -149,3 +144,25 @@
     ],
 }
 
+cc_library_shared {
+    name: "libmediadrmmetrics_consumer",
+    srcs: [
+        "DrmMetricsConsumer.cpp",
+    ],
+
+    include_dirs: [
+        "frameworks/av/media/libmedia/include"
+    ],
+
+    shared_libs: [
+        "android.hardware.drm@1.0",
+        "android.hardware.drm@1.1",
+        "android.hardware.drm@1.2",
+        "libbinder",
+        "libhidlbase",
+        "liblog",
+        "libmediadrm",
+        "libmediadrmmetrics_full",
+        "libutils",
+    ],
+}
diff --git a/drm/libmediadrm/CryptoHal.cpp b/drm/libmediadrm/CryptoHal.cpp
index 55b9bb8..18772e0 100644
--- a/drm/libmediadrm/CryptoHal.cpp
+++ b/drm/libmediadrm/CryptoHal.cpp
@@ -20,7 +20,6 @@
 
 #include <android/hardware/drm/1.0/types.h>
 #include <android/hidl/manager/1.2/IServiceManager.h>
-#include <binder/IMemory.h>
 #include <hidl/ServiceManagement.h>
 #include <hidlmemory/FrameworkUtils.h>
 #include <media/hardware/CryptoAPI.h>
@@ -251,7 +250,7 @@
 
 
 /**
- * If the heap base isn't set, get the heap base from the IMemory
+ * If the heap base isn't set, get the heap base from the HidlMemory
  * and send it to the HAL so it can map a remote heap of the same
  * size.  Once the heap base is established, shared memory buffers
  * are sent by providing an offset into the heap and a buffer size.
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index f3028d8..5b32a04 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -38,6 +38,8 @@
 #include <mediadrm/DrmHal.h>
 #include <mediadrm/DrmSessionClientInterface.h>
 #include <mediadrm/DrmSessionManager.h>
+#include <mediadrm/IDrmMetricsConsumer.h>
+#include <mediadrm/DrmUtils.h>
 
 #include <vector>
 
@@ -387,44 +389,8 @@
     mPluginV1_2.clear();
 }
 
-Vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
-    Vector<sp<IDrmFactory>> factories;
-
-    auto manager = hardware::defaultServiceManager1_2();
-
-    if (manager != NULL) {
-        manager->listManifestByInterface(drm::V1_0::IDrmFactory::descriptor,
-                [&factories](const hidl_vec<hidl_string> &registered) {
-                    for (const auto &instance : registered) {
-                        auto factory = drm::V1_0::IDrmFactory::getService(instance);
-                        if (factory != NULL) {
-                            factories.push_back(factory);
-                        }
-                    }
-                }
-            );
-        manager->listManifestByInterface(drm::V1_1::IDrmFactory::descriptor,
-                [&factories](const hidl_vec<hidl_string> &registered) {
-                    for (const auto &instance : registered) {
-                        auto factory = drm::V1_1::IDrmFactory::getService(instance);
-                        if (factory != NULL) {
-                            factories.push_back(factory);
-                        }
-                    }
-                }
-            );
-        manager->listManifestByInterface(drm::V1_2::IDrmFactory::descriptor,
-                [&factories](const hidl_vec<hidl_string> &registered) {
-                    for (const auto &instance : registered) {
-                        auto factory = drm::V1_2::IDrmFactory::getService(instance);
-                        if (factory != NULL) {
-                            factories.push_back(factory);
-                        }
-                    }
-                }
-            );
-    }
-
+std::vector<sp<IDrmFactory>> DrmHal::makeDrmFactories() {
+    std::vector<sp<IDrmFactory>> factories(DrmUtils::MakeDrmFactories());
     if (factories.size() == 0) {
         // must be in passthrough mode, load the default passthrough service
         auto passthrough = IDrmFactory::getService();
@@ -1362,11 +1328,11 @@
     return status.isOk() ? toStatusT(status) : DEAD_OBJECT;
 }
 
-status_t DrmHal::getMetrics(PersistableBundle* metrics) {
-    if (metrics == nullptr) {
+status_t DrmHal::getMetrics(const sp<IDrmMetricsConsumer> &consumer) {
+    if (consumer == nullptr) {
         return UNEXPECTED_NULL;
     }
-    mMetrics.Export(metrics);
+    consumer->consumeFrameworkMetrics(mMetrics);
 
     // Append vendor metrics if they are supported.
     if (mPluginV1_1 != NULL) {
@@ -1393,11 +1359,7 @@
                     if (status != Status::OK) {
                       ALOGV("Error getting plugin metrics: %d", status);
                     } else {
-                        PersistableBundle pluginBundle;
-                        if (MediaDrmMetrics::HidlMetricsToBundle(
-                                pluginMetrics, &pluginBundle) == OK) {
-                            metrics->putPersistableBundle(String16(vendor), pluginBundle);
-                        }
+                      consumer->consumeHidlMetrics(vendor, pluginMetrics);
                     }
                     err = toStatusT(status);
                 });
diff --git a/drm/libmediadrm/DrmMetrics.cpp b/drm/libmediadrm/DrmMetrics.cpp
index 3080802..996fd19 100644
--- a/drm/libmediadrm/DrmMetrics.cpp
+++ b/drm/libmediadrm/DrmMetrics.cpp
@@ -29,143 +29,12 @@
 using ::android::String16;
 using ::android::String8;
 using ::android::drm_metrics::DrmFrameworkMetrics;
-using ::android::hardware::hidl_string;
-using ::android::hardware::hidl_vec;
 using ::android::hardware::drm::V1_0::EventType;
 using ::android::hardware::drm::V1_2::KeyStatusType;
 using ::android::hardware::drm::V1_1::DrmMetricGroup;
-using ::android::os::PersistableBundle;
 
 namespace {
 
-template <typename T> std::string GetAttributeName(T type);
-
-template <> std::string GetAttributeName<KeyStatusType>(KeyStatusType type) {
-    static const char *type_names[] = {"USABLE", "EXPIRED",
-                                       "OUTPUT_NOT_ALLOWED", "STATUS_PENDING",
-                                       "INTERNAL_ERROR"};
-    if (((size_t)type) > arraysize(type_names)) {
-        return "UNKNOWN_TYPE";
-    }
-    return type_names[(size_t)type];
-}
-
-template <> std::string GetAttributeName<EventType>(EventType type) {
-    static const char *type_names[] = {"PROVISION_REQUIRED", "KEY_NEEDED",
-                                       "KEY_EXPIRED", "VENDOR_DEFINED",
-                                       "SESSION_RECLAIMED"};
-    if (((size_t)type) > arraysize(type_names)) {
-        return "UNKNOWN_TYPE";
-    }
-    return type_names[(size_t)type];
-}
-
-template <typename T>
-void ExportCounterMetric(const android::CounterMetric<T> &counter,
-                         PersistableBundle *metrics) {
-    if (!metrics) {
-        ALOGE("metrics was unexpectedly null.");
-        return;
-    }
-    std::string success_count_name = counter.metric_name() + ".ok.count";
-    std::string error_count_name = counter.metric_name() + ".error.count";
-    std::vector<int64_t> status_values;
-    counter.ExportValues(
-        [&](const android::status_t status, const int64_t value) {
-            if (status == android::OK) {
-                metrics->putLong(android::String16(success_count_name.c_str()),
-                                 value);
-            } else {
-                int64_t total_errors(0);
-                metrics->getLong(android::String16(error_count_name.c_str()),
-                                 &total_errors);
-                metrics->putLong(android::String16(error_count_name.c_str()),
-                                 total_errors + value);
-                status_values.push_back(status);
-            }
-        });
-    if (!status_values.empty()) {
-        std::string error_list_name = counter.metric_name() + ".error.list";
-        metrics->putLongVector(android::String16(error_list_name.c_str()),
-                               status_values);
-    }
-}
-
-template <typename T>
-void ExportCounterMetricWithAttributeNames(
-    const android::CounterMetric<T> &counter, PersistableBundle *metrics) {
-    if (!metrics) {
-        ALOGE("metrics was unexpectedly null.");
-        return;
-    }
-    counter.ExportValues([&](const T &attribute, const int64_t value) {
-        std::string name = counter.metric_name() + "." +
-                           GetAttributeName(attribute) + ".count";
-        metrics->putLong(android::String16(name.c_str()), value);
-    });
-}
-
-template <typename T>
-void ExportEventMetric(const android::EventMetric<T> &event,
-                       PersistableBundle *metrics) {
-    if (!metrics) {
-        ALOGE("metrics was unexpectedly null.");
-        return;
-    }
-    std::string success_count_name = event.metric_name() + ".ok.count";
-    std::string error_count_name = event.metric_name() + ".error.count";
-    std::string timing_name = event.metric_name() + ".ok.average_time_micros";
-    std::vector<int64_t> status_values;
-    event.ExportValues([&](const android::status_t &status,
-                           const android::EventStatistics &value) {
-        if (status == android::OK) {
-            metrics->putLong(android::String16(success_count_name.c_str()),
-                             value.count);
-            metrics->putLong(android::String16(timing_name.c_str()),
-                             value.mean);
-        } else {
-            int64_t total_errors(0);
-            metrics->getLong(android::String16(error_count_name.c_str()),
-                             &total_errors);
-            metrics->putLong(android::String16(error_count_name.c_str()),
-                             total_errors + value.count);
-            status_values.push_back(status);
-        }
-    });
-    if (!status_values.empty()) {
-        std::string error_list_name = event.metric_name() + ".error.list";
-        metrics->putLongVector(android::String16(error_list_name.c_str()),
-                               status_values);
-    }
-}
-
-void ExportSessionLifespans(
-    const std::map<std::string, std::pair<int64_t, int64_t>> &mSessionLifespans,
-    PersistableBundle *metrics) {
-    if (!metrics) {
-        ALOGE("metrics was unexpectedly null.");
-        return;
-    }
-
-    if (mSessionLifespans.empty()) {
-        return;
-    }
-
-    PersistableBundle startTimesBundle;
-    PersistableBundle endTimesBundle;
-    for (auto it = mSessionLifespans.begin(); it != mSessionLifespans.end();
-         it++) {
-        String16 key(it->first.c_str(), it->first.size());
-        startTimesBundle.putLong(key, it->second.first);
-        endTimesBundle.putLong(key, it->second.second);
-    }
-    metrics->putPersistableBundle(
-        android::String16("drm.mediadrm.session_start_times_ms"),
-        startTimesBundle);
-    metrics->putPersistableBundle(
-        android::String16("drm.mediadrm.session_end_times_ms"), endTimesBundle);
-}
-
 std::string ToHexString(const android::Vector<uint8_t> &sessionId) {
     std::ostringstream out;
     out << std::hex << std::setfill('0');
@@ -175,31 +44,6 @@
     return out.str();
 }
 
-template <typename CT>
-void SetValue(const String16 &name, DrmMetricGroup::ValueType type,
-              const CT &value, PersistableBundle *bundle) {
-    switch (type) {
-    case DrmMetricGroup::ValueType::INT64_TYPE:
-        bundle->putLong(name, value.int64Value);
-        break;
-    case DrmMetricGroup::ValueType::DOUBLE_TYPE:
-        bundle->putDouble(name, value.doubleValue);
-        break;
-    case DrmMetricGroup::ValueType::STRING_TYPE:
-        bundle->putString(name, String16(value.stringValue.c_str()));
-        break;
-    default:
-        ALOGE("Unexpected value type: %hhu", type);
-    }
-}
-
-inline String16 MakeIndexString(unsigned int index) {
-  std::string str("[");
-  str.append(std::to_string(index));
-  str.append("]");
-  return String16(str.c_str());
-}
-
 } // namespace
 
 namespace android {
@@ -237,23 +81,6 @@
     }
 }
 
-void MediaDrmMetrics::Export(PersistableBundle *metrics) {
-    if (!metrics) {
-        ALOGE("metrics was unexpectedly null.");
-        return;
-    }
-    ExportCounterMetric(mOpenSessionCounter, metrics);
-    ExportCounterMetric(mCloseSessionCounter, metrics);
-    ExportEventMetric(mGetKeyRequestTimeUs, metrics);
-    ExportEventMetric(mProvideKeyResponseTimeUs, metrics);
-    ExportCounterMetric(mGetProvisionRequestCounter, metrics);
-    ExportCounterMetric(mProvideProvisionResponseCounter, metrics);
-    ExportCounterMetricWithAttributeNames(mKeyStatusChangeCounter, metrics);
-    ExportCounterMetricWithAttributeNames(mEventCounter, metrics);
-    ExportCounterMetric(mGetDeviceUniqueIdCounter, metrics);
-    ExportSessionLifespans(mSessionLifespans, metrics);
-}
-
 status_t MediaDrmMetrics::GetSerializedMetrics(std::string *serializedMetrics) {
 
     if (!serializedMetrics) {
@@ -361,62 +188,14 @@
     return OK;
 }
 
+std::map<std::string, std::pair<int64_t, int64_t>> MediaDrmMetrics::GetSessionLifespans() const {
+  return mSessionLifespans;
+}
+
 int64_t MediaDrmMetrics::GetCurrentTimeMs() {
     struct timeval tv;
     gettimeofday(&tv, NULL);
     return ((int64_t)tv.tv_sec * 1000) + ((int64_t)tv.tv_usec / 1000);
 }
 
-status_t MediaDrmMetrics::HidlMetricsToBundle(
-    const hidl_vec<DrmMetricGroup> &hidlMetricGroups,
-    PersistableBundle *bundleMetricGroups) {
-    if (bundleMetricGroups == nullptr) {
-        return UNEXPECTED_NULL;
-    }
-    if (hidlMetricGroups.size() == 0) {
-        return OK;
-    }
-
-    int groupIndex = 0;
-    std::map<String16, int> indexMap;
-    for (const auto &hidlMetricGroup : hidlMetricGroups) {
-        PersistableBundle bundleMetricGroup;
-        for (const auto &hidlMetric : hidlMetricGroup.metrics) {
-            String16 metricName(hidlMetric.name.c_str());
-            PersistableBundle bundleMetric;
-            // Add metric component values.
-            for (const auto &value : hidlMetric.values) {
-                SetValue(String16(value.componentName.c_str()), value.type,
-                         value, &bundleMetric);
-            }
-            // Set metric attributes.
-            PersistableBundle bundleMetricAttributes;
-            for (const auto &attribute : hidlMetric.attributes) {
-                SetValue(String16(attribute.name.c_str()), attribute.type,
-                         attribute, &bundleMetricAttributes);
-            }
-            // Add attributes to the bundle metric.
-            bundleMetric.putPersistableBundle(String16("attributes"),
-                                              bundleMetricAttributes);
-            // Add one layer of indirection, allowing for repeated metric names.
-            PersistableBundle repeatedMetrics;
-            bundleMetricGroup.getPersistableBundle(metricName,
-                                                   &repeatedMetrics);
-            int index = indexMap[metricName];
-            repeatedMetrics.putPersistableBundle(MakeIndexString(index),
-                                                 bundleMetric);
-            indexMap[metricName] = ++index;
-
-            // Add the bundle metric to the group of metrics.
-            bundleMetricGroup.putPersistableBundle(metricName,
-                                                   repeatedMetrics);
-        }
-        // Add the bundle metric group to the collection of groups.
-        bundleMetricGroups->putPersistableBundle(MakeIndexString(groupIndex++),
-                                                 bundleMetricGroup);
-    }
-
-    return OK;
-}
-
 } // namespace android
diff --git a/drm/libmediadrm/DrmMetricsConsumer.cpp b/drm/libmediadrm/DrmMetricsConsumer.cpp
new file mode 100644
index 0000000..b47b4ff
--- /dev/null
+++ b/drm/libmediadrm/DrmMetricsConsumer.cpp
@@ -0,0 +1,270 @@
+/*
+ * 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 "DrmMetricsConsumer"
+
+#include <android-base/macros.h>
+#include <mediadrm/DrmMetricsConsumer.h>
+#include <mediadrm/DrmMetrics.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+
+using ::android::String16;
+using ::android::String8;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::drm::V1_0::EventType;
+using ::android::hardware::drm::V1_2::KeyStatusType;
+using ::android::hardware::drm::V1_1::DrmMetricGroup;
+using ::android::os::PersistableBundle;
+
+namespace {
+
+template <typename T> std::string GetAttributeName(T type);
+
+template <> std::string GetAttributeName<KeyStatusType>(KeyStatusType type) {
+    static const char *type_names[] = {"USABLE", "EXPIRED",
+                                       "OUTPUT_NOT_ALLOWED", "STATUS_PENDING",
+                                       "INTERNAL_ERROR"};
+    if (((size_t)type) > arraysize(type_names)) {
+        return "UNKNOWN_TYPE";
+    }
+    return type_names[(size_t)type];
+}
+
+template <> std::string GetAttributeName<EventType>(EventType type) {
+    static const char *type_names[] = {"PROVISION_REQUIRED", "KEY_NEEDED",
+                                       "KEY_EXPIRED", "VENDOR_DEFINED",
+                                       "SESSION_RECLAIMED"};
+    if (((size_t)type) > arraysize(type_names)) {
+        return "UNKNOWN_TYPE";
+    }
+    return type_names[(size_t)type];
+}
+
+template <typename T>
+void ExportCounterMetric(const android::CounterMetric<T> &counter,
+                         PersistableBundle *metrics) {
+    if (!metrics) {
+        ALOGE("metrics was unexpectedly null.");
+        return;
+    }
+    std::string success_count_name = counter.metric_name() + ".ok.count";
+    std::string error_count_name = counter.metric_name() + ".error.count";
+    std::vector<int64_t> status_values;
+    counter.ExportValues(
+        [&](const android::status_t status, const int64_t value) {
+            if (status == android::OK) {
+                metrics->putLong(android::String16(success_count_name.c_str()),
+                                 value);
+            } else {
+                int64_t total_errors(0);
+                metrics->getLong(android::String16(error_count_name.c_str()),
+                                 &total_errors);
+                metrics->putLong(android::String16(error_count_name.c_str()),
+                                 total_errors + value);
+                status_values.push_back(status);
+            }
+        });
+    if (!status_values.empty()) {
+        std::string error_list_name = counter.metric_name() + ".error.list";
+        metrics->putLongVector(android::String16(error_list_name.c_str()),
+                               status_values);
+    }
+}
+
+template <typename T>
+void ExportCounterMetricWithAttributeNames(
+    const android::CounterMetric<T> &counter, PersistableBundle *metrics) {
+    if (!metrics) {
+        ALOGE("metrics was unexpectedly null.");
+        return;
+    }
+    counter.ExportValues([&](const T &attribute, const int64_t value) {
+        std::string name = counter.metric_name() + "." +
+                           GetAttributeName(attribute) + ".count";
+        metrics->putLong(android::String16(name.c_str()), value);
+    });
+}
+
+template <typename T>
+void ExportEventMetric(const android::EventMetric<T> &event,
+                       PersistableBundle *metrics) {
+    if (!metrics) {
+        ALOGE("metrics was unexpectedly null.");
+        return;
+    }
+    std::string success_count_name = event.metric_name() + ".ok.count";
+    std::string error_count_name = event.metric_name() + ".error.count";
+    std::string timing_name = event.metric_name() + ".ok.average_time_micros";
+    std::vector<int64_t> status_values;
+    event.ExportValues([&](const android::status_t &status,
+                           const android::EventStatistics &value) {
+        if (status == android::OK) {
+            metrics->putLong(android::String16(success_count_name.c_str()),
+                             value.count);
+            metrics->putLong(android::String16(timing_name.c_str()),
+                             value.mean);
+        } else {
+            int64_t total_errors(0);
+            metrics->getLong(android::String16(error_count_name.c_str()),
+                             &total_errors);
+            metrics->putLong(android::String16(error_count_name.c_str()),
+                             total_errors + value.count);
+            status_values.push_back(status);
+        }
+    });
+    if (!status_values.empty()) {
+        std::string error_list_name = event.metric_name() + ".error.list";
+        metrics->putLongVector(android::String16(error_list_name.c_str()),
+                               status_values);
+    }
+}
+
+void ExportSessionLifespans(
+    const std::map<std::string, std::pair<int64_t, int64_t>> &sessionLifespans,
+    PersistableBundle *metrics) {
+    if (!metrics) {
+        ALOGE("metrics was unexpectedly null.");
+        return;
+    }
+
+    if (sessionLifespans.empty()) {
+        return;
+    }
+
+    PersistableBundle startTimesBundle;
+    PersistableBundle endTimesBundle;
+    for (auto it = sessionLifespans.begin(); it != sessionLifespans.end();
+         it++) {
+        String16 key(it->first.c_str(), it->first.size());
+        startTimesBundle.putLong(key, it->second.first);
+        endTimesBundle.putLong(key, it->second.second);
+    }
+    metrics->putPersistableBundle(
+        android::String16("drm.mediadrm.session_start_times_ms"),
+        startTimesBundle);
+    metrics->putPersistableBundle(
+        android::String16("drm.mediadrm.session_end_times_ms"), endTimesBundle);
+}
+
+template <typename CT>
+void SetValue(const String16 &name, DrmMetricGroup::ValueType type,
+              const CT &value, PersistableBundle *bundle) {
+    switch (type) {
+    case DrmMetricGroup::ValueType::INT64_TYPE:
+        bundle->putLong(name, value.int64Value);
+        break;
+    case DrmMetricGroup::ValueType::DOUBLE_TYPE:
+        bundle->putDouble(name, value.doubleValue);
+        break;
+    case DrmMetricGroup::ValueType::STRING_TYPE:
+        bundle->putString(name, String16(value.stringValue.c_str()));
+        break;
+    default:
+        ALOGE("Unexpected value type: %hhu", type);
+    }
+}
+
+inline String16 MakeIndexString(unsigned int index) {
+  std::string str("[");
+  str.append(std::to_string(index));
+  str.append("]");
+  return String16(str.c_str());
+}
+
+} // namespace
+
+namespace android {
+
+status_t DrmMetricsConsumer::consumeFrameworkMetrics(const MediaDrmMetrics &metrics) {
+    ExportCounterMetric(metrics.mOpenSessionCounter, mBundle);
+    ExportCounterMetric(metrics.mCloseSessionCounter, mBundle);
+    ExportEventMetric(metrics.mGetKeyRequestTimeUs, mBundle);
+    ExportEventMetric(metrics.mProvideKeyResponseTimeUs, mBundle);
+    ExportCounterMetric(metrics.mGetProvisionRequestCounter, mBundle);
+    ExportCounterMetric(metrics.mProvideProvisionResponseCounter, mBundle);
+    ExportCounterMetricWithAttributeNames(metrics.mKeyStatusChangeCounter, mBundle);
+    ExportCounterMetricWithAttributeNames(metrics.mEventCounter, mBundle);
+    ExportCounterMetric(metrics.mGetDeviceUniqueIdCounter, mBundle);
+    ExportSessionLifespans(metrics.GetSessionLifespans(), mBundle);
+    return android::OK;
+}
+
+status_t DrmMetricsConsumer::consumeHidlMetrics(
+        const String8 &vendor,
+        const hidl_vec<DrmMetricGroup> &pluginMetrics) {
+    PersistableBundle pluginBundle;
+    if (DrmMetricsConsumer::HidlMetricsToBundle(
+            pluginMetrics, &pluginBundle) == OK) {
+        mBundle->putPersistableBundle(String16(vendor), pluginBundle);
+    }
+    return android::OK;
+}
+
+status_t DrmMetricsConsumer::HidlMetricsToBundle(
+    const hidl_vec<DrmMetricGroup> &hidlMetricGroups,
+    PersistableBundle *bundleMetricGroups) {
+    if (bundleMetricGroups == nullptr) {
+        return UNEXPECTED_NULL;
+    }
+    if (hidlMetricGroups.size() == 0) {
+        return OK;
+    }
+
+    int groupIndex = 0;
+    std::map<String16, int> indexMap;
+    for (const auto &hidlMetricGroup : hidlMetricGroups) {
+        PersistableBundle bundleMetricGroup;
+        for (const auto &hidlMetric : hidlMetricGroup.metrics) {
+            String16 metricName(hidlMetric.name.c_str());
+            PersistableBundle bundleMetric;
+            // Add metric component values.
+            for (const auto &value : hidlMetric.values) {
+                SetValue(String16(value.componentName.c_str()), value.type,
+                         value, &bundleMetric);
+            }
+            // Set metric attributes.
+            PersistableBundle bundleMetricAttributes;
+            for (const auto &attribute : hidlMetric.attributes) {
+                SetValue(String16(attribute.name.c_str()), attribute.type,
+                         attribute, &bundleMetricAttributes);
+            }
+            // Add attributes to the bundle metric.
+            bundleMetric.putPersistableBundle(String16("attributes"),
+                                              bundleMetricAttributes);
+            // Add one layer of indirection, allowing for repeated metric names.
+            PersistableBundle repeatedMetrics;
+            bundleMetricGroup.getPersistableBundle(metricName,
+                                                   &repeatedMetrics);
+            int index = indexMap[metricName];
+            repeatedMetrics.putPersistableBundle(MakeIndexString(index),
+                                                 bundleMetric);
+            indexMap[metricName] = ++index;
+
+            // Add the bundle metric to the group of metrics.
+            bundleMetricGroup.putPersistableBundle(metricName,
+                                                   repeatedMetrics);
+        }
+        // Add the bundle metric group to the collection of groups.
+        bundleMetricGroups->putPersistableBundle(MakeIndexString(groupIndex++),
+                                                 bundleMetricGroup);
+    }
+
+    return OK;
+}
+
+} // namespace android
+
diff --git a/drm/libmediadrm/DrmUtils.cpp b/drm/libmediadrm/DrmUtils.cpp
index a126a1d..3549637 100644
--- a/drm/libmediadrm/DrmUtils.cpp
+++ b/drm/libmediadrm/DrmUtils.cpp
@@ -75,7 +75,7 @@
             auto factory = Hal::getService(instance);
             if (factory != nullptr) {
                 ALOGI("found %s %s", Hal::descriptor, instance.c_str());
-                if (factory->isCryptoSchemeSupported(uuid)) {
+                if (!uuid || factory->isCryptoSchemeSupported(uuid)) {
                     factories.push_back(factory);
                 }
             }
diff --git a/drm/libmediadrm/include/mediadrm/BundleDrmMetricsConsumer.h b/drm/libmediadrm/include/mediadrm/BundleDrmMetricsConsumer.h
deleted file mode 100644
index 1bcb352..0000000
--- a/drm/libmediadrm/include/mediadrm/BundleDrmMetricsConsumer.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2019 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 <binder/PersistableBundle.h>
-#include <mediadrm/IDrmMetricsConsumer.h>
-#include <utils/Errors.h>
-
-#ifndef ANDROID_BUNDLEMETRICSCONSUMER_H_
-
-#define ANDROID_BUNDLEMETRICSCONSUMER_H_
-
-namespace android {
-
-/**
- * IDrmMetricsConsumer which saves IDrm/ICrypto metrics into a PersistableBundle.
- *
- * Example usage:
- *
- *   PersistableBundle bundle;
- *   BundleDrmMetricsConsumer consumer(&bundle);
- *   drm->exportMetrics(&consumer);
- *   crypto->exportMetrics(&consumer);
- *   // bundle now contains metrics from drm/crypto.
- *
- */
-struct BundleDrmMetricsConsumer : public IDrmMetricsConsumer {
-    BundleDrmMetricsConsumer(os::PersistableBundle*) {}
-
-    status_t consumeFrameworkMetrics(const MediaDrmMetrics &) override {
-        return OK;
-    }
-
-    status_t consumeHidlMetrics(
-            const String8 &/*vendor*/,
-            const hidl_vec<DrmMetricGroup> &/*pluginMetrics*/) override {
-        return OK;
-    }
-
-private:
-    DISALLOW_EVIL_CONSTRUCTORS(BundleDrmMetricsConsumer);
-};
-
-}  // namespace android
-
-#endif // ANDROID_BUNDLEMETRICSCONSUMER_H_
diff --git a/drm/libmediadrm/include/mediadrm/DrmHal.h b/drm/libmediadrm/include/mediadrm/DrmHal.h
index f261d89..3b4639b 100644
--- a/drm/libmediadrm/include/mediadrm/DrmHal.h
+++ b/drm/libmediadrm/include/mediadrm/DrmHal.h
@@ -30,6 +30,7 @@
 #include <mediadrm/DrmSessionManager.h>
 #include <mediadrm/IDrm.h>
 #include <mediadrm/IDrmClient.h>
+#include <mediadrm/IDrmMetricsConsumer.h>
 #include <utils/threads.h>
 
 namespace drm = ::android::hardware::drm;
@@ -136,7 +137,7 @@
     virtual status_t setPropertyString(String8 const &name, String8 const &value ) const;
     virtual status_t setPropertyByteArray(String8 const &name,
                                           Vector<uint8_t> const &value ) const;
-    virtual status_t getMetrics(os::PersistableBundle *metrics);
+    virtual status_t getMetrics(const sp<IDrmMetricsConsumer> &consumer);
 
     virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
                                         String8 const &algorithm);
@@ -197,7 +198,7 @@
     mutable Mutex mEventLock;
     mutable Mutex mNotifyLock;
 
-    const Vector<sp<IDrmFactory>> mFactories;
+    const std::vector<sp<IDrmFactory>> mFactories;
     sp<IDrmPlugin> mPlugin;
     sp<drm::V1_1::IDrmPlugin> mPluginV1_1;
     sp<drm::V1_2::IDrmPlugin> mPluginV1_2;
@@ -218,7 +219,7 @@
      */
     status_t mInitCheck;
 
-    Vector<sp<IDrmFactory>> makeDrmFactories();
+    std::vector<sp<IDrmFactory>> makeDrmFactories();
     sp<IDrmPlugin> makeDrmPlugin(const sp<IDrmFactory>& factory,
             const uint8_t uuid[16], const String8& appPackageName);
 
diff --git a/drm/libmediadrm/include/mediadrm/DrmMetrics.h b/drm/libmediadrm/include/mediadrm/DrmMetrics.h
index 833ffa4..100b8f7 100644
--- a/drm/libmediadrm/include/mediadrm/DrmMetrics.h
+++ b/drm/libmediadrm/include/mediadrm/DrmMetrics.h
@@ -75,55 +75,14 @@
   void SetAppUid(uid_t appUid) { mAppUid = appUid; }
   uid_t GetAppUid() const { return mAppUid; }
 
-  // Export the metrics to a PersistableBundle.
-  void Export(os::PersistableBundle* metricsBundle);
-
   // Get the serialized metrics. Metrics are formatted as a serialized
   // DrmFrameworkMetrics proto. If there is a failure serializing the metrics,
   // this returns an error. The parameter |serlializedMetrics| is owned by the
   // caller and must not be null.
   status_t GetSerializedMetrics(std::string* serializedMetrics);
 
-  // Converts the DRM plugin metrics to a PersistableBundle. All of the metrics
-  // found in |pluginMetrics| are added to the |metricsBundle| parameter.
-  // |pluginBundle| is owned by the caller and must not be null.
-  //
-  // Each item in the pluginMetrics vector is added as a new PersistableBundle. E.g.
-  // DrmMetricGroup {
-  //   metrics[0] {
-  //     name: "buf_copy"
-  //     attributes[0] {
-  //       name: "size"
-  //       type: INT64_TYPE
-  //       int64Value: 1024
-  //     }
-  //     values[0] {
-  //       componentName: "operation_count"
-  //       type: INT64_TYPE
-  //       int64Value: 75
-  //     }
-  //     values[1] {
-  //       component_name: "average_time_seconds"
-  //       type: DOUBLE_TYPE
-  //       doubleValue: 0.00000042
-  //     }
-  //   }
-  // }
-  //
-  // becomes
-  //
-  // metricsBundle {
-  //   "0": (PersistableBundle) {
-  //     "attributes" : (PersistableBundle) {
-  //       "size" : (int64) 1024
-  //     }
-  //     "operation_count" : (int64) 75
-  //     "average_time_seconds" : (double) 0.00000042
-  //   }
-  //
-  static status_t HidlMetricsToBundle(
-          const hardware::hidl_vec<hardware::drm::V1_1::DrmMetricGroup>& pluginMetrics,
-          os::PersistableBundle* metricsBundle);
+  // Get copy of session lifetimes.
+  std::map<std::string, std::pair<int64_t, int64_t>> GetSessionLifespans() const;
 
  protected:
   // This is visible for testing only.
diff --git a/drm/libmediadrm/include/mediadrm/DrmMetricsConsumer.h b/drm/libmediadrm/include/mediadrm/DrmMetricsConsumer.h
new file mode 100644
index 0000000..bbbf4b5
--- /dev/null
+++ b/drm/libmediadrm/include/mediadrm/DrmMetricsConsumer.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2019 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 <binder/PersistableBundle.h>
+#include <mediadrm/IDrmMetricsConsumer.h>
+#include <utils/Errors.h>
+
+#ifndef ANDROID_METRICSCONSUMER_H_
+
+#define ANDROID_METRICSCONSUMER_H_
+
+namespace android {
+
+/**
+ * IDrmMetricsConsumer which saves IDrm/ICrypto metrics into a PersistableBundle.
+ *
+ * Example usage:
+ *
+ *   PersistableBundle bundle;
+ *   DrmMetricsConsumer consumer(&bundle);
+ *   drm->exportMetrics(&consumer);
+ *   crypto->exportMetrics(&consumer);
+ *   // bundle now contains metrics from drm/crypto.
+ *
+ */
+struct DrmMetricsConsumer : public IDrmMetricsConsumer {
+    DrmMetricsConsumer(os::PersistableBundle *bundle) : mBundle(bundle) {}
+
+    status_t consumeFrameworkMetrics(const MediaDrmMetrics &) override;
+
+    status_t consumeHidlMetrics(
+            const String8 &/*vendor*/,
+            const hidl_vec<DrmMetricGroup> &/*pluginMetrics*/) override;
+
+    // Converts the DRM plugin metrics to a PersistableBundle. All of the metrics
+    // found in |pluginMetrics| are added to the |metricsBundle| parameter.
+    // |pluginBundle| is owned by the caller and must not be null.
+    //
+    // Each item in the pluginMetrics vector is added as a new PersistableBundle. E.g.
+    // DrmMetricGroup {
+    //   metrics[0] {
+    //     name: "buf_copy"
+    //     attributes[0] {
+    //       name: "size"
+    //       type: INT64_TYPE
+    //       int64Value: 1024
+    //     }
+    //     values[0] {
+    //       componentName: "operation_count"
+    //       type: INT64_TYPE
+    //       int64Value: 75
+    //     }
+    //     values[1] {
+    //       component_name: "average_time_seconds"
+    //       type: DOUBLE_TYPE
+    //       doubleValue: 0.00000042
+    //     }
+    //   }
+    // }
+    //
+    // becomes
+    //
+    // metricsBundle {
+    //   "0": (PersistableBundle) {
+    //     "attributes" : (PersistableBundle) {
+    //       "size" : (int64) 1024
+    //     }
+    //     "operation_count" : (int64) 75
+    //     "average_time_seconds" : (double) 0.00000042
+    //   }
+    //
+    static status_t HidlMetricsToBundle(
+            const hardware::hidl_vec<hardware::drm::V1_1::DrmMetricGroup>& pluginMetrics,
+            os::PersistableBundle* metricsBundle);
+
+private:
+    os::PersistableBundle *mBundle;
+    DISALLOW_EVIL_CONSTRUCTORS(DrmMetricsConsumer);
+};
+
+}  // namespace android
+
+#endif // ANDROID_METRICSCONSUMER_H_
diff --git a/drm/libmediadrm/include/mediadrm/IDrm.h b/drm/libmediadrm/include/mediadrm/IDrm.h
index 4103d5d..0177c24 100644
--- a/drm/libmediadrm/include/mediadrm/IDrm.h
+++ b/drm/libmediadrm/include/mediadrm/IDrm.h
@@ -14,11 +14,10 @@
  * limitations under the License.
  */
 
-#include <binder/IInterface.h>
-#include <binder/PersistableBundle.h>
 #include <media/stagefright/foundation/ABase.h>
 #include <media/drm/DrmAPI.h>
 #include <mediadrm/IDrmClient.h>
+#include <mediadrm/IDrmMetricsConsumer.h>
 
 #ifndef ANDROID_IDRM_H_
 
@@ -107,7 +106,7 @@
     virtual status_t setPropertyByteArray(String8 const &name,
                                           Vector<uint8_t> const &value) const = 0;
 
-    virtual status_t getMetrics(os::PersistableBundle *metrics) = 0;
+    virtual status_t getMetrics(const sp<IDrmMetricsConsumer> &consumer) = 0;
 
     virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
                                         String8 const &algorithm) = 0;
diff --git a/drm/libmediadrm/include/mediadrm/IDrmMetricsConsumer.h b/drm/libmediadrm/include/mediadrm/IDrmMetricsConsumer.h
index efa61d8..aef35c3 100644
--- a/drm/libmediadrm/include/mediadrm/IDrmMetricsConsumer.h
+++ b/drm/libmediadrm/include/mediadrm/IDrmMetricsConsumer.h
@@ -55,8 +55,8 @@
  * ----------------------------------------
  *
  * For an example implementation of IDrmMetricsConsumer, please
- * see BundleDrmMetricsConsumer. BundleDrmMetricsConsumer consumes
- * IDrm/ICrypto metrics and saves the metrics to a PersistableBundle.
+ * see DrmMetricsConsumer. DrmMetricsConsumer consumes IDrm/ICrypto
+ * metrics and saves the metrics to a PersistableBundle.
  *
  */
 struct IDrmMetricsConsumer : public RefBase {
diff --git a/drm/libmediadrm/interface/mediadrm/DrmUtils.h b/drm/libmediadrm/interface/mediadrm/DrmUtils.h
index 3017274..20b3fe9 100644
--- a/drm/libmediadrm/interface/mediadrm/DrmUtils.h
+++ b/drm/libmediadrm/interface/mediadrm/DrmUtils.h
@@ -21,7 +21,6 @@
 #include <android/hardware/drm/1.0/IDrmFactory.h>
 #include <utils/Errors.h>  // for status_t
 #include <utils/StrongPointer.h>
-#include <binder/Parcel.h>
 #include <vector>
 
 using namespace ::android::hardware::drm;
@@ -39,17 +38,17 @@
 
 sp<ICrypto> MakeCrypto(status_t *pstatus = nullptr);
 
-template<typename BA>
-void WriteByteArray(Parcel &obj, const BA &vec) {
+template<typename BA, typename PARCEL>
+void WriteByteArray(PARCEL &obj, const BA &vec) {
     obj.writeInt32(vec.size());
     if (vec.size()) {
         obj.write(vec.data(), vec.size());
     }
 }
 
-template<typename ET, typename BA>
+template<typename ET, typename BA, typename PARCEL>
 void WriteEventToParcel(
-        Parcel &obj,
+        PARCEL &obj,
         ET eventType,
         const BA &sessionId,
         const BA &data) {
@@ -58,18 +57,18 @@
     obj.writeInt32(eventType);
 }
 
-template<typename BA>
+template<typename BA, typename PARCEL>
 void WriteExpirationUpdateToParcel(
-        Parcel &obj,
+        PARCEL &obj,
         const BA &sessionId,
         int64_t expiryTimeInMS) {
     WriteByteArray(obj, sessionId);
     obj.writeInt64(expiryTimeInMS);
 }
 
-template<typename BA, typename KSL>
+template<typename BA, typename KSL, typename PARCEL>
 void WriteKeysChange(
-        Parcel &obj,
+        PARCEL &obj,
         const BA &sessionId,
         const KSL &keyStatusList,
         bool hasNewUsableKey) {
@@ -82,7 +81,7 @@
     obj.writeInt32(hasNewUsableKey);
 }
 
-std::vector<sp<::V1_0::IDrmFactory>> MakeDrmFactories(const uint8_t uuid[16]);
+std::vector<sp<::V1_0::IDrmFactory>> MakeDrmFactories(const uint8_t uuid[16] = nullptr);
 
 std::vector<sp<::V1_0::IDrmPlugin>> MakeDrmPlugins(const uint8_t uuid[16],
                                                    const char *appPackageName);
diff --git a/drm/libmediadrm/tests/Android.bp b/drm/libmediadrm/tests/Android.bp
index 2e39943..7471e05 100644
--- a/drm/libmediadrm/tests/Android.bp
+++ b/drm/libmediadrm/tests/Android.bp
@@ -24,6 +24,8 @@
       "libbinder",
       "libhidlbase",
       "liblog",
+      "libmediadrm",
+      "libmediadrmmetrics_consumer",
       "libmediadrmmetrics_full",
       "libmediametrics",
       "libprotobuf-cpp-full",
diff --git a/drm/libmediadrm/tests/DrmMetrics_test.cpp b/drm/libmediadrm/tests/DrmMetrics_test.cpp
index 5c8a1b0..f362d60 100644
--- a/drm/libmediadrm/tests/DrmMetrics_test.cpp
+++ b/drm/libmediadrm/tests/DrmMetrics_test.cpp
@@ -16,6 +16,7 @@
 
 #define LOG_TAG "DrmMetricsTest"
 #include "mediadrm/DrmMetrics.h"
+#include "mediadrm/DrmMetricsConsumer.h"
 
 #include <android/hardware/drm/1.0/types.h>
 #include <android/hardware/drm/1.1/types.h>
@@ -58,8 +59,9 @@
 TEST_F(MediaDrmMetricsTest, EmptySuccess) {
   MediaDrmMetrics metrics;
   PersistableBundle bundle;
+  DrmMetricsConsumer consumer(&bundle);
 
-  metrics.Export(&bundle);
+  consumer.consumeFrameworkMetrics(metrics);
   EXPECT_TRUE(bundle.empty());
 }
 
@@ -85,8 +87,9 @@
   metrics.mEventCounter.Increment(EventType::PROVISION_REQUIRED);
 
   PersistableBundle bundle;
+  DrmMetricsConsumer consumer(&bundle);
 
-  metrics.Export(&bundle);
+  consumer.consumeFrameworkMetrics(metrics);
   EXPECT_EQ(11U, bundle.size());
 
   // Verify the list of pairs of int64 metrics.
@@ -174,7 +177,8 @@
   metrics.SetSessionEnd(sessionId1);
 
   PersistableBundle bundle;
-  metrics.Export(&bundle);
+  DrmMetricsConsumer consumer(&bundle);
+  consumer.consumeFrameworkMetrics(metrics);
   EXPECT_EQ(35U, bundle.size());
 
   // Verify the list of pairs of int64 metrics.
@@ -421,7 +425,7 @@
   hidl_vec<DrmMetricGroup> hidlMetricGroups;
   PersistableBundle bundleMetricGroups;
 
-  ASSERT_EQ(OK, MediaDrmMetrics::HidlMetricsToBundle(hidlMetricGroups, &bundleMetricGroups));
+  ASSERT_EQ(OK, DrmMetricsConsumer::HidlMetricsToBundle(hidlMetricGroups, &bundleMetricGroups));
   ASSERT_EQ(0U, bundleMetricGroups.size());
 }
 
@@ -441,7 +445,7 @@
           } } };
 
   PersistableBundle bundleMetricGroups;
-  ASSERT_EQ(OK, MediaDrmMetrics::HidlMetricsToBundle(hidl_vec<DrmMetricGroup>({hidlMetricGroup}),
+  ASSERT_EQ(OK, DrmMetricsConsumer::HidlMetricsToBundle(hidl_vec<DrmMetricGroup>({hidlMetricGroup}),
                                                      &bundleMetricGroups));
   ASSERT_EQ(1U, bundleMetricGroups.size());
   PersistableBundle bundleMetricGroup;
diff --git a/include/media/DataSource.h b/include/media/DataSource.h
deleted file mode 120000
index 198b27e..0000000
--- a/include/media/DataSource.h
+++ /dev/null
@@ -1 +0,0 @@
-stagefright/DataSource.h
\ No newline at end of file
diff --git a/media/libstagefright/include/media/stagefright/DataSource.h b/include/media/DataSource.h
similarity index 97%
rename from media/libstagefright/include/media/stagefright/DataSource.h
rename to include/media/DataSource.h
index 83d3e5d..8efa809 100644
--- a/media/libstagefright/include/media/stagefright/DataSource.h
+++ b/include/media/DataSource.h
@@ -19,14 +19,14 @@
 #define DATA_SOURCE_H_
 
 #include <sys/types.h>
+
+#include <android/IDataSource.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/DataSourceBase.h>
-#include <media/IDataSource.h>
 #include <media/MediaExtractorPluginApi.h>
 #include <utils/Errors.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
-#include <drm/DrmManagerClient.h>
 
 
 namespace android {
diff --git a/media/codec2/hidl/services/vendor.cpp b/media/codec2/hidl/services/vendor.cpp
index 65bb6f7..81bffeb 100644
--- a/media/codec2/hidl/services/vendor.cpp
+++ b/media/codec2/hidl/services/vendor.cpp
@@ -23,7 +23,9 @@
 #include <hidl/HidlTransportSupport.h>
 #include <minijail.h>
 
+#include <util/C2InterfaceHelper.h>
 #include <C2Component.h>
+#include <C2Config.h>
 
 // This is the absolute on-device path of the prebuild_etc module
 // "android.hardware.media.c2@1.1-default-seccomp_policy" in Android.bp.
@@ -37,11 +39,14 @@
         "/vendor/etc/seccomp_policy/"
         "android.hardware.media.c2@1.1-extended-seccomp-policy";
 
-class DummyC2Store : public C2ComponentStore {
+class StoreImpl : public C2ComponentStore {
 public:
-    DummyC2Store() = default;
+    StoreImpl()
+        : mReflectorHelper(std::make_shared<C2ReflectorHelper>()),
+          mInterface(mReflectorHelper) {
+    }
 
-    virtual ~DummyC2Store() override = default;
+    virtual ~StoreImpl() override = default;
 
     virtual C2String getName() const override {
         return "default";
@@ -71,31 +76,69 @@
     }
 
     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;
+        const std::vector<C2Param*>& stackParams,
+        const std::vector<C2Param::Index>& heapParamIndices,
+        std::vector<std::unique_ptr<C2Param>>* const heapParams) const override {
+        return mInterface.query(stackParams, heapParamIndices, C2_MAY_BLOCK, heapParams);
     }
 
     virtual c2_status_t config_sm(
-            const std::vector<C2Param*>& /* params */,
-            std::vector<std::unique_ptr<C2SettingResult>>* const /* failures */) override {
-        return C2_OMITTED;
+            const std::vector<C2Param*>& params,
+            std::vector<std::unique_ptr<C2SettingResult>>* const failures) override {
+        return mInterface.config(params, C2_MAY_BLOCK, failures);
     }
 
     virtual std::shared_ptr<C2ParamReflector> getParamReflector() const override {
-        return nullptr;
+        return mReflectorHelper;
     }
 
     virtual c2_status_t querySupportedParams_nb(
-            std::vector<std::shared_ptr<C2ParamDescriptor>>* const /* params */) const override {
-        return C2_OMITTED;
+            std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const override {
+        return mInterface.querySupportedParams(params);
     }
 
     virtual c2_status_t querySupportedValues_sm(
-            std::vector<C2FieldSupportedValuesQuery>& /* fields */) const override {
-        return C2_OMITTED;
+            std::vector<C2FieldSupportedValuesQuery>& fields) const override {
+        return mInterface.querySupportedValues(fields, C2_MAY_BLOCK);
     }
+
+private:
+    class Interface : public C2InterfaceHelper {
+    public:
+        Interface(const std::shared_ptr<C2ReflectorHelper> &helper)
+            : C2InterfaceHelper(helper) {
+            setDerivedInstance(this);
+
+            addParameter(
+                DefineParam(mIonUsageInfo, "ion-usage")
+                .withDefault(new C2StoreIonUsageInfo())
+                .withFields({
+                    C2F(mIonUsageInfo, usage).flags(
+                            {C2MemoryUsage::CPU_READ | C2MemoryUsage::CPU_WRITE}),
+                    C2F(mIonUsageInfo, capacity).inRange(0, UINT32_MAX, 1024),
+                    C2F(mIonUsageInfo, heapMask).any(),
+                    C2F(mIonUsageInfo, allocFlags).flags({}),
+                    C2F(mIonUsageInfo, minAlignment).equalTo(0)
+                })
+                .withSetter(SetIonUsage)
+                .build());
+        }
+
+        virtual ~Interface() = default;
+
+    private:
+        static C2R SetIonUsage(bool /* mayBlock */, C2P<C2StoreIonUsageInfo> &me) {
+            // Vendor's TODO: put appropriate mapping logic
+            me.set().heapMask = ~0;
+            me.set().allocFlags = 0;
+            me.set().minAlignment = 0;
+            return C2R::Ok();
+        }
+
+        std::shared_ptr<C2StoreIonUsageInfo> mIonUsageInfo;
+    };
+    std::shared_ptr<C2ReflectorHelper> mReflectorHelper;
+    Interface mInterface;
 };
 
 int main(int /* argc */, char** /* argv */) {
@@ -124,7 +167,7 @@
         //         /* implementation of C2ComponentStore */);
         LOG(DEBUG) << "Instantiating Codec2's IComponentStore service...";
         store = new utils::ComponentStore(
-                std::make_shared<DummyC2Store>());
+                std::make_shared<StoreImpl>());
 
         if (store == nullptr) {
             LOG(ERROR) << "Cannot create Codec2's IComponentStore service.";
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index c78cdc1..31e5406 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -1524,7 +1524,9 @@
 
     {
         Mutexed<State>::Locked state(mState);
-        state->set(FLUSHED);
+        if (state->get() == FLUSHING) {
+            state->set(FLUSHED);
+        }
     }
     mCallback->onFlushCompleted();
 }
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 39f3f35..2bcb7e2 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -826,10 +826,8 @@
     bool secure = mComponent->getName().find(".secure") != std::string::npos;
 
     std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore();
-    int poolMask = property_get_int32(
-            "debug.stagefright.c2-poolmask",
-            1 << C2PlatformAllocatorStore::ION |
-            1 << C2PlatformAllocatorStore::BUFFERQUEUE);
+    int poolMask = GetCodec2PoolMask();
+    C2PlatformAllocatorStore::id_t preferredLinearId = GetPreferredLinearAllocatorId(poolMask);
 
     if (inputFormat != nullptr) {
         bool graphic = (iStreamFormat.value == C2BufferData::GRAPHIC);
@@ -839,7 +837,7 @@
 
             // set default allocator ID.
             pools->inputAllocatorId = (graphic) ? C2PlatformAllocatorStore::GRALLOC
-                                                : C2PlatformAllocatorStore::ION;
+                                                : preferredLinearId;
 
             // query C2PortAllocatorsTuning::input from component. If an allocator ID is obtained
             // from component, create the input block pool with given ID. Otherwise, use default IDs.
@@ -978,7 +976,7 @@
 
             // set default allocator ID.
             pools->outputAllocatorId = (graphic) ? C2PlatformAllocatorStore::GRALLOC
-                                                 : C2PlatformAllocatorStore::ION;
+                                                 : preferredLinearId;
 
             // query C2PortAllocatorsTuning::output from component, or use default allocator if
             // unsuccessful.
@@ -1670,6 +1668,14 @@
     mMetaMode = mode;
 }
 
+void CCodecBufferChannel::setCrypto(const sp<ICrypto> &crypto) {
+    mCrypto = crypto;
+}
+
+void CCodecBufferChannel::setDescrambler(const sp<IDescrambler> &descrambler) {
+    mDescrambler = descrambler;
+}
+
 status_t toStatusT(c2_status_t c2s, c2_operation_t c2op) {
     // C2_OK is always translated to OK.
     if (c2s == C2_OK) {
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
index c0fa138..82fec18 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.h
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -56,6 +56,9 @@
     virtual ~CCodecBufferChannel();
 
     // BufferChannelBase interface
+    void setCrypto(const sp<ICrypto> &crypto) override;
+    void setDescrambler(const sp<IDescrambler> &descrambler) override;
+
     virtual status_t queueInputBuffer(const sp<MediaCodecBuffer> &buffer) override;
     virtual status_t queueSecureInputBuffer(
             const sp<MediaCodecBuffer> &buffer,
@@ -318,6 +321,9 @@
     std::atomic_bool mInputMetEos;
     std::once_flag mRenderWarningFlag;
 
+    sp<ICrypto> mCrypto;
+    sp<IDescrambler> mDescrambler;
+
     inline bool hasCryptoOrDescrambler() {
         return mCrypto != nullptr || mDescrambler != nullptr;
     }
diff --git a/media/codec2/vndk/Android.bp b/media/codec2/vndk/Android.bp
index 4c529a6..e0b3939 100644
--- a/media/codec2/vndk/Android.bp
+++ b/media/codec2/vndk/Android.bp
@@ -16,6 +16,7 @@
     vendor_available: true,
 
     srcs: [
+        "C2AllocatorBlob.cpp",
         "C2AllocatorIon.cpp",
         "C2AllocatorGralloc.cpp",
         "C2Buffer.cpp",
diff --git a/media/codec2/vndk/C2AllocatorBlob.cpp b/media/codec2/vndk/C2AllocatorBlob.cpp
new file mode 100644
index 0000000..50c9e59
--- /dev/null
+++ b/media/codec2/vndk/C2AllocatorBlob.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2019 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 "C2AllocatorBlob"
+
+#include <C2AllocatorBlob.h>
+#include <C2PlatformSupport.h>
+
+#include <android/hardware/graphics/common/1.2/types.h>
+#include <utils/Log.h>
+
+namespace android {
+
+using ::android::hardware::graphics::common::V1_2::PixelFormat;
+
+constexpr uint32_t kLinearBufferHeight = 1u;
+constexpr uint32_t kLinearBufferFormat = static_cast<uint32_t>(PixelFormat::BLOB);
+
+namespace {
+
+c2_status_t GetCapacityFromHandle(const C2Handle* const grallocHandle, size_t* capacity) {
+    uint32_t width, height, format, stride, generation, igbp_slot;
+    uint64_t usage, igbp_id;
+    _UnwrapNativeCodec2GrallocMetadata(grallocHandle, &width, &height, &format, &usage, &stride,
+                                       &generation, &igbp_id, &igbp_slot);
+
+    if (height != kLinearBufferHeight || format != kLinearBufferFormat) {
+        return C2_BAD_VALUE;
+    }
+    *capacity = width;
+    return C2_OK;
+}
+
+}  // namespace
+
+// C2AllocationBlob is a wrapper for C2AllocationGralloc allocated by C2AllocatorGralloc.
+// C2AllocationBlob::handle() delegates to the backed C2AllocationGralloc::handle().
+class C2AllocationBlob : public C2LinearAllocation {
+public:
+    C2AllocationBlob(std::shared_ptr<C2GraphicAllocation> graphicAllocation, size_t capacity,
+                     C2Allocator::id_t allocatorId);
+    ~C2AllocationBlob() override;
+    c2_status_t map(size_t offset, size_t size, C2MemoryUsage usage, C2Fence* fence,
+                    void** addr /* nonnull */) override;
+    c2_status_t unmap(void* addr, size_t size, C2Fence* fenceFd) override;
+
+    id_t getAllocatorId() const override { return mAllocatorId; }
+    const C2Handle* handle() const override { return mGraphicAllocation->handle(); }
+    bool equals(const std::shared_ptr<C2LinearAllocation>& other) const override {
+        return other && other->handle() == handle();
+    }
+
+private:
+    const std::shared_ptr<C2GraphicAllocation> mGraphicAllocation;
+    const C2Allocator::id_t mAllocatorId;
+};
+
+C2AllocationBlob::C2AllocationBlob(
+        std::shared_ptr<C2GraphicAllocation> graphicAllocation, size_t capacity,
+        C2Allocator::id_t allocatorId)
+      : C2LinearAllocation(capacity),
+        mGraphicAllocation(std::move(graphicAllocation)),
+        mAllocatorId(allocatorId) {}
+
+C2AllocationBlob::~C2AllocationBlob() {}
+
+c2_status_t C2AllocationBlob::map(size_t offset, size_t size, C2MemoryUsage usage,
+                                  C2Fence* fence, void** addr /* nonnull */) {
+    C2PlanarLayout layout;
+    C2Rect rect = C2Rect(size, kLinearBufferHeight).at(offset, 0u);
+    return mGraphicAllocation->map(rect, usage, fence, &layout, reinterpret_cast<uint8_t**>(addr));
+}
+
+c2_status_t C2AllocationBlob::unmap(void* addr, size_t size, C2Fence* fenceFd) {
+    C2Rect rect(size, kLinearBufferHeight);
+    return mGraphicAllocation->unmap(reinterpret_cast<uint8_t**>(&addr), rect, fenceFd);
+}
+
+/* ====================================== BLOB ALLOCATOR ====================================== */
+C2AllocatorBlob::C2AllocatorBlob(id_t id) {
+    C2MemoryUsage minUsage = {0, 0};
+    C2MemoryUsage maxUsage = {C2MemoryUsage::CPU_READ | C2MemoryUsage::READ_PROTECTED,
+                              C2MemoryUsage::CPU_WRITE};
+    Traits traits = {"android.allocator.blob", id, LINEAR, minUsage, maxUsage};
+    mTraits = std::make_shared<C2Allocator::Traits>(traits);
+    auto allocatorStore = GetCodec2PlatformAllocatorStore();
+    allocatorStore->fetchAllocator(C2PlatformAllocatorStore::GRALLOC, &mC2AllocatorGralloc);
+    if (!mC2AllocatorGralloc) {
+        ALOGE("Failed to obtain C2AllocatorGralloc as backed allocator");
+    }
+}
+
+C2AllocatorBlob::~C2AllocatorBlob() {}
+
+c2_status_t C2AllocatorBlob::newLinearAllocation(
+        uint32_t capacity, C2MemoryUsage usage, std::shared_ptr<C2LinearAllocation>* allocation) {
+    if (allocation == nullptr) {
+        return C2_BAD_VALUE;
+    }
+
+    allocation->reset();
+
+    if (!mC2AllocatorGralloc) {
+        return C2_CORRUPTED;
+    }
+
+    std::shared_ptr<C2GraphicAllocation> graphicAllocation;
+    c2_status_t status = mC2AllocatorGralloc->newGraphicAllocation(
+            capacity, kLinearBufferHeight, kLinearBufferFormat, usage, &graphicAllocation);
+    if (status != C2_OK) {
+        ALOGE("Failed newGraphicAllocation");
+        return status;
+    }
+
+    allocation->reset(new C2AllocationBlob(std::move(graphicAllocation),
+                                           static_cast<size_t>(capacity), mTraits->id));
+    return C2_OK;
+}
+
+c2_status_t C2AllocatorBlob::priorLinearAllocation(
+        const C2Handle* handle, std::shared_ptr<C2LinearAllocation>* allocation) {
+    if (allocation == nullptr) {
+        return C2_BAD_VALUE;
+    }
+
+    allocation->reset();
+
+    if (!mC2AllocatorGralloc) {
+        return C2_CORRUPTED;
+    }
+
+    std::shared_ptr<C2GraphicAllocation> graphicAllocation;
+    c2_status_t status = mC2AllocatorGralloc->priorGraphicAllocation(handle, &graphicAllocation);
+    if (status != C2_OK) {
+        ALOGE("Failed priorGraphicAllocation");
+        return status;
+    }
+
+    const C2Handle* const grallocHandle = graphicAllocation->handle();
+    size_t capacity = 0;
+    status = GetCapacityFromHandle(grallocHandle, &capacity);
+    if (status != C2_OK) {
+        ALOGE("Failed to extract capacity from Handle");
+        return status;
+    }
+
+    allocation->reset(new C2AllocationBlob(std::move(graphicAllocation), capacity, mTraits->id));
+    return C2_OK;
+}
+
+id_t C2AllocatorBlob::getId() const {
+    return mTraits->id;
+}
+
+C2String C2AllocatorBlob::getName() const {
+    return mTraits->name;
+}
+
+std::shared_ptr<const C2Allocator::Traits> C2AllocatorBlob::getTraits() const {
+    return mTraits;
+}
+
+// static
+bool C2AllocatorBlob::isValid(const C2Handle* const o) {
+    size_t capacity;
+    // Distinguish C2Handle purely allocated by C2AllocatorGralloc, or one allocated through
+    // C2AllocatorBlob, by checking the handle's height is 1, and its format is
+    // PixelFormat::BLOB by GetCapacityFromHandle().
+    return C2AllocatorGralloc::isValid(o) && GetCapacityFromHandle(o, &capacity) == C2_OK;
+}
+
+}  // namespace android
diff --git a/media/codec2/vndk/C2AllocatorGralloc.cpp b/media/codec2/vndk/C2AllocatorGralloc.cpp
index cd179be..78ac355 100644
--- a/media/codec2/vndk/C2AllocatorGralloc.cpp
+++ b/media/codec2/vndk/C2AllocatorGralloc.cpp
@@ -605,14 +605,11 @@
                           (int32_t)rect.width, (int32_t)rect.height },
                         // TODO: fence
                         hidl_handle(),
-                        [&err, &pointer](const auto &maperr, const auto &mapPointer,
-                                         int32_t bytesPerPixel, int32_t bytesPerStride) {
+                        [&err, &pointer](const auto &maperr, const auto &mapPointer) {
                             err = maperr2error(maperr);
                             if (err == C2_OK) {
                                 pointer = mapPointer;
                             }
-                            (void)bytesPerPixel;
-                            (void)bytesPerStride;
                         }).isOk()) {
                     ALOGE("failed transaction: lock(RGBA_1010102) (@4.0)");
                     return C2_CORRUPTED;
@@ -743,14 +740,11 @@
                           (int32_t)rect.width, (int32_t)rect.height },
                         // TODO: fence
                         hidl_handle(),
-                        [&err, &pointer](const auto &maperr, const auto &mapPointer,
-                                         int32_t bytesPerPixel, int32_t bytesPerStride) {
+                        [&err, &pointer](const auto &maperr, const auto &mapPointer) {
                             err = maperr2error(maperr);
                             if (err == C2_OK) {
                                 pointer = mapPointer;
                             }
-                            (void)bytesPerPixel;
-                            (void)bytesPerStride;
                         }).isOk()) {
                     ALOGE("failed transaction: lock(RGBA_8888) (@4.0)");
                     return C2_CORRUPTED;
@@ -816,6 +810,70 @@
             break;
         }
 
+        case PixelFormat4::BLOB: {
+            void* pointer = nullptr;
+            if (mMapper2) {
+                if (!mMapper2->lock(const_cast<native_handle_t*>(mBuffer), grallocUsage,
+                                    {(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;
+                                        }
+                                    }).isOk()) {
+                    ALOGE("failed transaction: lock(BLOB)");
+                    return C2_CORRUPTED;
+                }
+            } else if (mMapper3) {
+                if (!mMapper3->lock(
+                        const_cast<native_handle_t*>(mBuffer),
+                        grallocUsage,
+                        { (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,
+                                         int32_t bytesPerPixel, int32_t bytesPerStride) {
+                            err = maperr2error(maperr);
+                            if (err == C2_OK) {
+                                pointer = mapPointer;
+                            }
+                            (void)bytesPerPixel;
+                            (void)bytesPerStride;
+                        }).isOk()) {
+                    ALOGE("failed transaction: lock(BLOB) (@3.0)");
+                    return C2_CORRUPTED;
+                }
+            } else {
+                if (!mMapper4->lock(
+                        const_cast<native_handle_t *>(mBuffer),
+                        grallocUsage,
+                        { (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;
+                            }
+                        }).isOk()) {
+                    ALOGE("failed transaction: lock(BLOB) (@4.0)");
+                    return C2_CORRUPTED;
+                }
+            }
+            if (err != C2_OK) {
+                ALOGD("lock failed: %d", err);
+                return err;
+            }
+
+            *addr = static_cast<uint8_t*>(pointer);
+            break;
+        }
+
         case PixelFormat4::YCBCR_420_888:
             // fall-through
         case PixelFormat4::YV12:
@@ -875,27 +933,14 @@
                     return C2_CORRUPTED;
                 }
             } else {
-                if (!mMapper4->lockYCbCr(
-                        const_cast<native_handle_t *>(mBuffer), grallocUsage,
-                        { (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 = YCbCrLayout{
-                                        mapLayout.y,
-                                        mapLayout.cb,
-                                        mapLayout.cr,
-                                        mapLayout.yStride,
-                                        mapLayout.cStride,
-                                        mapLayout.chromaStep};
-                            }
-                        }).isOk()) {
-                    ALOGE("failed transaction: lockYCbCr (@4.0)");
-                    return C2_CORRUPTED;
-                }
+                // No device currently supports IMapper 4.0 so it is safe to just return an error
+                // code here.
+                //
+                // This will be supported by a combination of lock and BufferMetadata getters.
+                // We are going to refactor all the IAllocator/IMapper versioning code into a
+                // shared library. We will then add the IMapper 4.0 lockYCbCr support then.
+                ALOGE("failed transaction: lockYCbCr (@4.0)");
+                return C2_CORRUPTED;
             }
             if (err != C2_OK) {
                 ALOGD("lockYCbCr failed: %d", err);
diff --git a/media/codec2/vndk/C2Buffer.cpp b/media/codec2/vndk/C2Buffer.cpp
index 2d99b53..0b08f31 100644
--- a/media/codec2/vndk/C2Buffer.cpp
+++ b/media/codec2/vndk/C2Buffer.cpp
@@ -22,14 +22,17 @@
 #include <map>
 #include <mutex>
 
-#include <C2AllocatorIon.h>
+#include <C2AllocatorBlob.h>
 #include <C2AllocatorGralloc.h>
+#include <C2AllocatorIon.h>
 #include <C2BufferPriv.h>
 #include <C2BlockInternal.h>
+#include <C2PlatformSupport.h>
 #include <bufferpool/ClientManager.h>
 
 namespace {
 
+using android::C2AllocatorBlob;
 using android::C2AllocatorGralloc;
 using android::C2AllocatorIon;
 using android::hardware::media::bufferpool::BufferPoolData;
@@ -393,10 +396,29 @@
 std::shared_ptr<C2LinearBlock> _C2BlockFactory::CreateLinearBlock(
         const C2Handle *handle) {
     // TODO: get proper allocator? and mutex?
-    static std::unique_ptr<C2AllocatorIon> sAllocator = std::make_unique<C2AllocatorIon>(0);
+    static std::unique_ptr<C2Allocator> sAllocator = []{
+        std::unique_ptr<C2Allocator> allocator;
+        if (android::GetPreferredLinearAllocatorId(android::GetCodec2PoolMask()) ==
+                android::C2PlatformAllocatorStore::BLOB) {
+            allocator = std::make_unique<C2AllocatorBlob>(android::C2PlatformAllocatorStore::BLOB);
+        } else {
+            allocator = std::make_unique<C2AllocatorIon>(android::C2PlatformAllocatorStore::ION);
+        }
+        return allocator;
+    }();
+
+    if (sAllocator == nullptr)
+        return nullptr;
+
+    bool isValidHandle = false;
+    if (sAllocator->getId() == android::C2PlatformAllocatorStore::BLOB) {
+        isValidHandle = C2AllocatorBlob::isValid(handle);
+    } else {
+        isValidHandle = C2AllocatorIon::isValid(handle);
+    }
 
     std::shared_ptr<C2LinearAllocation> alloc;
-    if (C2AllocatorIon::isValid(handle)) {
+    if (isValidHandle) {
         c2_status_t err = sAllocator->priorLinearAllocation(handle, &alloc);
         if (err == C2_OK) {
             std::shared_ptr<C2LinearBlock> block = _C2BlockFactory::CreateLinearBlock(alloc);
@@ -409,10 +431,29 @@
 std::shared_ptr<C2LinearBlock> _C2BlockFactory::CreateLinearBlock(
         const C2Handle *cHandle, const std::shared_ptr<BufferPoolData> &data) {
     // TODO: get proper allocator? and mutex?
-    static std::unique_ptr<C2AllocatorIon> sAllocator = std::make_unique<C2AllocatorIon>(0);
+    static std::unique_ptr<C2Allocator> sAllocator = []{
+        std::unique_ptr<C2Allocator> allocator;
+        if (android::GetPreferredLinearAllocatorId(android::GetCodec2PoolMask()) ==
+                android::C2PlatformAllocatorStore::BLOB) {
+            allocator = std::make_unique<C2AllocatorBlob>(android::C2PlatformAllocatorStore::BLOB);
+        } else {
+            allocator = std::make_unique<C2AllocatorIon>(android::C2PlatformAllocatorStore::ION);
+        }
+        return allocator;
+    }();
+
+    if (sAllocator == nullptr)
+        return nullptr;
+
+    bool isValidHandle = false;
+    if (sAllocator->getId() == android::C2PlatformAllocatorStore::BLOB) {
+        isValidHandle = C2AllocatorBlob::isValid(cHandle);
+    } else {
+        isValidHandle = C2AllocatorIon::isValid(cHandle);
+    }
 
     std::shared_ptr<C2LinearAllocation> alloc;
-    if (C2AllocatorIon::isValid(cHandle)) {
+    if (isValidHandle) {
         c2_status_t err = sAllocator->priorLinearAllocation(cHandle, &alloc);
         const std::shared_ptr<C2PooledBlockPoolData> poolData =
                 std::make_shared<C2PooledBlockPoolData>(data);
diff --git a/media/codec2/vndk/C2Store.cpp b/media/codec2/vndk/C2Store.cpp
index 5b2bd7b..d16527e 100644
--- a/media/codec2/vndk/C2Store.cpp
+++ b/media/codec2/vndk/C2Store.cpp
@@ -18,6 +18,7 @@
 #define LOG_NDEBUG 0
 #include <utils/Log.h>
 
+#include <C2AllocatorBlob.h>
 #include <C2AllocatorGralloc.h>
 #include <C2AllocatorIon.h>
 #include <C2BufferPriv.h>
@@ -26,6 +27,7 @@
 #include <C2Config.h>
 #include <C2PlatformStorePluginLoader.h>
 #include <C2PlatformSupport.h>
+#include <cutils/properties.h>
 #include <util/C2InterfaceHelper.h>
 
 #include <dlfcn.h>
@@ -35,6 +37,10 @@
 #include <memory>
 #include <mutex>
 
+#ifdef __ANDROID_APEX__
+#include <android-base/properties.h>
+#endif
+
 namespace android {
 
 /**
@@ -71,6 +77,9 @@
     ~C2PlatformAllocatorStoreImpl() override = default;
 
 private:
+    /// returns a shared-singleton blob allocator (gralloc-backed)
+    std::shared_ptr<C2Allocator> fetchBlobAllocator();
+
     /// returns a shared-singleton ion allocator
     std::shared_ptr<C2Allocator> fetchIonAllocator();
 
@@ -93,10 +102,12 @@
 c2_status_t C2PlatformAllocatorStoreImpl::fetchAllocator(
         id_t id, std::shared_ptr<C2Allocator> *const allocator) {
     allocator->reset();
+    if (id == C2AllocatorStore::DEFAULT_LINEAR) {
+        id = GetPreferredLinearAllocatorId(GetCodec2PoolMask());
+    }
     switch (id) {
     // TODO: should we implement a generic registry for all, and use that?
     case C2PlatformAllocatorStore::ION:
-    case C2AllocatorStore::DEFAULT_LINEAR:
         *allocator = fetchIonAllocator();
         break;
 
@@ -109,6 +120,10 @@
         *allocator = fetchBufferQueueAllocator();
         break;
 
+    case C2PlatformAllocatorStore::BLOB:
+        *allocator = fetchBlobAllocator();
+        break;
+
     default:
         // Try to create allocator from platform store plugins.
         c2_status_t res =
@@ -218,6 +233,18 @@
     return allocator;
 }
 
+std::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchBlobAllocator() {
+    static std::mutex mutex;
+    static std::weak_ptr<C2Allocator> blobAllocator;
+    std::lock_guard<std::mutex> lock(mutex);
+    std::shared_ptr<C2Allocator> allocator = blobAllocator.lock();
+    if (allocator == nullptr) {
+        allocator = std::make_shared<C2AllocatorBlob>(C2PlatformAllocatorStore::BLOB);
+        blobAllocator = allocator;
+    }
+    return allocator;
+}
+
 std::shared_ptr<C2Allocator> C2PlatformAllocatorStoreImpl::fetchGrallocAllocator() {
     static std::mutex mutex;
     static std::weak_ptr<C2Allocator> grallocAllocator;
@@ -288,6 +315,18 @@
     return gPreferredComponentStore ? gPreferredComponentStore : GetCodec2PlatformComponentStore();
 }
 
+int GetCodec2PoolMask() {
+    return property_get_int32(
+            "debug.stagefright.c2-poolmask",
+            1 << C2PlatformAllocatorStore::ION |
+            1 << C2PlatformAllocatorStore::BUFFERQUEUE);
+}
+
+C2PlatformAllocatorStore::id_t GetPreferredLinearAllocatorId(int poolMask) {
+    return ((poolMask >> C2PlatformAllocatorStore::BLOB) & 1) ? C2PlatformAllocatorStore::BLOB
+                                                              : C2PlatformAllocatorStore::ION;
+}
+
 namespace {
 
 class _C2BlockPoolCache {
@@ -304,11 +343,25 @@
         std::shared_ptr<C2Allocator> allocator;
         c2_status_t res = C2_NOT_FOUND;
 
+        if (allocatorId == C2AllocatorStore::DEFAULT_LINEAR) {
+            allocatorId = GetPreferredLinearAllocatorId(GetCodec2PoolMask());
+        }
         switch(allocatorId) {
             case C2PlatformAllocatorStore::ION:
-            case C2AllocatorStore::DEFAULT_LINEAR:
                 res = allocatorStore->fetchAllocator(
-                        C2AllocatorStore::DEFAULT_LINEAR, &allocator);
+                        C2PlatformAllocatorStore::ION, &allocator);
+                if (res == C2_OK) {
+                    std::shared_ptr<C2BlockPool> ptr =
+                            std::make_shared<C2PooledBlockPool>(
+                                    allocator, poolId);
+                    *pool = ptr;
+                    mBlockPools[poolId] = ptr;
+                    mComponents[poolId] = component;
+                }
+                break;
+            case C2PlatformAllocatorStore::BLOB:
+                res = allocatorStore->fetchAllocator(
+                        C2PlatformAllocatorStore::BLOB, &allocator);
                 if (res == C2_OK) {
                     std::shared_ptr<C2BlockPool> ptr =
                             std::make_shared<C2PooledBlockPool>(
@@ -599,9 +652,33 @@
 
             struct Setter {
                 static C2R setIonUsage(bool /* mayBlock */, C2P<C2StoreIonUsageInfo> &me) {
+#ifdef __ANDROID_APEX__
+                    static int32_t defaultHeapMask = [] {
+                        int32_t heapmask = base::GetIntProperty(
+                                "ro.com.android.media.swcodec.ion.heapmask", int32_t(0xFFFFFFFF));
+                        ALOGD("Default ION heapmask = %d", heapmask);
+                        return heapmask;
+                    }();
+                    static int32_t defaultFlags = [] {
+                        int32_t flags = base::GetIntProperty(
+                                "ro.com.android.media.swcodec.ion.flags", 0);
+                        ALOGD("Default ION flags = %d", flags);
+                        return flags;
+                    }();
+                    static uint32_t defaultAlign = [] {
+                        uint32_t align = base::GetUintProperty(
+                                "ro.com.android.media.swcodec.ion.align", 0u);
+                        ALOGD("Default ION align = %d", align);
+                        return align;
+                    }();
+                    me.set().heapMask = defaultHeapMask;
+                    me.set().allocFlags = defaultFlags;
+                    me.set().minAlignment = defaultAlign;
+#else
                     me.set().heapMask = ~0;
                     me.set().allocFlags = 0;
                     me.set().minAlignment = 0;
+#endif
                     return C2R::Ok();
                 }
             };
diff --git a/media/codec2/vndk/include/C2AllocatorBlob.h b/media/codec2/vndk/include/C2AllocatorBlob.h
new file mode 100644
index 0000000..89ce949
--- /dev/null
+++ b/media/codec2/vndk/include/C2AllocatorBlob.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 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_BLOB_H_
+#define STAGEFRIGHT_CODEC2_ALLOCATOR_BLOB_H_
+
+#include <functional>
+
+#include <C2AllocatorGralloc.h>
+#include <C2Buffer.h>
+
+namespace android {
+
+class C2AllocatorBlob : 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 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;
+
+    C2AllocatorBlob(id_t id);
+
+    virtual ~C2AllocatorBlob() override;
+
+    static bool isValid(const C2Handle* const o);
+
+private:
+    std::shared_ptr<const Traits> mTraits;
+    // Design as C2AllocatorGralloc-backed to unify Gralloc implementations.
+    std::shared_ptr<C2Allocator> mC2AllocatorGralloc;
+};
+
+} // namespace android
+
+#endif // STAGEFRIGHT_CODEC2_ALLOCATOR_BLOB_H_
diff --git a/media/codec2/vndk/include/C2PlatformSupport.h b/media/codec2/vndk/include/C2PlatformSupport.h
index f31282c..a14e0d3 100644
--- a/media/codec2/vndk/include/C2PlatformSupport.h
+++ b/media/codec2/vndk/include/C2PlatformSupport.h
@@ -66,6 +66,15 @@
         BUFFERQUEUE,
 
         /**
+         * ID of the gralloc backed platform allocator for linear blob buffer.
+         *
+         * 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.
+         */
+        BLOB,
+
+        /**
          * ID of indicating the end of platform allocator definition.
          *
          * \note always put this macro in the last place.
@@ -131,6 +140,20 @@
  */
 void SetPreferredCodec2ComponentStore(std::shared_ptr<C2ComponentStore> store);
 
+/**
+ * Returns the pool mask.
+ * \retval the default pool mask should be adopted if it could not be obtained from property
+ *         "debug.stagefright.c2-poolmask"
+ */
+int GetCodec2PoolMask();
+
+/**
+ * Returns the preferred linear buffer allocator id from param poolMask.
+ * C2PlatformAllocatorStore::ION should be chosen as fallback allocator if BLOB is not enabled from
+ * param poolMask.
+ */
+C2PlatformAllocatorStore::id_t GetPreferredLinearAllocatorId(int poolMask);
+
 } // namespace android
 
 #endif // STAGEFRIGHT_CODEC2_PLATFORM_SUPPORT_H_
diff --git a/media/libaaudio/src/Android.bp b/media/libaaudio/src/Android.bp
index 850b1d0..463f606 100644
--- a/media/libaaudio/src/Android.bp
+++ b/media/libaaudio/src/Android.bp
@@ -40,6 +40,20 @@
         "libutils",
         "libbinder",
     ],
+
+    sanitize: {
+        integer_overflow: true,
+        misc_undefined: ["bounds"],
+        diag: {
+            integer_overflow: true,
+            misc_undefined: ["bounds"],
+            no_recover: [
+                "bounds",
+                "integer",
+            ],
+        },
+    },
+
 }
 
 cc_library {
@@ -57,7 +71,7 @@
     export_include_dirs: ["."],
     header_libs: [
         "libaaudio_headers",
-        "libmedia_headers"
+        "libmedia_headers",
     ],
     export_header_lib_headers: ["libaaudio_headers"],
 
@@ -116,4 +130,17 @@
         "flowgraph/SourceI16.cpp",
         "flowgraph/SourceI24.cpp",
     ],
+    sanitize: {
+        integer_overflow: true,
+        misc_undefined: ["bounds"],
+        diag: {
+            integer_overflow: true,
+            misc_undefined: ["bounds"],
+            no_recover: [
+                "bounds",
+                "integer",
+            ],
+        },
+    },
+
 }
diff --git a/media/libaaudio/src/fifo/FifoControllerBase.cpp b/media/libaaudio/src/fifo/FifoControllerBase.cpp
index 66e247f..1dece0e 100644
--- a/media/libaaudio/src/fifo/FifoControllerBase.cpp
+++ b/media/libaaudio/src/fifo/FifoControllerBase.cpp
@@ -33,7 +33,9 @@
 }
 
 fifo_frames_t FifoControllerBase::getFullFramesAvailable() {
-    return (fifo_frames_t) (getWriteCounter() - getReadCounter());
+    fifo_frames_t temp = 0;
+    __builtin_sub_overflow(getWriteCounter(), getReadCounter(), &temp);
+    return temp;
 }
 
 fifo_frames_t FifoControllerBase::getReadIndex() {
@@ -42,7 +44,9 @@
 }
 
 void FifoControllerBase::advanceReadIndex(fifo_frames_t numFrames) {
-    setReadCounter(getReadCounter() + numFrames);
+   fifo_counter_t temp = 0;
+    __builtin_add_overflow(getReadCounter(), numFrames, &temp);
+    setReadCounter(temp);
 }
 
 fifo_frames_t FifoControllerBase::getEmptyFramesAvailable() {
@@ -55,7 +59,9 @@
 }
 
 void FifoControllerBase::advanceWriteIndex(fifo_frames_t numFrames) {
-    setWriteCounter(getWriteCounter() + numFrames);
+    fifo_counter_t temp = 0;
+    __builtin_add_overflow(getWriteCounter(), numFrames, &temp);
+    setWriteCounter(temp);
 }
 
 void FifoControllerBase::setThreshold(fifo_frames_t threshold) {
diff --git a/media/libaudiofoundation/AudioContainers.cpp b/media/libaudiofoundation/AudioContainers.cpp
index 1bfe3f9..31257d5 100644
--- a/media/libaudiofoundation/AudioContainers.cpp
+++ b/media/libaudiofoundation/AudioContainers.cpp
@@ -42,6 +42,13 @@
     return audioDeviceOutAllScoSet;
 }
 
+const DeviceTypeSet& getAudioDeviceOutAllUsbSet() {
+    static const DeviceTypeSet audioDeviceOutAllUsbSet = DeviceTypeSet(
+            std::begin(AUDIO_DEVICE_OUT_ALL_USB_ARRAY),
+            std::end(AUDIO_DEVICE_OUT_ALL_USB_ARRAY));
+    return audioDeviceOutAllUsbSet;
+}
+
 const DeviceTypeSet& getAudioDeviceInAllSet() {
     static const DeviceTypeSet audioDeviceInAllSet = DeviceTypeSet(
             std::begin(AUDIO_DEVICE_IN_ALL_ARRAY),
@@ -49,6 +56,13 @@
     return audioDeviceInAllSet;
 }
 
+const DeviceTypeSet& getAudioDeviceInAllUsbSet() {
+    static const DeviceTypeSet audioDeviceInAllUsbSet = DeviceTypeSet(
+            std::begin(AUDIO_DEVICE_IN_ALL_USB_ARRAY),
+            std::end(AUDIO_DEVICE_IN_ALL_USB_ARRAY));
+    return audioDeviceInAllUsbSet;
+}
+
 bool deviceTypesToString(const DeviceTypeSet &deviceTypes, std::string &str) {
     if (deviceTypes.empty()) {
         str = "Empty device types";
diff --git a/media/libaudiofoundation/include/media/AudioContainers.h b/media/libaudiofoundation/include/media/AudioContainers.h
index 2a3385b..72fda49 100644
--- a/media/libaudiofoundation/include/media/AudioContainers.h
+++ b/media/libaudiofoundation/include/media/AudioContainers.h
@@ -37,7 +37,9 @@
 const DeviceTypeSet& getAudioDeviceOutAllSet();
 const DeviceTypeSet& getAudioDeviceOutAllA2dpSet();
 const DeviceTypeSet& getAudioDeviceOutAllScoSet();
+const DeviceTypeSet& getAudioDeviceOutAllUsbSet();
 const DeviceTypeSet& getAudioDeviceInAllSet();
+const DeviceTypeSet& getAudioDeviceInAllUsbSet();
 
 template<typename T>
 static std::vector<T> Intersection(const std::set<T>& a, const std::set<T>& b) {
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index 8669e2a..e96a68c 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -27,6 +27,7 @@
         "android.hardware.audio.common-util",
         "android.hidl.allocator@1.0",
         "android.hidl.memory@1.0",
+        "libaudiofoundation",
         "libaudiohal_deathhandler",
         "libaudioutils",
         "libbase",
diff --git a/media/libaudiohal/impl/ConversionHelperHidl.cpp b/media/libaudiohal/impl/ConversionHelperHidl.cpp
index 9f8a520..f29b0f3 100644
--- a/media/libaudiohal/impl/ConversionHelperHidl.cpp
+++ b/media/libaudiohal/impl/ConversionHelperHidl.cpp
@@ -17,6 +17,7 @@
 #include <string.h>
 
 #define LOG_TAG "HalHidl"
+#include <media/AudioContainers.h>
 #include <media/AudioParameter.h>
 #include <utils/Log.h>
 
@@ -109,26 +110,22 @@
     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)) {
+    if (getAudioDeviceOutAllA2dpSet().count(halDevice) > 0 ||
+        halDevice == AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
         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)) {
+    } else if (halDevice == AUDIO_DEVICE_OUT_IP || halDevice == AUDIO_DEVICE_IN_IP) {
         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)) {
+    } else if (getAudioDeviceOutAllUsbSet().count(halDevice) > 0 ||
+               getAudioDeviceInAllUsbSet().count(halDevice) > 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)) {
+    } else if (halDevice == AUDIO_DEVICE_OUT_BUS || halDevice == AUDIO_DEVICE_IN_BUS) {
         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)) {
+    } else if (halDevice == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ||
+               halDevice == AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
         snprintf(halAddress, sizeof(halAddress), "%s", address.rSubmixAddress.c_str());
     } else {
         snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index 409a220..d52416c 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -22,6 +22,7 @@
 #include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
 #include <cutils/native_handle.h>
 #include <hwbinder/IPCThreadState.h>
+#include <media/AudioContainers.h>
 #include <utils/Log.h>
 
 #include <common/all-versions/VersionUtils.h>
@@ -51,42 +52,32 @@
     if (halAddress == nullptr || strnlen(halAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
         return OK;
     }
-    const bool isInput = (device & AUDIO_DEVICE_BIT_IN) != 0;
-    if (isInput) device &= ~AUDIO_DEVICE_BIT_IN;
-    if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_A2DP) != 0)
-            || (isInput && (device & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
+    if (getAudioDeviceOutAllA2dpSet().count(device) > 0
+            || device == AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
         int status = sscanf(halAddress,
                 "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX",
                 &address->address.mac[0], &address->address.mac[1], &address->address.mac[2],
                 &address->address.mac[3], &address->address.mac[4], &address->address.mac[5]);
         return status == 6 ? OK : BAD_VALUE;
-    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_IP) != 0)
-            || (isInput && (device & AUDIO_DEVICE_IN_IP) != 0)) {
+    } else if (device == AUDIO_DEVICE_OUT_IP || device == AUDIO_DEVICE_IN_IP) {
         int status = sscanf(halAddress,
                 "%hhu.%hhu.%hhu.%hhu",
                 &address->address.ipv4[0], &address->address.ipv4[1],
                 &address->address.ipv4[2], &address->address.ipv4[3]);
         return status == 4 ? OK : BAD_VALUE;
-    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_USB)) != 0
-            || (isInput && (device & AUDIO_DEVICE_IN_ALL_USB)) != 0) {
+    } else if (getAudioDeviceOutAllUsbSet().count(device) > 0
+            || getAudioDeviceInAllUsbSet().count(device) > 0) {
         int status = sscanf(halAddress,
                 "card=%d;device=%d",
                 &address->address.alsa.card, &address->address.alsa.device);
         return status == 2 ? OK : BAD_VALUE;
-    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_BUS) != 0)
-            || (isInput && (device & AUDIO_DEVICE_IN_BUS) != 0)) {
-        if (halAddress != NULL) {
-            address->busAddress = halAddress;
-            return OK;
-        }
-        return BAD_VALUE;
-    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0
-            || (isInput && (device & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
-        if (halAddress != NULL) {
-            address->rSubmixAddress = halAddress;
-            return OK;
-        }
-        return BAD_VALUE;
+    } else if (device == AUDIO_DEVICE_OUT_BUS || device == AUDIO_DEVICE_IN_BUS) {
+        address->busAddress = halAddress;
+        return OK;
+    } else if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX
+            || device == AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
+        address->rSubmixAddress = halAddress;
+        return OK;
     }
     return OK;
 }
diff --git a/media/libdatasource/include/datasource/HTTPBase.h b/media/libdatasource/include/datasource/HTTPBase.h
index 8b20187..656e85e 100644
--- a/media/libdatasource/include/datasource/HTTPBase.h
+++ b/media/libdatasource/include/datasource/HTTPBase.h
@@ -21,6 +21,7 @@
 #include <media/DataSource.h>
 #include <media/stagefright/foundation/ABase.h>
 #include <media/stagefright/MediaErrors.h>
+#include <utils/KeyedVector.h>
 #include <utils/List.h>
 #include <utils/threads.h>
 
diff --git a/media/libheif/HeifDecoderImpl.cpp b/media/libheif/HeifDecoderImpl.cpp
index b80f4b4..9d79f89 100644
--- a/media/libheif/HeifDecoderImpl.cpp
+++ b/media/libheif/HeifDecoderImpl.cpp
@@ -21,10 +21,10 @@
 
 #include <stdio.h>
 
+#include <android/IDataSource.h>
 #include <binder/IMemory.h>
 #include <binder/MemoryDealer.h>
 #include <drm/drm_framework_common.h>
-#include <media/IDataSource.h>
 #include <media/mediametadataretriever.h>
 #include <media/MediaSource.h>
 #include <media/stagefright/foundation/ADebug.h>
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index b064f08..e8ff463 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -23,6 +23,14 @@
     path: "aidl",
 }
 
+filegroup {
+    name: "mediaextractorservice_aidl",
+    srcs: [
+        "aidl/android/IMediaExtractorService.aidl",
+    ],
+    path: "aidl",
+}
+
 aidl_interface {
     name: "resourcemanager_aidl_interface",
     local_include_dir: "aidl",
@@ -249,13 +257,13 @@
     name: "libmedia",
 
     srcs: [
+        ":mediaextractorservice_aidl",
         "IDataSource.cpp",
         "BufferingSettings.cpp",
         "mediaplayer.cpp",
         "IMediaHTTPConnection.cpp",
         "IMediaHTTPService.cpp",
         "IMediaExtractor.cpp",
-        "IMediaExtractorService.cpp",
         "IMediaPlayerService.cpp",
         "IMediaPlayerClient.cpp",
         "IMediaRecorderClient.cpp",
@@ -305,6 +313,7 @@
         "libprocessgroup",
         "libutils",
         "libbinder",
+        "libbinder_ndk",
         "libsonivox",
         "libandroidicu",
         "libexpat",
@@ -327,11 +336,11 @@
 
     static_libs: [
         "libc_malloc_debug_backtrace", // for memory heap analysis
-        "resourcemanager_aidl_interface-unstable-cpp",
+        "resourcemanager_aidl_interface-ndk_platform",
     ],
 
     export_static_lib_headers: [
-        "resourcemanager_aidl_interface-unstable-cpp",
+        "resourcemanager_aidl_interface-ndk_platform",
     ],
 
     export_include_dirs: [
diff --git a/media/libmedia/IDataSource.cpp b/media/libmedia/IDataSource.cpp
index 61f0a68..e96a113 100644
--- a/media/libmedia/IDataSource.cpp
+++ b/media/libmedia/IDataSource.cpp
@@ -19,8 +19,7 @@
 #include <utils/Log.h>
 #include <utils/Timers.h>
 
-#include <media/IDataSource.h>
-
+#include <android/IDataSource.h>
 #include <binder/IMemory.h>
 #include <binder/Parcel.h>
 #include <media/stagefright/foundation/ADebug.h>
diff --git a/media/libmedia/IMediaExtractor.cpp b/media/libmedia/IMediaExtractor.cpp
index fb6d3a2..7389851 100644
--- a/media/libmedia/IMediaExtractor.cpp
+++ b/media/libmedia/IMediaExtractor.cpp
@@ -25,7 +25,7 @@
 #include <binder/IPCThreadState.h>
 #include <binder/Parcel.h>
 #include <binder/PermissionCache.h>
-#include <media/IMediaExtractor.h>
+#include <android/IMediaExtractor.h>
 #include <media/stagefright/MetaData.h>
 
 namespace android {
diff --git a/media/libmedia/IMediaExtractorService.cpp b/media/libmedia/IMediaExtractorService.cpp
deleted file mode 100644
index 243b09d..0000000
--- a/media/libmedia/IMediaExtractorService.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
-**
-** Copyright 2007, 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 "IMediaExtractorService"
-//#define LOG_NDEBUG 0
-
-#include <utils/Log.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <binder/Parcel.h>
-#include <media/IMediaExtractorService.h>
-
-namespace android {
-
-enum {
-    MAKE_EXTRACTOR = IBinder::FIRST_CALL_TRANSACTION,
-    MAKE_IDATA_SOURCE_FD,
-    GET_SUPPORTED_TYPES,
-};
-
-class BpMediaExtractorService : public BpInterface<IMediaExtractorService>
-{
-public:
-    explicit BpMediaExtractorService(const sp<IBinder>& impl)
-        : BpInterface<IMediaExtractorService>(impl)
-    {
-    }
-
-    virtual sp<IMediaExtractor> makeExtractor(const sp<IDataSource> &source, const char *mime) {
-        Parcel data, reply;
-        data.writeInterfaceToken(IMediaExtractorService::getInterfaceDescriptor());
-        data.writeStrongBinder(IInterface::asBinder(source));
-        if (mime != NULL) {
-            data.writeCString(mime);
-        }
-        status_t ret = remote()->transact(MAKE_EXTRACTOR, data, &reply);
-        if (ret == NO_ERROR) {
-            return interface_cast<IMediaExtractor>(reply.readStrongBinder());
-        }
-        return NULL;
-    }
-
-    virtual sp<IDataSource> makeIDataSource(int fd, int64_t offset, int64_t length)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IMediaExtractorService::getInterfaceDescriptor());
-        data.writeFileDescriptor(fd);
-        data.writeInt64(offset);
-        data.writeInt64(length);
-        status_t ret = remote()->transact(MAKE_IDATA_SOURCE_FD, data, &reply);
-        ALOGV("fd:%d offset:%lld length:%lld ret:%d",
-                fd, (long long)offset, (long long)length, ret);
-        if (ret == NO_ERROR) {
-            return interface_cast<IDataSource>(reply.readStrongBinder());
-        }
-        return nullptr;
-    }
-
-    virtual std::unordered_set<std::string> getSupportedTypes() {
-        std::unordered_set<std::string> supportedTypes;
-        Parcel data, reply;
-        data.writeInterfaceToken(IMediaExtractorService::getInterfaceDescriptor());
-        status_t ret = remote()->transact(GET_SUPPORTED_TYPES, data, &reply);
-        if (ret == NO_ERROR) {
-            // process reply
-            while(true) {
-                const char *ext = reply.readCString();
-                if (!ext) {
-                    break;
-                }
-                supportedTypes.insert(std::string(ext));
-            }
-        }
-        return supportedTypes;
-    }
-};
-
-IMPLEMENT_META_INTERFACE(MediaExtractorService, "android.media.IMediaExtractorService");
-
-// ----------------------------------------------------------------------
-
-status_t BnMediaExtractorService::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch (code) {
-
-        case MAKE_EXTRACTOR: {
-            CHECK_INTERFACE(IMediaExtractorService, data, reply);
-            sp<IBinder> b;
-            status_t ret = data.readStrongBinder(&b);
-            if (ret != NO_ERROR || b == NULL) {
-                ALOGE("Error reading source from parcel");
-                return ret;
-            }
-            // If we make an extractor through Binder, enabled shared memory
-            // for MediaBuffers for this process.
-            MediaBuffer::useSharedMemory();
-            sp<IDataSource> source = interface_cast<IDataSource>(b);
-            const char *mime = data.readCString();
-            sp<IMediaExtractor> ex = makeExtractor(source, mime);
-            reply->writeStrongBinder(IInterface::asBinder(ex));
-            return NO_ERROR;
-        }
-
-        case MAKE_IDATA_SOURCE_FD: {
-            CHECK_INTERFACE(IMediaExtractorService, data, reply);
-            const int fd = dup(data.readFileDescriptor()); // -1 fd checked in makeIDataSource
-            const int64_t offset = data.readInt64();
-            const int64_t length = data.readInt64();
-            ALOGV("fd %d  offset%lld  length:%lld", fd, (long long)offset, (long long)length);
-            sp<IDataSource> source = makeIDataSource(fd, offset, length);
-            reply->writeStrongBinder(IInterface::asBinder(source));
-            // The FileSource closes the descriptor, so if it is not created
-            // we need to close the descriptor explicitly.
-            if (source.get() == nullptr && fd != -1) {
-                close(fd);
-            }
-            return NO_ERROR;
-        }
-
-        case GET_SUPPORTED_TYPES:
-        {
-            CHECK_INTERFACE(IMediaExtractorService, data, reply);
-            std::unordered_set<std::string> supportedTypes = getSupportedTypes();
-            for (auto it = supportedTypes.begin(); it != supportedTypes.end(); ++it) {
-                reply->writeCString((*it).c_str());
-            }
-            return NO_ERROR;
-        }
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-} // namespace android
diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp
index d95bc8e..8a3b84e 100644
--- a/media/libmedia/IMediaMetadataRetriever.cpp
+++ b/media/libmedia/IMediaMetadataRetriever.cpp
@@ -19,8 +19,8 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <android/IDataSource.h>
 #include <binder/Parcel.h>
-#include <media/IDataSource.h>
 #include <media/IMediaHTTPService.h>
 #include <media/IMediaMetadataRetriever.h>
 #include <processgroup/sched_policy.h>
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index ea06665..20bc23d 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -19,18 +19,15 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <android/IDataSource.h>
 #include <binder/Parcel.h>
-
+#include <gui/IGraphicBufferProducer.h>
 #include <media/AudioResamplerPublic.h>
 #include <media/AVSyncSettings.h>
 #include <media/BufferingSettings.h>
-
-#include <media/IDataSource.h>
 #include <media/IMediaHTTPService.h>
 #include <media/IMediaPlayer.h>
 #include <media/IStreamSource.h>
-
-#include <gui/IGraphicBufferProducer.h>
 #include <utils/String8.h>
 
 namespace android {
diff --git a/media/libmedia/MediaResource.cpp b/media/libmedia/MediaResource.cpp
index fe86d27..0936a99 100644
--- a/media/libmedia/MediaResource.cpp
+++ b/media/libmedia/MediaResource.cpp
@@ -35,7 +35,7 @@
     this->value = value;
 }
 
-MediaResource::MediaResource(Type type, const std::vector<uint8_t> &id, int64_t value) {
+MediaResource::MediaResource(Type type, const std::vector<int8_t> &id, int64_t value) {
     this->type = type;
     this->subType = SubType::kUnspecifiedSubType;
     this->id = id;
@@ -66,11 +66,11 @@
 }
 
 //static
-MediaResource MediaResource::DrmSessionResource(const std::vector<uint8_t> &id, int64_t value) {
+MediaResource MediaResource::DrmSessionResource(const std::vector<int8_t> &id, int64_t value) {
     return MediaResource(Type::kDrmSession, id, value);
 }
 
-static String8 bytesToHexString(const std::vector<uint8_t> &bytes) {
+static String8 bytesToHexString(const std::vector<int8_t> &bytes) {
     String8 str;
     for (auto &b : bytes) {
         str.appendFormat("%02x", b);
diff --git a/media/libmedia/MediaResourcePolicy.cpp b/media/libmedia/MediaResourcePolicy.cpp
index c463179..afa971d 100644
--- a/media/libmedia/MediaResourcePolicy.cpp
+++ b/media/libmedia/MediaResourcePolicy.cpp
@@ -16,20 +16,21 @@
 
 //#define LOG_NDEBUG 0
 #define LOG_TAG "MediaResourcePolicy"
-#include <utils/Log.h>
+
+#include <aidl/android/media/IResourceManagerService.h>
 #include <media/MediaResourcePolicy.h>
-#include <android/media/IResourceManagerService.h>
+#include <utils/Log.h>
 
 namespace android {
 
-using android::media::IResourceManagerService;
+using aidl::android::media::IResourceManagerService;
 //static
-const ::std::string& MediaResourcePolicy::kPolicySupportsMultipleSecureCodecs() {
-    return IResourceManagerService::kPolicySupportsMultipleSecureCodecs();
+const char* MediaResourcePolicy::kPolicySupportsMultipleSecureCodecs() {
+    return IResourceManagerService::kPolicySupportsMultipleSecureCodecs;
 }
 //static
-const ::std::string& MediaResourcePolicy::kPolicySupportsSecureWithNonSecureCodec() {
-    return IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec();
+const char* MediaResourcePolicy::kPolicySupportsSecureWithNonSecureCodec() {
+    return IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec;
 }
 
 MediaResourcePolicy::MediaResourcePolicy(
diff --git a/media/libmedia/aidl/android/IDataSource.aidl b/media/libmedia/aidl/android/IDataSource.aidl
new file mode 100644
index 0000000..fb954bf
--- /dev/null
+++ b/media/libmedia/aidl/android/IDataSource.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2019 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 android;
+
+/** @hide */
+interface IDataSource {
+    // Stub for manual implementation
+}
diff --git a/media/libmedia/aidl/android/IMediaExtractor.aidl b/media/libmedia/aidl/android/IMediaExtractor.aidl
new file mode 100644
index 0000000..5ba68e6
--- /dev/null
+++ b/media/libmedia/aidl/android/IMediaExtractor.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2019 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 android;
+
+/** @hide */
+interface IMediaExtractor {
+    // Stub for manual implementation
+}
diff --git a/media/libmedia/aidl/android/IMediaExtractorService.aidl b/media/libmedia/aidl/android/IMediaExtractorService.aidl
new file mode 100644
index 0000000..c57fa16
--- /dev/null
+++ b/media/libmedia/aidl/android/IMediaExtractorService.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 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 android;
+
+import android.IDataSource;
+import android.IMediaExtractor;
+
+/**
+ * Binder interface for the media extractor service
+ *
+ * @hide
+ */
+interface IMediaExtractorService {
+
+    IMediaExtractor makeExtractor(IDataSource source, @nullable @utf8InCpp String mime);
+    IDataSource makeIDataSource(in FileDescriptor fd, long offset, long length);
+    @utf8InCpp String[] getSupportedTypes();
+}
diff --git a/media/libmedia/include/media/IDataSource.h b/media/libmedia/include/android/IDataSource.h
similarity index 100%
rename from media/libmedia/include/media/IDataSource.h
rename to media/libmedia/include/android/IDataSource.h
diff --git a/media/libmedia/include/media/IMediaExtractor.h b/media/libmedia/include/android/IMediaExtractor.h
similarity index 100%
rename from media/libmedia/include/media/IMediaExtractor.h
rename to media/libmedia/include/android/IMediaExtractor.h
diff --git a/media/libmedia/include/media/IMediaExtractorService.h b/media/libmedia/include/media/IMediaExtractorService.h
deleted file mode 100644
index 5ce2cdb..0000000
--- a/media/libmedia/include/media/IMediaExtractorService.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_IMEDIAEXTRACTORSERVICE_H
-#define ANDROID_IMEDIAEXTRACTORSERVICE_H
-
-#include <unordered_set>
-
-#include <binder/IInterface.h>
-#include <binder/IMemory.h>
-#include <binder/Parcel.h>
-#include <media/IDataSource.h>
-#include <media/IMediaExtractor.h>
-
-namespace android {
-
-class IMediaExtractorService: public IInterface
-{
-public:
-    DECLARE_META_INTERFACE(MediaExtractorService);
-
-    virtual sp<IMediaExtractor> makeExtractor(const sp<IDataSource> &source, const char *mime) = 0;
-
-    virtual sp<IDataSource> makeIDataSource(int fd, int64_t offset, int64_t length) = 0;
-
-    virtual std::unordered_set<std::string> getSupportedTypes() = 0;
-};
-
-class BnMediaExtractorService: public BnInterface<IMediaExtractorService>
-{
-public:
-    virtual status_t    onTransact(uint32_t code, const Parcel& data, Parcel* reply,
-                                uint32_t flags = 0);
-};
-
-}   // namespace android
-
-#endif  // ANDROID_IMEDIAEXTRACTORSERVICE_H
diff --git a/media/libmedia/include/media/MediaResource.h b/media/libmedia/include/media/MediaResource.h
index caf03b1..e7362c1 100644
--- a/media/libmedia/include/media/MediaResource.h
+++ b/media/libmedia/include/media/MediaResource.h
@@ -18,13 +18,14 @@
 #ifndef ANDROID_MEDIA_RESOURCE_H
 #define ANDROID_MEDIA_RESOURCE_H
 
-#include <android/media/MediaResourceParcel.h>
+#include <aidl/android/media/MediaResourceParcel.h>
+#include <utils/String8.h>
 
 namespace android {
 
-using android::media::MediaResourceParcel;
-using android::media::MediaResourceSubType;
-using android::media::MediaResourceType;
+using aidl::android::media::MediaResourceParcel;
+using aidl::android::media::MediaResourceSubType;
+using aidl::android::media::MediaResourceType;
 
 class MediaResource : public MediaResourceParcel {
 public:
@@ -34,13 +35,13 @@
     MediaResource() = delete;
     MediaResource(Type type, int64_t value);
     MediaResource(Type type, SubType subType, int64_t value);
-    MediaResource(Type type, const std::vector<uint8_t> &id, int64_t value);
+    MediaResource(Type type, const std::vector<int8_t> &id, int64_t value);
 
     static MediaResource CodecResource(bool secure, bool video);
     static MediaResource GraphicMemoryResource(int64_t value);
     static MediaResource CpuBoostResource();
     static MediaResource VideoBatteryResource();
-    static MediaResource DrmSessionResource(const std::vector<uint8_t> &id, int64_t value);
+    static MediaResource DrmSessionResource(const std::vector<int8_t> &id, int64_t value);
 };
 
 inline static const char *asString(MediaResource::Type i, const char *def = "??") {
diff --git a/media/libmedia/include/media/MediaResourcePolicy.h b/media/libmedia/include/media/MediaResourcePolicy.h
index 7ae1a73..052395b 100644
--- a/media/libmedia/include/media/MediaResourcePolicy.h
+++ b/media/libmedia/include/media/MediaResourcePolicy.h
@@ -18,19 +18,20 @@
 #ifndef ANDROID_MEDIA_RESOURCE_POLICY_H
 #define ANDROID_MEDIA_RESOURCE_POLICY_H
 
-#include <android/media/MediaResourcePolicyParcel.h>
+#include <aidl/android/media/MediaResourcePolicyParcel.h>
+#include <utils/String8.h>
 
 namespace android {
 
-using media::MediaResourcePolicyParcel;
+using aidl::android::media::MediaResourcePolicyParcel;
 
 class MediaResourcePolicy : public MediaResourcePolicyParcel {
 public:
     MediaResourcePolicy() = delete;
     MediaResourcePolicy(const std::string& type, const std::string& value);
 
-    static const ::std::string& kPolicySupportsMultipleSecureCodecs();
-    static const ::std::string& kPolicySupportsSecureWithNonSecureCodec();
+    static const char* kPolicySupportsMultipleSecureCodecs();
+    static const char* kPolicySupportsSecureWithNonSecureCodec();
 };
 
 String8 toString(const MediaResourcePolicyParcel &policy);
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 26908e5..60d2f85 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -17,6 +17,7 @@
 
 //#define LOG_NDEBUG 0
 #define LOG_TAG "MediaPlayerNative"
+#include <utils/Log.h>
 
 #include <fcntl.h>
 #include <inttypes.h>
@@ -24,25 +25,15 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#include <utils/Log.h>
 
-#include <binder/IServiceManager.h>
+#include <android/IDataSource.h>
 #include <binder/IPCThreadState.h>
-
-#include <gui/Surface.h>
-
 #include <media/mediaplayer.h>
 #include <media/AudioResamplerPublic.h>
 #include <media/AudioSystem.h>
 #include <media/AVSyncSettings.h>
-#include <media/IDataSource.h>
-#include <media/MediaAnalyticsItem.h>
-
-#include <binder/MemoryBase.h>
-
 #include <utils/KeyedVector.h>
 #include <utils/String8.h>
-
 #include <system/audio.h>
 #include <system/window.h>
 
diff --git a/media/libmediaplayerservice/StagefrightMetadataRetriever.h b/media/libmediaplayerservice/StagefrightMetadataRetriever.h
index ee51290..c09a501 100644
--- a/media/libmediaplayerservice/StagefrightMetadataRetriever.h
+++ b/media/libmediaplayerservice/StagefrightMetadataRetriever.h
@@ -18,7 +18,7 @@
 
 #define STAGEFRIGHT_METADATA_RETRIEVER_H_
 
-#include <media/IMediaExtractor.h>
+#include <android/IMediaExtractor.h>
 #include <media/MediaMetadataRetrieverInterface.h>
 
 #include <utils/KeyedVector.h>
diff --git a/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceMediaHTTP.h b/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceMediaHTTP.h
index b5124dc..2f94ada 100644
--- a/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceMediaHTTP.h
+++ b/media/libmediaplayerservice/datasource/include/datasource/PlayerServiceMediaHTTP.h
@@ -19,6 +19,7 @@
 #define PLAYER_SERVICE_MEDIA_HTTP_H_
 
 #include <datasource/MediaHTTP.h>
+#include <drm/DrmManagerClient.h>
 #include <media/stagefright/foundation/AString.h>
 
 namespace android {
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 00e3443..a49e72e 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -30,12 +30,13 @@
 #include <media/DataSource.h>
 #include <media/MediaBufferHolder.h>
 #include <media/MediaSource.h>
-#include <media/IMediaExtractorService.h>
+#include <android/IMediaExtractorService.h>
 #include <media/IMediaHTTPService.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/InterfaceUtils.h>
+#include <media/stagefright/FoundationUtils.h>
 #include <media/stagefright/MediaBuffer.h>
 #include <media/stagefright/MediaClock.h>
 #include <media/stagefright/MediaDefs.h>
@@ -75,7 +76,6 @@
       mUIDValid(uidValid),
       mUID(uid),
       mMediaClock(mediaClock),
-      mFd(-1),
       mBitrate(-1LL),
       mPendingReadBufferTypes(0) {
     ALOGV("GenericSource");
@@ -98,10 +98,7 @@
     mUri.clear();
     mUriHeaders.clear();
     mSources.clear();
-    if (mFd >= 0) {
-        close(mFd);
-        mFd = -1;
-    }
+    mFd.reset();
     mOffset = 0;
     mLength = 0;
     mStarted = false;
@@ -137,11 +134,11 @@
 status_t NuPlayer::GenericSource::setDataSource(
         int fd, int64_t offset, int64_t length) {
     Mutex::Autolock _l(mLock);
-    ALOGV("setDataSource %d/%lld/%lld", fd, (long long)offset, (long long)length);
+    ALOGV("setDataSource %d/%lld/%lld (%s)", fd, (long long)offset, (long long)length, nameForFd(fd).c_str());
 
     resetDataSource();
 
-    mFd = dup(fd);
+    mFd.reset(dup(fd));
     mOffset = offset;
     mLength = length;
 
@@ -413,24 +410,19 @@
         } else {
             if (property_get_bool("media.stagefright.extractremote", true) &&
                     !PlayerServiceFileSource::requiresDrm(
-                            mFd, mOffset, mLength, nullptr /* mime */)) {
+                            mFd.get(), mOffset, mLength, nullptr /* mime */)) {
                 sp<IBinder> binder =
                         defaultServiceManager()->getService(String16("media.extractor"));
                 if (binder != nullptr) {
                     ALOGD("FileSource remote");
                     sp<IMediaExtractorService> mediaExService(
                             interface_cast<IMediaExtractorService>(binder));
-                    sp<IDataSource> source =
-                            mediaExService->makeIDataSource(mFd, mOffset, mLength);
+                    sp<IDataSource> source;
+                    mediaExService->makeIDataSource(mFd, mOffset, mLength, &source);
                     ALOGV("IDataSource(FileSource): %p %d %lld %lld",
-                            source.get(), mFd, (long long)mOffset, (long long)mLength);
+                            source.get(), mFd.get(), (long long)mOffset, (long long)mLength);
                     if (source.get() != nullptr) {
                         mDataSource = CreateDataSourceFromIDataSource(source);
-                        if (mDataSource != nullptr) {
-                            // Close the local file descriptor as it is not needed anymore.
-                            close(mFd);
-                            mFd = -1;
-                        }
                     } else {
                         ALOGW("extractor service cannot make data source");
                     }
@@ -440,12 +432,8 @@
             }
             if (mDataSource == nullptr) {
                 ALOGD("FileSource local");
-                mDataSource = new PlayerServiceFileSource(mFd, mOffset, mLength);
+                mDataSource = new PlayerServiceFileSource(mFd.get(), mOffset, mLength);
             }
-            // TODO: close should always be done on mFd, see the lines following
-            // CreateDataSourceFromIDataSource above,
-            // and the FileSource constructor should dup the mFd argument as needed.
-            mFd = -1;
         }
 
         if (mDataSource == NULL) {
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index 4d1905d..7a2ab8f 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -23,6 +23,7 @@
 
 #include "ATSParser.h"
 
+#include <android-base/unique_fd.h>
 #include <media/mediaplayer.h>
 #include <media/stagefright/MediaBuffer.h>
 
@@ -154,7 +155,7 @@
     sp<IMediaHTTPService> mHTTPService;
     AString mUri;
     KeyedVector<String8, String8> mUriHeaders;
-    int mFd;
+    base::unique_fd mFd;
     int64_t mOffset;
     int64_t mLength;
 
diff --git a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
index 9a8ed8d..f114046 100644
--- a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
+++ b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
@@ -23,7 +23,6 @@
 
 #include <aidl/android/media/BnResourceManagerClient.h>
 #include <aidl/android/media/BnResourceManagerService.h>
-#include <android/media/BnResourceManagerClient.h>
 
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/ProcessInfoInterface.h>
@@ -37,110 +36,11 @@
 
 namespace android {
 
-using ::android::binder::Status;
-using ::android::media::ResourceManagerService;
-using ::ndk::ScopedAStatus;
-
-using NdkBnResourceManagerClient = ::aidl::android::media::BnResourceManagerClient;
-using NdkBnResourceManagerService = ::aidl::android::media::BnResourceManagerService;
-using NdkMediaResource = ::aidl::android::media::MediaResourceParcel;
-using NdkResourceManagerClient = ::aidl::android::media::IResourceManagerClient;
-
-using FwkBnResourceManagerClient = ::android::media::BnResourceManagerClient;
-using FwkMediaResource = ::android::media::MediaResourceParcel;
-
-namespace {
-
-struct FwkResourceManagerClientImpl : public FwkBnResourceManagerClient {
-    FwkResourceManagerClientImpl(const std::shared_ptr<NdkResourceManagerClient> &client)
-        : mClient(client) {
-    }
-
-    Status reclaimResource(bool* _aidl_return) override {
-        mClient->reclaimResource(_aidl_return);
-        return Status::ok();
-    }
-
-    Status getName(std::string* _aidl_return) override {
-        mClient->getName(_aidl_return);
-        return Status::ok();
-    }
-
-private:
-    std::shared_ptr<NdkResourceManagerClient> mClient;
-};
-
-FwkMediaResource NdkToFwkMediaResource(const NdkMediaResource &in) {
-    FwkMediaResource out{};
-    out.type = static_cast<decltype(out.type)>(in.type);
-    out.subType = static_cast<decltype(out.subType)>(in.subType);
-    auto v(reinterpret_cast<const uint8_t *>(in.id.data()));
-    out.id.assign(v, v + in.id.size());
-    out.value = in.value;
-    return out;
-}
-
-std::vector<FwkMediaResource> NdkToFwkMediaResourceVec(const std::vector<NdkMediaResource> &in) {
-    std::vector<FwkMediaResource> out;
-    for (auto e : in) {
-        out.push_back(NdkToFwkMediaResource(e));
-    }
-    return out;
-}
-
-ScopedAStatus FwkToNdkStatus(Status err) {
-    return ScopedAStatus(AStatus_fromExceptionCode(err.serviceSpecificErrorCode()));
-}
-
-struct NdkResourceManagerServiceImpl : public NdkBnResourceManagerService {
-    using NdkMediaResourcePolicy = ::aidl::android::media::MediaResourcePolicyParcel;
-
-    NdkResourceManagerServiceImpl(const sp<ResourceManagerService> &service)
-        : mService(service) {}
-
-    ScopedAStatus config(const std::vector<NdkMediaResourcePolicy>& in_policies) override {
-        (void)in_policies;
-        return ScopedAStatus::ok();
-    }
-
-    ScopedAStatus addResource(int32_t in_pid, int32_t in_uid, int64_t in_clientId,
-            const std::shared_ptr<NdkResourceManagerClient>& in_client,
-            const std::vector<NdkMediaResource>& in_resources) override {
-        sp<FwkBnResourceManagerClient> client(new FwkResourceManagerClientImpl(in_client));
-        std::vector<FwkMediaResource> resources(NdkToFwkMediaResourceVec(in_resources));
-        auto err = mService->addResource(in_pid, in_uid, in_clientId, client, resources);
-        return FwkToNdkStatus(err);
-    }
-
-    ScopedAStatus removeResource(int32_t in_pid, int64_t in_clientId,
-            const std::vector<NdkMediaResource>& in_resources) override {
-        std::vector<FwkMediaResource> resources(NdkToFwkMediaResourceVec(in_resources));
-        auto err = mService->removeResource(in_pid, in_clientId, resources);
-        return FwkToNdkStatus(err);
-    }
-
-    ScopedAStatus removeClient(int32_t in_pid, int64_t in_clientId) override{
-        auto err = mService->removeClient(in_pid, in_clientId);
-        return FwkToNdkStatus(err);
-    }
-
-    ScopedAStatus reclaimResource(int32_t in_callingPid,
-            const std::vector<NdkMediaResource>& in_resources, bool* _aidl_return) override {
-        std::vector<FwkMediaResource> resources(NdkToFwkMediaResourceVec(in_resources));
-        auto err = mService->reclaimResource(in_callingPid, resources, _aidl_return);
-        return FwkToNdkStatus(err);
-    }
-
-private:
-    sp<ResourceManagerService> mService;
-};
-
-template <typename Impl>
-std::shared_ptr<NdkResourceManagerClient> NdkImplToIface(const Impl &impl) {
-    return std::static_pointer_cast<NdkResourceManagerClient>(impl);
-}
-
-}
+using Status = ::ndk::ScopedAStatus;
+using ::aidl::android::media::BnResourceManagerClient;
+using ::aidl::android::media::BnResourceManagerService;
+using ::aidl::android::media::MediaResourceParcel;
+using ::aidl::android::media::IResourceManagerClient;
 
 static Vector<uint8_t> toAndroidVector(const std::vector<uint8_t> &vec) {
     Vector<uint8_t> aVec;
@@ -169,27 +69,27 @@
     DISALLOW_EVIL_CONSTRUCTORS(FakeProcessInfo);
 };
 
-struct FakeDrm : public NdkBnResourceManagerClient {
+struct FakeDrm : public BnResourceManagerClient {
     FakeDrm(const std::vector<uint8_t>& sessionId, const sp<DrmSessionManager>& manager)
         : mSessionId(toAndroidVector(sessionId)),
           mReclaimed(false),
           mDrmSessionManager(manager) {}
 
-    ScopedAStatus reclaimResource(bool* _aidl_return) {
+    Status reclaimResource(bool* _aidl_return) {
         mReclaimed = true;
         mDrmSessionManager->removeSession(mSessionId);
         *_aidl_return = true;
-        return ScopedAStatus::ok();
+        return Status::ok();
     }
 
-    ScopedAStatus getName(::std::string* _aidl_return) {
+    Status getName(::std::string* _aidl_return) {
         String8 name("FakeDrm[");
         for (size_t i = 0; i < mSessionId.size(); ++i) {
             name.appendFormat("%02x", mSessionId[i]);
         }
         name.append("]");
         *_aidl_return = name;
-        return ScopedAStatus::ok();
+        return Status::ok();
     }
 
     bool isReclaimed() const {
@@ -215,8 +115,7 @@
 
     virtual void noteResetVideo() override {}
 
-    virtual bool requestCpusetBoost(
-            bool /*enable*/, const sp<IInterface> &/*client*/) override {
+    virtual bool requestCpusetBoost(bool /*enable*/) override {
         return true;
     }
 
@@ -237,21 +136,25 @@
 class DrmSessionManagerTest : public ::testing::Test {
 public:
     DrmSessionManagerTest()
-        : mService(new ResourceManagerService(new FakeProcessInfo(), new FakeSystemCallback())),
-          mDrmSessionManager(new DrmSessionManager(std::shared_ptr<NdkBnResourceManagerService>(new NdkResourceManagerServiceImpl(mService)))),
-          mTestDrm1(new FakeDrm(kTestSessionId1, mDrmSessionManager)),
-          mTestDrm2(new FakeDrm(kTestSessionId2, mDrmSessionManager)),
-          mTestDrm3(new FakeDrm(kTestSessionId3, mDrmSessionManager)) {
+        : mService(::ndk::SharedRefBase::make<ResourceManagerService>
+            (new FakeProcessInfo(), new FakeSystemCallback())),
+          mDrmSessionManager(new DrmSessionManager(mService)),
+          mTestDrm1(::ndk::SharedRefBase::make<FakeDrm>(
+                  kTestSessionId1, mDrmSessionManager)),
+          mTestDrm2(::ndk::SharedRefBase::make<FakeDrm>(
+                  kTestSessionId2, mDrmSessionManager)),
+          mTestDrm3(::ndk::SharedRefBase::make<FakeDrm>(
+                  kTestSessionId3, mDrmSessionManager)) {
     }
 
 protected:
     void addSession() {
-        mDrmSessionManager->addSession(kTestPid1, NdkImplToIface(mTestDrm1), mTestDrm1->mSessionId);
-        mDrmSessionManager->addSession(kTestPid2, NdkImplToIface(mTestDrm2), mTestDrm2->mSessionId);
-        mDrmSessionManager->addSession(kTestPid2, NdkImplToIface(mTestDrm3), mTestDrm3->mSessionId);
+        mDrmSessionManager->addSession(kTestPid1, mTestDrm1, mTestDrm1->mSessionId);
+        mDrmSessionManager->addSession(kTestPid2, mTestDrm2, mTestDrm2->mSessionId);
+        mDrmSessionManager->addSession(kTestPid2, mTestDrm3, mTestDrm3->mSessionId);
     }
 
-    sp<ResourceManagerService> mService;
+    std::shared_ptr<ResourceManagerService> mService;
     sp<DrmSessionManager> mDrmSessionManager;
     std::shared_ptr<FakeDrm> mTestDrm1;
     std::shared_ptr<FakeDrm> mTestDrm2;
@@ -302,8 +205,9 @@
 
     // add a session from a higher priority process.
     const std::vector<uint8_t> sid{1, 3, 5};
-    std::shared_ptr<FakeDrm> drm(new FakeDrm(sid, mDrmSessionManager));
-    mDrmSessionManager->addSession(15, NdkImplToIface(drm), drm->mSessionId);
+    std::shared_ptr<FakeDrm> drm =
+            ::ndk::SharedRefBase::make<FakeDrm>(sid, mDrmSessionManager);
+    mDrmSessionManager->addSession(15, drm, drm->mSessionId);
 
     // make sure mTestDrm2 is reclaimed next instead of mTestDrm3
     mDrmSessionManager->useSession(mTestDrm3->mSessionId);
@@ -323,9 +227,9 @@
     EXPECT_FALSE(mDrmSessionManager->reclaimSession(kTestPid2));
 
     // add sessions from same pid
-    mDrmSessionManager->addSession(kTestPid2, NdkImplToIface(mTestDrm1), mTestDrm1->mSessionId);
-    mDrmSessionManager->addSession(kTestPid2, NdkImplToIface(mTestDrm2), mTestDrm2->mSessionId);
-    mDrmSessionManager->addSession(kTestPid2, NdkImplToIface(mTestDrm3), mTestDrm3->mSessionId);
+    mDrmSessionManager->addSession(kTestPid2, mTestDrm1, mTestDrm1->mSessionId);
+    mDrmSessionManager->addSession(kTestPid2, mTestDrm2, mTestDrm2->mSessionId);
+    mDrmSessionManager->addSession(kTestPid2, mTestDrm3, mTestDrm3->mSessionId);
 
     // use some but not all sessions
     mDrmSessionManager->useSession(mTestDrm1->mSessionId);
diff --git a/media/libstagefright/ACodecBufferChannel.cpp b/media/libstagefright/ACodecBufferChannel.cpp
index aa4c22a..bf8f09c 100644
--- a/media/libstagefright/ACodecBufferChannel.cpp
+++ b/media/libstagefright/ACodecBufferChannel.cpp
@@ -433,4 +433,12 @@
             it->mClientBuffer);
 }
 
+void ACodecBufferChannel::setCrypto(const sp<ICrypto> &crypto) {
+    mCrypto = crypto;
+}
+
+void ACodecBufferChannel::setDescrambler(const sp<IDescrambler> &descrambler) {
+    mDescrambler = descrambler;
+}
+
 }  // namespace android
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 76eadf7..e78e1e7 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -227,6 +227,7 @@
         "libaudioutils",
         "libbase",
         "libbinder",
+        "libbinder_ndk",
         "libcamera_client",
         "libcutils",
         "libdatasource",
diff --git a/media/libstagefright/CallbackDataSource.cpp b/media/libstagefright/CallbackDataSource.cpp
index dea83d4..eb3cb45 100644
--- a/media/libstagefright/CallbackDataSource.cpp
+++ b/media/libstagefright/CallbackDataSource.cpp
@@ -20,9 +20,9 @@
 
 #include "include/CallbackDataSource.h"
 
+#include <android/IDataSource.h>
 #include <binder/IMemory.h>
 #include <binder/IPCThreadState.h>
-#include <media/IDataSource.h>
 #include <media/stagefright/foundation/ADebug.h>
 
 #include <algorithm>
diff --git a/media/libstagefright/CodecBase.cpp b/media/libstagefright/CodecBase.cpp
index 5765883..5b724aa 100644
--- a/media/libstagefright/CodecBase.cpp
+++ b/media/libstagefright/CodecBase.cpp
@@ -26,14 +26,6 @@
 
 namespace android {
 
-void BufferChannelBase::setCrypto(const sp<ICrypto> &crypto) {
-    mCrypto = crypto;
-}
-
-void BufferChannelBase::setDescrambler(const sp<IDescrambler> &descrambler) {
-    mDescrambler = descrambler;
-}
-
 void BufferChannelBase::IMemoryToSharedBuffer(
         const sp<IMemory> &memory,
         int32_t heapSeqNum,
diff --git a/media/libstagefright/FrameCaptureLayer.cpp b/media/libstagefright/FrameCaptureLayer.cpp
index 29642be..815057d 100644
--- a/media/libstagefright/FrameCaptureLayer.cpp
+++ b/media/libstagefright/FrameCaptureLayer.cpp
@@ -32,6 +32,8 @@
 namespace android {
 
 static const int64_t kAcquireBufferTimeoutNs = 100000000LL;
+static constexpr float kDefaultMaxMasteringLuminance = 1000.0;
+static constexpr float kDefaultMaxContentLuminance = 1000.0;
 
 ui::Dataspace translateDataspace(ui::Dataspace dataspace) {
     ui::Dataspace updatedDataspace = dataspace;
@@ -93,6 +95,14 @@
     layerSettings->source.buffer.textureName = textureName;
     layerSettings->source.buffer.usePremultipliedAlpha = false;
     layerSettings->source.buffer.isY410BT2020 = isHdrY410(mBufferItem);
+    bool hasSmpte2086 = mBufferItem.mHdrMetadata.validTypes & HdrMetadata::SMPTE2086;
+    bool hasCta861_3 = mBufferItem.mHdrMetadata.validTypes & HdrMetadata::CTA861_3;
+    layerSettings->source.buffer.maxMasteringLuminance = hasSmpte2086
+            ? mBufferItem.mHdrMetadata.smpte2086.maxLuminance
+                    : kDefaultMaxMasteringLuminance;
+    layerSettings->source.buffer.maxContentLuminance = hasCta861_3
+            ? mBufferItem.mHdrMetadata.cta8613.maxContentLightLevel
+                    : kDefaultMaxContentLuminance;
 
     // Set filtering to false since the capture itself doesn't involve
     // any scaling, metadata retriever JNI is scaling the bitmap if
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 14564c9..257dd0f 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -27,11 +27,11 @@
 #include <android/hardware/cas/native/1.0/IDescrambler.h>
 #include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
 
-#include <android/media/BnResourceManagerClient.h>
-#include <android/media/IResourceManagerService.h>
+#include <aidl/android/media/BnResourceManagerClient.h>
+#include <aidl/android/media/IResourceManagerService.h>
+#include <android/binder_ibinder.h>
+#include <android/binder_manager.h>
 #include <binder/IMemory.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
 #include <binder/MemoryDealer.h>
 #include <cutils/properties.h>
 #include <gui/BufferQueue.h>
@@ -64,9 +64,10 @@
 
 namespace android {
 
-using ::android::binder::Status;
-using ::android::media::BnResourceManagerClient;
-using ::android::media::IResourceManagerService;
+using Status = ::ndk::ScopedAStatus;
+using aidl::android::media::BnResourceManagerClient;
+using aidl::android::media::IResourceManagerClient;
+using aidl::android::media::IResourceManagerService;
 
 // key for media statistics
 static const char *kCodecKeyName = "codec";
@@ -111,7 +112,7 @@
 static bool kEmitHistogram = false;
 
 
-static int64_t getId(const sp<IResourceManagerClient> &client) {
+static int64_t getId(const std::shared_ptr<IResourceManagerClient> &client) {
     return (int64_t) client.get();
 }
 
@@ -164,7 +165,6 @@
         return Status::ok();
     }
 
-protected:
     virtual ~ResourceManagerClient() {}
 
 private:
@@ -173,93 +173,99 @@
     DISALLOW_EVIL_CONSTRUCTORS(ResourceManagerClient);
 };
 
-struct MediaCodec::ResourceManagerServiceProxy : public IBinder::DeathRecipient {
-    ResourceManagerServiceProxy(pid_t pid, uid_t uid);
-    ~ResourceManagerServiceProxy();
+struct MediaCodec::ResourceManagerServiceProxy : public RefBase {
+    ResourceManagerServiceProxy(pid_t pid, uid_t uid,
+            const std::shared_ptr<IResourceManagerClient> &client);
+    virtual ~ResourceManagerServiceProxy();
 
     void init();
 
     // implements DeathRecipient
-    virtual void binderDied(const wp<IBinder>& /*who*/);
+    static void BinderDiedCallback(void* cookie);
+    void binderDied();
 
-    void addResource(
-            int64_t clientId,
-            const sp<IResourceManagerClient> &client,
-            const std::vector<MediaResourceParcel> &resources);
-
-    void removeResource(
-            int64_t clientId,
-            const std::vector<MediaResourceParcel> &resources);
-
-    void removeClient(int64_t clientId);
-
+    void addResource(const MediaResourceParcel &resource);
+    void removeResource(const MediaResourceParcel &resource);
+    void removeClient();
     bool reclaimResource(const std::vector<MediaResourceParcel> &resources);
 
 private:
     Mutex mLock;
-    sp<android::media::IResourceManagerService> mService;
     pid_t mPid;
     uid_t mUid;
+    std::shared_ptr<IResourceManagerService> mService;
+    std::shared_ptr<IResourceManagerClient> mClient;
+    ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
 };
 
 MediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy(
-        pid_t pid, uid_t uid)
-        : mPid(pid), mUid(uid) {
+        pid_t pid, uid_t uid, const std::shared_ptr<IResourceManagerClient> &client)
+        : mPid(pid), mUid(uid), mClient(client),
+          mDeathRecipient(AIBinder_DeathRecipient_new(BinderDiedCallback)) {
     if (mPid == MediaCodec::kNoPid) {
-        mPid = IPCThreadState::self()->getCallingPid();
+        mPid = AIBinder_getCallingPid();
     }
 }
 
 MediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() {
-    if (mService != NULL) {
-        IInterface::asBinder(mService)->unlinkToDeath(this);
+    if (mService != nullptr) {
+        AIBinder_unlinkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this);
     }
 }
 
 void MediaCodec::ResourceManagerServiceProxy::init() {
-    sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> binder = sm->getService(String16("media.resource_manager"));
-    mService = interface_cast<IResourceManagerService>(binder);
-    if (mService == NULL) {
+    ::ndk::SpAIBinder binder(AServiceManager_getService("media.resource_manager"));
+    mService = IResourceManagerService::fromBinder(binder);
+    if (mService == nullptr) {
         ALOGE("Failed to get ResourceManagerService");
         return;
     }
-    IInterface::asBinder(mService)->linkToDeath(this);
+
+    AIBinder_linkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this);
 }
 
-void MediaCodec::ResourceManagerServiceProxy::binderDied(const wp<IBinder>& /*who*/) {
+//static
+void MediaCodec::ResourceManagerServiceProxy::BinderDiedCallback(void* cookie) {
+    auto thiz = static_cast<ResourceManagerServiceProxy*>(cookie);
+    thiz->binderDied();
+}
+
+void MediaCodec::ResourceManagerServiceProxy::binderDied() {
     ALOGW("ResourceManagerService died.");
     Mutex::Autolock _l(mLock);
-    mService.clear();
+    mService = nullptr;
 }
 
 void MediaCodec::ResourceManagerServiceProxy::addResource(
-        int64_t clientId,
-        const sp<IResourceManagerClient> &client,
-        const std::vector<MediaResourceParcel> &resources) {
+        const MediaResourceParcel &resource) {
+    std::vector<MediaResourceParcel> resources;
+    resources.push_back(resource);
+
     Mutex::Autolock _l(mLock);
-    if (mService == NULL) {
+    if (mService == nullptr) {
         return;
     }
-    mService->addResource(mPid, mUid, clientId, client, resources);
+    mService->addResource(mPid, mUid, getId(mClient), mClient, resources);
 }
 
 void MediaCodec::ResourceManagerServiceProxy::removeResource(
-        int64_t clientId,
-        const std::vector<MediaResourceParcel> &resources) {
+        const MediaResourceParcel &resource) {
+    std::vector<MediaResourceParcel> resources;
+    resources.push_back(resource);
+
     Mutex::Autolock _l(mLock);
-    if (mService == NULL) {
+    if (mService == nullptr) {
         return;
     }
-    mService->removeResource(mPid, clientId, resources);
+    mService->removeResource(mPid, getId(mClient), resources);
 }
 
-void MediaCodec::ResourceManagerServiceProxy::removeClient(int64_t clientId) {
+void MediaCodec::ResourceManagerServiceProxy::removeClient() {
     Mutex::Autolock _l(mLock);
-    if (mService == NULL) {
+    if (mService == nullptr) {
         return;
     }
-    mService->removeClient(mPid, clientId);
+    mService->removeClient(mPid, getId(mClient));
 }
 
 bool MediaCodec::ResourceManagerServiceProxy::reclaimResource(
@@ -579,19 +585,19 @@
       mCpuBoostRequested(false),
       mLatencyUnknown(0) {
     if (uid == kNoUid) {
-        mUid = IPCThreadState::self()->getCallingUid();
+        mUid = AIBinder_getCallingUid();
     } else {
         mUid = uid;
     }
-    mResourceManagerClient = new ResourceManagerClient(this);
-    mResourceManagerService = new ResourceManagerServiceProxy(pid, mUid);
+    mResourceManagerProxy = new ResourceManagerServiceProxy(pid, mUid,
+            ::ndk::SharedRefBase::make<ResourceManagerClient>(this));
 
     initMediametrics();
 }
 
 MediaCodec::~MediaCodec() {
     CHECK_EQ(mState, UNINITIALIZED);
-    mResourceManagerService->removeClient(getId(mResourceManagerClient));
+    mResourceManagerProxy->removeClient();
 
     flushMediametrics();
 }
@@ -792,7 +798,7 @@
 
     if (mBatteryChecker != nullptr) {
         mBatteryChecker->onCodecActivity([this] () {
-            addResource(MediaResource::VideoBatteryResource());
+            mResourceManagerProxy->addResource(MediaResource::VideoBatteryResource());
         });
     }
 
@@ -832,7 +838,7 @@
 
     if (mBatteryChecker != nullptr) {
         mBatteryChecker->onCodecActivity([this] () {
-            addResource(MediaResource::VideoBatteryResource());
+            mResourceManagerProxy->addResource(MediaResource::VideoBatteryResource());
         });
     }
 
@@ -942,7 +948,7 @@
 }
 
 status_t MediaCodec::init(const AString &name) {
-    mResourceManagerService->init();
+    mResourceManagerProxy->init();
 
     // save init parameters for reset
     mInitName = name;
@@ -955,37 +961,41 @@
     mCodecInfo.clear();
 
     bool secureCodec = false;
-    AString tmp = name;
-    if (tmp.endsWith(".secure")) {
-        secureCodec = true;
-        tmp.erase(tmp.size() - 7, 7);
-    }
-    const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
-    if (mcl == NULL) {
-        mCodec = NULL;  // remove the codec.
-        return NO_INIT; // if called from Java should raise IOException
-    }
-    for (const AString &codecName : { name, tmp }) {
-        ssize_t codecIdx = mcl->findCodecByName(codecName.c_str());
-        if (codecIdx < 0) {
-            continue;
+    const char *owner = "";
+    if (!name.startsWith("android.filter.")) {
+        AString tmp = name;
+        if (tmp.endsWith(".secure")) {
+            secureCodec = true;
+            tmp.erase(tmp.size() - 7, 7);
         }
-        mCodecInfo = mcl->getCodecInfo(codecIdx);
-        Vector<AString> mediaTypes;
-        mCodecInfo->getSupportedMediaTypes(&mediaTypes);
-        for (size_t i = 0; i < mediaTypes.size(); i++) {
-            if (mediaTypes[i].startsWith("video/")) {
-                mIsVideo = true;
-                break;
+        const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
+        if (mcl == NULL) {
+            mCodec = NULL;  // remove the codec.
+            return NO_INIT; // if called from Java should raise IOException
+        }
+        for (const AString &codecName : { name, tmp }) {
+            ssize_t codecIdx = mcl->findCodecByName(codecName.c_str());
+            if (codecIdx < 0) {
+                continue;
             }
+            mCodecInfo = mcl->getCodecInfo(codecIdx);
+            Vector<AString> mediaTypes;
+            mCodecInfo->getSupportedMediaTypes(&mediaTypes);
+            for (size_t i = 0; i < mediaTypes.size(); i++) {
+                if (mediaTypes[i].startsWith("video/")) {
+                    mIsVideo = true;
+                    break;
+                }
+            }
+            break;
         }
-        break;
-    }
-    if (mCodecInfo == nullptr) {
-        return NAME_NOT_FOUND;
+        if (mCodecInfo == nullptr) {
+            return NAME_NOT_FOUND;
+        }
+        owner = mCodecInfo->getOwnerName();
     }
 
-    mCodec = GetCodecBase(name, mCodecInfo->getOwnerName());
+    mCodec = GetCodecBase(name, owner);
     if (mCodec == NULL) {
         return NAME_NOT_FOUND;
     }
@@ -1014,9 +1024,11 @@
                     new BufferCallback(new AMessage(kWhatCodecNotify, this))));
 
     sp<AMessage> msg = new AMessage(kWhatInit, this);
-    msg->setObject("codecInfo", mCodecInfo);
-    // name may be different from mCodecInfo->getCodecName() if we stripped
-    // ".secure"
+    if (mCodecInfo) {
+        msg->setObject("codecInfo", mCodecInfo);
+        // name may be different from mCodecInfo->getCodecName() if we stripped
+        // ".secure"
+    }
     msg->setString("name", name);
 
     if (mMetricsHandle != 0) {
@@ -1035,7 +1047,7 @@
     for (int i = 0; i <= kMaxRetry; ++i) {
         if (i > 0) {
             // Don't try to reclaim resource for the first time.
-            if (!mResourceManagerService->reclaimResource(resources)) {
+            if (!mResourceManagerProxy->reclaimResource(resources)) {
                 break;
             }
         }
@@ -1150,7 +1162,7 @@
     for (int i = 0; i <= kMaxRetry; ++i) {
         if (i > 0) {
             // Don't try to reclaim resource for the first time.
-            if (!mResourceManagerService->reclaimResource(resources)) {
+            if (!mResourceManagerProxy->reclaimResource(resources)) {
                 break;
             }
         }
@@ -1271,19 +1283,6 @@
     return size;
 }
 
-void MediaCodec::addResource(const MediaResourceParcel &resource) {
-    std::vector<MediaResourceParcel> resources;
-    resources.push_back(resource);
-    mResourceManagerService->addResource(
-            getId(mResourceManagerClient), mResourceManagerClient, resources);
-}
-
-void MediaCodec::removeResource(const MediaResourceParcel &resource) {
-    std::vector<MediaResourceParcel> resources;
-    resources.push_back(resource);
-    mResourceManagerService->removeResource(getId(mResourceManagerClient), resources);
-}
-
 status_t MediaCodec::start() {
     sp<AMessage> msg = new AMessage(kWhatStart, this);
 
@@ -1296,7 +1295,7 @@
     for (int i = 0; i <= kMaxRetry; ++i) {
         if (i > 0) {
             // Don't try to reclaim resource for the first time.
-            if (!mResourceManagerService->reclaimResource(resources)) {
+            if (!mResourceManagerProxy->reclaimResource(resources)) {
                 break;
             }
             // Recover codec from previous error before retry start.
@@ -1734,7 +1733,7 @@
             totalPixel = width * height;
         }
         if (totalPixel >= 1920 * 1080) {
-            addResource(MediaResource::CpuBoostResource());
+            mResourceManagerProxy->addResource(MediaResource::CpuBoostResource());
             mCpuBoostRequested = true;
         }
     }
@@ -2070,9 +2069,9 @@
                                                 mComponentName.c_str());
                     }
 
-                    const char *owner = mCodecInfo->getOwnerName();
+                    const char *owner = mCodecInfo ? mCodecInfo->getOwnerName() : "";
                     if (mComponentName.startsWith("OMX.google.")
-                            && (owner == nullptr || strncmp(owner, "default", 8) == 0)) {
+                            && strncmp(owner, "default", 8) == 0) {
                         mFlags |= kFlagUsesSoftwareRenderer;
                     } else {
                         mFlags &= ~kFlagUsesSoftwareRenderer;
@@ -2089,7 +2088,8 @@
 
                     if (mIsVideo) {
                         // audio codec is currently ignored.
-                        addResource(MediaResource::CodecResource(mFlags & kFlagIsSecure, mIsVideo));
+                        mResourceManagerProxy->addResource(
+                                MediaResource::CodecResource(mFlags & kFlagIsSecure, mIsVideo));
                     }
 
                     (new AMessage)->postReply(mReplyID);
@@ -2210,8 +2210,8 @@
 
                     CHECK_EQ(mState, STARTING);
                     if (mIsVideo) {
-                        addResource(MediaResource::GraphicMemoryResource(
-                                getGraphicBufferSize()));
+                        mResourceManagerProxy->addResource(
+                                MediaResource::GraphicMemoryResource(getGraphicBufferSize()));
                     }
                     setState(STARTED);
                     (new AMessage)->postReply(mReplyID);
@@ -2435,7 +2435,7 @@
                         mBatteryChecker->onClientRemoved();
                     }
 
-                    mResourceManagerService->removeClient(getId(mResourceManagerClient));
+                    mResourceManagerProxy->removeClient();
 
                     (new AMessage)->postReply(mReplyID);
                     break;
@@ -2480,12 +2480,14 @@
             setState(INITIALIZING);
 
             sp<RefBase> codecInfo;
-            CHECK(msg->findObject("codecInfo", &codecInfo));
+            (void)msg->findObject("codecInfo", &codecInfo);
             AString name;
             CHECK(msg->findString("name", &name));
 
             sp<AMessage> format = new AMessage;
-            format->setObject("codecInfo", codecInfo);
+            if (codecInfo) {
+                format->setObject("codecInfo", codecInfo);
+            }
             format->setString("componentName", name);
 
             mCodec->initiateAllocateComponent(format);
@@ -3150,7 +3152,8 @@
         {
             if (mBatteryChecker != nullptr) {
                 mBatteryChecker->onCheckBatteryTimer(msg, [this] () {
-                    removeResource(MediaResource::VideoBatteryResource());
+                    mResourceManagerProxy->removeResource(
+                            MediaResource::VideoBatteryResource());
                 });
             }
             break;
diff --git a/media/libstagefright/MediaCodecListOverrides.cpp b/media/libstagefright/MediaCodecListOverrides.cpp
index 6b5b50e..4a167d1 100644
--- a/media/libstagefright/MediaCodecListOverrides.cpp
+++ b/media/libstagefright/MediaCodecListOverrides.cpp
@@ -265,7 +265,7 @@
         }
     }
     global_results->add(
-            MediaResourcePolicy::kPolicySupportsMultipleSecureCodecs().c_str(),
+            MediaResourcePolicy::kPolicySupportsMultipleSecureCodecs(),
             supportMultipleSecureCodecs);
 }
 
diff --git a/media/libstagefright/MediaExtractorFactory.cpp b/media/libstagefright/MediaExtractorFactory.cpp
index 120f354..2457561 100644
--- a/media/libstagefright/MediaExtractorFactory.cpp
+++ b/media/libstagefright/MediaExtractorFactory.cpp
@@ -27,8 +27,8 @@
 #include <media/stagefright/InterfaceUtils.h>
 #include <media/stagefright/MediaExtractor.h>
 #include <media/stagefright/MediaExtractorFactory.h>
-#include <media/IMediaExtractor.h>
-#include <media/IMediaExtractorService.h>
+#include <android/IMediaExtractor.h>
+#include <android/IMediaExtractorService.h>
 #include <nativeloader/dlext_namespaces.h>
 #include <private/android_filesystem_config.h>
 #include <cutils/properties.h>
@@ -54,9 +54,13 @@
         sp<IBinder> binder = defaultServiceManager()->getService(String16("media.extractor"));
 
         if (binder != 0) {
-            sp<IMediaExtractorService> mediaExService(interface_cast<IMediaExtractorService>(binder));
-            sp<IMediaExtractor> ex = mediaExService->makeExtractor(
-                    CreateIDataSourceFromDataSource(source), mime);
+            sp<IMediaExtractorService> mediaExService(
+                    interface_cast<IMediaExtractorService>(binder));
+            sp<IMediaExtractor> ex;
+            mediaExService->makeExtractor(
+                    CreateIDataSourceFromDataSource(source),
+                    mime ? std::make_unique<std::string>(mime) : nullptr,
+                    &ex);
             return ex;
         } else {
             ALOGE("extractor service not running");
@@ -262,7 +266,7 @@
     return strcmp(first->def.extractor_name, second->def.extractor_name) < 0;
 }
 
-static std::unordered_set<std::string> gSupportedExtensions;
+static std::vector<std::string> gSupportedExtensions;
 
 // static
 void MediaExtractorFactory::LoadExtractors() {
@@ -308,7 +312,7 @@
                 if (ext == nullptr) {
                     break;
                 }
-                gSupportedExtensions.insert(std::string(ext));
+                gSupportedExtensions.push_back(std::string(ext));
             }
         }
     }
@@ -317,7 +321,7 @@
 }
 
 // static
-std::unordered_set<std::string> MediaExtractorFactory::getSupportedTypes() {
+std::vector<std::string> MediaExtractorFactory::getSupportedTypes() {
     if (getuid() == AID_MEDIA_EX) {
         return gSupportedExtensions;
     }
@@ -326,9 +330,11 @@
 
     if (binder != 0) {
         sp<IMediaExtractorService> mediaExService(interface_cast<IMediaExtractorService>(binder));
-        return mediaExService->getSupportedTypes();
+        std::vector<std::string> supportedTypes;
+        mediaExService->getSupportedTypes(&supportedTypes);
+        return supportedTypes;
     }
-    return std::unordered_set<std::string>();
+    return std::vector<std::string>();
 }
 
 status_t MediaExtractorFactory::dump(int fd, const Vector<String16>&) {
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index ce73676..6fd0805 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -35,7 +35,7 @@
 
 StagefrightMediaScanner::~StagefrightMediaScanner() {}
 
-static std::unordered_set<std::string> gSupportedExtensions;
+static std::vector<std::string> gSupportedExtensions;
 
 static bool FileHasAcceptableExtension(const char *extension) {
 
@@ -44,7 +44,12 @@
         gSupportedExtensions = MediaExtractorFactory::getSupportedTypes();
     }
 
-    return  gSupportedExtensions.count(std::string(extension + 1)) != 0;
+    for (auto ext: gSupportedExtensions) {
+        if (ext == (extension + 1)) {
+            return true;
+        }
+    }
+    return false;
 }
 
 MediaScanResult StagefrightMediaScanner::processFile(
diff --git a/media/libstagefright/filters/MediaFilter.cpp b/media/libstagefright/filters/MediaFilter.cpp
index 777ab5b..c7baa73 100644
--- a/media/libstagefright/filters/MediaFilter.cpp
+++ b/media/libstagefright/filters/MediaFilter.cpp
@@ -20,13 +20,12 @@
 #include <inttypes.h>
 #include <utils/Trace.h>
 
-#include <binder/MemoryDealer.h>
-
-#include <media/stagefright/BufferProducerWrapper.h>
 #include <media/stagefright/foundation/ABuffer.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AMessage.h>
 
+#include <media/stagefright/BufferProducerWrapper.h>
+#include <media/stagefright/MediaCodecConstants.h>
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MediaFilter.h>
@@ -42,11 +41,121 @@
 #include "SaturationFilter.h"
 #include "ZeroFilter.h"
 
-#include "../include/ACodecBufferChannel.h"
-#include "../include/SharedMemoryBuffer.h"
-
 namespace android {
 
+class MediaFilter::BufferChannel : public BufferChannelBase {
+public:
+    BufferChannel(const sp<AMessage> &in, const sp<AMessage> &out)
+        : mInputBufferFilled(in), mOutputBufferDrained(out) {
+    }
+
+    ~BufferChannel() override = default;
+
+    // BufferChannelBase
+
+    status_t queueInputBuffer(const sp<MediaCodecBuffer> &buffer) override {
+        sp<AMessage> msg = mInputBufferFilled->dup();
+        msg->setObject("buffer", buffer);
+        msg->post();
+        return OK;
+    }
+
+    status_t queueSecureInputBuffer(
+            const sp<MediaCodecBuffer> &,
+            bool,
+            const uint8_t *,
+            const uint8_t *,
+            CryptoPlugin::Mode,
+            CryptoPlugin::Pattern,
+            const CryptoPlugin::SubSample *,
+            size_t,
+            AString *) override {
+        return INVALID_OPERATION;
+    }
+
+    status_t renderOutputBuffer(
+            const sp<MediaCodecBuffer> &buffer, int64_t /* timestampNs */) override {
+        sp<AMessage> msg = mOutputBufferDrained->dup();
+        msg->setObject("buffer", buffer);
+        msg->post();
+        return OK;
+    }
+
+    status_t discardBuffer(const sp<MediaCodecBuffer> &buffer) override {
+        if (FindBufferIndex(&mInputBuffers, buffer) >= 0) {
+            sp<AMessage> msg = mInputBufferFilled->dup();
+            msg->setObject("buffer", buffer);
+            msg->post();
+            return OK;
+        }
+        sp<AMessage> msg = mOutputBufferDrained->dup();
+        msg->setObject("buffer", buffer);
+        msg->post();
+        return OK;
+    }
+
+    void getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) {
+        if (!array) {
+            return;
+        }
+        array->clear();
+        array->appendVector(mInputBuffers);
+    }
+
+    void getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) {
+        if (!array) {
+            return;
+        }
+        array->clear();
+        array->appendVector(mOutputBuffers);
+    }
+
+    // For MediaFilter
+
+    void fillThisBuffer(const sp<MediaCodecBuffer> &buffer) {
+        ssize_t index = FindBufferIndex(&mInputBuffers, buffer);
+        mCallback->onInputBufferAvailable(index, buffer);
+    }
+
+    void drainThisBuffer(const sp<MediaCodecBuffer> &buffer, int flags) {
+        ssize_t index = FindBufferIndex(&mOutputBuffers, buffer);
+        buffer->meta()->setInt32("flags", flags);
+        mCallback->onOutputBufferAvailable(index, buffer);
+    }
+
+    template <class T>
+    void setInputBuffers(T begin, T end) {
+        mInputBuffers.clear();
+        for (T it = begin; it != end; ++it) {
+            mInputBuffers.push_back(it->mData);
+        }
+    }
+
+    template <class T>
+    void setOutputBuffers(T begin, T end) {
+        mOutputBuffers.clear();
+        for (T it = begin; it != end; ++it) {
+            mOutputBuffers.push_back(it->mData);
+        }
+    }
+
+private:
+    sp<AMessage> mInputBufferFilled;
+    sp<AMessage> mOutputBufferDrained;
+    Vector<sp<MediaCodecBuffer>> mInputBuffers;
+    Vector<sp<MediaCodecBuffer>> mOutputBuffers;
+
+    static ssize_t FindBufferIndex(
+            Vector<sp<MediaCodecBuffer>> *array, const sp<MediaCodecBuffer> &buffer) {
+        for (size_t i = 0; i < array->size(); ++i) {
+            if (array->itemAt(i) == buffer) {
+                return i;
+            }
+        }
+        return -1;
+    }
+};
+
 // parameter: number of input and output buffers
 static const size_t kBufferCountActual = 4;
 
@@ -54,9 +163,6 @@
     : mState(UNINITIALIZED),
       mGeneration(0),
       mGraphicBufferListener(NULL) {
-    mBufferChannel = std::make_shared<ACodecBufferChannel>(
-            new AMessage(kWhatInputBufferFilled, this),
-            new AMessage(kWhatOutputBufferDrained, this));
 }
 
 MediaFilter::~MediaFilter() {
@@ -65,6 +171,11 @@
 //////////////////// PUBLIC FUNCTIONS //////////////////////////////////////////
 
 std::shared_ptr<BufferChannelBase> MediaFilter::getBufferChannel() {
+    if (!mBufferChannel) {
+        mBufferChannel = std::make_shared<BufferChannel>(
+                new AMessage(kWhatInputBufferFilled, this),
+                new AMessage(kWhatOutputBufferDrained, this));
+    }
     return mBufferChannel;
 }
 
@@ -212,28 +323,23 @@
     const bool isInput = portIndex == kPortIndexInput;
     const size_t bufferSize = isInput ? mMaxInputSize : mMaxOutputSize;
 
-    CHECK(mDealer[portIndex] == NULL);
     CHECK(mBuffers[portIndex].isEmpty());
 
     ALOGV("Allocating %zu buffers of size %zu on %s port",
             kBufferCountActual, bufferSize,
             isInput ? "input" : "output");
 
-    size_t totalSize = kBufferCountActual * bufferSize;
-
-    mDealer[portIndex] = new MemoryDealer(totalSize, "MediaFilter");
-
+    // trigger output format change
+    sp<AMessage> outputFormat = mOutputFormat->dup();
     for (size_t i = 0; i < kBufferCountActual; ++i) {
-        sp<IMemory> mem = mDealer[portIndex]->allocate(bufferSize);
-        CHECK(mem.get() != NULL);
-
         BufferInfo info;
         info.mStatus = BufferInfo::OWNED_BY_US;
         info.mBufferID = i;
         info.mGeneration = mGeneration;
         info.mOutputFlags = 0;
-        info.mData = new SharedMemoryBuffer(
-                isInput ? mInputFormat : mOutputFormat, mem);
+        info.mData = new MediaCodecBuffer(
+                isInput ? mInputFormat : outputFormat,
+                new ABuffer(bufferSize));
         info.mData->meta()->setInt64("timeUs", 0);
 
         mBuffers[portIndex].push_back(info);
@@ -243,27 +349,24 @@
                     &mBuffers[portIndex].editItemAt(i));
         }
     }
-
-    std::vector<ACodecBufferChannel::BufferAndId> array(mBuffers[portIndex].size());
-    for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
-        array[i] = {mBuffers[portIndex][i].mData, mBuffers[portIndex][i].mBufferID};
-    }
-    if (portIndex == kPortIndexInput) {
-        mBufferChannel->setInputBufferArray(array);
+    if (isInput) {
+        mBufferChannel->setInputBuffers(
+                mBuffers[portIndex].begin(), mBuffers[portIndex].end());
     } else {
-        mBufferChannel->setOutputBufferArray(array);
+        mBufferChannel->setOutputBuffers(
+                mBuffers[portIndex].begin(), mBuffers[portIndex].end());
     }
 
     return OK;
 }
 
-MediaFilter::BufferInfo* MediaFilter::findBufferByID(
-        uint32_t portIndex, IOMX::buffer_id bufferID,
+MediaFilter::BufferInfo* MediaFilter::findBuffer(
+        uint32_t portIndex, const sp<MediaCodecBuffer> &buffer,
         ssize_t *index) {
     for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
         BufferInfo *info = &mBuffers[portIndex].editItemAt(i);
 
-        if (info->mBufferID == bufferID) {
+        if (info->mData == buffer) {
             if (index != NULL) {
                 *index = i;
             }
@@ -293,7 +396,7 @@
 
     info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
 
-    mBufferChannel->fillThisBuffer(info->mBufferID);
+    mBufferChannel->fillThisBuffer(info->mData);
 }
 
 void MediaFilter::postDrainThisBuffer(BufferInfo *info) {
@@ -304,7 +407,7 @@
     sp<AMessage> reply = new AMessage(kWhatOutputBufferDrained, this);
     reply->setInt32("buffer-id", info->mBufferID);
 
-    mBufferChannel->drainThisBuffer(info->mBufferID, info->mOutputFlags);
+    mBufferChannel->drainThisBuffer(info->mData, info->mOutputFlags);
 
     info->mStatus = BufferInfo::OWNED_BY_UPSTREAM;
 }
@@ -359,7 +462,7 @@
     outputInfo->mOutputFlags = 0;
     int32_t eos = 0;
     if (inputInfo->mData->meta()->findInt32("eos", &eos) && eos != 0) {
-        outputInfo->mOutputFlags |= OMX_BUFFERFLAG_EOS;
+        outputInfo->mOutputFlags |= BUFFER_FLAG_END_OF_STREAM;
         mPortEOS[kPortIndexOutput] = true;
         outputInfo->mData->meta()->setInt32("eos", eos);
         postEOS();
@@ -400,8 +503,7 @@
         return;
     }
 
-    // HACK - need "OMX.google" to use MediaCodec's software renderer
-    mCallback->onComponentAllocated("OMX.google.MediaFilter");
+    mCallback->onComponentAllocated(mComponentName.c_str());
     mState = INITIALIZED;
     ALOGV("Handled kWhatAllocateComponent.");
 }
@@ -477,6 +579,7 @@
     mOutputFormat->setRect("crop", 0, 0, mStride, mSliceHeight);
     mOutputFormat->setInt32("width", mWidth);
     mOutputFormat->setInt32("height", mHeight);
+    mOutputFormat->setInt32("using-sw-renderer", 1);
 
     mCallback->onComponentConfigured(mInputFormat, mOutputFormat);
     mState = CONFIGURED;
@@ -509,9 +612,11 @@
 }
 
 void MediaFilter::onInputBufferFilled(const sp<AMessage> &msg) {
-    IOMX::buffer_id bufferID;
-    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
-    BufferInfo *info = findBufferByID(kPortIndexInput, bufferID);
+    sp<RefBase> obj;
+    CHECK(msg->findObject("buffer", &obj));
+    sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
+    ssize_t index = -1;
+    BufferInfo *info = findBuffer(kPortIndexInput, buffer, &index);
 
     if (mState != STARTED) {
         // we're not running, so we'll just keep that buffer...
@@ -520,7 +625,7 @@
     }
 
     if (info->mGeneration != mGeneration) {
-        ALOGV("Caught a stale input buffer [ID %d]", bufferID);
+        ALOGV("Caught a stale input buffer [index %zd]", index);
         // buffer is stale (taken before a flush/shutdown) - repost it
         CHECK_EQ(info->mStatus, BufferInfo::OWNED_BY_US);
         postFillThisBuffer(info);
@@ -530,30 +635,9 @@
     CHECK_EQ(info->mStatus, BufferInfo::OWNED_BY_UPSTREAM);
     info->mStatus = BufferInfo::OWNED_BY_US;
 
-    sp<MediaCodecBuffer> buffer;
     int32_t err = OK;
     bool eos = false;
 
-    sp<RefBase> obj;
-    if (!msg->findObject("buffer", &obj)) {
-        // these are unfilled buffers returned by client
-        CHECK(msg->findInt32("err", &err));
-
-        if (err == OK) {
-            // buffers with no errors are returned on MediaCodec.flush
-            ALOGV("saw unfilled buffer (MediaCodec.flush)");
-            postFillThisBuffer(info);
-            return;
-        } else {
-            ALOGV("saw error %d instead of an input buffer", err);
-            eos = true;
-        }
-
-        buffer.clear();
-    } else {
-        buffer = static_cast<MediaCodecBuffer *>(obj.get());
-    }
-
     int32_t isCSD;
     if (buffer != NULL && buffer->meta()->findInt32("csd", &isCSD)
             && isCSD != 0) {
@@ -577,13 +661,15 @@
         mInputEOSResult = err;
     }
 
-    ALOGV("Handled kWhatInputBufferFilled. [ID %u]", bufferID);
+    ALOGV("Handled kWhatInputBufferFilled. [index %zd]", index);
 }
 
 void MediaFilter::onOutputBufferDrained(const sp<AMessage> &msg) {
-    IOMX::buffer_id bufferID;
-    CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
-    BufferInfo *info = findBufferByID(kPortIndexOutput, bufferID);
+    sp<RefBase> obj;
+    CHECK(msg->findObject("buffer", &obj));
+    sp<MediaCodecBuffer> buffer = static_cast<MediaCodecBuffer *>(obj.get());
+    ssize_t index = -1;
+    BufferInfo *info = findBuffer(kPortIndexOutput, buffer, &index);
 
     if (mState != STARTED) {
         // we're not running, so we'll just keep that buffer...
@@ -592,7 +678,7 @@
     }
 
     if (info->mGeneration != mGeneration) {
-        ALOGV("Caught a stale output buffer [ID %d]", bufferID);
+        ALOGV("Caught a stale output buffer [index %zd]", index);
         // buffer is stale (taken before a flush/shutdown) - keep it
         CHECK_EQ(info->mStatus, BufferInfo::OWNED_BY_US);
         return;
@@ -605,8 +691,7 @@
 
     processBuffers();
 
-    ALOGV("Handled kWhatOutputBufferDrained. [ID %u]",
-            bufferID);
+    ALOGV("Handled kWhatOutputBufferDrained. [index %zd]", index);
 }
 
 void MediaFilter::onShutdown(const sp<AMessage> &msg) {
@@ -739,7 +824,7 @@
             return;
         }
 
-        eosBuf->mOutputFlags = OMX_BUFFERFLAG_EOS;
+        eosBuf->mOutputFlags = BUFFER_FLAG_END_OF_STREAM;
         eosBuf->mGeneration = mGeneration;
         eosBuf->mData->setRange(0, 0);
         postDrainThisBuffer(eosBuf);
diff --git a/media/libstagefright/include/ACodecBufferChannel.h b/media/libstagefright/include/ACodecBufferChannel.h
index 3a087d1..5f65575 100644
--- a/media/libstagefright/include/ACodecBufferChannel.h
+++ b/media/libstagefright/include/ACodecBufferChannel.h
@@ -67,6 +67,9 @@
     virtual ~ACodecBufferChannel();
 
     // BufferChannelBase interface
+    void setCrypto(const sp<ICrypto> &crypto) override;
+    void setDescrambler(const sp<IDescrambler> &descrambler) override;
+
     virtual status_t queueInputBuffer(const sp<MediaCodecBuffer> &buffer) override;
     virtual status_t queueSecureInputBuffer(
             const sp<MediaCodecBuffer> &buffer,
@@ -135,6 +138,9 @@
 
     sp<MemoryDealer> makeMemoryDealer(size_t heapSize);
 
+    sp<ICrypto> mCrypto;
+    sp<IDescrambler> mDescrambler;
+
     bool hasCryptoOrDescrambler() {
         return mCrypto != NULL || mDescrambler != NULL;
     }
diff --git a/media/libstagefright/include/media/stagefright/CodecBase.h b/media/libstagefright/include/media/stagefright/CodecBase.h
index e728c00..bc7881c 100644
--- a/media/libstagefright/include/media/stagefright/CodecBase.h
+++ b/media/libstagefright/include/media/stagefright/CodecBase.h
@@ -257,15 +257,15 @@
  */
 class BufferChannelBase {
 public:
+    BufferChannelBase() = default;
     virtual ~BufferChannelBase() = default;
 
     inline void setCallback(std::unique_ptr<CodecBase::BufferCallback> &&callback) {
         mCallback = std::move(callback);
     }
 
-    void setCrypto(const sp<ICrypto> &crypto);
-
-    void setDescrambler(const sp<IDescrambler> &descrambler);
+    virtual void setCrypto(const sp<ICrypto> &) {}
+    virtual void setDescrambler(const sp<IDescrambler> &) {}
 
     /**
      * Queue an input buffer into the buffer channel.
@@ -336,8 +336,6 @@
 
 protected:
     std::unique_ptr<CodecBase::BufferCallback> mCallback;
-    sp<ICrypto> mCrypto;
-    sp<IDescrambler> mDescrambler;
 };
 
 }  // namespace android
diff --git a/media/libstagefright/include/media/stagefright/InterfaceUtils.h b/media/libstagefright/include/media/stagefright/InterfaceUtils.h
index b83a958..671f2ff 100644
--- a/media/libstagefright/include/media/stagefright/InterfaceUtils.h
+++ b/media/libstagefright/include/media/stagefright/InterfaceUtils.h
@@ -20,7 +20,7 @@
 #include <utils/RefBase.h>
 #include <media/stagefright/RemoteMediaExtractor.h>
 #include <media/MediaSource.h>
-#include <media/IMediaExtractor.h>
+#include <android/IMediaExtractor.h>
 #include <media/IMediaSource.h>
 
 namespace android {
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index 78d00b1..78cb01c 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -29,6 +29,14 @@
 #include <media/stagefright/FrameRenderTracker.h>
 #include <utils/Vector.h>
 
+namespace aidl {
+namespace android {
+namespace media {
+class MediaResourceParcel;
+} // media
+} // android
+} // aidl
+
 namespace android {
 
 struct ABuffer;
@@ -51,13 +59,9 @@
 namespace V1_0 {
 struct IDescrambler;
 }}}}
-namespace media {
-class IResourceManagerClient;
-class MediaResourceParcel;
-}
+
 using hardware::cas::native::V1_0::IDescrambler;
-using media::IResourceManagerClient;
-using media::MediaResourceParcel;
+using aidl::android::media::MediaResourceParcel;
 
 struct MediaCodec : public AHandler {
     enum ConfigureFlags {
@@ -315,8 +319,7 @@
     sp<AMessage> mCallback;
     sp<AMessage> mOnFrameRenderedNotification;
 
-    sp<IResourceManagerClient> mResourceManagerClient;
-    sp<ResourceManagerServiceProxy> mResourceManagerService;
+    sp<ResourceManagerServiceProxy> mResourceManagerProxy;
 
     bool mIsVideo;
     int32_t mVideoWidth;
@@ -410,8 +413,6 @@
     bool isExecuting() const;
 
     uint64_t getGraphicBufferSize();
-    void addResource(const MediaResourceParcel &resource);
-    void removeResource(const MediaResourceParcel &resource);
     void requestCpuBoostIfNeeded();
 
     bool hasPendingBuffer(int portIndex);
diff --git a/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h b/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
index 2ab98e1..745e342 100644
--- a/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
+++ b/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
@@ -22,7 +22,7 @@
 #include <unordered_set>
 
 #include <android/dlext.h>
-#include <media/IMediaExtractor.h>
+#include <android/IMediaExtractor.h>
 
 namespace android {
 
@@ -36,7 +36,7 @@
     static sp<IMediaExtractor> CreateFromService(
             const sp<DataSource> &source, const char *mime = NULL);
     static status_t dump(int fd, const Vector<String16>& args);
-    static std::unordered_set<std::string> getSupportedTypes();
+    static std::vector<std::string> getSupportedTypes();
     static void LoadExtractors();
 
 private:
diff --git a/media/libstagefright/include/media/stagefright/MediaFilter.h b/media/libstagefright/include/media/stagefright/MediaFilter.h
index a28c49d..1255e0f 100644
--- a/media/libstagefright/include/media/stagefright/MediaFilter.h
+++ b/media/libstagefright/include/media/stagefright/MediaFilter.h
@@ -21,9 +21,7 @@
 
 namespace android {
 
-class ACodecBufferChannel;
 struct GraphicBufferListener;
-class MemoryDealer;
 struct SimpleFilter;
 
 struct MediaFilter : public CodecBase {
@@ -65,6 +63,8 @@
         sp<MediaCodecBuffer> mData;
     };
 
+    class BufferChannel;
+
     enum State {
       UNINITIALIZED,
       INITIALIZED,
@@ -104,7 +104,6 @@
     sp<AMessage> mInputFormat;
     sp<AMessage> mOutputFormat;
 
-    sp<MemoryDealer> mDealer[2];
     Vector<BufferInfo> mBuffers[2];
     Vector<BufferInfo*> mAvailableInputBuffers;
     Vector<BufferInfo*> mAvailableOutputBuffers;
@@ -113,15 +112,15 @@
     sp<SimpleFilter> mFilter;
     sp<GraphicBufferListener> mGraphicBufferListener;
 
-    std::shared_ptr<ACodecBufferChannel> mBufferChannel;
+    std::shared_ptr<BufferChannel> mBufferChannel;
 
     // helper functions
     void signalProcessBuffers();
     void signalError(status_t error);
 
     status_t allocateBuffersOnPort(OMX_U32 portIndex);
-    BufferInfo *findBufferByID(
-            uint32_t portIndex, uint32_t bufferID,
+    BufferInfo *findBuffer(
+            uint32_t portIndex, const sp<MediaCodecBuffer> &buffer,
             ssize_t *index = NULL);
     void postFillThisBuffer(BufferInfo *info);
     void postDrainThisBuffer(BufferInfo *info);
diff --git a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
index 4307110..98e4b22 100644
--- a/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/NuMediaExtractor.h
@@ -21,7 +21,7 @@
 #include <media/mediaplayer.h>
 #include <media/stagefright/foundation/ABase.h>
 #include <media/stagefright/foundation/AudioPresentationInfo.h>
-#include <media/IMediaExtractor.h>
+#include <android/IMediaExtractor.h>
 #include <media/MediaSource.h>
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
diff --git a/media/libstagefright/include/media/stagefright/RemoteDataSource.h b/media/libstagefright/include/media/stagefright/RemoteDataSource.h
index 83273cb..d82be8a 100644
--- a/media/libstagefright/include/media/stagefright/RemoteDataSource.h
+++ b/media/libstagefright/include/media/stagefright/RemoteDataSource.h
@@ -17,10 +17,10 @@
 #ifndef REMOTE_DATA_SOURCE_H_
 #define REMOTE_DATA_SOURCE_H_
 
+#include <android/IDataSource.h>
 #include <binder/IMemory.h>
 #include <binder/MemoryDealer.h>
 #include <media/DataSource.h>
-#include <media/IDataSource.h>
 
 namespace android {
 
diff --git a/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h b/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h
index 9925114..2bf5a8b 100644
--- a/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/RemoteMediaExtractor.h
@@ -17,7 +17,7 @@
 #ifndef REMOTE_MEDIA_EXTRACTOR_H_
 #define REMOTE_MEDIA_EXTRACTOR_H_
 
-#include <media/IMediaExtractor.h>
+#include <android/IMediaExtractor.h>
 #include <media/stagefright/MediaExtractor.h>
 #include <media/stagefright/foundation/ABase.h>
 
diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp
index 1f65372..7b22b05 100644
--- a/media/mediaserver/main_mediaserver.cpp
+++ b/media/mediaserver/main_mediaserver.cpp
@@ -40,7 +40,7 @@
     ALOGI("ServiceManager: %p", sm.get());
     AIcu_initializeIcuOrDie();
     MediaPlayerService::instantiate();
-    media::ResourceManagerService::instantiate();
+    ResourceManagerService::instantiate();
     registerExtensions();
     ProcessState::self()->startThreadPool();
     IPCThreadState::self()->joinThreadPool();
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index 0eb46f4..f83d530 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -79,7 +79,6 @@
         "android.hidl.token@1.0-utils",
         "libandroid_runtime_lazy",
         "libbase",
-        "libbinder",
         "libdatasource",
         "libmedia",
         "libmediadrm",
diff --git a/media/ndk/NdkMediaDrm.cpp b/media/ndk/NdkMediaDrm.cpp
index 8a95982..3af9771 100644
--- a/media/ndk/NdkMediaDrm.cpp
+++ b/media/ndk/NdkMediaDrm.cpp
@@ -20,6 +20,10 @@
 #include <inttypes.h>
 #include <unistd.h>
 
+#include <iostream>
+#include <fstream>
+#include <string>
+
 #include <media/NdkMediaDrm.h>
 
 #include <cutils/properties.h>
@@ -28,12 +32,10 @@
 #include <gui/Surface.h>
 
 #include <android-base/properties.h>
-#include <binder/PermissionController.h>
 #include <mediadrm/DrmUtils.h>
 #include <mediadrm/IDrm.h>
 #include <mediadrm/IDrmClient.h>
 #include <media/stagefright/MediaErrors.h>
-#include <binder/IServiceManager.h>
 #include <media/NdkMediaCrypto.h>
 
 
@@ -236,24 +238,15 @@
 }
 
 static status_t GetAppPackageName(String8 *packageName) {
-    sp<IServiceManager> serviceManager = defaultServiceManager();
-    sp<IBinder> binder = serviceManager->getService(String16("permission"));
-
-    sp<IPermissionController> permissionContol = interface_cast<IPermissionController>(binder);
-    if (permissionContol == NULL) {
-        ALOGE("Failed to get permission service");
+    // todo(robertshih): use refactored/renamed libneuralnetworks_packageinfo which is stable
+    std::string appName;
+    std::ifstream cmdline("/proc/self/cmdline");
+    std::getline(cmdline, appName);
+    cmdline.close();
+    if (appName.empty()) {
         return UNKNOWN_ERROR;
     }
-
-    Vector<String16> packages;
-    permissionContol->getPackagesForUid(getuid(), packages);
-
-    if (packages.isEmpty()) {
-        ALOGE("Unable to get package name for current UID");
-        return UNKNOWN_ERROR;
-    }
-
-    *packageName = String8(packages[0]);
+    *packageName = String8(appName.c_str());
     return OK;
 }
 
diff --git a/media/utils/ISchedulingPolicyService.cpp b/media/utils/ISchedulingPolicyService.cpp
index b210404..e60e230 100644
--- a/media/utils/ISchedulingPolicyService.cpp
+++ b/media/utils/ISchedulingPolicyService.cpp
@@ -62,12 +62,12 @@
         return reply.readInt32();
     }
 
-    virtual int requestCpusetBoost(bool enable, const sp<IInterface>& client)
+    virtual int requestCpusetBoost(bool enable, const sp<IBinder>& client)
     {
         Parcel data, reply;
         data.writeInterfaceToken(ISchedulingPolicyService::getInterfaceDescriptor());
         data.writeInt32(enable);
-        data.writeStrongBinder(IInterface::asBinder(client));
+        data.writeStrongBinder(client);
         status_t status = remote()->transact(REQUEST_CPUSET_BOOST, data, &reply, 0);
         if (status != NO_ERROR) {
             return status;
diff --git a/media/utils/ISchedulingPolicyService.h b/media/utils/ISchedulingPolicyService.h
index e4f7c0d..6fa100a 100644
--- a/media/utils/ISchedulingPolicyService.h
+++ b/media/utils/ISchedulingPolicyService.h
@@ -29,7 +29,7 @@
     virtual int         requestPriority(/*pid_t*/int32_t pid, /*pid_t*/int32_t tid,
                                         int32_t prio, bool isForApp, bool asynchronous) = 0;
 
-    virtual int         requestCpusetBoost(bool enable, const sp<IInterface>& client) = 0;
+    virtual int         requestCpusetBoost(bool enable, const sp<IBinder>& client) = 0;
 };
 
 class BnSchedulingPolicyService : public BnInterface<ISchedulingPolicyService>
diff --git a/media/utils/SchedulingPolicyService.cpp b/media/utils/SchedulingPolicyService.cpp
index 4e9792f..ad38862 100644
--- a/media/utils/SchedulingPolicyService.cpp
+++ b/media/utils/SchedulingPolicyService.cpp
@@ -59,7 +59,7 @@
     return ret;
 }
 
-int requestCpusetBoost(bool enable, const sp<IInterface> &client)
+int requestCpusetBoost(bool enable, const sp<IBinder> &client)
 {
     int ret;
     sMutex.lock();
diff --git a/media/utils/include/mediautils/SchedulingPolicyService.h b/media/utils/include/mediautils/SchedulingPolicyService.h
index a33539f..546cec5 100644
--- a/media/utils/include/mediautils/SchedulingPolicyService.h
+++ b/media/utils/include/mediautils/SchedulingPolicyService.h
@@ -21,7 +21,7 @@
 
 namespace android {
 
-class IInterface;
+class IBinder;
 // Request elevated priority for thread tid, whose thread group leader must be pid.
 // The priority parameter is currently restricted to either 1 or 2.
 // The asynchronous parameter should be 'true' to return immediately,
@@ -35,7 +35,7 @@
 // for the server to receive death notifications. When 'enable' is 'false', server
 // will attempt to move media.codec process back to the original cpuset, and
 // 'client' is ignored in this case.
-int requestCpusetBoost(bool enable, const sp<IInterface> &client);
+int requestCpusetBoost(bool enable, const sp<IBinder> &client);
 
 }   // namespace android
 
diff --git a/services/mediaextractor/MediaExtractorService.cpp b/services/mediaextractor/MediaExtractorService.cpp
index 6239fb2..9e814d1 100644
--- a/services/mediaextractor/MediaExtractorService.cpp
+++ b/services/mediaextractor/MediaExtractorService.cpp
@@ -29,48 +29,57 @@
 
 namespace android {
 
-MediaExtractorService::MediaExtractorService()
-        : BnMediaExtractorService() {
+MediaExtractorService::MediaExtractorService() {
     MediaExtractorFactory::LoadExtractors();
 }
 
-sp<IMediaExtractor> MediaExtractorService::makeExtractor(
-        const sp<IDataSource> &remoteSource, const char *mime) {
-    ALOGV("@@@ MediaExtractorService::makeExtractor for %s", mime);
+MediaExtractorService::~MediaExtractorService() {
+    ALOGE("should not be in ~MediaExtractorService");
+}
+
+::android::binder::Status MediaExtractorService::makeExtractor(
+        const ::android::sp<::android::IDataSource>& remoteSource,
+        const ::std::unique_ptr< ::std::string> &mime,
+        ::android::sp<::android::IMediaExtractor>* _aidl_return) {
+    ALOGV("@@@ MediaExtractorService::makeExtractor for %s", mime.get()->c_str());
 
     sp<DataSource> localSource = CreateDataSourceFromIDataSource(remoteSource);
 
-    sp<IMediaExtractor> extractor = MediaExtractorFactory::CreateFromService(localSource, mime);
+    sp<IMediaExtractor> extractor = MediaExtractorFactory::CreateFromService(
+            localSource,
+            mime.get() ? mime.get()->c_str() : nullptr);
 
     ALOGV("extractor service created %p (%s)",
             extractor.get(),
             extractor == nullptr ? "" : extractor->name());
 
     if (extractor != nullptr) {
-        registerMediaExtractor(extractor, localSource, mime);
-        return extractor;
+        registerMediaExtractor(extractor, localSource, mime.get() ? mime.get()->c_str() : nullptr);
     }
-    return nullptr;
+    *_aidl_return = extractor;
+    return binder::Status::ok();
 }
 
-sp<IDataSource> MediaExtractorService::makeIDataSource(int fd, int64_t offset, int64_t length)
-{
-    sp<DataSource> source = DataSourceFactory::getInstance()->CreateFromFd(fd, offset, length);
-    return CreateIDataSourceFromDataSource(source);
+::android::binder::Status MediaExtractorService::makeIDataSource(
+        const base::unique_fd &fd,
+        int64_t offset,
+        int64_t length,
+        ::android::sp<::android::IDataSource>* _aidl_return) {
+    // the caller will close the fd owned by the unique_fd upon return of this function,
+    // so we need to dup() it to retain it.
+    sp<DataSource> source = DataSourceFactory::getInstance()->CreateFromFd(dup(fd.get()), offset, length);
+    *_aidl_return = CreateIDataSourceFromDataSource(source);
+    return binder::Status::ok();
 }
 
-std::unordered_set<std::string> MediaExtractorService::getSupportedTypes() {
-    return MediaExtractorFactory::getSupportedTypes();
+::android::binder::Status MediaExtractorService::getSupportedTypes(
+        ::std::vector<::std::string>* _aidl_return) {
+    *_aidl_return = MediaExtractorFactory::getSupportedTypes();
+    return binder::Status::ok();
 }
 
 status_t MediaExtractorService::dump(int fd, const Vector<String16>& args) {
     return MediaExtractorFactory::dump(fd, args) || dumpExtractors(fd, args);
 }
 
-status_t MediaExtractorService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
-        uint32_t flags)
-{
-    return BnMediaExtractorService::onTransact(code, data, reply, flags);
-}
-
 }   // namespace android
diff --git a/services/mediaextractor/MediaExtractorService.h b/services/mediaextractor/MediaExtractorService.h
index c9cebcf..1b61c4b 100644
--- a/services/mediaextractor/MediaExtractorService.h
+++ b/services/mediaextractor/MediaExtractorService.h
@@ -18,31 +18,33 @@
 #define ANDROID_MEDIA_EXTRACTOR_SERVICE_H
 
 #include <binder/BinderService.h>
-#include <media/IMediaExtractorService.h>
-#include <media/IMediaExtractor.h>
+#include <android/BnMediaExtractorService.h>
+#include <android/IMediaExtractor.h>
 
 namespace android {
 
 class MediaExtractorService : public BinderService<MediaExtractorService>, public BnMediaExtractorService
 {
-    friend class BinderService<MediaExtractorService>;    // for MediaExtractorService()
 public:
     MediaExtractorService();
-    virtual ~MediaExtractorService() { }
-    virtual void onFirstRef() { }
+    virtual ~MediaExtractorService();
 
     static const char*  getServiceName() { return "media.extractor"; }
 
-    virtual sp<IMediaExtractor> makeExtractor(const sp<IDataSource> &source, const char *mime);
+    virtual ::android::binder::Status makeExtractor(
+            const ::android::sp<::android::IDataSource>& source,
+            const ::std::unique_ptr< ::std::string> &mime,
+            ::android::sp<::android::IMediaExtractor>* _aidl_return);
 
-    virtual sp<IDataSource> makeIDataSource(int fd, int64_t offset, int64_t length);
+    virtual ::android::binder::Status makeIDataSource(
+            const base::unique_fd &fd,
+            int64_t offset,
+            int64_t length,
+            ::android::sp<::android::IDataSource>* _aidl_return);
 
-    virtual std::unordered_set<std::string> getSupportedTypes();
+    virtual ::android::binder::Status getSupportedTypes(::std::vector<::std::string>* _aidl_return);
 
-    virtual status_t    dump(int fd, const Vector<String16>& args);
-
-    virtual status_t    onTransact(uint32_t code, const Parcel& data, Parcel* reply,
-                                uint32_t flags);
+    virtual status_t dump(int fd, const Vector<String16>& args);
 
 private:
     Mutex               mLock;
diff --git a/services/mediaresourcemanager/Android.bp b/services/mediaresourcemanager/Android.bp
index d468406..a3519d5 100644
--- a/services/mediaresourcemanager/Android.bp
+++ b/services/mediaresourcemanager/Android.bp
@@ -12,6 +12,7 @@
         "libmedia",
         "libmediautils",
         "libbinder",
+        "libbinder_ndk",
         "libutils",
         "liblog",
     ],
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index ae832c7..877c44d 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -19,6 +19,8 @@
 #define LOG_TAG "ResourceManagerService"
 #include <utils/Log.h>
 
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
 #include <binder/IMediaResourceMonitor.h>
 #include <binder/IServiceManager.h>
 #include <cutils/sched_policy.h>
@@ -38,28 +40,25 @@
 
 namespace android {
 
-namespace media {
+DeathNotifier::DeathNotifier(const std::shared_ptr<ResourceManagerService> &service,
+        int pid, int64_t clientId)
+    : mService(service), mPid(pid), mClientId(clientId) {}
 
-class DeathNotifier : public IBinder::DeathRecipient {
-public:
-    DeathNotifier(const wp<ResourceManagerService> &service, int pid, int64_t clientId)
-        : mService(service), mPid(pid), mClientId(clientId) {}
+//static
+void DeathNotifier::BinderDiedCallback(void* cookie) {
+    auto thiz = static_cast<DeathNotifier*>(cookie);
+    thiz->binderDied();
+}
 
-    virtual void binderDied(const wp<IBinder> & /* who */) override {
-        // Don't check for pid validity since we know it's already dead.
-        sp<ResourceManagerService> service = mService.promote();
-        if (service == nullptr) {
-            ALOGW("ResourceManagerService is dead as well.");
-            return;
-        }
-        service->removeResource(mPid, mClientId, false);
+void DeathNotifier::binderDied() {
+    // Don't check for pid validity since we know it's already dead.
+    std::shared_ptr<ResourceManagerService> service = mService.lock();
+    if (service == nullptr) {
+        ALOGW("ResourceManagerService is dead as well.");
+        return;
     }
-
-private:
-    wp<ResourceManagerService> mService;
-    int mPid;
-    int64_t mClientId;
-};
+    service->removeResource(mPid, mClientId, false);
+}
 
 template <typename T>
 static String8 getString(const std::vector<T> &items) {
@@ -104,7 +103,7 @@
 static ResourceInfo& getResourceInfoForEdit(
         uid_t uid,
         int64_t clientId,
-        const sp<IResourceManagerClient>& client,
+        const std::shared_ptr<IResourceManagerClient>& client,
         ResourceInfos& infos) {
     ssize_t index = infos.indexOfKey(clientId);
 
@@ -135,14 +134,15 @@
     }
 }
 
-status_t ResourceManagerService::dump(int fd, const Vector<String16>& /* args */) {
+binder_status_t ResourceManagerService::dump(
+        int fd, const char** /*args*/, uint32_t /*numArgs*/) {
     String8 result;
 
     if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
         result.format("Permission Denial: "
                 "can't dump ResourceManagerService from pid=%d, uid=%d\n",
-                IPCThreadState::self()->getCallingPid(),
-                IPCThreadState::self()->getCallingUid());
+                AIBinder_getCallingPid(),
+                AIBinder_getCallingUid());
         write(fd, result.string(), result.size());
         return PERMISSION_DENIED;
     }
@@ -206,7 +206,7 @@
 
 struct SystemCallbackImpl :
         public ResourceManagerService::SystemCallbackInterface {
-    SystemCallbackImpl() {}
+    SystemCallbackImpl() : mClientToken(new BBinder()) {}
 
     virtual void noteStartVideo(int uid) override {
         BatteryNotifier::getInstance().noteStartVideo(uid);
@@ -217,9 +217,8 @@
     virtual void noteResetVideo() override {
         BatteryNotifier::getInstance().noteResetVideo();
     }
-    virtual bool requestCpusetBoost(
-            bool enable, const sp<IInterface> &client) override {
-        return android::requestCpusetBoost(enable, client);
+    virtual bool requestCpusetBoost(bool enable) override {
+        return android::requestCpusetBoost(enable, mClientToken);
     }
 
 protected:
@@ -227,6 +226,7 @@
 
 private:
     DISALLOW_EVIL_CONSTRUCTORS(SystemCallbackImpl);
+    sp<IBinder> mClientToken;
 };
 
 ResourceManagerService::ResourceManagerService()
@@ -240,10 +240,26 @@
       mServiceLog(new ServiceLog()),
       mSupportsMultipleSecureCodecs(true),
       mSupportsSecureWithNonSecureCodec(true),
-      mCpuBoostCount(0) {
+      mCpuBoostCount(0),
+      mDeathRecipient(AIBinder_DeathRecipient_new(DeathNotifier::BinderDiedCallback)) {
     mSystemCB->noteResetVideo();
 }
 
+//static
+void ResourceManagerService::instantiate() {
+    std::shared_ptr<ResourceManagerService> service =
+            ::ndk::SharedRefBase::make<ResourceManagerService>();
+    binder_status_t status =
+            AServiceManager_addService(service->asBinder().get(), getServiceName());
+    if (status != STATUS_OK) {
+        return;
+    }
+    // TODO: mediaserver main() is already starting the thread pool,
+    // move this to mediaserver main() when other services in mediaserver
+    // are converted to ndk-platform aidl.
+    //ABinderProcess_startThreadPool();
+}
+
 ResourceManagerService::~ResourceManagerService() {}
 
 Status ResourceManagerService::config(const std::vector<MediaResourcePolicyParcel>& policies) {
@@ -271,7 +287,7 @@
         // Request it on every new instance of kCpuBoost, as the media.codec
         // could have died, if we only do it the first time subsequent instances
         // never gets the boost.
-        if (mSystemCB->requestCpusetBoost(true, this) != OK) {
+        if (mSystemCB->requestCpusetBoost(true) != OK) {
             ALOGW("couldn't request cpuset boost");
         }
         mCpuBoostCount++;
@@ -287,7 +303,7 @@
             && resource.subType == MediaResource::SubType::kUnspecifiedSubType
             && mCpuBoostCount > 0) {
         if (--mCpuBoostCount == 0) {
-            mSystemCB->requestCpusetBoost(false, this);
+            mSystemCB->requestCpusetBoost(false);
         }
     } else if (resource.type == MediaResource::Type::kBattery
             && resource.subType == MediaResource::SubType::kVideoCodec) {
@@ -316,7 +332,7 @@
         int32_t pid,
         int32_t uid,
         int64_t clientId,
-        const sp<IResourceManagerClient>& client,
+        const std::shared_ptr<IResourceManagerClient>& client,
         const std::vector<MediaResourceParcel>& resources) {
     String8 log = String8::format("addResource(pid %d, clientId %lld, resources %s)",
             pid, (long long) clientId, getString(resources).string());
@@ -352,8 +368,9 @@
         }
     }
     if (info.deathNotifier == nullptr && client != nullptr) {
-        info.deathNotifier = new DeathNotifier(this, pid, clientId);
-        IInterface::asBinder(client)->linkToDeath(info.deathNotifier);
+        info.deathNotifier = new DeathNotifier(ref<ResourceManagerService>(), pid, clientId);
+        AIBinder_linkToDeath(client->asBinder().get(),
+                mDeathRecipient.get(), info.deathNotifier.get());
     }
     notifyResourceGranted(pid, resources);
     return Status::ok();
@@ -442,18 +459,20 @@
         onLastRemoved(it->second, info);
     }
 
-    IInterface::asBinder(info.client)->unlinkToDeath(info.deathNotifier);
+    AIBinder_unlinkToDeath(info.client->asBinder().get(),
+            mDeathRecipient.get(), info.deathNotifier.get());
 
     infos.removeItemsAt(index);
     return Status::ok();
 }
 
 void ResourceManagerService::getClientForResource_l(
-        int callingPid, const MediaResourceParcel *res, Vector<sp<IResourceManagerClient>> *clients) {
+        int callingPid, const MediaResourceParcel *res,
+        Vector<std::shared_ptr<IResourceManagerClient>> *clients) {
     if (res == NULL) {
         return;
     }
-    sp<IResourceManagerClient> client;
+    std::shared_ptr<IResourceManagerClient> client;
     if (getLowestPriorityBiggestClient_l(callingPid, res->type, &client)) {
         clients->push_back(client);
     }
@@ -468,7 +487,7 @@
     mServiceLog->add(log);
     *_aidl_return = false;
 
-    Vector<sp<IResourceManagerClient>> clients;
+    Vector<std::shared_ptr<IResourceManagerClient>> clients;
     {
         Mutex::Autolock lock(mLock);
         if (!mProcessInfo->isValidPid(callingPid)) {
@@ -547,7 +566,7 @@
         return Status::ok();
     }
 
-    sp<IResourceManagerClient> failedClient;
+    std::shared_ptr<IResourceManagerClient> failedClient;
     for (size_t i = 0; i < clients.size(); ++i) {
         log = String8::format("reclaimResource from client %p", clients[i].get());
         mServiceLog->add(log);
@@ -590,8 +609,9 @@
 }
 
 bool ResourceManagerService::getAllClients_l(
-        int callingPid, MediaResource::Type type, Vector<sp<IResourceManagerClient>> *clients) {
-    Vector<sp<IResourceManagerClient>> temp;
+        int callingPid, MediaResource::Type type,
+        Vector<std::shared_ptr<IResourceManagerClient>> *clients) {
+    Vector<std::shared_ptr<IResourceManagerClient>> temp;
     for (size_t i = 0; i < mMap.size(); ++i) {
         ResourceInfos &infos = mMap.editValueAt(i);
         for (size_t j = 0; j < infos.size(); ++j) {
@@ -616,7 +636,8 @@
 }
 
 bool ResourceManagerService::getLowestPriorityBiggestClient_l(
-        int callingPid, MediaResource::Type type, sp<IResourceManagerClient> *client) {
+        int callingPid, MediaResource::Type type,
+        std::shared_ptr<IResourceManagerClient> *client) {
     int lowestPriorityPid;
     int lowestPriority;
     int callingPriority;
@@ -688,14 +709,14 @@
 }
 
 bool ResourceManagerService::getBiggestClient_l(
-        int pid, MediaResource::Type type, sp<IResourceManagerClient> *client) {
+        int pid, MediaResource::Type type, std::shared_ptr<IResourceManagerClient> *client) {
     ssize_t index = mMap.indexOfKey(pid);
     if (index < 0) {
         ALOGE("getBiggestClient_l: can't find resource info for pid %d", pid);
         return false;
     }
 
-    sp<IResourceManagerClient> clientTemp;
+    std::shared_ptr<IResourceManagerClient> clientTemp;
     uint64_t largestValue = 0;
     const ResourceInfos &infos = mMap.valueAt(index);
     for (size_t i = 0; i < infos.size(); ++i) {
@@ -720,5 +741,4 @@
     return true;
 }
 
-} // namespace media
 } // namespace android
diff --git a/services/mediaresourcemanager/ResourceManagerService.h b/services/mediaresourcemanager/ResourceManagerService.h
index b5b9f86..ae12d7b 100644
--- a/services/mediaresourcemanager/ResourceManagerService.h
+++ b/services/mediaresourcemanager/ResourceManagerService.h
@@ -18,9 +18,8 @@
 #ifndef ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H
 #define ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H
 
-#include <android/media/BnResourceManagerService.h>
+#include <aidl/android/media/BnResourceManagerService.h>
 #include <arpa/inet.h>
-#include <binder/BinderService.h>
 #include <media/MediaResource.h>
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
@@ -30,22 +29,26 @@
 
 namespace android {
 
+class DeathNotifier;
+class ResourceManagerService;
 class ServiceLog;
 struct ProcessInfoInterface;
 
-namespace media {
-
-using android::binder::Status;
+using Status = ::ndk::ScopedAStatus;
+using ::aidl::android::media::IResourceManagerClient;
+using ::aidl::android::media::BnResourceManagerService;
+using ::aidl::android::media::MediaResourceParcel;
+using ::aidl::android::media::MediaResourcePolicyParcel;
 
 typedef std::map<std::tuple<
-        MediaResource::Type, MediaResource::SubType, std::vector<uint8_t>>,
+        MediaResource::Type, MediaResource::SubType, std::vector<int8_t>>,
         MediaResourceParcel> ResourceList;
 
 struct ResourceInfo {
     int64_t clientId;
     uid_t uid;
-    sp<IResourceManagerClient> client;
-    sp<IBinder::DeathRecipient> deathNotifier;
+    std::shared_ptr<IResourceManagerClient> client;
+    sp<DeathNotifier> deathNotifier;
     ResourceList resources;
 };
 
@@ -53,27 +56,42 @@
 typedef KeyedVector<int64_t, ResourceInfo> ResourceInfos;
 typedef KeyedVector<int, ResourceInfos> PidResourceInfosMap;
 
-class ResourceManagerService
-    : public BinderService<ResourceManagerService>,
-      public BnResourceManagerService
-{
+class DeathNotifier : public RefBase {
+public:
+    DeathNotifier(const std::shared_ptr<ResourceManagerService> &service,
+            int pid, int64_t clientId);
+
+    ~DeathNotifier() {}
+
+    // Implement death recipient
+    static void BinderDiedCallback(void* cookie);
+    void binderDied();
+
+private:
+    std::weak_ptr<ResourceManagerService> mService;
+    int mPid;
+    int64_t mClientId;
+};
+class ResourceManagerService : public BnResourceManagerService {
 public:
     struct SystemCallbackInterface : public RefBase {
         virtual void noteStartVideo(int uid) = 0;
         virtual void noteStopVideo(int uid) = 0;
         virtual void noteResetVideo() = 0;
-        virtual bool requestCpusetBoost(
-                bool enable, const sp<IInterface> &client) = 0;
+        virtual bool requestCpusetBoost(bool enable) = 0;
     };
 
     static char const *getServiceName() { return "media.resource_manager"; }
+    static void instantiate();
 
-    virtual status_t dump(int fd, const Vector<String16>& args);
+    virtual inline binder_status_t dump(
+            int /*fd*/, const char** /*args*/, uint32_t /*numArgs*/);
 
     ResourceManagerService();
     explicit ResourceManagerService(
             const sp<ProcessInfoInterface> &processInfo,
             const sp<SystemCallbackInterface> &systemResource);
+    virtual ~ResourceManagerService();
 
     // IResourceManagerService interface
     Status config(const std::vector<MediaResourcePolicyParcel>& policies) override;
@@ -82,7 +100,7 @@
             int32_t pid,
             int32_t uid,
             int64_t clientId,
-            const sp<IResourceManagerClient>& client,
+            const std::shared_ptr<IResourceManagerClient>& client,
             const std::vector<MediaResourceParcel>& resources) override;
 
     Status removeResource(
@@ -102,9 +120,6 @@
 
     Status removeResource(int pid, int64_t clientId, bool checkValid);
 
-protected:
-    virtual ~ResourceManagerService();
-
 private:
     friend class ResourceManagerServiceTest;
 
@@ -112,13 +127,13 @@
     // Returns false if any client belongs to a process with higher priority than the
     // calling process. The clients will remain unchanged if returns false.
     bool getAllClients_l(int callingPid, MediaResource::Type type,
-            Vector<sp<IResourceManagerClient>> *clients);
+            Vector<std::shared_ptr<IResourceManagerClient>> *clients);
 
     // Gets the client who owns specified resource type from lowest possible priority process.
     // Returns false if the calling process priority is not higher than the lowest process
     // priority. The client will remain unchanged if returns false.
     bool getLowestPriorityBiggestClient_l(int callingPid, MediaResource::Type type,
-            sp<IResourceManagerClient> *client);
+            std::shared_ptr<IResourceManagerClient> *client);
 
     // Gets lowest priority process that has the specified resource type.
     // Returns false if failed. The output parameters will remain unchanged if failed.
@@ -126,14 +141,15 @@
 
     // Gets the client who owns biggest piece of specified resource type from pid.
     // Returns false if failed. The client will remain unchanged if failed.
-    bool getBiggestClient_l(int pid, MediaResource::Type type, sp<IResourceManagerClient> *client);
+    bool getBiggestClient_l(int pid, MediaResource::Type type,
+            std::shared_ptr<IResourceManagerClient> *client);
 
     bool isCallingPriorityHigher_l(int callingPid, int pid);
 
-    // A helper function basically calls getLowestPriorityBiggestClient_l and add the result client
-    // to the given Vector.
-    void getClientForResource_l(int callingPid,
-            const MediaResourceParcel *res, Vector<sp<IResourceManagerClient>> *clients);
+    // A helper function basically calls getLowestPriorityBiggestClient_l and add
+    // the result client to the given Vector.
+    void getClientForResource_l(int callingPid, const MediaResourceParcel *res,
+            Vector<std::shared_ptr<IResourceManagerClient>> *clients);
 
     void onFirstAdded(const MediaResourceParcel& res, const ResourceInfo& clientInfo);
     void onLastRemoved(const MediaResourceParcel& res, const ResourceInfo& clientInfo);
@@ -149,10 +165,10 @@
     bool mSupportsMultipleSecureCodecs;
     bool mSupportsSecureWithNonSecureCodec;
     int32_t mCpuBoostCount;
+    ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
 };
 
 // ----------------------------------------------------------------------------
-} // namespace media
 } // namespace android
 
 #endif // ANDROID_MEDIA_RESOURCEMANAGERSERVICE_H
diff --git a/services/mediaresourcemanager/test/Android.bp b/services/mediaresourcemanager/test/Android.bp
index 543c87c..b6c548c 100644
--- a/services/mediaresourcemanager/test/Android.bp
+++ b/services/mediaresourcemanager/test/Android.bp
@@ -5,6 +5,7 @@
     test_suites: ["device-tests"],
     shared_libs: [
         "libbinder",
+        "libbinder_ndk",
         "liblog",
         "libmedia",
         "libresourcemanagerservice",
diff --git a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
index 203baf5..168fde9 100644
--- a/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
+++ b/services/mediaresourcemanager/test/ResourceManagerService_test.cpp
@@ -21,18 +21,28 @@
 #include <gtest/gtest.h>
 
 #include "ResourceManagerService.h"
-#include <android/media/BnResourceManagerClient.h>
+#include <aidl/android/media/BnResourceManagerClient.h>
 #include <media/MediaResource.h>
 #include <media/MediaResourcePolicy.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/ProcessInfoInterface.h>
 
+namespace aidl {
 namespace android {
 namespace media {
+bool operator== (const MediaResourceParcel& lhs, const MediaResourceParcel& rhs) {
+    return lhs.type == rhs.type && lhs.subType == rhs.subType &&
+            lhs.id == rhs.id && lhs.value == rhs.value;
+}}}}
 
-using ::android::binder::Status;
+namespace android {
 
-static int64_t getId(const sp<IResourceManagerClient>& client) {
+using Status = ::ndk::ScopedAStatus;
+using ::aidl::android::media::BnResourceManagerClient;
+using ::aidl::android::media::IResourceManagerService;
+using ::aidl::android::media::IResourceManagerClient;
+
+static int64_t getId(const std::shared_ptr<IResourceManagerClient>& client) {
     return (int64_t) client.get();
 }
 
@@ -89,8 +99,7 @@
         mEventCount++;
     }
 
-    virtual bool requestCpusetBoost(
-            bool enable, const sp<IInterface> &/*client*/) override {
+    virtual bool requestCpusetBoost(bool enable) override {
         mLastEvent = {enable ? EventType::CPUSET_ENABLE : EventType::CPUSET_DISABLE, 0};
         mEventCount++;
         return true;
@@ -112,12 +121,11 @@
 
 
 struct TestClient : public BnResourceManagerClient {
-    TestClient(int pid, sp<ResourceManagerService> service)
+    TestClient(int pid, const std::shared_ptr<ResourceManagerService> &service)
         : mReclaimed(false), mPid(pid), mService(service) {}
 
     Status reclaimResource(bool* _aidl_return) override {
-        sp<IResourceManagerClient> client(this);
-        mService->removeClient(mPid, (int64_t) client.get());
+        mService->removeClient(mPid, getId(ref<TestClient>()));
         mReclaimed = true;
         *_aidl_return = true;
         return Status::ok();
@@ -136,13 +144,12 @@
         mReclaimed = false;
     }
 
-protected:
     virtual ~TestClient() {}
 
 private:
     bool mReclaimed;
     int mPid;
-    sp<ResourceManagerService> mService;
+    std::shared_ptr<ResourceManagerService> mService;
     DISALLOW_EVIL_CONSTRUCTORS(TestClient);
 };
 
@@ -172,10 +179,11 @@
 public:
     ResourceManagerServiceTest()
         : mSystemCB(new TestSystemCallback()),
-          mService(new ResourceManagerService(new TestProcessInfo, mSystemCB)),
-          mTestClient1(new TestClient(kTestPid1, mService)),
-          mTestClient2(new TestClient(kTestPid2, mService)),
-          mTestClient3(new TestClient(kTestPid2, mService)) {
+          mService(::ndk::SharedRefBase::make<ResourceManagerService>(
+                  new TestProcessInfo, mSystemCB)),
+          mTestClient1(::ndk::SharedRefBase::make<TestClient>(kTestPid1, mService)),
+          mTestClient2(::ndk::SharedRefBase::make<TestClient>(kTestPid2, mService)),
+          mTestClient3(::ndk::SharedRefBase::make<TestClient>(kTestPid2, mService)) {
     }
 
 protected:
@@ -193,7 +201,7 @@
 
     static void expectEqResourceInfo(const ResourceInfo &info,
             int uid,
-            sp<IResourceManagerClient> client,
+            std::shared_ptr<IResourceManagerClient> client,
             const std::vector<MediaResourceParcel> &resources) {
         EXPECT_EQ(uid, info.uid);
         EXPECT_EQ(client, info.client);
@@ -334,11 +342,11 @@
         std::vector<MediaResourcePolicyParcel> policies1;
         policies1.push_back(
                 MediaResourcePolicy(
-                        IResourceManagerService::kPolicySupportsMultipleSecureCodecs(),
+                        IResourceManagerService::kPolicySupportsMultipleSecureCodecs,
                         "true"));
         policies1.push_back(
                 MediaResourcePolicy(
-                        IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec(),
+                        IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec,
                         "false"));
         mService->config(policies1);
         EXPECT_TRUE(mService->mSupportsMultipleSecureCodecs);
@@ -347,11 +355,11 @@
         std::vector<MediaResourcePolicyParcel> policies2;
         policies2.push_back(
                 MediaResourcePolicy(
-                        IResourceManagerService::kPolicySupportsMultipleSecureCodecs(),
+                        IResourceManagerService::kPolicySupportsMultipleSecureCodecs,
                         "false"));
         policies2.push_back(
                 MediaResourcePolicy(
-                        IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec(),
+                        IResourceManagerService::kPolicySupportsSecureWithNonSecureCodec,
                         "true"));
         mService->config(policies2);
         EXPECT_FALSE(mService->mSupportsMultipleSecureCodecs);
@@ -458,7 +466,7 @@
         addResource();
 
         MediaResource::Type type = MediaResource::Type::kSecureCodec;
-        Vector<sp<IResourceManagerClient> > clients;
+        Vector<std::shared_ptr<IResourceManagerClient> > clients;
         EXPECT_FALSE(mService->getAllClients_l(kLowPriorityPid, type, &clients));
         // some higher priority process (e.g. kTestPid2) owns the resource, so getAllClients_l
         // will fail.
@@ -667,7 +675,7 @@
 
     void testGetLowestPriorityBiggestClient() {
         MediaResource::Type type = MediaResource::Type::kGraphicMemory;
-        sp<IResourceManagerClient> client;
+        std::shared_ptr<IResourceManagerClient> client;
         EXPECT_FALSE(mService->getLowestPriorityBiggestClient_l(kHighPriorityPid, type, &client));
 
         addResource();
@@ -706,7 +714,7 @@
 
     void testGetBiggestClient() {
         MediaResource::Type type = MediaResource::Type::kGraphicMemory;
-        sp<IResourceManagerClient> client;
+        std::shared_ptr<IResourceManagerClient> client;
         EXPECT_FALSE(mService->getBiggestClient_l(kTestPid2, type, &client));
 
         addResource();
@@ -799,10 +807,10 @@
     }
 
     sp<TestSystemCallback> mSystemCB;
-    sp<ResourceManagerService> mService;
-    sp<IResourceManagerClient> mTestClient1;
-    sp<IResourceManagerClient> mTestClient2;
-    sp<IResourceManagerClient> mTestClient3;
+    std::shared_ptr<ResourceManagerService> mService;
+    std::shared_ptr<IResourceManagerClient> mTestClient1;
+    std::shared_ptr<IResourceManagerClient> mTestClient2;
+    std::shared_ptr<IResourceManagerClient> mTestClient3;
 };
 
 TEST_F(ResourceManagerServiceTest, config) {
@@ -862,5 +870,4 @@
     testCpusetBoost();
 }
 
-} // namespace media
 } // namespace android
diff --git a/tools/OWNERS b/tools/OWNERS
deleted file mode 100644
index f9cb567..0000000
--- a/tools/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-gkasten@google.com
diff --git a/tools/resampler_tools/Android.bp b/tools/resampler_tools/Android.bp
deleted file mode 100644
index 7549359..0000000
--- a/tools/resampler_tools/Android.bp
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2005 The Android Open Source Project
-//
-// Android.mk for resampler_tools
-//
-
-cc_binary_host {
-    name: "fir",
-
-    srcs: ["fir.cpp"],
-
-    cflags: [
-        "-Werror",
-        "-Wall",
-    ],
-}
diff --git a/tools/resampler_tools/OWNERS b/tools/resampler_tools/OWNERS
deleted file mode 100644
index b4a6798..0000000
--- a/tools/resampler_tools/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-hunga@google.com
diff --git a/tools/resampler_tools/fir.cpp b/tools/resampler_tools/fir.cpp
deleted file mode 100644
index fe4d212..0000000
--- a/tools/resampler_tools/fir.cpp
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * Copyright (C) 2007 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 <math.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-
-static inline double sinc(double x) {
-    if (fabs(x) == 0.0f) return 1.0f;
-    return sin(x) / x;
-}
-
-static inline double sqr(double x) {
-    return x*x;
-}
-
-static inline int64_t toint(double x, int64_t maxval) {
-    int64_t v;
-
-    v = static_cast<int64_t>(floor(x * maxval + 0.5));
-    if (v >= maxval) {
-        return maxval - 1; // error!
-    }
-    return v;
-}
-
-static double I0(double x) {
-    // from the Numerical Recipes in C p. 237
-    double ax,ans,y;
-    ax=fabs(x);
-    if (ax < 3.75) {
-        y=x/3.75;
-        y*=y;
-        ans=1.0+y*(3.5156229+y*(3.0899424+y*(1.2067492
-                +y*(0.2659732+y*(0.360768e-1+y*0.45813e-2)))));
-    } else {
-        y=3.75/ax;
-        ans=(exp(ax)/sqrt(ax))*(0.39894228+y*(0.1328592e-1
-                +y*(0.225319e-2+y*(-0.157565e-2+y*(0.916281e-2
-                        +y*(-0.2057706e-1+y*(0.2635537e-1+y*(-0.1647633e-1
-                                +y*0.392377e-2))))))));
-    }
-    return ans;
-}
-
-static double kaiser(int k, int N, double beta) {
-    if (k < 0 || k > N)
-        return 0;
-    return I0(beta * sqrt(1.0 - sqr((2.0*k)/N - 1.0))) / I0(beta);
-}
-
-static void usage(char* name) {
-    fprintf(stderr,
-            "usage: %s [-h] [-d] [-D] [-s sample_rate] [-c cut-off_frequency] [-n half_zero_crossings]"
-            " [-f {float|fixed|fixed16}] [-b beta] [-v dBFS] [-l lerp]\n"
-            "       %s [-h] [-d] [-D] [-s sample_rate] [-c cut-off_frequency] [-n half_zero_crossings]"
-            " [-f {float|fixed|fixed16}] [-b beta] [-v dBFS] -p M/N\n"
-            "    -h    this help message\n"
-            "    -d    debug, print comma-separated coefficient table\n"
-            "    -D    generate extra declarations\n"
-            "    -p    generate poly-phase filter coefficients, with sample increment M/N\n"
-            "    -s    sample rate (48000)\n"
-            "    -c    cut-off frequency (20478)\n"
-            "    -n    number of zero-crossings on one side (8)\n"
-            "    -l    number of lerping bits (4)\n"
-            "    -m    number of polyphases (related to -l, default 16)\n"
-            "    -f    output format, can be fixed, fixed16, or float (fixed)\n"
-            "    -b    kaiser window parameter beta (7.865 [-80dB])\n"
-            "    -v    attenuation in dBFS (0)\n",
-            name, name
-    );
-    exit(0);
-}
-
-int main(int argc, char** argv)
-{
-    // nc is the number of bits to store the coefficients
-    int nc = 32;
-    bool polyphase = false;
-    unsigned int polyM = 160;
-    unsigned int polyN = 147;
-    bool debug = false;
-    double Fs = 48000;
-    double Fc = 20478;
-    double atten = 1;
-    int format = 0;     // 0=fixed, 1=float
-    bool declarations = false;
-
-    // in order to keep the errors associated with the linear
-    // interpolation of the coefficients below the quantization error
-    // we must satisfy:
-    //   2^nz >= 2^(nc/2)
-    //
-    // for 16 bit coefficients that would be 256
-    //
-    // note that increasing nz only increases memory requirements,
-    // but doesn't increase the amount of computation to do.
-    //
-    //
-    // see:
-    // Smith, J.O. Digital Audio Resampling Home Page
-    // https://ccrma.stanford.edu/~jos/resample/, 2011-03-29
-    //
-
-    //         | 0.1102*(A - 8.7)                         A > 50
-    //  beta = | 0.5842*(A - 21)^0.4 + 0.07886*(A - 21)   21 <= A <= 50
-    //         | 0                                        A < 21
-    //   with A is the desired stop-band attenuation in dBFS
-    //
-    // for eg:
-    //
-    //    30 dB    2.210
-    //    40 dB    3.384
-    //    50 dB    4.538
-    //    60 dB    5.658
-    //    70 dB    6.764
-    //    80 dB    7.865
-    //    90 dB    8.960
-    //   100 dB   10.056
-    double beta = 7.865;
-
-    // 2*nzc = (A - 8) / (2.285 * dw)
-    //      with dw the transition width = 2*pi*dF/Fs
-    //
-    int nzc = 8;
-
-    /*
-     * Example:
-     * 44.1 KHz to 48 KHz resampling
-     * 100 dB rejection above 28 KHz
-     *   (the spectrum will fold around 24 KHz and we want 100 dB rejection
-     *    at the point where the folding reaches 20 KHz)
-     *  ...___|_____
-     *        |     \|
-     *        | ____/|\____
-     *        |/alias|     \
-     *  ------/------+------\---------> KHz
-     *       20     24     28
-     *
-     * Transition band 8 KHz, or dw = 1.0472
-     *
-     * beta = 10.056
-     * nzc  = 20
-     */
-
-    int M = 1 << 4; // number of phases for interpolation
-    int ch;
-    while ((ch = getopt(argc, argv, ":hds:c:n:f:l:m:b:p:v:z:D")) != -1) {
-        switch (ch) {
-            case 'd':
-                debug = true;
-                break;
-            case 'D':
-                declarations = true;
-                break;
-            case 'p':
-                if (sscanf(optarg, "%u/%u", &polyM, &polyN) != 2) {
-                    usage(argv[0]);
-                }
-                polyphase = true;
-                break;
-            case 's':
-                Fs = atof(optarg);
-                break;
-            case 'c':
-                Fc = atof(optarg);
-                break;
-            case 'n':
-                nzc = atoi(optarg);
-                break;
-            case 'm':
-                M = atoi(optarg);
-                break;
-            case 'l':
-                M = 1 << atoi(optarg);
-                break;
-            case 'f':
-                if (!strcmp(optarg, "fixed")) {
-                    format = 0;
-                }
-                else if (!strcmp(optarg, "fixed16")) {
-                    format = 0;
-                    nc = 16;
-                }
-                else if (!strcmp(optarg, "float")) {
-                    format = 1;
-                }
-                else {
-                    usage(argv[0]);
-                }
-                break;
-            case 'b':
-                beta = atof(optarg);
-                break;
-            case 'v':
-                atten = pow(10, -fabs(atof(optarg))*0.05 );
-                break;
-            case 'h':
-            default:
-                usage(argv[0]);
-                break;
-        }
-    }
-
-    // cut off frequency ratio Fc/Fs
-    double Fcr = Fc / Fs;
-
-    // total number of coefficients (one side)
-
-    const int N = M * nzc;
-
-    // lerp (which is most useful if M is a power of 2)
-
-    int nz = 0; // recalculate nz as the bits needed to represent M
-    for (int i = M-1 ; i; i>>=1, nz++);
-    // generate the right half of the filter
-    if (!debug) {
-        printf("// cmd-line:");
-        for (int i=0 ; i<argc ; i++) {
-            printf(" %s", argv[i]);
-        }
-        printf("\n");
-        if (declarations) {
-            if (!polyphase) {
-                printf("const int32_t RESAMPLE_FIR_SIZE           = %d;\n", N);
-                printf("const int32_t RESAMPLE_FIR_INT_PHASES     = %d;\n", M);
-                printf("const int32_t RESAMPLE_FIR_NUM_COEF       = %d;\n", nzc);
-            } else {
-                printf("const int32_t RESAMPLE_FIR_SIZE           = %d;\n", 2*nzc*polyN);
-                printf("const int32_t RESAMPLE_FIR_NUM_COEF       = %d;\n", 2*nzc);
-            }
-            if (!format) {
-                printf("const int32_t RESAMPLE_FIR_COEF_BITS      = %d;\n", nc);
-            }
-            printf("\n");
-            printf("static %s resampleFIR[] = {", !format ? "int32_t" : "float");
-        }
-    }
-
-    if (!polyphase) {
-        for (int i=0 ; i<=M ; i++) { // an extra set of coefs for interpolation
-            for (int j=0 ; j<nzc ; j++) {
-                int ix = j*M + i;
-                double x = (2.0 * M_PI * ix * Fcr) / M;
-                double y = kaiser(ix+N, 2*N, beta) * sinc(x) * 2.0 * Fcr;
-                y *= atten;
-
-                if (!debug) {
-                    if (j == 0)
-                        printf("\n    ");
-                }
-                if (!format) {
-                    int64_t yi = toint(y, 1ULL<<(nc-1));
-                    if (nc > 16) {
-                        printf("0x%08x,", int32_t(yi));
-                    } else {
-                        printf("0x%04x,", int32_t(yi)&0xffff);
-                    }
-                } else {
-                    printf("%.9g%s", y, debug ? "," : "f,");
-                }
-                if (j != nzc-1) {
-                    printf(" ");
-                }
-            }
-        }
-    } else {
-        for (unsigned int j=0 ; j<polyN ; j++) {
-            // calculate the phase
-            double p = ((polyM*j) % polyN) / double(polyN);
-            if (!debug) printf("\n    ");
-            else        printf("\n");
-            // generate a FIR per phase
-            for (int i=-nzc ; i<nzc ; i++) {
-                double x = 2.0 * M_PI * Fcr * (i + p);
-                double y = kaiser(i+N, 2*N, beta) * sinc(x) * 2.0 * Fcr;;
-                y *= atten;
-                if (!format) {
-                    int64_t yi = toint(y, 1ULL<<(nc-1));
-                    if (nc > 16) {
-                        printf("0x%08x,", int32_t(yi));
-                    } else {
-                        printf("0x%04x,", int32_t(yi)&0xffff);
-                    }
-                } else {
-                    printf("%.9g%s", y, debug ? "," : "f,");
-                }
-
-                if (i != nzc-1) {
-                    printf(" ");
-                }
-            }
-        }
-    }
-
-    if (!debug && declarations) {
-        printf("\n};");
-    }
-    printf("\n");
-    return 0;
-}
-
-// http://www.csee.umbc.edu/help/sound/AFsp-V2R1/html/audio/ResampAudio.html