Merge "Make tombstone in the child process on loading failure." into qt-dev
diff --git a/apex/Android.bp b/apex/Android.bp
index 2cc6fcb..ec0efe6 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -12,27 +12,22 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+com_android_media_extractors = [
+    "libaacextractor",
+    "libamrextractor",
+    "libflacextractor",
+    "libmidiextractor",
+    "libmkvextractor",
+    "libmp3extractor",
+    "libmp4extractor",
+    "libmpeg2extractor",
+    "liboggextractor",
+    "libwavextractor",
+]
+
 apex_defaults {
     name: "com.android.media-defaults",
     java_libs: ["updatable-media"],
-    multilib: {
-        first: {
-            // Extractor process runs only with the primary ABI.
-            native_shared_libs: [
-                // Extractor plugins
-                "libaacextractor",
-                "libamrextractor",
-                "libflacextractor",
-                "libmidiextractor",
-                "libmkvextractor",
-                "libmp3extractor",
-                "libmp4extractor",
-                "libmpeg2extractor",
-                "liboggextractor",
-                "libwavextractor",
-            ],
-        },
-    },
     key: "com.android.media.key",
     certificate: ":com.android.media.certificate",
 
@@ -44,6 +39,12 @@
     name: "com.android.media",
     manifest: "manifest.json",
     defaults: ["com.android.media-defaults"],
+    multilib: {
+        first: {
+            // Extractor process runs only with the primary ABI.
+            native_shared_libs: com_android_media_extractors,
+        },
+    },
 }
 
 filegroup {
diff --git a/apex/ld.config.txt b/apex/ld.config.txt
index 715113d..87af5a1 100644
--- a/apex/ld.config.txt
+++ b/apex/ld.config.txt
@@ -38,7 +38,8 @@
 namespace.platform.isolated = true
 
 namespace.platform.search.paths = /system/${LIB}
-namespace.platform.asan.search.paths = /data/asan/system/${LIB}
+namespace.platform.asan.search.paths  = /data/asan/system/${LIB}
+namespace.platform.asan.search.paths +=           /system/${LIB}
 
 # /system/lib/libc.so, etc are symlinks to /apex/com.android.lib/lib/bionic/libc.so, etc.
 # Add /apex/... pat to the permitted paths because linker uses realpath(3)
diff --git a/apex/testing/Android.bp b/apex/testing/Android.bp
index 701ced7..297d864 100644
--- a/apex/testing/Android.bp
+++ b/apex/testing/Android.bp
@@ -17,6 +17,13 @@
     manifest: "test_manifest.json",
     file_contexts: "com.android.media",
     defaults: ["com.android.media-defaults"],
+    multilib: {
+        both: {
+            // for test apex, built for both ABIs
+            native_shared_libs: com_android_media_extractors,
+        },
+    },
+    compile_multilib: "both",
     installable: false,
 }
 
diff --git a/camera/ndk/Android.bp b/camera/ndk/Android.bp
index d96f403..7786856 100644
--- a/camera/ndk/Android.bp
+++ b/camera/ndk/Android.bp
@@ -64,6 +64,10 @@
         "-Wextra",
         "-Werror",
     ],
+    // TODO: jchowdhary@, use header_libs instead b/131165718
+    include_dirs: [
+        "system/media/private/camera/include",
+    ],
     export_include_dirs: ["include"],
     export_shared_lib_headers: [
         "libnativewindow",
@@ -123,6 +127,10 @@
         "android.hardware.camera.common@1.0-helper",
         "libarect",
     ],
+    // TODO: jchowdhary@, use header_libs instead b/131165718
+    include_dirs: [
+        "system/media/private/camera/include",
+    ],
     product_variables: {
         pdk: {
             enabled: false,
diff --git a/camera/ndk/NdkCameraManager.cpp b/camera/ndk/NdkCameraManager.cpp
index 23d01ef..3d231a8 100644
--- a/camera/ndk/NdkCameraManager.cpp
+++ b/camera/ndk/NdkCameraManager.cpp
@@ -190,3 +190,17 @@
     }
     return mgr->openCamera(cameraId, callback, device);
 }
+
+#ifdef __ANDROID_VNDK__
+EXPORT
+camera_status_t ACameraManager_getTagFromName(ACameraManager *mgr, const char* cameraId,
+        const char *name, /*out*/uint32_t *tag) {
+    ATRACE_CALL();
+    if (mgr == nullptr || cameraId == nullptr || name == nullptr) {
+        ALOGE("%s: invalid argument! mgr %p cameraId %p name %p",
+                __FUNCTION__, mgr, cameraId, name);
+        return ACAMERA_ERROR_INVALID_PARAMETER;
+    }
+    return mgr->getTagFromName(cameraId, name, tag);
+}
+#endif
diff --git a/camera/ndk/include/camera/NdkCameraManager.h b/camera/ndk/include/camera/NdkCameraManager.h
index 5c810bb..2cc8a97 100644
--- a/camera/ndk/include/camera/NdkCameraManager.h
+++ b/camera/ndk/include/camera/NdkCameraManager.h
@@ -374,6 +374,23 @@
         ACameraManager* manager,
         const ACameraManager_ExtendedAvailabilityCallbacks* callback) __INTRODUCED_IN(29);
 
+#ifdef __ANDROID_VNDK__
+/**
+ * Retrieve the tag value, given the tag name and camera id.
+ * This method is device specific since some metadata might be defined by device manufacturers
+ * and might only be accessible for specific cameras.
+ * @param manager The {@link ACameraManager} of interest.
+ * @param cameraId The cameraId, which is used to query camera characteristics.
+ * @param name The name of the tag being queried.
+ * @param tag The output tag assigned by this method.
+ *
+ * @return ACAMERA_OK only if the function call was successful.
+ */
+camera_status_t ACameraManager_getTagFromName(ACameraManager *manager, const char* cameraId,
+        const char *name, /*out*/uint32_t *tag)
+        __INTRODUCED_IN(29);
+#endif
+
 #endif /* __ANDROID_API__ >= 29 */
 
 __END_DECLS
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
index 575ee9d..70c887a 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.cpp
@@ -22,6 +22,8 @@
 #include "ACameraMetadata.h"
 #include "ndk_vendor/impl/ACameraDevice.h"
 #include "utils.h"
+#include <CameraMetadata.h>
+#include <camera_metadata_hidden.h>
 
 #include <utils/Vector.h>
 #include <cutils/properties.h>
@@ -587,6 +589,26 @@
     return ACAMERA_OK;
 }
 
+camera_status_t
+ACameraManager::getTagFromName(const char *cameraId, const char *name, uint32_t *tag) {
+    sp<ACameraMetadata> rawChars;
+    camera_status_t ret = getCameraCharacteristics(cameraId, &rawChars);
+    if (ret != ACAMERA_OK) {
+        ALOGE("%s, Cannot retrieve camera characteristics for camera id %s", __FUNCTION__,
+                cameraId);
+        return ACAMERA_ERROR_METADATA_NOT_FOUND;
+    }
+    const CameraMetadata& metadata = rawChars->getInternalData();
+    const camera_metadata_t *rawMetadata = metadata.getAndLock();
+    metadata_vendor_id_t vendorTagId = get_camera_metadata_vendor_id(rawMetadata);
+    metadata.unlock(rawMetadata);
+    sp<VendorTagDescriptorCache> vtCache = VendorTagDescriptorCache::getGlobalVendorTagCache();
+    sp<VendorTagDescriptor> vTags = nullptr;
+    vtCache->getVendorTagDescriptor(vendorTagId, &vTags);
+    status_t status= metadata.getTagFromName(name, vTags.get(), tag);
+    return status == OK ? ACAMERA_OK : ACAMERA_ERROR_METADATA_NOT_FOUND;
+}
+
 ACameraManager::~ACameraManager() {
 
 }
diff --git a/camera/ndk/ndk_vendor/impl/ACameraManager.h b/camera/ndk/ndk_vendor/impl/ACameraManager.h
index df69353..2c62d44 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraManager.h
+++ b/camera/ndk/ndk_vendor/impl/ACameraManager.h
@@ -204,6 +204,7 @@
     camera_status_t openCamera(const char* cameraId,
                                ACameraDevice_StateCallbacks* callback,
                                /*out*/ACameraDevice** device);
