Merge "codec2: allow multiple components to get block pool from ID" into sc-dev
diff --git a/METADATA b/METADATA
index 1fbda08..aabda36 100644
--- a/METADATA
+++ b/METADATA
@@ -2,6 +2,22 @@
 #     CONSULT THE OWNERS AND opensource-licensing@google.com BEFORE
 #     DEPENDING ON IT IN YOUR PROJECT. ***
 third_party {
-  # would be NOTICE save for drm/mediadrm/plugins/clearkey/hidl/
+  # would be NOTICE save for Widevine Master License Agreement in:
+  #   drm/mediadrm/plugins/clearkey/hidl/DeviceFiles.cpp
+  #   drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp
+  #   drm/mediadrm/plugins/clearkey/hidl/include/DeviceFiles.h
+  #   drm/mediadrm/plugins/clearkey/hidl/protos/DeviceFiles.proto
+  #   drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h
+  # and patent disclaimers in:
+  #   media/codec2/components/aac/patent_disclaimer.txt
+  #   media/codec2/components/amr_nb_wb/patent_disclaimer.txt
+  #   media/codec2/components/mp3/patent_disclaimer.txt
+  #   media/codec2/components/mpeg4_h263/patent_disclaimer.txt
+  #   media/codecs/amrnb/patent_disclaimer.txt
+  #   media/codecs/amrwb/dec/patent_disclaimer.txt
+  #   media/codecs/amrwb/enc/patent_disclaimer.txt
+  #   media/codecs/m4v_h263/patent_disclaimer.txt
+  #   media/codecs/mp3dec/patent_disclaimer.txt
+  #   media/libstagefright/codecs/aacenc/patent_disclaimer.txt
   license_type: BY_EXCEPTION_ONLY
 }
diff --git a/apex/TEST_MAPPING b/apex/TEST_MAPPING
index 09c46d6..4b7c019 100644
--- a/apex/TEST_MAPPING
+++ b/apex/TEST_MAPPING
@@ -16,7 +16,7 @@
           "include-filter": "com.google.android.media.gts.WidevineGenericOpsTests"
         },
         {
-          "include-filter": "com.google.android.media.gts.WidevineYouTubePerformanceTests"
+          "include-filter": "com.google.android.media.gts.WidevineH264PlaybackTests"
         }
       ]
     }
diff --git a/drm/TEST_MAPPING b/drm/TEST_MAPPING
index aa8a7d8..3642898 100644
--- a/drm/TEST_MAPPING
+++ b/drm/TEST_MAPPING
@@ -11,7 +11,7 @@
           "include-filter": "com.google.android.media.gts.WidevineGenericOpsTests"
         },
         {
-          "include-filter": "com.google.android.media.gts.WidevineYouTubePerformanceTests"
+          "include-filter": "com.google.android.media.gts.WidevineH264PlaybackTests"
         }
       ]
     }
diff --git a/include/drm/TEST_MAPPING b/include/drm/TEST_MAPPING
index 512e844..74fa50d 100644
--- a/include/drm/TEST_MAPPING
+++ b/include/drm/TEST_MAPPING
@@ -10,7 +10,7 @@
           "include-filter": "com.google.android.media.gts.WidevineGenericOpsTests"
         },
         {
-          "include-filter": "com.google.android.media.gts.WidevineYouTubePerformanceTests"
+          "include-filter": "com.google.android.media.gts.WidevineH264PlaybackTests"
         }
       ]
     }
diff --git a/media/TEST_MAPPING b/media/TEST_MAPPING
index 80e0924..5bc7262 100644
--- a/media/TEST_MAPPING
+++ b/media/TEST_MAPPING
@@ -30,7 +30,7 @@
                     "include-filter": "com.google.android.media.gts.WidevineGenericOpsTests"
                 },
                 {
-                    "include-filter": "com.google.android.media.gts.WidevineYouTubePerformanceTests"
+                    "include-filter": "com.google.android.media.gts.WidevineH264PlaybackTests"
                 }
             ]
         }
diff --git a/media/codec2/components/aac/C2SoftAacDec.cpp b/media/codec2/components/aac/C2SoftAacDec.cpp
index f3341ab..3e6b0ff 100644
--- a/media/codec2/components/aac/C2SoftAacDec.cpp
+++ b/media/codec2/components/aac/C2SoftAacDec.cpp
@@ -877,10 +877,14 @@
             work->worklets.front()->output.configUpdate.push_back(
                     C2Param::Copy(currentBoostFactor));
 
-            C2StreamDrcCompressionModeTuning::input currentCompressMode(0u,
-                    (C2Config::drc_compression_mode_t) compressMode);
-            work->worklets.front()->output.configUpdate.push_back(
-                    C2Param::Copy(currentCompressMode));
+            if (android_get_device_api_level() < __ANDROID_API_S__) {
+                // We used to report DRC compression mode in the output format
+                // in Q and R, but stopped doing that in S
+                C2StreamDrcCompressionModeTuning::input currentCompressMode(0u,
+                        (C2Config::drc_compression_mode_t) compressMode);
+                work->worklets.front()->output.configUpdate.push_back(
+                        C2Param::Copy(currentCompressMode));
+            }
 
             C2StreamDrcEncodedTargetLevelTuning::input currentEncodedTargetLevel(0u,
                     (C2FloatValue) (encTargetLevel*-0.25));
diff --git a/media/codec2/fuzzer/C2Fuzzer.cpp b/media/codec2/fuzzer/C2Fuzzer.cpp
index 71956a2..51e1013 100644
--- a/media/codec2/fuzzer/C2Fuzzer.cpp
+++ b/media/codec2/fuzzer/C2Fuzzer.cpp
@@ -148,9 +148,8 @@
   std::vector<std::tuple<C2String, C2ComponentFactory::CreateCodec2FactoryFunc,
         C2ComponentFactory::DestroyCodec2FactoryFunc>> codec2FactoryFunc;
 
-  codec2FactoryFunc.emplace_back(std::make_tuple(C2COMPONENTNAME,
-                                                &CreateCodec2Factory,
-                                                &DestroyCodec2Factory));
+  codec2FactoryFunc.emplace_back(
+      std::make_tuple(C2COMPONENTNAME, &CreateCodec2Factory, &DestroyCodec2Factory));
 
   std::shared_ptr<C2ComponentStore> componentStore = GetTestComponentStore(codec2FactoryFunc);
   if (!componentStore) {
diff --git a/media/codec2/fuzzer/C2Fuzzer.h b/media/codec2/fuzzer/C2Fuzzer.h
index 2efad50..d5ac81a 100644
--- a/media/codec2/fuzzer/C2Fuzzer.h
+++ b/media/codec2/fuzzer/C2Fuzzer.h
@@ -59,8 +59,9 @@
  private:
   class BufferSource {
    public:
-    BufferSource(const uint8_t* data, size_t size)
-        : mData(data), mSize(size), mReadIndex(size - kMarkerSize) {}
+    BufferSource(const uint8_t* data, size_t size) : mData(data), mSize(size) {
+      mReadIndex = (size <= kMarkerSize) ? 0 : (size - kMarkerSize);
+    }
     ~BufferSource() {
       mData = nullptr;
       mSize = 0;
@@ -72,10 +73,20 @@
     FrameData getFrame();
 
    private:
-    bool isMarker() { return (memcmp(&mData[mReadIndex], kMarker, kMarkerSize) == 0); }
+    bool isMarker() {
+      if ((kMarkerSize < mSize) && (mReadIndex < mSize - kMarkerSize)) {
+        return (memcmp(&mData[mReadIndex], kMarker, kMarkerSize) == 0);
+      } else {
+        return false;
+      }
+    }
 
     bool isCSDMarker(size_t position) {
-      return (memcmp(&mData[position], kCsdMarkerSuffix, kMarkerSuffixSize) == 0);
+      if ((kMarkerSuffixSize < mSize) && (position < mSize - kMarkerSuffixSize)) {
+        return (memcmp(&mData[position], kCsdMarkerSuffix, kMarkerSuffixSize) == 0);
+      } else {
+        return false;
+      }
     }
 
     bool searchForMarker();
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 5de4d7f..e749345 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -487,6 +487,31 @@
     }
 };
 
+void RevertOutputFormatIfNeeded(
+        const sp<AMessage> &oldFormat, sp<AMessage> &currentFormat) {
+    // We used to not report changes to these keys to the client.
+    const static std::set<std::string> sIgnoredKeys({
+            KEY_BIT_RATE,
+            KEY_MAX_BIT_RATE,
+            "csd-0",
+            "csd-1",
+            "csd-2",
+    });
+    if (currentFormat == oldFormat) {
+        return;
+    }
+    sp<AMessage> diff = currentFormat->changesFrom(oldFormat);
+    AMessage::Type type;
+    for (size_t i = diff->countEntries(); i > 0; --i) {
+        if (sIgnoredKeys.count(diff->getEntryNameAt(i - 1, &type)) > 0) {
+            diff->removeEntryAt(i - 1);
+        }
+    }
+    if (diff->countEntries() == 0) {
+        currentFormat = oldFormat;
+    }
+}
+
 }  // namespace
 
 // CCodec::ClientListener
@@ -518,9 +543,24 @@
     virtual void onError(
             const std::weak_ptr<Codec2Client::Component>& component,
             uint32_t errorCode) override {
-        // TODO
-        (void)component;
-        (void)errorCode;
+        {
+            // Component is only used for reporting as we use a separate listener for each instance
+            std::shared_ptr<Codec2Client::Component> comp = component.lock();
+            if (!comp) {
+                ALOGD("Component died with error: 0x%x", errorCode);
+            } else {
+                ALOGD("Component \"%s\" returned error: 0x%x", comp->getName().c_str(), errorCode);
+            }
+        }
+
+        // Report to MediaCodec
+        // Note: for now we do not propagate the error code to MediaCodec as we would need
+        // to translate to a MediaCodec error.
+        sp<CCodec> codec(mCodec.promote());
+        if (!codec || !codec->mCallback) {
+            return;
+        }
+        codec->mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
     }
 
     virtual void onDeath(
@@ -1687,7 +1727,9 @@
                     || comp->getName().find("c2.android.") == 0)) {
         mChannel->setParameters(configUpdate);
     } else {
+        sp<AMessage> outputFormat = config->mOutputFormat;
         (void)config->setParameters(comp, configUpdate, C2_MAY_BLOCK);
+        RevertOutputFormatIfNeeded(outputFormat, config->mOutputFormat);
     }
 }
 
@@ -1812,7 +1854,6 @@
             // handle configuration changes in work done
             Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
             const std::unique_ptr<Config> &config = *configLocked;
-            bool changed = false;
             Config::Watcher<C2StreamInitDataInfo::output> initData =
                 config->watch<C2StreamInitDataInfo::output>();
             if (!work->worklets.empty()
@@ -1847,9 +1888,9 @@
                     ++stream;
                 }
 
