Merge "Refactor opening output interface between AF and AP."
diff --git a/camera/cameraserver/Android.bp b/camera/cameraserver/Android.bp
index 334f879..320c499 100644
--- a/camera/cameraserver/Android.bp
+++ b/camera/cameraserver/Android.bp
@@ -17,6 +17,10 @@
 
     srcs: ["main_cameraserver.cpp"],
 
+    header_libs: [
+        "libmedia_headers",
+    ],
+
     shared_libs: [
         "libcameraservice",
         "liblog",
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 8507729..52c7438 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -35,6 +35,10 @@
         "include"
     ],
 
+    header_libs: [
+        "libmedia_headers",
+    ],
+
     shared_libs: [
         "libbinder",
         "libcutils",
@@ -77,6 +81,9 @@
         export_proto_headers: true,
         type: "lite",
     },
+    header_libs: [
+        "libmedia_headers",
+    ],
     shared_libs: [
         "android.hardware.drm@1.0",
         "android.hardware.drm@1.1",
@@ -112,6 +119,9 @@
         export_proto_headers: true,
         type: "full",
     },
+    header_libs: [
+        "libmedia_headers",
+    ],
     shared_libs: [
         "android.hardware.drm@1.0",
         "android.hardware.drm@1.1",
diff --git a/drm/libmediadrm/tests/Android.bp b/drm/libmediadrm/tests/Android.bp
index 873083b..2e39943 100644
--- a/drm/libmediadrm/tests/Android.bp
+++ b/drm/libmediadrm/tests/Android.bp
@@ -3,8 +3,8 @@
 cc_test {
     name: "CounterMetric_test",
     srcs: ["CounterMetric_test.cpp"],
+    header_libs: ["libmedia_headers"],
     shared_libs: ["libmediadrm"],
-    include_dirs: ["frameworks/av/include/media"],
     cflags: [
       "-Werror",
       "-Wall",
@@ -14,6 +14,9 @@
 cc_test {
     name: "DrmMetrics_test",
     srcs: ["DrmMetrics_test.cpp"],
+    header_libs: [
+        "libmedia_headers"
+    ],
     shared_libs: [
       "android.hardware.drm@1.0",
       "android.hardware.drm@1.1",
@@ -29,7 +32,6 @@
     static_libs: ["libgmock"],
     include_dirs: [
       "frameworks/av/drm/libmediadrm/include",
-      "frameworks/av/include/media",
     ],
     cflags: [
         // Suppress unused parameter and no error options. These cause problems
@@ -41,12 +43,14 @@
 cc_test {
     name: "EventMetric_test",
     srcs: ["EventMetric_test.cpp"],
+    header_libs: [
+        "libmedia_headers"
+    ],
     shared_libs: [
       "liblog",
       "libmediadrm",
       "libutils",
     ],
-    include_dirs: ["frameworks/av/include/media"],
     cflags: [
       "-Werror",
       "-Wall",
diff --git a/drm/libmediadrm/tests/CounterMetric_test.cpp b/drm/libmediadrm/tests/CounterMetric_test.cpp
index 6bca0da..c2becb4 100644
--- a/drm/libmediadrm/tests/CounterMetric_test.cpp
+++ b/drm/libmediadrm/tests/CounterMetric_test.cpp
@@ -16,7 +16,7 @@
 
 #include <gtest/gtest.h>
 
-#include "CounterMetric.h"
+#include <media/CounterMetric.h>
 
 namespace android {
 
diff --git a/drm/libmediadrm/tests/EventMetric_test.cpp b/drm/libmediadrm/tests/EventMetric_test.cpp
index eb6c4f6..b3c3f62 100644
--- a/drm/libmediadrm/tests/EventMetric_test.cpp
+++ b/drm/libmediadrm/tests/EventMetric_test.cpp
@@ -16,7 +16,7 @@
 
 #include <gtest/gtest.h>
 
-#include "EventMetric.h"
+#include <media/EventMetric.h>
 
 namespace android {
 
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
index bf35224..af7c367 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
@@ -97,7 +97,8 @@
 ///////////////////////////////////////////////////////////////////////////////
 ClearKeyCasPlugin::ClearKeyCasPlugin(
         void *appData, CasPluginCallback callback)
-    : mCallback(callback), mCallbackExt(NULL), mAppData(appData) {
+    : mCallback(callback), mCallbackExt(NULL), mStatusCallback(NULL),
+    mAppData(appData) {
     ALOGV("CTOR");
 }
 
@@ -112,6 +113,13 @@
     ClearKeySessionLibrary::get()->destroyPlugin(this);
 }
 
+status_t ClearKeyCasPlugin::setStatusCallback(
+    CasPluginStatusCallback callback) {
+    ALOGV("setStatusCallback");
+    mStatusCallback = callback;
+    return OK;
+}
+
 status_t ClearKeyCasPlugin::setPrivateData(const CasData &/*data*/) {
     ALOGV("setPrivateData");
 
@@ -135,6 +143,19 @@
     return ClearKeySessionLibrary::get()->addSession(this, sessionId);
 }
 
+status_t ClearKeyCasPlugin::openSession(uint32_t intent, uint32_t mode,
+    CasSessionId* sessionId) {
+    ALOGV("openSession with intent=%d, mode=%d", intent, mode);
+    // Echo the received information to the callback.
+    // Clear key plugin doesn't use any event, echo'ing for testing only.
+    if (mStatusCallback != NULL) {
+        mStatusCallback((void*)mAppData, intent, mode);
+    }
+
+    // Clear key plugin doesn't use intent and mode.
+    return ClearKeySessionLibrary::get()->addSession(this, sessionId);
+}
+
 status_t ClearKeyCasPlugin::closeSession(const CasSessionId &sessionId) {
     ALOGV("closeSession: sessionId=%s", sessionIdToString(sessionId).string());
     std::shared_ptr<ClearKeyCasSession> session =
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
index f48d5b1..c6938e6 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
@@ -71,11 +71,17 @@
     ClearKeyCasPlugin(void *appData, CasPluginCallbackExt callback);
     virtual ~ClearKeyCasPlugin();
 
+    virtual status_t setStatusCallback(
+            CasPluginStatusCallback callback) override;
+
     virtual status_t setPrivateData(
             const CasData &data) override;
 
     virtual status_t openSession(CasSessionId *sessionId) override;
 
+    virtual status_t openSession(uint32_t intent, uint32_t mode,
+                                     CasSessionId *sessionId) override;
+
     virtual status_t closeSession(
             const CasSessionId &sessionId) override;
 
@@ -105,6 +111,7 @@
     std::unique_ptr<KeyFetcher> mKeyFetcher;
     CasPluginCallback mCallback;
     CasPluginCallbackExt mCallbackExt;
+    CasPluginStatusCallback mStatusCallback;
     void* mAppData;
 };
 
diff --git a/drm/mediacas/plugins/mock/MockCasPlugin.cpp b/drm/mediacas/plugins/mock/MockCasPlugin.cpp
index 2964791..f8bab0a 100644
--- a/drm/mediacas/plugins/mock/MockCasPlugin.cpp
+++ b/drm/mediacas/plugins/mock/MockCasPlugin.cpp
@@ -111,6 +111,12 @@
     MockSessionLibrary::get()->destroyPlugin(this);
 }
 
+status_t MockCasPlugin::setStatusCallback(
+    CasPluginStatusCallback /*callback*/) {
+    ALOGV("setStatusCallback");
+    return OK;
+}
+
 status_t MockCasPlugin::setPrivateData(const CasData& /*data*/) {
     ALOGV("setPrivateData");
     return OK;
@@ -121,6 +127,13 @@
     return MockSessionLibrary::get()->addSession(this, sessionId);
 }
 
+status_t MockCasPlugin::openSession(uint32_t intent, uint32_t mode,
+    CasSessionId* sessionId) {
+    ALOGV("openSession with intent=%d, mode=%d", intent, mode);
+    // Clear key plugin doesn't use intent and mode.
+    return MockSessionLibrary::get()->addSession(this, sessionId);
+}
+
 status_t MockCasPlugin::closeSession(const CasSessionId &sessionId) {
     ALOGV("closeSession: sessionId=%s", arrayToString(sessionId).string());
     Mutex::Autolock lock(mLock);
diff --git a/drm/mediacas/plugins/mock/MockCasPlugin.h b/drm/mediacas/plugins/mock/MockCasPlugin.h
index 74b540c..660fd44 100644
--- a/drm/mediacas/plugins/mock/MockCasPlugin.h
+++ b/drm/mediacas/plugins/mock/MockCasPlugin.h
@@ -65,11 +65,17 @@
     MockCasPlugin();
     virtual ~MockCasPlugin();
 
+    virtual status_t setStatusCallback(
+            CasPluginStatusCallback callback) override;
+
     virtual status_t setPrivateData(
             const CasData &data) override;
 
     virtual status_t openSession(CasSessionId *sessionId) override;
 
+    virtual status_t openSession(uint32_t intent, uint32_t mode,
+                                     CasSessionId *sessionId) override;
+
     virtual status_t closeSession(
             const CasSessionId &sessionId) override;
 
diff --git a/drm/mediadrm/plugins/clearkey/default/InitDataParser.cpp b/drm/mediadrm/plugins/clearkey/default/InitDataParser.cpp
index caff393..121a4e2 100644
--- a/drm/mediadrm/plugins/clearkey/default/InitDataParser.cpp
+++ b/drm/mediadrm/plugins/clearkey/default/InitDataParser.cpp
@@ -76,10 +76,21 @@
 
 android::status_t InitDataParser::parsePssh(const Vector<uint8_t>& initData,
         Vector<const uint8_t*>* keyIds) {
+    // Description of PSSH format:
+    // https://w3c.github.io/encrypted-media/format-registry/initdata/cenc.html
     size_t readPosition = 0;
 
-    // Validate size field
     uint32_t expectedSize = initData.size();
+    const char psshIdentifier[4] = {'p', 's', 's', 'h'};
+    const uint8_t psshVersion1[4] = {1, 0, 0, 0};
+    uint32_t keyIdCount = 0;
+    size_t headerSize = sizeof(expectedSize) + sizeof(psshIdentifier) +
+                        sizeof(psshVersion1) + kSystemIdSize + sizeof(keyIdCount);
+    if (initData.size() < headerSize) {
+        return android::ERROR_DRM_CANNOT_HANDLE;
+    }
+
+    // Validate size field
     expectedSize = htonl(expectedSize);
     if (memcmp(&initData[readPosition], &expectedSize,
                sizeof(expectedSize)) != 0) {
@@ -88,7 +99,6 @@
     readPosition += sizeof(expectedSize);
 
     // Validate PSSH box identifier
-    const char psshIdentifier[4] = {'p', 's', 's', 'h'};
     if (memcmp(&initData[readPosition], psshIdentifier,
                sizeof(psshIdentifier)) != 0) {
         return android::ERROR_DRM_CANNOT_HANDLE;
@@ -96,7 +106,6 @@
     readPosition += sizeof(psshIdentifier);
 
     // Validate EME version number
-    const uint8_t psshVersion1[4] = {1, 0, 0, 0};
     if (memcmp(&initData[readPosition], psshVersion1,
                sizeof(psshVersion1)) != 0) {
         return android::ERROR_DRM_CANNOT_HANDLE;
@@ -110,12 +119,14 @@
     readPosition += kSystemIdSize;
 
     // Read key ID count
-    uint32_t keyIdCount;
     memcpy(&keyIdCount, &initData[readPosition], sizeof(keyIdCount));
     keyIdCount = ntohl(keyIdCount);
     readPosition += sizeof(keyIdCount);
-    if (readPosition + ((uint64_t)keyIdCount * kKeyIdSize) !=
-            initData.size() - sizeof(uint32_t)) {
+
+    uint64_t psshSize = 0;
+    if (__builtin_mul_overflow(keyIdCount, kKeyIdSize, &psshSize) ||
+        __builtin_add_overflow(readPosition, psshSize, &psshSize) ||
+        psshSize != initData.size() - sizeof(uint32_t) /* DataSize(0) */) {
         return android::ERROR_DRM_CANNOT_HANDLE;
     }
 
diff --git a/include/media/CounterMetric.h b/include/media/CounterMetric.h
deleted file mode 120000
index baba043..0000000
--- a/include/media/CounterMetric.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/CounterMetric.h
\ No newline at end of file
diff --git a/include/media/EventMetric.h b/include/media/EventMetric.h
deleted file mode 120000
index 5707d9a..0000000
--- a/include/media/EventMetric.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/EventMetric.h
\ No newline at end of file
diff --git a/include/media/IDataSource.h b/include/media/IDataSource.h
deleted file mode 120000
index 41cdd8b..0000000
--- a/include/media/IDataSource.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IDataSource.h
\ No newline at end of file
diff --git a/include/media/IMediaLogService.h b/include/media/IMediaLogService.h
deleted file mode 120000
index 245a29d..0000000
--- a/include/media/IMediaLogService.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IMediaLogService.h
\ No newline at end of file
diff --git a/include/media/IMediaPlayerClient.h b/include/media/IMediaPlayerClient.h
deleted file mode 120000
index b6547ce..0000000
--- a/include/media/IMediaPlayerClient.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IMediaPlayerClient.h
\ No newline at end of file
diff --git a/include/media/IMediaRecorderClient.h b/include/media/IMediaRecorderClient.h
deleted file mode 120000
index 89f4359..0000000
--- a/include/media/IMediaRecorderClient.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/IMediaRecorderClient.h
\ No newline at end of file
diff --git a/include/media/MemoryLeakTrackUtil.h b/include/media/MemoryLeakTrackUtil.h
deleted file mode 120000
index 504173e..0000000
--- a/include/media/MemoryLeakTrackUtil.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/MemoryLeakTrackUtil.h
\ No newline at end of file
diff --git a/include/media/Metadata.h b/include/media/Metadata.h
deleted file mode 120000
index e421168..0000000
--- a/include/media/Metadata.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/Metadata.h
\ No newline at end of file
diff --git a/include/media/MidiIoWrapper.h b/include/media/MidiIoWrapper.h
deleted file mode 120000
index 786ec3d..0000000
--- a/include/media/MidiIoWrapper.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/MidiIoWrapper.h
\ No newline at end of file
diff --git a/include/media/Modulo.h b/include/media/Modulo.h
deleted file mode 120000
index 989c4cb..0000000
--- a/include/media/Modulo.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/Modulo.h
\ No newline at end of file
diff --git a/include/media/PluginMetricsReporting.h b/include/media/PluginMetricsReporting.h
deleted file mode 120000
index 7d9a7a0..0000000
--- a/include/media/PluginMetricsReporting.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/PluginMetricsReporting.h
\ No newline at end of file
diff --git a/include/media/RingBuffer.h b/include/media/RingBuffer.h
deleted file mode 120000
index 9af28d5..0000000
--- a/include/media/RingBuffer.h
+++ /dev/null
@@ -1 +0,0 @@
-../../media/libmedia/include/media/RingBuffer.h
\ No newline at end of file
diff --git a/media/codec2/components/aac/C2SoftAacEnc.cpp b/media/codec2/components/aac/C2SoftAacEnc.cpp
index a8f39d5..be52a1d 100644
--- a/media/codec2/components/aac/C2SoftAacEnc.cpp
+++ b/media/codec2/components/aac/C2SoftAacEnc.cpp
@@ -521,16 +521,14 @@
                 mInputSize += outargs.numInSamples * sizeof(int16_t);
             }
 
-            if (outargs.numInSamples > 0) {
-                inBuffer[0] = (int16_t *)inBuffer[0] + outargs.numInSamples;
-                inBufferSize[0] -= outargs.numInSamples * sizeof(int16_t);
-                inargs.numInSamples -= outargs.numInSamples;
-            }
-
             if (inBuffer[0] == mRemainder) {
                 inBuffer[0] = const_cast<uint8_t *>(data);
                 inBufferSize[0] = capacity;
                 inargs.numInSamples = capacity / sizeof(int16_t);
+            } else if (outargs.numInSamples > 0) {
+                inBuffer[0] = (int16_t *)inBuffer[0] + outargs.numInSamples;
+                inBufferSize[0] -= outargs.numInSamples * sizeof(int16_t);
+                inargs.numInSamples -= outargs.numInSamples;
             }
         }
         ALOGV("encoderErr = %d mInputSize = %zu "
diff --git a/media/codec2/hidl/client/client.cpp b/media/codec2/hidl/client/client.cpp
index c620bad..c747190 100644
--- a/media/codec2/hidl/client/client.cpp
+++ b/media/codec2/hidl/client/client.cpp
@@ -125,6 +125,9 @@
         if (!mClient) {
             mClient = Codec2Client::_CreateFromIndex(mIndex);
         }
+        CHECK(mClient) << "Failed to create Codec2Client to service \""
+                       << GetServiceNames()[mIndex] << "\". (Index = "
+                       << mIndex << ").";
         return mClient;
     }
 
@@ -832,6 +835,7 @@
 
 c2_status_t Codec2Client::ForAllServices(
         const std::string &key,
+        size_t numberOfAttempts,
         std::function<c2_status_t(const std::shared_ptr<Codec2Client>&)>
             predicate) {
     c2_status_t status = C2_NO_INIT;  // no IComponentStores present
@@ -860,23 +864,31 @@
 
     for (size_t index : indices) {
         Cache& cache = Cache::List()[index];
-        std::shared_ptr<Codec2Client> client{cache.getClient()};
-        if (client) {
+        for (size_t tries = numberOfAttempts; tries > 0; --tries) {
+            std::shared_ptr<Codec2Client> client{cache.getClient()};
             status = predicate(client);
             if (status == C2_OK) {
                 std::scoped_lock lock{key2IndexMutex};
                 key2Index[key] = index; // update last known client index
                 return C2_OK;
+            } else if (status == C2_TRANSACTION_FAILED) {
+                LOG(WARNING) << "\"" << key << "\" failed for service \""
+                             << client->getName()
+                             << "\" due to transaction failure. "
+                             << "(Service may have crashed.)"
+                             << (tries > 1 ? " Retrying..." : "");
+                cache.invalidate();
+                continue;
             }
-        }
-        if (wasMapped) {
-            LOG(INFO) << "Could not find \"" << key << "\""
-                         " in the last instance. Retrying...";
-            wasMapped = false;
-            cache.invalidate();
+            if (wasMapped) {
+                LOG(INFO) << "\"" << key << "\" became invalid in service \""
+                          << client->getName() << "\". Retrying...";
+                wasMapped = false;
+            }
+            break;
         }
     }
-    return status;  // return the last status from a valid client
+    return status; // return the last status from a valid client
 }
 
 std::shared_ptr<Codec2Client::Component>
@@ -885,35 +897,37 @@
         const std::shared_ptr<Listener>& listener,
         std::shared_ptr<Codec2Client>* owner,
         size_t numberOfAttempts) {
-    while (true) {
-        std::shared_ptr<Component> component;
-        c2_status_t status = ForAllServices(
-                componentName,
-                [owner, &component, componentName, &listener](
-                        const std::shared_ptr<Codec2Client> &client)
-                            -> c2_status_t {
-                    c2_status_t status = client->createComponent(componentName,
-                                                                 listener,
-                                                                 &component);
-                    if (status == C2_OK) {
-                        if (owner) {
-                            *owner = client;
-                        }
-                    } else if (status != C2_NOT_FOUND) {
-                        LOG(DEBUG) << "IComponentStore("
-                                       << client->getServiceName()
-                                   << ")::createComponent(\"" << componentName
-                                   << "\") returned status = "
-                                   << status << ".";
+    std::string key{"create:"};
+    key.append(componentName);
+    std::shared_ptr<Component> component;
+    c2_status_t status = ForAllServices(
+            key,
+            numberOfAttempts,
+            [owner, &component, componentName, &listener](
+                    const std::shared_ptr<Codec2Client> &client)
+                        -> c2_status_t {
+                c2_status_t status = client->createComponent(componentName,
+                                                             listener,
+                                                             &component);
+                if (status == C2_OK) {
+                    if (owner) {
+                        *owner = client;
                     }
-                    return status;
-                });
-        if (numberOfAttempts > 0 && status == C2_TRANSACTION_FAILED) {
-            --numberOfAttempts;
-            continue;
-        }
-        return component;
+                } else if (status != C2_NOT_FOUND) {
+                    LOG(DEBUG) << "IComponentStore("
+                                   << client->getServiceName()
+                               << ")::createComponent(\"" << componentName
+                               << "\") returned status = "
+                               << status << ".";
+                }
+                return status;
+            });
+    if (status != C2_OK) {
+        LOG(DEBUG) << "Failed to create component \"" << componentName
+                   << "\" from all known services. "
+                      "Last returned status = " << status << ".";
     }
+    return component;
 }
 
 std::shared_ptr<Codec2Client::Interface>
@@ -921,34 +935,36 @@
         const char* interfaceName,
         std::shared_ptr<Codec2Client>* owner,
         size_t numberOfAttempts) {
-    while (true) {
-        std::shared_ptr<Interface> interface;
-        c2_status_t status = ForAllServices(
-                interfaceName,
-                [owner, &interface, interfaceName](
-                        const std::shared_ptr<Codec2Client> &client)
-                            -> c2_status_t {
-                    c2_status_t status = client->createInterface(interfaceName,
-                                                                 &interface);
-                    if (status == C2_OK) {
-                        if (owner) {
-                            *owner = client;
-                        }
-                    } else if (status != C2_NOT_FOUND) {
-                        LOG(DEBUG) << "IComponentStore("
-                                       << client->getServiceName()
-                                   << ")::createInterface(\"" << interfaceName
-                                   << "\") returned status = "
-                                   << status << ".";
+    std::string key{"create:"};
+    key.append(interfaceName);
+    std::shared_ptr<Interface> interface;
+    c2_status_t status = ForAllServices(
+            key,
+            numberOfAttempts,
+            [owner, &interface, interfaceName](
+                    const std::shared_ptr<Codec2Client> &client)
+                        -> c2_status_t {
+                c2_status_t status = client->createInterface(interfaceName,
+                                                             &interface);
+                if (status == C2_OK) {
+                    if (owner) {
+                        *owner = client;
                     }
-                    return status;
-                });
-        if (numberOfAttempts > 0 && status == C2_TRANSACTION_FAILED) {
-            --numberOfAttempts;
-            continue;
-        }
-        return interface;
+                } else if (status != C2_NOT_FOUND) {
+                    LOG(DEBUG) << "IComponentStore("
+                                   << client->getServiceName()
+                               << ")::createInterface(\"" << interfaceName
+                               << "\") returned status = "
+                               << status << ".";
+                }
+                return status;
+            });
+    if (status != C2_OK) {
+        LOG(DEBUG) << "Failed to create interface \"" << interfaceName
+                   << "\" from all known services. "
+                      "Last returned status = " << status << ".";
     }
+    return interface;
 }
 
 std::vector<C2Component::Traits> const& Codec2Client::ListComponents() {
diff --git a/media/codec2/hidl/client/include/codec2/hidl/client.h b/media/codec2/hidl/client/include/codec2/hidl/client.h
index 848901d..c37407f 100644
--- a/media/codec2/hidl/client/include/codec2/hidl/client.h
+++ b/media/codec2/hidl/client/include/codec2/hidl/client.h
@@ -208,11 +208,25 @@
 protected:
     sp<Base> mBase;
 
-    // Finds the first store where the predicate returns OK, and returns the last
-    // predicate result. Uses key to remember the last store found, and if cached,
-    // it tries that store before trying all stores (one retry).
+    // Finds the first store where the predicate returns C2_OK and returns the
+    // last predicate result. The predicate will be tried on all stores. The
+    // function will return C2_OK the first time the predicate returns C2_OK,
+    // or it will return the value from the last time that predicate is tried.
+    // (The latter case corresponds to a failure on every store.) The order of
+    // the stores to try is the same as the return value of GetServiceNames().
+    //
+    // key is used to remember the last store with which the predicate last
+    // succeeded. If the last successful store is cached, it will be tried
+    // first before all the stores are tried. Note that the last successful
+    // store will be tried twice---first before all the stores, and another time
+    // with all the stores.
+    //
+    // If an attempt to evaluate the predicate results in a transaction failure,
+    // repeated attempts will be made until the predicate returns without a
+    // transaction failure or numberOfAttempts attempts have been made.
     static c2_status_t ForAllServices(
             const std::string& key,
+            size_t numberOfAttempts,
             std::function<c2_status_t(std::shared_ptr<Codec2Client> const&)>
                 predicate);
 
diff --git a/media/codec2/sfplugin/Android.bp b/media/codec2/sfplugin/Android.bp
index 11c1ba0..e174751 100644
--- a/media/codec2/sfplugin/Android.bp
+++ b/media/codec2/sfplugin/Android.bp
@@ -9,7 +9,6 @@
         "CCodecConfig.cpp",
         "Codec2Buffer.cpp",
         "Codec2InfoBuilder.cpp",
-        "Omx2IGraphicBufferSource.cpp",
         "PipelineWatcher.cpp",
         "ReflectedParamUpdater.cpp",
         "SkipCutBuffer.cpp",
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 4a31953..1cbbbb8 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -26,7 +26,6 @@
 #include <C2ParamInternal.h>
 #include <C2PlatformSupport.h>
 
-#include <android/IGraphicBufferSource.h>
 #include <android/IOMXBufferSource.h>
 #include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
 #include <android/hardware/media/omx/1.0/IOmx.h>
@@ -35,8 +34,11 @@
 #include <gui/IGraphicBufferProducer.h>
 #include <gui/Surface.h>
 #include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
-#include <media/omx/1.0/WGraphicBufferSource.h>
+#include <media/omx/1.0/WOmxNode.h>
+#include <media/openmax/OMX_Core.h>
 #include <media/openmax/OMX_IndexExt.h>
+#include <media/stagefright/omx/1.0/WGraphicBufferSource.h>
+#include <media/stagefright/omx/OmxGraphicBufferSource.h>
 #include <media/stagefright/BufferProducerWrapper.h>
 #include <media/stagefright/MediaCodecConstants.h>
 #include <media/stagefright/PersistentSurface.h>
@@ -45,7 +47,6 @@
 #include "CCodec.h"
 #include "CCodecBufferChannel.h"
 #include "InputSurfaceWrapper.h"
-#include "Omx2IGraphicBufferSource.h"
 
 extern "C" android::PersistentSurface *CreateInputSurface();
 
@@ -54,9 +55,10 @@
 using namespace std::chrono_literals;
 using ::android::hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
 using android::base::StringPrintf;
-using BGraphicBufferSource = ::android::IGraphicBufferSource;
 using ::android::hardware::media::c2::V1_0::IInputSurface;
 
+typedef hardware::media::omx::V1_0::IGraphicBufferSource HGraphicBufferSource;
+
 namespace {
 
 class CCodecWatchdog : public AHandler {
@@ -180,9 +182,10 @@
 
 class GraphicBufferSourceWrapper : public InputSurfaceWrapper {
 public:
-//    explicit GraphicBufferSourceWrapper(const sp<BGraphicBufferSource> &source) : mSource(source) {}
+    typedef hardware::media::omx::V1_0::Status OmxStatus;
+
     GraphicBufferSourceWrapper(
-            const sp<BGraphicBufferSource> &source,
+            const sp<HGraphicBufferSource> &source,
             uint32_t width,
             uint32_t height,
             uint64_t usage)
@@ -194,6 +197,7 @@
 
     status_t connect(const std::shared_ptr<Codec2Client::Component> &comp) override {
         mNode = new C2OMXNode(comp);
+        mOmxNode = new hardware::media::omx::V1_0::utils::TWOmxNode(mNode);
         mNode->setFrameSize(mWidth, mHeight);
 
         // Usage is queried during configure(), so setting it beforehand.
@@ -204,7 +208,8 @@
 
         // NOTE: we do not use/pass through color aspects from GraphicBufferSource as we
         // communicate that directly to the component.
-        mSource->configure(mNode, mDataSpace);
+        mSource->configure(
+                mOmxNode, static_cast<hardware::graphics::common::V1_0::Dataspace>(mDataSpace));
         return OK;
     }
 
@@ -220,21 +225,16 @@
         source->onOmxIdle();
         source->onOmxLoaded();
         mNode.clear();
+        mOmxNode.clear();
     }
 
-    status_t GetStatus(const binder::Status &status) {
-        status_t err = OK;
-        if (!status.isOk()) {
-            err = status.serviceSpecificErrorCode();
-            if (err == OK) {
-                err = status.transactionError();
-                if (err == OK) {
-                    // binder status failed, but there is no servie or transaction error
-                    err = UNKNOWN_ERROR;
-                }
-            }
+    status_t GetStatus(hardware::Return<OmxStatus> &&status) {
+        if (status.isOk()) {
+            return static_cast<status_t>(status.withDefault(OmxStatus::UNKNOWN_ERROR));
+        } else if (status.isDeadObject()) {
+            return DEAD_OBJECT;
         }
-        return err;
+        return UNKNOWN_ERROR;
     }
 
     status_t start() override {
@@ -359,7 +359,15 @@
                 err = res;
             } else {
                 status << " delayUs";
-                res = GetStatus(mSource->getStopTimeOffsetUs(&config.mInputDelayUs));
+                hardware::Return<void> trans = mSource->getStopTimeOffsetUs(
+                        [&res, &delayUs = config.mInputDelayUs](
+                                auto status, auto stopTimeOffsetUs) {
+                            res = static_cast<status_t>(status);
+                            delayUs = stopTimeOffsetUs;
+                        });
+                if (!trans.isOk()) {
+                    res = trans.isDeadObject() ? DEAD_OBJECT : UNKNOWN_ERROR;
+                }
                 if (res != OK) {
                     status << " (=> " << asString(res) << ")";
                 } else {
@@ -388,8 +396,9 @@
     }
 
 private:
-    sp<BGraphicBufferSource> mSource;
+    sp<HGraphicBufferSource> mSource;
     sp<C2OMXNode> mNode;
+    sp<hardware::media::omx::V1_0::IOmxNode> mOmxNode;
     uint32_t mWidth;
     uint32_t mHeight;
     Config mConfig;
@@ -1092,9 +1101,7 @@
                 gbs = source;
             });
     if (transStatus.isOk() && s == OmxStatus::OK) {
-        return new PersistentSurface(
-                new H2BGraphicBufferProducer(gbp),
-                sp<::android::IGraphicBufferSource>(new LWGraphicBufferSource(gbs)));
+        return new PersistentSurface(new H2BGraphicBufferProducer(gbp), gbs);
     }
 
     return nullptr;
@@ -1125,28 +1132,28 @@
     }
 
     sp<PersistentSurface> persistentSurface = CreateCompatibleInputSurface();
+    sp<hidl::base::V1_0::IBase> hidlTarget = persistentSurface->getHidlTarget();
+    sp<IInputSurface> hidlInputSurface = IInputSurface::castFrom(hidlTarget);
+    sp<HGraphicBufferSource> gbs = HGraphicBufferSource::castFrom(hidlTarget);
 
-    if (persistentSurface->getHidlTarget()) {
-        sp<IInputSurface> hidlInputSurface = IInputSurface::castFrom(
-                persistentSurface->getHidlTarget());
-        if (!hidlInputSurface) {
-            ALOGE("Corrupted input surface");
-            mCallback->onInputSurfaceCreationFailed(UNKNOWN_ERROR);
-            return;
-        }
+    if (hidlInputSurface) {
         std::shared_ptr<Codec2Client::InputSurface> inputSurface =
                 std::make_shared<Codec2Client::InputSurface>(hidlInputSurface);
         err = setupInputSurface(std::make_shared<C2InputSurfaceWrapper>(
                 inputSurface));
         bufferProducer = inputSurface->getGraphicBufferProducer();
-    } else {
+    } else if (gbs) {
         int32_t width = 0;
         (void)outputFormat->findInt32("width", &width);
         int32_t height = 0;
         (void)outputFormat->findInt32("height", &height);
         err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>(
-                persistentSurface->getBufferSource(), width, height, usage));
+                gbs, width, height, usage));
         bufferProducer = persistentSurface->getBufferProducer();
+    } else {
+        ALOGE("Corrupted input surface");
+        mCallback->onInputSurfaceCreationFailed(UNKNOWN_ERROR);
+        return;
     }
 
     if (err != OK) {
@@ -1212,15 +1219,10 @@
         outputFormat = config->mOutputFormat;
         usage = config->mISConfig ? config->mISConfig->mUsage : 0;
     }
-    auto hidlTarget = surface->getHidlTarget();
-    if (hidlTarget) {
-        sp<IInputSurface> inputSurface =
-                IInputSurface::castFrom(hidlTarget);
-        if (!inputSurface) {
-            ALOGE("Failed to set input surface: Corrupted surface.");
-            mCallback->onInputSurfaceDeclined(UNKNOWN_ERROR);
-            return;
-        }
+    sp<hidl::base::V1_0::IBase> hidlTarget = surface->getHidlTarget();
+    sp<IInputSurface> inputSurface = IInputSurface::castFrom(hidlTarget);
+    sp<HGraphicBufferSource> gbs = HGraphicBufferSource::castFrom(hidlTarget);
+    if (inputSurface) {
         status_t err = setupInputSurface(std::make_shared<C2InputSurfaceWrapper>(
                 std::make_shared<Codec2Client::InputSurface>(inputSurface)));
         if (err != OK) {
@@ -1228,18 +1230,22 @@
             mCallback->onInputSurfaceDeclined(err);
             return;
         }
-    } else {
+    } else if (gbs) {
         int32_t width = 0;
         (void)outputFormat->findInt32("width", &width);
         int32_t height = 0;
         (void)outputFormat->findInt32("height", &height);
         status_t err = setupInputSurface(std::make_shared<GraphicBufferSourceWrapper>(
-                surface->getBufferSource(), width, height, usage));
+                gbs, width, height, usage));
         if (err != OK) {
             ALOGE("Failed to set up input surface: %d", err);
             mCallback->onInputSurfaceDeclined(err);
             return;
         }
+    } else {
+        ALOGE("Failed to set input surface: Corrupted surface.");
+        mCallback->onInputSurfaceDeclined(UNKNOWN_ERROR);
+        return;
     }
     mCallback->onInputSurfaceAccepted(inputFormat, outputFormat);
 }
@@ -1867,6 +1873,7 @@
 // Create Codec 2.0 input surface
 extern "C" android::PersistentSurface *CreateInputSurface() {
     using namespace android;
+    using ::android::hardware::media::omx::V1_0::implementation::TWGraphicBufferSource;
     // Attempt to create a Codec2's input surface.
     std::shared_ptr<Codec2Client::InputSurface> inputSurface =
             Codec2Client::CreateInputSurface();
@@ -1880,9 +1887,7 @@
                 return nullptr;
             }
             return new PersistentSurface(
-                    gbs->getIGraphicBufferProducer(),
-                    sp<IGraphicBufferSource>(
-                        new Omx2IGraphicBufferSource(gbs)));
+                    gbs->getIGraphicBufferProducer(), new TWGraphicBufferSource(gbs));
         } else {
             return nullptr;
         }
diff --git a/media/extractors/midi/Android.bp b/media/extractors/midi/Android.bp
index 7d42e70..d36cb49 100644
--- a/media/extractors/midi/Android.bp
+++ b/media/extractors/midi/Android.bp
@@ -6,6 +6,10 @@
         "frameworks/av/media/libstagefright/include",
     ],
 
+    header_libs: [
+        "libmedia_headers",
+    ],
+
     shared_libs: [
         "liblog",
         "libmediandk",
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index ee5d089..b707d78 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -700,7 +700,7 @@
  * Added in API level 29.
  *
  * @param builder reference provided by AAudio_createStreamBuilder()
- * @param inputPreset the desired level of opt-out from being captured.
+ * @param capturePolicy the desired level of opt-out from being captured.
  */
 AAUDIO_API void AAudioStreamBuilder_setAllowedCapturePolicy(AAudioStreamBuilder* builder,
         aaudio_allowed_capture_policy_t capturePolicy) __INTRODUCED_IN(29);
diff --git a/media/libaaudio/src/Android.bp b/media/libaaudio/src/Android.bp
index 56c0170..850b1d0 100644
--- a/media/libaaudio/src/Android.bp
+++ b/media/libaaudio/src/Android.bp
@@ -10,7 +10,9 @@
         "legacy",
         "utility",
     ],
-    header_libs: ["libaaudio_headers"],
+    header_libs: [
+        "libaaudio_headers",
+    ],
     export_header_lib_headers: ["libaaudio_headers"],
     version_script: "libaaudio.map.txt",
 
@@ -53,7 +55,10 @@
     ],
 
     export_include_dirs: ["."],
-    header_libs: ["libaaudio_headers"],
+    header_libs: [
+        "libaaudio_headers",
+        "libmedia_headers"
+    ],
     export_header_lib_headers: ["libaaudio_headers"],
 
     shared_libs: [
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 6614e5e..7481daa 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -250,6 +250,8 @@
         mTimeOffsetNanos = offsetMicros * AAUDIO_NANOS_PER_MICROSECOND;
     }
 
+    setBufferSize(capacity / 2); // Default buffer size to match Q
+
     setState(AAUDIO_STREAM_STATE_OPEN);
 
     return result;
@@ -739,6 +741,7 @@
     adjustedFrames = std::min(actualFrames, adjustedFrames);
 
     mBufferSizeInFrames = adjustedFrames;
+    ALOGV("%s(%d) returns %d", __func__, requestedFrames, adjustedFrames);
     return (aaudio_result_t) adjustedFrames;
 }
 
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 2752ba6..ad79e9c 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -93,6 +93,7 @@
     header_libs: [
         "libaudioclient_headers",
         "libbase_headers",
+        "libmedia_headers",
     ],
     export_header_lib_headers: ["libaudioclient_headers"],
 
diff --git a/media/libaudioclient/tests/Android.bp b/media/libaudioclient/tests/Android.bp
index 52bb2fb..d509be6 100644
--- a/media/libaudioclient/tests/Android.bp
+++ b/media/libaudioclient/tests/Android.bp
@@ -11,6 +11,9 @@
     defaults: ["libaudioclient_tests_defaults"],
     srcs: ["test_create_audiotrack.cpp",
            "test_create_utils.cpp"],
+    header_libs: [
+        "libmedia_headers",
+    ],
     shared_libs: [
         "libaudioclient",
         "libbinder",
@@ -25,6 +28,9 @@
     defaults: ["libaudioclient_tests_defaults"],
     srcs: ["test_create_audiorecord.cpp",
            "test_create_utils.cpp"],
+    header_libs: [
+        "libmedia_headers",
+    ],
     shared_libs: [
         "libaudioclient",
         "libbinder",
diff --git a/media/libaudioprocessing/Android.bp b/media/libaudioprocessing/Android.bp
index e8aa700..9b5d58c 100644
--- a/media/libaudioprocessing/Android.bp
+++ b/media/libaudioprocessing/Android.bp
@@ -33,6 +33,7 @@
 
     header_libs: [
         "libbase_headers",
+        "libmedia_headers"
     ],
 
     shared_libs: [
diff --git a/media/libaudioprocessing/tests/Android.bp b/media/libaudioprocessing/tests/Android.bp
index f4e497b..20c2c2c 100644
--- a/media/libaudioprocessing/tests/Android.bp
+++ b/media/libaudioprocessing/tests/Android.bp
@@ -3,7 +3,11 @@
 cc_defaults {
     name: "libaudioprocessing_test_defaults",
 
-    header_libs: ["libbase_headers"],
+    header_libs: [
+        "libbase_headers",
+        "libmedia_headers",
+    ],
+
     shared_libs: [
         "libaudioclient",
         "libaudioprocessing",
diff --git a/media/libaudioprocessing/tests/fuzzer/Android.bp b/media/libaudioprocessing/tests/fuzzer/Android.bp
new file mode 100644
index 0000000..1df47b7
--- /dev/null
+++ b/media/libaudioprocessing/tests/fuzzer/Android.bp
@@ -0,0 +1,10 @@
+cc_fuzz {
+  name: "libaudioprocessing_resampler_fuzzer",
+  srcs: [
+    "libaudioprocessing_resampler_fuzzer.cpp",
+  ],
+  defaults: ["libaudioprocessing_test_defaults"],
+  static_libs: [
+    "libsndfile",
+  ],
+}
diff --git a/media/libaudioprocessing/tests/fuzzer/libaudioprocessing_resampler_fuzzer.cpp b/media/libaudioprocessing/tests/fuzzer/libaudioprocessing_resampler_fuzzer.cpp
new file mode 100644
index 0000000..938c610
--- /dev/null
+++ b/media/libaudioprocessing/tests/fuzzer/libaudioprocessing_resampler_fuzzer.cpp
@@ -0,0 +1,188 @@
+/*
+ * 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 <android-base/macros.h>
+#include <audio_utils/primitives.h>
+#include <audio_utils/sndfile.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <math.h>
+#include <media/AudioBufferProvider.h>
+#include <media/AudioResampler.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
+#include <utils/Vector.h>
+
+#include <memory>
+
+using namespace android;
+
+const int MAX_FRAMES = 10;
+const int MIN_FREQ = 1e3;
+const int MAX_FREQ = 100e3;
+
+const AudioResampler::src_quality qualities[] = {
+    AudioResampler::DEFAULT_QUALITY,
+    AudioResampler::LOW_QUALITY,
+    AudioResampler::MED_QUALITY,
+    AudioResampler::HIGH_QUALITY,
+    AudioResampler::VERY_HIGH_QUALITY,
+    AudioResampler::DYN_LOW_QUALITY,
+    AudioResampler::DYN_MED_QUALITY,
+    AudioResampler::DYN_HIGH_QUALITY,
+};
+
+class Provider : public AudioBufferProvider {
+  const void* mAddr;        // base address
+  const size_t mNumFrames;  // total frames
+  const size_t mFrameSize;  // size of each frame in bytes
+  size_t mNextFrame;        // index of next frame to provide
+  size_t mUnrel;            // number of frames not yet released
+ public:
+  Provider(const void* addr, size_t frames, size_t frameSize)
+      : mAddr(addr),
+        mNumFrames(frames),
+        mFrameSize(frameSize),
+        mNextFrame(0),
+        mUnrel(0) {}
+  status_t getNextBuffer(Buffer* buffer) override {
+    if (buffer->frameCount > mNumFrames - mNextFrame) {
+      buffer->frameCount = mNumFrames - mNextFrame;
+    }
+    mUnrel = buffer->frameCount;
+    if (buffer->frameCount > 0) {
+      buffer->raw = (char*)mAddr + mFrameSize * mNextFrame;
+      return NO_ERROR;
+    } else {
+      buffer->raw = nullptr;
+      return NOT_ENOUGH_DATA;
+    }
+  }
+  virtual void releaseBuffer(Buffer* buffer) {
+    if (buffer->frameCount > mUnrel) {
+      mNextFrame += mUnrel;
+      mUnrel = 0;
+    } else {
+      mNextFrame += buffer->frameCount;
+      mUnrel -= buffer->frameCount;
+    }
+    buffer->frameCount = 0;
+    buffer->raw = nullptr;
+  }
+  void reset() { mNextFrame = 0; }
+};
+
+audio_format_t chooseFormat(AudioResampler::src_quality quality,
+                            uint8_t input_byte) {
+  switch (quality) {
+    case AudioResampler::DYN_LOW_QUALITY:
+    case AudioResampler::DYN_MED_QUALITY:
+    case AudioResampler::DYN_HIGH_QUALITY:
+      if (input_byte % 2) {
+        return AUDIO_FORMAT_PCM_FLOAT;
+      }
+      FALLTHROUGH_INTENDED;
+    default:
+      return AUDIO_FORMAT_PCM_16_BIT;
+  }
+}
+
+int parseValue(const uint8_t* src, int index, void* dst, size_t size) {
+  memcpy(dst, &src[index], size);
+  return size;
+}
+
+bool validFreq(int freq) { return freq > MIN_FREQ && freq < MAX_FREQ; }
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  int input_freq = 0;
+  int output_freq = 0;
+  int input_channels = 0;
+
+  float left_volume = 0;
+  float right_volume = 0;
+
+  size_t metadata_size = 2 + 3 * sizeof(int) + 2 * sizeof(float);
+  if (size < metadata_size) {
+    // not enough data to set options
+    return 0;
+  }
+
+  AudioResampler::src_quality quality = qualities[data[0] % 8];
+  audio_format_t format = chooseFormat(quality, data[1]);
+
+  int index = 2;
+
+  index += parseValue(data, index, &input_freq, sizeof(int));
+  index += parseValue(data, index, &output_freq, sizeof(int));
+  index += parseValue(data, index, &input_channels, sizeof(int));
+
+  index += parseValue(data, index, &left_volume, sizeof(float));
+  index += parseValue(data, index, &right_volume, sizeof(float));
+
+  if (!validFreq(input_freq) || !validFreq(output_freq)) {
+    // sampling frequencies must be reasonable
+    return 0;
+  }
+
+  if (input_channels < 1 ||
+      input_channels > (quality < AudioResampler::DYN_LOW_QUALITY ? 2 : 8)) {
+    // invalid number of input channels
+    return 0;
+  }
+
+  size_t single_channel_size =
+      format == AUDIO_FORMAT_PCM_FLOAT ? sizeof(float) : sizeof(int16_t);
+  size_t input_frame_size = single_channel_size * input_channels;
+  size_t input_size = size - metadata_size;
+  uint8_t input_data[input_size];
+  memcpy(input_data, &data[metadata_size], input_size);
+
+  size_t input_frames = input_size / input_frame_size;
+  if (input_frames > MAX_FRAMES) {
+    return 0;
+  }
+
+  Provider provider(input_data, input_frames, input_frame_size);
+
+  std::unique_ptr<AudioResampler> resampler(
+      AudioResampler::create(format, input_channels, output_freq, quality));
+
+  resampler->setSampleRate(input_freq);
+  resampler->setVolume(left_volume, right_volume);
+
+  // output is at least stereo samples
+  int output_channels = input_channels > 2 ? input_channels : 2;
+  size_t output_frame_size = output_channels * sizeof(int32_t);
+  size_t output_frames = (input_frames * output_freq) / input_freq;
+  size_t output_size = output_frames * output_frame_size;
+
+  uint8_t output_data[output_size];
+  for (size_t i = 0; i < output_frames; i++) {
+    memset(output_data, 0, output_size);
+    resampler->resample((int*)output_data, i, &provider);
+  }
+
+  return 0;
+}
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index d70c6d4..8e96e8c 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -18,7 +18,6 @@
 filegroup {
     name: "libmedia_omx_aidl",
     srcs: [
-        "aidl/android/IGraphicBufferSource.aidl",
         "aidl/android/IOMXBufferSource.aidl",
     ],
     path: "aidl",
@@ -53,7 +52,6 @@
         "IOMX.cpp",
         "MediaCodecBuffer.cpp",
         "OMXBuffer.cpp",
-        "omx/1.0/WGraphicBufferSource.cpp",
         "omx/1.0/WOmxBufferSource.cpp",
         "omx/1.0/WOmxNode.cpp",
         "omx/1.0/WOmxObserver.cpp",
@@ -186,6 +184,7 @@
     ],
 
     header_libs: [
+        "libmedia_headers",
         "media_ndk_headers",
     ],
 
@@ -279,7 +278,6 @@
         "MediaProfiles.cpp",
         "MediaResource.cpp",
         "MediaResourcePolicy.cpp",
-        "Visualizer.cpp",
         "StringArray.cpp",
         "NdkMediaFormatPriv.cpp",
         "NdkMediaErrorPriv.cpp",
@@ -315,7 +313,6 @@
         "libstagefright_foundation",
         "libgui",
         "libdl",
-        "libaudioutils",
         "libaudioclient",
         "libmedia_codeclist",
         "libmedia_omx",
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index bc0c2cd..959a3d7 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -29,7 +29,6 @@
 #include <utils/NativeHandle.h>
 
 #include <media/omx/1.0/WOmxNode.h>
-#include <android/IGraphicBufferSource.h>
 #include <android/IOMXBufferSource.h>
 
 namespace android {
diff --git a/media/libmedia/Visualizer.cpp b/media/libmedia/Visualizer.cpp
deleted file mode 100644
index 2bf0802..0000000
--- a/media/libmedia/Visualizer.cpp
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
-**
-** Copyright 2010, 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 "Visualizer"
-#include <utils/Log.h>
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <limits.h>
-
-#include <media/Visualizer.h>
-#include <audio_utils/fixedfft.h>
-#include <utils/Thread.h>
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-Visualizer::Visualizer (const String16& opPackageName,
-         int32_t priority,
-         effect_callback_t cbf,
-         void* user,
-         audio_session_t sessionId)
-    :   AudioEffect(SL_IID_VISUALIZATION, opPackageName, NULL, priority, cbf, user, sessionId),
-        mCaptureRate(CAPTURE_RATE_DEF),
-        mCaptureSize(CAPTURE_SIZE_DEF),
-        mSampleRate(44100000),
-        mScalingMode(VISUALIZER_SCALING_MODE_NORMALIZED),
-        mMeasurementMode(MEASUREMENT_MODE_NONE),
-        mCaptureCallBack(NULL),
-        mCaptureCbkUser(NULL)
-{
-    initCaptureSize();
-}
-
-Visualizer::~Visualizer()
-{
-    ALOGV("Visualizer::~Visualizer()");
-    setEnabled(false);
-    setCaptureCallBack(NULL, NULL, 0, 0);
-}
-
-void Visualizer::release()
-{
-    ALOGV("Visualizer::release()");
-    setEnabled(false);
-    Mutex::Autolock _l(mCaptureLock);
-
-    mCaptureThread.clear();
-    mCaptureCallBack = NULL;
-    mCaptureCbkUser = NULL;
-    mCaptureFlags = 0;
-    mCaptureRate = 0;
-}
-
-status_t Visualizer::setEnabled(bool enabled)
-{
-    Mutex::Autolock _l(mCaptureLock);
-
-    sp<CaptureThread> t = mCaptureThread;
-    if (t != 0) {
-        if (enabled) {
-            if (t->exitPending()) {
-                mCaptureLock.unlock();
-                if (t->requestExitAndWait() == WOULD_BLOCK) {
-                    mCaptureLock.lock();
-                    ALOGE("Visualizer::enable() called from thread");
-                    return INVALID_OPERATION;
-                }
-                mCaptureLock.lock();
-            }
-        }
-        t->mLock.lock();
-    }
-
-    status_t status = AudioEffect::setEnabled(enabled);
-
-    if (t != 0) {
-        if (enabled && status == NO_ERROR) {
-            t->run("Visualizer");
-        } else {
-            t->requestExit();
-        }
-    }
-
-    if (t != 0) {
-        t->mLock.unlock();
-    }
-
-    return status;
-}
-
-status_t Visualizer::setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags,
-        uint32_t rate)
-{
-    if (rate > CAPTURE_RATE_MAX) {
-        return BAD_VALUE;
-    }
-    Mutex::Autolock _l(mCaptureLock);
-
-    if (mEnabled) {
-        return INVALID_OPERATION;
-    }
-
-    if (mCaptureThread != 0) {
-        mCaptureLock.unlock();
-        mCaptureThread->requestExitAndWait();
-        mCaptureLock.lock();
-    }
-
-    mCaptureThread.clear();
-    mCaptureCallBack = cbk;
-    mCaptureCbkUser = user;
-    mCaptureFlags = flags;
-    mCaptureRate = rate;
-
-    if (cbk != NULL) {
-        mCaptureThread = new CaptureThread(this, rate, ((flags & CAPTURE_CALL_JAVA) != 0));
-    }
-    ALOGV("setCaptureCallBack() rate: %d thread %p flags 0x%08x",
-            rate, mCaptureThread.get(), mCaptureFlags);
-    return NO_ERROR;
-}
-
-status_t Visualizer::setCaptureSize(uint32_t size)
-{
-    if (size > VISUALIZER_CAPTURE_SIZE_MAX ||
-        size < VISUALIZER_CAPTURE_SIZE_MIN ||
-        popcount(size) != 1) {
-        return BAD_VALUE;
-    }
-
-    Mutex::Autolock _l(mCaptureLock);
-    if (mEnabled) {
-        return INVALID_OPERATION;
-    }
-
-    uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
-    effect_param_t *p = (effect_param_t *)buf32;
-
-    p->psize = sizeof(uint32_t);
-    p->vsize = sizeof(uint32_t);
-    *(int32_t *)p->data = VISUALIZER_PARAM_CAPTURE_SIZE;
-    *((int32_t *)p->data + 1)= size;
-    status_t status = setParameter(p);
-
-    ALOGV("setCaptureSize size %d  status %d p->status %d", size, status, p->status);
-
-    if (status == NO_ERROR) {
-        status = p->status;
-        if (status == NO_ERROR) {
-            mCaptureSize = size;
-        }
-    }
-
-    return status;
-}
-
-status_t Visualizer::setScalingMode(uint32_t mode) {
-    if ((mode != VISUALIZER_SCALING_MODE_NORMALIZED)
-            && (mode != VISUALIZER_SCALING_MODE_AS_PLAYED)) {
-        return BAD_VALUE;
-    }
-
-    Mutex::Autolock _l(mCaptureLock);
-
-    uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
-    effect_param_t *p = (effect_param_t *)buf32;
-
-    p->psize = sizeof(uint32_t);
-    p->vsize = sizeof(uint32_t);
-    *(int32_t *)p->data = VISUALIZER_PARAM_SCALING_MODE;
-    *((int32_t *)p->data + 1)= mode;
-    status_t status = setParameter(p);
-
-    ALOGV("setScalingMode mode %d  status %d p->status %d", mode, status, p->status);
-
-    if (status == NO_ERROR) {
-        status = p->status;
-        if (status == NO_ERROR) {
-            mScalingMode = mode;
-        }
-    }
-
-    return status;
-}
-
-status_t Visualizer::setMeasurementMode(uint32_t mode) {
-    if ((mode != MEASUREMENT_MODE_NONE)
-            //Note: needs to be handled as a mask when more measurement modes are added
-            && ((mode & MEASUREMENT_MODE_PEAK_RMS) != mode)) {
-        return BAD_VALUE;
-    }
-
-    Mutex::Autolock _l(mCaptureLock);
-
-    uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
-    effect_param_t *p = (effect_param_t *)buf32;
-
-    p->psize = sizeof(uint32_t);
-    p->vsize = sizeof(uint32_t);
-    *(int32_t *)p->data = VISUALIZER_PARAM_MEASUREMENT_MODE;
-    *((int32_t *)p->data + 1)= mode;
-    status_t status = setParameter(p);
-
-    ALOGV("setMeasurementMode mode %d  status %d p->status %d", mode, status, p->status);
-
-    if (status == NO_ERROR) {
-        status = p->status;
-        if (status == NO_ERROR) {
-            mMeasurementMode = mode;
-        }
-    }
-    return status;
-}
-
-status_t Visualizer::getIntMeasurements(uint32_t type, uint32_t number, int32_t *measurements) {
-    if (mMeasurementMode == MEASUREMENT_MODE_NONE) {
-        ALOGE("Cannot retrieve int measurements, no measurement mode set");
-        return INVALID_OPERATION;
-    }
-    if (!(mMeasurementMode & type)) {
-        // measurement type has not been set on this Visualizer
-        ALOGE("Cannot retrieve int measurements, requested measurement mode 0x%x not set(0x%x)",
-                type, mMeasurementMode);
-        return INVALID_OPERATION;
-    }
-    // only peak+RMS measurement supported
-    if ((type != MEASUREMENT_MODE_PEAK_RMS)
-            // for peak+RMS measurement, the results are 2 int32_t values
-            || (number != 2)) {
-        ALOGE("Cannot retrieve int measurements, MEASUREMENT_MODE_PEAK_RMS returns 2 ints, not %d",
-                        number);
-        return BAD_VALUE;
-    }
-
-    status_t status = NO_ERROR;
-    if (mEnabled) {
-        uint32_t replySize = number * sizeof(int32_t);
-        status = command(VISUALIZER_CMD_MEASURE,
-                sizeof(uint32_t)  /*cmdSize*/,
-                &type /*cmdData*/,
-                &replySize, measurements);
-        ALOGV("getMeasurements() command returned %d", status);
-        if ((status == NO_ERROR) && (replySize == 0)) {
-            status = NOT_ENOUGH_DATA;
-        }
-    } else {
-        ALOGV("getMeasurements() disabled");
-        return INVALID_OPERATION;
-    }
-    return status;
-}
-
-status_t Visualizer::getWaveForm(uint8_t *waveform)
-{
-    if (waveform == NULL) {
-        return BAD_VALUE;
-    }
-    if (mCaptureSize == 0) {
-        return NO_INIT;
-    }
-
-    status_t status = NO_ERROR;
-    if (mEnabled) {
-        uint32_t replySize = mCaptureSize;
-        status = command(VISUALIZER_CMD_CAPTURE, 0, NULL, &replySize, waveform);
-        ALOGV("getWaveForm() command returned %d", status);
-        if ((status == NO_ERROR) && (replySize == 0)) {
-            status = NOT_ENOUGH_DATA;
-        }
-    } else {
-        ALOGV("getWaveForm() disabled");
-        memset(waveform, 0x80, mCaptureSize);
-    }
-    return status;
-}
-
-status_t Visualizer::getFft(uint8_t *fft)
-{
-    if (fft == NULL) {
-        return BAD_VALUE;
-    }
-    if (mCaptureSize == 0) {
-        return NO_INIT;
-    }
-
-    status_t status = NO_ERROR;
-    if (mEnabled) {
-        uint8_t buf[mCaptureSize];
-        status = getWaveForm(buf);
-        if (status == NO_ERROR) {
-            status = doFft(fft, buf);
-        }
-    } else {
-        memset(fft, 0, mCaptureSize);
-    }
-    return status;
-}
-
-status_t Visualizer::doFft(uint8_t *fft, uint8_t *waveform)
-{
-    int32_t workspace[mCaptureSize >> 1];
-    int32_t nonzero = 0;
-
-    for (uint32_t i = 0; i < mCaptureSize; i += 2) {
-        workspace[i >> 1] =
-                ((waveform[i] ^ 0x80) << 24) | ((waveform[i + 1] ^ 0x80) << 8);
-        nonzero |= workspace[i >> 1];
-    }
-
-    if (nonzero) {
-        fixed_fft_real(mCaptureSize >> 1, workspace);
-    }
-
-    for (uint32_t i = 0; i < mCaptureSize; i += 2) {
-        short tmp = workspace[i >> 1] >> 21;
-        while (tmp > 127 || tmp < -128) tmp >>= 1;
-        fft[i] = tmp;
-        tmp = workspace[i >> 1];
-        tmp >>= 5;
-        while (tmp > 127 || tmp < -128) tmp >>= 1;
-        fft[i + 1] = tmp;
-    }
-
-    return NO_ERROR;
-}
-
-void Visualizer::periodicCapture()
-{
-    Mutex::Autolock _l(mCaptureLock);
-    ALOGV("periodicCapture() %p mCaptureCallBack %p mCaptureFlags 0x%08x",
-            this, mCaptureCallBack, mCaptureFlags);
-    if (mCaptureCallBack != NULL &&
-        (mCaptureFlags & (CAPTURE_WAVEFORM|CAPTURE_FFT)) &&
-        mCaptureSize != 0) {
-        uint8_t waveform[mCaptureSize];
-        status_t status = getWaveForm(waveform);
-        if (status != NO_ERROR) {
-            return;
-        }
-        uint8_t fft[mCaptureSize];
-        if (mCaptureFlags & CAPTURE_FFT) {
-            status = doFft(fft, waveform);
-        }
-        if (status != NO_ERROR) {
-            return;
-        }
-        uint8_t *wavePtr = NULL;
-        uint8_t *fftPtr = NULL;
-        uint32_t waveSize = 0;
-        uint32_t fftSize = 0;
-        if (mCaptureFlags & CAPTURE_WAVEFORM) {
-            wavePtr = waveform;
-            waveSize = mCaptureSize;
-        }
-        if (mCaptureFlags & CAPTURE_FFT) {
-            fftPtr = fft;
-            fftSize = mCaptureSize;
-        }
-        mCaptureCallBack(mCaptureCbkUser, waveSize, wavePtr, fftSize, fftPtr, mSampleRate);
-    }
-}
-
-uint32_t Visualizer::initCaptureSize()
-{
-    uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
-    effect_param_t *p = (effect_param_t *)buf32;
-
-    p->psize = sizeof(uint32_t);
-    p->vsize = sizeof(uint32_t);
-    *(int32_t *)p->data = VISUALIZER_PARAM_CAPTURE_SIZE;
-    status_t status = getParameter(p);
-
-    if (status == NO_ERROR) {
-        status = p->status;
-    }
-
-    uint32_t size = 0;
-    if (status == NO_ERROR) {
-        size = *((int32_t *)p->data + 1);
-    }
-    mCaptureSize = size;
-
-    ALOGV("initCaptureSize size %d status %d", mCaptureSize, status);
-
-    return size;
-}
-
-void Visualizer::controlStatusChanged(bool controlGranted) {
-    if (controlGranted) {
-        // this Visualizer instance regained control of the effect, reset the scaling mode
-        //   and capture size as has been cached through it.
-        ALOGV("controlStatusChanged(true) causes effect parameter reset:");
-        ALOGV("    scaling mode reset to %d", mScalingMode);
-        setScalingMode(mScalingMode);
-        ALOGV("    capture size reset to %d", mCaptureSize);
-        setCaptureSize(mCaptureSize);
-    }
-    AudioEffect::controlStatusChanged(controlGranted);
-}
-
-//-------------------------------------------------------------------------
-
-Visualizer::CaptureThread::CaptureThread(Visualizer* receiver, uint32_t captureRate,
-        bool bCanCallJava)
-    : Thread(bCanCallJava), mReceiver(receiver)
-{
-    mSleepTimeUs = 1000000000 / captureRate;
-    ALOGV("CaptureThread cstor %p captureRate %d mSleepTimeUs %d", this, captureRate, mSleepTimeUs);
-}
-
-bool Visualizer::CaptureThread::threadLoop()
-{
-    ALOGV("CaptureThread %p enter", this);
-    sp<Visualizer> receiver = mReceiver.promote();
-    if (receiver == NULL) {
-        return false;
-    }
-    while (!exitPending())
-    {
-        usleep(mSleepTimeUs);
-        receiver->periodicCapture();
-    }
-    ALOGV("CaptureThread %p exiting", this);
-    return false;
-}
-
-} // namespace android
diff --git a/media/libmedia/include/media/IOMX.h b/media/libmedia/include/media/IOMX.h
index 7e7c2d2..70c8a74 100644
--- a/media/libmedia/include/media/IOMX.h
+++ b/media/libmedia/include/media/IOMX.h
@@ -34,9 +34,17 @@
 #include <media/openmax/OMX_VideoExt.h>
 
 namespace android {
+namespace hardware {
+namespace media {
+namespace omx {
+namespace V1_0 {
+struct IGraphicBufferSource;
+}  // namespace V1_0
+}  // namespace omx
+}  // namespace media
+}  // namespace hardware
 
 class IGraphicBufferProducer;
-class IGraphicBufferSource;
 class IMemory;
 class IOMXBufferSource;
 class IOMXNode;
@@ -82,7 +90,7 @@
 
     virtual status_t createInputSurface(
             sp<IGraphicBufferProducer> *bufferProducer,
-            sp<IGraphicBufferSource> *bufferSource) = 0;
+            sp<hardware::media::omx::V1_0::IGraphicBufferSource> *bufferSource) = 0;
 };
 
 class IOMXNode : public IInterface {
diff --git a/media/libmedia/include/media/Visualizer.h b/media/libmedia/include/media/Visualizer.h
deleted file mode 100644
index 8078e36..0000000
--- a/media/libmedia/include/media/Visualizer.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2010 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_MEDIA_VISUALIZER_H
-#define ANDROID_MEDIA_VISUALIZER_H
-
-#include <media/AudioEffect.h>
-#include <system/audio_effects/effect_visualizer.h>
-#include <utils/Thread.h>
-
-/**
- * The Visualizer class enables application to retrieve part of the currently playing audio for
- * visualization purpose. It is not an audio recording interface and only returns partial and low
- * quality audio content. However, to protect privacy of certain audio data (e.g voice mail) the use
- * of the visualizer requires the permission android.permission.RECORD_AUDIO.
- * The audio session ID passed to the constructor indicates which audio content should be
- * visualized:
- * - If the session is 0, the audio output mix is visualized
- * - If the session is not 0, the audio from a particular MediaPlayer or AudioTrack
- *   using this audio session is visualized
- * Two types of representation of audio content can be captured:
- * - Waveform data: consecutive 8-bit (unsigned) mono samples by using the getWaveForm() method
- * - Frequency data: 8-bit magnitude FFT by using the getFft() method
- *
- * The length of the capture can be retrieved or specified by calling respectively
- * getCaptureSize() and setCaptureSize() methods. Note that the size of the FFT
- * is half of the specified capture size but both sides of the spectrum are returned yielding in a
- * number of bytes equal to the capture size. The capture size must be a power of 2 in the range
- * returned by getMinCaptureSize() and getMaxCaptureSize().
- * In addition to the polling capture mode, a callback mode is also available by installing a
- * callback function by use of the setCaptureCallBack() method. The rate at which the callback
- * is called as well as the type of data returned is specified.
- * Before capturing data, the Visualizer must be enabled by calling the setEnabled() method.
- * When data capture is not needed any more, the Visualizer should be disabled.
- */
-
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class Visualizer: public AudioEffect {
-public:
-
-    enum callback_flags {
-        CAPTURE_WAVEFORM = 0x00000001,  // capture callback returns a PCM wave form
-        CAPTURE_FFT = 0x00000002,       // apture callback returns a frequency representation
-        CAPTURE_CALL_JAVA = 0x00000004  // the callback thread can call java
-    };
-
-
-    /* Constructor.
-     * See AudioEffect constructor for details on parameters.
-     */
-                        Visualizer(const String16& opPackageName,
-                                   int32_t priority = 0,
-                                   effect_callback_t cbf = NULL,
-                                   void* user = NULL,
-                                   audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX);
-
-                        ~Visualizer();
-
-    virtual status_t    setEnabled(bool enabled);
-
-    // maximum capture size in samples
-    static uint32_t getMaxCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MAX; }
-    // minimum capture size in samples
-    static uint32_t getMinCaptureSize() { return VISUALIZER_CAPTURE_SIZE_MIN; }
-    // maximum capture rate in millihertz
-    static uint32_t getMaxCaptureRate() { return CAPTURE_RATE_MAX; }
-
-    // callback used to return periodic PCM or FFT captures to the application. Either one or both
-    // types of data are returned (PCM and FFT) according to flags indicated when installing the
-    // callback. When a type of data is not present, the corresponding size (waveformSize or
-    // fftSize) is 0.
-    typedef void (*capture_cbk_t)(void* user,
-                                    uint32_t waveformSize,
-                                    uint8_t *waveform,
-                                    uint32_t fftSize,
-                                    uint8_t *fft,
-                                    uint32_t samplingrate);
-
-    // install a callback to receive periodic captures. The capture rate is specified in milliHertz
-    // and the capture format is according to flags  (see callback_flags).
-    status_t setCaptureCallBack(capture_cbk_t cbk, void* user, uint32_t flags, uint32_t rate);
-
-    // set the capture size capture size must be a power of two in the range
-    // [VISUALIZER_CAPTURE_SIZE_MAX. VISUALIZER_CAPTURE_SIZE_MIN]
-    // must be called when the visualizer is not enabled
-    status_t setCaptureSize(uint32_t size);
-    uint32_t getCaptureSize() { return mCaptureSize; }
-
-    // returns the capture rate indicated when installing the callback
-    uint32_t getCaptureRate() { return mCaptureRate; }
-
-    // returns the sampling rate of the audio being captured
-    uint32_t getSamplingRate() { return mSampleRate; }
-
-    // set the way volume affects the captured data
-    // mode must one of VISUALIZER_SCALING_MODE_NORMALIZED,
-    //  VISUALIZER_SCALING_MODE_AS_PLAYED
-    status_t setScalingMode(uint32_t mode);
-    uint32_t getScalingMode() { return mScalingMode; }
-
-    // set which measurements are done on the audio buffers processed by the effect.
-    // valid measurements (mask): MEASUREMENT_MODE_PEAK_RMS
-    status_t setMeasurementMode(uint32_t mode);
-    uint32_t getMeasurementMode() { return mMeasurementMode; }
-
-    // return a set of int32_t measurements
-    status_t getIntMeasurements(uint32_t type, uint32_t number, int32_t *measurements);
-
-    // return a capture in PCM 8 bit unsigned format. The size of the capture is equal to
-    // getCaptureSize()
-    status_t getWaveForm(uint8_t *waveform);
-
-    // return a capture in FFT 8 bit signed format. The size of the capture is equal to
-    // getCaptureSize() but the length of the FFT is half of the size (both parts of the spectrum
-    // are returned
-    status_t getFft(uint8_t *fft);
-    void release();
-
-protected:
-    // from IEffectClient
-    virtual void controlStatusChanged(bool controlGranted);
-
-private:
-
-    static const uint32_t CAPTURE_RATE_MAX = 20000;
-    static const uint32_t CAPTURE_RATE_DEF = 10000;
-    static const uint32_t CAPTURE_SIZE_DEF = VISUALIZER_CAPTURE_SIZE_MAX;
-
-    /* internal class to handle the callback */
-    class CaptureThread : public Thread
-    {
-    public:
-        CaptureThread(Visualizer* visualizer, uint32_t captureRate, bool bCanCallJava = false);
-
-    private:
-        friend class Visualizer;
-        virtual bool        threadLoop();
-        wp<Visualizer> mReceiver;
-        Mutex       mLock;
-        uint32_t mSleepTimeUs;
-    };
-
-    status_t doFft(uint8_t *fft, uint8_t *waveform);
-    void periodicCapture();
-    uint32_t initCaptureSize();
-
-    Mutex mCaptureLock;
-    uint32_t mCaptureRate;
-    uint32_t mCaptureSize;
-    uint32_t mSampleRate;
-    uint32_t mScalingMode;
-    uint32_t mMeasurementMode;
-    capture_cbk_t mCaptureCallBack;
-    void *mCaptureCbkUser;
-    sp<CaptureThread> mCaptureThread;
-    uint32_t mCaptureFlags;
-};
-
-
-}; // namespace android
-
-#endif // ANDROID_MEDIA_VISUALIZER_H
diff --git a/media/libmedia/include/media/omx/1.0/Conversion.h b/media/libmedia/include/media/omx/1.0/Conversion.h
index 6dc46b7..811936b 100644
--- a/media/libmedia/include/media/omx/1.0/Conversion.h
+++ b/media/libmedia/include/media/omx/1.0/Conversion.h
@@ -45,7 +45,6 @@
 #include <android/hardware/media/omx/1.0/IOmxObserver.h>
 #include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
 
-#include <android/IGraphicBufferSource.h>
 #include <android/IOMXBufferSource.h>
 
 namespace android {
diff --git a/media/libmedia/include/media/omx/1.0/WOmx.h b/media/libmedia/include/media/omx/1.0/WOmx.h
index 0680eec..46ada9b 100644
--- a/media/libmedia/include/media/omx/1.0/WOmx.h
+++ b/media/libmedia/include/media/omx/1.0/WOmx.h
@@ -67,7 +67,7 @@
             sp<IOMXNode>* omxNode) override;
     status_t createInputSurface(
             sp<::android::IGraphicBufferProducer>* bufferProducer,
-            sp<::android::IGraphicBufferSource>* bufferSource) override;
+            sp<::android::hardware::media::omx::V1_0::IGraphicBufferSource>* bufferSource) override;
 };
 
 }  // namespace utils
diff --git a/media/libmedia/omx/1.0/WOmx.cpp b/media/libmedia/omx/1.0/WOmx.cpp
index ce624fa..4bacdda 100644
--- a/media/libmedia/omx/1.0/WOmx.cpp
+++ b/media/libmedia/omx/1.0/WOmx.cpp
@@ -18,7 +18,6 @@
 #include <media/omx/1.0/WOmx.h>
 #include <media/omx/1.0/WOmxNode.h>
 #include <media/omx/1.0/WOmxObserver.h>
-#include <media/omx/1.0/WGraphicBufferSource.h>
 #include <media/omx/1.0/Conversion.h>
 
 namespace android {
@@ -70,7 +69,7 @@
 
 status_t LWOmx::createInputSurface(
         sp<::android::IGraphicBufferProducer>* bufferProducer,
-        sp<::android::IGraphicBufferSource>* bufferSource) {
+        sp<::android::hardware::media::omx::V1_0::IGraphicBufferSource>* bufferSource) {
     status_t fnStatus;
     status_t transStatus = toStatusT(mBase->createInputSurface(
             [&fnStatus, bufferProducer, bufferSource] (
@@ -79,7 +78,7 @@
                     sp<IGraphicBufferSource> const& tSource) {
                 fnStatus = toStatusT(status);
                 *bufferProducer = new H2BGraphicBufferProducer(tProducer);
-                *bufferSource = new LWGraphicBufferSource(tSource);
+                *bufferSource = tSource;
             }));
     return transStatus == NO_ERROR ? fnStatus : transStatus;
 }
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index f17520a..00e3443 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -784,7 +784,7 @@
         return;
     }
 
-    int64_t nextSubTimeUs;
+    int64_t nextSubTimeUs = 0;
     readBuffer(type, -1, MediaPlayerSeekMode::SEEK_PREVIOUS_SYNC /* mode */, &nextSubTimeUs);
 
     sp<ABuffer> buffer;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 0ca20b9..965e5a6 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -24,6 +24,8 @@
 #include <inttypes.h>
 #include <utils/Trace.h>
 
+#include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
+
 #include <gui/Surface.h>
 
 #include <media/stagefright/ACodec.h>
@@ -45,6 +47,7 @@
 #include <media/hardware/HardwareAPI.h>
 #include <media/MediaBufferHolder.h>
 #include <media/OMXBuffer.h>
+#include <media/omx/1.0/Conversion.h>
 #include <media/omx/1.0/WOmxNode.h>
 
 #include <hidlmemory/mapping.h>
@@ -63,7 +66,9 @@
 
 namespace android {
 
-using binder::Status;
+typedef hardware::media::omx::V1_0::IGraphicBufferSource HGraphicBufferSource;
+
+using hardware::media::omx::V1_0::Status;
 
 enum {
     kMaxIndicesToCheck = 32, // used when enumerating supported formats and profiles
@@ -98,16 +103,11 @@
     }
 }
 
-static inline status_t statusFromBinderStatus(const Status &status) {
+static inline status_t statusFromBinderStatus(hardware::Return<Status> &&status) {
     if (status.isOk()) {
-        return OK;
-    }
-    status_t err;
-    if ((err = status.serviceSpecificErrorCode()) != OK) {
-        return err;
-    }
-    if ((err = status.transactionError()) != OK) {
-        return err;
+        return static_cast<status_t>(status.withDefault(Status::UNKNOWN_ERROR));
+    } else if (status.isDeadObject()) {
+        return DEAD_OBJECT;
     }
     // Other exception
     return UNKNOWN_ERROR;
@@ -6906,8 +6906,11 @@
         return err;
     }
 
+    using hardware::media::omx::V1_0::utils::TWOmxNode;
     err = statusFromBinderStatus(
-            mCodec->mGraphicBufferSource->configure(mCodec->mOMXNode, dataSpace));
+            mCodec->mGraphicBufferSource->configure(
+                    new TWOmxNode(mCodec->mOMXNode),
+                    static_cast<hardware::graphics::common::V1_0::Dataspace>(dataSpace)));
     if (err != OK) {
         ALOGE("[%s] Unable to configure for node (err %d)",
               mCodec->mComponentName.c_str(), err);
@@ -6993,8 +6996,9 @@
         }
 
         err = statusFromBinderStatus(
-                mCodec->mGraphicBufferSource->setColorAspects(ColorUtils::packToU32(
-                        *(ColorAspects *)colorAspectsBuffer->base())));
+                mCodec->mGraphicBufferSource->setColorAspects(
+                        hardware::media::omx::V1_0::utils::toHardwareColorAspects(
+                                *(ColorAspects *)colorAspectsBuffer->base())));
 
         if (err != OK) {
             ALOGE("[%s] Unable to configure color aspects (err %d)",
@@ -7010,8 +7014,10 @@
     ALOGV("onCreateInputSurface");
 
     sp<IGraphicBufferProducer> bufferProducer;
+    sp<HGraphicBufferSource> bufferSource;
     status_t err = mCodec->mOMX->createInputSurface(
-            &bufferProducer, &mCodec->mGraphicBufferSource);
+            &bufferProducer, &bufferSource);
+    mCodec->mGraphicBufferSource = bufferSource;
 
     if (err == OK) {
         err = setupInputSurface();
@@ -7044,8 +7050,12 @@
     }
 
     sp<PersistentSurface> surface = static_cast<PersistentSurface *>(obj.get());
-    mCodec->mGraphicBufferSource = surface->getBufferSource();
-    status_t err = setupInputSurface();
+    sp<HGraphicBufferSource> hgbs = HGraphicBufferSource::castFrom(surface->getHidlTarget());
+    status_t err = BAD_VALUE;
+    if (hgbs) {
+        mCodec->mGraphicBufferSource = hgbs;
+        err = setupInputSurface();
+    }
 
     if (err == OK) {
         mCodec->mCallback->onInputSurfaceAccepted(
@@ -7564,8 +7574,14 @@
         }
 
         int64_t stopTimeOffsetUs;
-        err = statusFromBinderStatus(
-                mGraphicBufferSource->getStopTimeOffsetUs(&stopTimeOffsetUs));
+        hardware::Return<void> trans = mGraphicBufferSource->getStopTimeOffsetUs(
+                [&err, &stopTimeOffsetUs](auto status, auto result) {
+                    err = static_cast<status_t>(status);
+                    stopTimeOffsetUs = result;
+                });
+        if (!trans.isOk()) {
+            err = trans.isDeadObject() ? DEAD_OBJECT : UNKNOWN_ERROR;
+        }
 
         if (err != OK) {
             ALOGE("Failed to get stop time offset (err %d)", err);
diff --git a/media/libstagefright/FrameDecoder.cpp b/media/libstagefright/FrameDecoder.cpp
index 03415d5..3bb9c36 100644
--- a/media/libstagefright/FrameDecoder.cpp
+++ b/media/libstagefright/FrameDecoder.cpp
@@ -917,12 +917,6 @@
     }
     converter.setSrcColorSpace(standard, range, transfer);
 
-    int32_t dstLeft, dstTop, dstRight, dstBottom;
-    dstLeft = mTilesDecoded % mGridCols * width;
-    dstTop = mTilesDecoded / mGridCols * height;
-    dstRight = dstLeft + width - 1;
-    dstBottom = dstTop + height - 1;
-
     int32_t crop_left, crop_top, crop_right, crop_bottom;
     if (!outputFormat->findRect("crop", &crop_left, &crop_top, &crop_right, &crop_bottom)) {
         crop_left = crop_top = 0;
@@ -930,15 +924,25 @@
         crop_bottom = height - 1;
     }
 
+    int32_t crop_width, crop_height;
+    crop_width = crop_right - crop_left + 1;
+    crop_height = crop_bottom - crop_top + 1;
+
+    int32_t dstLeft, dstTop, dstRight, dstBottom;
+    dstLeft = mTilesDecoded % mGridCols * crop_width;
+    dstTop = mTilesDecoded / mGridCols * crop_height;
+    dstRight = dstLeft + crop_width - 1;
+    dstBottom = dstTop + crop_height - 1;
+
     // apply crop on bottom-right
     // TODO: need to move this into the color converter itself.
     if (dstRight >= mWidth) {
-        crop_right = mWidth - dstLeft - 1;
-        dstRight = dstLeft + crop_right;
+        crop_right = crop_left + mWidth - dstLeft - 1;
+        dstRight = mWidth - 1;
     }
     if (dstBottom >= mHeight) {
-        crop_bottom = mHeight - dstTop - 1;
-        dstBottom = dstTop + crop_bottom;
+        crop_bottom = crop_top + mHeight - dstTop - 1;
+        dstBottom = mHeight - 1;
     }
 
     *done = (++mTilesDecoded >= mTargetTiles);
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index d2e884e..14564c9 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -21,12 +21,11 @@
 #include <inttypes.h>
 #include <stdlib.h>
 
-#include "include/SecureBuffer.h"
-#include "include/SharedMemoryBuffer.h"
 #include "include/SoftwareRenderer.h"
 #include "StagefrightPluginLoader.h"
 
 #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>
@@ -545,7 +544,7 @@
     sp<IOMX> omx = client.interface();
 
     sp<IGraphicBufferProducer> bufferProducer;
-    sp<IGraphicBufferSource> bufferSource;
+    sp<hardware::media::omx::V1_0::IGraphicBufferSource> bufferSource;
 
     status_t err = omx->createInputSurface(&bufferProducer, &bufferSource);
 
diff --git a/media/libstagefright/id3/Android.bp b/media/libstagefright/id3/Android.bp
index d9704a6..c8173cf 100644
--- a/media/libstagefright/id3/Android.bp
+++ b/media/libstagefright/id3/Android.bp
@@ -4,6 +4,7 @@
     srcs: ["ID3.cpp"],
 
     header_libs: [
+        "libmedia_headers",
         "media_ndk_headers",
     ],
 
diff --git a/media/libstagefright/include/media/stagefright/ACodec.h b/media/libstagefright/include/media/stagefright/ACodec.h
index f9055a4..7754de4 100644
--- a/media/libstagefright/include/media/stagefright/ACodec.h
+++ b/media/libstagefright/include/media/stagefright/ACodec.h
@@ -37,6 +37,15 @@
 #define TRACK_BUFFER_TIMING     0
 
 namespace android {
+namespace hardware {
+namespace media {
+namespace omx {
+namespace V1_0 {
+struct IGraphicBufferSource;
+}  // namespace V1_0
+}  // namespace omx
+}  // namespace media
+}  // namespace hardware
 
 struct ABuffer;
 class ACodecBufferChannel;
@@ -279,7 +288,7 @@
     size_t mNumUndequeuedBuffers;
     sp<DataConverter> mConverter[2];
 
-    sp<IGraphicBufferSource> mGraphicBufferSource;
+    sp<hardware::media::omx::V1_0::IGraphicBufferSource> mGraphicBufferSource;
     int64_t mRepeatFrameDelayUs;
     int64_t mMaxPtsGapUs;
     float mMaxFps;
diff --git a/media/libstagefright/include/media/stagefright/MediaErrors.h b/media/libstagefright/include/media/stagefright/MediaErrors.h
index 09639e2..6f48c5d 100644
--- a/media/libstagefright/include/media/stagefright/MediaErrors.h
+++ b/media/libstagefright/include/media/stagefright/MediaErrors.h
@@ -99,7 +99,13 @@
     ERROR_CAS_DEVICE_REVOKED                 = CAS_ERROR_BASE - 9,
     ERROR_CAS_RESOURCE_BUSY                  = CAS_ERROR_BASE - 10,
     ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION = CAS_ERROR_BASE - 11,
-    ERROR_CAS_LAST_USED_ERRORCODE            = CAS_ERROR_BASE - 11,
+    ERROR_CAS_NEED_ACTIVATION                = CAS_ERROR_BASE - 12,
+    ERROR_CAS_NEED_PAIRING                   = CAS_ERROR_BASE - 13,
+    ERROR_CAS_NO_CARD                        = CAS_ERROR_BASE - 14,
+    ERROR_CAS_CARD_MUTE                      = CAS_ERROR_BASE - 15,
+    ERROR_CAS_CARD_INVALID                   = CAS_ERROR_BASE - 16,
+    ERROR_CAS_BLACKOUT                       = CAS_ERROR_BASE - 17,
+    ERROR_CAS_LAST_USED_ERRORCODE            = CAS_ERROR_BASE - 17,
 
     ERROR_CAS_VENDOR_MAX                     = CAS_ERROR_BASE - 500,
     ERROR_CAS_VENDOR_MIN                     = CAS_ERROR_BASE - 999,
diff --git a/media/libstagefright/include/media/stagefright/PersistentSurface.h b/media/libstagefright/include/media/stagefright/PersistentSurface.h
index 49b36c9..f4943c3 100644
--- a/media/libstagefright/include/media/stagefright/PersistentSurface.h
+++ b/media/libstagefright/include/media/stagefright/PersistentSurface.h
@@ -18,31 +18,21 @@
 
 #define PERSISTENT_SURFACE_H_
 
-#include <android/IGraphicBufferSource.h>
 #include <binder/Parcel.h>
 #include <hidl/HidlSupport.h>
 #include <hidl/HybridInterface.h>
 #include <gui/IGraphicBufferProducer.h>
 #include <media/stagefright/foundation/ABase.h>
 
-using android::hidl::base::V1_0::IBase;
-
 namespace android {
 
 struct PersistentSurface : public RefBase {
     PersistentSurface() {}
 
-    // create an OMX persistent surface
+    // create a persistent surface
     PersistentSurface(
             const sp<IGraphicBufferProducer>& bufferProducer,
-            const sp<IGraphicBufferSource>& bufferSource) :
-        mBufferProducer(bufferProducer),
-        mBufferSource(bufferSource) { }
-
-    // create a HIDL persistent surface
-    PersistentSurface(
-            const sp<IGraphicBufferProducer>& bufferProducer,
-            const sp<IBase>& hidlTarget) :
+            const sp<hidl::base::V1_0::IBase>& hidlTarget) :
         mBufferProducer(bufferProducer),
         mHidlTarget(hidlTarget) { }
 
@@ -50,18 +40,12 @@
         return mBufferProducer;
     }
 
-    sp<IGraphicBufferSource> getBufferSource() const {
-        return mBufferSource;
-    }
-
-    sp<IBase> getHidlTarget() const {
+    sp<hidl::base::V1_0::IBase> getHidlTarget() const {
         return mHidlTarget;
     }
 
     status_t writeToParcel(Parcel *parcel) const {
         parcel->writeStrongBinder(IInterface::asBinder(mBufferProducer));
-        // this can handle null
-        parcel->writeStrongBinder(IInterface::asBinder(mBufferSource));
         // write hidl target
         if (mHidlTarget != nullptr) {
             HalToken token;
@@ -79,8 +63,6 @@
     status_t readFromParcel(const Parcel *parcel) {
         mBufferProducer = interface_cast<IGraphicBufferProducer>(
                 parcel->readStrongBinder());
-        mBufferSource = interface_cast<IGraphicBufferSource>(
-                parcel->readStrongBinder());
         // read hidl target
         bool haveHidlTarget = parcel->readBool();
         if (haveHidlTarget) {
@@ -97,8 +79,7 @@
 
 private:
     sp<IGraphicBufferProducer> mBufferProducer;
-    sp<IGraphicBufferSource> mBufferSource;
-    sp<IBase> mHidlTarget;
+    sp<hidl::base::V1_0::IBase> mHidlTarget;
 
     DISALLOW_EVIL_CONSTRUCTORS(PersistentSurface);
 };
diff --git a/media/libstagefright/omx/1.0/WGraphicBufferSource.cpp b/media/libstagefright/omx/1.0/WGraphicBufferSource.cpp
index ed272bb..7d217eb 100644
--- a/media/libstagefright/omx/1.0/WGraphicBufferSource.cpp
+++ b/media/libstagefright/omx/1.0/WGraphicBufferSource.cpp
@@ -14,6 +14,10 @@
  * limitations under the License.
  */
 
+#ifdef __LP64__
+#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
+#endif
+
 //#define LOG_NDEBUG 0
 #define LOG_TAG "TWGraphicBufferSource"
 
@@ -21,6 +25,7 @@
 #include <media/stagefright/omx/1.0/WOmxNode.h>
 #include <media/stagefright/omx/1.0/Conversion.h>
 #include <media/stagefright/omx/OMXUtils.h>
+#include <media/stagefright/omx/OmxGraphicBufferSource.h>
 #include <android/hardware/media/omx/1.0/IOmxBufferSource.h>
 #include <android/hardware/media/omx/1.0/IOmxNode.h>
 #include <media/openmax/OMX_Component.h>
diff --git a/media/libstagefright/omx/OmxGraphicBufferSource.cpp b/media/libstagefright/omx/OmxGraphicBufferSource.cpp
index 8de1f4f..7b187f9 100644
--- a/media/libstagefright/omx/OmxGraphicBufferSource.cpp
+++ b/media/libstagefright/omx/OmxGraphicBufferSource.cpp
@@ -14,12 +14,18 @@
  * limitations under the License.
  */
 
+#ifdef __LP64__
+#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
+#endif
+
 #include <inttypes.h>
 
 #define LOG_TAG "OmxGraphicBufferSource"
 //#define LOG_NDEBUG 0
 #include <utils/Log.h>
 
+#include <media/openmax/OMX_Core.h>
+
 #include <media/stagefright/bqhelper/ComponentWrapper.h>
 #include <media/stagefright/bqhelper/GraphicBufferSource.h>
 #include <media/stagefright/omx/OmxGraphicBufferSource.h>
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
index 9669677..264c01d 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/1.0/Conversion.h
@@ -48,7 +48,6 @@
 #include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
 #include <android/hardware/media/omx/1.0/IOmxObserver.h>
 
-#include <android/IGraphicBufferSource.h>
 #include <android/IOMXBufferSource.h>
 
 namespace android {
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/1.0/WGraphicBufferSource.h b/media/libstagefright/omx/include/media/stagefright/omx/1.0/WGraphicBufferSource.h
index 4e56c98..02d4b7b 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/1.0/WGraphicBufferSource.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/1.0/WGraphicBufferSource.h
@@ -26,18 +26,16 @@
 #include <android/hardware/media/omx/1.0/IOmxNode.h>
 #include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
 
-#include <android/BnGraphicBufferSource.h>
-
-#include <media/stagefright/omx/OmxGraphicBufferSource.h>
-
 namespace android {
+
+class OmxGraphicBufferSource;
+
 namespace hardware {
 namespace media {
 namespace omx {
 namespace V1_0 {
 namespace implementation {
 
-using ::android::OmxGraphicBufferSource;
 using ::android::hardware::graphics::common::V1_0::Dataspace;
 using ::android::hardware::media::omx::V1_0::ColorAspects;
 using ::android::hardware::media::omx::V1_0::IGraphicBufferSource;
@@ -52,8 +50,6 @@
 using ::android::hardware::Void;
 using ::android::sp;
 
-using ::android::IOMXNode;
-
 /**
  * Wrapper classes for conversion
  * ==============================
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/OmxGraphicBufferSource.h b/media/libstagefright/omx/include/media/stagefright/omx/OmxGraphicBufferSource.h
index 518e0cb..e576d75 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/OmxGraphicBufferSource.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/OmxGraphicBufferSource.h
@@ -21,7 +21,6 @@
 #include <media/stagefright/bqhelper/GraphicBufferSource.h>
 #include <media/stagefright/foundation/ABase.h>
 
-#include <android/BnGraphicBufferSource.h>
 #include <android/BnOMXBufferSource.h>
 
 #include "IOmxNodeWrapper.h"
diff --git a/media/libstagefright/webm/Android.bp b/media/libstagefright/webm/Android.bp
index 9f3e807..2cebe8f 100644
--- a/media/libstagefright/webm/Android.bp
+++ b/media/libstagefright/webm/Android.bp
@@ -34,6 +34,7 @@
     ],
 
     header_libs: [
+        "libmedia_headers",
         "media_ndk_headers",
     ],
 }
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index 61f9014..aac6d71 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -149,6 +149,10 @@
         "-Wall",
     ],
 
+    header_libs: [
+        "libmedia_headers",
+    ],
+
     shared_libs: [
     ],
 
diff --git a/media/tests/benchmark/src/native/common/Android.bp b/media/tests/benchmark/src/native/common/Android.bp
index e163738..1da0102 100644
--- a/media/tests/benchmark/src/native/common/Android.bp
+++ b/media/tests/benchmark/src/native/common/Android.bp
@@ -15,10 +15,10 @@
  */
 
 cc_library_static {
-    name: "libbenchmark_common",
+    name: "libmediabenchmark_common",
     defaults: [
-        "libbenchmark-defaults",
-        "libbenchmark_soft_sanitize_all-defaults",
+        "libmediabenchmark-defaults",
+        "libmediabenchmark_soft_sanitize_all-defaults",
     ],
 
     srcs: [
@@ -32,19 +32,19 @@
 }
 
 cc_defaults {
-    name: "libbenchmark_common-defaults",
+    name: "libmediabenchmark_common-defaults",
 
     defaults: [
-        "libbenchmark-defaults",
+        "libmediabenchmark-defaults",
     ],
 
     static_libs: [
-        "libbenchmark_common",
+        "libmediabenchmark_common",
     ],
 }
 
 cc_defaults {
-    name: "libbenchmark-defaults",
+    name: "libmediabenchmark-defaults",
 
     shared_libs: [
         "libmediandk",
@@ -61,7 +61,7 @@
 // public dependency for native implementation
 // to be used by code under media/benchmark/* only
 cc_defaults {
-    name: "libbenchmark_soft_sanitize_all-defaults",
+    name: "libmediabenchmark_soft_sanitize_all-defaults",
 
     sanitize: {
         misc_undefined: [
diff --git a/media/tests/benchmark/src/native/decoder/Android.bp b/media/tests/benchmark/src/native/decoder/Android.bp
index f2d3db5..b6286d4 100644
--- a/media/tests/benchmark/src/native/decoder/Android.bp
+++ b/media/tests/benchmark/src/native/decoder/Android.bp
@@ -15,15 +15,15 @@
  */
 
 cc_library_static {
-    name: "libbenchmark_decoder",
+    name: "libmediabenchmark_decoder",
     defaults: [
-        "libbenchmark_common-defaults",
-        "libbenchmark_soft_sanitize_all-defaults",
+        "libmediabenchmark_common-defaults",
+        "libmediabenchmark_soft_sanitize_all-defaults",
     ],
 
     srcs: ["Decoder.cpp"],
 
-    static_libs: ["libbenchmark_extractor"],
+    static_libs: ["libmediabenchmark_extractor"],
 
     export_include_dirs: ["."],
 
diff --git a/media/tests/benchmark/src/native/encoder/Android.bp b/media/tests/benchmark/src/native/encoder/Android.bp
index c14c319..239f378 100644
--- a/media/tests/benchmark/src/native/encoder/Android.bp
+++ b/media/tests/benchmark/src/native/encoder/Android.bp
@@ -15,16 +15,16 @@
  */
 
 cc_library_static {
-    name: "libbenchmark_encoder",
+    name: "libmediabenchmark_encoder",
     defaults: [
-        "libbenchmark_common-defaults",
-        "libbenchmark_soft_sanitize_all-defaults",
+        "libmediabenchmark_common-defaults",
+        "libmediabenchmark_soft_sanitize_all-defaults",
     ],
 
     srcs: ["Encoder.cpp"],
 
-    static_libs: ["libbenchmark_extractor",
-                  "libbenchmark_decoder",
+    static_libs: ["libmediabenchmark_extractor",
+                  "libmediabenchmark_decoder",
     ],
 
     export_include_dirs: ["."],
diff --git a/media/tests/benchmark/src/native/extractor/Android.bp b/media/tests/benchmark/src/native/extractor/Android.bp
index 2fbe4e8..dfd0d49 100644
--- a/media/tests/benchmark/src/native/extractor/Android.bp
+++ b/media/tests/benchmark/src/native/extractor/Android.bp
@@ -15,10 +15,10 @@
  */
 
 cc_library_static {
-    name: "libbenchmark_extractor",
+    name: "libmediabenchmark_extractor",
     defaults: [
-        "libbenchmark_common-defaults",
-        "libbenchmark_soft_sanitize_all-defaults",
+        "libmediabenchmark_common-defaults",
+        "libmediabenchmark_soft_sanitize_all-defaults",
     ],
 
     srcs: ["Extractor.cpp"],
diff --git a/media/tests/benchmark/src/native/muxer/Android.bp b/media/tests/benchmark/src/native/muxer/Android.bp
index 6ef2a2e..f669d4a 100644
--- a/media/tests/benchmark/src/native/muxer/Android.bp
+++ b/media/tests/benchmark/src/native/muxer/Android.bp
@@ -15,15 +15,15 @@
  */
 
 cc_library_static {
-    name: "libbenchmark_muxer",
+    name: "libmediabenchmark_muxer",
     defaults: [
-        "libbenchmark_common-defaults",
-        "libbenchmark_soft_sanitize_all-defaults",
+        "libmediabenchmark_common-defaults",
+        "libmediabenchmark_soft_sanitize_all-defaults",
     ],
 
     srcs: ["Muxer.cpp"],
 
-    static_libs: ["libbenchmark_extractor"],
+    static_libs: ["libmediabenchmark_extractor"],
 
     export_include_dirs: ["."],
 
diff --git a/media/tests/benchmark/tests/Android.bp b/media/tests/benchmark/tests/Android.bp
index fc21ef7..24fd68c 100644
--- a/media/tests/benchmark/tests/Android.bp
+++ b/media/tests/benchmark/tests/Android.bp
@@ -18,28 +18,28 @@
     name: "extractorTest",
     gtest: true,
     defaults: [
-        "libbenchmark_common-defaults",
-        "libbenchmark_soft_sanitize_all-defaults",
+        "libmediabenchmark_common-defaults",
+        "libmediabenchmark_soft_sanitize_all-defaults",
     ],
 
     srcs: ["ExtractorTest.cpp"],
 
-    static_libs: ["libbenchmark_extractor"]
+    static_libs: ["libmediabenchmark_extractor"]
 }
 
 cc_test {
     name: "decoderTest",
     gtest: true,
     defaults: [
-        "libbenchmark_common-defaults",
-        "libbenchmark_soft_sanitize_all-defaults",
+        "libmediabenchmark_common-defaults",
+        "libmediabenchmark_soft_sanitize_all-defaults",
     ],
 
     srcs: ["DecoderTest.cpp"],
 
     static_libs: [
-        "libbenchmark_extractor",
-        "libbenchmark_decoder",
+        "libmediabenchmark_extractor",
+        "libmediabenchmark_decoder",
     ],
 }
 
@@ -47,15 +47,15 @@
     name: "muxerTest",
     gtest: true,
     defaults: [
-        "libbenchmark_common-defaults",
-        "libbenchmark_soft_sanitize_all-defaults",
+        "libmediabenchmark_common-defaults",
+        "libmediabenchmark_soft_sanitize_all-defaults",
     ],
 
     srcs: ["MuxerTest.cpp"],
 
     static_libs: [
-        "libbenchmark_extractor",
-        "libbenchmark_muxer",
+        "libmediabenchmark_extractor",
+        "libmediabenchmark_muxer",
     ],
 }
 
@@ -63,15 +63,15 @@
     name: "encoderTest",
     gtest: true,
     defaults: [
-        "libbenchmark_common-defaults",
-        "libbenchmark_soft_sanitize_all-defaults",
+        "libmediabenchmark_common-defaults",
+        "libmediabenchmark_soft_sanitize_all-defaults",
     ],
 
     srcs: ["EncoderTest.cpp"],
 
     static_libs: [
-        "libbenchmark_extractor",
-        "libbenchmark_decoder",
-        "libbenchmark_encoder",
+        "libmediabenchmark_extractor",
+        "libmediabenchmark_decoder",
+        "libmediabenchmark_encoder",
     ],
 }
diff --git a/media/utils/Android.bp b/media/utils/Android.bp
index c0967d9..8a9039c 100644
--- a/media/utils/Android.bp
+++ b/media/utils/Android.bp
@@ -48,6 +48,7 @@
 
     header_libs: [
         "bionic_libc_platform_headers",
+        "libmedia_headers",
     ],
 
     local_include_dirs: ["include"],
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
index e33bbad..4088e92 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.cpp
@@ -31,7 +31,6 @@
 #include <mediadrm/ICrypto.h>
 #include <media/MediaCodecBuffer.h>
 #include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/foundation/MediaDefs.h>
 #include <media/stagefright/MediaCodecConstants.h>
 
@@ -66,7 +65,8 @@
         mMainImageSurfaceId(-1),
         mYuvBufferAcquired(false),
         mProducerListener(new ProducerListener()),
-        mOutputBufferCounter(0),
+        mDequeuedOutputBufferCnt(0),
+        mCodecOutputCounter(0),
         mGridTimestampUs(0) {
 }
 
@@ -231,6 +231,8 @@
     if (bufferInfo.mError) return;
 
     mCodecOutputBufferTimestamps.push(bufferInfo.mTimestamp);
+    ALOGV("%s: [%" PRId64 "]: Adding codecOutputBufferTimestamp (%zu timestamps in total)",
+            __FUNCTION__, bufferInfo.mTimestamp, mCodecOutputBufferTimestamps.size());
 }
 
 // We need to get the settings early to handle the case where the codec output
@@ -361,6 +363,8 @@
             mCodecOutputBuffers.push_back(outputBufferInfo);
             mInputReadyCondition.signal();
         } else {
+            ALOGV("%s: Releasing output buffer: size %d flags: 0x%x ", __FUNCTION__,
+                outputBufferInfo.size, outputBufferInfo.flags);
             mCodec->releaseOutputBuffer(outputBufferInfo.index);
         }
     } else {
@@ -414,8 +418,10 @@
         mNumOutputTiles = 1;
     }
 
-    ALOGV("%s: mNumOutputTiles is %zu", __FUNCTION__, mNumOutputTiles);
     mFormat = newFormat;
+
+    ALOGV("%s: mNumOutputTiles is %zu", __FUNCTION__, mNumOutputTiles);
+    mInputReadyCondition.signal();
 }
 
 void HeicCompositeStream::onHeicCodecError() {
@@ -459,9 +465,8 @@
 
     // Cannot use SourceSurface buffer count since it could be codec's 512*512 tile
     // buffer count.
-    int maxProducerBuffers = 1;
     if ((res = native_window_set_buffer_count(
-                    anwConsumer, maxProducerBuffers + maxConsumerBuffers)) != OK) {
+                    anwConsumer, kMaxOutputSurfaceProducerCount + maxConsumerBuffers)) != OK) {
         ALOGE("%s: Unable to set buffer count for stream %d", __FUNCTION__, mMainImageStreamId);
         return res;
     }
@@ -505,6 +510,8 @@
     }
 
     if (mSettingsByFrameNumber.find(resultExtras.frameNumber) != mSettingsByFrameNumber.end()) {
+        ALOGV("%s: [%" PRId64 "]: frameNumber %" PRId64, __FUNCTION__,
+                timestamp, resultExtras.frameNumber);
         mFrameNumberMap.emplace(resultExtras.frameNumber, timestamp);
         mSettingsByTimestamp[timestamp] = mSettingsByFrameNumber[resultExtras.frameNumber];
         mSettingsByFrameNumber.erase(resultExtras.frameNumber);
@@ -593,13 +600,15 @@
         } else {
             // Direct mapping between camera timestamp (in ns) and codec timestamp (in us).
             bufferTime = mCodecOutputBufferTimestamps.front();
-            mOutputBufferCounter++;
-            if (mOutputBufferCounter == mNumOutputTiles) {
+            mCodecOutputCounter++;
+            if (mCodecOutputCounter == mNumOutputTiles) {
                 mCodecOutputBufferTimestamps.pop();
-                mOutputBufferCounter = 0;
+                mCodecOutputCounter = 0;
             }
 
             mPendingInputFrames[bufferTime].codecOutputBuffers.push_back(*it);
+            ALOGV("%s: [%" PRId64 "]: Pushing codecOutputBuffers (time %" PRId64 " us)",
+                    __FUNCTION__, bufferTime, it->timeUs);
         }
         mCodecOutputBuffers.erase(it);
     }
@@ -607,6 +616,7 @@
     while (!mFrameNumberMap.empty()) {
         auto it = mFrameNumberMap.begin();
         mPendingInputFrames[it->second].frameNumber = it->first;
+        ALOGV("%s: [%" PRId64 "]: frameNumber is %" PRId64, __FUNCTION__, it->second, it->first);
         mFrameNumberMap.erase(it);
     }
 
@@ -675,16 +685,29 @@
     }
 
     bool newInputAvailable = false;
-    for (const auto& it : mPendingInputFrames) {
+    for (auto& it : mPendingInputFrames) {
+        // New input is considered to be available only if:
+        // 1. input buffers are ready, or
+        // 2. App segment and muxer is created, or
+        // 3. A codec output tile is ready, and an output buffer is available.
+        // This makes sure that muxer gets created only when an output tile is
+        // generated, because right now we only handle 1 HEIC output buffer at a
+        // time (max dequeued buffer count is 1).
         bool appSegmentReady = (it.second.appSegmentBuffer.data != nullptr) &&
-                !it.second.appSegmentWritten && it.second.result != nullptr;
+                !it.second.appSegmentWritten && it.second.result != nullptr &&
+                it.second.muxer != nullptr;
         bool codecOutputReady = !it.second.codecOutputBuffers.empty();
         bool codecInputReady = (it.second.yuvBuffer.data != nullptr) &&
                 (!it.second.codecInputBuffers.empty());
+        bool hasOutputBuffer = it.second.muxer != nullptr ||
+                (mDequeuedOutputBufferCnt < kMaxOutputSurfaceProducerCount);
         if ((!it.second.error) &&
                 (it.first < *currentTs) &&
-                (appSegmentReady || codecOutputReady || codecInputReady)) {
+                (appSegmentReady || (codecOutputReady && hasOutputBuffer) || codecInputReady)) {
             *currentTs = it.first;
+            if (it.second.format == nullptr && mFormat != nullptr) {
+                it.second.format = mFormat->dup();
+            }
             newInputAvailable = true;
             break;
         }
@@ -716,15 +739,17 @@
     status_t res = OK;
 
     bool appSegmentReady = inputFrame.appSegmentBuffer.data != nullptr &&
-            !inputFrame.appSegmentWritten && inputFrame.result != nullptr;
+            !inputFrame.appSegmentWritten && inputFrame.result != nullptr &&
+            inputFrame.muxer != nullptr;
     bool codecOutputReady = inputFrame.codecOutputBuffers.size() > 0;
     bool codecInputReady = inputFrame.yuvBuffer.data != nullptr &&
-           !inputFrame.codecInputBuffers.empty();
+            !inputFrame.codecInputBuffers.empty();
+    bool hasOutputBuffer = inputFrame.muxer != nullptr ||
+            (mDequeuedOutputBufferCnt < kMaxOutputSurfaceProducerCount);
 
-    if (!appSegmentReady && !codecOutputReady && !codecInputReady) {
-        ALOGW("%s: No valid appSegmentBuffer/codec input/outputBuffer available!", __FUNCTION__);
-        return OK;
-    }
+    ALOGV("%s: [%" PRId64 "]: appSegmentReady %d, codecOutputReady %d, codecInputReady %d,"
+            " dequeuedOutputBuffer %d", __FUNCTION__, timestamp, appSegmentReady,
+            codecOutputReady, codecInputReady, mDequeuedOutputBufferCnt);
 
     // Handle inputs for Hevc tiling
     if (codecInputReady) {
@@ -736,7 +761,13 @@
         }
     }
 
-    // Initialize and start muxer if not yet done so
+    if (!(codecOutputReady && hasOutputBuffer) && !appSegmentReady) {
+        return OK;
+    }
+
+    // Initialize and start muxer if not yet done so. In this case,
+    // codecOutputReady must be true. Otherwise, appSegmentReady is guaranteed
+    // to be false, and the function must have returned early.
     if (inputFrame.muxer == nullptr) {
         res = startMuxerForInputFrame(timestamp, inputFrame);
         if (res != OK) {
@@ -747,7 +778,7 @@
     }
 
     // Write JPEG APP segments data to the muxer.
-    if (appSegmentReady && inputFrame.muxer != nullptr) {
+    if (appSegmentReady) {
         res = processAppSegment(timestamp, inputFrame);
         if (res != OK) {
             ALOGE("%s: Failed to process JPEG APP segments: %s (%d)", __FUNCTION__,
@@ -780,11 +811,6 @@
 
 status_t HeicCompositeStream::startMuxerForInputFrame(nsecs_t timestamp, InputFrame &inputFrame) {
     sp<ANativeWindow> outputANW = mOutputSurface;
-    if (inputFrame.codecOutputBuffers.size() == 0) {
-        // No single codec output buffer has been generated. Continue to
-        // wait.
-        return OK;
-    }
 
     auto res = outputANW->dequeueBuffer(mOutputSurface.get(), &inputFrame.anb, &inputFrame.fenceFd);
     if (res != OK) {
@@ -792,6 +818,7 @@
                 res);
         return res;
     }
+    mDequeuedOutputBufferCnt++;
 
     // Combine current thread id, stream id and timestamp to uniquely identify image.
     std::ostringstream tempOutputFile;
@@ -828,7 +855,7 @@
         }
     }
 
-    ssize_t trackId = inputFrame.muxer->addTrack(mFormat);
+    ssize_t trackId = inputFrame.muxer->addTrack(inputFrame.format);
     if (trackId < 0) {
         ALOGE("%s: Failed to addTrack to the muxer: %zd", __FUNCTION__, trackId);
         return NO_INIT;
@@ -844,6 +871,8 @@
         return res;
     }
 
+    ALOGV("%s: [%" PRId64 "]: Muxer started for inputFrame", __FUNCTION__,
+            timestamp);
     return OK;
 }
 
@@ -852,9 +881,6 @@
     auto appSegmentSize = findAppSegmentsSize(inputFrame.appSegmentBuffer.data,
             inputFrame.appSegmentBuffer.width * inputFrame.appSegmentBuffer.height,
             &app1Size);
-    ALOGV("%s: appSegmentSize is %zu, width %d, height %d, app1Size %zu", __FUNCTION__,
-          appSegmentSize, inputFrame.appSegmentBuffer.width,
-          inputFrame.appSegmentBuffer.height, app1Size);
     if (appSegmentSize == 0) {
         ALOGE("%s: Failed to find JPEG APP segment size", __FUNCTION__);
         return NO_INIT;
@@ -912,6 +938,9 @@
     }
     inputFrame.appSegmentWritten = true;
 
+    ALOGV("%s: [%" PRId64 "]: appSegmentSize is %zu, width %d, height %d, app1Size %zu",
+          __FUNCTION__, timestamp, appSegmentSize, inputFrame.appSegmentBuffer.width,
+          inputFrame.appSegmentBuffer.height, app1Size);
     return OK;
 }
 
@@ -934,8 +963,9 @@
                 mOutputWidth - tileX * mGridWidth : mGridWidth;
         size_t height = (tileY == static_cast<size_t>(mGridRows) - 1) ?
                 mOutputHeight - tileY * mGridHeight : mGridHeight;
-        ALOGV("%s: inputBuffer tileIndex [%zu, %zu], top %zu, left %zu, width %zu, height %zu",
-                __FUNCTION__, tileX, tileY, top, left, width, height);
+        ALOGV("%s: inputBuffer tileIndex [%zu, %zu], top %zu, left %zu, width %zu, height %zu,"
+                " timeUs %" PRId64, __FUNCTION__, tileX, tileY, top, left, width, height,
+                inputBuffer.timeUs);
 
         res = copyOneYuvTile(buffer, inputFrame.yuvBuffer, top, left, width, height);
         if (res != OK) {
@@ -990,6 +1020,9 @@
     }
 
     inputFrame.codecOutputBuffers.erase(inputFrame.codecOutputBuffers.begin());
+
+    ALOGV("%s: [%" PRId64 "]: Output buffer index %d",
+        __FUNCTION__, timestamp, it->index);
     return OK;
 }
 
@@ -1046,7 +1079,9 @@
         return res;
     }
     inputFrame.anb = nullptr;
+    mDequeuedOutputBufferCnt--;
 
+    ALOGV("%s: [%" PRId64 "]", __FUNCTION__, timestamp);
     ATRACE_ASYNC_END("HEIC capture", inputFrame.frameNumber);
     return OK;
 }
diff --git a/services/camera/libcameraservice/api2/HeicCompositeStream.h b/services/camera/libcameraservice/api2/HeicCompositeStream.h
index 260c68e..9bec909 100644
--- a/services/camera/libcameraservice/api2/HeicCompositeStream.h
+++ b/services/camera/libcameraservice/api2/HeicCompositeStream.h
@@ -25,6 +25,7 @@
 #include <media/hardware/VideoAPI.h>
 #include <media/MediaCodecBuffer.h>
 #include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/AMessage.h>
 #include <media/stagefright/MediaCodec.h>
 #include <media/stagefright/MediaMuxer.h>
 
@@ -157,6 +158,7 @@
         bool                      errorNotified;
         int64_t                   frameNumber;
 
+        sp<AMessage>              format;
         sp<MediaMuxer>            muxer;
         int                       fenceFd;
         int                       fileFd;
@@ -218,9 +220,10 @@
     sp<CpuConsumer>   mMainImageConsumer; // Only applicable for HEVC codec.
     bool              mYuvBufferAcquired; // Only applicable to HEVC codec
 
+    static const int32_t kMaxOutputSurfaceProducerCount = 1;
     sp<Surface>       mOutputSurface;
     sp<ProducerListener> mProducerListener;
-
+    int32_t           mDequeuedOutputBufferCnt;
 
     // Map from frame number to JPEG setting of orientation+quality
     std::map<int64_t, std::pair<int32_t, int32_t>> mSettingsByFrameNumber;
@@ -233,7 +236,7 @@
     // Keep all incoming HEIC blob buffer pending further processing.
     std::vector<CodecOutputBufferInfo> mCodecOutputBuffers;
     std::queue<int64_t> mCodecOutputBufferTimestamps;
-    size_t mOutputBufferCounter;
+    size_t mCodecOutputCounter;
 
     // Keep all incoming Yuv buffer pending tiling and encoding (for HEVC YUV tiling only)
     std::vector<int64_t> mInputYuvBuffers;
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index 608521a..7ed4c3d 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -1187,7 +1187,7 @@
     }
 
     sp<provider::V2_4::ICameraProvider> interface;
-    interface = mServiceProxy->getService(newProvider);
+    interface = mServiceProxy->tryGetService(newProvider);
 
     if (interface == nullptr) {
         ALOGE("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 4112711..2ef1f6f 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -96,6 +96,10 @@
                 const std::string &serviceName,
                 const sp<hidl::manager::V1_0::IServiceNotification>
                 &notification) = 0;
+        // Will not wait for service to start if it's not already running
+        virtual sp<hardware::camera::provider::V2_4::ICameraProvider> tryGetService(
+                const std::string &serviceName) = 0;
+        // Will block for service if it exists but isn't running
         virtual sp<hardware::camera::provider::V2_4::ICameraProvider> getService(
                 const std::string &serviceName) = 0;
         virtual hardware::hidl_vec<hardware::hidl_string> listServices() = 0;
@@ -112,6 +116,10 @@
             return hardware::camera::provider::V2_4::ICameraProvider::registerForNotifications(
                     serviceName, notification);
         }
+        virtual sp<hardware::camera::provider::V2_4::ICameraProvider> tryGetService(
+                const std::string &serviceName) override {
+            return hardware::camera::provider::V2_4::ICameraProvider::tryGetService(serviceName);
+        }
         virtual sp<hardware::camera::provider::V2_4::ICameraProvider> getService(
                 const std::string &serviceName) override {
             return hardware::camera::provider::V2_4::ICameraProvider::getService(serviceName);
diff --git a/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp b/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
index 78d737d..084dc62 100644
--- a/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
+++ b/services/camera/libcameraservice/tests/CameraProviderManagerTest.cpp
@@ -183,6 +183,7 @@
     sp<TestICameraProvider> mTestCameraProvider;
 
     TestInteractionProxy() {}
+
     void setProvider(sp<TestICameraProvider> provider) {
         mTestCameraProvider = provider;
     }
@@ -199,13 +200,31 @@
         return true;
     }
 
+    virtual sp<hardware::camera::provider::V2_4::ICameraProvider> tryGetService(
+            const std::string &serviceName) override {
+        // If no provider has been given, act like the HAL isn't available and return null.
+        if (mTestCameraProvider == nullptr) return nullptr;
+        return getService(serviceName);
+    }
+
     virtual sp<hardware::camera::provider::V2_4::ICameraProvider> getService(
             const std::string &serviceName) override {
+        // If no provider has been given, fail; in reality, getService would
+        // block for HALs that don't start correctly, so we should never use
+        // getService when we don't have a valid HAL running
+        if (mTestCameraProvider == nullptr) {
+            ADD_FAILURE() << "getService called with no valid provider; would block indefinitely";
+            // Real getService would block, but that's bad in unit tests. So
+            // just record an error and return nullptr
+            return nullptr;
+        }
         mLastRequestedServiceNames.push_back(serviceName);
         return mTestCameraProvider;
     }
 
     virtual hardware::hidl_vec<hardware::hidl_string> listServices() override {
+        // Always provide a list even if there's no actual provider yet, to
+        // simulate stuck HAL situations as well
         hardware::hidl_vec<hardware::hidl_string> ret = {"test/0"};
         return ret;
     }
@@ -438,3 +457,52 @@
             << "Unable to change device state";
 
 }
+
+// Test that CameraProviderManager doesn't get stuck when the camera HAL isn't really working
+TEST(CameraProviderManagerTest, BadHalStartupTest) {
+
+    std::vector<hardware::hidl_string> deviceNames;
+    deviceNames.push_back("device@3.2/test/0");
+    deviceNames.push_back("device@1.0/test/0");
+    deviceNames.push_back("device@3.2/test/1");
+    hardware::hidl_vec<common::V1_0::VendorTagSection> vendorSection;
+    status_t res;
+
+    sp<CameraProviderManager> providerManager = new CameraProviderManager();
+    sp<TestStatusListener> statusListener = new TestStatusListener();
+    TestInteractionProxy serviceProxy;
+    sp<TestICameraProvider> provider =  new TestICameraProvider(deviceNames,
+            vendorSection);
+
+    // Not setting up provider in the service proxy yet, to test cases where a
+    // HAL isn't starting right
+    res = providerManager->initialize(statusListener, &serviceProxy);
+    ASSERT_EQ(res, OK) << "Unable to initialize provider manager";
+
+    // Now set up provider and trigger a registration
+    serviceProxy.setProvider(provider);
+    int numProviders = static_cast<int>(serviceProxy.listServices().size());
+
+    hardware::hidl_string testProviderFqInterfaceName =
+            "android.hardware.camera.provider@2.4::ICameraProvider";
+    hardware::hidl_string testProviderInstanceName = "test/0";
+    serviceProxy.mManagerNotificationInterface->onRegistration(
+            testProviderFqInterfaceName,
+            testProviderInstanceName, false);
+
+    // Check that new provider is called once for all the init methods
+    EXPECT_EQ(provider->mCalledCounter[TestICameraProvider::SET_CALLBACK], numProviders) <<
+            "Only one call to setCallback per provider expected during register";
+    EXPECT_EQ(provider->mCalledCounter[TestICameraProvider::GET_VENDOR_TAGS], numProviders) <<
+            "Only one call to getVendorTags per provider expected during register";
+    EXPECT_EQ(provider->mCalledCounter[TestICameraProvider::IS_SET_TORCH_MODE_SUPPORTED],
+            numProviders) <<
+            "Only one call to isSetTorchModeSupported per provider expected during init";
+    EXPECT_EQ(provider->mCalledCounter[TestICameraProvider::GET_CAMERA_ID_LIST], numProviders) <<
+            "Only one call to getCameraIdList per provider expected during init";
+    EXPECT_EQ(provider->mCalledCounter[TestICameraProvider::NOTIFY_DEVICE_STATE], numProviders) <<
+            "Only one call to notifyDeviceState per provider expected during init";
+
+    ASSERT_EQ(serviceProxy.mLastRequestedServiceNames.back(), testProviderInstanceName) <<
+            "Incorrect instance requested from service manager";
+}
diff --git a/services/mediaanalytics/statsd_audiopolicy.cpp b/services/mediaanalytics/statsd_audiopolicy.cpp
index 06c4dde..95cb274 100644
--- a/services/mediaanalytics/statsd_audiopolicy.cpp
+++ b/services/mediaanalytics/statsd_audiopolicy.cpp
@@ -60,14 +60,14 @@
         metrics_proto.set_status(status);
     }
     //string char kAudioPolicyRqstSrc[] = "android.media.audiopolicy.rqst.src";
-    char *rqst_src = NULL;
-    if (item->getCString("android.media.audiopolicy.rqst.src", &rqst_src)) {
-        metrics_proto.set_request_source(rqst_src);
+    std::string rqst_src;
+    if (item->getString("android.media.audiopolicy.rqst.src", &rqst_src)) {
+        metrics_proto.set_request_source(std::move(rqst_src));
     }
     //string char kAudioPolicyRqstPkg[] = "android.media.audiopolicy.rqst.pkg";
-    char *rqst_pkg = NULL;
-    if (item->getCString("android.media.audiopolicy.rqst.pkg", &rqst_pkg)) {
-        metrics_proto.set_request_package(rqst_pkg);
+    std::string rqst_pkg;
+    if (item->getString("android.media.audiopolicy.rqst.pkg", &rqst_pkg)) {
+        metrics_proto.set_request_package(std::move(rqst_pkg));
     }
     //int32 char kAudioPolicyRqstSession[] = "android.media.audiopolicy.rqst.session";
     int32_t rqst_session = -1;
@@ -75,20 +75,20 @@
         metrics_proto.set_request_session(rqst_session);
     }
     //string char kAudioPolicyRqstDevice[] = "android.media.audiopolicy.rqst.device";
-    char *rqst_device = NULL;
-    if (item->getCString("android.media.audiopolicy.rqst.device", &rqst_device)) {
-        metrics_proto.set_request_device(rqst_device);
+    std::string rqst_device;
+    if (item->getString("android.media.audiopolicy.rqst.device", &rqst_device)) {
+        metrics_proto.set_request_device(std::move(rqst_device));
     }
 
     //string char kAudioPolicyActiveSrc[] = "android.media.audiopolicy.active.src";
-    char *active_src = NULL;
-    if (item->getCString("android.media.audiopolicy.active.src", &active_src)) {
-        metrics_proto.set_active_source(active_src);
+    std::string active_src;
+    if (item->getString("android.media.audiopolicy.active.src", &active_src)) {
+        metrics_proto.set_active_source(std::move(active_src));
     }
     //string char kAudioPolicyActivePkg[] = "android.media.audiopolicy.active.pkg";
-    char *active_pkg = NULL;
-    if (item->getCString("android.media.audiopolicy.active.pkg", &active_pkg)) {
-        metrics_proto.set_active_package(active_pkg);
+    std::string active_pkg;
+    if (item->getString("android.media.audiopolicy.active.pkg", &active_pkg)) {
+        metrics_proto.set_active_package(std::move(active_pkg));
     }
     //int32 char kAudioPolicyActiveSession[] = "android.media.audiopolicy.active.session";
     int32_t active_session = -1;
@@ -96,9 +96,9 @@
         metrics_proto.set_active_session(active_session);
     }
     //string char kAudioPolicyActiveDevice[] = "android.media.audiopolicy.active.device";
-    char *active_device = NULL;
-    if (item->getCString("android.media.audiopolicy.active.device", &active_device)) {
-        metrics_proto.set_active_device(active_device);
+    std::string active_device;
+    if (item->getString("android.media.audiopolicy.active.device", &active_device)) {
+        metrics_proto.set_active_device(std::move(active_device));
     }
 
 
@@ -119,14 +119,6 @@
         ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
     }
 
-    // must free the strings that we were given
-    free(rqst_src);
-    free(rqst_pkg);
-    free(rqst_device);
-    free(active_src);
-    free(active_pkg);
-    free(active_device);
-
     return true;
 }
 
diff --git a/services/mediaanalytics/statsd_audiorecord.cpp b/services/mediaanalytics/statsd_audiorecord.cpp
index c9edb27..7c7a62c 100644
--- a/services/mediaanalytics/statsd_audiorecord.cpp
+++ b/services/mediaanalytics/statsd_audiorecord.cpp
@@ -54,14 +54,14 @@
 
     // flesh out the protobuf we'll hand off with our data
     //
-    char *encoding = NULL;
-    if (item->getCString("android.media.audiorecord.encoding", &encoding)) {
-        metrics_proto.set_encoding(encoding);
+    std::string encoding;
+    if (item->getString("android.media.audiorecord.encoding", &encoding)) {
+        metrics_proto.set_encoding(std::move(encoding));
     }
 
-    char *source = NULL;
-    if (item->getCString("android.media.audiorecord.source", &source)) {
-        metrics_proto.set_source(source);
+    std::string source;
+    if (item->getString("android.media.audiorecord.source", &source)) {
+        metrics_proto.set_source(std::move(source));
     }
 
     int32_t latency = -1;
@@ -101,11 +101,11 @@
         metrics_proto.set_error_code(errcode);
     }
 
-    char *errfunc = NULL;
-    if (item->getCString("android.media.audiorecord.errfunc", &errfunc)) {
-        metrics_proto.set_error_function(errfunc);
-    } else if (item->getCString("android.media.audiorecord.lastError.at", &errfunc)) {
-        metrics_proto.set_error_function(errfunc);
+    std::string errfunc;
+    if (item->getString("android.media.audiorecord.errfunc", &errfunc)) {
+        metrics_proto.set_error_function(std::move(errfunc));
+    } else if (item->getString("android.media.audiorecord.lastError.at", &errfunc)) {
+        metrics_proto.set_error_function(std::move(errfunc));
     }
 
     // portId (int32)
@@ -119,9 +119,9 @@
         metrics_proto.set_frame_count(frameCount);
     }
     // attributes (string)
-    char *attributes = NULL;
-    if (item->getCString("android.media.audiorecord.attributes", &attributes)) {
-        metrics_proto.set_attributes(attributes);
+    std::string attributes;
+    if (item->getString("android.media.audiorecord.attributes", &attributes)) {
+        metrics_proto.set_attributes(std::move(attributes));
     }
     // channelMask (int64)
     int64_t channelMask = -1;
@@ -152,12 +152,6 @@
         ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
     }
 
-    // must free the strings that we were given
-    free(encoding);
-    free(source);
-    free(errfunc);
-    free(attributes);
-
     return true;
 }
 
diff --git a/services/mediaanalytics/statsd_audiothread.cpp b/services/mediaanalytics/statsd_audiothread.cpp
index 8232424..e9d6b17 100644
--- a/services/mediaanalytics/statsd_audiothread.cpp
+++ b/services/mediaanalytics/statsd_audiothread.cpp
@@ -56,9 +56,9 @@
 
     // flesh out the protobuf we'll hand off with our data
     //
-    char *mytype = NULL;
-    if (item->getCString(MM_PREFIX "type", &mytype)) {
-        metrics_proto.set_type(mytype);
+    std::string mytype;
+    if (item->getString(MM_PREFIX "type", &mytype)) {
+        metrics_proto.set_type(std::move(mytype));
     }
     int32_t framecount = -1;
     if (item->getInt32(MM_PREFIX "framecount", &framecount)) {
@@ -68,17 +68,17 @@
     if (item->getInt32(MM_PREFIX "samplerate", &samplerate)) {
         metrics_proto.set_samplerate(samplerate);
     }
-    char *workhist = NULL;
-    if (item->getCString(MM_PREFIX "workMs.hist", &workhist)) {
-        metrics_proto.set_work_millis_hist(workhist);
+    std::string workhist;
+    if (item->getString(MM_PREFIX "workMs.hist", &workhist)) {
+        metrics_proto.set_work_millis_hist(std::move(workhist));
     }
-    char *latencyhist = NULL;
-    if (item->getCString(MM_PREFIX "latencyMs.hist", &latencyhist)) {
-        metrics_proto.set_latency_millis_hist(latencyhist);
+    std::string latencyhist;
+    if (item->getString(MM_PREFIX "latencyMs.hist", &latencyhist)) {
+        metrics_proto.set_latency_millis_hist(std::move(latencyhist));
     }
-    char *warmuphist = NULL;
-    if (item->getCString(MM_PREFIX "warmupMs.hist", &warmuphist)) {
-        metrics_proto.set_warmup_millis_hist(warmuphist);
+    std::string warmuphist;
+    if (item->getString(MM_PREFIX "warmupMs.hist", &warmuphist)) {
+        metrics_proto.set_warmup_millis_hist(std::move(warmuphist));
     }
     int64_t underruns = -1;
     if (item->getInt64(MM_PREFIX "underruns", &underruns)) {
@@ -108,9 +108,9 @@
         metrics_proto.set_port_id(port_id);
     }
     // item->setCString(MM_PREFIX "type", threadTypeToString(mType));
-    char *type = NULL;
-    if (item->getCString(MM_PREFIX "type", &type)) {
-        metrics_proto.set_type(type);
+    std::string type;
+    if (item->getString(MM_PREFIX "type", &type)) {
+        metrics_proto.set_type(std::move(type));
     }
     // item->setInt32(MM_PREFIX "sampleRate", (int32_t)mSampleRate);
     int32_t sample_rate = -1;
@@ -123,9 +123,9 @@
         metrics_proto.set_channel_mask(channel_mask);
     }
     // item->setCString(MM_PREFIX "encoding", toString(mFormat).c_str());
-    char *encoding = NULL;
-    if (item->getCString(MM_PREFIX "encoding", &encoding)) {
-        metrics_proto.set_encoding(encoding);
+    std::string encoding;
+    if (item->getString(MM_PREFIX "encoding", &encoding)) {
+        metrics_proto.set_encoding(std::move(encoding));
     }
     // item->setInt32(MM_PREFIX "frameCount", (int32_t)mFrameCount);
     int32_t frame_count = -1;
@@ -133,14 +133,14 @@
         metrics_proto.set_frame_count(frame_count);
     }
     // item->setCString(MM_PREFIX "outDevice", toString(mOutDevice).c_str());
-    char *outDevice = NULL;
-    if (item->getCString(MM_PREFIX "outDevice", &outDevice)) {
-        metrics_proto.set_output_device(outDevice);
+    std::string outDevice;
+    if (item->getString(MM_PREFIX "outDevice", &outDevice)) {
+        metrics_proto.set_output_device(std::move(outDevice));
     }
     // item->setCString(MM_PREFIX "inDevice", toString(mInDevice).c_str());
-    char *inDevice = NULL;
-    if (item->getCString(MM_PREFIX "inDevice", &inDevice)) {
-        metrics_proto.set_input_device(inDevice);
+    std::string inDevice;
+    if (item->getString(MM_PREFIX "inDevice", &inDevice)) {
+        metrics_proto.set_input_device(std::move(inDevice));
     }
     // item->setDouble(MM_PREFIX "ioJitterMs.mean", mIoJitterMs.getMean());
     double iojitters_ms_mean = -1;
@@ -201,16 +201,6 @@
         ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
     }
 
-    // must free the strings that we were given
-    free(mytype);
-    free(workhist);
-    free(latencyhist);
-    free(warmuphist);
-    free(type);
-    free(encoding);
-    free(inDevice);
-    free(outDevice);
-
     return true;
 }
 
diff --git a/services/mediaanalytics/statsd_audiotrack.cpp b/services/mediaanalytics/statsd_audiotrack.cpp
index f250ced..57cda99 100644
--- a/services/mediaanalytics/statsd_audiotrack.cpp
+++ b/services/mediaanalytics/statsd_audiotrack.cpp
@@ -57,23 +57,23 @@
 
     // static constexpr char kAudioTrackStreamType[] = "android.media.audiotrack.streamtype";
     // optional string streamType;
-    char *streamtype = NULL;
-    if (item->getCString("android.media.audiotrack.streamtype", &streamtype)) {
-        metrics_proto.set_stream_type(streamtype);
+    std::string streamtype;
+    if (item->getString("android.media.audiotrack.streamtype", &streamtype)) {
+        metrics_proto.set_stream_type(std::move(streamtype));
     }
 
     // static constexpr char kAudioTrackContentType[] = "android.media.audiotrack.type";
     // optional string contentType;
-    char *contenttype = NULL;
-    if (item->getCString("android.media.audiotrack.type", &contenttype)) {
-        metrics_proto.set_content_type(contenttype);
+    std::string contenttype;
+    if (item->getString("android.media.audiotrack.type", &contenttype)) {
+        metrics_proto.set_content_type(std::move(contenttype));
     }
 
     // static constexpr char kAudioTrackUsage[] = "android.media.audiotrack.usage";
     // optional string trackUsage;
-    char *trackusage = NULL;
-    if (item->getCString("android.media.audiotrack.usage", &trackusage)) {
-        metrics_proto.set_track_usage(trackusage);
+    std::string trackusage;
+    if (item->getString("android.media.audiotrack.usage", &trackusage)) {
+        metrics_proto.set_track_usage(std::move(trackusage));
     }
 
     // static constexpr char kAudioTrackSampleRate[] = "android.media.audiotrack.samplerate";
@@ -111,9 +111,9 @@
         metrics_proto.set_port_id(port_id);
     }
     // encoding (string)
-    char *encoding = NULL;
-    if (item->getCString("android.media.audiotrack.encoding", &encoding)) {
-        metrics_proto.set_encoding(encoding);
+    std::string encoding;
+    if (item->getString("android.media.audiotrack.encoding", &encoding)) {
+        metrics_proto.set_encoding(std::move(encoding));
     }
     // frameCount (int32)
     int32_t frame_count = -1;
@@ -121,9 +121,9 @@
         metrics_proto.set_frame_count(frame_count);
     }
     // attributes (string)
-    char *attributes = NULL;
-    if (item->getCString("android.media.audiotrack.attributes", &attributes)) {
-        metrics_proto.set_attributes(attributes);
+    std::string attributes;
+    if (item->getString("android.media.audiotrack.attributes", &attributes)) {
+        metrics_proto.set_attributes(std::move(attributes));
     }
 
     std::string serialized;
@@ -143,13 +143,6 @@
         ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
     }
 
-    // must free the strings that we were given
-    free(streamtype);
-    free(contenttype);
-    free(trackusage);
-    free(encoding);
-    free(attributes);
-
     return true;
 }
 
diff --git a/services/mediaanalytics/statsd_codec.cpp b/services/mediaanalytics/statsd_codec.cpp
index dc8e4ef..bf82e50 100644
--- a/services/mediaanalytics/statsd_codec.cpp
+++ b/services/mediaanalytics/statsd_codec.cpp
@@ -55,19 +55,19 @@
     // flesh out the protobuf we'll hand off with our data
     //
     // android.media.mediacodec.codec   string
-    char *codec = NULL;
-    if (item->getCString("android.media.mediacodec.codec", &codec)) {
-        metrics_proto.set_codec(codec);
+    std::string codec;
+    if (item->getString("android.media.mediacodec.codec", &codec)) {
+        metrics_proto.set_codec(std::move(codec));
     }
     // android.media.mediacodec.mime    string
-    char *mime = NULL;
-    if (item->getCString("android.media.mediacodec.mime", &mime)) {
-        metrics_proto.set_mime(mime);
+    std::string mime;
+    if (item->getString("android.media.mediacodec.mime", &mime)) {
+        metrics_proto.set_mime(std::move(mime));
     }
     // android.media.mediacodec.mode    string
-    char *mode = NULL;
-    if ( item->getCString("android.media.mediacodec.mode", &mode)) {
-        metrics_proto.set_mode(mode);
+    std::string mode;
+    if ( item->getString("android.media.mediacodec.mode", &mode)) {
+        metrics_proto.set_mode(std::move(mode));
     }
     // android.media.mediacodec.encoder int32
     int32_t encoder = -1;
@@ -125,9 +125,9 @@
         metrics_proto.set_error_code(errcode);
     }
     // android.media.mediacodec.errstate        string
-    char *errstate = NULL;
-    if ( item->getCString("android.media.mediacodec.errstate", &errstate)) {
-        metrics_proto.set_error_state(errstate);
+    std::string errstate;
+    if ( item->getString("android.media.mediacodec.errstate", &errstate)) {
+        metrics_proto.set_error_state(std::move(errstate));
     }
     // android.media.mediacodec.latency.max  int64
     int64_t latency_max = -1;
@@ -173,12 +173,6 @@
         ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
     }
 
-    // must free the strings that we were given
-    free(codec);
-    free(mime);
-    free(mode);
-    free(errstate);
-
     return true;
 }
 
diff --git a/services/mediaanalytics/statsd_extractor.cpp b/services/mediaanalytics/statsd_extractor.cpp
index 395c912..d84930c 100644
--- a/services/mediaanalytics/statsd_extractor.cpp
+++ b/services/mediaanalytics/statsd_extractor.cpp
@@ -56,14 +56,14 @@
     //
 
     // android.media.mediaextractor.fmt         string
-    char *fmt = NULL;
-    if (item->getCString("android.media.mediaextractor.fmt", &fmt)) {
-        metrics_proto.set_format(fmt);
+    std::string fmt;
+    if (item->getString("android.media.mediaextractor.fmt", &fmt)) {
+        metrics_proto.set_format(std::move(fmt));
     }
     // android.media.mediaextractor.mime        string
-    char *mime = NULL;
-    if (item->getCString("android.media.mediaextractor.mime", &mime)) {
-        metrics_proto.set_mime(mime);
+    std::string mime;
+    if (item->getString("android.media.mediaextractor.mime", &mime)) {
+        metrics_proto.set_mime(std::move(mime));
     }
     // android.media.mediaextractor.ntrk        int32
     int32_t ntrk = -1;
@@ -88,10 +88,6 @@
         ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
     }
 
-    // must free the strings that we were given
-    free(fmt);
-    free(mime);
-
     return true;
 }
 
diff --git a/services/mediaanalytics/statsd_nuplayer.cpp b/services/mediaanalytics/statsd_nuplayer.cpp
index 5ec118a..e6e0f2c 100644
--- a/services/mediaanalytics/statsd_nuplayer.cpp
+++ b/services/mediaanalytics/statsd_nuplayer.cpp
@@ -62,13 +62,13 @@
     // differentiate between nuplayer and nuplayer2
     metrics_proto.set_whichplayer(item->getKey().c_str());
 
-    char *video_mime = NULL;
-    if (item->getCString("android.media.mediaplayer.video.mime", &video_mime)) {
-        metrics_proto.set_video_mime(video_mime);
+    std::string video_mime;
+    if (item->getString("android.media.mediaplayer.video.mime", &video_mime)) {
+        metrics_proto.set_video_mime(std::move(video_mime));
     }
-    char *video_codec = NULL;
-    if (item->getCString("android.media.mediaplayer.video.codec", &video_codec)) {
-        metrics_proto.set_video_codec(video_codec);
+    std::string video_codec;
+    if (item->getString("android.media.mediaplayer.video.codec", &video_codec)) {
+        metrics_proto.set_video_codec(std::move(video_codec));
     }
 
     int32_t width = -1;
@@ -97,13 +97,13 @@
         metrics_proto.set_framerate(fps);
     }
 
-    char *audio_mime = NULL;
-    if (item->getCString("android.media.mediaplayer.audio.mime", &audio_mime)) {
-        metrics_proto.set_audio_mime(audio_mime);
+    std::string audio_mime;
+    if (item->getString("android.media.mediaplayer.audio.mime", &audio_mime)) {
+        metrics_proto.set_audio_mime(std::move(audio_mime));
     }
-    char *audio_codec = NULL;
-    if (item->getCString("android.media.mediaplayer.audio.codec", &audio_codec)) {
-        metrics_proto.set_audio_codec(audio_codec);
+    std::string audio_codec;
+    if (item->getString("android.media.mediaplayer.audio.codec", &audio_codec)) {
+        metrics_proto.set_audio_codec(std::move(audio_codec));
     }
 
     int64_t duration_ms = -1;
@@ -123,14 +123,14 @@
     if (item->getInt32("android.media.mediaplayer.errcode", &error_code)) {
         metrics_proto.set_error_code(error_code);
     }
-    char *error_state = NULL;
-    if (item->getCString("android.media.mediaplayer.errstate", &error_state)) {
-        metrics_proto.set_error_state(error_state);
+    std::string error_state;
+    if (item->getString("android.media.mediaplayer.errstate", &error_state)) {
+        metrics_proto.set_error_state(std::move(error_state));
     }
 
-    char *data_source_type = NULL;
-    if (item->getCString("android.media.mediaplayer.dataSource", &data_source_type)) {
-        metrics_proto.set_data_source_type(data_source_type);
+    std::string data_source_type;
+    if (item->getString("android.media.mediaplayer.dataSource", &data_source_type)) {
+        metrics_proto.set_data_source_type(std::move(data_source_type));
     }
 
     int64_t rebufferingMs = -1;
@@ -164,14 +164,6 @@
         ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
     }
 
-    // must free the strings that we were given
-    free(video_mime);
-    free(video_codec);
-    free(audio_mime);
-    free(audio_codec);
-    free(error_state);
-    free(data_source_type);
-
     return true;
 }
 
diff --git a/services/mediaanalytics/statsd_recorder.cpp b/services/mediaanalytics/statsd_recorder.cpp
index 4d981b4..d286f00 100644
--- a/services/mediaanalytics/statsd_recorder.cpp
+++ b/services/mediaanalytics/statsd_recorder.cpp
@@ -56,14 +56,14 @@
     //
 
     // string kRecorderAudioMime = "android.media.mediarecorder.audio.mime";
-    char *audio_mime = NULL;
-    if (item->getCString("android.media.mediarecorder.audio.mime", &audio_mime)) {
-        metrics_proto.set_audio_mime(audio_mime);
+    std::string audio_mime;
+    if (item->getString("android.media.mediarecorder.audio.mime", &audio_mime)) {
+        metrics_proto.set_audio_mime(std::move(audio_mime));
     }
     // string kRecorderVideoMime = "android.media.mediarecorder.video.mime";
-    char *video_mime = NULL;
-    if (item->getCString("android.media.mediarecorder.video.mime", &video_mime)) {
-        metrics_proto.set_video_mime(video_mime);
+    std::string video_mime;
+    if (item->getString("android.media.mediarecorder.video.mime", &video_mime)) {
+        metrics_proto.set_video_mime(std::move(video_mime));
     }
     // int32 kRecorderVideoProfile = "android.media.mediarecorder.video-encoder-profile";
     int32_t videoProfile = -1;
@@ -183,10 +183,6 @@
         ALOGV("NOT sending: private data (len=%zu)", strlen(serialized.c_str()));
     }
 
-    // must free the strings that we were given
-    free(audio_mime);
-    free(video_mime);
-
     return true;
 }
 
diff --git a/services/mediadrm/Android.mk b/services/mediadrm/Android.mk
index 707a2aa..72d42ae 100644
--- a/services/mediadrm/Android.mk
+++ b/services/mediadrm/Android.mk
@@ -21,6 +21,7 @@
     main_mediadrmserver.cpp
 
 LOCAL_HEADER_LIBRARIES:= \
+    libmedia_headers \
     libmediadrm_headers
 
 LOCAL_SHARED_LIBRARIES:= \
diff --git a/services/medialog/Android.bp b/services/medialog/Android.bp
index bee5d25..74b63d5 100644
--- a/services/medialog/Android.bp
+++ b/services/medialog/Android.bp
@@ -6,6 +6,10 @@
         "MediaLogService.cpp",
     ],
 
+    header_libs: [
+        "libmedia_headers",
+    ],
+
     shared_libs: [
         "libaudioutils",
         "libbinder",