+    camera_status_t getTagFromName(const char *cameraId, const char *name, uint32_t *tag);
 
   private:
     enum {
diff --git a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
index 7368775..37de30a 100644
--- a/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
+++ b/camera/ndk/ndk_vendor/tests/AImageReaderVendorTest.cpp
@@ -799,6 +799,15 @@
     bool isBC = isCapabilitySupported(staticMetadata,
             ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
 
+    uint32_t namedTag = 0;
+    // Test that ACameraMetadata_getTagFromName works as expected for public tag
+    // names
+    camera_status_t status = ACameraManager_getTagFromName(mCameraManager, cameraId,
+            "android.control.aeMode", &namedTag);
+
+    ASSERT_EQ(status, ACAMERA_OK);
+    ASSERT_EQ(namedTag, ACAMERA_CONTROL_AE_MODE);
+
     ACameraMetadata_free(staticMetadata);
 
     if (!isBC) {
diff --git a/media/codec2/components/aom/C2SoftAomDec.cpp b/media/codec2/components/aom/C2SoftAomDec.cpp
index 4bcc2c6..df4dadb 100644
--- a/media/codec2/components/aom/C2SoftAomDec.cpp
+++ b/media/codec2/components/aom/C2SoftAomDec.cpp
@@ -78,6 +78,26 @@
                 .withSetter(ProfileLevelSetter, mSize)
                 .build());
 
+        mHdr10PlusInfoInput = C2StreamHdr10PlusInfo::input::AllocShared(0);
+        addParameter(
+                DefineParam(mHdr10PlusInfoInput, C2_PARAMKEY_INPUT_HDR10_PLUS_INFO)
+                .withDefault(mHdr10PlusInfoInput)
+                .withFields({
+                    C2F(mHdr10PlusInfoInput, m.value).any(),
+                })
+                .withSetter(Hdr10PlusInfoInputSetter)
+                .build());
+
+        mHdr10PlusInfoOutput = C2StreamHdr10PlusInfo::output::AllocShared(0);
+        addParameter(
+                DefineParam(mHdr10PlusInfoOutput, C2_PARAMKEY_OUTPUT_HDR10_PLUS_INFO)
+                .withDefault(mHdr10PlusInfoOutput)
+                .withFields({
+                    C2F(mHdr10PlusInfoOutput, m.value).any(),
+                })
+                .withSetter(Hdr10PlusInfoOutputSetter)
+                .build());
+
         addParameter(DefineParam(mMaxSize, C2_PARAMKEY_MAX_PICTURE_SIZE)
                          .withDefault(new C2StreamMaxPictureSizeTuning::output(
                              0u, 320, 240))
@@ -203,6 +223,18 @@
         return mDefaultColorAspects;
     }
 
+    static C2R Hdr10PlusInfoInputSetter(bool mayBlock, C2P<C2StreamHdr10PlusInfo::input> &me) {
+        (void)mayBlock;
+        (void)me;  // TODO: validate
+        return C2R::Ok();
+    }
+
+    static C2R Hdr10PlusInfoOutputSetter(bool mayBlock, C2P<C2StreamHdr10PlusInfo::output> &me) {
+        (void)mayBlock;
+        (void)me;  // TODO: validate
+        return C2R::Ok();
+    }
+
   private:
     std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel;
     std::shared_ptr<C2StreamPictureSizeInfo::output> mSize;
@@ -211,6 +243,8 @@
     std::shared_ptr<C2StreamColorInfo::output> mColorInfo;
     std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat;
     std::shared_ptr<C2StreamColorAspectsTuning::output> mDefaultColorAspects;
+    std::shared_ptr<C2StreamHdr10PlusInfo::input> mHdr10PlusInfoInput;
+    std::shared_ptr<C2StreamHdr10PlusInfo::output> mHdr10PlusInfoOutput;
 };
 
 C2SoftAomDec::C2SoftAomDec(const char* name, c2_node_id_t id,
@@ -341,7 +375,8 @@
                               const std::shared_ptr<C2GraphicBlock>& block) {
     std::shared_ptr<C2Buffer> buffer =
         createGraphicBuffer(block, C2Rect(mWidth, mHeight));
-    auto fillWork = [buffer, index](const std::unique_ptr<C2Work>& work) {
+    auto fillWork = [buffer, index, intf = this->mIntf](
+            const std::unique_ptr<C2Work>& work) {
         uint32_t flags = 0;
         if ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) &&
             (c2_cntr64_t(index) == work->input.ordinal.frameIndex)) {
@@ -353,6 +388,28 @@
         work->worklets.front()->output.buffers.push_back(buffer);
         work->worklets.front()->output.ordinal = work->input.ordinal;
         work->workletsProcessed = 1u;
+
+        for (const std::unique_ptr<C2Param> &param: work->input.configUpdate) {
+            if (param) {
+                C2StreamHdr10PlusInfo::input *hdr10PlusInfo =
+                        C2StreamHdr10PlusInfo::input::From(param.get());
+
+                if (hdr10PlusInfo != nullptr) {
+                    std::vector<std::unique_ptr<C2SettingResult>> failures;
+                    std::unique_ptr<C2Param> outParam = C2Param::CopyAsStream(
+                            *param.get(), true /*output*/, param->stream());
+                    c2_status_t err = intf->config(
+                            { outParam.get() }, C2_MAY_BLOCK, &failures);
+                    if (err == C2_OK) {
+                        work->worklets.front()->output.configUpdate.push_back(
+                                C2Param::Copy(*outParam.get()));
+                    } else {
+                        ALOGE("finishWork: Config update size failed");
+                    }
+                    break;
+                }
+            }
+        }
     };
     if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) {
         fillWork(work);
diff --git a/media/codec2/components/opus/C2SoftOpusEnc.cpp b/media/codec2/components/opus/C2SoftOpusEnc.cpp
index a0b2443..f1020c3 100644
--- a/media/codec2/components/opus/C2SoftOpusEnc.cpp
+++ b/media/codec2/components/opus/C2SoftOpusEnc.cpp
@@ -194,12 +194,12 @@
         return C2_BAD_VALUE;
     }
 
-    // Unconstrained VBR
-    if (opus_multistream_encoder_ctl(mEncoder, OPUS_SET_VBR(0) != OPUS_OK)) {
+    // Constrained VBR
+    if (opus_multistream_encoder_ctl(mEncoder, OPUS_SET_VBR(1) != OPUS_OK)) {
         ALOGE("failed to set vbr type");
         return C2_BAD_VALUE;
     }
-    if (opus_multistream_encoder_ctl(mEncoder, OPUS_SET_VBR_CONSTRAINT(0) !=
+    if (opus_multistream_encoder_ctl(mEncoder, OPUS_SET_VBR_CONSTRAINT(1) !=
             OPUS_OK)) {
         ALOGE("failed to set vbr constraint");
         return C2_BAD_VALUE;
diff --git a/media/codec2/sfplugin/utils/Codec2Mapper.cpp b/media/codec2/sfplugin/utils/Codec2Mapper.cpp
index d62944a..40160c7 100644
--- a/media/codec2/sfplugin/utils/Codec2Mapper.cpp
+++ b/media/codec2/sfplugin/utils/Codec2Mapper.cpp
@@ -379,11 +379,19 @@
 
 
 ALookup<C2Config::profile_t, int32_t> sAv1Profiles = {
-    { C2Config::PROFILE_AV1_0, AV1Profile0 },
-    { C2Config::PROFILE_AV1_1, AV1Profile1 },
-    { C2Config::PROFILE_AV1_2, AV1Profile2 },
+    // TODO: will need to disambiguate between Main8 and Main10
+    { C2Config::PROFILE_AV1_0, AV1ProfileMain8 },
+    { C2Config::PROFILE_AV1_0, AV1ProfileMain10 },
 };
 
+ALookup<C2Config::profile_t, int32_t> sAv1HdrProfiles = {
+    { C2Config::PROFILE_AV1_0, AV1ProfileMain10 },
+    { C2Config::PROFILE_AV1_0, AV1ProfileMain10HDR10 },
+};
+
+ALookup<C2Config::profile_t, int32_t> sAv1Hdr10PlusProfiles = {
+    { C2Config::PROFILE_AV1_0, AV1ProfileMain10HDR10Plus },
+};
 
 /**
  * A helper that passes through vendor extension profile and level values.
@@ -590,6 +598,10 @@
 };
 
 struct Av1ProfileLevelMapper : ProfileLevelMapperHelper {
+    Av1ProfileLevelMapper(bool isHdr = false, bool isHdr10Plus = false) :
+        ProfileLevelMapperHelper(),
+        mIsHdr(isHdr), mIsHdr10Plus(isHdr10Plus) {}
+
     virtual bool simpleMap(C2Config::level_t from, int32_t *to) {
         return sAv1Levels.map(from, to);
     }
@@ -597,11 +609,19 @@
         return sAv1Levels.map(from, to);
     }
     virtual bool simpleMap(C2Config::profile_t from, int32_t *to) {
-        return sAv1Profiles.map(from, to);
+        return mIsHdr10Plus ? sAv1Hdr10PlusProfiles.map(from, to) :
+                     mIsHdr ? sAv1HdrProfiles.map(from, to) :
+                              sAv1Profiles.map(from, to);
     }
     virtual bool simpleMap(int32_t from, C2Config::profile_t *to) {
-        return sAv1Profiles.map(from, to);
+        return mIsHdr10Plus ? sAv1Hdr10PlusProfiles.map(from, to) :
+                     mIsHdr ? sAv1HdrProfiles.map(from, to) :
+                              sAv1Profiles.map(from, to);
     }
+
+private:
+    bool mIsHdr;
+    bool mIsHdr10Plus;
 };
 
 } // namespace
diff --git a/media/extractors/aac/Android.bp b/media/extractors/aac/Android.bp
index a58167a..6fe5970 100644
--- a/media/extractors/aac/Android.bp
+++ b/media/extractors/aac/Android.bp
@@ -20,7 +20,7 @@
     name: "libaacextractor",
     relative_install_path: "extractors",
 
-    compile_multilib: "first",
+    compile_multilib: "both",
 
     cflags: [
         "-Werror",
diff --git a/media/extractors/amr/Android.bp b/media/extractors/amr/Android.bp
index 4bd933d..b26b2d8 100644
--- a/media/extractors/amr/Android.bp
+++ b/media/extractors/amr/Android.bp
@@ -18,7 +18,7 @@
     name: "libamrextractor",
     relative_install_path: "extractors",
 
-    compile_multilib: "first",
+    compile_multilib: "both",
 
     cflags: [
         "-Werror",
diff --git a/media/extractors/flac/Android.bp b/media/extractors/flac/Android.bp
index 3a3d051..3e83090 100644
--- a/media/extractors/flac/Android.bp
+++ b/media/extractors/flac/Android.bp
@@ -24,7 +24,7 @@
     name: "libflacextractor",
     relative_install_path: "extractors",
 
-    compile_multilib: "first",
+    compile_multilib: "both",
 
     cflags: [
         "-Werror",
diff --git a/media/extractors/midi/Android.bp b/media/extractors/midi/Android.bp
index 7d42e70..6790dd6 100644
--- a/media/extractors/midi/Android.bp
+++ b/media/extractors/midi/Android.bp
@@ -19,7 +19,7 @@
     name: "libmidiextractor",
     relative_install_path: "extractors",
 
-    compile_multilib: "first",
+    compile_multilib: "both",
 
     cflags: [
         "-Werror",
diff --git a/media/extractors/mkv/Android.bp b/media/extractors/mkv/Android.bp
index 1744d3d..7c94149 100644
--- a/media/extractors/mkv/Android.bp
+++ b/media/extractors/mkv/Android.bp
@@ -25,7 +25,7 @@
     name: "libmkvextractor",
     relative_install_path: "extractors",
 
-    compile_multilib: "first",
+    compile_multilib: "both",
 
     cflags: [
         "-Werror",
diff --git a/media/extractors/mp3/Android.bp b/media/extractors/mp3/Android.bp
index 4e2f248..168ef68 100644
--- a/media/extractors/mp3/Android.bp
+++ b/media/extractors/mp3/Android.bp
@@ -24,7 +24,7 @@
     name: "libmp3extractor",
     relative_install_path: "extractors",
 
-    compile_multilib: "first",
+    compile_multilib: "both",
 
     cflags: [
         "-Werror",
diff --git a/media/extractors/mp4/Android.bp b/media/extractors/mp4/Android.bp
index 1b308aa..9b9c931 100644
--- a/media/extractors/mp4/Android.bp
+++ b/media/extractors/mp4/Android.bp
@@ -32,7 +32,7 @@
     ],
     version_script: "exports.lds",
     relative_install_path: "extractors",
-    compile_multilib: "first",
+    compile_multilib: "both",
 }
 
 cc_library_shared {
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 5a31c58..e1bfb62 100755
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -338,13 +338,16 @@
             return MEDIA_MIMETYPE_VIDEO_HEVC;
         case FOURCC("ac-4"):
             return MEDIA_MIMETYPE_AUDIO_AC4;
+        case FOURCC("Opus"):
+            return MEDIA_MIMETYPE_AUDIO_OPUS;
 
         case FOURCC("twos"):
         case FOURCC("sowt"):
             return MEDIA_MIMETYPE_AUDIO_RAW;
         case FOURCC("alac"):
             return MEDIA_MIMETYPE_AUDIO_ALAC;
-
+        case FOURCC("fLaC"):
+            return MEDIA_MIMETYPE_AUDIO_FLAC;
         case FOURCC("av01"):
             return MEDIA_MIMETYPE_VIDEO_AV1;
         case FOURCC(".mp3"):
@@ -1640,9 +1643,11 @@
         case FOURCC("enca"):
         case FOURCC("samr"):
         case FOURCC("sawb"):
+        case FOURCC("Opus"):
         case FOURCC("twos"):
         case FOURCC("sowt"):
         case FOURCC("alac"):
+        case FOURCC("fLaC"):
         case FOURCC(".mp3"):
         case 0x6D730055: // "ms U" mp3 audio
         {
@@ -1729,6 +1734,47 @@
             AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, num_channels);
             AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, sample_rate);
 
+            if (chunk_type == FOURCC("Opus")) {
+                uint8_t opusInfo[19];
+                data_offset += sizeof(buffer);
+                // Read Opus Header
+                if (mDataSource->readAt(
+                        data_offset, opusInfo, sizeof(opusInfo)) < (ssize_t)sizeof(opusInfo)) {
+                    return ERROR_IO;
+                }
+
+                // OpusHeader must start with this magic sequence
+                // http://wiki.xiph.org/OggOpus#ID_Header
+                strncpy((char *)opusInfo, "OpusHead", 8);
+
+                // Read Opus Specific Box values
+                size_t opusOffset = 10;
+                uint16_t pre_skip = U16_AT(&opusInfo[opusOffset]);
+                uint32_t sample_rate = U32_AT(&opusInfo[opusOffset + 2]);
+                uint16_t out_gain = U16_AT(&opusInfo[opusOffset + 6]);
+
+                // Convert Opus Specific Box values. ParseOpusHeader expects
+                // the values in LE, however MP4 stores these values as BE
+                // https://opus-codec.org/docs/opus_in_isobmff.html#4.3.2
+                memcpy(&opusInfo[opusOffset], &pre_skip, sizeof(pre_skip));
+                memcpy(&opusInfo[opusOffset + 2], &sample_rate, sizeof(sample_rate));
+                memcpy(&opusInfo[opusOffset + 6], &out_gain, sizeof(out_gain));
+
+                int64_t codecDelay = 6500000;
+                int64_t seekPreRollNs = 80000000;  // Fixed 80 msec
+
+                AMediaFormat_setBuffer(mLastTrack->meta,
+                            AMEDIAFORMAT_KEY_CSD_0, opusInfo, sizeof(opusInfo));
+                AMediaFormat_setBuffer(mLastTrack->meta,
+                        AMEDIAFORMAT_KEY_CSD_1, &codecDelay, sizeof(codecDelay));
+                AMediaFormat_setBuffer(mLastTrack->meta,
+                        AMEDIAFORMAT_KEY_CSD_2, &seekPreRollNs, sizeof(seekPreRollNs));
+
+                data_offset += sizeof(opusInfo);
+                *offset = data_offset;
+                CHECK_EQ(*offset, stop_offset);
+            }
+
             if (chunk_type == FOURCC("alac")) {
 
                 // See 'external/alac/ALACMagicCookieDescription.txt for the detail'.
@@ -1766,6 +1812,29 @@
                 CHECK_EQ(*offset, stop_offset);
             }
 
+            if (chunk_type == FOURCC("fLaC")) {
+
+                // From https://github.com/xiph/flac/blob/master/doc/isoflac.txt
+                // 4 for mime, 4 for blockType and BlockLen, 34 for metadata
+                uint8_t flacInfo[4 + 4 + 34];
+                // skipping dFla, version
+                data_offset += sizeof(buffer) + 12;
+                size_t flacOffset = 4;
+                // Add flaC header mime type to CSD
+                strncpy((char *)flacInfo, "fLaC", 4);
+                if (mDataSource->readAt(
+                        data_offset, flacInfo + flacOffset, sizeof(flacInfo) - flacOffset) <
+                        (ssize_t)sizeof(flacInfo) - flacOffset) {
+                    return ERROR_IO;
+                }
+                data_offset += sizeof(flacInfo) - flacOffset;
+
+                AMediaFormat_setBuffer(mLastTrack->meta, AMEDIAFORMAT_KEY_CSD_0, flacInfo,
+                                       sizeof(flacInfo));
+                *offset = data_offset;
+                CHECK_EQ(*offset, stop_offset);
+            }
+
             while (*offset < stop_offset) {
                 status_t err = parseChunk(offset, depth + 1);
                 if (err != OK) {
diff --git a/media/extractors/mpeg2/Android.bp b/media/extractors/mpeg2/Android.bp
index 0f0c72c..14f49ae 100644
--- a/media/extractors/mpeg2/Android.bp
+++ b/media/extractors/mpeg2/Android.bp
@@ -40,7 +40,7 @@
     name: "libmpeg2extractor",
     relative_install_path: "extractors",
 
-    compile_multilib: "first",
+    compile_multilib: "both",
 
     cflags: [
         "-Werror",
diff --git a/media/extractors/mpeg2/ExtractorBundle.cpp b/media/extractors/mpeg2/ExtractorBundle.cpp
index 946a2a9..a7c756b 100644
--- a/media/extractors/mpeg2/ExtractorBundle.cpp
+++ b/media/extractors/mpeg2/ExtractorBundle.cpp
@@ -29,6 +29,8 @@
 
 static const char *extensions[] = {
    "m2p",
+   "m2ts",
+   "mts",
    "ts",
    NULL
 };
diff --git a/media/extractors/mpeg2/MPEG2TSExtractor.cpp b/media/extractors/mpeg2/MPEG2TSExtractor.cpp
index 49dd0b4..50ce657 100644
--- a/media/extractors/mpeg2/MPEG2TSExtractor.cpp
+++ b/media/extractors/mpeg2/MPEG2TSExtractor.cpp
@@ -238,6 +238,12 @@
       mParser(new ATSParser),
       mLastSyncEvent(0),
       mOffset(0) {
+    char header;
+    if (source->readAt(0, &header, 1) == 1 && header == 0x47) {
+        mHeaderSkip = 0;
+    } else {
+        mHeaderSkip = 4;
+    }
     init();
 }
 
@@ -460,7 +466,7 @@
     Mutex::Autolock autoLock(mLock);
 
     uint8_t packet[kTSPacketSize];
-    ssize_t n = mDataSource->readAt(mOffset, packet, kTSPacketSize);
+    ssize_t n = mDataSource->readAt(mOffset + mHeaderSkip, packet, kTSPacketSize);
 
     if (n < (ssize_t)kTSPacketSize) {
         if (n >= 0) {
@@ -470,7 +476,7 @@
     }
 
     ATSParser::SyncEvent event(mOffset);
-    mOffset += n;
+    mOffset += mHeaderSkip + n;
     status_t err = mParser->feedTSPacket(packet, kTSPacketSize, &event);
     if (event.hasReturnedData()) {
         if (isInit) {
@@ -539,15 +545,15 @@
                 break;
             }
 
-            ssize_t n = mDataSource->readAt(offset, packet, kTSPacketSize);
+            ssize_t n = mDataSource->readAt(offset+mHeaderSkip, packet, kTSPacketSize);
             if (n < 0) {
                 return n;
             } else if (n < (ssize_t)kTSPacketSize) {
                 break;
             }
 
-            offset += kTSPacketSize;
-            bytesRead += kTSPacketSize;
+            offset += kTSPacketSize + mHeaderSkip;
+            bytesRead += kTSPacketSize + mHeaderSkip;
             err = parser->feedTSPacket(packet, kTSPacketSize, &ev);
             if (err != OK) {
                 return err;
@@ -791,7 +797,17 @@
         char header;
         if (source->readAt(kTSPacketSize * i, &header, 1) != 1
                 || header != 0x47) {
-            return false;
+            // not ts file, check if m2ts file
+            for (int j = 0; j < 5; ++j) {
+                char headers[5];
+                if (source->readAt((kTSPacketSize + 4) * j, &headers, 5) != 5
+                    || headers[4] != 0x47) {
+                    // not m2ts file too, return
+                    return false;
+                }
+            }
+            ALOGV("this is m2ts file\n");
+            break;
         }
     }
 
diff --git a/media/extractors/mpeg2/MPEG2TSExtractor.h b/media/extractors/mpeg2/MPEG2TSExtractor.h
index 2537d3b..dcd1e7b 100644
--- a/media/extractors/mpeg2/MPEG2TSExtractor.h
+++ b/media/extractors/mpeg2/MPEG2TSExtractor.h
@@ -102,6 +102,7 @@
 
     status_t  estimateDurationsFromTimesUsAtEnd();
 
+    size_t mHeaderSkip;
     DISALLOW_EVIL_CONSTRUCTORS(MPEG2TSExtractor);
 };
 
diff --git a/media/extractors/ogg/Android.bp b/media/extractors/ogg/Android.bp
index 604ec59..fd03f64 100644
--- a/media/extractors/ogg/Android.bp
+++ b/media/extractors/ogg/Android.bp
@@ -26,7 +26,7 @@
     name: "liboggextractor",
     relative_install_path: "extractors",
 
-    compile_multilib: "first",
+    compile_multilib: "both",
 
     cflags: [
         "-Werror",
diff --git a/media/extractors/ogg/OggExtractor.cpp b/media/extractors/ogg/OggExtractor.cpp
index b63ae6b..72b94bb 100644
--- a/media/extractors/ogg/OggExtractor.cpp
+++ b/media/extractors/ogg/OggExtractor.cpp
@@ -323,6 +323,7 @@
       mFirstDataOffset(-1),
       mHapticChannelCount(0) {
     mCurrentPage.mNumSegments = 0;
+    mCurrentPage.mFlags = 0;
 
     vorbis_info_init(&mVi);
     vorbis_comment_init(&mVc);
@@ -414,19 +415,18 @@
 
     ALOGV("prevPageOffset at %lld, pageOffset at %lld",
             (long long)prevPageOffset, (long long)pageOffset);
-
+    uint8_t flag = 0;
     for (;;) {
         Page prevPage;
         ssize_t n = readPage(prevPageOffset, &prevPage);
 
         if (n <= 0) {
-            return (status_t)n;
+            return (flag & 0x4) ? OK : (status_t)n;
         }
-
+        flag = prevPage.mFlags;
         prevPageOffset += n;
-
+        *granulePos = prevPage.mGranulePosition;
         if (prevPageOffset == pageOffset) {
-            *granulePos = prevPage.mGranulePosition;
             return OK;
         }
     }
@@ -688,7 +688,7 @@
         TRESPASS();
     }
 
-    uint32_t numSamples = frameSizeUs * numFrames * kOpusSampleRate / 1000000;
+    uint32_t numSamples = (uint32_t)((uint64_t)frameSizeUs * numFrames * kOpusSampleRate) / 1000000;
     return numSamples;
 }
 
@@ -868,6 +868,7 @@
         CHECK_EQ(mNextLaceIndex, mCurrentPage.mNumSegments);
 
         mOffset += mCurrentPageSize;
+        uint8_t flag = mCurrentPage.mFlags;
         ssize_t n = readPage(mOffset, &mCurrentPage);
 
         if (n <= 0) {
@@ -878,6 +879,7 @@
 
             ALOGV("readPage returned %zd", n);
 
+            if (flag & 0x04) return AMEDIA_ERROR_END_OF_STREAM;
             return (media_status_t) n;
         }
 
diff --git a/media/extractors/wav/Android.bp b/media/extractors/wav/Android.bp
index 7e89271..15fd796 100644
--- a/media/extractors/wav/Android.bp
+++ b/media/extractors/wav/Android.bp
@@ -21,7 +21,7 @@
     name: "libwavextractor",
     relative_install_path: "extractors",
 
-    compile_multilib: "first",
+    compile_multilib: "both",
 
     cflags: [
         "-Werror",
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index e9b6fb1..03bd6ce 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -59,6 +59,7 @@
         "IEffectClient.cpp",
         "ToneGenerator.cpp",
         "PlayerBase.cpp",
+        "RecordingActivityTracker.cpp",
         "TrackPlayerBase.cpp",
     ],
     shared_libs: [
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index f07be46..a1b04ca 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -22,7 +22,11 @@
 #include <android-base/macros.h>
 #include <sys/resource.h>
 
+#include <audiomanager/AudioManager.h>
+#include <audiomanager/IAudioManager.h>
+#include <binder/Binder.h>
 #include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
 #include <media/AudioRecord.h>
 #include <utils/Log.h>
 #include <private/media/AudioTrackShared.h>
@@ -173,7 +177,7 @@
         }
         // No lock here: worst case we remove a NULL callback which will be a nop
         if (mDeviceCallback != 0 && mInput != AUDIO_IO_HANDLE_NONE) {
-            AudioSystem::removeAudioDeviceCallback(this, mInput);
+            AudioSystem::removeAudioDeviceCallback(this, mInput, mPortId);
         }
         IInterface::asBinder(mAudioRecord)->unlinkToDeath(mDeathNotifier, this);
         mAudioRecord.clear();
@@ -219,6 +223,8 @@
           inputSource, sampleRate, format, channelMask, frameCount, notificationFrames,
           sessionId, transferType, flags, String8(mOpPackageName).string(), uid, pid);
 
+    mTracker.reset(new RecordingActivityTracker());
+
     mSelectedDeviceId = selectedDeviceId;
     mSelectedMicDirection = selectedMicDirection;
     mSelectedMicFieldDimension = microphoneFieldDimension;
@@ -396,6 +402,7 @@
     // This is legacy behavior.  This is not done in stop() to avoid a race condition
     // where the last marker event is issued twice.
     mMarkerReached = false;
+    // mActive is checked by restoreRecord_l
     mActive = true;
 
     status_t status = NO_ERROR;
@@ -416,7 +423,9 @@
     if (status != NO_ERROR) {
         mActive = false;
         ALOGE("%s(%d): status %d", __func__, mPortId, status);
+        mMediaMetrics.markError(status, __FUNCTION__);
     } else {
+        mTracker->recordingStarted();
         sp<AudioRecordThread> t = mAudioRecordThread;
         if (t != 0) {
             t->resume();
@@ -429,10 +438,6 @@
         // we've successfully started, log that time
         mMediaMetrics.logStart(systemTime());
     }
-
-    if (status != NO_ERROR) {
-        mMediaMetrics.markError(status, __FUNCTION__);
-    }
     return status;
 }
 
@@ -447,6 +452,7 @@
     mActive = false;
     mProxy->interrupt();
     mAudioRecord->stop();
+    mTracker->recordingStopped();
 
     // Note: legacy handling - stop does not clear record marker and
     // periodic update position; we update those on start().
@@ -711,6 +717,7 @@
         }
     }
     input.opPackageName = opPackageName;
+    input.riid = mTracker->getRiid();
 
     input.flags = mFlags;
     // The notification frame count is the period between callbacks, as suggested by the client
@@ -783,14 +790,13 @@
     mAudioRecord = record;
     mCblkMemory = output.cblk;
     mBufferMemory = output.buffers;
-    mPortId = output.portId;
     IPCThreadState::self()->flushCommands();
 
     mCblk = cblk;
     // note that output.frameCount is the (possibly revised) value of mReqFrameCount
     if (output.frameCount < mReqFrameCount || (mReqFrameCount == 0 && output.frameCount == 0)) {
         ALOGW("%s(%d): Requested frameCount %zu but received frameCount %zu",
-              __func__, mPortId,
+              __func__, output.portId,
               mReqFrameCount,  output.frameCount);
     }
 
@@ -798,19 +804,20 @@
     // The computation is done on server side.
     if (mNotificationFramesReq > 0 && output.notificationFrameCount != mNotificationFramesReq) {
         ALOGW("%s(%d): Server adjusted notificationFrames from %u to %zu for frameCount %zu",
-                __func__, mPortId,
+                __func__, output.portId,
                 mNotificationFramesReq, output.notificationFrameCount, output.frameCount);
     }
     mNotificationFramesAct = (uint32_t)output.notificationFrameCount;
 
     //mInput != input includes the case where mInput == AUDIO_IO_HANDLE_NONE for first creation
-    if (mDeviceCallback != 0 && mInput != output.inputId) {
+    if (mDeviceCallback != 0) {
         if (mInput != AUDIO_IO_HANDLE_NONE) {
-            AudioSystem::removeAudioDeviceCallback(this, mInput);
+            AudioSystem::removeAudioDeviceCallback(this, mInput, mPortId);
         }
-        AudioSystem::addAudioDeviceCallback(this, output.inputId);
+        AudioSystem::addAudioDeviceCallback(this, output.inputId, output.portId);
     }
 
+    mPortId = output.portId;
     // We retain a copy of the I/O handle, but don't own the reference
     mInput = output.inputId;
     mRefreshRemaining = true;
@@ -1325,9 +1332,9 @@
     if (mInput != AUDIO_IO_HANDLE_NONE) {
         if (mDeviceCallback != 0) {
             ALOGW("%s(%d): callback already present!", __func__, mPortId);
-            AudioSystem::removeAudioDeviceCallback(this, mInput);
+            AudioSystem::removeAudioDeviceCallback(this, mInput, mPortId);
         }
-        status = AudioSystem::addAudioDeviceCallback(this, mInput);
+        status = AudioSystem::addAudioDeviceCallback(this, mInput, mPortId);
     }
     mDeviceCallback = callback;
     return status;
@@ -1347,7 +1354,7 @@
     }
     mDeviceCallback.clear();
     if (mInput != AUDIO_IO_HANDLE_NONE) {
-        AudioSystem::removeAudioDeviceCallback(this, mInput);
+        AudioSystem::removeAudioDeviceCallback(this, mInput, mPortId);
     }
     return NO_ERROR;
 }
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index de82d2b..d359f52 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -428,6 +428,7 @@
 
 audio_unique_id_t AudioSystem::newAudioUniqueId(audio_unique_id_use_t use)
 {
+    // Must not use AF as IDs will re-roll on audioserver restart, b/130369529.
     const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
     if (af == 0) return AUDIO_UNIQUE_ID_ALLOCATE;
     return af->newAudioUniqueId(use);
@@ -522,12 +523,10 @@
     if (ioDesc == 0 || ioDesc->mIoHandle == AUDIO_IO_HANDLE_NONE) return;
 
     audio_port_handle_t deviceId = AUDIO_PORT_HANDLE_NONE;
-    Vector<sp<AudioDeviceCallback>> callbacksToCall;
+    std::vector<sp<AudioDeviceCallback>> callbacksToCall;
     {
         Mutex::Autolock _l(mLock);
-        bool deviceValidOrChanged = false;
-        bool sendCallbacks = false;
-        ssize_t ioIndex = -1;
+        auto callbacks = std::map<audio_port_handle_t, wp<AudioDeviceCallback>>();
 
         switch (event) {
         case AUDIO_OUTPUT_OPENED:
@@ -545,17 +544,11 @@
             if (ioDesc->getDeviceId() != AUDIO_PORT_HANDLE_NONE) {
                 deviceId = ioDesc->getDeviceId();
                 if (event == AUDIO_OUTPUT_OPENED || event == AUDIO_INPUT_OPENED) {
-                    ioIndex = mAudioDeviceCallbackProxies.indexOfKey(ioDesc->mIoHandle);
-                    if (ioIndex >= 0) {
-                        sendCallbacks = true;
-                        deviceValidOrChanged = true;
+                    auto it = mAudioDeviceCallbacks.find(ioDesc->mIoHandle);
+                    if (it != mAudioDeviceCallbacks.end()) {
+                        callbacks = it->second;
                     }
                 }
-                if (event == AUDIO_OUTPUT_REGISTERED || event == AUDIO_INPUT_REGISTERED) {
-                    ioIndex = mAudioDeviceCallbackProxies.indexOfKey(ioDesc->mIoHandle);
-                    sendCallbacks = (ioIndex >= 0)
-                            && !mAudioDeviceCallbackProxies.valueAt(ioIndex).notifiedOnce();
-                }
             }
             ALOGV("ioConfigChanged() new %s %s %d samplingRate %u, format %#x channel mask %#x "
                     "frameCount %zu deviceId %d",
@@ -577,7 +570,7 @@
                   event == AUDIO_OUTPUT_CLOSED ? "output" : "input", ioDesc->mIoHandle);
 
             mIoDescriptors.removeItem(ioDesc->mIoHandle);
-            mAudioDeviceCallbackProxies.removeItem(ioDesc->mIoHandle);
+            mAudioDeviceCallbacks.erase(ioDesc->mIoHandle);
             } break;
 
         case AUDIO_OUTPUT_CONFIG_CHANGED:
@@ -592,10 +585,11 @@
             mIoDescriptors.replaceValueFor(ioDesc->mIoHandle, ioDesc);
 
             if (deviceId != ioDesc->getDeviceId()) {
-                deviceValidOrChanged = true;
                 deviceId = ioDesc->getDeviceId();
-                ioIndex = mAudioDeviceCallbackProxies.indexOfKey(ioDesc->mIoHandle);
-                sendCallbacks = ioIndex >= 0;
+                auto it = mAudioDeviceCallbacks.find(ioDesc->mIoHandle);
+                if (it != mAudioDeviceCallbacks.end()) {
+                    callbacks = it->second;
+                }
             }
             ALOGV("ioConfigChanged() new config for %s %d samplingRate %u, format %#x "
                     "channel mask %#x frameCount %zu frameCountHAL %zu deviceId %d",
@@ -605,35 +599,40 @@
                     ioDesc->getDeviceId());
 
         } break;
-        }
-
-        // sendCallbacks true =>  ioDesc->mIoHandle and deviceId are valid
-        if (sendCallbacks) {
-            AudioDeviceCallbackProxies &callbackProxies =
-                mAudioDeviceCallbackProxies.editValueAt(ioIndex);
-            for (size_t i = 0; i < callbackProxies.size(); ) {
-                sp<AudioDeviceCallback> callback = callbackProxies[i]->callback();
-                if (callback.get() != nullptr) {
-                    // Call the callback only if the device actually changed, the input or output
-                    // was opened or closed or the client was newly registered and the callback
-                    // was never called
-                    if (!callbackProxies[i]->notifiedOnce() || deviceValidOrChanged) {
-                        callbacksToCall.add(callback);
-                        callbackProxies[i]->setNotifiedOnce();
-                    }
-                    i++;
-                } else {
-                    callbackProxies.removeAt(i);
+        case AUDIO_CLIENT_STARTED: {
+            sp<AudioIoDescriptor> oldDesc = getIoDescriptor_l(ioDesc->mIoHandle);
+            if (oldDesc == 0) {
+                ALOGW("ioConfigChanged() start client on unknown io! %d", ioDesc->mIoHandle);
+                break;
+            }
+            ALOGV("ioConfigChanged() AUDIO_CLIENT_STARTED  io %d port %d num callbacks %zu",
+                ioDesc->mIoHandle, ioDesc->mPortId, mAudioDeviceCallbacks.size());
+            oldDesc->mPatch = ioDesc->mPatch;
+            auto it = mAudioDeviceCallbacks.find(ioDesc->mIoHandle);
+            if (it != mAudioDeviceCallbacks.end()) {
+                auto cbks = it->second;
+                auto it2 = cbks.find(ioDesc->mPortId);
+                if (it2 != cbks.end()) {
+                   callbacks.emplace(ioDesc->mPortId, it2->second);
+                   deviceId = oldDesc->getDeviceId();
                 }
             }
-            callbackProxies.setNotifiedOnce();
+        } break;
+        }
+
+        for (auto wpCbk : callbacks) {
+            sp<AudioDeviceCallback> spCbk = wpCbk.second.promote();
+            if (spCbk != nullptr) {
+                callbacksToCall.push_back(spCbk);
+            }
         }
     }
 
     // Callbacks must be called without mLock held. May lead to dead lock if calling for
     // example getRoutedDevice that updates the device and tries to acquire mLock.
-    for (size_t i = 0; i < callbacksToCall.size(); i++) {
-        callbacksToCall[i]->onAudioDeviceUpdate(ioDesc->mIoHandle, deviceId);
+    for (auto cb  : callbacksToCall) {
+        // If callbacksToCall is not empty, it implies ioDesc->mIoHandle and deviceId are valid
+        cb->onAudioDeviceUpdate(ioDesc->mIoHandle, deviceId);
     }
 }
 
@@ -686,51 +685,34 @@
 }
 
 status_t AudioSystem::AudioFlingerClient::addAudioDeviceCallback(
-        const wp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo)
+        const wp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo,
+        audio_port_handle_t portId)
 {
+    ALOGV("%s audioIo %d portId %d", __func__, audioIo, portId);
     Mutex::Autolock _l(mLock);
-    AudioDeviceCallbackProxies callbackProxies;
-    ssize_t ioIndex = mAudioDeviceCallbackProxies.indexOfKey(audioIo);
-    if (ioIndex >= 0) {
-        callbackProxies = mAudioDeviceCallbackProxies.valueAt(ioIndex);
+    auto& callbacks = mAudioDeviceCallbacks.emplace(audioIo, std::map<audio_port_handle_t, wp<AudioDeviceCallback>>()).first->second;
+    auto result = callbacks.try_emplace(portId, callback);
+    if (!result.second) {
+        return INVALID_OPERATION;
     }
-
-    for (size_t cbIndex = 0; cbIndex < callbackProxies.size(); cbIndex++) {
-        sp<AudioDeviceCallback> cbk = callbackProxies[cbIndex]->callback();
-        if (cbk.get() == callback.unsafe_get()) {
-            return INVALID_OPERATION;
-        }
-    }
-    callbackProxies.add(new AudioDeviceCallbackProxy(callback));
-    callbackProxies.resetNotifiedOnce();
-    mAudioDeviceCallbackProxies.replaceValueFor(audioIo, callbackProxies);
     return NO_ERROR;
 }
 
 status_t AudioSystem::AudioFlingerClient::removeAudioDeviceCallback(
-        const wp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo)
+        const wp<AudioDeviceCallback>& callback __unused, audio_io_handle_t audioIo,
+        audio_port_handle_t portId)
 {
+    ALOGV("%s audioIo %d portId %d", __func__, audioIo, portId);
     Mutex::Autolock _l(mLock);
-    ssize_t ioIndex = mAudioDeviceCallbackProxies.indexOfKey(audioIo);
-    if (ioIndex < 0) {
+    auto it = mAudioDeviceCallbacks.find(audioIo);
+    if (it == mAudioDeviceCallbacks.end()) {
         return INVALID_OPERATION;
     }
-    AudioDeviceCallbackProxies callbackProxies = mAudioDeviceCallbackProxies.valueAt(ioIndex);
-    size_t cbIndex;
-    for (cbIndex = 0; cbIndex < callbackProxies.size(); cbIndex++) {
-        sp<AudioDeviceCallback> cbk = callbackProxies[cbIndex]->callback();
-        if (cbk.get() == callback.unsafe_get()) {
-            break;
-        }
-    }
-    if (cbIndex == callbackProxies.size()) {
+    if (it->second.erase(portId) == 0) {
         return INVALID_OPERATION;
     }
-    callbackProxies.removeAt(cbIndex);
-    if (callbackProxies.size() != 0) {
-        mAudioDeviceCallbackProxies.replaceValueFor(audioIo, callbackProxies);
-    } else {
-        mAudioDeviceCallbackProxies.removeItem(audioIo);
+    if (it->second.size() == 0) {
+        mAudioDeviceCallbacks.erase(audioIo);
     }
     return NO_ERROR;
 }
@@ -924,6 +906,7 @@
 
 status_t AudioSystem::getInputForAttr(const audio_attributes_t *attr,
                                 audio_io_handle_t *input,
+                                audio_unique_id_t riid,
                                 audio_session_t session,
                                 pid_t pid,
                                 uid_t uid,
@@ -936,7 +919,7 @@
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return NO_INIT;
     return aps->getInputForAttr(
-            attr, input, session, pid, uid, opPackageName,
+            attr, input, riid, session, pid, uid, opPackageName,
             config, flags, selectedDeviceId, portId);
 }
 
@@ -1269,13 +1252,14 @@
 }
 
 status_t AudioSystem::addAudioDeviceCallback(
-        const wp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo)
+        const wp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo,
+        audio_port_handle_t portId)
 {
     const sp<AudioFlingerClient> afc = getAudioFlingerClient();
     if (afc == 0) {
         return NO_INIT;
     }
-    status_t status = afc->addAudioDeviceCallback(callback, audioIo);
+    status_t status = afc->addAudioDeviceCallback(callback, audioIo, portId);
     if (status == NO_ERROR) {
         const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
         if (af != 0) {
@@ -1286,13 +1270,14 @@
 }
 
 status_t AudioSystem::removeAudioDeviceCallback(
-        const wp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo)
+        const wp<AudioDeviceCallback>& callback, audio_io_handle_t audioIo,
+        audio_port_handle_t portId)
 {
     const sp<AudioFlingerClient> afc = getAudioFlingerClient();
     if (afc == 0) {
         return NO_INIT;
     }
-    return afc->removeAudioDeviceCallback(callback, audioIo);
+    return afc->removeAudioDeviceCallback(callback, audioIo, portId);
 }
 
 audio_port_handle_t AudioSystem::getDeviceIdForIo(audio_io_handle_t audioIo)
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index bd48f56..9387d4d 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -309,7 +309,7 @@
         }
         // No lock here: worst case we remove a NULL callback which will be a nop
         if (mDeviceCallback != 0 && mOutput != AUDIO_IO_HANDLE_NONE) {
-            AudioSystem::removeAudioDeviceCallback(this, mOutput);
+            AudioSystem::removeAudioDeviceCallback(this, mOutput, mPortId);
         }
         IInterface::asBinder(mAudioTrack)->unlinkToDeath(mDeathNotifier, this);
         mAudioTrack.clear();
@@ -1495,7 +1495,6 @@
     mAfFrameCount = output.afFrameCount;
     mAfSampleRate = output.afSampleRate;
     mAfLatency = output.afLatencyMs;
-    mPortId = output.portId;
 
     mLatency = mAfLatency + (1000LL * mFrameCount) / mSampleRate;
 
@@ -1543,14 +1542,15 @@
     mFlags = output.flags;
 
     //mOutput != output includes the case where mOutput == AUDIO_IO_HANDLE_NONE for first creation
-    if (mDeviceCallback != 0 && mOutput != output.outputId) {
+    if (mDeviceCallback != 0) {
         if (mOutput != AUDIO_IO_HANDLE_NONE) {
-            AudioSystem::removeAudioDeviceCallback(this, mOutput);
+            AudioSystem::removeAudioDeviceCallback(this, mOutput, mPortId);
         }
-        AudioSystem::addAudioDeviceCallback(this, output.outputId);
+        AudioSystem::addAudioDeviceCallback(this, output.outputId, output.portId);
         callbackAdded = true;
     }
 
+    mPortId = output.portId;
     // We retain a copy of the I/O handle, but don't own the reference
     mOutput = output.outputId;
     mRefreshRemaining = true;
@@ -1615,7 +1615,7 @@
 exit:
     if (status != NO_ERROR && callbackAdded) {
         // note: mOutput is always valid is callbackAdded is true
-        AudioSystem::removeAudioDeviceCallback(this, mOutput);
+        AudioSystem::removeAudioDeviceCallback(this, mOutput, mPortId);
     }
 
     mStatus = status;
@@ -2922,6 +2922,7 @@
 
 status_t AudioTrack::addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback)
 {
+
     if (callback == 0) {
         ALOGW("%s(%d): adding NULL callback!", __func__, mPortId);
         return BAD_VALUE;
@@ -2935,9 +2936,9 @@
     if (mOutput != AUDIO_IO_HANDLE_NONE) {
         if (mDeviceCallback != 0) {
             ALOGW("%s(%d): callback already present!", __func__, mPortId);
-            AudioSystem::removeAudioDeviceCallback(this, mOutput);
+            AudioSystem::removeAudioDeviceCallback(this, mOutput, mPortId);
         }
-        status = AudioSystem::addAudioDeviceCallback(this, mOutput);
+        status = AudioSystem::addAudioDeviceCallback(this, mOutput, mPortId);
     }
     mDeviceCallback = callback;
     return status;
@@ -2957,7 +2958,7 @@
     }
     mDeviceCallback.clear();
     if (mOutput != AUDIO_IO_HANDLE_NONE) {
-        AudioSystem::removeAudioDeviceCallback(this, mOutput);
+        AudioSystem::removeAudioDeviceCallback(this, mOutput, mPortId);
     }
     return NO_ERROR;
 }
@@ -2979,6 +2980,7 @@
             mRoutedDeviceId = deviceId;
         }
     }
+
     if (callback.get() != nullptr) {
         callback->onAudioDeviceUpdate(mOutput, mRoutedDeviceId);
     }
diff --git a/media/libaudioclient/IAudioFlingerClient.cpp b/media/libaudioclient/IAudioFlingerClient.cpp
index b2dbc4c..47eb7dc 100644
--- a/media/libaudioclient/IAudioFlingerClient.cpp
+++ b/media/libaudioclient/IAudioFlingerClient.cpp
@@ -52,6 +52,7 @@
         data.writeInt64(ioDesc->mFrameCount);
         data.writeInt64(ioDesc->mFrameCountHAL);
         data.writeInt32(ioDesc->mLatency);
+        data.writeInt32(ioDesc->mPortId);
         remote()->transact(IO_CONFIG_CHANGED, data, &reply, IBinder::FLAG_ONEWAY);
     }
 };
@@ -76,6 +77,7 @@
             ioDesc->mFrameCount = data.readInt64();
             ioDesc->mFrameCountHAL = data.readInt64();
             ioDesc->mLatency = data.readInt32();
+            ioDesc->mPortId = data.readInt32();
             ioConfigChanged(event, ioDesc);
             return NO_ERROR;
         } break;
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 4a8bb52..9b4221c 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -305,6 +305,7 @@
 
     virtual status_t getInputForAttr(const audio_attributes_t *attr,
                                      audio_io_handle_t *input,
+                                     audio_unique_id_t riid,
                                      audio_session_t session,
                                      pid_t pid,
                                      uid_t uid,
@@ -334,6 +335,7 @@
         }
         data.write(attr, sizeof(audio_attributes_t));
         data.writeInt32(*input);
+        data.writeInt32(riid);
         data.writeInt32(session);
         data.writeInt32(pid);
         data.writeInt32(uid);
@@ -1511,6 +1513,7 @@
             data.read(&attr, sizeof(audio_attributes_t));
             sanetizeAudioAttributes(&attr);
             audio_io_handle_t input = (audio_io_handle_t)data.readInt32();
+            audio_unique_id_t riid = (audio_unique_id_t)data.readInt32();
             audio_session_t session = (audio_session_t)data.readInt32();
             pid_t pid = (pid_t)data.readInt32();
             uid_t uid = (uid_t)data.readInt32();
@@ -1521,7 +1524,7 @@
             audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
             audio_port_handle_t selectedDeviceId = (audio_port_handle_t) data.readInt32();
             audio_port_handle_t portId = (audio_port_handle_t)data.readInt32();
-            status_t status = getInputForAttr(&attr, &input, session, pid, uid,
+            status_t status = getInputForAttr(&attr, &input, riid, session, pid, uid,
                                               opPackageName, &config,
                                               flags, &selectedDeviceId, &portId);
             reply->writeInt32(status);
diff --git a/media/libaudioclient/IAudioPolicyServiceClient.cpp b/media/libaudioclient/IAudioPolicyServiceClient.cpp
index 52d8ccd..0f9580c 100644
--- a/media/libaudioclient/IAudioPolicyServiceClient.cpp
+++ b/media/libaudioclient/IAudioPolicyServiceClient.cpp
@@ -50,6 +50,7 @@
 }
 
 inline void readRecordClientInfoFromParcel(const Parcel& data, record_client_info_t *clientInfo) {
+    clientInfo->riid = (audio_unique_id_t) data.readInt32();
     clientInfo->uid = (uid_t) data.readUint32();
     clientInfo->session = (audio_session_t) data.readInt32();
     clientInfo->source = (audio_source_t) data.readInt32();
@@ -58,6 +59,7 @@
 }
 
 inline void writeRecordClientInfoToParcel(Parcel& data, const record_client_info_t *clientInfo) {
+    data.writeInt32((int32_t) clientInfo->riid);
     data.writeUint32((uint32_t) clientInfo->uid);
     data.writeInt32((int32_t) clientInfo->session);
     data.writeInt32((int32_t) clientInfo->source);
diff --git a/media/libaudioclient/RecordingActivityTracker.cpp b/media/libaudioclient/RecordingActivityTracker.cpp
new file mode 100644
index 0000000..bd10895
--- /dev/null
+++ b/media/libaudioclient/RecordingActivityTracker.cpp
@@ -0,0 +1,63 @@
+/*
+ * 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 <audiomanager/AudioManager.h>
+#include <audiomanager/IAudioManager.h>
+#include <binder/Binder.h>
+#include <binder/IServiceManager.h>
+#include <media/RecordingActivityTracker.h>
+
+namespace android {
+
+RecordingActivityTracker::RecordingActivityTracker()
+        : mRIId(RECORD_RIID_INVALID), mToken(new BBinder())
+{
+    // use checkService() to avoid blocking if audio service is not up yet
+    sp<IBinder> binder = defaultServiceManager()->checkService(String16("audio"));
+    if (binder != 0) {
+        mAudioManager = interface_cast<IAudioManager>(binder);
+    } else {
+        ALOGE("RecordingActivityTracker(): binding to audio service failed, service up?");
+    }
+}
+
+RecordingActivityTracker::~RecordingActivityTracker()
+{
+}
+
+audio_unique_id_t RecordingActivityTracker::getRiid()
+{
+    if (mRIId == RECORD_RIID_INVALID && mAudioManager) {
+        mRIId = mAudioManager->trackRecorder(mToken);
+    }
+    return mRIId;
+}
+
+void RecordingActivityTracker::recordingStarted()
+{
+    if (getRiid() != RECORD_RIID_INVALID && mAudioManager) {
+        mAudioManager->recorderEvent(mRIId, RECORDER_STATE_STARTED);
+    }
+}
+
+void RecordingActivityTracker::recordingStopped()
+{
+    if (getRiid() != RECORD_RIID_INVALID && mAudioManager) {
+        mAudioManager->recorderEvent(mRIId, RECORDER_STATE_STOPPED);
+    }
+}
+
+} // namespace android
diff --git a/media/libaudioclient/include/media/AudioIoDescriptor.h b/media/libaudioclient/include/media/AudioIoDescriptor.h
index 859f1a9..981d33a 100644
--- a/media/libaudioclient/include/media/AudioIoDescriptor.h
+++ b/media/libaudioclient/include/media/AudioIoDescriptor.h
@@ -28,6 +28,7 @@
     AUDIO_INPUT_OPENED,
     AUDIO_INPUT_CLOSED,
     AUDIO_INPUT_CONFIG_CHANGED,
+    AUDIO_CLIENT_STARTED,
 };
 
 // audio input/output descriptor used to cache output configurations in client process to avoid
@@ -37,7 +38,7 @@
     AudioIoDescriptor() :
         mIoHandle(AUDIO_IO_HANDLE_NONE),
         mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT), mChannelMask(AUDIO_CHANNEL_NONE),
-        mFrameCount(0), mFrameCountHAL(0), mLatency(0)
+        mFrameCount(0), mFrameCountHAL(0), mLatency(0), mPortId(AUDIO_PORT_HANDLE_NONE)
     {
         memset(&mPatch, 0, sizeof(struct audio_patch));
     }
@@ -66,6 +67,7 @@
     size_t                  mFrameCount;
     size_t                  mFrameCountHAL;
     uint32_t                mLatency;   // only valid for output
+    audio_port_handle_t     mPortId;    // valid for event AUDIO_CLIENT_STARTED
 };
 
 
diff --git a/media/libaudioclient/include/media/AudioPolicy.h b/media/libaudioclient/include/media/AudioPolicy.h
index 4b94c12..a40e019 100644
--- a/media/libaudioclient/include/media/AudioPolicy.h
+++ b/media/libaudioclient/include/media/AudioPolicy.h
@@ -119,11 +119,11 @@
 };
 
 
-// definitions for audio recording configuration updates
-// which update type is reported
-#define RECORD_CONFIG_EVENT_NONE -1
-#define RECORD_CONFIG_EVENT_START 1
-#define RECORD_CONFIG_EVENT_STOP  0
+// definitions for audio recording configuration updates;
+// keep in sync with AudioManager.java for values used from native code
+#define RECORD_CONFIG_EVENT_START  0
+#define RECORD_CONFIG_EVENT_STOP   1
+#define RECORD_CONFIG_EVENT_UPDATE 2
 
 static inline bool is_mix_loopback_render(uint32_t routeFlags) {
     return (routeFlags & MIX_ROUTE_FLAG_LOOP_BACK_AND_RENDER)
diff --git a/media/libaudioclient/include/media/AudioRecord.h b/media/libaudioclient/include/media/AudioRecord.h
index 9c81bb7..a3c0fe4 100644
--- a/media/libaudioclient/include/media/AudioRecord.h
+++ b/media/libaudioclient/include/media/AudioRecord.h
@@ -17,6 +17,9 @@
 #ifndef ANDROID_AUDIORECORD_H
 #define ANDROID_AUDIORECORD_H
 
+#include <memory>
+#include <vector>
+
 #include <binder/IMemory.h>
 #include <cutils/sched_policy.h>
 #include <media/AudioSystem.h>
@@ -24,9 +27,9 @@
 #include <media/MediaAnalyticsItem.h>
 #include <media/Modulo.h>
 #include <media/MicrophoneInfo.h>
+#include <media/RecordingActivityTracker.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
-#include <vector>
 
 #include "android/media/IAudioRecord.h"
 
@@ -618,6 +621,8 @@
     sp<AudioRecordThread>   mAudioRecordThread;
     mutable Mutex           mLock;
 
+    std::unique_ptr<RecordingActivityTracker> mTracker;
+
     // Current client state:  false = stopped, true = active.  Protected by mLock.  If more states
     // are added, consider changing this to enum State { ... } mState as in AudioTrack.
     bool                    mActive;
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index d180bbc..f79ec21 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -242,6 +242,7 @@
     // or release it with releaseInput().
     static status_t getInputForAttr(const audio_attributes_t *attr,
                                     audio_io_handle_t *input,
+                                    audio_unique_id_t riid,
                                     audio_session_t session,
                                     pid_t pid,
                                     uid_t uid,
@@ -437,32 +438,12 @@
                                          audio_port_handle_t deviceId) = 0;
     };
 
-    class AudioDeviceCallbackProxy : public RefBase
-    {
-    public:
-
-          AudioDeviceCallbackProxy(wp<AudioDeviceCallback> callback)
-              : mCallback(callback) {}
-          ~AudioDeviceCallbackProxy() override {}
-
-          sp<AudioDeviceCallback> callback() const { return mCallback.promote(); };
-
-          bool notifiedOnce() const { return mNotifiedOnce; }
-          void setNotifiedOnce() { mNotifiedOnce = true; }
-    private:
-        /**
-         * @brief mNotifiedOnce it forces the callback to be called at least once when
-         * registered with a VALID AudioDevice, and allows not to flood other listeners
-         * on this iohandle that already know the valid device.
-         */
-         bool mNotifiedOnce = false;
-         wp<AudioDeviceCallback> mCallback;
-    };
-
     static status_t addAudioDeviceCallback(const wp<AudioDeviceCallback>& callback,
-                                           audio_io_handle_t audioIo);
+                                           audio_io_handle_t audioIo,
+                                           audio_port_handle_t portId);
     static status_t removeAudioDeviceCallback(const wp<AudioDeviceCallback>& callback,
-                                              audio_io_handle_t audioIo);
+                                              audio_io_handle_t audioIo,
+                                              audio_port_handle_t portId);
 
     static audio_port_handle_t getDeviceIdForIo(audio_io_handle_t audioIo);
 
@@ -493,9 +474,11 @@
 
 
         status_t addAudioDeviceCallback(const wp<AudioDeviceCallback>& callback,
-                                               audio_io_handle_t audioIo);
+                                               audio_io_handle_t audioIo,
+                                               audio_port_handle_t portId);
         status_t removeAudioDeviceCallback(const wp<AudioDeviceCallback>& callback,
-                                           audio_io_handle_t audioIo);
+                                           audio_io_handle_t audioIo,
+                                           audio_port_handle_t portId);
 
         audio_port_handle_t getDeviceIdForIo(audio_io_handle_t audioIo);
 