-                if (config->updateConfiguration(updates, config->mOutputDomain)) {
-                    changed = true;
-                }
+                sp<AMessage> outputFormat = config->mOutputFormat;
+                config->updateConfiguration(updates, config->mOutputDomain);
+                RevertOutputFormatIfNeeded(outputFormat, config->mOutputFormat);
 
                 // copy standard infos to graphic buffers if not already present (otherwise, we
                 // may overwrite the actual intermediate value with a final value)
@@ -1883,7 +1924,7 @@
                 config->mInputSurface->onInputBufferDone(work->input.ordinal.frameIndex);
             }
             mChannel->onWorkDone(
-                    std::move(work), changed ? config->mOutputFormat->dup() : nullptr,
+                    std::move(work), config->mOutputFormat,
                     initData.hasChanged() ? initData.update().get() : nullptr);
             break;
         }
diff --git a/media/codec2/sfplugin/CCodecBuffers.cpp b/media/codec2/sfplugin/CCodecBuffers.cpp
index d656350..a3b188e 100644
--- a/media/codec2/sfplugin/CCodecBuffers.cpp
+++ b/media/codec2/sfplugin/CCodecBuffers.cpp
@@ -161,8 +161,7 @@
     setSkipCutBuffer(delay, padding);
 }
 
-void OutputBuffers::updateSkipCutBuffer(
-        const sp<AMessage> &format, bool notify) {
+void OutputBuffers::updateSkipCutBuffer(const sp<AMessage> &format) {
     AString mediaType;
     if (format->findString(KEY_MIME, &mediaType)
             && mediaType == MIMETYPE_AUDIO_RAW) {
@@ -173,9 +172,6 @@
             updateSkipCutBuffer(sampleRate, channelCount);
         }
     }
-    if (notify) {
-        mUnreportedFormat = nullptr;
-    }
 }
 
 void OutputBuffers::submit(const sp<MediaCodecBuffer> &buffer) {
@@ -199,7 +195,6 @@
     mReorderStash.clear();
     mDepth = 0;
     mKey = C2Config::ORDINAL;
-    mUnreportedFormat = nullptr;
 }
 
 void OutputBuffers::flushStash() {
@@ -275,25 +270,25 @@
     *c2Buffer = entry.buffer;
     sp<AMessage> outputFormat = entry.format;
 
-    // The output format can be processed without a registered slot.
-    if (outputFormat) {
-        updateSkipCutBuffer(outputFormat, entry.notify);
-    }
-
-    if (entry.notify) {
-        if (outputFormat) {
-            setFormat(outputFormat);
-        } else if (mUnreportedFormat) {
-            outputFormat = mUnreportedFormat;
-            setFormat(outputFormat);
+    if (entry.notify && mFormat != outputFormat) {
+        updateSkipCutBuffer(outputFormat);
+        sp<ABuffer> imageData;
+        if (mFormat->findBuffer("image-data", &imageData)) {
+            outputFormat->setBuffer("image-data", imageData);
         }
-        mUnreportedFormat = nullptr;
-    } else {
-        if (outputFormat) {
-            mUnreportedFormat = outputFormat;
-        } else if (!mUnreportedFormat) {
-            mUnreportedFormat = mFormat;
+        int32_t stride;
+        if (mFormat->findInt32(KEY_STRIDE, &stride)) {
+            outputFormat->setInt32(KEY_STRIDE, stride);
         }
+        int32_t sliceHeight;
+        if (mFormat->findInt32(KEY_SLICE_HEIGHT, &sliceHeight)) {
+            outputFormat->setInt32(KEY_SLICE_HEIGHT, sliceHeight);
+        }
+        ALOGV("[%s] popFromStashAndRegister: output format reference changed: %p -> %p",
+                mName, mFormat.get(), outputFormat.get());
+        ALOGD("[%s] popFromStashAndRegister: output format changed to %s",
+                mName, outputFormat->debugString().c_str());
+        setFormat(outputFormat);
     }
 
     // Flushing mReorderStash because no other buffers should come after output
@@ -304,10 +299,6 @@
     }
 
     if (!entry.notify) {
-        if (outputFormat) {
-            ALOGD("[%s] popFromStashAndRegister: output format changed to %s",
-                    mName, outputFormat->debugString().c_str());
-        }
         mPending.pop_front();
         return DISCARD;
     }
@@ -325,10 +316,6 @@
     (*outBuffer)->meta()->setInt64("timeUs", entry.timestamp);
     (*outBuffer)->meta()->setInt32("flags", entry.flags);
     (*outBuffer)->meta()->setInt64("frameIndex", entry.ordinal.frameIndex.peekll());
-    if (outputFormat) {
-        ALOGD("[%s] popFromStashAndRegister: output format changed to %s",
-                mName, outputFormat->debugString().c_str());
-    }
     ALOGV("[%s] popFromStashAndRegister: "
           "out buffer index = %zu [%p] => %p + %zu (%lld)",
           mName, *index, outBuffer->get(),
@@ -1182,7 +1169,6 @@
 void OutputBuffersArray::transferFrom(OutputBuffers* source) {
     mFormat = source->mFormat;
     mSkipCutBuffer = source->mSkipCutBuffer;
-    mUnreportedFormat = source->mUnreportedFormat;
     mPending = std::move(source->mPending);
     mReorderStash = std::move(source->mReorderStash);
     mDepth = source->mDepth;
diff --git a/media/codec2/sfplugin/CCodecBuffers.h b/media/codec2/sfplugin/CCodecBuffers.h
index c383a7c..7c4e7b1 100644
--- a/media/codec2/sfplugin/CCodecBuffers.h
+++ b/media/codec2/sfplugin/CCodecBuffers.h
@@ -215,10 +215,8 @@
 
     /**
      * Update SkipCutBuffer from format. The @p format must not be null.
-     * @p notify determines whether the format comes with a buffer that should
-     * be reported to the client or not.
      */
-    void updateSkipCutBuffer(const sp<AMessage> &format, bool notify = true);
+    void updateSkipCutBuffer(const sp<AMessage> &format);
 
     /**
      * Output Stash
@@ -392,9 +390,6 @@
 
     // Output stash
 
-    // Output format that has not been made available to the client.
-    sp<AMessage> mUnreportedFormat;
-
     // Struct for an entry in the output stash (mPending and mReorderStash)
     struct StashEntry {
         inline StashEntry()
diff --git a/media/codec2/sfplugin/CCodecConfig.cpp b/media/codec2/sfplugin/CCodecConfig.cpp
index 79c6227..5decb99 100644
--- a/media/codec2/sfplugin/CCodecConfig.cpp
+++ b/media/codec2/sfplugin/CCodecConfig.cpp
@@ -765,21 +765,13 @@
 
     // convert to compression type and add default
     add(ConfigMapper(KEY_AAC_DRC_HEAVY_COMPRESSION, C2_PARAMKEY_DRC_COMPRESSION_MODE, "value")
-        .limitTo(D::AUDIO & D::DECODER & (D::CONFIG | D::PARAM | D::READ))
-        .withMappers([](C2Value v) -> C2Value {
+        .limitTo(D::AUDIO & D::DECODER & (D::CONFIG | D::PARAM))
+        .withMapper([](C2Value v) -> C2Value {
             int32_t value;
             if (!v.get(&value) || value < 0) {
                 value = property_get_int32(PROP_DRC_OVERRIDE_HEAVY, DRC_DEFAULT_MOBILE_DRC_HEAVY);
             }
             return value == 1 ? C2Config::DRC_COMPRESSION_HEAVY : C2Config::DRC_COMPRESSION_LIGHT;
-        },[](C2Value v) -> C2Value {
-            int32_t value;
-            if (v.get(&value)) {
-              return value;
-            }
-            else {
-              return C2Value();
-            }
         }));
 
     // convert to dBFS and add default
diff --git a/media/codec2/vndk/util/C2InterfaceHelper.cpp b/media/codec2/vndk/util/C2InterfaceHelper.cpp
index 9eb52d2..19d2295 100644
--- a/media/codec2/vndk/util/C2InterfaceHelper.cpp
+++ b/media/codec2/vndk/util/C2InterfaceHelper.cpp
@@ -645,6 +645,7 @@
                     lateReadParams.emplace_back(p);
                     std::unique_ptr<C2Param> request(C2Param::CopyAsRequest(*p));
                     p = request.get();
+                    paramIx = p->index();
                     paramRequests.emplace_back(std::move(request));
                 }
             }
diff --git a/media/codecs/amrnb/enc/src/pitch_fr.cpp b/media/codecs/amrnb/enc/src/pitch_fr.cpp
index 5a846fa..584f79b 100644
--- a/media/codecs/amrnb/enc/src/pitch_fr.cpp
+++ b/media/codecs/amrnb/enc/src/pitch_fr.cpp
@@ -570,12 +570,14 @@
     Word16 corr[],     /* i   : normalized correlation  */
     Word16 flag3,      /* i   : subsample resolution
                                 (3: =1 / 6: =0)         */
-    Flag   *pOverflow
+    Flag   *pOverflow,
+    enum Mode mode
 )
 {
     Word16 i;
     Word16 max;
     Word16 corr_int;
+    Word16 minPitch;
 
     /* Test the fractions around T0 and choose the one which maximizes   */
     /* the interpolated normalized correlation.                          */
@@ -593,14 +595,22 @@
         }
     }
 
+    minPitch = (mode == MR122) ? PIT_MIN_MR122 : PIT_MIN;
     if (flag3 == 0)
     {
         /* Limit the fraction value in the interval [-2,-1,0,1,2,3] */
 
         if (*frac == -3)
         {
-            *frac = 3;
-            (*lag)--;
+            if (*lag > minPitch)
+            {
+                *frac = 3;
+                (*lag)--;
+            }
+            else
+            {
+                *frac = -2;
+            }
         }
     }
     else
@@ -609,13 +619,27 @@
 
         if (*frac == -2)
         {
-            *frac = 1;
-            (*lag)--;
+            if (*lag > minPitch)
+            {
+                *frac = 1;
+                (*lag)--;
+            }
+            else
+            {
+                *frac = -1;
+            }
         }
-        if (*frac == 2)
+        else if (*frac == 2)
         {
-            *frac = -1;
-            (*lag)++;
+            if (*lag < PIT_MAX)
+            {
+                *frac = -1;
+                (*lag)++;
+            }
+            else
+            {
+                *frac = 1;
+            }
         }
     }
 }
@@ -1533,20 +1557,20 @@
 
                 /* normal search in fractions around T0 */
 
-                searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow);
+                searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow, mode);
 
             }
             else if (lag == (tmp_lag - 2))
             {
                 /* limit search around T0 to the right side */
                 frac = 0;
-                searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow);
+                searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow, mode);
             }
             else if (lag == (tmp_lag + 1))
             {
                 /* limit search around T0 to the left side */
                 last_frac = 0;
-                searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow);
+                searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow, mode);
             }
             else
             {
@@ -1556,7 +1580,7 @@
         }
         else
             /* test the fractions around T0 */
