Merge "audio policy: fix global effect attachment" into oc-dev
diff --git a/drm/libmediadrm/CasImpl.cpp b/drm/libmediadrm/CasImpl.cpp
index fcedd6b..1a33bb0 100644
--- a/drm/libmediadrm/CasImpl.cpp
+++ b/drm/libmediadrm/CasImpl.cpp
@@ -113,36 +113,15 @@
     return getBinderStatus(holder->get()->setPrivateData(pvtData));
 }
 
-Status CasImpl::openSession(int32_t program_number, CasSessionId* sessionId) {
-    ALOGV("openSession: program_number=%d", program_number);
+Status CasImpl::openSession(CasSessionId* sessionId) {
+    ALOGV("openSession");
     sp<PluginHolder> holder = mPluginHolder;
     if (holder == NULL) {
         return getBinderStatus(INVALID_OPERATION);
     }
-    status_t err = holder->get()->openSession(program_number, sessionId);
+    status_t err = holder->get()->openSession(sessionId);
 
-    ALOGV("openSession: session opened for program_number=%d, sessionId=%s",
-            program_number, sessionIdToString(*sessionId).string());
-
-    return getBinderStatus(err);
-}
-
-Status CasImpl::openSessionForStream(
-        int32_t program_number,
-        int32_t elementary_PID,
-        CasSessionId* sessionId) {
-    ALOGV("openSession: program_number=%d, elementary_PID=%d",
-            program_number, elementary_PID);
-    sp<PluginHolder> holder = mPluginHolder;
-    if (holder == NULL) {
-        return getBinderStatus(INVALID_OPERATION);
-    }
-    status_t err = holder->get()->openSession(
-            program_number, elementary_PID, sessionId);
-
-    ALOGV("openSession: session opened for "
-            "program_number=%d, elementary_PID=%d, sessionId=%s",
-            program_number, elementary_PID,
+    ALOGV("openSession: session opened, sessionId=%s",
             sessionIdToString(*sessionId).string());
 
     return getBinderStatus(err);
diff --git a/drm/libmediadrm/CryptoHal.cpp b/drm/libmediadrm/CryptoHal.cpp
index 25c16da..d613a5b 100644
--- a/drm/libmediadrm/CryptoHal.cpp
+++ b/drm/libmediadrm/CryptoHal.cpp
@@ -134,7 +134,7 @@
 
     if (factories.size() == 0) {
         // must be in passthrough mode, load the default passthrough service
-        auto passthrough = ICryptoFactory::getService("crypto");
+        auto passthrough = ICryptoFactory::getService();
         if (passthrough != NULL) {
             ALOGI("makeCryptoFactories: using default crypto instance");
             factories.push_back(passthrough);
diff --git a/drm/libmediadrm/DrmHal.cpp b/drm/libmediadrm/DrmHal.cpp
index ddbc83d..3596f12 100644
--- a/drm/libmediadrm/DrmHal.cpp
+++ b/drm/libmediadrm/DrmHal.cpp
@@ -220,7 +220,7 @@
 
     if (factories.size() == 0) {
         // must be in passthrough mode, load the default passthrough service
-        auto passthrough = IDrmFactory::getService("drm");
+        auto passthrough = IDrmFactory::getService();
         if (passthrough != NULL) {
             ALOGI("makeDrmFactories: using default drm instance");
             factories.push_back(passthrough);
diff --git a/drm/libmediadrm/aidl/android/media/ICas.aidl b/drm/libmediadrm/aidl/android/media/ICas.aidl
index 6b2ce4a..9746593 100644
--- a/drm/libmediadrm/aidl/android/media/ICas.aidl
+++ b/drm/libmediadrm/aidl/android/media/ICas.aidl
@@ -21,8 +21,7 @@
 /** @hide */
 interface ICas {
     void setPrivateData(in byte[] pvtData);
-    byte[] openSession(int program_number);
-    byte[] openSessionForStream(int program_number, int elementary_PID);
+    byte[] openSession();
     void closeSession(in byte[] sessionId);
     void setSessionPrivateData(in byte[] sessionId, in byte[] pvtData);
     void processEcm(in byte[] sessionId, in MediaCas.ParcelableCasData ecm);
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
index f4c3577..4ed5fce 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp
@@ -110,23 +110,10 @@
     return result;
 }
 
-status_t ClearKeyCasPlugin::openSession(
-        uint16_t program_number, CasSessionId* sessionId) {
-    ALOGV("openSession: program_number=%u", program_number);
+status_t ClearKeyCasPlugin::openSession(CasSessionId* sessionId) {
+    ALOGV("openSession");
 
-    return ClearKeySessionLibrary::get()->addSession(
-            this, program_number, 0, sessionId);
-}
-
-status_t ClearKeyCasPlugin::openSession(
-        uint16_t program_number,
-        uint16_t elementary_PID,
-        CasSessionId *sessionId) {
-    ALOGV("openSession: program_number=%u, elementary_PID=%u",
-            program_number, elementary_PID);
-
-    return ClearKeySessionLibrary::get()->addSession(
-            this, program_number, elementary_PID, sessionId);
+    return ClearKeySessionLibrary::get()->addSession(this, sessionId);
 }
 
 status_t ClearKeyCasPlugin::closeSession(const CasSessionId &sessionId) {
diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
index 8cf9b90..b7134e4 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
+++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h
@@ -68,13 +68,7 @@
     virtual status_t setPrivateData(
             const CasData &data) override;
 
-    virtual status_t openSession(
-            uint16_t program_number, CasSessionId *sessionId) override;
-
-    virtual status_t openSession(
-            uint16_t program_number,
-            uint16_t elementary_PID,
-            CasSessionId *sessionId) override;
+    virtual status_t openSession(CasSessionId *sessionId) override;
 
     virtual status_t closeSession(
             const CasSessionId &sessionId) override;
diff --git a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp
index 4e5f479..faea008 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp
+++ b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp
@@ -29,29 +29,14 @@
 Mutex ClearKeySessionLibrary::sSingletonLock;
 ClearKeySessionLibrary* ClearKeySessionLibrary::sSingleton = NULL;
 
-inline bool operator < (
-        const SessionInfo& lhs, const SessionInfo& rhs) {
-    if (lhs.plugin < rhs.plugin) return true;
-    else if (lhs.plugin > rhs.plugin) return false;
-
-    if (lhs.program_number < rhs.program_number) return true;
-    else if (lhs.program_number > rhs.program_number) return false;
-
-    return lhs.elementary_PID < rhs.elementary_PID;
-}
-
-ClearKeyCasSession::ClearKeyCasSession(const SessionInfo &info)
-    : mSessionInfo(info) {
+ClearKeyCasSession::ClearKeyCasSession(CasPlugin *plugin)
+    : mPlugin(plugin) {
     mKeyInfo[0].valid = mKeyInfo[1].valid = false;
 }
 
 ClearKeyCasSession::~ClearKeyCasSession() {
 }
 
-const SessionInfo& ClearKeyCasSession::getSessionInfo() const {
-    return mSessionInfo;
-}
-
 ClearKeySessionLibrary* ClearKeySessionLibrary::get() {
     Mutex::Autolock lock(sSingletonLock);
 
@@ -66,24 +51,12 @@
 ClearKeySessionLibrary::ClearKeySessionLibrary() : mNextSessionId(1) {}
 
 status_t ClearKeySessionLibrary::addSession(
-        CasPlugin *plugin,
-        uint16_t program_number,
-        uint16_t elementary_PID,
-        CasSessionId *sessionId) {
+        CasPlugin *plugin, CasSessionId *sessionId) {
     CHECK(sessionId);
 
     Mutex::Autolock lock(mSessionsLock);
 
-    SessionInfo info = {plugin, program_number, elementary_PID};
-    ssize_t index = mSessionInfoToIDMap.indexOfKey(info);
-    if (index >= 0) {
-        ALOGW("Session already exists: program_number=%u, elementary_PID=%u",
-                program_number, elementary_PID);
-        *sessionId = mSessionInfoToIDMap[index];
-        return OK;
-    }
-
-    sp<ClearKeyCasSession> session = new ClearKeyCasSession(info);
+    sp<ClearKeyCasSession> session = new ClearKeyCasSession(plugin);
 
     uint8_t *byteArray = (uint8_t *) &mNextSessionId;
     sessionId->push_back(byteArray[3]);
@@ -92,7 +65,6 @@
     sessionId->push_back(byteArray[0]);
     mNextSessionId++;
 
-    mSessionInfoToIDMap.add(info, *sessionId);
     mIDToSessionMap.add(*sessionId, session);
     return OK;
 }
@@ -117,19 +89,16 @@
     }
 
     sp<ClearKeyCasSession> session = mIDToSessionMap.valueAt(index);
-    mSessionInfoToIDMap.removeItem(session->getSessionInfo());
     mIDToSessionMap.removeItemsAt(index);
 }
 
 void ClearKeySessionLibrary::destroyPlugin(CasPlugin *plugin) {
     Mutex::Autolock lock(mSessionsLock);
 
-    for (ssize_t index = mSessionInfoToIDMap.size() - 1; index >= 0; index--) {
-        const SessionInfo &info = mSessionInfoToIDMap.keyAt(index);
-        if (info.plugin == plugin) {
-            const CasSessionId &id = mSessionInfoToIDMap.valueAt(index);
-            mIDToSessionMap.removeItem(id);
-            mSessionInfoToIDMap.removeItemsAt(index);
+    for (ssize_t index = mIDToSessionMap.size() - 1; index >= 0; index--) {
+        sp<ClearKeyCasSession> session = mIDToSessionMap.valueAt(index);
+        if (session->getPlugin() == plugin) {
+            mIDToSessionMap.removeItemsAt(index);
         }
     }
 }
diff --git a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h
index ebefa72..01f5f47 100644
--- a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h
+++ b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h
@@ -30,12 +30,6 @@
 namespace clearkeycas {
 class KeyFetcher;
 
-struct SessionInfo {
-    CasPlugin *plugin;
-    uint16_t program_number;
-    uint16_t elementary_PID;
-};
-
 class ClearKeyCasSession : public RefBase {
 public:
     ssize_t decrypt(
@@ -59,14 +53,14 @@
     };
     sp<ABuffer> mEcmBuffer;
     Mutex mKeyLock;
-    SessionInfo mSessionInfo;
+    CasPlugin* mPlugin;
     KeyInfo mKeyInfo[kNumKeys];
 
     friend class ClearKeySessionLibrary;
 
-    explicit ClearKeyCasSession(const SessionInfo &info);
+    explicit ClearKeyCasSession(CasPlugin *plugin);
     virtual ~ClearKeyCasSession();
-    const SessionInfo& getSessionInfo() const;
+    CasPlugin* getPlugin() const { return mPlugin; }
     status_t decryptPayload(
             const AES_KEY& key, size_t length, size_t offset, char* buffer) const;
 
@@ -77,11 +71,7 @@
 public:
     static ClearKeySessionLibrary* get();
 
-    status_t addSession(
-            CasPlugin *plugin,
-            uint16_t program_number,
-            uint16_t elementary_PID,
-            CasSessionId *sessionId);
+    status_t addSession(CasPlugin *plugin, CasSessionId *sessionId);
 
     sp<ClearKeyCasSession> findSession(const CasSessionId& sessionId);
 
@@ -96,7 +86,6 @@
     Mutex mSessionsLock;
     uint32_t mNextSessionId;
     KeyedVector<CasSessionId, sp<ClearKeyCasSession>> mIDToSessionMap;
-    KeyedVector<SessionInfo, CasSessionId> mSessionInfoToIDMap;
 
     ClearKeySessionLibrary();
     DISALLOW_EVIL_CONSTRUCTORS(ClearKeySessionLibrary);
diff --git a/drm/mediacas/plugins/mock/MockCasPlugin.cpp b/drm/mediacas/plugins/mock/MockCasPlugin.cpp
index 12cac60..18cd9a4 100644
--- a/drm/mediacas/plugins/mock/MockCasPlugin.cpp
+++ b/drm/mediacas/plugins/mock/MockCasPlugin.cpp
@@ -103,22 +103,9 @@
     return OK;
 }
 
-status_t MockCasPlugin::openSession(
-        uint16_t program_number, CasSessionId* sessionId) {
-    ALOGV("openSession: program_number=%u", program_number);
-    return MockSessionLibrary::get()->addSession(
-            this, program_number, 0, sessionId);
-}
-
-status_t MockCasPlugin::openSession(
-        uint16_t program_number,
-        uint16_t elementary_PID,
-        CasSessionId *sessionId) {
-    ALOGV("openSession: program_number=%u, elementary_PID=%u",
-            program_number, elementary_PID);
-
-    return MockSessionLibrary::get()->addSession(
-            this, program_number, elementary_PID, sessionId);
+status_t MockCasPlugin::openSession(CasSessionId* sessionId) {
+    ALOGV("openSession");
+    return MockSessionLibrary::get()->addSession(this, sessionId);
 }
 
 status_t MockCasPlugin::closeSession(const CasSessionId &sessionId) {
diff --git a/drm/mediacas/plugins/mock/MockCasPlugin.h b/drm/mediacas/plugins/mock/MockCasPlugin.h
index 91c8855..9632492 100644
--- a/drm/mediacas/plugins/mock/MockCasPlugin.h
+++ b/drm/mediacas/plugins/mock/MockCasPlugin.h
@@ -63,13 +63,7 @@
     virtual status_t setPrivateData(
             const CasData &data) override;
 
-    virtual status_t openSession(
-            uint16_t program_number, CasSessionId *sessionId) override;
-
-    virtual status_t openSession(
-            uint16_t program_number,
-            uint16_t elementary_PID,
-            CasSessionId *sessionId) override;
+    virtual status_t openSession(CasSessionId *sessionId) override;
 
     virtual status_t closeSession(
             const CasSessionId &sessionId) override;
diff --git a/drm/mediacas/plugins/mock/MockSessionLibrary.cpp b/drm/mediacas/plugins/mock/MockSessionLibrary.cpp
index 8679a04..a7ee9a0 100644
--- a/drm/mediacas/plugins/mock/MockSessionLibrary.cpp
+++ b/drm/mediacas/plugins/mock/MockSessionLibrary.cpp
@@ -26,26 +26,6 @@
 Mutex MockSessionLibrary::sSingletonLock;
 MockSessionLibrary* MockSessionLibrary::sSingleton = NULL;
 
-inline bool operator < (
-        const SessionInfo& lhs,
-        const SessionInfo& rhs) {
-    if (lhs.plugin < rhs.plugin) return true;
-    else if (lhs.plugin > rhs.plugin) return false;
-
-    if (lhs.program_number < rhs.program_number) return true;
-    else if (lhs.program_number > rhs.program_number) return false;
-
-    return lhs.elementary_PID < rhs.elementary_PID;
-}
-
-void MockCasSession::setSessionInfo(const SessionInfo &info) {
-    mSessionInfo = info;
-}
-
-const SessionInfo& MockCasSession::getSessionInfo() const {
-    return mSessionInfo;
-}
-
 MockSessionLibrary* MockSessionLibrary::get() {
     Mutex::Autolock lock(sSingletonLock);
 
@@ -60,23 +40,10 @@
 MockSessionLibrary::MockSessionLibrary() : mNextSessionId(1) {}
 
 status_t MockSessionLibrary::addSession(
-        CasPlugin *plugin,
-        uint16_t program_number,
-        uint16_t elementary_PID,
-        CasSessionId *sessionId) {
+        CasPlugin *plugin, CasSessionId *sessionId) {
     Mutex::Autolock lock(mSessionsLock);
 
-    SessionInfo info = {plugin, program_number, elementary_PID};
-    ssize_t index = mSessionInfoToIDMap.indexOfKey(info);
-    if (index >= 0) {
-        ALOGW("Session already exists: program_number=%u, elementary_PID=%u",
-                program_number, elementary_PID);
-        *sessionId = mSessionInfoToIDMap[index];
-        return OK;
-    }
-
-    sp<MockCasSession> session = new MockCasSession();
-    session->setSessionInfo(info);
+    sp<MockCasSession> session = new MockCasSession(plugin);
 
     uint8_t *byteArray = (uint8_t *) &mNextSessionId;
     sessionId->push_back(byteArray[3]);
@@ -85,7 +52,6 @@
     sessionId->push_back(byteArray[0]);
     mNextSessionId++;
 
-    mSessionInfoToIDMap.add(info, *sessionId);
     mIDToSessionMap.add(*sessionId, session);
     return OK;
 }
@@ -110,19 +76,16 @@
     }
 
     sp<MockCasSession> session = mIDToSessionMap.valueAt(index);
-    mSessionInfoToIDMap.removeItem(session->getSessionInfo());
     mIDToSessionMap.removeItemsAt(index);
 }
 
 void MockSessionLibrary::destroyPlugin(CasPlugin *plugin) {
     Mutex::Autolock lock(mSessionsLock);
 
-    for (ssize_t index = mSessionInfoToIDMap.size() - 1; index >= 0; index--) {
-        const SessionInfo &info = mSessionInfoToIDMap.keyAt(index);
-        if (info.plugin == plugin) {
-            const CasSessionId &id = mSessionInfoToIDMap.valueAt(index);
-            mIDToSessionMap.removeItem(id);
-            mSessionInfoToIDMap.removeItemsAt(index);
+    for (ssize_t index = mIDToSessionMap.size() - 1; index >= 0; index--) {
+        sp<MockCasSession> session = mIDToSessionMap.valueAt(index);
+        if (session->getPlugin() == plugin) {
+            mIDToSessionMap.removeItemsAt(index);
         }
     }
 }
diff --git a/drm/mediacas/plugins/mock/MockSessionLibrary.h b/drm/mediacas/plugins/mock/MockSessionLibrary.h
index d28cbdc..0b30f4c 100644
--- a/drm/mediacas/plugins/mock/MockSessionLibrary.h
+++ b/drm/mediacas/plugins/mock/MockSessionLibrary.h
@@ -25,23 +25,17 @@
 
 namespace android {
 
-struct SessionInfo {
-    CasPlugin *plugin;
-    uint16_t program_number;
-    uint16_t elementary_PID;
-};
-
 class MockCasSession : public RefBase {
 public:
-    explicit MockCasSession() {}
+    explicit MockCasSession(CasPlugin *plugin) : mPlugin(plugin) {}
     virtual ~MockCasSession() {}
 
 private:
     friend class MockSessionLibrary;
-    SessionInfo mSessionInfo;
 
-    void setSessionInfo(const SessionInfo &info);
-    const SessionInfo& getSessionInfo() const;
+    CasPlugin* mPlugin;
+
+    CasPlugin* getPlugin() const { return mPlugin; }
 
     DISALLOW_EVIL_CONSTRUCTORS(MockCasSession);
 };
@@ -50,11 +44,7 @@
 public:
     static MockSessionLibrary* get();
 
-    status_t addSession(
-            CasPlugin *plugin,
-            uint16_t program_number,
-            uint16_t elementary_PID,
-            CasSessionId *sessionId);
+    status_t addSession(CasPlugin *plugin, CasSessionId *sessionId);
 
     sp<MockCasSession> findSession(const CasSessionId& sessionId);
 
@@ -69,7 +59,6 @@
     Mutex mSessionsLock;
     uint32_t mNextSessionId;
     KeyedVector<CasSessionId, sp<MockCasSession> > mIDToSessionMap;
-    KeyedVector<SessionInfo, CasSessionId> mSessionInfoToIDMap;
 
     MockSessionLibrary();
     DISALLOW_EVIL_CONSTRUCTORS(MockSessionLibrary);
diff --git a/include/media/CasImpl.h b/include/media/CasImpl.h
index 3c07092..0dd506c 100644
--- a/include/media/CasImpl.h
+++ b/include/media/CasImpl.h
@@ -54,13 +54,7 @@
     virtual Status setPrivateData(
             const CasData& pvtData) override;
 
-    virtual Status openSession(
-            int32_t program_number, CasSessionId* _aidl_return) override;
-
-    virtual Status openSessionForStream(
-            int32_t program_number,
-            int32_t elementary_PID,
-            CasSessionId* _aidl_return) override;
+    virtual Status openSession(CasSessionId* _aidl_return) override;
 
     virtual Status closeSession(const CasSessionId& sessionId) override;
 
diff --git a/media/libaaudio/Doxyfile b/media/libaaudio/Doxyfile
index 5cce2ca..e2c4960 100644
--- a/media/libaaudio/Doxyfile
+++ b/media/libaaudio/Doxyfile
@@ -743,8 +743,7 @@
 # spaces.
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = include/aaudio/AAudioDefinitions.h \
-                         include/aaudio/AAudio.h \
+INPUT                  = include/aaudio/AAudio.h \
                          src/legacy/AudioStreamTrack.h \
                          src/legacy/AudioStreamRecord.h \
                          src/legacy/AAudioLegacy.h \
diff --git a/media/libaaudio/examples/input_monitor/src/input_monitor.cpp b/media/libaaudio/examples/input_monitor/src/input_monitor.cpp
index 545496f..0e14af0 100644
--- a/media/libaaudio/examples/input_monitor/src/input_monitor.cpp
+++ b/media/libaaudio/examples/input_monitor/src/input_monitor.cpp
@@ -21,7 +21,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
-#include <aaudio/AAudioDefinitions.h>
 #include <aaudio/AAudio.h>
 
 #define SAMPLE_RATE        48000
diff --git a/media/libaaudio/examples/input_monitor/src/input_monitor_callback.cpp b/media/libaaudio/examples/input_monitor/src/input_monitor_callback.cpp
index 8d40d94..b482e93 100644
--- a/media/libaaudio/examples/input_monitor/src/input_monitor_callback.cpp
+++ b/media/libaaudio/examples/input_monitor/src/input_monitor_callback.cpp
@@ -22,7 +22,6 @@
 #include <stdio.h>
 #include <math.h>
 #include <time.h>
-#include <aaudio/AAudioDefinitions.h>
 #include <aaudio/AAudio.h>
 
 #define NUM_SECONDS           10
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index 25ad5f8..d0c7c22 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -30,12 +30,103 @@
 #define AAUDIO_AAUDIO_H
 
 #include <time.h>
-#include "AAudioDefinitions.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/**
+ * This is used to represent a value that has not been specified.
+ * For example, an application could use AAUDIO_UNSPECIFIED to indicate
+ * that is did not not care what the specific value of a parameter was
+ * and would accept whatever it was given.
+ */
+#define AAUDIO_UNSPECIFIED           0
+#define AAUDIO_DEVICE_UNSPECIFIED    0
+
+enum {
+    AAUDIO_DIRECTION_OUTPUT,
+    AAUDIO_DIRECTION_INPUT
+};
+typedef int32_t aaudio_direction_t;
+
+enum {
+    AAUDIO_FORMAT_INVALID = -1,
+    AAUDIO_FORMAT_UNSPECIFIED = 0,
+    AAUDIO_FORMAT_PCM_I16,
+    AAUDIO_FORMAT_PCM_FLOAT,
+    AAUDIO_FORMAT_PCM_I8_24,
+    AAUDIO_FORMAT_PCM_I32
+};
+typedef int32_t aaudio_format_t;
+
+/**
+ * @deprecated use aaudio_format_t instead
+ * TODO remove when tests and examples are updated
+ */
+typedef int32_t aaudio_audio_format_t;
+
+enum {
+    AAUDIO_OK,
+    AAUDIO_ERROR_BASE = -900, // TODO review
+    AAUDIO_ERROR_DISCONNECTED,
+    AAUDIO_ERROR_ILLEGAL_ARGUMENT,
+    AAUDIO_ERROR_INCOMPATIBLE,
+    AAUDIO_ERROR_INTERNAL, // an underlying API returned an error code
+    AAUDIO_ERROR_INVALID_STATE,
+    AAUDIO_ERROR_UNEXPECTED_STATE,
+    AAUDIO_ERROR_UNEXPECTED_VALUE,
+    AAUDIO_ERROR_INVALID_HANDLE,
+    AAUDIO_ERROR_INVALID_QUERY,
+    AAUDIO_ERROR_UNIMPLEMENTED,
+    AAUDIO_ERROR_UNAVAILABLE,
+    AAUDIO_ERROR_NO_FREE_HANDLES,
+    AAUDIO_ERROR_NO_MEMORY,
+    AAUDIO_ERROR_NULL,
+    AAUDIO_ERROR_TIMEOUT,
+    AAUDIO_ERROR_WOULD_BLOCK,
+    AAUDIO_ERROR_INVALID_FORMAT,
+    AAUDIO_ERROR_OUT_OF_RANGE,
+    AAUDIO_ERROR_NO_SERVICE,
+    AAUDIO_ERROR_INVALID_RATE
+};
+typedef int32_t  aaudio_result_t;
+
+enum
+{
+    AAUDIO_STREAM_STATE_UNINITIALIZED = 0,
+    AAUDIO_STREAM_STATE_UNKNOWN,
+    AAUDIO_STREAM_STATE_OPEN,
+    AAUDIO_STREAM_STATE_STARTING,
+    AAUDIO_STREAM_STATE_STARTED,
+    AAUDIO_STREAM_STATE_PAUSING,
+    AAUDIO_STREAM_STATE_PAUSED,
+    AAUDIO_STREAM_STATE_FLUSHING,
+    AAUDIO_STREAM_STATE_FLUSHED,
+    AAUDIO_STREAM_STATE_STOPPING,
+    AAUDIO_STREAM_STATE_STOPPED,
+    AAUDIO_STREAM_STATE_CLOSING,
+    AAUDIO_STREAM_STATE_CLOSED,
+    AAUDIO_STREAM_STATE_DISCONNECTED
+};
+typedef int32_t aaudio_stream_state_t;
+
+
+enum {
+    /**
+     * This will be the only stream using a particular source or sink.
+     * This mode will provide the lowest possible latency.
+     * You should close EXCLUSIVE streams immediately when you are not using them.
+     */
+            AAUDIO_SHARING_MODE_EXCLUSIVE,
+    /**
+     * Multiple applications will be mixed by the AAudio Server.
+     * This will have higher latency than the EXCLUSIVE mode.
+     */
+            AAUDIO_SHARING_MODE_SHARED
+};
+typedef int32_t aaudio_sharing_mode_t;
+
 typedef struct AAudioStreamStruct         AAudioStream;
 typedef struct AAudioStreamBuilderStruct  AAudioStreamBuilder;
 
@@ -253,7 +344,7 @@
  * AAudioStream_requestStop() is called.
  *
  * This callback function will be called on a real-time thread owned by AAudio. See
- * {@link aaudio_data_callback_proc_t} for more information.
+ * {@link AAudioStream_dataCallback} for more information.
  *
  * Note that the AAudio callbacks will never be called simultaneously from multiple threads.
  *
@@ -415,7 +506,6 @@
  * set to AAUDIO_STREAM_STATE_UNKNOWN and a zero timeout.
  *
  * @param stream reference provided by AAudioStreamBuilder_openStream()
- * @param state pointer to a variable that will be set to the current state
  */
 AAUDIO_API aaudio_stream_state_t AAudioStream_getState(AAudioStream* stream);
 
diff --git a/media/libaaudio/include/aaudio/AAudioDefinitions.h b/media/libaaudio/include/aaudio/AAudioDefinitions.h
deleted file mode 100644
index 57e3dbd..0000000
--- a/media/libaaudio/include/aaudio/AAudioDefinitions.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @addtogroup Audio
- * @{
- */
-
-/**
- * @file AAudioDefinitions.h
- */
-
-#ifndef AAUDIO_AAUDIODEFINITIONS_H
-#define AAUDIO_AAUDIODEFINITIONS_H
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * This is used to represent a value that has not been specified.
- * For example, an application could use AAUDIO_UNSPECIFIED to indicate
- * that is did not not care what the specific value of a parameter was
- * and would accept whatever it was given.
- */
-#define AAUDIO_UNSPECIFIED           0
-#define AAUDIO_DEVICE_UNSPECIFIED    0
-
-enum {
-    AAUDIO_DIRECTION_OUTPUT,
-    AAUDIO_DIRECTION_INPUT
-};
-typedef int32_t aaudio_direction_t;
-
-enum {
-    AAUDIO_FORMAT_INVALID = -1,
-    AAUDIO_FORMAT_UNSPECIFIED = 0,
-    AAUDIO_FORMAT_PCM_I16,
-    AAUDIO_FORMAT_PCM_FLOAT,
-    AAUDIO_FORMAT_PCM_I8_24,
-    AAUDIO_FORMAT_PCM_I32
-};
-typedef int32_t aaudio_format_t;
-
-/**
- * @deprecated use aaudio_format_t instead
- * TODO remove when tests and examples are updated
- */
-typedef int32_t aaudio_audio_format_t;
-
-enum {
-    AAUDIO_OK,
-    AAUDIO_ERROR_BASE = -900, // TODO review
-    AAUDIO_ERROR_DISCONNECTED,
-    AAUDIO_ERROR_ILLEGAL_ARGUMENT,
-    AAUDIO_ERROR_INCOMPATIBLE,
-    AAUDIO_ERROR_INTERNAL, // an underlying API returned an error code
-    AAUDIO_ERROR_INVALID_STATE,
-    AAUDIO_ERROR_UNEXPECTED_STATE,
-    AAUDIO_ERROR_UNEXPECTED_VALUE,
-    AAUDIO_ERROR_INVALID_HANDLE,
-    AAUDIO_ERROR_INVALID_QUERY,
-    AAUDIO_ERROR_UNIMPLEMENTED,
-    AAUDIO_ERROR_UNAVAILABLE,
-    AAUDIO_ERROR_NO_FREE_HANDLES,
-    AAUDIO_ERROR_NO_MEMORY,
-    AAUDIO_ERROR_NULL,
-    AAUDIO_ERROR_TIMEOUT,
-    AAUDIO_ERROR_WOULD_BLOCK,
-    AAUDIO_ERROR_INVALID_FORMAT,
-    AAUDIO_ERROR_OUT_OF_RANGE,
-    AAUDIO_ERROR_NO_SERVICE,
-    AAUDIO_ERROR_INVALID_RATE
-};
-typedef int32_t  aaudio_result_t;
-
-enum
-{
-    AAUDIO_STREAM_STATE_UNINITIALIZED = 0,
-    AAUDIO_STREAM_STATE_UNKNOWN,
-    AAUDIO_STREAM_STATE_OPEN,
-    AAUDIO_STREAM_STATE_STARTING,
-    AAUDIO_STREAM_STATE_STARTED,
-    AAUDIO_STREAM_STATE_PAUSING,
-    AAUDIO_STREAM_STATE_PAUSED,
-    AAUDIO_STREAM_STATE_FLUSHING,
-    AAUDIO_STREAM_STATE_FLUSHED,
-    AAUDIO_STREAM_STATE_STOPPING,
-    AAUDIO_STREAM_STATE_STOPPED,
-    AAUDIO_STREAM_STATE_CLOSING,
-    AAUDIO_STREAM_STATE_CLOSED,
-    AAUDIO_STREAM_STATE_DISCONNECTED
-};
-typedef int32_t aaudio_stream_state_t;
-
-
-enum {
-    /**
-     * This will be the only stream using a particular source or sink.
-     * This mode will provide the lowest possible latency.
-     * You should close EXCLUSIVE streams immediately when you are not using them.
-     */
-    AAUDIO_SHARING_MODE_EXCLUSIVE,
-    /**
-     * Multiple applications will be mixed by the AAudio Server.
-     * This will have higher latency than the EXCLUSIVE mode.
-     */
-    AAUDIO_SHARING_MODE_SHARED
-};
-typedef int32_t aaudio_sharing_mode_t;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // AAUDIO_AAUDIODEFINITIONS_H
-
-/** @} */
diff --git a/media/libaaudio/src/binding/AAudioBinderClient.h b/media/libaaudio/src/binding/AAudioBinderClient.h
index 5613d5b..1497177 100644
--- a/media/libaaudio/src/binding/AAudioBinderClient.h
+++ b/media/libaaudio/src/binding/AAudioBinderClient.h
@@ -17,7 +17,7 @@
 #ifndef AAUDIO_AAUDIO_BINDER_CLIENT_H
 #define AAUDIO_AAUDIO_BINDER_CLIENT_H
 
-#include <aaudio/AAudioDefinitions.h>
+#include <aaudio/AAudio.h>
 #include "AAudioServiceDefinitions.h"
 #include "AAudioServiceInterface.h"
 #include "binding/AAudioStreamRequest.h"
diff --git a/media/libaaudio/src/binding/AAudioServiceMessage.h b/media/libaaudio/src/binding/AAudioServiceMessage.h
index b74b6c2..19d6d52 100644
--- a/media/libaaudio/src/binding/AAudioServiceMessage.h
+++ b/media/libaaudio/src/binding/AAudioServiceMessage.h
@@ -19,7 +19,7 @@
 
 #include <stdint.h>
 
-#include <aaudio/AAudioDefinitions.h>
+#include <aaudio/AAudio.h>
 
 namespace aaudio {
 
diff --git a/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp b/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
index ba41a3b..5adb477 100644
--- a/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
+++ b/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
@@ -17,11 +17,11 @@
 #include <stdint.h>
 
 #include <sys/mman.h>
+#include <aaudio/AAudio.h>
+
 #include <binder/Parcel.h>
 #include <binder/Parcelable.h>
 
-#include <aaudio/AAudioDefinitions.h>
-
 #include "binding/AAudioStreamConfiguration.h"
 
 using android::NO_ERROR;
diff --git a/media/libaaudio/src/binding/AAudioStreamConfiguration.h b/media/libaaudio/src/binding/AAudioStreamConfiguration.h
index b68d8b2..78c4983 100644
--- a/media/libaaudio/src/binding/AAudioStreamConfiguration.h
+++ b/media/libaaudio/src/binding/AAudioStreamConfiguration.h
@@ -19,9 +19,9 @@
 
 #include <stdint.h>
 
+#include <aaudio/AAudio.h>
 #include <binder/Parcel.h>
 #include <binder/Parcelable.h>
-#include <aaudio/AAudioDefinitions.h>
 
 using android::status_t;
 using android::Parcel;
diff --git a/media/libaaudio/src/binding/AAudioStreamRequest.cpp b/media/libaaudio/src/binding/AAudioStreamRequest.cpp
index b8a0429..ec21f8a 100644
--- a/media/libaaudio/src/binding/AAudioStreamRequest.cpp
+++ b/media/libaaudio/src/binding/AAudioStreamRequest.cpp
@@ -24,7 +24,7 @@
 #include <binder/Parcel.h>
 #include <binder/Parcelable.h>
 
-#include <aaudio/AAudioDefinitions.h>
+#include <aaudio/AAudio.h>
 
 #include "binding/AAudioStreamConfiguration.h"
 #include "binding/AAudioStreamRequest.h"
diff --git a/media/libaaudio/src/binding/AAudioStreamRequest.h b/media/libaaudio/src/binding/AAudioStreamRequest.h
index 6546562..992e978 100644
--- a/media/libaaudio/src/binding/AAudioStreamRequest.h
+++ b/media/libaaudio/src/binding/AAudioStreamRequest.h
@@ -19,9 +19,9 @@
 
 #include <stdint.h>
 
+#include <aaudio/AAudio.h>
 #include <binder/Parcel.h>
 #include <binder/Parcelable.h>
-#include <aaudio/AAudioDefinitions.h>
 
 #include "binding/AAudioStreamConfiguration.h"
 
diff --git a/media/libaaudio/src/binding/IAAudioService.cpp b/media/libaaudio/src/binding/IAAudioService.cpp
index 20cbbc8..03fc088 100644
--- a/media/libaaudio/src/binding/IAAudioService.cpp
+++ b/media/libaaudio/src/binding/IAAudioService.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include <aaudio/AAudioDefinitions.h>
+#include <aaudio/AAudio.h>
 
 #include "binding/AudioEndpointParcelable.h"
 #include "binding/AAudioStreamRequest.h"
diff --git a/media/libaaudio/src/binding/SharedMemoryParcelable.cpp b/media/libaaudio/src/binding/SharedMemoryParcelable.cpp
index cfb820f..649c884 100644
--- a/media/libaaudio/src/binding/SharedMemoryParcelable.cpp
+++ b/media/libaaudio/src/binding/SharedMemoryParcelable.cpp
@@ -22,7 +22,7 @@
 #include <stdio.h>
 
 #include <sys/mman.h>
-#include <aaudio/AAudioDefinitions.h>
+#include <aaudio/AAudio.h>
 
 #include <binder/Parcelable.h>
 #include <utility/AAudioUtilities.h>
diff --git a/media/libaaudio/src/binding/SharedRegionParcelable.cpp b/media/libaaudio/src/binding/SharedRegionParcelable.cpp
index 8e57832..7381dcb 100644
--- a/media/libaaudio/src/binding/SharedRegionParcelable.cpp
+++ b/media/libaaudio/src/binding/SharedRegionParcelable.cpp
@@ -23,7 +23,7 @@
 #include <sys/mman.h>
 #include <binder/Parcelable.h>
 
-#include <aaudio/AAudioDefinitions.h>
+#include <aaudio/AAudio.h>
 
 #include "binding/SharedMemoryParcelable.h"
 #include "binding/SharedRegionParcelable.h"
diff --git a/media/libaaudio/src/binding/SharedRegionParcelable.h b/media/libaaudio/src/binding/SharedRegionParcelable.h
index 5fb2a4c..e9f5785 100644
--- a/media/libaaudio/src/binding/SharedRegionParcelable.h
+++ b/media/libaaudio/src/binding/SharedRegionParcelable.h
@@ -22,7 +22,7 @@
 #include <sys/mman.h>
 #include <binder/Parcelable.h>
 
-#include <aaudio/AAudioDefinitions.h>
+#include <aaudio/AAudio.h>
 
 #include "binding/SharedMemoryParcelable.h"
 
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 3934a6d..7304205 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -193,11 +193,11 @@
 void *AudioStreamInternal::callbackLoop() {
     aaudio_result_t result = AAUDIO_OK;
     aaudio_data_callback_result_t callbackResult = AAUDIO_CALLBACK_RESULT_CONTINUE;
-    int32_t framesWritten = 0;
     AAudioStream_dataCallback appCallback = getDataCallbackProc();
     if (appCallback == nullptr) return NULL;
 
-    while (mCallbackEnabled.load() && isPlaying() && (result >= 0)) { // result might be a frame count
+    // result might be a frame count
+    while (mCallbackEnabled.load() && isPlaying() && (result >= 0)) {
         // Call application using the AAudio callback interface.
         callbackResult = (*appCallback)(
                 (AAudioStream *) this,
@@ -206,30 +206,32 @@
                 mCallbackFrames);
 
         if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
-            // Write audio data to stream
+            // Write audio data to stream.
             int64_t timeoutNanos = calculateReasonableTimeout(mCallbackFrames);
+
+            // This is a BLOCKING WRITE!
             result = write(mCallbackBuffer, mCallbackFrames, timeoutNanos);
-            if (result == AAUDIO_ERROR_DISCONNECTED) {
+            if ((result != mCallbackFrames)) {
+                ALOGE("AudioStreamInternal(): callbackLoop: write() returned %d", result);
+                if (result >= 0) {
+                    // Only wrote some of the frames requested. Must have timed out.
+                    result = AAUDIO_ERROR_TIMEOUT;
+                }
                 if (getErrorCallbackProc() != nullptr) {
-                    ALOGD("AudioStreamAAudio(): callbackLoop() stream disconnected");
                     (*getErrorCallbackProc())(
                             (AAudioStream *) this,
                             getErrorCallbackUserData(),
-                            AAUDIO_OK);
+                            result);
                 }
                 break;
-            } else if (result != mCallbackFrames) {
-                ALOGE("AudioStreamAAudio(): callbackLoop() wrote %d / %d",
-                      framesWritten, mCallbackFrames);
-                break;
             }
         } else if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
-            ALOGD("AudioStreamAAudio(): callback returned AAUDIO_CALLBACK_RESULT_STOP");
+            ALOGD("AudioStreamInternal(): callback returned AAUDIO_CALLBACK_RESULT_STOP");
             break;
         }
     }
 
-    ALOGD("AudioStreamAAudio(): callbackLoop() exiting, result = %d, isPlaying() = %d",
+    ALOGD("AudioStreamInternal(): callbackLoop() exiting, result = %d, isPlaying() = %d",
           result, (int) isPlaying());
     return NULL; // TODO review
 }
@@ -237,7 +239,7 @@
 static void *aaudio_callback_thread_proc(void *context)
 {
     AudioStreamInternal *stream = (AudioStreamInternal *)context;
-    //LOGD("AudioStreamAAudio(): oboe_callback_thread, stream = %p", stream);
+    //LOGD("AudioStreamInternal(): oboe_callback_thread, stream = %p", stream);
     if (stream != NULL) {
         return stream->callbackLoop();
     } else {
diff --git a/media/libaaudio/src/core/AAudioAudio.cpp b/media/libaaudio/src/core/AAudioAudio.cpp
index d91d0e4..b17309c 100644
--- a/media/libaaudio/src/core/AAudioAudio.cpp
+++ b/media/libaaudio/src/core/AAudioAudio.cpp
@@ -21,7 +21,6 @@
 #include <time.h>
 #include <pthread.h>
 
-#include <aaudio/AAudioDefinitions.h>
 #include <aaudio/AAudio.h>
 
 #include "AudioStreamBuilder.h"
@@ -401,6 +400,12 @@
     return audioStream->getFramesPerBurst();
 }
 
+AAUDIO_API int32_t AAudioStream_getFramesPerDataCallback(AAudioStream* stream)
+{
+    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
+    return audioStream->getFramesPerDataCallback();
+}
+
 AAUDIO_API int32_t AAudioStream_getBufferCapacityInFrames(AAudioStream* stream)
 {
     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.cpp b/media/libaaudio/src/core/AudioStreamBuilder.cpp
index c0b59bb..a4d1970 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.cpp
+++ b/media/libaaudio/src/core/AudioStreamBuilder.cpp
@@ -21,7 +21,6 @@
 #include <new>
 #include <stdint.h>
 
-#include <aaudio/AAudioDefinitions.h>
 #include <aaudio/AAudio.h>
 
 #include "binding/AAudioBinderClient.h"
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.h b/media/libaaudio/src/core/AudioStreamBuilder.h
index 93ca7f5..c0ee6fe 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.h
+++ b/media/libaaudio/src/core/AudioStreamBuilder.h
@@ -19,7 +19,6 @@
 
 #include <stdint.h>
 
-#include <aaudio/AAudioDefinitions.h>
 #include <aaudio/AAudio.h>
 
 #include "AudioStream.h"
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.cpp b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
index b608434..f0a6ceb 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
@@ -264,7 +264,7 @@
 
 int32_t AudioStreamRecord::getFramesPerBurst() const
 {
-    return 192; // TODO add query to AudioRecord.cpp
+    return static_cast<int32_t>(mAudioRecord->getNotificationPeriodInFrames());
 }
 
 aaudio_result_t AudioStreamRecord::getTimestamp(clockid_t clockId,
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index 8d60678..1bb9e53 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -344,7 +344,7 @@
 
 int32_t AudioStreamTrack::getFramesPerBurst() const
 {
-    return 192; // TODO add query to AudioTrack.cpp
+    return static_cast<int32_t>(mAudioTrack->getNotificationPeriodInFrames());
 }
 
 int64_t AudioStreamTrack::getFramesRead() {
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index 26fa75d..5637f0d 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -22,7 +22,7 @@
 #include <sys/types.h>
 #include <utils/Errors.h>
 
-#include "aaudio/AAudioDefinitions.h"
+#include "aaudio/AAudio.h"
 #include "AAudioUtilities.h"
 
 using namespace android;
diff --git a/media/libaaudio/src/utility/AAudioUtilities.h b/media/libaaudio/src/utility/AAudioUtilities.h
index d3b5ffe..3dc501e 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.h
+++ b/media/libaaudio/src/utility/AAudioUtilities.h
@@ -23,7 +23,7 @@
 #include <utils/Errors.h>
 #include <hardware/audio.h>
 
-#include "aaudio/AAudioDefinitions.h"
+#include "aaudio/AAudio.h"
 
 /**
  * Convert an AAudio result into the closest matching Android status.
diff --git a/media/libaaudio/src/utility/AudioClock.h b/media/libaaudio/src/utility/AudioClock.h
index 952c7b8..43b71b0 100644
--- a/media/libaaudio/src/utility/AudioClock.h
+++ b/media/libaaudio/src/utility/AudioClock.h
@@ -20,7 +20,7 @@
 #include <stdint.h>
 #include <time.h>
 
-#include <aaudio/AAudioDefinitions.h>
+#include <aaudio/AAudio.h>
 
 // Time conversion constants.
 #define AAUDIO_NANOS_PER_MICROSECOND ((int64_t)1000)
diff --git a/media/libaaudio/src/utility/HandleTracker.cpp b/media/libaaudio/src/utility/HandleTracker.cpp
index c4880b8..f957234 100644
--- a/media/libaaudio/src/utility/HandleTracker.cpp
+++ b/media/libaaudio/src/utility/HandleTracker.cpp
@@ -24,7 +24,7 @@
 #include <stdint.h>
 #include <utils/Mutex.h>
 
-#include <aaudio/AAudioDefinitions.h>
+#include <aaudio/AAudio.h>
 #include "HandleTracker.h"
 
 using android::Mutex;
diff --git a/media/libaaudio/tests/test_handle_tracker.cpp b/media/libaaudio/tests/test_handle_tracker.cpp
index e1cb676..c4db47a 100644
--- a/media/libaaudio/tests/test_handle_tracker.cpp
+++ b/media/libaaudio/tests/test_handle_tracker.cpp
@@ -21,7 +21,7 @@
 
 #include <gtest/gtest.h>
 
-#include <aaudio/AAudioDefinitions.h>
+#include <aaudio/AAudio.h>
 #include "utility/HandleTracker.h"
 
 // Test adding one address.
diff --git a/media/libaaudio/tests/test_marshalling.cpp b/media/libaaudio/tests/test_marshalling.cpp
index b1f77c0..79beed6 100644
--- a/media/libaaudio/tests/test_marshalling.cpp
+++ b/media/libaaudio/tests/test_marshalling.cpp
@@ -25,7 +25,7 @@
 #include <gtest/gtest.h>
 #include <sys/mman.h>
 
-#include <aaudio/AAudioDefinitions.h>
+#include <aaudio/AAudio.h>
 #include <binding/AudioEndpointParcelable.h>
 
 using namespace android;
diff --git a/media/libaudioclient/include/AudioRecord.h b/media/libaudioclient/include/AudioRecord.h
index 1c8746f..1b034b5 100644
--- a/media/libaudioclient/include/AudioRecord.h
+++ b/media/libaudioclient/include/AudioRecord.h
@@ -243,6 +243,13 @@
             size_t      frameSize() const   { return mFrameSize; }
             audio_source_t inputSource() const  { return mAttributes.source; }
 
+    /*
+     * Return the period of the notification callback in frames.
+     * This value is set when the AudioRecord is constructed.
+     * It can be modified if the AudioRecord is rerouted.
+     */
+            uint32_t    getNotificationPeriodInFrames() const { return mNotificationFramesAct; }
+
     /* After it's created the track is not active. Call start() to
      * make it active. If set, the callback will start being called.
      * If event is not AudioSystem::SYNC_EVENT_NONE, the capture start will be delayed until
diff --git a/media/libaudioclient/include/AudioTrack.h b/media/libaudioclient/include/AudioTrack.h
index 0358363..16eb225 100644
--- a/media/libaudioclient/include/AudioTrack.h
+++ b/media/libaudioclient/include/AudioTrack.h
@@ -348,7 +348,12 @@
             uint32_t    channelCount() const { return mChannelCount; }
             size_t      frameCount() const  { return mFrameCount; }
 
-    // TODO consider notificationFrames() if needed
+    /*
+     * Return the period of the notification callback in frames.
+     * This value is set when the AudioTrack is constructed.
+     * It can be modified if the AudioTrack is rerouted.
+     */
+            uint32_t    getNotificationPeriodInFrames() const { return mNotificationFramesAct; }
 
     /* Return effective size of audio buffer that an application writes to
      * or a negative error if the track is uninitialized.
diff --git a/media/libaudiohal/Android.mk b/media/libaudiohal/Android.mk
index 032b3e9..68a1f7b 100644
--- a/media/libaudiohal/Android.mk
+++ b/media/libaudiohal/Android.mk
@@ -4,8 +4,6 @@
 
 LOCAL_SHARED_LIBRARIES := \
     libcutils   \
-    libeffects  \
-    libhardware \
     liblog      \
     libutils
 
@@ -22,6 +20,10 @@
     EffectsFactoryHalLocal.cpp  \
     StreamHalLocal.cpp
 
+LOCAL_SHARED_LIBRARIES += \
+    libeffects  \
+    libhardware
+
 else  # if !USE_LEGACY_LOCAL_AUDIO_HAL
 
 LOCAL_SRC_FILES := \
diff --git a/media/libaudiohal/EffectsFactoryHalHidl.cpp b/media/libaudiohal/EffectsFactoryHalHidl.cpp
index 605c059..a8081b7 100644
--- a/media/libaudiohal/EffectsFactoryHalHidl.cpp
+++ b/media/libaudiohal/EffectsFactoryHalHidl.cpp
@@ -18,7 +18,6 @@
 //#define LOG_NDEBUG 0
 
 #include <cutils/native_handle.h>
-#include <media/EffectsFactoryApi.h>
 
 #include "ConversionHelperHidl.h"
 #include "EffectHalHidl.h"
@@ -39,7 +38,7 @@
 
 // static
 bool EffectsFactoryHalInterface::isNullUuid(const effect_uuid_t *pEffectUuid) {
-    return EffectIsNullUuid(pEffectUuid);
+    return memcmp(pEffectUuid, EFFECT_UUID_NULL, sizeof(effect_uuid_t)) == 0;
 }
 
 EffectsFactoryHalHidl::EffectsFactoryHalHidl() : ConversionHelperHidl("EffectsFactory") {
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 4b14543..772555d 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -1,3 +1,9 @@
+cc_library_headers {
+    name: "libmedia_headers",
+    vendor_available: true,
+    export_include_dirs: ["include"],
+}
+
 cc_library {
     name: "libmedia_helper",
     srcs: ["AudioParameter.cpp", "TypeConverter.cpp"],
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index e8c46e3..621c2ce 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -613,12 +613,21 @@
     uint32_t type;
     const void *data;
     size_t size;
-    if (meta->findData(kKeyCas, &type, &data, &size)) {
+    if (meta->findData(kKeyCASessionID, &type, &data, &size)) {
         sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
-        msg->setBuffer("cas", buffer);
+        if (buffer.get() == NULL || buffer->base() == NULL) {
+            return NO_MEMORY;
+        }
+
+        msg->setBuffer("ca-session-id", buffer);
         memcpy(buffer->data(), data, size);
     }
 
+    int32_t systemId;
+    if (meta->findInt32(kKeyCASystemID, &systemId)) {
+        msg->setInt32("ca-system-id", systemId);
+    }
+
     if (!strncasecmp("video/scrambled", mime, 15)
             || !strncasecmp("audio/scrambled", mime, 15)) {
 
diff --git a/media/libstagefright/include/MetaData.h b/media/libstagefright/include/MetaData.h
index 214f4ff..7afd22d 100644
--- a/media/libstagefright/include/MetaData.h
+++ b/media/libstagefright/include/MetaData.h
@@ -176,7 +176,8 @@
     kKeyCryptoDefaultIVSize = 'cryS',  // int32_t
 
     kKeyPssh              = 'pssh',  // raw data
-    kKeyCas               = ' cas',
+    kKeyCASystemID        = 'caid',  // int32_t
+    kKeyCASessionID       = 'seid',  // raw data
 
     // Please see MediaFormat.KEY_IS_AUTOSELECT.
     kKeyTrackIsAutoselect = 'auto', // bool (int32_t)
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 47caf61..8099edb 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -140,7 +140,8 @@
     unsigned pid() const { return mElementaryPID; }
     void setPID(unsigned pid) { mElementaryPID = pid; }
 
-    void setCasSession(
+    void setCasInfo(
+            int32_t systemId,
             const sp<IDescrambler> &descrambler,
             const std::vector<uint8_t> &sessionId);
 
@@ -682,9 +683,10 @@
         sp<Stream> &stream = mStreams.editValueAt(i);
         sp<IDescrambler> descrambler;
         std::vector<uint8_t> sessionId;
-        if (mParser->mCasManager->getCasSession(
-                mProgramNumber, stream->pid(), &descrambler, &sessionId)) {
-            stream->setCasSession(descrambler, sessionId);
+        int32_t systemId;
+        if (mParser->mCasManager->getCasInfo(mProgramNumber, stream->pid(),
+                &systemId, &descrambler, &sessionId)) {
+            stream->setCasInfo(systemId, descrambler, sessionId);
         }
     }
 }
@@ -767,8 +769,8 @@
             meta->setCString(kKeyMIMEType,
                     isAudio() ? MEDIA_MIMETYPE_AUDIO_SCRAMBLED
                               : MEDIA_MIMETYPE_VIDEO_SCRAMBLED);
-            // for DrmInitData
-            meta->setData(kKeyCas, 0, &CA_system_ID, sizeof(CA_system_ID));
+            // for MediaExtractor.CasInfo
+            meta->setInt32(kKeyCASystemID, CA_system_ID);
             mSource = new AnotherPacketSource(meta);
         }
     }
@@ -1566,14 +1568,14 @@
     return NULL;
 }
 
-void ATSParser::Stream::setCasSession(
-        const sp<IDescrambler> &descrambler,
+void ATSParser::Stream::setCasInfo(
+        int32_t systemId, const sp<IDescrambler> &descrambler,
         const std::vector<uint8_t> &sessionId) {
     if (mSource != NULL && mDescrambler == NULL && descrambler != NULL) {
         signalDiscontinuity(DISCONTINUITY_FORMAT_ONLY, NULL);
         mDescrambler = descrambler;
         if (mQueue->isScrambled()) {
-            mQueue->setCasSession(sessionId);
+            mQueue->setCasInfo(systemId, sessionId);
         }
     }
 }
diff --git a/media/libstagefright/mpeg2ts/CasManager.cpp b/media/libstagefright/mpeg2ts/CasManager.cpp
index 4e34a30..047b1b3 100644
--- a/media/libstagefright/mpeg2ts/CasManager.cpp
+++ b/media/libstagefright/mpeg2ts/CasManager.cpp
@@ -52,8 +52,9 @@
         sp<IDescrambler> mDescrambler;
     };
     status_t initSession(
-             const sp<ICas>& cas, PidToSessionMap &sessionMap,
-             CasSession *session, unsigned programNumber, unsigned elementaryPID);
+            const sp<ICas>& cas,
+            PidToSessionMap &sessionMap,
+            CasSession *session);
     void closeSession(const sp<ICas>& cas, const CasSession &casSession);
 
     unsigned mProgramNumber;
@@ -88,14 +89,14 @@
 status_t ATSParser::CasManager::ProgramCasManager::setMediaCas(
         const sp<ICas> &cas, PidToSessionMap &sessionMap) {
     if (mHasProgramCas) {
-        return initSession(cas, sessionMap, &mProgramCas, mProgramNumber, 0);
+        return initSession(cas, sessionMap, &mProgramCas);
     }
+    // TODO: share session among streams that has identical CA_descriptors.
+    // For now, we open one session for each stream that has CA_descriptor.
     for (size_t index = 0; index < mStreamPidToCasMap.size(); index++) {
-        unsigned elementaryPID = mStreamPidToCasMap.keyAt(index);
-        status_t err;
-        if ((err = initSession(cas, sessionMap,
-                &mStreamPidToCasMap.editValueAt(index),
-                mProgramNumber, elementaryPID)) != OK) {
+        status_t err = initSession(
+                cas, sessionMap, &mStreamPidToCasMap.editValueAt(index));
+        if (err != OK) {
             return err;
         }
     }
@@ -121,8 +122,9 @@
 }
 
 status_t ATSParser::CasManager::ProgramCasManager::initSession(
-         const sp<ICas>& cas, PidToSessionMap &sessionMap,
-         CasSession *session, unsigned programNumber, unsigned elementaryPID) {
+         const sp<ICas>& cas,
+         PidToSessionMap &sessionMap,
+         CasSession *session) {
     sp<IServiceManager> sm = defaultServiceManager();
     sp<IBinder> casServiceBinder = sm->getService(String16("media.cas"));
     sp<IMediaCasService> casService =
@@ -137,13 +139,7 @@
     std::vector<uint8_t> sessionId;
     const CADescriptor &descriptor = session->mCADescriptor;
 
-    Status status;
-    if (elementaryPID == 0) {
-        status = cas->openSession(programNumber, &sessionId);
-    } else {
-        status = cas->openSessionForStream(
-                programNumber, elementaryPID, &sessionId);
-    }
+    Status status = cas->openSession(&sessionId);
     if (!status.isOk()) {
         ALOGE("Failed to open session: exception=%d, error=%d",
                 status.exceptionCode(), status.serviceSpecificErrorCode());
@@ -298,13 +294,15 @@
     return true;
 }
 
-bool ATSParser::CasManager::getCasSession(
+bool ATSParser::CasManager::getCasInfo(
         unsigned programNumber, unsigned elementaryPID,
-        sp<IDescrambler> *descrambler, std::vector<uint8_t> *sessionId) const {
+        int32_t *systemId, sp<IDescrambler> *descrambler,
+        std::vector<uint8_t> *sessionId) const {
     ssize_t index = mProgramCasMap.indexOfKey(programNumber);
     if (index < 0) {
         return false;
     }
+    *systemId = mSystemId;
     return mProgramCasMap[index]->getCasSession(
             elementaryPID, descrambler, sessionId);
 }
diff --git a/media/libstagefright/mpeg2ts/CasManager.h b/media/libstagefright/mpeg2ts/CasManager.h
index a7a3de9..8088dec 100644
--- a/media/libstagefright/mpeg2ts/CasManager.h
+++ b/media/libstagefright/mpeg2ts/CasManager.h
@@ -39,9 +39,9 @@
             unsigned programNumber, unsigned elementaryPID,
             const CADescriptor &descriptor);
 
-    bool getCasSession(
+    bool getCasInfo(
             unsigned programNumber, unsigned elementaryPID,
-            sp<IDescrambler> *descrambler,
+            int32_t *systemId, sp<IDescrambler> *descrambler,
             std::vector<uint8_t> *sessionId) const;
 
     bool isCAPid(unsigned pid);
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index 6bac1db..ae7ec77 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -41,7 +41,8 @@
 ElementaryStreamQueue::ElementaryStreamQueue(Mode mode, uint32_t flags)
     : mMode(mode),
       mFlags(flags),
-      mEOSReached(false) {
+      mEOSReached(false),
+      mCASystemId(0) {
 }
 
 sp<MetaData> ElementaryStreamQueue::getFormat() {
@@ -67,6 +68,16 @@
     mEOSReached = false;
 }
 
+bool ElementaryStreamQueue::isScrambled() const {
+    return (mFlags & kFlag_ScrambledData) != 0;
+}
+
+void ElementaryStreamQueue::setCasInfo(
+        int32_t systemId, const std::vector<uint8_t> &sessionId) {
+    mCASystemId = systemId;
+    mCasSessionId = sessionId;
+}
+
 // Parse AC3 header assuming the current ptr is start position of syncframe,
 // update metadata only applicable, and return the payload size
 static unsigned parseAC3SyncFrame(
@@ -938,8 +949,10 @@
                 mFormat->setInt32(kKeyWidth, 1280);
                 mFormat->setInt32(kKeyHeight, 720);
             }
-            // for DrmInitData
-            mFormat->setData(kKeyCas, 0, mCasSessionId.data(), mCasSessionId.size());
+            // for MediaExtractor.CasInfo
+            mFormat->setInt32(kKeyCASystemID, mCASystemId);
+            mFormat->setData(kKeyCASessionID, 0,
+                    mCasSessionId.data(), mCasSessionId.size());
         }
         return dequeueScrambledAccessUnit();
     }
@@ -1213,8 +1226,10 @@
             mFormat->setInt32(kKeyWidth, 1280);
             mFormat->setInt32(kKeyHeight, 720);
 
-            // for DrmInitData
-            mFormat->setData(kKeyCas, 0, mCasSessionId.data(), mCasSessionId.size());
+            // for MediaExtractor.CasInfo
+            mFormat->setInt32(kKeyCASystemID, mCASystemId);
+            mFormat->setData(kKeyCASessionID, 0,
+                    mCasSessionId.data(), mCasSessionId.size());
         }
         return dequeueScrambledAccessUnit();
     }
diff --git a/media/libstagefright/mpeg2ts/ESQueue.h b/media/libstagefright/mpeg2ts/ESQueue.h
index 6941e3f..11e1af7 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.h
+++ b/media/libstagefright/mpeg2ts/ESQueue.h
@@ -65,13 +65,9 @@
 
     sp<MetaData> getFormat();
 
-    bool isScrambled() {
-        return (mFlags & kFlag_ScrambledData) != 0;
-    }
+    bool isScrambled() const;
 
-    void setCasSession(const std::vector<uint8_t> &sessionId) {
-        mCasSessionId = sessionId;
-    }
+    void setCasInfo(int32_t systemId, const std::vector<uint8_t> &sessionId);
 
 private:
     struct RangeInfo {
@@ -99,6 +95,7 @@
 
     sp<ABuffer> mScrambledBuffer;
     List<ScrambledRangeInfo> mScrambledRangeInfos;
+    int32_t mCASystemId;
     std::vector<uint8_t> mCasSessionId;
 
     sp<MetaData> mFormat;
diff --git a/media/mtp/MtpFfsHandle.cpp b/media/mtp/MtpFfsHandle.cpp
index 565a2fe..c78002c 100644
--- a/media/mtp/MtpFfsHandle.cpp
+++ b/media/mtp/MtpFfsHandle.cpp
@@ -520,7 +520,16 @@
     // When receiving files, the incoming length is given in 32 bits.
     // A >4G file is given as 0xFFFFFFFF
     uint32_t file_length = mfr.length;
-    uint64_t offset = lseek(mfr.fd, 0, SEEK_CUR);
+    uint64_t offset = mfr.offset;
+    struct usb_endpoint_descriptor mBulkOut_desc;
+    int packet_size;
+
+    if (ioctl(mBulkOut, FUNCTIONFS_ENDPOINT_DESC, reinterpret_cast<unsigned long>(&mBulkOut_desc))) {
+        PLOG(ERROR) << "Could not get FFS bulk-out descriptor";
+        packet_size = MAX_PACKET_SIZE_HS;
+    } else {
+        packet_size = mBulkOut_desc.wMaxPacketSize;
+    }
 
     char *data = mBuffer1.data();
     char *data2 = mBuffer2.data();
@@ -573,21 +582,26 @@
         }
 
         if (read) {
-            // Enqueue a new write request
-            aio.aio_buf = data;
-            aio.aio_sink = mfr.fd;
-            aio.aio_offset = offset;
-            aio.aio_nbytes = ret;
-            aio_write(&aio);
-
             if (file_length == MAX_MTP_FILE_SIZE) {
                 // For larger files, receive until a short packet is received.
                 if (static_cast<size_t>(ret) < length) {
                     file_length = 0;
                 }
             } else {
+                // Receive an empty packet if size is a multiple of the endpoint size.
                 file_length -= ret;
+                if (file_length == 0 && ret % packet_size == 0) {
+                    if (TEMP_FAILURE_RETRY(::read(mBulkOut, data, packet_size)) != 0) {
+                        return -1;
+                    }
+                }
             }
+            // Enqueue a new write request
+            aio.aio_buf = data;
+            aio.aio_sink = mfr.fd;
+            aio.aio_offset = offset;
+            aio.aio_nbytes = ret;
+            aio_write(&aio);
 
             offset += ret;
             std::swap(data, data2);
@@ -695,9 +709,11 @@
         }
     }
 
-    if (given_length == MAX_MTP_FILE_SIZE && ret % packet_size == 0) {
+    if (ret % packet_size == 0) {
         // If the last packet wasn't short, send a final empty packet
-        if (writeHandle(mBulkIn, data, 0) == -1) return -1;
+        if (TEMP_FAILURE_RETRY(::write(mBulkIn, data, 0)) != 0) {
+            return -1;
+        }
     }
 
     return 0;
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index 2be9362..2d78f99 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -67,6 +67,7 @@
     libmediautils \
     libcamera_client \
     libcamera_metadata \
+    libfmq \
     libgui \
     libhardware \
     libhidlbase \
@@ -79,7 +80,7 @@
     android.hardware.camera.device@3.2 \
     android.hidl.manager@1.0
 
-LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libbinder libcamera_client
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libbinder libcamera_client libfmq
 
 LOCAL_C_INCLUDES += \
     system/media/private/camera/include \
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 7d8d61e..ab077f0 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -199,10 +199,42 @@
         return res;
     }
 
+    std::shared_ptr<RequestMetadataQueue> queue;
+    auto requestQueueRet = session->getCaptureRequestMetadataQueue(
+        [&queue](const auto& descriptor) {
+            queue = std::make_shared<RequestMetadataQueue>(descriptor);
+            if (!queue->isValid() || queue->availableToWrite() <= 0) {
+                ALOGE("HAL returns empty request metadata fmq, not use it");
+                queue = nullptr;
+                // don't use the queue onwards.
+            }
+        });
+    if (!requestQueueRet.isOk()) {
+        ALOGE("Transaction error when getting request metadata fmq: %s, not use it",
+                requestQueueRet.description().c_str());
+        queue = nullptr;
+        // Don't use the queue onwards.
+    }
+    auto resultQueueRet = session->getCaptureResultMetadataQueue(
+        [&queue = mResultMetadataQueue](const auto& descriptor) {
+            queue = std::make_unique<ResultMetadataQueue>(descriptor);
+            if (!queue->isValid() ||  queue->availableToWrite() <= 0) {
+                ALOGE("HAL returns empty result metadata fmq, not use it");
+                queue = nullptr;
+                // Don't use the queue onwards.
+            }
+        });
+    if (!resultQueueRet.isOk()) {
+        ALOGE("Transaction error when getting result metadata queue from camera session: %s",
+                resultQueueRet.description().c_str());
+        mResultMetadataQueue = nullptr;
+        // Don't use the queue onwards.
+    }
+
     // TODO: camera service will absorb 3_2/3_3/3_4 differences in the future
     //       for now use 3_4 to keep legacy devices working
     mDeviceVersion = CAMERA_DEVICE_API_VERSION_3_4;
-    mInterface = std::make_unique<HalInterface>(session);
+    mInterface = std::make_unique<HalInterface>(session, queue);
     std::string providerType;
     mVendorTagId = manager->getProviderTagIdLocked(mId.string());
 
@@ -938,24 +970,56 @@
     return res;
 }
 
-
+// Only one processCaptureResult should be called at a time, so
+// the locks won't block. The locks are present here simply to enforce this.
 hardware::Return<void> Camera3Device::processCaptureResult(
         const hardware::hidl_vec<
                 hardware::camera::device::V3_2::CaptureResult>& results) {
-    for (const auto& result : results) {
-        processOneCaptureResult(result);
+
+    if (mProcessCaptureResultLock.tryLock() != OK) {
+        // This should never happen; it indicates a wrong client implementation
+        // that doesn't follow the contract. But, we can be tolerant here.
+        ALOGE("%s: callback overlapped! waiting 1s...",
+                __FUNCTION__);
+        if (mProcessCaptureResultLock.timedLock(1000000000 /* 1s */) != OK) {
+            ALOGE("%s: cannot acquire lock in 1s, dropping results",
+                    __FUNCTION__);
+            // really don't know what to do, so bail out.
+            return hardware::Void();
+        }
     }
+    for (const auto& result : results) {
+        processOneCaptureResultLocked(result);
+    }
+    mProcessCaptureResultLock.unlock();
     return hardware::Void();
 }
 
-void Camera3Device::processOneCaptureResult(
+void Camera3Device::processOneCaptureResultLocked(
         const hardware::camera::device::V3_2::CaptureResult& result) {
     camera3_capture_result r;
     status_t res;
     r.frame_number = result.frameNumber;
-    if (result.result.size() != 0) {
-        r.result = reinterpret_cast<const camera_metadata_t*>(result.result.data());
-        size_t expected_metadata_size = result.result.size();
+
+    hardware::camera::device::V3_2::CameraMetadata resultMetadata;
+    if (result.fmqResultSize > 0) {
+        resultMetadata.resize(result.fmqResultSize);
+        if (mResultMetadataQueue == nullptr) {
+            return; // logged in initialize()
+        }
+        if (!mResultMetadataQueue->read(resultMetadata.data(), result.fmqResultSize)) {
+            ALOGE("%s: Frame %d: Cannot read camera metadata from fmq, size = %" PRIu64,
+                    __FUNCTION__, result.frameNumber, result.fmqResultSize);
+            return;
+        }
+    } else {
+        resultMetadata.setToExternal(const_cast<uint8_t *>(result.result.data()),
+                result.result.size());
+    }
+
+    if (resultMetadata.size() != 0) {
+        r.result = reinterpret_cast<const camera_metadata_t*>(resultMetadata.data());
+        size_t expected_metadata_size = resultMetadata.size();
         if ((res = validate_camera_metadata_structure(r.result, &expected_metadata_size)) != OK) {
             ALOGE("%s: Frame %d: Invalid camera metadata received by camera service from HAL: %s (%d)",
                     __FUNCTION__, result.frameNumber, strerror(-res), res);
@@ -3035,16 +3099,20 @@
 Camera3Device::HalInterface::HalInterface(camera3_device_t *device) :
         mHal3Device(device) {}
 
-Camera3Device::HalInterface::HalInterface(sp<ICameraDeviceSession> &session) :
+Camera3Device::HalInterface::HalInterface(
+            sp<ICameraDeviceSession> &session,
+            std::shared_ptr<RequestMetadataQueue> queue) :
         mHal3Device(nullptr),
-        mHidlSession(session) {}
+        mHidlSession(session),
+        mRequestMetadataQueue(queue) {}
 
 Camera3Device::HalInterface::HalInterface() :
         mHal3Device(nullptr) {}
 
 Camera3Device::HalInterface::HalInterface(const HalInterface& other) :
         mHal3Device(other.mHal3Device),
-        mHidlSession(other.mHidlSession) {}
+        mHidlSession(other.mHidlSession),
+        mRequestMetadataQueue(other.mRequestMetadataQueue) {}
 
 bool Camera3Device::HalInterface::valid() {
     return (mHal3Device != nullptr) || (mHidlSession != nullptr);
@@ -3276,12 +3344,8 @@
     }
 
     captureRequest->frameNumber = request->frame_number;
-    // A null request settings maps to a size-0 CameraMetadata
-    if (request->settings != nullptr) {
-        captureRequest->settings.setToExternal(
-                reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(request->settings)),
-                get_camera_metadata_size(request->settings));
-    }
+
+    captureRequest->fmqSettingsSize = 0;
 
     {
         std::lock_guard<std::mutex> lock(mInflightLock);
@@ -3367,6 +3431,33 @@
 
     common::V1_0::Status status = common::V1_0::Status::INTERNAL_ERROR;
     *numRequestProcessed = 0;
+
+    // Write metadata to FMQ.
+    for (size_t i = 0; i < batchSize; i++) {
+        camera3_capture_request_t* request = requests[i];
+        device::V3_2::CaptureRequest* captureRequest = &captureRequests[i];
+
+        if (request->settings != nullptr) {
+            size_t settingsSize = get_camera_metadata_size(request->settings);
+            if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
+                    reinterpret_cast<const uint8_t*>(request->settings), settingsSize)) {
+                captureRequest->settings.resize(0);
+                captureRequest->fmqSettingsSize = settingsSize;
+            } else {
+                if (mRequestMetadataQueue != nullptr) {
+                    ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
+                }
+                captureRequest->settings.setToExternal(
+                        reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(request->settings)),
+                        get_camera_metadata_size(request->settings));
+                captureRequest->fmqSettingsSize = 0u;
+            }
+        } else {
+            // A null request settings maps to a size-0 CameraMetadata
+            captureRequest->settings.resize(0);
+            captureRequest->fmqSettingsSize = 0u;
+        }
+    }
     mHidlSession->processCaptureRequest(captureRequests, cachesToRemove,
             [&status, &numRequestProcessed] (auto s, uint32_t n) {
                 status = s;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 9c0210b..eaffad8 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -31,6 +31,7 @@
 #include <android/hardware/camera/device/3.2/ICameraDevice.h>
 #include <android/hardware/camera/device/3.2/ICameraDeviceSession.h>
 #include <android/hardware/camera/device/3.2/ICameraDeviceCallback.h>
+#include <fmq/MessageQueue.h>
 #include <hardware/camera3.h>
 
 #include <camera/CaptureResult.h>
@@ -181,6 +182,11 @@
     status_t setConsumerSurfaces(int streamId, const std::vector<sp<Surface>>& consumers) override;
 
   private:
+
+    // internal typedefs
+    using RequestMetadataQueue = hardware::MessageQueue<uint8_t, hardware::kSynchronizedReadWrite>;
+    using ResultMetadataQueue  = hardware::MessageQueue<uint8_t, hardware::kSynchronizedReadWrite>;
+
     static const size_t        kDumpLockAttempts  = 10;
     static const size_t        kDumpSleepDuration = 100000; // 0.10 sec
     static const nsecs_t       kShutdownTimeout   = 5000000000; // 5 sec
@@ -218,6 +224,9 @@
     // Flag indicating is the current active stream configuration is constrained high speed.
     bool                       mIsConstrainedHighSpeedConfiguration;
 
+    // FMQ to write result on. Must be guarded by mProcessCaptureResultLock.
+    std::unique_ptr<ResultMetadataQueue> mResultMetadataQueue;
+
     /**** Scope for mLock ****/
 
     /**
@@ -227,7 +236,8 @@
     class HalInterface : public camera3::Camera3StreamBufferFreedListener {
       public:
         HalInterface(camera3_device_t *device);
-        HalInterface(sp<hardware::camera::device::V3_2::ICameraDeviceSession> &session);
+        HalInterface(sp<hardware::camera::device::V3_2::ICameraDeviceSession> &session,
+                     std::shared_ptr<RequestMetadataQueue> queue);
         HalInterface(const HalInterface &other);
         HalInterface();
 
@@ -261,6 +271,7 @@
       private:
         camera3_device_t *mHal3Device;
         sp<hardware::camera::device::V3_2::ICameraDeviceSession> mHidlSession;
+        std::shared_ptr<RequestMetadataQueue> mRequestMetadataQueue;
 
         std::mutex mInflightLock;
 
@@ -456,12 +467,15 @@
             const hardware::hidl_vec<
                     hardware::camera::device::V3_2::NotifyMsg>& msgs) override;
 
-    // Handle one capture result
-    void processOneCaptureResult(
+    // Handle one capture result. Assume that mProcessCaptureResultLock is held.
+    void processOneCaptureResultLocked(
             const hardware::camera::device::V3_2::CaptureResult& results);
     // Handle one notify message
     void notify(const hardware::camera::device::V3_2::NotifyMsg& msg);
 
+    // lock to ensure only one processCaptureResult is called at a time.
+    Mutex mProcessCaptureResultLock;
+
     /**
      * Common initialization code shared by both HAL paths
      *
diff --git a/services/mediacodec/main_codecservice.cpp b/services/mediacodec/main_codecservice.cpp
index 3a4546b..c4e4cff 100644
--- a/services/mediacodec/main_codecservice.cpp
+++ b/services/mediacodec/main_codecservice.cpp
@@ -46,6 +46,11 @@
 int main(int argc __unused, char** argv)
 {
     LOG(INFO) << "mediacodecservice starting";
+    bool treble = property_get_bool("persist.media.treble_omx", true);
+    if (treble) {
+      android::ProcessState::initWithDriver("/dev/vndbinder");
+    }
+
     signal(SIGPIPE, SIG_IGN);
     SetUpMinijail(kSystemSeccompPolicyPath, kVendorSeccompPolicyPath);
 
@@ -54,7 +59,7 @@
     ::android::hardware::configureRpcThreadpool(64, false);
     sp<ProcessState> proc(ProcessState::self());
 
-    if (property_get_bool("persist.media.treble_omx", true)) {
+    if (treble) {
         using namespace ::android::hardware::media::omx::V1_0;
         sp<IOmx> omx = new implementation::Omx();
         if (omx == nullptr) {
diff --git a/services/oboeservice/AAudioService.cpp b/services/oboeservice/AAudioService.cpp
index e4fa1c5..723ef63 100644
--- a/services/oboeservice/AAudioService.cpp
+++ b/services/oboeservice/AAudioService.cpp
@@ -21,7 +21,7 @@
 //#include <time.h>
 //#include <pthread.h>
 
-#include <aaudio/AAudioDefinitions.h>
+#include <aaudio/AAudio.h>
 #include <mediautils/SchedulingPolicyService.h>
 #include <utils/String16.h>
 
diff --git a/services/oboeservice/AAudioThread.cpp b/services/oboeservice/AAudioThread.cpp
index b1b563d..ebb50f8 100644
--- a/services/oboeservice/AAudioThread.cpp
+++ b/services/oboeservice/AAudioThread.cpp
@@ -20,7 +20,7 @@
 
 #include <pthread.h>
 
-#include <aaudio/AAudioDefinitions.h>
+#include <aaudio/AAudio.h>
 #include <utility/AAudioUtilities.h>
 
 #include "AAudioThread.h"
diff --git a/services/oboeservice/AAudioThread.h b/services/oboeservice/AAudioThread.h
index dd9f640..02f1459 100644
--- a/services/oboeservice/AAudioThread.h
+++ b/services/oboeservice/AAudioThread.h
@@ -20,7 +20,7 @@
 #include <atomic>
 #include <pthread.h>
 
-#include <aaudio/AAudioDefinitions.h>
+#include <aaudio/AAudio.h>
 
 namespace aaudio {
 
diff --git a/services/oboeservice/SharedMemoryProxy.cpp b/services/oboeservice/SharedMemoryProxy.cpp
index 83ae1d4..fc4532c 100644
--- a/services/oboeservice/SharedMemoryProxy.cpp
+++ b/services/oboeservice/SharedMemoryProxy.cpp
@@ -18,7 +18,7 @@
 //#define LOG_NDEBUG 0
 #include <utils/Log.h>
 
-#include <aaudio/AAudioDefinitions.h>
+#include <aaudio/AAudio.h>
 #include "SharedMemoryProxy.h"
 
 using namespace android;
diff --git a/services/oboeservice/SharedMemoryProxy.h b/services/oboeservice/SharedMemoryProxy.h
index 99bfdea..89eeb4b 100644
--- a/services/oboeservice/SharedMemoryProxy.h
+++ b/services/oboeservice/SharedMemoryProxy.h
@@ -21,7 +21,7 @@
 #include <cutils/ashmem.h>
 #include <sys/mman.h>
 
-#include <aaudio/AAudioDefinitions.h>
+#include <aaudio/AAudio.h>
 
 namespace aaudio {
 
diff --git a/services/oboeservice/TimestampScheduler.h b/services/oboeservice/TimestampScheduler.h
index 325bee4..baa5c41 100644
--- a/services/oboeservice/TimestampScheduler.h
+++ b/services/oboeservice/TimestampScheduler.h
@@ -17,7 +17,7 @@
 #ifndef AAUDIO_TIMESTAMP_SCHEDULER_H
 #define AAUDIO_TIMESTAMP_SCHEDULER_H
 
-#include <aaudio/AAudioDefinitions.h>
+#include <aaudio/AAudio.h>
 #include <utility/AudioClock.h>
 
 namespace aaudio {
diff --git a/services/soundtrigger/Android.mk b/services/soundtrigger/Android.mk
index 3e7a7ce..e21aae3 100644
--- a/services/soundtrigger/Android.mk
+++ b/services/soundtrigger/Android.mk
@@ -17,6 +17,9 @@
 include $(CLEAR_VARS)
 
 ifeq ($(SOUND_TRIGGER_USE_STUB_MODULE), 1)
+    ifneq ($(USE_LEGACY_LOCAL_AUDIO_HAL), true)
+        $(error Requires building with USE_LEGACY_LOCAL_AUDIO_HAL=true)
+    endif
     LOCAL_CFLAGS += -DSOUND_TRIGGER_USE_STUB_MODULE
 endif
 
diff --git a/services/soundtrigger/SoundTriggerHalHidl.cpp b/services/soundtrigger/SoundTriggerHalHidl.cpp
index 7cc8a2b..0cd5cf7 100644
--- a/services/soundtrigger/SoundTriggerHalHidl.cpp
+++ b/services/soundtrigger/SoundTriggerHalHidl.cpp
@@ -252,6 +252,8 @@
 SoundTriggerHalHidl::SoundTriggerHalHidl(const char *moduleName)
     : mModuleName(moduleName), mNextUniqueId(1)
 {
+    LOG_ALWAYS_FATAL_IF(strcmp(mModuleName, "primary") != 0,
+            "Treble soundtrigger only supports primary module");
 }
 
 SoundTriggerHalHidl::~SoundTriggerHalHidl()
@@ -265,9 +267,7 @@
         if (mModuleName == NULL) {
             mModuleName = "primary";
         }
-        std::string serviceName = "sound_trigger.";
-        serviceName.append(mModuleName);
-        mISoundTrigger = ISoundTriggerHw::getService(serviceName);
+        mISoundTrigger = ISoundTriggerHw::getService();
         if (mISoundTrigger != 0) {
             mISoundTrigger->linkToDeath(HalDeathHandler::getInstance(), 0 /*cookie*/);
         }