@@ -503,26 +486,8 @@
         Mutex                               mLock;
         DefaultKeyedVector<audio_io_handle_t, sp<AudioIoDescriptor> >   mIoDescriptors;
 
-        class AudioDeviceCallbackProxies : public Vector<sp<AudioDeviceCallbackProxy>>
-        {
-        public:
-            /**
-             * @brief notifiedOnce ensures that if a client adds a callback, it must at least be
-             * called once with the device on which it will be routed to.
-             * @return true if already notified or nobody waits for a callback, false otherwise.
-             */
-            bool notifiedOnce() const { return (size() == 0) || mNotifiedOnce; }
-            void setNotifiedOnce() { mNotifiedOnce = true; }
-            void resetNotifiedOnce() { mNotifiedOnce = false; }
-        private:
-            /**
-             * @brief mNotifiedOnce it forces each callback to be called at least once when
-             * registered with a VALID AudioDevice
-             */
-            bool mNotifiedOnce = false;
-        };
-        DefaultKeyedVector<audio_io_handle_t, AudioDeviceCallbackProxies>
-                mAudioDeviceCallbackProxies;
+        std::map<audio_io_handle_t, std::map<audio_port_handle_t, wp<AudioDeviceCallback>>>
+                mAudioDeviceCallbacks;
         // cached values for recording getInputBufferSize() queries
         size_t                              mInBuffSize;    // zero indicates cache is invalid
         uint32_t                            mInSamplingRate;
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index dcc18b6..8ec8931 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -205,6 +205,9 @@
                 return DEAD_OBJECT;
             }
             opPackageName = parcel->readString16();