-            searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow);
+            searchFrac(&lag, &frac, last_frac, corr, flag3, pOverflow, mode);
     }
 
     /*-----------------------------------------------------------------------*
diff --git a/media/codecs/mp3dec/src/pvmp3_framedecoder.cpp b/media/codecs/mp3dec/src/pvmp3_framedecoder.cpp
index 15d2feb..5cf1ed3 100644
--- a/media/codecs/mp3dec/src/pvmp3_framedecoder.cpp
+++ b/media/codecs/mp3dec/src/pvmp3_framedecoder.cpp
@@ -598,18 +598,10 @@
         }
         else
         {
-            int32 tmp1 = *(ptr++);
-            for (int32 nBytes = temp >> 1; nBytes != 0; nBytes--)  /* read main data. */
+            for (int32 nBytes = temp; nBytes != 0; nBytes--)  /* read main data. */
             {
-                int32 tmp2 = *(ptr++);
-                fillDataBuf(&pVars->mainDataStream, tmp1);
-                fillDataBuf(&pVars->mainDataStream, tmp2);
-                tmp1 = *(ptr++);
-            }
-
-            if (temp&1)
-            {
-                fillDataBuf(&pVars->mainDataStream, tmp1);
+                int32 tmp = *(ptr++);
+                fillDataBuf(&pVars->mainDataStream, tmp);
             }
 
             /* adjust circular buffer counter */
@@ -618,14 +610,9 @@
     }
     else
     {
-        for (int32 nBytes = temp >> 1; nBytes != 0; nBytes--)  /* read main data. */
+        for (int32 nBytes = temp; nBytes != 0; nBytes--)  /* read main data. */
         {
             fillDataBuf(&pVars->mainDataStream, *(pVars->inputStream.pBuffer + module(offset++  , BUFSIZE)));
-            fillDataBuf(&pVars->mainDataStream, *(pVars->inputStream.pBuffer + module(offset++  , BUFSIZE)));
-        }
-        if (temp&1)
-        {
-            fillDataBuf(&pVars->mainDataStream, *(pVars->inputStream.pBuffer + module(offset  , BUFSIZE)));
         }
     }
 
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index f1fa7f5..74258a1 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1997,7 +1997,8 @@
 }
 
 status_t AudioSystem::getProductStrategyFromAudioAttributes(const AudioAttributes& aa,
-                                                            product_strategy_t& productStrategy) {
+                                                            product_strategy_t& productStrategy,
+                                                            bool fallbackOnDefault) {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return PERMISSION_DENIED;
 
@@ -2006,7 +2007,8 @@
     int32_t productStrategyAidl;
 
     RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
-            aps->getProductStrategyFromAudioAttributes(aaAidl, &productStrategyAidl)));
+            aps->getProductStrategyFromAudioAttributes(aaAidl, fallbackOnDefault,
+            &productStrategyAidl)));
     productStrategy = VALUE_OR_RETURN_STATUS(
             aidl2legacy_int32_t_product_strategy_t(productStrategyAidl));
     return OK;
@@ -2025,7 +2027,8 @@
 }
 
 status_t AudioSystem::getVolumeGroupFromAudioAttributes(const AudioAttributes& aa,
-                                                        volume_group_t& volumeGroup) {
+                                                        volume_group_t& volumeGroup,
+                                                        bool fallbackOnDefault) {
     const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
     if (aps == 0) return PERMISSION_DENIED;
 
@@ -2033,7 +2036,7 @@
             legacy2aidl_AudioAttributes_AudioAttributesEx(aa));
     int32_t volumeGroupAidl;
     RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
-            aps->getVolumeGroupFromAudioAttributes(aaAidl, &volumeGroupAidl)));
+            aps->getVolumeGroupFromAudioAttributes(aaAidl, fallbackOnDefault, &volumeGroupAidl)));
     volumeGroup = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_volume_group_t(volumeGroupAidl));
     return OK;
 }
diff --git a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
index c8ab0ae..89fad5a 100644
--- a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
@@ -297,10 +297,12 @@
     boolean isHapticPlaybackSupported();
 
     AudioProductStrategy[] listAudioProductStrategies();
-    int /* product_strategy_t */ getProductStrategyFromAudioAttributes(in AudioAttributesEx aa);
+    int /* product_strategy_t */ getProductStrategyFromAudioAttributes(in AudioAttributesEx aa,
+                                                                       boolean fallbackOnDefault);
 
     AudioVolumeGroup[] listAudioVolumeGroups();
-    int /* volume_group_t */ getVolumeGroupFromAudioAttributes(in AudioAttributesEx aa);
+    int /* volume_group_t */ getVolumeGroupFromAudioAttributes(in AudioAttributesEx aa,
+                                                               boolean fallbackOnDefault);
 
     void setRttEnabled(boolean enabled);
 
diff --git a/media/libaudioclient/fuzzer/Android.bp b/media/libaudioclient/fuzzer/Android.bp
index edfc5a5..a8eb385 100644
--- a/media/libaudioclient/fuzzer/Android.bp
+++ b/media/libaudioclient/fuzzer/Android.bp
@@ -21,7 +21,7 @@
     ],
     static_libs: [
         "android.hardware.audio.common@7.0-enums",
-        "effect-aidl-unstable-cpp",
+        "effect-aidl-cpp",
         "libaudioclient",
         "libbase",
         "libcgrouprc",
@@ -33,16 +33,16 @@
         "libmediametricsservice",
         "libmedia_helper",
         "libprocessgroup",
-        "shared-file-region-aidl-unstable-cpp",
+        "shared-file-region-aidl-cpp",
     ],
     shared_libs: [
         "android.hardware.audio.common-util",
-        "audioclient-types-aidl-unstable-cpp",
-        "audioflinger-aidl-unstable-cpp",
-        "audiopolicy-aidl-unstable-cpp",
-        "audiopolicy-types-aidl-unstable-cpp",
-        "av-types-aidl-unstable-cpp",
-        "capture_state_listener-aidl-unstable-cpp",
+        "audioclient-types-aidl-cpp",
+        "audioflinger-aidl-cpp",
+        "audiopolicy-aidl-cpp",
+        "audiopolicy-types-aidl-cpp",
+        "av-types-aidl-cpp",
+        "capture_state_listener-aidl-cpp",
         "libaudioclient_aidl_conversion",
         "libaudioflinger",
         "libaudiofoundation",
@@ -55,7 +55,7 @@
         "libnblog",
         "libutils",
         "libxml2",
-        "mediametricsservice-aidl-unstable-cpp",
+        "mediametricsservice-aidl-cpp",
     ],
     header_libs: [
         "libaudiofoundation_headers",
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index db4c28f..694f2d0 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -428,16 +428,17 @@
     static bool     isHapticPlaybackSupported();
 
     static status_t listAudioProductStrategies(AudioProductStrategyVector &strategies);
-    static status_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa,
-                                                        product_strategy_t &productStrategy);
+    static status_t getProductStrategyFromAudioAttributes(
+            const AudioAttributes &aa, product_strategy_t &productStrategy,
+            bool fallbackOnDefault = true);
 
     static audio_attributes_t streamTypeToAttributes(audio_stream_type_t stream);
     static audio_stream_type_t attributesToStreamType(const audio_attributes_t &attr);
 
     static status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups);
 
-    static status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
-                                                      volume_group_t &volumeGroup);
+    static status_t getVolumeGroupFromAudioAttributes(
+            const AudioAttributes &aa, volume_group_t &volumeGroup, bool fallbackOnDefault = true);
 
     static status_t setRttEnabled(bool enabled);
 