+            if (parcel->read(&riid, sizeof(audio_unique_id_t)) != NO_ERROR) {
+                return DEAD_OBJECT;
+            }
 
             /* input/output arguments*/
             (void)parcel->read(&flags, sizeof(audio_input_flags_t));
@@ -221,6 +224,7 @@
             (void)parcel->write(&config, sizeof(audio_config_base_t));
             (void)clientInfo.writeToParcel(parcel);
             (void)parcel->writeString16(opPackageName);
+            (void)parcel->write(&riid, sizeof(audio_unique_id_t));
 
             /* input/output arguments*/
             (void)parcel->write(&flags, sizeof(audio_input_flags_t));
@@ -236,6 +240,7 @@
         audio_config_base_t config;
         AudioClient clientInfo;
         String16 opPackageName;
+        audio_unique_id_t riid;
 
         /* input/output */
         audio_input_flags_t flags;
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index 11983d5..b639044 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -73,6 +73,7 @@
     virtual void releaseOutput(audio_port_handle_t portId) = 0;
     virtual status_t  getInputForAttr(const audio_attributes_t *attr,
                               audio_io_handle_t *input,
+                              audio_unique_id_t riid,
                               audio_session_t session,
                               pid_t pid,
                               uid_t uid,
diff --git a/media/libaudioclient/include/media/IAudioPolicyServiceClient.h b/media/libaudioclient/include/media/IAudioPolicyServiceClient.h
index 79008c3..47b31ee 100644
--- a/media/libaudioclient/include/media/IAudioPolicyServiceClient.h
+++ b/media/libaudioclient/include/media/IAudioPolicyServiceClient.h
@@ -31,6 +31,7 @@
 // ----------------------------------------------------------------------------
 
 struct record_client_info {
+    audio_unique_id_t riid;
     uid_t uid;
     audio_session_t session;
     audio_source_t source;
diff --git a/media/libaudioclient/include/media/RecordingActivityTracker.h b/media/libaudioclient/include/media/RecordingActivityTracker.h
new file mode 100644
index 0000000..9891a70
--- /dev/null
+++ b/media/libaudioclient/include/media/RecordingActivityTracker.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __ANDROID_RECORDING_ACTIVITY_TRACKER_H__
+#define __ANDROID_RECORDING_ACTIVITY_TRACKER_H__
+
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+class IAudioManager;
+class IBinder;
+
+class RecordingActivityTracker
+{
+public:
+    RecordingActivityTracker();
+    ~RecordingActivityTracker();
+    audio_unique_id_t getRiid();
+    void recordingStarted();
+    void recordingStopped();
+
+private:
+    sp<IAudioManager> mAudioManager;
+    audio_unique_id_t mRIId;
+    sp<IBinder>       mToken;
+};
+
+} // namespace android
+
+#endif // __ANDROID_RECORDING_ACTIVITY_TRACKER_H__
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 3b87462..317b5ec 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -2580,6 +2580,8 @@
         layerParams.nPLayerCountActual = numLayers - numBLayers;
         layerParams.nBLayerCountActual = numBLayers;
         layerParams.bBitrateRatiosSpecified = OMX_FALSE;
+        layerParams.nLayerCountMax = numLayers;
+        layerParams.nBLayerCountMax = numBLayers;
 
         err = mOMXNode->setParameter(
                 (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering,
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 2ca5eee..e56750b 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -1110,6 +1110,9 @@
             reset();
         }
         if (!isResourceError(err)) {
+            if (err == OK) {
+                disableLegacyBufferDropPostQ(surface);
+            }
             break;
         }
     }
@@ -1175,7 +1178,11 @@
     msg->setObject("surface", surface);
 
     sp<AMessage> response;
-    return PostAndAwaitResponse(msg, &response);
+    status_t result = PostAndAwaitResponse(msg, &response);
+    if (result == OK) {
+        disableLegacyBufferDropPostQ(surface);
+    }
+    return result;
 }
 
 status_t MediaCodec::createInputSurface(
diff --git a/media/libstagefright/SurfaceUtils.cpp b/media/libstagefright/SurfaceUtils.cpp
index 9e11a94..4c94baa 100644
--- a/media/libstagefright/SurfaceUtils.cpp
+++ b/media/libstagefright/SurfaceUtils.cpp
@@ -18,10 +18,13 @@
 #define LOG_TAG "SurfaceUtils"
 #include <utils/Log.h>
 
+#include <android/api-level.h>
 #include <media/hardware/VideoAPI.h>
 #include <media/stagefright/SurfaceUtils.h>
 #include <gui/Surface.h>
 
+extern "C" int android_get_application_target_sdk_version();
+
 namespace android {
 
 status_t setNativeWindowSizeFormatAndUsage(
@@ -291,5 +294,28 @@
 
     return err;
 }
+
+status_t disableLegacyBufferDropPostQ(const sp<Surface> &surface) {
+    sp<IGraphicBufferProducer> igbp =
+            surface ? surface->getIGraphicBufferProducer() : nullptr;
+    if (igbp) {
+        int targetSdk = android_get_application_target_sdk_version();
+        // When the caller is not an app (e.g. MediaPlayer in mediaserver)
+        // targetSdk is __ANDROID_API_FUTURE__.
+        bool drop =
+                targetSdk < __ANDROID_API_Q__ ||
+                targetSdk == __ANDROID_API_FUTURE__;
+        if (!drop) {
+            status_t err = igbp->setLegacyBufferDrop(false);
+            if (err == NO_ERROR) {
+                ALOGD("legacy buffer drop disabled: target sdk (%d)",
+                      targetSdk);
+            } else {
+                ALOGD("disabling legacy buffer drop failed: %d", err);
+            }
+        }
+    }
+    return NO_ERROR;
+}
 }  // namespace android
 
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 537e4c0..3de934f 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -1101,7 +1101,9 @@
     } else if (meta->findData(kKeyHVCC, &type, &data, &size)) {
         const uint8_t *ptr = (const uint8_t *)data;
 
-        if (size < 23 || ptr[0] != 1) {  // configurationVersion == 1
+        if (size < 23 || (ptr[0] != 1 && ptr[0] != 0)) {
+            // configurationVersion == 1 or 0
+            // 1 is what the standard dictates, but some old muxers may have used 0.
             ALOGE("b/23680780");
             return BAD_VALUE;
         }
diff --git a/media/libstagefright/VideoFrameSchedulerBase.cpp b/media/libstagefright/VideoFrameSchedulerBase.cpp
index 77107ff..0d1517b 100644
--- a/media/libstagefright/VideoFrameSchedulerBase.cpp
+++ b/media/libstagefright/VideoFrameSchedulerBase.cpp
@@ -115,6 +115,10 @@
 
 #endif
 
+// If overflow happens, the value is already incorrect, and no mater what value we get is OK.
+// And this part of calculation is not important, so it's OK to simply disable overflow check
+// instead of using double which makes code more complicated.
+__attribute__((no_sanitize("integer")))
 bool VideoFrameSchedulerBase::PLL::fit(
         nsecs_t phase, nsecs_t period, size_t numSamplesToUse,
         int64_t *a, int64_t *b, int64_t *err) {
diff --git a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
index c84614a..50d7724 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodecConstants.h
@@ -356,16 +356,18 @@
     }
 }
 
-constexpr int32_t AV1Profile0 = 0x01;
-constexpr int32_t AV1Profile1 = 0x02;
-constexpr int32_t AV1Profile2 = 0x04;
+constexpr int32_t AV1ProfileMain8 = 0x1;
+constexpr int32_t AV1ProfileMain10 = 0x2;
+constexpr int32_t AV1ProfileMain10HDR10 = 0x1000;
+constexpr int32_t AV1ProfileMain10HDR10Plus = 0x2000;
 
 inline static const char *asString_AV1Profile(int32_t i, const char *def = "??") {
     switch (i) {
-        case AV1Profile0:       return "0";
-        case AV1Profile1:       return "1";
-        case AV1Profile2:       return "2";
-        default:                return def;
+        case AV1ProfileMain8:           return "Main8";
+        case AV1ProfileMain10:          return "Main10HDR";
+        case AV1ProfileMain10HDR10:     return "Main10HDR10";
+        case AV1ProfileMain10HDR10Plus: return "Main10HDRPlus";
+        default:                        return def;
     }
 }
 
diff --git a/media/libstagefright/include/media/stagefright/SurfaceUtils.h b/media/libstagefright/include/media/stagefright/SurfaceUtils.h
index 689e458..ae55c65 100644
--- a/media/libstagefright/include/media/stagefright/SurfaceUtils.h
+++ b/media/libstagefright/include/media/stagefright/SurfaceUtils.h
@@ -19,8 +19,10 @@
 #define SURFACE_UTILS_H_
 
 #include <utils/Errors.h>
+#include <utils/StrongPointer.h>
 
 struct ANativeWindow;
+class Surface;
 
 namespace android {
 
@@ -40,6 +42,15 @@
 status_t nativeWindowConnect(ANativeWindow *surface, const char *reason);
 status_t nativeWindowDisconnect(ANativeWindow *surface, const char *reason);
 
+/**
+ * Disable buffer dropping behavior of BufferQueue if target sdk of application
+ * is Q or later. If the caller is not an app (e.g. MediaPlayer in mediaserver)
+ * retain buffer dropping behavior.
+ *
+ * @return NO_ERROR
+ */
+status_t disableLegacyBufferDropPostQ(const sp<Surface> &surface);
+
 } // namespace android
 
 #endif  // SURFACE_UTILS_H_
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 55db699..5e5ea11 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -46,6 +46,7 @@
 #include <cutils/properties.h>
 
 #include <system/audio.h>
+#include <audiomanager/AudioManager.h>
 
 #include "AudioFlinger.h"
 #include "NBAIO_Tee.h"
@@ -312,6 +313,7 @@
                  "%s does not support secondary outputs, ignoring them", __func__);
     } else {
         ret = AudioSystem::getInputForAttr(attr, &io,
+                                              RECORD_RIID_INVALID,
                                               actualSessionId,
                                               client.clientPid,
                                               client.clientUid,
@@ -699,8 +701,8 @@
         updatePid = true;
     }
     pid_t clientPid = input.clientInfo.clientPid;
+    const pid_t callingPid = IPCThreadState::self()->getCallingPid();
     if (updatePid) {
-        const pid_t callingPid = IPCThreadState::self()->getCallingPid();
         ALOGW_IF(clientPid != -1 && clientPid != callingPid,
                  "%s uid %d pid %d tried to pass itself off as pid %d",
                  __func__, callingUid, callingPid, clientPid);
@@ -785,7 +787,8 @@
                                       &output.frameCount, &output.notificationFrameCount,
                                       input.notificationsPerBuffer, input.speed,
                                       input.sharedBuffer, sessionId, &output.flags,
-                                      input.clientInfo.clientTid, clientUid, &lStatus, portId);
+                                      callingPid, input.clientInfo.clientTid, clientUid,
+                                      &lStatus, portId);
         LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (track == 0));
         // we don't abort yet if lStatus != NO_ERROR; there is still work to be done regardless
 
@@ -1839,8 +1842,8 @@
         updatePid = true;
     }
     pid_t clientPid = input.clientInfo.clientPid;
+    const pid_t callingPid = IPCThreadState::self()->getCallingPid();
     if (updatePid) {
-        const pid_t callingPid = IPCThreadState::self()->getCallingPid();
         ALOGW_IF(clientPid != -1 && clientPid != callingPid,
                  "%s uid %d pid %d tried to pass itself off as pid %d",
                  __func__, callingUid, callingPid, clientPid);
@@ -1889,6 +1892,7 @@
         portId = AUDIO_PORT_HANDLE_NONE;
     }
     lStatus = AudioSystem::getInputForAttr(&input.attr, &output.inputId,
+                                      input.riid,
                                       sessionId,
                                     // FIXME compare to AudioTrack
                                       clientPid,
@@ -1916,7 +1920,7 @@
                                                   input.config.format, input.config.channel_mask,
                                                   &output.frameCount, sessionId,
                                                   &output.notificationFrameCount,
-                                                  clientUid, &output.flags,
+                                                  callingPid, clientUid, &output.flags,
                                                   input.clientInfo.clientTid,
                                                   &lStatus, portId);
         LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (recordTrack == 0));
diff --git a/services/audioflinger/MmapTracks.h b/services/audioflinger/MmapTracks.h
index 968d5aa..b83f6b5 100644
--- a/services/audioflinger/MmapTracks.h
+++ b/services/audioflinger/MmapTracks.h
@@ -31,6 +31,7 @@
                             bool isOut,
                             uid_t uid,
                             pid_t pid,
+                            pid_t creatorPid,
                             audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
     virtual             ~MmapTrack();
 
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 4fd72a7..bb97f8d 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -22,11 +22,16 @@
 // Checks and monitors OP_PLAY_AUDIO
 class OpPlayAudioMonitor : public RefBase {
 public:
-    OpPlayAudioMonitor(uid_t uid, audio_usage_t usage, int id, audio_stream_type_t streamType);
     ~OpPlayAudioMonitor() override;
     bool hasOpPlayAudio() const;
 
+    static sp<OpPlayAudioMonitor> createIfNeeded(
+            uid_t uid, audio_usage_t usage, int id, audio_stream_type_t streamType);
+
 private:
+    OpPlayAudioMonitor(uid_t uid, audio_usage_t usage, int id);
+    void onFirstRef() override;
+
     AppOpsManager mAppOpsManager;
 
     class PlayAudioOpCallback : public BnAppOpsCallback {
@@ -64,6 +69,7 @@
                                 size_t bufferSize,
                                 const sp<IMemory>& sharedBuffer,
                                 audio_session_t sessionId,
+                                pid_t creatorPid,
                                 uid_t uid,
                                 audio_output_flags_t flags,
                                 track_type type,
@@ -209,7 +215,9 @@
 
     int fastIndex() const { return mFastIndex; }
 
-    bool isPlaybackRestricted() const { return !mOpPlayAudioMonitor->hasOpPlayAudio(); }
+    bool isPlaybackRestricted() const {
+        // The monitor is only created for tracks that can be silenced.
+        return mOpPlayAudioMonitor ? !mOpPlayAudioMonitor->hasOpPlayAudio() : false; }
 
 protected:
 
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index ec1f86c..08660dd 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -32,6 +32,7 @@
                                 void *buffer,
                                 size_t bufferSize,
                                 audio_session_t sessionId,
+                                pid_t creatorPid,
                                 uid_t uid,
                                 audio_input_flags_t flags,
                                 track_type type,
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 711a6dd..0c6cfa1 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -59,6 +59,7 @@
 #include <media/nbaio/SourceAudioBufferProvider.h>
 #include <mediautils/BatteryNotifier.h>
 
+#include <audiomanager/AudioManager.h>
 #include <powermanager/PowerManager.h>
 
 #include <media/audiohal/EffectsFactoryHalInterface.h>
@@ -565,14 +566,16 @@
     return status;
 }
 
-void AudioFlinger::ThreadBase::sendIoConfigEvent(audio_io_config_event event, pid_t pid)
+void AudioFlinger::ThreadBase::sendIoConfigEvent(audio_io_config_event event, pid_t pid,
+                                                 audio_port_handle_t portId)
 {
     Mutex::Autolock _l(mLock);
-    sendIoConfigEvent_l(event, pid);
+    sendIoConfigEvent_l(event, pid, portId);
 }
 
 // sendIoConfigEvent_l() must be called with ThreadBase::mLock held
-void AudioFlinger::ThreadBase::sendIoConfigEvent_l(audio_io_config_event event, pid_t pid)
+void AudioFlinger::ThreadBase::sendIoConfigEvent_l(audio_io_config_event event, pid_t pid,
+                                                   audio_port_handle_t portId)
 {
     // The audio statistics history is exponentially weighted to forget events
     // about five or more seconds in the past.  In order to have
@@ -583,7 +586,7 @@
     mProcessTimeMs.reset();
     mTimestampVerifier.discontinuity();
 
-    sp<ConfigEvent> configEvent = (ConfigEvent *)new IoConfigEvent(event, pid);
+    sp<ConfigEvent> configEvent = (ConfigEvent *)new IoConfigEvent(event, pid, portId);
     sendConfigEvent_l(configEvent);
 }
 
@@ -666,7 +669,7 @@
         } break;
         case CFG_EVENT_IO: {
             IoConfigEventData *data = (IoConfigEventData *)event->mData.get();
-            ioConfigChanged(data->mEvent, data->mPid);
+            ioConfigChanged(data->mEvent, data->mPid, data->mPortId);
         } break;
         case CFG_EVENT_SET_PARAMETER: {
             SetParameterConfigEventData *data = (SetParameterConfigEventData *)event->mData.get();
@@ -1951,6 +1954,7 @@
         const sp<IMemory>& sharedBuffer,
         audio_session_t sessionId,
         audio_output_flags_t *flags,
+        pid_t creatorPid,
         pid_t tid,
         uid_t uid,
         status_t *status,
@@ -2234,7 +2238,7 @@
         track = new Track(this, client, streamType, attr, sampleRate, format,
                           channelMask, frameCount,
                           nullptr /* buffer */, (size_t)0 /* bufferSize */, sharedBuffer,
-                          sessionId, uid, *flags, TrackBase::TYPE_DEFAULT, portId);
+                          sessionId, creatorPid, uid, *flags, TrackBase::TYPE_DEFAULT, portId);
 
         lStatus = track != 0 ? track->initCheck() : (status_t) NO_MEMORY;
         if (lStatus != NO_ERROR) {
@@ -2390,6 +2394,7 @@
             // to track the speaker usage
             addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStart);
 #endif