diff --git a/media/libeffects/lvm/benchmarks/Android.bp b/media/libeffects/lvm/benchmarks/Android.bp
index 930292f..4f11a8a 100644
--- a/media/libeffects/lvm/benchmarks/Android.bp
+++ b/media/libeffects/lvm/benchmarks/Android.bp
@@ -1,6 +1,7 @@
 cc_benchmark {
     name: "lvm_benchmark",
     vendor: true,
+    host_supported: true,
     srcs: ["lvm_benchmark.cpp"],
     static_libs: [
         "libbundlewrapper",
diff --git a/media/libeffects/lvm/lib/Android.bp b/media/libeffects/lvm/lib/Android.bp
index 0ac9aa3..73c913b 100644
--- a/media/libeffects/lvm/lib/Android.bp
+++ b/media/libeffects/lvm/lib/Android.bp
@@ -9,6 +9,7 @@
     },
 
     vendor: true,
+    host_supported: true,
     srcs: [
         "StereoWidening/src/LVCS_BypassMix.cpp",
         "StereoWidening/src/LVCS_Control.cpp",
diff --git a/media/libeffects/lvm/wrapper/Android.bp b/media/libeffects/lvm/wrapper/Android.bp
index f96928b..bcbe3e6 100644
--- a/media/libeffects/lvm/wrapper/Android.bp
+++ b/media/libeffects/lvm/wrapper/Android.bp
@@ -9,6 +9,7 @@
     },
 
     vendor: true,
+    host_supported: true,
     srcs: ["Bundle/EffectBundle.cpp"],
 
     cppflags: [
@@ -25,7 +26,6 @@
     shared_libs: [
         "libaudioutils",
         "libcutils",
-        "libdl",
         "liblog",
     ],
 
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 865baad..c9d41ba 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -166,8 +166,8 @@
 
 /* Effect Library Interface Implementation */
 
-extern "C" int EffectCreate(const effect_uuid_t* uuid, int32_t sessionId, int32_t ioId __unused,
-                            effect_handle_t* pHandle) {
+extern "C" int EffectCreate(const effect_uuid_t* uuid, int32_t sessionId,
+                            int32_t /* ioId __unused */, effect_handle_t* pHandle) {
     int ret = 0;
     int sessionNo = -1;
     int i;
@@ -1354,7 +1354,8 @@
 //
 //----------------------------------------------------------------------------
 void VirtualizerGetSpeakerAngles(audio_channel_mask_t channelMask,
-                                 audio_devices_t deviceType __unused, int32_t* pSpeakerAngles) {
+                                 audio_devices_t /* deviceType __unused */,
+                                 int32_t* pSpeakerAngles) {
     // the channel count is guaranteed to be 1 or 2
     // the device is guaranteed to be of type headphone
     // this virtualizer is always using 2 virtual speakers at -90 and 90deg of azimuth, 0deg of
@@ -1495,8 +1496,8 @@
 //  pLow:       lower band range
 //  pLow:       upper band range
 //----------------------------------------------------------------------------
-int32_t EqualizerGetBandFreqRange(EffectContext* pContext __unused, int32_t band, uint32_t* pLow,
-                                  uint32_t* pHi) {
+int32_t EqualizerGetBandFreqRange(EffectContext* /* pContext __unused */, int32_t band,
+                                  uint32_t* pLow, uint32_t* pHi) {
     *pLow = bandFreqRange[band][0];
     *pHi = bandFreqRange[band][1];
     return 0;
@@ -1519,7 +1520,7 @@
 //  pLow:       lower band range
 //  pLow:       upper band range
 //----------------------------------------------------------------------------
-int32_t EqualizerGetBand(EffectContext* pContext __unused, uint32_t targetFreq) {
+int32_t EqualizerGetBand(EffectContext* /* pContext __unused */, uint32_t targetFreq) {
     int band = 0;
 
     if (targetFreq < bandFreqRange[0][0]) {
diff --git a/media/libeffects/preprocessing/tests/Android.bp b/media/libeffects/preprocessing/tests/Android.bp
index 5e8255a..ff897e8 100644
--- a/media/libeffects/preprocessing/tests/Android.bp
+++ b/media/libeffects/preprocessing/tests/Android.bp
@@ -18,6 +18,7 @@
         "libaudioeffects",
         "libhardware_headers",
     ],
+    gtest: false,
 }
 
 cc_test {
@@ -29,4 +30,5 @@
         "-Werror",
         "-Wextra",
     ],
+    gtest: false,
 }
diff --git a/media/libeffects/preprocessing/tests/correlation.cpp b/media/libeffects/preprocessing/tests/correlation.cpp
index b13dcc7..eb56fc3 100644
--- a/media/libeffects/preprocessing/tests/correlation.cpp
+++ b/media/libeffects/preprocessing/tests/correlation.cpp
@@ -107,12 +107,19 @@
         return EXIT_FAILURE;
     }
 
-    int numFrames = fileSize1 / sizeof(int16_t);
+    size_t numFrames = fileSize1 / sizeof(int16_t);
     std::unique_ptr<int16_t[]> inBuffer1(new int16_t[numFrames]());
     std::unique_ptr<int16_t[]> inBuffer2(new int16_t[numFrames]());
 
-    fread(inBuffer1.get(), sizeof(int16_t), numFrames, fInput1.get());
-    fread(inBuffer2.get(), sizeof(int16_t), numFrames, fInput2.get());
+    if (numFrames != fread(inBuffer1.get(), sizeof(int16_t), numFrames, fInput1.get())) {
+        printf("\nError: Unable to read %zu samples from file %s\n", numFrames, argv[1]);
+        return EXIT_FAILURE;
+    }
+
+    if (numFrames != fread(inBuffer2.get(), sizeof(int16_t), numFrames, fInput2.get())) {
+        printf("\nError: Unable to read %zu samples from file %s\n", numFrames, argv[2]);
+        return EXIT_FAILURE;
+    }
 
     auto pairAutoCorr1 = correlation(inBuffer1.get(), inBuffer1.get(), numFrames, enableCrossCorr);
     auto pairAutoCorr2 = correlation(inBuffer2.get(), inBuffer2.get(), numFrames, enableCrossCorr);
diff --git a/media/libmediametrics/Android.bp b/media/libmediametrics/Android.bp
index 3dfd850..06e67ad 100644
--- a/media/libmediametrics/Android.bp
+++ b/media/libmediametrics/Android.bp
@@ -16,7 +16,7 @@
         "libcutils",
         "liblog",
         "libutils",
-        "mediametricsservice-aidl-unstable-cpp",
+        "mediametricsservice-aidl-cpp",
     ],
 
     export_include_dirs: ["include"],
diff --git a/media/libmediametrics/MediaMetricsItem.cpp b/media/libmediametrics/MediaMetricsItem.cpp
index f4371fd..a8350ea 100644
--- a/media/libmediametrics/MediaMetricsItem.cpp
+++ b/media/libmediametrics/MediaMetricsItem.cpp
@@ -285,6 +285,7 @@
     status_t status = writeToByteString(&str, &size);
     if (status == NO_ERROR) {
         status = submitBuffer(str, size);
+        free(str);
     }
     if (status != NO_ERROR) {
         ALOGW("%s: failed to record: %s", __func__, this->toString().c_str());
diff --git a/media/libmediaplayerservice/Android.bp b/media/libmediaplayerservice/Android.bp
index ab6863f..45f2f97 100644
--- a/media/libmediaplayerservice/Android.bp
+++ b/media/libmediaplayerservice/Android.bp
@@ -1,4 +1,4 @@
-cc_library_shared {
+cc_library {
 
     srcs: [
         "ActivityManager.cpp",
diff --git a/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp b/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp
index d08c66d..04477c6 100644
--- a/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp
+++ b/media/libmediaplayerservice/tests/stagefrightRecorder/Android.bp
@@ -23,26 +23,47 @@
     ],
 
     include_dirs: [
-        "system/media/audio/include",
-        "frameworks/av/include",
-        "frameworks/av/camera/include",
         "frameworks/av/media/libmediaplayerservice",
-        "frameworks/av/media/libmediametrics/include",
-        "frameworks/av/media/ndk/include",
+    ],
+
+    static_libs: [
+        "libmediaplayerservice",
+        "libstagefright_httplive",
+        "libstagefright_rtsp",
     ],
 
     shared_libs: [
+        "android.hardware.media.c2@1.0",
+        "android.hardware.media.omx@1.0",
+        "libbase",
+        "libandroid_net",
+        "libaudioclient",
+        "libbinder",
+        "libcamera_client",
+        "libcodec2_client",
+        "libcrypto",
+        "libcutils",
+        "libdatasource",
+        "libdl",
+        "libdrmframework",
+        "libgui",
+        "libhidlbase",
         "liblog",
         "libmedia",
-        "libbinder",
-        "libutils",
-        "libmediaplayerservice",
-        "libstagefright",
+        "libmedia_codeclist",
+        "libmedia_omx",
+        "libmediadrm",
         "libmediandk",
+        "libmediametrics",
+        "libmediautils",
+        "libmemunreachable",
+        "libnetd_client",
+        "libpowermanager",
+        "libstagefright",
+        "libstagefright_foundation",
+        "libutils",
     ],
 
-    compile_multilib: "prefer32",
-
     cflags: [
         "-Werror",
         "-Wall",
diff --git a/media/libmediaplayerservice/tests/stagefrightRecorder/AndroidTest.xml b/media/libmediaplayerservice/tests/stagefrightRecorder/AndroidTest.xml
new file mode 100644
index 0000000..427026d
--- /dev/null
+++ b/media/libmediaplayerservice/tests/stagefrightRecorder/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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.
+-->
+<configuration description="Test module config for StagefrightRecorder unit tests">
+    <option name="test-suite-tag" value="StagefrightRecorderTest" />
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+        <option name="force-root" value="true" />
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push"
+                value="StagefrightRecorderTest->/data/local/tmp/StagefrightRecorderTest" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="StagefrightRecorderTest" />
+    </test>
+</configuration>
diff --git a/media/libmediatranscoding/transcoder/MediaSampleReaderNDK.cpp b/media/libmediatranscoding/transcoder/MediaSampleReaderNDK.cpp
index 1a6e7ed..8d36e31 100644
--- a/media/libmediatranscoding/transcoder/MediaSampleReaderNDK.cpp
+++ b/media/libmediatranscoding/transcoder/MediaSampleReaderNDK.cpp
@@ -98,6 +98,9 @@
         mTrackCursors[mExtractorTrackIndex].next.reset();
     }
 
+    // Update the extractor's sample index even if this track reaches EOS, so that the other tracks
+    // are not given an incorrect extractor position.
+    mExtractorSampleIndex++;
     if (!AMediaExtractor_advance(mExtractor)) {
         LOG(DEBUG) << "  EOS in advanceExtractor_l";
         mEosReached = true;
@@ -108,7 +111,6 @@
     }
 
     mExtractorTrackIndex = AMediaExtractor_getSampleTrackIndex(mExtractor);
-    mExtractorSampleIndex++;
 
     SampleCursor& cursor = mTrackCursors[mExtractorTrackIndex];
     if (mExtractorSampleIndex > cursor.previous.index) {
diff --git a/media/libmediatranscoding/transcoder/tests/MediaSampleReaderNDKTests.cpp b/media/libmediatranscoding/transcoder/tests/MediaSampleReaderNDKTests.cpp
index 11af0b1..3a499e5 100644
--- a/media/libmediatranscoding/transcoder/tests/MediaSampleReaderNDKTests.cpp
+++ b/media/libmediatranscoding/transcoder/tests/MediaSampleReaderNDKTests.cpp
@@ -272,6 +272,38 @@
     compareSamples(tester.getSamples());
 }
 
+/** Reads all samples except the last in each track, before finishing. */
+TEST_F(MediaSampleReaderNDKTests, TestLastSampleBeforeEOS) {
+    LOG(DEBUG) << "TestLastSampleBeforeEOS Starts";
+    initExtractorSamples();
+
+    {  // Natural track order
+        SampleAccessTester tester{mSourceFd, mFileSize};
+        for (int trackIndex = 0; trackIndex < mTrackCount; ++trackIndex) {
+            tester.readSamplesAsync(trackIndex, mExtractorSamples[trackIndex].size() - 1);
+        }
+        tester.waitForTracks();
+        for (int trackIndex = 0; trackIndex < mTrackCount; ++trackIndex) {
+            tester.readSamplesAsync(trackIndex, SAMPLE_COUNT_ALL);
+            tester.waitForTrack(trackIndex);
+        }
+        compareSamples(tester.getSamples());
+    }
+
+    {  // Reverse track order
+        SampleAccessTester tester{mSourceFd, mFileSize};
+        for (int trackIndex = mTrackCount - 1; trackIndex >= 0; --trackIndex) {
+            tester.readSamplesAsync(trackIndex, mExtractorSamples[trackIndex].size() - 1);
+        }
+        tester.waitForTracks();
+        for (int trackIndex = mTrackCount - 1; trackIndex >= 0; --trackIndex) {
+            tester.readSamplesAsync(trackIndex, SAMPLE_COUNT_ALL);
+            tester.waitForTrack(trackIndex);
+        }
+        compareSamples(tester.getSamples());
+    }
+}
+
 /** Reads all samples from all tracks sequentially. */
 TEST_F(MediaSampleReaderNDKTests, TestSequentialSampleAccess) {
     LOG(DEBUG) << "TestSequentialSampleAccess Starts";
diff --git a/media/libstagefright/writer_fuzzers/Android.bp b/media/libstagefright/writer_fuzzers/Android.bp
index 224aeb3..f1e504d 100644
--- a/media/libstagefright/writer_fuzzers/Android.bp
+++ b/media/libstagefright/writer_fuzzers/Android.bp
@@ -58,3 +58,59 @@
         "WriterFuzzerBase.cpp",
     ],
 }
+
+cc_fuzz {
+    name: "amrnb_writer_fuzzer",
+    defaults: ["writer-fuzzer-defaults"],
+    srcs: [
+        "amr_writer_fuzzer.cpp",
+    ],
+    cflags: [
+        "-DAMRNB",
+    ],
+}
+
+cc_fuzz {
+    name: "amrwb_writer_fuzzer",
+    defaults: ["writer-fuzzer-defaults"],
+    srcs: [
+        "amr_writer_fuzzer.cpp",
+    ],
+}
+
+cc_fuzz {
+    name : "mpeg4_writer_fuzzer",
+    defaults : ["writer-fuzzer-defaults"],
+    srcs : [
+        "mpeg4_writer_fuzzer.cpp",
+    ],
+    static_libs: [
+        "libstagefright_esds",
+    ],
+}
+
+cc_fuzz {
+    name : "ogg_writer_fuzzer",
+    defaults : ["writer-fuzzer-defaults"],
+    srcs : [
+        "ogg_writer_fuzzer.cpp",
+    ],
+    static_libs: [
+        "libogg",
+    ],
+}
+
+cc_fuzz {
+    name : "webm_writer_fuzzer",
+    defaults : ["writer-fuzzer-defaults"],
+    srcs : [
+        "webm_writer_fuzzer.cpp",
+    ],
+    static_libs: [
+        "libstagefright_webm",
+        "libdatasource",
+    ],
+    include_dirs: [
+        "frameworks/av/media/libstagefright",
+    ],
+}
diff --git a/media/libstagefright/writer_fuzzers/README.md b/media/libstagefright/writer_fuzzers/README.md
index 037236a..0d21031 100644
--- a/media/libstagefright/writer_fuzzers/README.md
+++ b/media/libstagefright/writer_fuzzers/README.md
@@ -1,7 +1,11 @@
 # Fuzzer for writers
 
 ## Table of contents
-   [libwriterfuzzerbase](#WriterFuzzerBase)
++  [libwriterfuzzerbase](#WriterFuzzerBase)
++  [Amr Writer](#amrWriterFuzzer)
++  [MPEG4 Writer](#mpeg4WriterFuzzer)
++  [OGG Writer](#oggWriterFuzzer)
++  [WEBM Writer](#webmWriterFuzzer)
 
 # <a name="WriterFuzzerBase"></a> Fuzzer for libwriterfuzzerbase
 All the writers have a common API - creating a writer, adding a source for
@@ -40,6 +44,56 @@
 This ensures that the plugin tolerates any kind of input (huge,
 malformed, etc) and thereby increasing the chance of identifying vulnerabilities.
 
+# <a name="amrWriterFuzzer"></a> Fuzzer for Amr Writer
+
+## Plugin Design Considerations
+The fuzzer plugin for AMR writer uses the `WriterFuzzerBase` class and
+implements only the `createWriter` to create the AMR writer class.
+
+##### Other considerations
+ * Two fuzzer binaries - amrnb_writer_fuzzer and amrwb_writer_fuzzer are generated based on the presence of a flag - 'AMRNB'
+
+# <a name="mpeg4WriterFuzzer"></a> Fuzzer for MPEG4 Writer
+
+## Plugin Design Considerations
+The fuzzer plugin for MPEG4 writer uses the `WriterFuzzerBase` class and
+implements only the `createWriter` to create the MPEG4 writer class.
+
+# <a name="oggWriterFuzzer"></a> Fuzzer for OGG Writer
+
+## Plugin Design Considerations
+The fuzzer plugin for OGG writer uses the `WriterFuzzerBase` class and
+implements only the `createWriter` to create the OGG writer class.
+
+# <a name="webmWriterFuzzer"></a> Fuzzer for WEBM Writer
+
+## Plugin Design Considerations
+The fuzzer plugin for WEBM writer uses the `WriterFuzzerBase` class and
+implements only the `createWriter` to create the WEBM writer class.
+
+## Build
+
+This describes steps to build writer fuzzer binaries.
+
+### Android
+
+`*` = amrnb/amrwb/mpeg4/ogg/webm
+#### Steps to build
+Build the fuzzer
+```
+  $ mm -j$(nproc) *_writer_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some media files to that folder
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/arm64/*_writer_fuzzer/*_writer_fuzzer CORPUS_DIR
+```
+
 
 ## References:
  * http://llvm.org/docs/LibFuzzer.html
diff --git a/media/libstagefright/writer_fuzzers/WriterFuzzerBase.cpp b/media/libstagefright/writer_fuzzers/WriterFuzzerBase.cpp
index 65593e7..844db39 100644
--- a/media/libstagefright/writer_fuzzers/WriterFuzzerBase.cpp
+++ b/media/libstagefright/writer_fuzzers/WriterFuzzerBase.cpp
@@ -218,7 +218,7 @@
     }
 }
 
-void WriterFuzzerBase::processData(const uint8_t *data, size_t size) {
+void WriterFuzzerBase::initFileWriterAndProcessData(const uint8_t *data, size_t size) {
     if (!createOutputFile()) {
         return;
     }
diff --git a/media/libstagefright/writer_fuzzers/amr_writer_fuzzer.cpp b/media/libstagefright/writer_fuzzers/amr_writer_fuzzer.cpp
new file mode 100644
index 0000000..bbb6f9f
--- /dev/null
+++ b/media/libstagefright/writer_fuzzers/amr_writer_fuzzer.cpp
@@ -0,0 +1,50 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "WriterFuzzerBase.h"
+
+#include <media/stagefright/AMRWriter.h>
+
+using namespace android;
+
+class AmrWriterFuzzer : public WriterFuzzerBase {
+   public:
+    bool createWriter();
+};
+
+bool AmrWriterFuzzer::createWriter() {
+    mWriter = new AMRWriter(mFd);
+    if (!mWriter) {
+        return false;
+    }
+    mFileMeta = new MetaData;
+#ifdef AMRNB
+    mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_AMR_NB);
+#else
+    mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_AMR_WB);
+#endif
+    return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    AmrWriterFuzzer writerFuzzer;
+    writerFuzzer.initFileWriterAndProcessData(data, size);
+    return 0;
+}
diff --git a/media/libstagefright/writer_fuzzers/include/WriterFuzzerBase.h b/media/libstagefright/writer_fuzzers/include/WriterFuzzerBase.h
index d819d43..da06463 100644
--- a/media/libstagefright/writer_fuzzers/include/WriterFuzzerBase.h
+++ b/media/libstagefright/writer_fuzzers/include/WriterFuzzerBase.h
@@ -107,7 +107,7 @@
 
     void sendBuffersToWriter(sp<MediaAdapter>& currentTrack, int32_t trackIndex);
 
-    void processData(const uint8_t* data, size_t size);
+    void initFileWriterAndProcessData(const uint8_t* data, size_t size);
 
    protected:
     class BufferSource {
diff --git a/media/libstagefright/writer_fuzzers/mpeg4_writer_fuzzer.cpp b/media/libstagefright/writer_fuzzers/mpeg4_writer_fuzzer.cpp
new file mode 100644
index 0000000..99bd2b6
--- /dev/null
+++ b/media/libstagefright/writer_fuzzers/mpeg4_writer_fuzzer.cpp
@@ -0,0 +1,46 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "WriterFuzzerBase.h"
+
+#include <media/stagefright/MPEG4Writer.h>
+
+using namespace android;
+
+class Mpeg4WriterFuzzer : public WriterFuzzerBase {
+   public:
+    bool createWriter();
+};
+
+bool Mpeg4WriterFuzzer::createWriter() {
+    mWriter = new MPEG4Writer(mFd);
+    if (!mWriter) {
+        return false;
+    }
+    mFileMeta = new MetaData;
+    mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_MPEG_4);
+    return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    Mpeg4WriterFuzzer writerFuzzer;
+    writerFuzzer.initFileWriterAndProcessData(data, size);
+    return 0;
+}
diff --git a/media/libstagefright/writer_fuzzers/ogg_writer_fuzzer.cpp b/media/libstagefright/writer_fuzzers/ogg_writer_fuzzer.cpp
new file mode 100644
index 0000000..ae9c94c
--- /dev/null
+++ b/media/libstagefright/writer_fuzzers/ogg_writer_fuzzer.cpp
@@ -0,0 +1,46 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "WriterFuzzerBase.h"
+
+#include <media/stagefright/OggWriter.h>
+
+using namespace android;
+
+class OGGWriterFuzzer : public WriterFuzzerBase {
+   public:
+    bool createWriter();
+};
+
+bool OGGWriterFuzzer::createWriter() {
+    mWriter = new OggWriter(mFd);
+    if (!mWriter) {
+        return false;
+    }
+    mFileMeta = new MetaData;
+    mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_OGG);
+    return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    OGGWriterFuzzer writerFuzzer;
+    writerFuzzer.initFileWriterAndProcessData(data, size);
+    return 0;
+}
diff --git a/media/libstagefright/writer_fuzzers/webm_writer_fuzzer.cpp b/media/libstagefright/writer_fuzzers/webm_writer_fuzzer.cpp
new file mode 100644
index 0000000..0a91b72
--- /dev/null
+++ b/media/libstagefright/writer_fuzzers/webm_writer_fuzzer.cpp
@@ -0,0 +1,46 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 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.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+
+#include "WriterFuzzerBase.h"
+
+#include <webm/WebmWriter.h>
+
+using namespace android;
+
+class WEBMWriterFuzzer : public WriterFuzzerBase {
+   public:
+    bool createWriter();
+};
+
+bool WEBMWriterFuzzer::createWriter() {
+    mWriter = new WebmWriter(mFd);
+    if (!mWriter) {
+        return false;
+    }
+    mFileMeta = new MetaData;
+    mFileMeta->setInt32(kKeyFileType, output_format::OUTPUT_FORMAT_WEBM);
+    return true;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    WEBMWriterFuzzer writerFuzzer;
+    writerFuzzer.initFileWriterAndProcessData(data, size);
+    return 0;
+}
diff --git a/media/ndk/Android.bp b/media/ndk/Android.bp
index ee4def5..6aed994 100644
--- a/media/ndk/Android.bp
+++ b/media/ndk/Android.bp
@@ -83,6 +83,7 @@
 
     static_libs: [
         "libgrallocusage",
+        "libnativehelper_lazy",
     ],
 
     header_libs: [
@@ -111,7 +112,6 @@
         "libgui",
         "libui",
         "libmediandk_utils",
-        "libnativehelper",
     ],
 
     export_header_lib_headers: ["jni_headers"],
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 7c0f2ce..9132086 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -285,13 +285,14 @@
 
     virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) = 0;
 
-    virtual status_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa,
-                                                           product_strategy_t &productStrategy) = 0;
+    virtual status_t getProductStrategyFromAudioAttributes(
+            const AudioAttributes &aa, product_strategy_t &productStrategy,
+            bool fallbackOnDefault) = 0;
 
     virtual status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups) = 0;
 
-    virtual status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
-                                                       volume_group_t &volumeGroup) = 0;
+    virtual status_t getVolumeGroupFromAudioAttributes(
+            const AudioAttributes &aa, volume_group_t &volumeGroup, bool fallbackOnDefault) = 0;
 
     virtual bool     isCallScreenModeSupported() = 0;
 
diff --git a/services/audiopolicy/engine/common/include/EngineBase.h b/services/audiopolicy/engine/common/include/EngineBase.h
index 3e42e2d..9bef97c 100644
--- a/services/audiopolicy/engine/common/include/EngineBase.h
+++ b/services/audiopolicy/engine/common/include/EngineBase.h
@@ -53,7 +53,7 @@
                                                audio_policy_dev_state_t /*state*/) override;
 
     product_strategy_t getProductStrategyForAttributes(
-            const audio_attributes_t &attr) const override;
+            const audio_attributes_t &attr, bool fallbackOnDefault = true) const override;
 
     audio_stream_type_t getStreamTypeForAttributes(const audio_attributes_t &attr) const override;
 
@@ -79,9 +79,11 @@
 
     VolumeGroupVector getVolumeGroups() const override;
 
-    volume_group_t getVolumeGroupForAttributes(const audio_attributes_t &attr) const override;
+    volume_group_t getVolumeGroupForAttributes(
+            const audio_attributes_t &attr, bool fallbackOnDefault = true) const override;
 
-    volume_group_t getVolumeGroupForStreamType(audio_stream_type_t stream) const override;
+    volume_group_t getVolumeGroupForStreamType(
+            audio_stream_type_t stream, bool fallbackOnDefault = true) const override;
 
     status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups) const override;
 
diff --git a/services/audiopolicy/engine/common/include/ProductStrategy.h b/services/audiopolicy/engine/common/include/ProductStrategy.h
index c505456..54625ea 100644
--- a/services/audiopolicy/engine/common/include/ProductStrategy.h
+++ b/services/audiopolicy/engine/common/include/ProductStrategy.h
@@ -129,7 +129,8 @@
      * @param attr
      * @return applicable product strategy for the given attribute, default if none applicable.
      */
-    product_strategy_t getProductStrategyForAttributes(const audio_attributes_t &attr) const;
+    product_strategy_t getProductStrategyForAttributes(
+            const audio_attributes_t &attr, bool fallbackOnDefault = true) const;
 
     product_strategy_t getProductStrategyForStream(audio_stream_type_t stream) const;
 
@@ -153,9 +154,11 @@
 
     std::string getDeviceAddressForProductStrategy(product_strategy_t strategy) const;
 
-    volume_group_t getVolumeGroupForAttributes(const audio_attributes_t &attr) const;
+    volume_group_t getVolumeGroupForAttributes(
+            const audio_attributes_t &attr, bool fallbackOnDefault = true) const;
 
-    volume_group_t getVolumeGroupForStreamType(audio_stream_type_t stream) const;
+    volume_group_t getVolumeGroupForStreamType(
+            audio_stream_type_t stream, bool fallbackOnDefault = true) const;
 
     volume_group_t getDefaultVolumeGroup() const;
 
diff --git a/services/audiopolicy/engine/common/src/EngineBase.cpp b/services/audiopolicy/engine/common/src/EngineBase.cpp
index 2137dd0..37e4caa 100644
--- a/services/audiopolicy/engine/common/src/EngineBase.cpp
+++ b/services/audiopolicy/engine/common/src/EngineBase.cpp
@@ -74,9 +74,10 @@
     return NO_ERROR;
 }
 
-product_strategy_t EngineBase::getProductStrategyForAttributes(const audio_attributes_t &attr) const
+product_strategy_t EngineBase::getProductStrategyForAttributes(
+        const audio_attributes_t &attr, bool fallbackOnDefault) const
 {
-    return mProductStrategies.getProductStrategyForAttributes(attr);
+    return mProductStrategies.getProductStrategyForAttributes(attr, fallbackOnDefault);
 }
 
 audio_stream_type_t EngineBase::getStreamTypeForAttributes(const audio_attributes_t &attr) const
@@ -320,14 +321,16 @@
     return group;
 }
 
-volume_group_t EngineBase::getVolumeGroupForAttributes(const audio_attributes_t &attr) const
+volume_group_t EngineBase::getVolumeGroupForAttributes(
+        const audio_attributes_t &attr, bool fallbackOnDefault) const
 {
-    return mProductStrategies.getVolumeGroupForAttributes(attr);
+    return mProductStrategies.getVolumeGroupForAttributes(attr, fallbackOnDefault);
 }
 
-volume_group_t EngineBase::getVolumeGroupForStreamType(audio_stream_type_t stream) const
+volume_group_t EngineBase::getVolumeGroupForStreamType(
+        audio_stream_type_t stream, bool fallbackOnDefault) const
 {
-    return mProductStrategies.getVolumeGroupForStreamType(stream);
+    return mProductStrategies.getVolumeGroupForStreamType(stream, fallbackOnDefault);
 }
 
 status_t EngineBase::listAudioVolumeGroups(AudioVolumeGroupVector &groups) const
diff --git a/services/audiopolicy/engine/common/src/ProductStrategy.cpp b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
index 060568a..d4cea5a 100644
--- a/services/audiopolicy/engine/common/src/ProductStrategy.cpp
+++ b/services/audiopolicy/engine/common/src/ProductStrategy.cpp
@@ -169,7 +169,7 @@
 }
 
 product_strategy_t ProductStrategyMap::getProductStrategyForAttributes(
-        const audio_attributes_t &attr) const
+        const audio_attributes_t &attr, bool fallbackOnDefault) const
 {
     for (const auto &iter : *this) {
         if (iter.second->matches(attr)) {
@@ -178,7 +178,7 @@
     }
     ALOGV("%s: No matching product strategy for attributes %s, return default", __FUNCTION__,
           toString(attr).c_str());
-    return getDefault();
+    return fallbackOnDefault? getDefault() : PRODUCT_STRATEGY_NONE;
 }
 
 audio_attributes_t ProductStrategyMap::getAttributesForStreamType(audio_stream_type_t stream) const
@@ -272,7 +272,8 @@
     return at(psId)->getDeviceAddress();
 }
 
-volume_group_t ProductStrategyMap::getVolumeGroupForAttributes(const audio_attributes_t &attr) const
+volume_group_t ProductStrategyMap::getVolumeGroupForAttributes(
+        const audio_attributes_t &attr, bool fallbackOnDefault) const
 {
     for (const auto &iter : *this) {
         volume_group_t group = iter.second->getVolumeGroupForAttributes(attr);
@@ -280,10 +281,11 @@
             return group;
         }
     }
-    return getDefaultVolumeGroup();
+    return fallbackOnDefault ? getDefaultVolumeGroup() : VOLUME_GROUP_NONE;
 }
 
-volume_group_t ProductStrategyMap::getVolumeGroupForStreamType(audio_stream_type_t stream) const
+volume_group_t ProductStrategyMap::getVolumeGroupForStreamType(
+        audio_stream_type_t stream, bool fallbackOnDefault) const
 {
     for (const auto &iter : *this) {
         volume_group_t group = iter.second->getVolumeGroupForStreamType(stream);
@@ -292,7 +294,7 @@
         }
     }
     ALOGW("%s: no volume group for %s, using default", __func__, toString(stream).c_str());
-    return getDefaultVolumeGroup();
+    return fallbackOnDefault ? getDefaultVolumeGroup() : VOLUME_GROUP_NONE;
 }
 
 volume_group_t ProductStrategyMap::getDefaultVolumeGroup() const