+            sendIoConfigEvent_l(AUDIO_CLIENT_STARTED, track->creatorPid(), track->portId());
         }
 
         // set retry count for buffer fill
@@ -2498,7 +2503,8 @@
     return mOutput->stream->selectPresentation(presentationId, programId);
 }
 
-void AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event, pid_t pid) {
+void AudioFlinger::PlaybackThread::ioConfigChanged(audio_io_config_event event, pid_t pid,
+                                                   audio_port_handle_t portId) {
     sp<AudioIoDescriptor> desc = new AudioIoDescriptor();
     ALOGV("PlaybackThread::ioConfigChanged, thread %p, event %d", this, event);
 
@@ -2517,7 +2523,10 @@
         desc->mFrameCountHAL = mFrameCount;
         desc->mLatency = latency_l();
         break;
-
+    case AUDIO_CLIENT_STARTED:
+        desc->mPatch = mPatch;
+        desc->mPortId = portId;
+        break;
     case AUDIO_OUTPUT_CLOSED:
     default:
         break;
@@ -7404,6 +7413,7 @@
         size_t *pFrameCount,
         audio_session_t sessionId,
         size_t *pNotificationFrameCount,
+        pid_t creatorPid,
         uid_t uid,
         audio_input_flags_t *flags,
         pid_t tid,
@@ -7541,7 +7551,7 @@
 
         track = new RecordTrack(this, client, attr, sampleRate,
                       format, channelMask, frameCount,
-                      nullptr /* buffer */, (size_t)0 /* bufferSize */, sessionId, uid,
+                      nullptr /* buffer */, (size_t)0 /* bufferSize */, sessionId, creatorPid, uid,
                       *flags, TrackBase::TYPE_DEFAULT, portId);
 
         lStatus = track->initCheck();
@@ -7649,6 +7659,8 @@
                 recordTrack->clearSyncStartEvent();
                 return status;
             }
+            sendIoConfigEvent_l(
+                AUDIO_CLIENT_STARTED, recordTrack->creatorPid(), recordTrack->portId());
         }
         // Catch up with current buffer indices if thread is already running.
         // This is what makes a new client discard all buffered data.  If the track's mRsmpInFront
@@ -8130,7 +8142,8 @@
     return String8();
 }
 
-void AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event event, pid_t pid) {
+void AudioFlinger::RecordThread::ioConfigChanged(audio_io_config_event event, pid_t pid,
+                                                 audio_port_handle_t portId) {
     sp<AudioIoDescriptor> desc = new AudioIoDescriptor();
 
     desc->mIoHandle = mId;
@@ -8147,7 +8160,10 @@
         desc->mFrameCountHAL = mFrameCount;
         desc->mLatency = 0;
         break;
-
+    case AUDIO_CLIENT_STARTED:
+        desc->mPatch = mPatch;
+        desc->mPortId = portId;
+        break;
     case AUDIO_INPUT_CLOSED:
     default:
         break;
@@ -8561,6 +8577,7 @@
         config.format = mFormat;
         audio_port_handle_t deviceId = mDeviceId;
         ret = AudioSystem::getInputForAttr(&mAttr, &io,
+                                              RECORD_RIID_INVALID,
                                               mSessionId,
                                               client.clientPid,
                                               client.clientUid,
@@ -8604,7 +8621,8 @@
 
     // Given that MmapThread::mAttr is mutable, should a MmapTrack have attributes ?
     sp<MmapTrack> track = new MmapTrack(this, mAttr, mSampleRate, mFormat, mChannelMask, mSessionId,
-                                        isOutput(), client.clientUid, client.clientPid, portId);
+                                        isOutput(), client.clientUid, client.clientPid,
+                                        IPCThreadState::self()->getCallingPid(), portId);
 
     if (isOutput()) {
         // force volume update when a new track is added
@@ -8830,7 +8848,8 @@
     return String8();
 }
 
-void AudioFlinger::MmapThread::ioConfigChanged(audio_io_config_event event, pid_t pid) {
+void AudioFlinger::MmapThread::ioConfigChanged(audio_io_config_event event, pid_t pid,
+                                               audio_port_handle_t portId __unused) {
     sp<AudioIoDescriptor> desc = new AudioIoDescriptor();
 
     desc->mIoHandle = mId;
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 37b2d08..336c2b4 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -103,8 +103,9 @@
 
     class IoConfigEventData : public ConfigEventData {
     public:
-        IoConfigEventData(audio_io_config_event event, pid_t pid) :
-            mEvent(event), mPid(pid) {}
+        IoConfigEventData(audio_io_config_event event, pid_t pid,
+                          audio_port_handle_t portId) :
+            mEvent(event), mPid(pid), mPortId(portId) {}
 
         virtual  void dump(char *buffer, size_t size) {
             snprintf(buffer, size, "IO event: event %d\n", mEvent);
@@ -112,13 +113,14 @@
 
         const audio_io_config_event mEvent;
         const pid_t                 mPid;
+        const audio_port_handle_t   mPortId;
     };
 
     class IoConfigEvent : public ConfigEvent {
     public:
-        IoConfigEvent(audio_io_config_event event, pid_t pid) :
+        IoConfigEvent(audio_io_config_event event, pid_t pid, audio_port_handle_t portId) :
             ConfigEvent(CFG_EVENT_IO) {
-            mData = new IoConfigEventData(event, pid);
+            mData = new IoConfigEventData(event, pid, portId);
         }
         virtual ~IoConfigEvent() {}
     };
@@ -260,13 +262,16 @@
                                                     status_t& status) = 0;
     virtual     status_t    setParameters(const String8& keyValuePairs);
     virtual     String8     getParameters(const String8& keys) = 0;
-    virtual     void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0) = 0;
+    virtual     void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0,
+                                        audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE) = 0;
                 // sendConfigEvent_l() must be called with ThreadBase::mLock held
                 // Can temporarily release the lock if waiting for a reply from
                 // processConfigEvents_l().
                 status_t    sendConfigEvent_l(sp<ConfigEvent>& event);
-                void        sendIoConfigEvent(audio_io_config_event event, pid_t pid = 0);
-                void        sendIoConfigEvent_l(audio_io_config_event event, pid_t pid = 0);
+                void        sendIoConfigEvent(audio_io_config_event event, pid_t pid = 0,
+                                              audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
+                void        sendIoConfigEvent_l(audio_io_config_event event, pid_t pid = 0,
+                                            audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
                 void        sendPrioConfigEvent(pid_t pid, pid_t tid, int32_t prio, bool forApp);
                 void        sendPrioConfigEvent_l(pid_t pid, pid_t tid, int32_t prio, bool forApp);
                 status_t    sendSetParameterConfigEvent_l(const String8& keyValuePair);
@@ -802,6 +807,7 @@
                                 const sp<IMemory>& sharedBuffer,
                                 audio_session_t sessionId,
                                 audio_output_flags_t *flags,
+                                pid_t creatorPid,
                                 pid_t tid,
                                 uid_t uid,
                                 status_t *status /*non-NULL*/,
@@ -825,7 +831,8 @@
                                 { return android_atomic_acquire_load(&mSuspended) > 0; }
 
     virtual     String8     getParameters(const String8& keys);
-    virtual     void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0);
+    virtual     void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0,
+                                            audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
                 status_t    getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);
                 // Consider also removing and passing an explicit mMainBuffer initialization
                 // parameter to AF::PlaybackThread::Track::Track().
@@ -1540,6 +1547,7 @@
                     size_t *pFrameCount,
                     audio_session_t sessionId,
                     size_t *pNotificationFrameCount,
+                    pid_t creatorPid,
                     uid_t uid,
                     audio_input_flags_t *flags,
                     pid_t tid,
@@ -1562,7 +1570,8 @@
                                                status_t& status);
     virtual void        cacheParameters_l() {}
     virtual String8     getParameters(const String8& keys);
-    virtual void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0);
+    virtual void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0,
+                                        audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
     virtual status_t    createAudioPatch_l(const struct audio_patch *patch,
                                            audio_patch_handle_t *handle);
     virtual status_t    releaseAudioPatch_l(const audio_patch_handle_t handle);
@@ -1743,7 +1752,8 @@
     virtual     bool        checkForNewParameter_l(const String8& keyValuePair,
                                                     status_t& status);
     virtual     String8     getParameters(const String8& keys);
-    virtual     void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0);
+    virtual     void        ioConfigChanged(audio_io_config_event event, pid_t pid = 0,
+                                            audio_port_handle_t portId = AUDIO_PORT_HANDLE_NONE);
                 void        readHalParameters_l();
     virtual     void        cacheParameters_l() {}
     virtual     status_t    createAudioPatch_l(const struct audio_patch *patch,
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index 4402d99..8f720b5 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -64,6 +64,7 @@
                                 void *buffer,
                                 size_t bufferSize,
                                 audio_session_t sessionId,
+                                pid_t creatorPid,
                                 uid_t uid,
                                 bool isOut,
                                 alloc_type alloc = ALLOC_CBLK,
@@ -79,6 +80,8 @@
             audio_track_cblk_t* cblk() const { return mCblk; }
             audio_session_t sessionId() const { return mSessionId; }
             uid_t       uid() const { return mUid; }
+            pid_t       creatorPid() const { return mCreatorPid; }
+
             audio_port_handle_t portId() const { return mPortId; }
     virtual status_t    setSyncEvent(const sp<SyncEvent>& event);
 
@@ -310,6 +313,8 @@
     std::atomic<bool>   mServerLatencyFromTrack{}; // latency from track or server timestamp.
     std::atomic<double> mServerLatencyMs{};        // last latency pushed from server thread.
     std::atomic<FrameTime> mKernelFrameTime{};     // last frame time on kernel side.
+    const pid_t         mCreatorPid;  // can be different from mclient->pid() for instance
+                                      // when created by NuPlayer on behalf of a client
 };
 
 // PatchProxyBufferProvider interface is implemented by PatchTrack and PatchRecord.
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 2ff80c6..e1f00c1 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -73,6 +73,7 @@
             void *buffer,
             size_t bufferSize,
             audio_session_t sessionId,
+            pid_t creatorPid,
             uid_t clientUid,
             bool isOut,
             alloc_type alloc,
@@ -101,7 +102,8 @@
         mType(type),
         mThreadIoHandle(thread ? thread->id() : AUDIO_IO_HANDLE_NONE),
         mPortId(portId),
-        mIsInvalid(false)
+        mIsInvalid(false),
+        mCreatorPid(creatorPid)
 {
     const uid_t callingUid = IPCThreadState::self()->getCallingUid();
     if (!isAudioServerOrMediaServerUid(callingUid) || clientUid == AUDIO_UID_INVALID) {
@@ -381,26 +383,28 @@
 // ----------------------------------------------------------------------------
 //      AppOp for audio playback
 // -------------------------------
-AudioFlinger::PlaybackThread::OpPlayAudioMonitor::OpPlayAudioMonitor(uid_t uid, audio_usage_t usage,
-        int id, audio_stream_type_t streamType)
-            : mHasOpPlayAudio(true), mUid(uid), mUsage((int32_t) usage), mId(id)
+
+// static
+sp<AudioFlinger::PlaybackThread::OpPlayAudioMonitor>
+AudioFlinger::PlaybackThread::OpPlayAudioMonitor::createIfNeeded(
+            uid_t uid, audio_usage_t usage, int id, audio_stream_type_t streamType)
 {
     if (isAudioServerOrRootUid(uid)) {
-        ALOGD("OpPlayAudio: not muting track:%d usage:%d root or audioserver", mId, usage);
-        return;
+        ALOGD("OpPlayAudio: not muting track:%d usage:%d root or audioserver", id, usage);
+        return nullptr;
     }
     // stream type has been filtered by audio policy to indicate whether it can be muted
     if (streamType == AUDIO_STREAM_ENFORCED_AUDIBLE) {
-        ALOGD("OpPlayAudio: not muting track:%d usage:%d ENFORCED_AUDIBLE", mId, usage);
-        return;
+        ALOGD("OpPlayAudio: not muting track:%d usage:%d ENFORCED_AUDIBLE", id, usage);
+        return nullptr;
     }
-    PermissionController permissionController;
-    permissionController.getPackagesForUid(uid, mPackages);
-    checkPlayAudioForUsage();
-    if (!mPackages.isEmpty()) {
-        mOpCallback = new PlayAudioOpCallback(this);
-        mAppOpsManager.startWatchingMode(AppOpsManager::OP_PLAY_AUDIO, mPackages[0], mOpCallback);
-    }
+    return new OpPlayAudioMonitor(uid, usage, id);
+}
+
+AudioFlinger::PlaybackThread::OpPlayAudioMonitor::OpPlayAudioMonitor(
+        uid_t uid, audio_usage_t usage, int id)
+        : mHasOpPlayAudio(true), mUid(uid), mUsage((int32_t) usage), mId(id)
+{
 }
 
 AudioFlinger::PlaybackThread::OpPlayAudioMonitor::~OpPlayAudioMonitor()
@@ -411,6 +415,17 @@
     mOpCallback.clear();
 }
 
+void AudioFlinger::PlaybackThread::OpPlayAudioMonitor::onFirstRef()
+{
+    PermissionController permissionController;
+    permissionController.getPackagesForUid(mUid, mPackages);
+    checkPlayAudioForUsage();
+    if (!mPackages.isEmpty()) {
+        mOpCallback = new PlayAudioOpCallback(this);
+        mAppOpsManager.startWatchingMode(AppOpsManager::OP_PLAY_AUDIO, mPackages[0], mOpCallback);
+    }
+}
+
 bool AudioFlinger::PlaybackThread::OpPlayAudioMonitor::hasOpPlayAudio() const {
     return mHasOpPlayAudio.load();
 }
@@ -472,6 +487,7 @@
             size_t bufferSize,
             const sp<IMemory>& sharedBuffer,
             audio_session_t sessionId,
+            pid_t creatorPid,
             uid_t uid,
             audio_output_flags_t flags,
             track_type type,
@@ -479,7 +495,7 @@
     :   TrackBase(thread, client, attr, sampleRate, format, channelMask, frameCount,
                   (sharedBuffer != 0) ? sharedBuffer->pointer() : buffer,
                   (sharedBuffer != 0) ? sharedBuffer->size() : bufferSize,
-                  sessionId, uid, true /*isOut*/,
+                  sessionId, creatorPid, uid, true /*isOut*/,
                   (type == TYPE_PATCH) ? ( buffer == NULL ? ALLOC_LOCAL : ALLOC_NONE) : ALLOC_CBLK,
                   type, portId),
     mFillingUpStatus(FS_INVALID),
@@ -492,7 +508,7 @@
     mPresentationCompleteFrames(0),
     mFrameMap(16 /* sink-frame-to-track-frame map memory */),
     mVolumeHandler(new media::VolumeHandler(sampleRate)),
-    mOpPlayAudioMonitor(new OpPlayAudioMonitor(uid, attr.usage, id(), streamType)),
+    mOpPlayAudioMonitor(OpPlayAudioMonitor::createIfNeeded(uid, attr.usage, id(), streamType)),
     // mSinkTimestamp
     mFastIndex(-1),
     mCachedVolume(1.0),
@@ -1530,7 +1546,7 @@
               audio_attributes_t{} /* currently unused for output track */,
               sampleRate, format, channelMask, frameCount,
               nullptr /* buffer */, (size_t)0 /* bufferSize */, nullptr /* sharedBuffer */,
-              AUDIO_SESSION_NONE, uid, AUDIO_OUTPUT_FLAG_NONE,
+              AUDIO_SESSION_NONE, getpid(), uid, AUDIO_OUTPUT_FLAG_NONE,
               TYPE_OUTPUT),
     mActive(false), mSourceThread(sourceThread)
 {
@@ -1759,7 +1775,7 @@
               audio_attributes_t{} /* currently unused for patch track */,
               sampleRate, format, channelMask, frameCount,
               buffer, bufferSize, nullptr /* sharedBuffer */,
-              AUDIO_SESSION_NONE, AID_AUDIOSERVER, flags, TYPE_PATCH),
+              AUDIO_SESSION_NONE, getpid(), AID_AUDIOSERVER, flags, TYPE_PATCH),
         PatchTrackBase(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, true, true),
                        *playbackThread, timeout)
 {
@@ -1914,12 +1930,14 @@
             void *buffer,
             size_t bufferSize,
             audio_session_t sessionId,
+            pid_t creatorPid,
             uid_t uid,
             audio_input_flags_t flags,
             track_type type,
             audio_port_handle_t portId)
     :   TrackBase(thread, client, attr, sampleRate, format,
-                  channelMask, frameCount, buffer, bufferSize, sessionId, uid, false /*isOut*/,
+                  channelMask, frameCount, buffer, bufferSize, sessionId,
+                  creatorPid, uid, false /*isOut*/,
                   (type == TYPE_DEFAULT) ?
                           ((flags & AUDIO_INPUT_FLAG_FAST) ? ALLOC_PIPE : ALLOC_CBLK) :
                           ((buffer == NULL) ? ALLOC_LOCAL : ALLOC_NONE),
@@ -2229,7 +2247,7 @@
     :   RecordTrack(recordThread, NULL,
                 audio_attributes_t{} /* currently unused for patch track */,
                 sampleRate, format, channelMask, frameCount,
-                buffer, bufferSize, AUDIO_SESSION_NONE, AID_AUDIOSERVER,
+                buffer, bufferSize, AUDIO_SESSION_NONE, getpid(), AID_AUDIOSERVER,
                 flags, TYPE_PATCH),
         PatchTrackBase(new ClientProxy(mCblk, mBuffer, frameCount, mFrameSize, false, true),
                        *recordThread, timeout)
@@ -2297,11 +2315,12 @@
         bool isOut,
         uid_t uid,
         pid_t pid,
+        pid_t creatorPid,
         audio_port_handle_t portId)
     :   TrackBase(thread, NULL, attr, sampleRate, format,
                   channelMask, (size_t)0 /* frameCount */,
                   nullptr /* buffer */, (size_t)0 /* bufferSize */,
-                  sessionId, uid, isOut,
+                  sessionId, creatorPid, uid, isOut,
                   ALLOC_NONE,
                   TYPE_DEFAULT, portId),
         mPid(pid), mSilenced(false), mSilencedNotified(false)