diff --git a/services/audiopolicy/engine/interface/EngineInterface.h b/services/audiopolicy/engine/interface/EngineInterface.h
index a9b536b..f0a01d3 100644
--- a/services/audiopolicy/engine/interface/EngineInterface.h
+++ b/services/audiopolicy/engine/interface/EngineInterface.h
@@ -110,11 +110,12 @@
      * Get the strategy selected for a given audio attributes.
      *
      * @param[in] audio attributes to get the selected @product_strategy_t followed by.
-     *
+     * @param fallbackOnDefault if true, will return the fallback strategy if the attributes
+     * are not explicitly assigned to a given strategy.
      * @return @product_strategy_t to be followed.
      */
     virtual product_strategy_t getProductStrategyForAttributes(
-            const audio_attributes_t &attr) const = 0;
+            const audio_attributes_t &attr, bool fallbackOnDefault = true) const = 0;
 
     /**
      * @brief getOutputDevicesForAttributes retrieves the devices to be used for given
@@ -271,19 +272,25 @@
      * @brief getVolumeGroupForAttributes gets the appropriate volume group to be used for a given
      * Audio Attributes.
      * @param attr to be considered
+     * @param fallbackOnDefault if true, will return the fallback volume group if the attributes
+     * are not associated to any volume group.
      * @return volume group associated to the given audio attributes, default group if none
      * applicable, VOLUME_GROUP_NONE if no default group defined.
      */
-    virtual volume_group_t getVolumeGroupForAttributes(const audio_attributes_t &attr) const = 0;
+    virtual volume_group_t getVolumeGroupForAttributes(
+            const audio_attributes_t &attr, bool fallbackOnDefault = true) const = 0;
 
     /**
      * @brief getVolumeGroupForStreamType gets the appropriate volume group to be used for a given
      * legacy stream type
      * @param stream type to be considered
+     * @param fallbackOnDefault if true, will return the fallback volume group if the stream type
+     * is not associated to any volume group.
      * @return volume group associated to the given stream type, default group if none applicable,
      * VOLUME_GROUP_NONE if no default group defined.
      */