diff --git a/services/audiopolicy/Android.bp b/services/audiopolicy/Android.bp
new file mode 100644
index 0000000..a42b89f
--- /dev/null
+++ b/services/audiopolicy/Android.bp
@@ -0,0 +1,5 @@
+cc_library_headers {
+    name: "libaudiopolicymanager_interface_headers",
+    host_supported: true,
+    export_include_dirs: ["."],
+}
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
deleted file mode 100644
index 3badda1..0000000
--- a/services/audiopolicy/Android.mk
+++ /dev/null
@@ -1,136 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    service/AudioPolicyService.cpp \
-    service/AudioPolicyEffects.cpp \
-    service/AudioPolicyInterfaceImpl.cpp \
-    service/AudioPolicyClientImpl.cpp
-
-LOCAL_C_INCLUDES := \
-    frameworks/av/services/audioflinger \
-    $(call include-path-for, audio-utils) \
-
-LOCAL_HEADER_LIBRARIES := \
-    libaudiopolicycommon \
-    libaudiopolicyengine_interface_headers \
-
-LOCAL_SHARED_LIBRARIES := \
-    libcutils \
-    libutils \
-    liblog \
-    libbinder \
-    libaudioclient \
-    libhardware_legacy \
-    libaudiopolicymanager \
-    libmedia_helper \
-    libmediametrics \
-    libmediautils \
-    libeffectsconfig \
-    libsensorprivacy
-
-LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
-    libsensorprivacy
-
-LOCAL_STATIC_LIBRARIES := \
-    libaudiopolicycomponents
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_MODULE:= libaudiopolicyservice
-
-LOCAL_CFLAGS += -fvisibility=hidden
-LOCAL_CFLAGS += -Wall -Werror
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= managerdefault/AudioPolicyManager.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libcutils \
-    libutils \
-    liblog \
-    libaudiopolicy \
-    libsoundtrigger
-
-ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
-
-ifneq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-$(error Configurable policy does not support legacy conf file)
-endif #ifneq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-
-LOCAL_C_INCLUDES += frameworks/av/services/audiopolicy/engineconfigurable/include
-LOCAL_C_INCLUDES += frameworks/av/include
-
-LOCAL_SHARED_LIBRARIES += libaudiopolicyengineconfigurable
-
-else
-
-LOCAL_SHARED_LIBRARIES += libaudiopolicyenginedefault
-
-endif # ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
-
-LOCAL_C_INCLUDES += \
-    $(call include-path-for, audio-utils) \
-
-LOCAL_HEADER_LIBRARIES := \
-    libaudiopolicycommon \
-    libaudiopolicyengine_interface_headers
-
-LOCAL_STATIC_LIBRARIES := \
-    libaudiopolicycomponents
-
-LOCAL_SHARED_LIBRARIES += libmedia_helper
-LOCAL_SHARED_LIBRARIES += libmediametrics
-
-LOCAL_SHARED_LIBRARIES += libbinder libhidlbase libxml2
-
-ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-LOCAL_CFLAGS += -DUSE_XML_AUDIO_POLICY_CONF
-endif #ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
-
-LOCAL_CFLAGS += -Wall -Werror
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_MODULE:= libaudiopolicymanagerdefault
-
-include $(BUILD_SHARED_LIBRARY)
-
-ifneq ($(USE_CUSTOM_AUDIO_POLICY), 1)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    manager/AudioPolicyFactory.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libaudiopolicymanagerdefault
-
-LOCAL_STATIC_LIBRARIES := \
-    libaudiopolicycomponents
-
-LOCAL_C_INCLUDES += \
-    $(call include-path-for, audio-utils) \
-
-LOCAL_HEADER_LIBRARIES := \
-    libaudiopolicycommon \
-    libaudiopolicyengine_interface_headers
-
-LOCAL_CFLAGS := -Wall -Werror
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_MODULE:= libaudiopolicymanager
-
-include $(BUILD_SHARED_LIBRARY)
-
-endif
-
-#######################################################################
-# Recursive call sub-folder Android.mk
-#
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 4b56a46..49937f0 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -124,6 +124,7 @@
     // request an input appropriate for record from the supplied device with supplied parameters.
     virtual status_t getInputForAttr(const audio_attributes_t *attr,
                                      audio_io_handle_t *input,
+                                     audio_unique_id_t riid,
                                      audio_session_t session,
                                      uid_t uid,
                                      const audio_config_base_t *config,
diff --git a/services/audiopolicy/common/managerdefinitions/Android.bp b/services/audiopolicy/common/managerdefinitions/Android.bp
index c9037a1..f02f3cf 100644
--- a/services/audiopolicy/common/managerdefinitions/Android.bp
+++ b/services/audiopolicy/common/managerdefinitions/Android.bp
@@ -34,6 +34,7 @@
     ],
     header_libs: [
         "libaudiopolicycommon",
+        "libaudiopolicymanager_interface_headers",
     ],
     export_header_lib_headers: ["libaudiopolicycommon"],
 
diff --git a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
index 4bb225d..0d05a63 100644
--- a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
@@ -22,6 +22,7 @@
 #include <sys/types.h>
 
 #include <system/audio.h>
+#include <audiomanager/AudioManager.h>
 #include <media/AudioProductStrategy.h>
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
@@ -146,20 +147,23 @@
 class RecordClientDescriptor: public ClientDescriptor
 {
 public:
-    RecordClientDescriptor(audio_port_handle_t portId, uid_t uid, audio_session_t sessionId,
-                        audio_attributes_t attributes, audio_config_base_t config,
-                        audio_port_handle_t preferredDeviceId,
+    RecordClientDescriptor(audio_port_handle_t portId, audio_unique_id_t riid, uid_t uid,
+                        audio_session_t sessionId, audio_attributes_t attributes,
+                        audio_config_base_t config, audio_port_handle_t preferredDeviceId,
                         audio_source_t source, audio_input_flags_t flags, bool isSoundTrigger) :
         ClientDescriptor(portId, uid, sessionId, attributes, config, preferredDeviceId),
-        mSource(source), mFlags(flags), mIsSoundTrigger(isSoundTrigger), mAppState(APP_STATE_IDLE) {}
+        mRIId(riid), mSource(source), mFlags(flags), mIsSoundTrigger(isSoundTrigger),
+        mAppState(APP_STATE_IDLE) {}
     ~RecordClientDescriptor() override = default;
 
     using ClientDescriptor::dump;
     void dump(String8 *dst, int spaces, int index) const override;
 
+    audio_unique_id_t riid() const { return mRIId; }
     audio_source_t source() const { return mSource; }
     audio_input_flags_t flags() const { return mFlags; }
     bool isSoundTrigger() const { return mIsSoundTrigger; }
+    bool isLowLevel() const { return mRIId == RECORD_RIID_INVALID; }
     void setAppState(app_state_t appState) { mAppState = appState; }
     app_state_t appState() { return mAppState; }
     bool isSilenced() const { return mAppState == APP_STATE_IDLE; }
@@ -167,6 +171,7 @@
     EffectDescriptorCollection getEnabledEffects() const { return mEnabledEffects; }
 
 private:
+    const audio_unique_id_t mRIId;
     const audio_source_t mSource;
     const audio_input_flags_t mFlags;
     const bool mIsSoundTrigger;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index 58683be..a096e8f 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "APM::AudioInputDescriptor"
 //#define LOG_NDEBUG 0
 
+#include <audiomanager/AudioManager.h>
 #include <media/AudioPolicy.h>
 #include <policy.h>
 #include <AudioPolicyInterface.h>
@@ -179,7 +180,9 @@
     mPatchHandle = handle;
     for (const auto &client : getClientIterable()) {
         if (client->active()) {
-            updateClientRecordingConfiguration(RECORD_CONFIG_EVENT_START, client);
+            updateClientRecordingConfiguration(
+                    client->isLowLevel() ? RECORD_CONFIG_EVENT_START : RECORD_CONFIG_EVENT_UPDATE,
+                    client);
         }
     }
 }
@@ -342,15 +345,19 @@
 void AudioInputDescriptor::updateClientRecordingConfiguration(
     int event, const sp<RecordClientDescriptor>& client)
 {
+    ALOGV("%s riid %d uid %d port %d session %d event %d",
+            __func__, client->riid(), client->uid(), client->portId(), client->session(), event);
     // do not send callback if starting and no device is selected yet to avoid
     // double callbacks from startInput() before and after the device is selected
-    if (event ==  RECORD_CONFIG_EVENT_START
-            && mPatchHandle == AUDIO_PATCH_HANDLE_NONE) {
+    // "start" and "stop" events for "high level" clients (AudioRecord) are sent by the client side
+    if ((event == RECORD_CONFIG_EVENT_START && mPatchHandle == AUDIO_PATCH_HANDLE_NONE)
+            || (!client->isLowLevel()
+                    && (event == RECORD_CONFIG_EVENT_START || event == RECORD_CONFIG_EVENT_STOP))) {
         return;
     }
 
     const audio_config_base_t sessionConfig = client->config();
-    const record_client_info_t recordClientInfo{client->uid(), client->session(),
+    const record_client_info_t recordClientInfo{client->riid(), client->uid(), client->session(),
                                                 client->source(), client->portId(),
                                                 client->isSilenced()};
     const audio_config_base_t config = getConfig();
@@ -429,7 +436,7 @@
     checkSuspendEffects();
 
     for (const auto& client : updatedClients) {
-        updateClientRecordingConfiguration(RECORD_CONFIG_EVENT_START, client);
+        updateClientRecordingConfiguration(RECORD_CONFIG_EVENT_UPDATE, client);
     }
 }
 
@@ -462,7 +469,7 @@
     checkSuspendEffects();
 
     for (const auto& client : updatedClients) {
-        updateClientRecordingConfiguration(RECORD_CONFIG_EVENT_START, client);
+        updateClientRecordingConfiguration(RECORD_CONFIG_EVENT_UPDATE, client);
     }
 }
 
diff --git a/services/audiopolicy/engine/Android.mk b/services/audiopolicy/engine/Android.mk
deleted file mode 100644
index dcce8e3..0000000
--- a/services/audiopolicy/engine/Android.mk
+++ /dev/null
@@ -1,9 +0,0 @@
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-#######################################################################
-# Recursive call sub-folder Android.mk
-#
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/services/audiopolicy/engineconfigurable/Android.bp b/services/audiopolicy/engineconfigurable/Android.bp
new file mode 100644
index 0000000..c27dc88
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/Android.bp
@@ -0,0 +1,44 @@
+cc_library_headers {
+    name: "libaudiopolicyengineconfigurable_interface_headers",
+    host_supported: true,
+    export_include_dirs: ["interface"],
+}
+
+cc_library_shared {
+    name: "libaudiopolicyengineconfigurable",
+    export_include_dirs: ["include"],
+    srcs: [
+        "src/Engine.cpp",
+        "src/EngineInstance.cpp",
+        "src/Stream.cpp",
+        "src/InputSource.cpp",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+    local_include_dirs: ["include"],
+    header_libs: [
+        "libbase_headers",
+        "libaudiopolicycommon",
+        "libaudiopolicyengine_interface_headers",
+        "libaudiopolicyengineconfigurable_interface_headers",
+    ],
+    static_libs: [
+        "libaudiopolicycomponents",
+        "libaudiopolicyengine_common",
+        "libaudiopolicyengine_config",
+        "libaudiopolicyengineconfigurable_pfwwrapper",
+
+    ],
+    shared_libs: [
+        "liblog",
+        "libcutils",
+        "libutils",
+        "libmedia_helper",
+        "libaudiopolicy",
+        "libparameter",
+        "libxml2",
+    ],
+}
diff --git a/services/audiopolicy/engineconfigurable/Android.mk b/services/audiopolicy/engineconfigurable/Android.mk
deleted file mode 100644
index 84a4422..0000000
--- a/services/audiopolicy/engineconfigurable/Android.mk
+++ /dev/null
@@ -1,67 +0,0 @@
-ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
-
-LOCAL_PATH := $(call my-dir)
-
-# Component build
-#######################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
-    src/Engine.cpp \
-    src/EngineInstance.cpp \
-    src/Stream.cpp \
-    src/InputSource.cpp \
-
-audio_policy_engine_includes_common := \
-    frameworks/av/services/audiopolicy/engineconfigurable/include \
-    frameworks/av/services/audiopolicy/engineconfigurable/interface
-
-LOCAL_CFLAGS += \
-    -Wall \
-    -Werror \
-    -Wextra \
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := \
-    $(audio_policy_engine_includes_common)
-
-LOCAL_C_INCLUDES := \
-    $(audio_policy_engine_includes_common) \
-    $(TARGET_OUT_HEADERS)/hw \
-    $(call include-path-for, frameworks-av) \
-    $(call include-path-for, audio-utils)
-
-LOCAL_HEADER_LIBRARIES := \
-    libaudiopolicycommon \
-    libaudiopolicyengine_interface_headers
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_MODULE := libaudiopolicyengineconfigurable
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_STATIC_LIBRARIES := \
-    libaudiopolicypfwwrapper \
-    libaudiopolicycomponents \
-    libaudiopolicyengine_common \
-    libaudiopolicyengine_config \
-
-LOCAL_SHARED_LIBRARIES := \
-    liblog \
-    libutils \
-    liblog \
-    libcutils \
-    libaudioutils \
-    libparameter \
-    libmedia_helper \
-    libaudiopolicy \
-    libxml2
-
-include $(BUILD_SHARED_LIBRARY)
-
-#######################################################################
-# Recursive call sub-folder Android.mk
-#
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
-endif
diff --git a/services/audiopolicy/engineconfigurable/config/Android.mk b/services/audiopolicy/engineconfigurable/config/Android.mk
deleted file mode 100644
index dcce8e3..0000000
--- a/services/audiopolicy/engineconfigurable/config/Android.mk
+++ /dev/null
@@ -1,9 +0,0 @@
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-#######################################################################
-# Recursive call sub-folder Android.mk
-#
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/services/audiopolicy/engineconfigurable/config/example/Android.mk b/services/audiopolicy/engineconfigurable/config/example/Android.mk
index f879afc..a0f1a90 100644
--- a/services/audiopolicy/engineconfigurable/config/example/Android.mk
+++ b/services/audiopolicy/engineconfigurable/config/example/Android.mk
@@ -1,5 +1,7 @@
 LOCAL_PATH := $(call my-dir)
 
+ifdef BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION
+
 TOOLS := frameworks/av/services/audiopolicy/engineconfigurable/tools
 PROVISION_CRITERION_TYPES := $(TOOLS)/provision_criterion_types_from_android_headers.mk
 
@@ -145,3 +147,5 @@
 include $(PROVISION_CRITERION_TYPES)
 
 endif #ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable caremu_configurable))
+
+endif #ifdef BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/Android.mk
deleted file mode 100644
index c402fd5..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/Android.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-#######################################################################
-# Recursive call sub-folder Android.mk
-#######################################################################
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
index ddc8721..19f93b3 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/Android.mk
@@ -9,6 +9,8 @@
 
 LOCAL_PATH := $(call my-dir)
 
+ifdef BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION
+
 ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),phone_configurable automotive_configurable caremu_configurable no-output_configurable no-input_configurable))
 
 PFW_CORE := external/parameter-framework
@@ -39,16 +41,16 @@
 LOCAL_MODULE_RELATIVE_PATH := parameter-framework
 LOCAL_SRC_FILES := $(LOCAL_MODULE).in
 LOCAL_REQUIRED_MODULES := \
-    PolicySubsystem.xml\
+    PolicySubsystem.xml \
     PolicyClass.xml
 
 # external/parameter-framework prevents from using debug interface
 AUDIO_PATTERN = @TUNING_ALLOWED@
-#ifeq ($(TARGET_BUILD_VARIANT),user)
+ifeq ($(TARGET_BUILD_VARIANT),user)
 AUDIO_VALUE = false
-#else
-#AUDIO_VALUE = true
-#endif
+else
+AUDIO_VALUE = true
+endif
 
 LOCAL_POST_INSTALL_CMD := $(hide) sed -i -e 's|$(AUDIO_PATTERN)|$(AUDIO_VALUE)|g' $(TARGET_OUT_VENDOR_ETC)/$(LOCAL_MODULE_RELATIVE_PATH)/$(LOCAL_MODULE)
 
@@ -106,26 +108,26 @@
 ifeq ($(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),$(filter $(BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION),no-output_configurable no-input_configurable))
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := PolicySubsystem-no-strategy.xml
-LOCAL_MODULE_STEM := PolicySubsystem.xml
+LOCAL_MODULE := PolicySubsystem.xml
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := ETC
 LOCAL_VENDOR_MODULE := true
 LOCAL_REQUIRED_MODULES := PolicySubsystem-CommonTypes.xml
 
 LOCAL_MODULE_RELATIVE_PATH := parameter-framework/Structure/Policy
-LOCAL_SRC_FILES := common/Structure/$(LOCAL_MODULE_STEM)
+LOCAL_SRC_FILES := common/Structure/$(LOCAL_MODULE)
 include $(BUILD_PREBUILT)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := ParameterFrameworkConfigurationPolicy.xml
+LOCAL_MODULE := ParameterFrameworkConfigurationPolicy-no-strategy.xml
+LOCAL_MODULE_STEM := ParameterFrameworkConfigurationPolicy.xml
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE_CLASS := ETC
 LOCAL_VENDOR_MODULE := true
 LOCAL_MODULE_RELATIVE_PATH := parameter-framework
 LOCAL_SRC_FILES := $(LOCAL_MODULE).in
 LOCAL_REQUIRED_MODULES := \
-    PolicySubsystem-no-strategy.xml\
+    PolicySubsystem.xml \
     PolicyClass.xml
 AUDIO_VALUE = false
 LOCAL_POST_INSTALL_CMD := $(hide) sed -i -e 's|$(AUDIO_PATTERN)|$(AUDIO_VALUE)|g' $(TARGET_OUT_VENDOR_ETC)/$(LOCAL_MODULE_RELATIVE_PATH)/$(LOCAL_MODULE)
@@ -181,4 +183,5 @@
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
 
+endif #ifdef BUILD_AUDIO_POLICY_EXAMPLE_CONFIGURATION
 
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in b/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in
index f80a07f..1be67dd 100644
--- a/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/examples/ParameterFrameworkConfigurationPolicy.xml.in
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <ParameterFrameworkConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    SystemClassName="Policy" ServerPort="/dev/socket/audioserver/policy_debug"
+    SystemClassName="Policy" ServerPort="unix:///dev/socket/audioserver/policy_debug"
     TuningAllowed="@TUNING_ALLOWED@">
 
     <SubsystemPlugins>
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.bp b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.bp
new file mode 100644
index 0000000..2685c6d
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.bp
@@ -0,0 +1,36 @@
+cc_library_shared {
+    name: "libpolicy-subsystem",
+    srcs: [
+        "PolicySubsystemBuilder.cpp",
+        "PolicySubsystem.cpp",
+        "InputSource.cpp",
+        "Stream.cpp",
+        "ProductStrategy.cpp",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+        "-fvisibility-inlines-hidden",
+        "-fvisibility=hidden",
+    ],
+    header_libs: [
+        "libbase_headers",
+        "libaudiopolicycommon",
+        "libaudioclient_headers",
+        "libaudiopolicyengine_interface_headers",
+        "libaudiopolicyengineconfigurable_interface_headers",
+    ],
+    static_libs: [
+        "libaudiopolicycomponents",
+        "libaudiopolicyengine_common",
+        "libpfw_utility",
+    ],
+    shared_libs: [
+        "libaudiopolicyengineconfigurable",
+        "liblog",
+        "libutils",
+        "libmedia_helper",
+        "libparameter"
+    ],
+}
diff --git a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk b/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk
deleted file mode 100644
index b060524..0000000
--- a/services/audiopolicy/engineconfigurable/parameter-framework/plugin/Android.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := \
-    PolicySubsystemBuilder.cpp \
-    PolicySubsystem.cpp \
-    InputSource.cpp \
-    Stream.cpp \
-    ProductStrategy.cpp
-
-LOCAL_CFLAGS += \
-    -Wall \
-    -Werror \
-    -Wextra \
-    -fvisibility-inlines-hidden \
-    -fvisibility=hidden
-
-LOCAL_C_INCLUDES := \
-    frameworks/av/services/audiopolicy/engineconfigurable/include \
-    frameworks/av/services/audiopolicy/engineconfigurable/interface
-
-LOCAL_SHARED_LIBRARIES := \
-    libaudiopolicyengineconfigurable  \
-    libparameter \
-    libmedia_helper \
-    liblog \
-
-LOCAL_HEADER_LIBRARIES := \
-    libaudiopolicycommon \
-    libaudioclient_headers \
-    libbase_headers
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_STATIC_LIBRARIES := \
-    libpfw_utility \
-    libaudiopolicycomponents
-
-LOCAL_MODULE := libpolicy-subsystem
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/services/audiopolicy/engineconfigurable/wrapper/Android.bp b/services/audiopolicy/engineconfigurable/wrapper/Android.bp
new file mode 100644
index 0000000..6f59487
--- /dev/null
+++ b/services/audiopolicy/engineconfigurable/wrapper/Android.bp
@@ -0,0 +1,21 @@
+cc_library {
+    name: "libaudiopolicyengineconfigurable_pfwwrapper",
+    export_include_dirs: ["include"],
+    srcs: ["ParameterManagerWrapper.cpp"],
+    cflags: [
+        "-Wall",
+        "-Werror",
+        "-Wextra",
+    ],
+    header_libs: [
+        "libbase_headers",
+        "libaudiopolicycommon",
+    ],
+    static_libs: ["libaudiopolicycomponents"],
+    shared_libs: [
+        "liblog",
+        "libutils",
+        "libmedia_helper",
+        "libparameter",
+    ],
+}
diff --git a/services/audiopolicy/engineconfigurable/wrapper/Android.mk b/services/audiopolicy/engineconfigurable/wrapper/Android.mk
deleted file mode 100644
index c7d8d34..0000000
--- a/services/audiopolicy/engineconfigurable/wrapper/Android.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-##################################################################
-# WRAPPER LIBRARY
-##################################################################
-
-include $(CLEAR_VARS)
-
-LOCAL_C_INCLUDES := \
-    $(LOCAL_PATH)/include \
-    frameworks/av/services/audiopolicy/engineconfigurable/include \
-    frameworks/av/services/audiopolicy/engineconfigurable/interface \
-    external/libxml2/include \
-    external/icu/icu4c/source/common
-
-LOCAL_SRC_FILES:= \
-    ParameterManagerWrapper.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libparameter \
-    libmedia_helper \
-    libxml2
-
-LOCAL_HEADER_LIBRARIES := \
-    libaudiopolicycommon
-
-LOCAL_STATIC_LIBRARIES := \
-    libaudiopolicycomponents
-
-LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
-
-LOCAL_MODULE:= libaudiopolicypfwwrapper
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_CFLAGS := -Wall -Werror -Wextra
-
-include $(BUILD_STATIC_LIBRARY)
-
diff --git a/services/audiopolicy/enginedefault/config/Android.mk b/services/audiopolicy/enginedefault/config/Android.mk
deleted file mode 100644
index dcce8e3..0000000
--- a/services/audiopolicy/enginedefault/config/Android.mk
+++ /dev/null
@@ -1,9 +0,0 @@
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-#######################################################################
-# Recursive call sub-folder Android.mk
-#
-include $(call all-makefiles-under,$(LOCAL_PATH))
-
diff --git a/services/audiopolicy/manager/Android.mk b/services/audiopolicy/manager/Android.mk
new file mode 100644
index 0000000..d6ca2f2
--- /dev/null
+++ b/services/audiopolicy/manager/Android.mk
@@ -0,0 +1,32 @@
+LOCAL_PATH:= $(call my-dir)
+
+ifneq ($(USE_CUSTOM_AUDIO_POLICY), 1)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    AudioPolicyFactory.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+    libaudiopolicymanagerdefault
+
+LOCAL_STATIC_LIBRARIES := \
+    libaudiopolicycomponents
+
+LOCAL_C_INCLUDES += \
+    $(call include-path-for, audio-utils)
+
+LOCAL_HEADER_LIBRARIES := \
+    libaudiopolicycommon \
+    libaudiopolicyengine_interface_headers \
+    libaudiopolicymanager_interface_headers
+
+LOCAL_CFLAGS := -Wall -Werror
+
+LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
+
+LOCAL_MODULE:= libaudiopolicymanager
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif #ifneq ($(USE_CUSTOM_AUDIO_POLICY), 1)
diff --git a/services/audiopolicy/manager/AudioPolicyFactory.cpp b/services/audiopolicy/manager/AudioPolicyFactory.cpp
index 3efa1b0..7aff6a9 100644
--- a/services/audiopolicy/manager/AudioPolicyFactory.cpp
+++ b/services/audiopolicy/manager/AudioPolicyFactory.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "managerdefault/AudioPolicyManager.h"
+#include <AudioPolicyManager.h>
 
 namespace android {
 
diff --git a/services/audiopolicy/managerdefault/Android.mk b/services/audiopolicy/managerdefault/Android.mk
new file mode 100644
index 0000000..684fc9f
--- /dev/null
+++ b/services/audiopolicy/managerdefault/Android.mk
@@ -0,0 +1,56 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= AudioPolicyManager.cpp
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libutils \
+    liblog \
+    libaudiopolicy \
+    libsoundtrigger
+
+ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
+
+ifneq ($(USE_XML_AUDIO_POLICY_CONF), 1)
+$(error Configurable policy does not support legacy conf file)
+endif #ifneq ($(USE_XML_AUDIO_POLICY_CONF), 1)
+
+LOCAL_SHARED_LIBRARIES += libaudiopolicyengineconfigurable
+
+else
+
+LOCAL_SHARED_LIBRARIES += libaudiopolicyenginedefault
+
+endif # ifeq ($(USE_CONFIGURABLE_AUDIO_POLICY), 1)
+
+LOCAL_C_INCLUDES += \
+    $(call include-path-for, audio-utils)
+
+LOCAL_HEADER_LIBRARIES := \
+    libaudiopolicycommon \
+    libaudiopolicyengine_interface_headers \
+    libaudiopolicymanager_interface_headers
+
+LOCAL_STATIC_LIBRARIES := \
+    libaudiopolicycomponents
+
+LOCAL_SHARED_LIBRARIES += libmedia_helper
+LOCAL_SHARED_LIBRARIES += libmediametrics
+
+LOCAL_SHARED_LIBRARIES += libbinder libhidlbase libxml2
+
+ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
+LOCAL_CFLAGS += -DUSE_XML_AUDIO_POLICY_CONF
+endif #ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
+
+LOCAL_CFLAGS += -Wall -Werror
+
+LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
+
+LOCAL_MODULE:= libaudiopolicymanagerdefault
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 7011ef7..c0ca440 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1884,6 +1884,7 @@
 
 status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
                                              audio_io_handle_t *input,
+                                             audio_unique_id_t riid,
                                              audio_session_t session,
                                              uid_t uid,
                                              const audio_config_base_t *config,
@@ -2027,7 +2028,7 @@
         mSoundTriggerSessions.indexOfKey(session) > 0;
     *portId = AudioPort::getNextUniqueId();
 
-    clientDesc = new RecordClientDescriptor(*portId, uid, session, attributes, *config,
+    clientDesc = new RecordClientDescriptor(*portId, riid, uid, session, attributes, *config,
                                             requestedDeviceId, attributes.source, flags,
                                             isSoundTrigger);
     inputDesc = mInputs.valueFor(*input);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 8ca06e7..612bd8f 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -128,6 +128,7 @@
         virtual void releaseOutput(audio_port_handle_t portId);
         virtual status_t getInputForAttr(const audio_attributes_t *attr,
                                          audio_io_handle_t *input,
+                                         audio_unique_id_t riid,
                                          audio_session_t session,
                                          uid_t uid,
                                          const audio_config_base_t *config,
diff --git a/services/audiopolicy/service/Android.mk b/services/audiopolicy/service/Android.mk
new file mode 100644
index 0000000..c4f4c56
--- /dev/null
+++ b/services/audiopolicy/service/Android.mk
@@ -0,0 +1,49 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    AudioPolicyService.cpp \
+    AudioPolicyEffects.cpp \
+    AudioPolicyInterfaceImpl.cpp \
+    AudioPolicyClientImpl.cpp
+
+LOCAL_C_INCLUDES := \
+    frameworks/av/services/audioflinger \
+    $(call include-path-for, audio-utils)
+
+LOCAL_HEADER_LIBRARIES := \
+    libaudiopolicycommon \
+    libaudiopolicyengine_interface_headers \
+    libaudiopolicymanager_interface_headers
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libutils \
+    liblog \
+    libbinder \
+    libaudioclient \
+    libaudioutils \
+    libhardware_legacy \
+    libaudiopolicymanager \
+    libmedia_helper \
+    libmediametrics \
+    libmediautils \
+    libeffectsconfig \
+    libsensorprivacy
+
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
+    libsensorprivacy
+
+LOCAL_STATIC_LIBRARIES := \
+    libaudiopolicycomponents
+
+LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
+
+LOCAL_MODULE:= libaudiopolicyservice
+
+LOCAL_CFLAGS += -fvisibility=hidden
+LOCAL_CFLAGS += -Wall -Werror
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 2e47eb6..06e68a9 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -334,6 +334,7 @@
 
 status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
                                              audio_io_handle_t *input,
+                                             audio_unique_id_t riid,
                                              audio_session_t session,
                                              pid_t pid,
                                              uid_t uid,
@@ -403,7 +404,7 @@
         {
             AutoCallerClear acc;
             // the audio_in_acoustics_t parameter is ignored by get_input()
-            status = mAudioPolicyManager->getInputForAttr(attr, input, session, uid,
+            status = mAudioPolicyManager->getInputForAttr(attr, input, riid, session, uid,
                                                          config,
                                                          flags, selectedDeviceId,
                                                          &inputType, portId);
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 6c19912..58256f7 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -33,7 +33,7 @@
 #include <media/AudioPolicy.h>
 #include <mediautils/ServiceUtilities.h>
 #include "AudioPolicyEffects.h"
-#include "managerdefault/AudioPolicyManager.h"
+#include <AudioPolicyInterface.h>
 #include <android/hardware/BnSensorPrivacyListener.h>
 
 #include <unordered_map>
@@ -91,6 +91,7 @@
     virtual void releaseOutput(audio_port_handle_t portId);
     virtual status_t getInputForAttr(const audio_attributes_t *attr,
                                      audio_io_handle_t *input,
+                                     audio_unique_id_t riid,
                                      audio_session_t session,
                                      pid_t pid,
                                      uid_t uid,
diff --git a/services/audiopolicy/tests/Android.mk b/services/audiopolicy/tests/Android.mk
index 97be44c..ab9f78b 100644
--- a/services/audiopolicy/tests/Android.mk
+++ b/services/audiopolicy/tests/Android.mk
@@ -18,7 +18,8 @@
 
 LOCAL_HEADER_LIBRARIES := \
     libaudiopolicycommon \
-    libaudiopolicyengine_interface_headers
+    libaudiopolicyengine_interface_headers \
+    libaudiopolicymanager_interface_headers
 
 LOCAL_SRC_FILES := \
   audiopolicymanager_tests.cpp \