-    virtual volume_group_t getVolumeGroupForStreamType(audio_stream_type_t stream) const = 0;
+    virtual volume_group_t getVolumeGroupForStreamType(
+            audio_stream_type_t stream, bool fallbackOnDefault = true) const = 0;
 
     /**
      * @brief listAudioVolumeGroups introspection API to get the Audio Volume Groups, aka
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index d3ceb1b..d0c8673 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -329,11 +329,14 @@
             return mEngine->listAudioProductStrategies(strategies);
         }
 
-        virtual status_t getProductStrategyFromAudioAttributes(const AudioAttributes &aa,
-                                                               product_strategy_t &productStrategy)
+        virtual status_t getProductStrategyFromAudioAttributes(
+                const AudioAttributes &aa, product_strategy_t &productStrategy,
+                bool fallbackOnDefault)
         {
-            productStrategy = mEngine->getProductStrategyForAttributes(aa.getAttributes());
-            return productStrategy != PRODUCT_STRATEGY_NONE ? NO_ERROR : BAD_VALUE;
+            productStrategy = mEngine->getProductStrategyForAttributes(
+                    aa.getAttributes(), fallbackOnDefault);
+            return (fallbackOnDefault && productStrategy == PRODUCT_STRATEGY_NONE) ?
+                    BAD_VALUE : NO_ERROR;
         }
 
         virtual status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups)
@@ -341,11 +344,13 @@
             return mEngine->listAudioVolumeGroups(groups);
         }
 
-        virtual status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
-                                                           volume_group_t &volumeGroup)
+        virtual status_t getVolumeGroupFromAudioAttributes(
+                const AudioAttributes &aa, volume_group_t &volumeGroup, bool fallbackOnDefault)
         {
-            volumeGroup = mEngine->getVolumeGroupForAttributes(aa.getAttributes());
-            return volumeGroup != VOLUME_GROUP_NONE ? NO_ERROR : BAD_VALUE;
+            volumeGroup = mEngine->getVolumeGroupForAttributes(
+                        aa.getAttributes(), fallbackOnDefault);
+            return (fallbackOnDefault && volumeGroup == VOLUME_GROUP_NONE) ?
+                    BAD_VALUE : NO_ERROR;
         }
 
         bool isCallScreenModeSupported() override;
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 399dfea..07122cc 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -1927,7 +1927,7 @@
 }
 
 Status AudioPolicyService::getProductStrategyFromAudioAttributes(
-        const media::AudioAttributesEx& aaAidl, int32_t* _aidl_return) {
+        const media::AudioAttributesEx& aaAidl, bool fallbackOnDefault, int32_t* _aidl_return) {
     AudioAttributes aa = VALUE_OR_RETURN_BINDER_STATUS(
             aidl2legacy_AudioAttributesEx_AudioAttributes(aaAidl));
     product_strategy_t productStrategy;
@@ -1937,8 +1937,8 @@
     }
     Mutex::Autolock _l(mLock);
     RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
-            mAudioPolicyManager->getProductStrategyFromAudioAttributes(aa,
-                                                                       productStrategy)));
+            mAudioPolicyManager->getProductStrategyFromAudioAttributes(
+                    aa, productStrategy, fallbackOnDefault)));
     *_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(
             legacy2aidl_product_strategy_t_int32_t(productStrategy));
     return Status::ok();
@@ -1959,8 +1959,8 @@
     return Status::ok();
 }
 
-Status AudioPolicyService::getVolumeGroupFromAudioAttributes(const media::AudioAttributesEx& aaAidl,
-                                                             int32_t* _aidl_return) {
+Status AudioPolicyService::getVolumeGroupFromAudioAttributes(
+        const media::AudioAttributesEx& aaAidl, bool fallbackOnDefault, int32_t* _aidl_return) {
     AudioAttributes aa = VALUE_OR_RETURN_BINDER_STATUS(
             aidl2legacy_AudioAttributesEx_AudioAttributes(aaAidl));
     volume_group_t volumeGroup;
@@ -1971,7 +1971,8 @@
     Mutex::Autolock _l(mLock);
     RETURN_IF_BINDER_ERROR(
             binderStatusFromStatusT(
-                    mAudioPolicyManager->getVolumeGroupFromAudioAttributes(aa, volumeGroup)));
+                    mAudioPolicyManager->getVolumeGroupFromAudioAttributes(
+                            aa, volumeGroup, fallbackOnDefault)));
     *_aidl_return = VALUE_OR_RETURN_BINDER_STATUS(legacy2aidl_volume_group_t_int32_t(volumeGroup));
     return Status::ok();
 }
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 149a858..a11b2cc 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -196,10 +196,12 @@
     binder::Status listAudioProductStrategies(
             std::vector<media::AudioProductStrategy>* _aidl_return) override;
     binder::Status getProductStrategyFromAudioAttributes(const media::AudioAttributesEx& aa,
+                                                         bool fallbackOnDefault,
                                                          int32_t* _aidl_return) override;
     binder::Status listAudioVolumeGroups(
             std::vector<media::AudioVolumeGroup>* _aidl_return) override;
     binder::Status getVolumeGroupFromAudioAttributes(const media::AudioAttributesEx& aa,
+                                                     bool fallbackOnDefault,
                                                      int32_t* _aidl_return) override;
     binder::Status setRttEnabled(bool enabled) override;
     binder::Status isCallScreenModeSupported(bool* _aidl_return) override;
diff --git a/services/audiopolicy/tests/audio_health_tests.cpp b/services/audiopolicy/tests/audio_health_tests.cpp
index ca2f0c6..df4389b 100644
--- a/services/audiopolicy/tests/audio_health_tests.cpp
+++ b/services/audiopolicy/tests/audio_health_tests.cpp
@@ -22,6 +22,7 @@
 #include <gtest/gtest.h>
 
 #include <media/AudioSystem.h>
+#include <media/TypeConverter.h>
 #include <system/audio.h>
 #include <utils/Log.h>
 
@@ -70,10 +71,18 @@
     ASSERT_NE("AudioPolicyConfig::setDefault", manager.getConfig().getSource());
 
     for (auto desc : manager.getConfig().getInputDevices()) {
-        ASSERT_NE(attachedDevices.end(), attachedDevices.find(desc->type()));
+        if (attachedDevices.find(desc->type()) == attachedDevices.end()) {
+            std::string deviceType;
+            (void)DeviceConverter::toString(desc->type(), deviceType);
+            ADD_FAILURE() << "Input device \"" << deviceType << "\" not found";
+        }
     }
     for (auto desc : manager.getConfig().getOutputDevices()) {
-        ASSERT_NE(attachedDevices.end(), attachedDevices.find(desc->type()));
+        if (attachedDevices.find(desc->type()) == attachedDevices.end()) {
+            std::string deviceType;
+            (void)DeviceConverter::toString(desc->type(), deviceType);
+            ADD_FAILURE() << "Output device \"" << deviceType << "\" not found";
+        }
     }
 }
 
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 7606d7d..3204217 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -4802,6 +4802,7 @@
                 ATRACE_ASYNC_BEGIN("still capture", mNextRequests[i].halRequest.frame_number);
             }
 
+            e = camera_metadata_ro_entry_t();
             find_camera_metadata_ro_entry(settings, ANDROID_CONTROL_ENABLE_ZSL, &e);
             if ((e.count > 0) && (e.data.u8[0] == ANDROID_CONTROL_ENABLE_ZSL_TRUE)) {
                 isZslCapture = true;
diff --git a/services/mediametrics/Android.bp b/services/mediametrics/Android.bp
index b64f726..8e1a88b 100644
--- a/services/mediametrics/Android.bp
+++ b/services/mediametrics/Android.bp
@@ -100,7 +100,7 @@
         "libmediametricsservice",
         "libmediautils",
         "libutils",
-        "mediametricsservice-aidl-unstable-cpp",
+        "mediametricsservice-aidl-cpp",
     ],
     header_libs: [
         "libaudioutils_headers",
@@ -143,7 +143,7 @@
     },
 
     shared_libs: [
-        "mediametricsservice-aidl-unstable-cpp",
+        "mediametricsservice-aidl-cpp",
         "libbase", // android logging
         "libbinder",
         "libcutils",
diff --git a/services/mediametrics/fuzzer/Android.bp b/services/mediametrics/fuzzer/Android.bp
index 6ac9d20..19ed919 100644
--- a/services/mediametrics/fuzzer/Android.bp
+++ b/services/mediametrics/fuzzer/Android.bp
@@ -43,7 +43,7 @@
         "libstagefright",
         "libstatslog",
         "libutils",
-        "mediametricsservice-aidl-unstable-cpp",
+        "mediametricsservice-aidl-cpp",
     ],
 
     include_dirs: [
diff --git a/services/mediametrics/tests/Android.bp b/services/mediametrics/tests/Android.bp
index 94112b0..e9d91c2 100644
--- a/services/mediametrics/tests/Android.bp
+++ b/services/mediametrics/tests/Android.bp
@@ -19,7 +19,7 @@
         "libmediametricsservice",
         "libmediautils",
         "libutils",
-        "mediametricsservice-aidl-unstable-cpp",
+        "mediametricsservice-aidl-cpp",
     ],
 
     header_libs: [
diff --git a/services/tuner/TunerDemux.cpp b/services/tuner/TunerDemux.cpp
index 8346992..ba8d6a7 100644
--- a/services/tuner/TunerDemux.cpp
+++ b/services/tuner/TunerDemux.cpp
@@ -222,6 +222,8 @@
     }
 
     Result res = mDemux->close();
+    mDemux = NULL;
+
     if (res != Result::SUCCESS) {
         return Status::fromServiceSpecificError(static_cast<int32_t>(res));
     }
diff --git a/services/tuner/TunerDescrambler.cpp b/services/tuner/TunerDescrambler.cpp
index 6b2889d..16338db 100644
--- a/services/tuner/TunerDescrambler.cpp
+++ b/services/tuner/TunerDescrambler.cpp
@@ -97,6 +97,8 @@
     }
 
     Result res = mDescrambler->close();
+    mDescrambler = NULL;
+
     if (res != Result::SUCCESS) {
         return Status::fromServiceSpecificError(static_cast<int32_t>(res));
     }
diff --git a/services/tuner/TunerDvr.cpp b/services/tuner/TunerDvr.cpp
index c7227b6..db4e07b 100644
--- a/services/tuner/TunerDvr.cpp
+++ b/services/tuner/TunerDvr.cpp
@@ -154,6 +154,8 @@
     }
 
     Result res = mDvr->close();
+    mDvr = NULL;
+
     if (res != Result::SUCCESS) {
         return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
     }
diff --git a/services/tuner/TunerFilter.cpp b/services/tuner/TunerFilter.cpp
index af5a600..dc9d246 100644
--- a/services/tuner/TunerFilter.cpp
+++ b/services/tuner/TunerFilter.cpp
@@ -285,6 +285,7 @@
         .srcPort = static_cast<uint16_t>(ipConf.ipAddr.srcPort),
         .dstPort = static_cast<uint16_t>(ipConf.ipAddr.dstPort),
     };
+
     ipConf.ipAddr.srcIpAddress.isIpV6
             ? ipAddr.srcIpAddress.v6(getIpV6Address(ipConf.ipAddr.srcIpAddress))
             : ipAddr.srcIpAddress.v4(getIpV4Address(ipConf.ipAddr.srcIpAddress));
@@ -314,7 +315,7 @@
 }
 
 hidl_array<uint8_t, IP_V6_LENGTH> TunerFilter::getIpV6Address(TunerDemuxIpAddress addr) {
-    hidl_array<uint8_t, IP_V6_LENGTH> ip = {0};
+    hidl_array<uint8_t, IP_V6_LENGTH> ip;
     if (addr.addr.size() != IP_V6_LENGTH) {
         return ip;
     }
@@ -323,7 +324,7 @@
 }
 
 hidl_array<uint8_t, IP_V4_LENGTH> TunerFilter::getIpV4Address(TunerDemuxIpAddress addr) {
-    hidl_array<uint8_t, IP_V4_LENGTH> ip = {0};
+    hidl_array<uint8_t, IP_V4_LENGTH> ip;
     if (addr.addr.size() != IP_V4_LENGTH) {
         return ip;
     }
@@ -541,6 +542,9 @@
         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
     }
     Result res = mFilter->close();
+    mFilter = NULL;
+    mFilter_1_1 = NULL;
+
     if (res != Result::SUCCESS) {
         return Status::fromServiceSpecificError(static_cast<int32_t>(res));
     }
@@ -620,16 +624,17 @@
         switch (eventExt.getDiscriminator()) {
             case DemuxFilterEventExt::Event::hidl_discriminator::monitorEvent: {
                 getMonitorEvent(eventsExt, tunerEvent);
-                break;
+                return;
             }
             case DemuxFilterEventExt::Event::hidl_discriminator::startId: {
                 getRestartEvent(eventsExt, tunerEvent);
-                break;
+                return;
             }
             default: {
                 break;
             }
         }
+        return;
     }
 
     if (!events.empty()) {
@@ -889,9 +894,6 @@
             tunerMonitor.set<TunerFilterMonitorEvent::cid>(static_cast<int>(monitorEvent.cid()));
             break;
         }
-        default: {
-            break;
-        }
     }
 
     TunerFilterEvent tunerEvent;
diff --git a/services/tuner/TunerFrontend.cpp b/services/tuner/TunerFrontend.cpp
index b85e58b..74b5519 100644
--- a/services/tuner/TunerFrontend.cpp
+++ b/services/tuner/TunerFrontend.cpp
@@ -278,11 +278,13 @@
     }
 
     Result status = mFrontend->close();
-    if (status == Result::SUCCESS) {
-        return Status::ok();
-    }
+    mFrontend = NULL;
+    mFrontend_1_1 = NULL;
 
-    return Status::fromServiceSpecificError(static_cast<int32_t>(status));
+    if (status != Result::SUCCESS) {
+        return Status::fromServiceSpecificError(static_cast<int32_t>(status));
+    }
+    return Status::ok();
 }
 
 Status TunerFrontend::getStatus(const vector<int32_t>& statusTypes,
@@ -804,13 +806,13 @@
             case FrontendStatusExt1_1::hidl_discriminator::rollOff: {
                 switch (s.rollOff().getDiscriminator()) {
                     case FrontendRollOff::hidl_discriminator::dvbs:
-                        status.set<TunerFrontendStatus::interleaving>((int)s.rollOff().dvbs());
+                        status.set<TunerFrontendStatus::rollOff>((int)s.rollOff().dvbs());
                         break;
                     case FrontendRollOff::hidl_discriminator::isdbs:
-                        status.set<TunerFrontendStatus::interleaving>((int)s.rollOff().isdbs());
+                        status.set<TunerFrontendStatus::rollOff>((int)s.rollOff().isdbs());
                         break;
                     case FrontendRollOff::hidl_discriminator::isdbs3:
-                        status.set<TunerFrontendStatus::interleaving>((int)s.rollOff().isdbs3());
+                        status.set<TunerFrontendStatus::rollOff>((int)s.rollOff().isdbs3());
                         break;
                 }
                 aidlStatus.push_back(status);
diff --git a/services/tuner/TunerLnb.cpp b/services/tuner/TunerLnb.cpp
index 0bfa3fd..4a5acf5 100644
--- a/services/tuner/TunerLnb.cpp
+++ b/services/tuner/TunerLnb.cpp
@@ -97,8 +97,13 @@
         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
     }
 
-    Result status = mLnb->close();
-    return Status::fromServiceSpecificError(static_cast<int32_t>(status));
+    Result res = mLnb->close();
+    mLnb = NULL;
+
+    if (res != Result::SUCCESS) {
+        return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+    }
+    return Status::ok();
 }
 
 /////////////// ILnbCallback ///////////////////////
diff --git a/services/tuner/TunerService.cpp b/services/tuner/TunerService.cpp
index 4f6f16c..b80fd85 100644
--- a/services/tuner/TunerService.cpp
+++ b/services/tuner/TunerService.cpp
@@ -52,10 +52,10 @@
 TunerService::TunerService() {}
 TunerService::~TunerService() {}
 
-void TunerService::instantiate() {
+binder_status_t TunerService::instantiate() {
     shared_ptr<TunerService> service =
             ::ndk::SharedRefBase::make<TunerService>();
-    AServiceManager_addService(service->asBinder().get(), getServiceName());
+    return AServiceManager_addService(service->asBinder().get(), getServiceName());
 }
 
 bool TunerService::hasITuner() {
@@ -68,23 +68,20 @@
         ALOGE("Failed to get ITuner service");
         return false;
     }
+    mTunerVersion = TUNER_HAL_VERSION_1_0;
+    mTuner_1_1 = ::android::hardware::tv::tuner::V1_1::ITuner::castFrom(mTuner);
+    if (mTuner_1_1 != nullptr) {
+        mTunerVersion = TUNER_HAL_VERSION_1_1;
+    } else {
+        ALOGE("Failed to get ITuner_1_1 service");
+    }
     return true;
 }
 
 bool TunerService::hasITuner_1_1() {
     ALOGD("hasITuner_1_1");
-    if (mTuner_1_1 != nullptr) {
-        return true;
-    }
-    if (!hasITuner()) {
-        return false;
-    }
-    mTuner_1_1 = ::android::hardware::tv::tuner::V1_1::ITuner::castFrom(mTuner);
-    if (mTuner_1_1 == nullptr) {
-        ALOGE("Failed to get ITuner_1_1 service");
-        return false;
-    }
-    return true;
+    hasITuner();
+    return (mTunerVersion == TUNER_HAL_VERSION_1_1);
 }
 
 Status TunerService::openDemux(
@@ -300,6 +297,12 @@
     return Status::ok();
 }
 
+Status TunerService::getTunerHalVersion(int* _aidl_return) {
+    hasITuner();
+    *_aidl_return = mTunerVersion;
+    return Status::ok();
+}
+
 void TunerService::updateFrontendResources() {
     hidl_vec<FrontendId> ids;
     Result res = getHidlFrontendIds(ids);
diff --git a/services/tuner/TunerService.h b/services/tuner/TunerService.h
index ce085cb..cc65b39 100644
--- a/services/tuner/TunerService.h
+++ b/services/tuner/TunerService.h
@@ -69,6 +69,10 @@
 
 namespace android {
 
+const static int TUNER_HAL_VERSION_UNKNOWN = 0;
+const static int TUNER_HAL_VERSION_1_0 = 1 << 16;
+const static int TUNER_HAL_VERSION_1_1 = (1 << 16) | 1;
+
 typedef enum {
     FRONTEND,
     LNB,
@@ -93,7 +97,7 @@
 
 public:
     static char const *getServiceName() { return "media.tuner"; }
-    static void instantiate();
+    static binder_status_t instantiate();
     TunerService();
     virtual ~TunerService();
 
@@ -110,6 +114,7 @@
     Status openDescrambler(int32_t descramblerHandle,
             std::shared_ptr<ITunerDescrambler>* _aidl_return) override;
     Status updateTunerResources() override;
+    Status getTunerHalVersion(int* _aidl_return) override;
 
     // TODO: create a map between resource id and handles.
     static int getResourceIdFromHandle(int resourceHandle, int /*type*/) {
@@ -141,6 +146,8 @@
 
     shared_ptr<ITunerResourceManager> mTunerResourceManager;
     int mResourceRequestCount = 0;
+
+    int mTunerVersion = TUNER_HAL_VERSION_UNKNOWN;
 };
 
 } // namespace android
diff --git a/services/tuner/TunerTimeFilter.cpp b/services/tuner/TunerTimeFilter.cpp
index dce76d2..25e1ad9 100644
--- a/services/tuner/TunerTimeFilter.cpp
+++ b/services/tuner/TunerTimeFilter.cpp
@@ -18,6 +18,9 @@
 
 #include "TunerTimeFilter.h"
 
+using ::android::hardware::tv::tuner::V1_0::Result;
+using ::android::hardware::tv::tuner::V1_1::Constant64Bit;
+
 namespace android {
 
 TunerTimeFilter::TunerTimeFilter(sp<ITimeFilter> timeFilter) {
@@ -28,23 +31,76 @@
     mTimeFilter = NULL;
 }
 
-Status TunerTimeFilter::setTimeStamp(int64_t /*timeStamp*/) {
-    return Status::ok();
+Status TunerTimeFilter::setTimeStamp(int64_t timeStamp) {
+    if (mTimeFilter == NULL) {
+        ALOGE("ITimeFilter is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result status = mTimeFilter->setTimeStamp(timeStamp);
+    return Status::fromServiceSpecificError(static_cast<int32_t>(status));
 }
 
 Status TunerTimeFilter::clearTimeStamp() {
-    return Status::ok();
+    if (mTimeFilter == NULL) {
+        ALOGE("ITimeFilter is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result status = mTimeFilter->clearTimeStamp();
+    return Status::fromServiceSpecificError(static_cast<int32_t>(status));
 }
 
-Status TunerTimeFilter::getSourceTime(int64_t* /*_aidl_return*/) {
-    return Status::ok();
+Status TunerTimeFilter::getSourceTime(int64_t* _aidl_return) {
+    if (mTimeFilter == NULL) {
+        *_aidl_return = (int64_t)Constant64Bit::INVALID_PRESENTATION_TIME_STAMP;
+        ALOGE("ITimeFilter is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result status;
+    mTimeFilter->getSourceTime(
+            [&](Result r, uint64_t t) {
+                status = r;
+                *_aidl_return = t;
+            });
+    if (status != Result::SUCCESS) {
+        *_aidl_return = (int64_t)Constant64Bit::INVALID_PRESENTATION_TIME_STAMP;
+    }
+    return Status::fromServiceSpecificError(static_cast<int32_t>(status));
 }
 
-Status TunerTimeFilter::getTimeStamp(int64_t* /*_aidl_return*/) {
-    return Status::ok();
+Status TunerTimeFilter::getTimeStamp(int64_t* _aidl_return) {
+    if (mTimeFilter == NULL) {
+        *_aidl_return = (int64_t)Constant64Bit::INVALID_PRESENTATION_TIME_STAMP;
+        ALOGE("ITimeFilter is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result status;
+    mTimeFilter->getTimeStamp(
+            [&](Result r, uint64_t t) {
+                status = r;
+                *_aidl_return = t;
+            });
+    if (status != Result::SUCCESS) {
+        *_aidl_return = (int64_t)Constant64Bit::INVALID_PRESENTATION_TIME_STAMP;
+    }
+    return Status::fromServiceSpecificError(static_cast<int32_t>(status));
 }
 
 Status TunerTimeFilter::close() {
+    if (mTimeFilter == NULL) {
+        ALOGE("ITimeFilter is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result res = mTimeFilter->close();
+    mTimeFilter = NULL;
+
+    if (res != Result::SUCCESS) {
+        return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+    }
     return Status::ok();
 }
 }  // namespace android
diff --git a/services/tuner/TunerTimeFilter.h b/services/tuner/TunerTimeFilter.h
index 50b8f54..d675319 100644
--- a/services/tuner/TunerTimeFilter.h
+++ b/services/tuner/TunerTimeFilter.h
@@ -19,6 +19,7 @@
 
 #include <aidl/android/media/tv/tuner/BnTunerTimeFilter.h>
 #include <android/hardware/tv/tuner/1.0/ITimeFilter.h>
+#include <android/hardware/tv/tuner/1.1/types.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <utils/Log.h>
 
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
index bea8811..f1651b9 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
@@ -101,4 +101,11 @@
      */
     // TODO: b/178124017 update TRM in TunerService independently.
     void updateTunerResources();
+
+    /**
+     * Get an integer that carries the Tuner HIDL version. The high 16 bits are the
+     * major version number while the low 16 bits are the minor version. Default
+     * value is unknown version 0.
+     */
+    int getTunerHalVersion();
 }
diff --git a/services/tuner/main_tunerservice.cpp b/services/tuner/main_tunerservice.cpp
index a0e7a9f..586a0e2 100644
--- a/services/tuner/main_tunerservice.cpp
+++ b/services/tuner/main_tunerservice.cpp
@@ -32,7 +32,11 @@
     sp<IServiceManager> sm = defaultServiceManager();
     ALOGD("ServiceManager: %p", sm.get());
 
-    TunerService::instantiate();
+    binder_status_t status = TunerService::instantiate();
+    if (status != STATUS_OK) {
+        ALOGD("Failed to add tuner service as AIDL interface");
+        return -1;
+    }
 
     ProcessState::self()->startThreadPool();
     IPCThreadState::self()->joinThreadPool();