Merge "MediaMetrics: Convert to AIDL" into sc-dev
diff --git a/apex/Android.bp b/apex/Android.bp
index bf91bf7..d8a0b91 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -15,7 +15,10 @@
 apex_defaults {
     name: "com.android.media-defaults",
     updatable: true,
-    java_libs: ["updatable-media"],
+    java_libs: [
+      "updatable-media",
+      "service-media-s",
+    ],
     multilib: {
         first: {
             // Extractor process runs only with the primary ABI.
diff --git a/camera/ndk/Android.bp b/camera/ndk/Android.bp
index 3cf94d0..5e1e43e 100644
--- a/camera/ndk/Android.bp
+++ b/camera/ndk/Android.bp
@@ -62,7 +62,7 @@
     ],
     cflags: [
         "-fvisibility=hidden",
-        "-DEXPORT=__attribute__ ((visibility (\"default\")))",
+        "-DEXPORT=__attribute__((visibility(\"default\")))",
         "-Wall",
         "-Wextra",
         "-Werror",
diff --git a/media/codec2/core/include/C2Config.h b/media/codec2/core/include/C2Config.h
index 38f7389..b806a25 100644
--- a/media/codec2/core/include/C2Config.h
+++ b/media/codec2/core/include/C2Config.h
@@ -221,6 +221,7 @@
     kParamIndexDrcEffectType, // drc, enum
     kParamIndexDrcOutputLoudness, // drc, float (dBFS)
     kParamIndexDrcAlbumMode, // drc, enum
+    kParamIndexAudioFrameSize, // int
 
     /* ============================== platform-defined parameters ============================== */
 
@@ -1969,9 +1970,20 @@
 /**
  * DRC output loudness in dBFS. Retrieved during decoding
  */
- typedef C2StreamParam<C2Info, C2FloatValue, kParamIndexDrcOutputLoudness>
+typedef C2StreamParam<C2Info, C2FloatValue, kParamIndexDrcOutputLoudness>
         C2StreamDrcOutputLoudnessTuning;
- constexpr char C2_PARAMKEY_DRC_OUTPUT_LOUDNESS[] = "output.drc.output-loudness";
+constexpr char C2_PARAMKEY_DRC_OUTPUT_LOUDNESS[] = "output.drc.output-loudness";
+
+/**
+ * Audio frame size in samples.
+ *
+ * Audio encoders can expose this parameter to signal the desired audio frame
+ * size that corresponds to a single coded access unit.
+ * Default value is 0, meaning that the encoder accepts input buffers of any size.
+ */
+typedef C2StreamParam<C2Info, C2Uint32Value, kParamIndexAudioFrameSize>
+        C2StreamAudioFrameSizeInfo;
+constexpr char C2_PARAMKEY_AUDIO_FRAME_SIZE[] = "raw.audio-frame-size";
 
 /* --------------------------------------- AAC components --------------------------------------- */
 
diff --git a/media/codec2/hidl/1.0/utils/types.cpp b/media/codec2/hidl/1.0/utils/types.cpp
index 1f0c856..72f7c43 100644
--- a/media/codec2/hidl/1.0/utils/types.cpp
+++ b/media/codec2/hidl/1.0/utils/types.cpp
@@ -895,13 +895,12 @@
         BufferPoolSender* bufferPoolSender,
         std::list<BaseBlock>* baseBlocks,
         std::map<const void*, uint32_t>* baseBlockIndices) {
-    // TODO: C2InfoBuffer is not implemented.
-    (void)d;
-    (void)s;
-    (void)bufferPoolSender;
-    (void)baseBlocks;
-    (void)baseBlockIndices;
-    LOG(INFO) << "InfoBuffer not implemented.";
+    d->index = static_cast<ParamIndex>(s.index());
+    Buffer& dBuffer = d->buffer;
+    if (!objcpy(&dBuffer, s.data(), bufferPoolSender, baseBlocks, baseBlockIndices)) {
+        LOG(ERROR) << "Invalid C2InfoBuffer::data";
+        return false;
+    }
     return true;
 }
 
@@ -1336,6 +1335,68 @@
     return true;
 }
 
+// InfoBuffer -> C2InfoBuffer
+bool objcpy(std::vector<C2InfoBuffer> *d, const InfoBuffer& s,
+        const std::vector<C2BaseBlock>& baseBlocks) {
+
+    // Currently, a non-null C2InfoBufer must contain exactly 1 block.
+    if (s.buffer.blocks.size() == 0) {
+        return true;
+    } else if (s.buffer.blocks.size() != 1) {
+        LOG(ERROR) << "Invalid InfoBuffer::Buffer "
+                      "Currently, a C2InfoBuffer must contain exactly 1 block.";
+        return false;
+    }
+
+    const Block &sBlock = s.buffer.blocks[0];
+    if (sBlock.index >= baseBlocks.size()) {
+        LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].index: "
+                      "Array index out of range.";
+        return false;
+    }
+    const C2BaseBlock &baseBlock = baseBlocks[sBlock.index];
+
+    // Parse meta.
+    std::vector<C2Param*> sBlockMeta;
+    if (!parseParamsBlob(&sBlockMeta, sBlock.meta)) {
+        LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].meta.";
+        return false;
+    }
+
+    // Copy fence.
+    C2Fence dFence;
+    if (!objcpy(&dFence, sBlock.fence)) {
+        LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].fence.";
+        return false;
+    }
+
+    // Construct a block.
+    switch (baseBlock.type) {
+    case C2BaseBlock::LINEAR:
+        if (sBlockMeta.size() == 1 && sBlockMeta[0] != nullptr &&
+            sBlockMeta[0]->size() == sizeof(C2Hidl_RangeInfo)) {
+            C2Hidl_RangeInfo *rangeInfo =
+                    reinterpret_cast<C2Hidl_RangeInfo*>(sBlockMeta[0]);
+            d->emplace_back(C2InfoBuffer::CreateLinearBuffer(
+                    s.index,
+                    baseBlock.linear->share(
+                            rangeInfo->offset, rangeInfo->length, dFence)));
+            return true;
+        }
+        LOG(ERROR) << "Invalid Meta for C2BaseBlock::Linear InfoBuffer.";
+        break;
+    case C2BaseBlock::GRAPHIC:
+        // It's not used now
+        LOG(ERROR) << "Non-Used C2BaseBlock::type for InfoBuffer.";
+        break;
+    default:
+        LOG(ERROR) << "Invalid C2BaseBlock::type for InfoBuffer.";
+        break;
+    }
+
+    return false;
+}
+
 // FrameData -> C2FrameData
 bool objcpy(C2FrameData* d, const FrameData& s,
         const std::vector<C2BaseBlock>& baseBlocks) {
@@ -1370,8 +1431,18 @@
         }
     }
 
-    // TODO: Implement this once C2InfoBuffer has constructors.
     d->infoBuffers.clear();
+    if (s.infoBuffers.size() == 0) {
+        // InfoBuffer is optional
+        return true;
+    }
+    d->infoBuffers.reserve(s.infoBuffers.size());
+    for (const InfoBuffer &sInfoBuffer: s.infoBuffers) {
+        if (!objcpy(&(d->infoBuffers), sInfoBuffer, baseBlocks)) {
+            LOG(ERROR) << "Invalid Framedata::infoBuffers.";
+            return false;
+        }
+    }
     return true;
 }
 
diff --git a/media/libaudiohal/Android.bp b/media/libaudiohal/Android.bp
index d9a7804..28549d0 100644
--- a/media/libaudiohal/Android.bp
+++ b/media/libaudiohal/Android.bp
@@ -14,7 +14,6 @@
     ],
 
     required: [
-        "libaudiohal@2.0",
         "libaudiohal@4.0",
         "libaudiohal@5.0",
         "libaudiohal@6.0",
diff --git a/media/libaudiohal/FactoryHalHidl.cpp b/media/libaudiohal/FactoryHalHidl.cpp
index 7228b22..e420d07 100644
--- a/media/libaudiohal/FactoryHalHidl.cpp
+++ b/media/libaudiohal/FactoryHalHidl.cpp
@@ -35,7 +35,6 @@
     "6.0",
     "5.0",
     "4.0",
-    "2.0",
     nullptr
 };
 
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index fe47881..0276e4b 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -54,22 +54,6 @@
 }
 
 cc_library_shared {
-    name: "libaudiohal@2.0",
-    defaults: ["libaudiohal_default"],
-    shared_libs: [
-        "android.hardware.audio.common@2.0",
-        "android.hardware.audio.common@2.0-util",
-        "android.hardware.audio.effect@2.0",
-        "android.hardware.audio@2.0",
-    ],
-    cflags: [
-        "-DMAJOR_VERSION=2",
-        "-DMINOR_VERSION=0",
-        "-include common/all-versions/VersionMacro.h",
-    ]
-}
-
-cc_library_shared {
     name: "libaudiohal@4.0",
     defaults: ["libaudiohal_default"],
     shared_libs: [
diff --git a/media/libmediahelper/tests/typeconverter_tests.cpp b/media/libmediahelper/tests/typeconverter_tests.cpp
index d7bfb89..181d636 100644
--- a/media/libmediahelper/tests/typeconverter_tests.cpp
+++ b/media/libmediahelper/tests/typeconverter_tests.cpp
@@ -182,8 +182,9 @@
         audio_format_t format;
         EXPECT_TRUE(FormatConverter::fromString(stringVal, format))
                 << "Conversion of \"" << stringVal << "\" failed";
-        EXPECT_TRUE(audio_is_valid_format(format))
-                << "Converted format \"" << stringVal << "\" is invalid";
+        EXPECT_EQ(enumVal != xsd::AudioFormat::AUDIO_FORMAT_DEFAULT,
+                audio_is_valid_format(format))
+                << "Validity of \"" << stringVal << "\" is not as expected";
         EXPECT_EQ(stringVal, toString(format));
     }
 }
diff --git a/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp b/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
index e3c0b05..994695f 100644
--- a/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
+++ b/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
@@ -238,7 +238,12 @@
     int32_t operatingRate = getDefaultOperatingRate(encoderFormat);
 
     if (operatingRate != -1) {
-        SetDefaultFormatValueInt32(AMEDIAFORMAT_KEY_OPERATING_RATE, encoderFormat, operatingRate);
+        float tmpf;
+        int32_t tmpi;
+        if (!AMediaFormat_getFloat(encoderFormat, AMEDIAFORMAT_KEY_OPERATING_RATE, &tmpf) &&
+            !AMediaFormat_getInt32(encoderFormat, AMEDIAFORMAT_KEY_OPERATING_RATE, &tmpi)) {
+            AMediaFormat_setInt32(encoderFormat, AMEDIAFORMAT_KEY_OPERATING_RATE, operatingRate);
+        }
     }
 
     SetDefaultFormatValueInt32(AMEDIAFORMAT_KEY_PRIORITY, encoderFormat, kDefaultCodecPriority);
@@ -260,8 +265,8 @@
         return AMEDIA_ERROR_INVALID_PARAMETER;
     }
 
-    // TODO: replace __ANDROID_API_FUTURE__with 31 when it's official (b/178144708)
-    #define __TRANSCODING_MIN_API__ __ANDROID_API_FUTURE__
+// TODO: replace __ANDROID_API_FUTURE__with 31 when it's official (b/178144708)
+#define __TRANSCODING_MIN_API__ __ANDROID_API_FUTURE__
 
     AMediaCodec* encoder;
     if (__builtin_available(android __TRANSCODING_MIN_API__, *)) {
diff --git a/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp b/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
index e0b2050..42933e6 100644
--- a/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
+++ b/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
@@ -33,6 +33,7 @@
 #include <binder/ProcessState.h>
 #include <fcntl.h>
 #include <media/MediaTranscoder.h>
+#include <media/NdkCommon.h>
 
 #include <iostream>
 
@@ -87,6 +88,7 @@
 
     AMediaFormat* videoFormat = AMediaFormat_new();
     AMediaFormat_setInt32(videoFormat, AMEDIAFORMAT_KEY_BIT_RATE, kVideoBitRate);
+    AMediaFormat_setString(videoFormat, AMEDIAFORMAT_KEY_MIME, AMEDIA_MIMETYPE_VIDEO_AVC);
     return videoFormat;
 }
 
@@ -222,7 +224,7 @@
 }
 
 static void SetMaxOperatingRate(AMediaFormat* format) {
-    AMediaFormat_setFloat(format, AMEDIAFORMAT_KEY_OPERATING_RATE, INT32_MAX);
+    AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_OPERATING_RATE, INT32_MAX);
     AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_PRIORITY, 1);
 }
 
diff --git a/media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml b/media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml
index 6d781cd..e40a507 100644
--- a/media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml
+++ b/media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml
@@ -24,6 +24,7 @@
     <test class="com.android.tradefed.testtype.GTest" >
         <option name="native-test-device-path" value="/data/local/tmp" />
         <option name="module-name" value="{MODULE}" />
+        <option name="native-test-timeout" value="10m" />
     </test>
 </configuration>
 
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 1f5b8d2..eaf0d10 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2961,7 +2961,10 @@
     auto backInserter = std::back_inserter(metadata.tracks);
     for (const sp<Track> &track : mActiveTracks) {
         // No track is invalid as this is called after prepareTrack_l in the same critical section
-        track->copyMetadataTo(backInserter);
+        // Do not forward metadata for PatchTrack with unspecified stream type
+        if (track->streamType() != AUDIO_STREAM_PATCH) {
+            track->copyMetadataTo(backInserter);
+        }
     }
     sendMetadataToBackend_l(metadata);
 }
@@ -8101,6 +8104,10 @@
     }
     StreamInHalInterface::SinkMetadata metadata;
     for (const sp<RecordTrack> &track : mActiveTracks) {
+        // Do not forward PatchRecord metadata to audio HAL
+        if (track->isPatchTrack()) {
+            continue;
+        }
         // No track is invalid as this is called after prepareTrack_l in the same critical section
         record_track_metadata_v7_t trackMetadata;
         trackMetadata.base = {
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index fed88a4..0ab63cf 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -590,7 +590,14 @@
 
     bool canCaptureHotword = captureHotwordAllowed(opPackageName, pid, uid);
     if ((inputSource == AUDIO_SOURCE_HOTWORD) && !canCaptureHotword) {
-        return binderStatusFromStatusT(BAD_VALUE);
+        return binderStatusFromStatusT(PERMISSION_DENIED);
+    }
+
+    if (((flags & AUDIO_INPUT_FLAG_HW_HOTWORD) != 0)
+            && !canCaptureHotword) {
+        ALOGE("%s: permission denied: hotword mode not allowed"
+              " for uid %d pid %d", __func__, uid, pid);
+        return binderStatusFromStatusT(PERMISSION_DENIED);
     }
 
     sp<AudioPolicyEffects>audioPolicyEffects;
diff --git a/services/tuner/TunerDemux.cpp b/services/tuner/TunerDemux.cpp
index 0e0cd3b..1f8b70d 100644
--- a/services/tuner/TunerDemux.cpp
+++ b/services/tuner/TunerDemux.cpp
@@ -124,4 +124,17 @@
     *_aidl_return = ::ndk::SharedRefBase::make<TunerDvr>(hidlDvr, dvrType);
     return Status::ok();
 }
+
+Status TunerDemux::close() {
+    if (mDemux == nullptr) {
+        ALOGE("IDemux is not initialized.");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result res = mDemux->close();
+    if (res != Result::SUCCESS) {
+        return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+    }
+    return Status::ok();
+}
 }  // namespace android
diff --git a/services/tuner/TunerDemux.h b/services/tuner/TunerDemux.h
index 675bb7c..594fd66 100644
--- a/services/tuner/TunerDemux.h
+++ b/services/tuner/TunerDemux.h
@@ -47,6 +47,7 @@
     Status openDvr(
         int dvbType, int bufferSize, const shared_ptr<ITunerDvrCallback>& cb,
         shared_ptr<ITunerDvr>* _aidl_return) override;
+    Status close() override;
 
 private:
     sp<IDemux> mDemux;
diff --git a/services/tuner/TunerFilter.cpp b/services/tuner/TunerFilter.cpp
index 722d36d..edfc291 100644
--- a/services/tuner/TunerFilter.cpp
+++ b/services/tuner/TunerFilter.cpp
@@ -16,16 +16,19 @@
 
 #define LOG_TAG "TunerFilter"
 
-#include <aidlcommonsupport/NativeHandle.h>
 #include "TunerFilter.h"
 
+using ::android::hardware::hidl_handle;
+using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
 using ::android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
+using ::android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType;
 using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterSettings;
+using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
 using ::android::hardware::tv::tuner::V1_0::Result;
-
 namespace android {
 
-TunerFilter::TunerFilter(sp<IFilter> filter, sp<IFilterCallback> callback) {
+TunerFilter::TunerFilter(
+        sp<IFilter> filter, sp<IFilterCallback> callback) {
     mFilter = filter;
     mFilter_1_1 = ::android::hardware::tv::tuner::V1_1::IFilter::castFrom(filter);
     mFilterCallback = callback;
@@ -103,6 +106,7 @@
                     break;
                 }
             }
+            halSettings.ts(ts);
             break;
         }
     }
@@ -113,6 +117,44 @@
     return Status::ok();
 }
 
+Status TunerFilter::getAvSharedHandleInfo(TunerFilterSharedHandleInfo* _aidl_return) {
+    if (mFilter_1_1 == nullptr) {
+        ALOGE("IFilter_1_1 is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result res;
+    mFilter_1_1->getAvSharedHandle([&](Result r, hidl_handle avMemory, uint64_t avMemSize) {
+        res = r;
+        if (res == Result::SUCCESS) {
+            TunerFilterSharedHandleInfo info{
+                .handle = dupToAidl(hidl_handle(avMemory.getNativeHandle())),
+                .size = static_cast<int64_t>(avMemSize),
+            };
+            *_aidl_return = std::move(info);
+        } else {
+            _aidl_return = NULL;
+        }
+    });
+
+    return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+}
+
+Status TunerFilter::releaseAvHandle(
+        const ::aidl::android::hardware::common::NativeHandle& handle, int64_t avDataId) {
+    if (mFilter == nullptr) {
+        ALOGE("IFilter is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result res = mFilter->releaseAvHandle(hidl_handle(makeFromAidl(handle)), avDataId);
+    if (res != Result::SUCCESS) {
+        return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+    }
+    return Status::ok();
+}
+
+
 Status TunerFilter::start() {
     if (mFilter == nullptr) {
         ALOGE("IFilter is not initialized");
@@ -149,6 +191,18 @@
     return Status::ok();
 }
 
+Status TunerFilter::close() {
+    if (mFilter == nullptr) {
+        ALOGE("IFilter is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+    Result res = mFilter->close();
+    if (res != Result::SUCCESS) {
+        return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+    }
+    return Status::ok();
+}
+
 sp<IFilter> TunerFilter::getHalFilter() {
     return mFilter;
 }
@@ -164,8 +218,8 @@
         tunerMedia.streamId = static_cast<int>(mediaEvent.streamId);
         tunerMedia.isPtsPresent = mediaEvent.isPtsPresent;
         tunerMedia.pts = static_cast<long>(mediaEvent.pts);
-        tunerMedia.dataLength = static_cast<long>(mediaEvent.dataLength);
-        tunerMedia.offset = static_cast<long>(mediaEvent.offset);
+        tunerMedia.dataLength = static_cast<int>(mediaEvent.dataLength);
+        tunerMedia.offset = static_cast<int>(mediaEvent.offset);
         tunerMedia.isSecureMemory = mediaEvent.isSecureMemory;
         tunerMedia.avDataId = static_cast<long>(mediaEvent.avDataId);
         tunerMedia.mpuSequenceNumber = static_cast<int>(mediaEvent.mpuSequenceNumber);
@@ -187,7 +241,6 @@
 }
 
 Return<void> TunerFilter::FilterCallback::onFilterEvent(const DemuxFilterEvent& filterEvent) {
-    ALOGD("FilterCallback::onFilterEvent");
     std::vector<DemuxFilterEvent::Event> events = filterEvent.events;
     std::vector<TunerFilterEvent> tunerEvent;
 
@@ -203,7 +256,8 @@
             }
         }
     }
-    mTunerFilterCallback->onFilterEvent(&tunerEvent);
+
+    mTunerFilterCallback->onFilterEvent(tunerEvent);
     return Void();
 }
 
diff --git a/services/tuner/TunerFilter.h b/services/tuner/TunerFilter.h
index 7f5838c..2f10435 100644
--- a/services/tuner/TunerFilter.h
+++ b/services/tuner/TunerFilter.h
@@ -19,6 +19,7 @@
 
 #include <aidl/android/media/tv/tuner/BnTunerFilter.h>
 #include <aidl/android/media/tv/tuner/ITunerFilterCallback.h>
+#include <aidlcommonsupport/NativeHandle.h>
 #include <android/hardware/tv/tuner/1.1/IFilter.h>
 #include <android/hardware/tv/tuner/1.0/ITuner.h>
 #include <media/stagefright/foundation/ADebug.h>
@@ -29,6 +30,7 @@
 using ::aidl::android::media::tv::tuner::TunerFilterConfiguration;
 using ::aidl::android::media::tv::tuner::TunerFilterEvent;
 using ::aidl::android::media::tv::tuner::TunerFilterMediaEvent;
+using ::aidl::android::media::tv::tuner::TunerFilterSharedHandleInfo;
 using ::aidl::android::media::tv::tuner::TunerFilterSettings;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
@@ -39,7 +41,6 @@
 using ::android::hardware::tv::tuner::V1_0::IFilter;
 using ::android::hardware::tv::tuner::V1_0::IFilterCallback;
 
-
 namespace android {
 
 class TunerFilter : public BnTunerFilter {
@@ -50,9 +51,13 @@
     Status getId(int32_t* _aidl_return) override;
     Status getId64Bit(int64_t* _aidl_return) override;
     Status configure(const TunerFilterConfiguration& config) override;
+    Status getAvSharedHandleInfo(TunerFilterSharedHandleInfo* _aidl_return) override;
+    Status releaseAvHandle(const ::aidl::android::hardware::common::NativeHandle& handle,
+            int64_t avDataId) override;
     Status start() override;
     Status stop() override;
     Status flush() override;
+    Status close() override;
     sp<IFilter> getHalFilter();
 
     struct FilterCallback : public IFilterCallback {
diff --git a/services/tuner/TunerFrontend.cpp b/services/tuner/TunerFrontend.cpp
index e92489d..bb8b07d 100644
--- a/services/tuner/TunerFrontend.cpp
+++ b/services/tuner/TunerFrontend.cpp
@@ -66,7 +66,6 @@
 using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtSettings;
 using ::android::hardware::tv::tuner::V1_0::FrontendScanAtsc3PlpInfo;
 using ::android::hardware::tv::tuner::V1_0::FrontendScanType;
-using ::android::hardware::tv::tuner::V1_0::FrontendSettings;;
 using ::android::hardware::tv::tuner::V1_0::Result;
 using ::android::hardware::tv::tuner::V1_1::FrontendModulation;
 
@@ -80,6 +79,7 @@
 
 TunerFrontend::~TunerFrontend() {
     mFrontend = NULL;
+    mFrontend_1_1 = NULL;
     mId = -1;
 }
 
@@ -103,12 +103,33 @@
     return Status::fromServiceSpecificError(static_cast<int32_t>(status));
 }
 
-Status TunerFrontend::tune(const TunerFrontendSettings& /*settings*/) {
-    return Status::ok();
+Status TunerFrontend::tune(const TunerFrontendSettings& settings) {
+    if (mFrontend == NULL) {
+        ALOGD("IFrontend is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    FrontendSettings frontendSettings = getHidlFrontendSettings(settings);
+    Result status = mFrontend->tune(frontendSettings);
+    if (status == Result::SUCCESS) {
+        return Status::ok();
+    }
+
+    return Status::fromServiceSpecificError(static_cast<int32_t>(status));
 }
 
 Status TunerFrontend::stopTune() {
-    return Status::ok();
+    if (mFrontend == NULL) {
+        ALOGD("IFrontend is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result status = mFrontend->stopTune();
+    if (status == Result::SUCCESS) {
+        return Status::ok();
+    }
+
+    return Status::fromServiceSpecificError(static_cast<int32_t>(status));
 }
 
 Status TunerFrontend::scan(const TunerFrontendSettings& settings, int frontendScanType) {
@@ -117,165 +138,7 @@
         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
     }
 
-    // TODO: extend TunerFrontendSettings to use 1.1 types
-    FrontendSettings frontendSettings;
-    switch (settings.getTag()) {
-        case TunerFrontendSettings::analog:
-            frontendSettings.analog({
-                .frequency = static_cast<uint32_t>(
-                        settings.get<TunerFrontendSettings::analog>().frequency),
-                .type = static_cast<FrontendAnalogType>(
-                        settings.get<TunerFrontendSettings::analog>().signalType),
-                .sifStandard = static_cast<FrontendAnalogSifStandard>(
-                        settings.get<TunerFrontendSettings::analog>().sifStandard),
-            });
-            break;
-        case TunerFrontendSettings::atsc:
-            frontendSettings.atsc({
-                .frequency = static_cast<uint32_t>(
-                        settings.get<TunerFrontendSettings::atsc>().frequency),
-                .modulation = static_cast<FrontendAtscModulation>(
-                        settings.get<TunerFrontendSettings::atsc>().modulation),
-            });
-            break;
-        case TunerFrontendSettings::atsc3:
-            frontendSettings.atsc3({
-                .frequency = static_cast<uint32_t>(
-                        settings.get<TunerFrontendSettings::atsc3>().frequency),
-                .bandwidth = static_cast<FrontendAtsc3Bandwidth>(
-                        settings.get<TunerFrontendSettings::atsc3>().bandwidth),
-                .demodOutputFormat = static_cast<FrontendAtsc3DemodOutputFormat>(
-                        settings.get<TunerFrontendSettings::atsc3>().demodOutputFormat),
-                .plpSettings = getAtsc3PlpSettings(settings.get<TunerFrontendSettings::atsc3>()),
-            });
-            break;
-        case TunerFrontendSettings::cable:
-            frontendSettings.dvbc({
-                .frequency = static_cast<uint32_t>(
-                        settings.get<TunerFrontendSettings::cable>().frequency),
-                .modulation = static_cast<FrontendDvbcModulation>(
-                        settings.get<TunerFrontendSettings::cable>().modulation),
-                .fec = static_cast<FrontendInnerFec>(
-                        settings.get<TunerFrontendSettings::cable>().innerFec),
-                .symbolRate = static_cast<uint32_t>(
-                        settings.get<TunerFrontendSettings::cable>().symbolRate),
-                .outerFec = static_cast<FrontendDvbcOuterFec>(
-                        settings.get<TunerFrontendSettings::cable>().outerFec),
-                .annex = static_cast<FrontendDvbcAnnex>(
-                        settings.get<TunerFrontendSettings::cable>().annex),
-                .spectralInversion = static_cast<FrontendDvbcSpectralInversion>(
-                        settings.get<TunerFrontendSettings::cable>().spectralInversion),
-            });
-            break;
-        case TunerFrontendSettings::dvbs:
-            frontendSettings.dvbs({
-                .frequency = static_cast<uint32_t>(
-                        settings.get<TunerFrontendSettings::dvbs>().frequency),
-                .modulation = static_cast<FrontendDvbsModulation>(
-                        settings.get<TunerFrontendSettings::dvbs>().modulation),
-                .coderate = getDvbsCodeRate(
-                        settings.get<TunerFrontendSettings::dvbs>().codeRate),
-                .symbolRate = static_cast<uint32_t>(
-                        settings.get<TunerFrontendSettings::dvbs>().symbolRate),
-                .rolloff = static_cast<FrontendDvbsRolloff>(
-                        settings.get<TunerFrontendSettings::dvbs>().rolloff),
-                .pilot = static_cast<FrontendDvbsPilot>(
-                        settings.get<TunerFrontendSettings::dvbs>().pilot),
-                .inputStreamId = static_cast<uint32_t>(
-                        settings.get<TunerFrontendSettings::dvbs>().inputStreamId),
-                .standard = static_cast<FrontendDvbsStandard>(
-                        settings.get<TunerFrontendSettings::dvbs>().standard),
-                .vcmMode = static_cast<FrontendDvbsVcmMode>(
-                        settings.get<TunerFrontendSettings::dvbs>().vcm),
-            });
-            break;
-        case TunerFrontendSettings::dvbt:
-            frontendSettings.dvbt({
-                .frequency = static_cast<uint32_t>(
-                        settings.get<TunerFrontendSettings::dvbt>().frequency),
-                .transmissionMode = static_cast<FrontendDvbtTransmissionMode>(
-                        settings.get<TunerFrontendSettings::dvbt>().transmissionMode),
-                .bandwidth = static_cast<FrontendDvbtBandwidth>(
-                        settings.get<TunerFrontendSettings::dvbt>().bandwidth),
-                .constellation = static_cast<FrontendDvbtConstellation>(
-                        settings.get<TunerFrontendSettings::dvbt>().constellation),
-                .hierarchy = static_cast<FrontendDvbtHierarchy>(
-                        settings.get<TunerFrontendSettings::dvbt>().hierarchy),
-                .hpCoderate = static_cast<FrontendDvbtCoderate>(
-                        settings.get<TunerFrontendSettings::dvbt>().hpCodeRate),
-                .lpCoderate = static_cast<FrontendDvbtCoderate>(
-                        settings.get<TunerFrontendSettings::dvbt>().lpCodeRate),
-                .guardInterval = static_cast<FrontendDvbtGuardInterval>(
-                        settings.get<TunerFrontendSettings::dvbt>().guardInterval),
-                .isHighPriority = settings.get<TunerFrontendSettings::dvbt>().isHighPriority,
-                .standard = static_cast<FrontendDvbtStandard>(
-                        settings.get<TunerFrontendSettings::dvbt>().standard),
-                .isMiso = settings.get<TunerFrontendSettings::dvbt>().isMiso,
-                .plpMode = static_cast<FrontendDvbtPlpMode>(
-                        settings.get<TunerFrontendSettings::dvbt>().plpMode),
-                .plpId = static_cast<uint8_t>(
-                        settings.get<TunerFrontendSettings::dvbt>().plpId),
-                .plpGroupId = static_cast<uint8_t>(
-                        settings.get<TunerFrontendSettings::dvbt>().plpGroupId),
-            });
-            break;
-        case TunerFrontendSettings::isdbs:
-            frontendSettings.isdbs({
-                .frequency = static_cast<uint32_t>(
-                        settings.get<TunerFrontendSettings::isdbs>().frequency),
-                .streamId = static_cast<uint16_t>(
-                        settings.get<TunerFrontendSettings::isdbs>().streamId),
-                .streamIdType = static_cast<FrontendIsdbsStreamIdType>(
-                        settings.get<TunerFrontendSettings::isdbs>().streamIdType),
-                .modulation = static_cast<FrontendIsdbsModulation>(
-                        settings.get<TunerFrontendSettings::isdbs>().modulation),
-                .coderate = static_cast<FrontendIsdbsCoderate>(
-                        settings.get<TunerFrontendSettings::isdbs>().codeRate),
-                .symbolRate = static_cast<uint32_t>(
-                        settings.get<TunerFrontendSettings::isdbs>().symbolRate),
-                .rolloff = static_cast<FrontendIsdbsRolloff>(
-                        settings.get<TunerFrontendSettings::isdbs>().rolloff),
-            });
-            break;
-        case TunerFrontendSettings::isdbs3:
-            frontendSettings.isdbs3({
-                .frequency = static_cast<uint32_t>(
-                        settings.get<TunerFrontendSettings::isdbs3>().frequency),
-                .streamId = static_cast<uint16_t>(
-                        settings.get<TunerFrontendSettings::isdbs3>().streamId),
-                .streamIdType = static_cast<FrontendIsdbsStreamIdType>(
-                        settings.get<TunerFrontendSettings::isdbs3>().streamIdType),
-                .modulation = static_cast<FrontendIsdbs3Modulation>(
-                        settings.get<TunerFrontendSettings::isdbs3>().modulation),
-                .coderate = static_cast<FrontendIsdbs3Coderate>(
-                        settings.get<TunerFrontendSettings::isdbs3>().codeRate),
-                .symbolRate = static_cast<uint32_t>(
-                        settings.get<TunerFrontendSettings::isdbs3>().symbolRate),
-                .rolloff = static_cast<FrontendIsdbs3Rolloff>(
-                        settings.get<TunerFrontendSettings::isdbs3>().rolloff),
-            });
-            break;
-        case TunerFrontendSettings::isdbt:
-            frontendSettings.isdbt({
-                .frequency = static_cast<uint32_t>(
-                        settings.get<TunerFrontendSettings::isdbt>().frequency),
-                .modulation = static_cast<FrontendIsdbtModulation>(
-                        settings.get<TunerFrontendSettings::isdbt>().modulation),
-                .bandwidth = static_cast<FrontendIsdbtBandwidth>(
-                        settings.get<TunerFrontendSettings::isdbt>().bandwidth),
-                .mode = static_cast<FrontendIsdbtMode>(
-                        settings.get<TunerFrontendSettings::isdbt>().mode),
-                .coderate = static_cast<FrontendIsdbtCoderate>(
-                        settings.get<TunerFrontendSettings::isdbt>().codeRate),
-                .guardInterval = static_cast<FrontendIsdbtGuardInterval>(
-                        settings.get<TunerFrontendSettings::isdbt>().guardInterval),
-                .serviceAreaId = static_cast<uint32_t>(
-                        settings.get<TunerFrontendSettings::isdbt>().serviceAreaId),
-            });
-            break;
-        default:
-            break;
-    }
+    FrontendSettings frontendSettings = getHidlFrontendSettings(settings);
     Result status = mFrontend->scan(
             frontendSettings, static_cast<FrontendScanType>(frontendScanType));
     if (status == Result::SUCCESS) {
@@ -286,7 +149,17 @@
 }
 
 Status TunerFrontend::stopScan() {
-    return Status::ok();
+    if (mFrontend == NULL) {
+        ALOGD("IFrontend is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result status = mFrontend->stopScan();
+    if (status == Result::SUCCESS) {
+        return Status::ok();
+    }
+
+    return Status::fromServiceSpecificError(static_cast<int32_t>(status));
 }
 
 Status TunerFrontend::setLnb(int /*lnbHandle*/) {
@@ -298,7 +171,17 @@
 }
 
 Status TunerFrontend::close() {
-    return Status::ok();
+    if (mFrontend == NULL) {
+        ALOGD("IFrontend is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result status = mFrontend->close();
+    if (status == Result::SUCCESS) {
+        return Status::ok();
+    }
+
+    return Status::fromServiceSpecificError(static_cast<int32_t>(status));
 }
 
 Status TunerFrontend::getStatus(const vector<int32_t>& /*statusTypes*/,
@@ -500,4 +383,167 @@
     };
     return coderate;
 }
+
+FrontendSettings TunerFrontend::getHidlFrontendSettings(const TunerFrontendSettings& settings) {
+    // TODO: extend TunerFrontendSettings to use 1.1 types
+    FrontendSettings frontendSettings;
+    switch (settings.getTag()) {
+        case TunerFrontendSettings::analog:
+            frontendSettings.analog({
+                .frequency = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::analog>().frequency),
+                .type = static_cast<FrontendAnalogType>(
+                        settings.get<TunerFrontendSettings::analog>().signalType),
+                .sifStandard = static_cast<FrontendAnalogSifStandard>(
+                        settings.get<TunerFrontendSettings::analog>().sifStandard),
+            });
+            break;
+        case TunerFrontendSettings::atsc:
+            frontendSettings.atsc({
+                .frequency = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::atsc>().frequency),
+                .modulation = static_cast<FrontendAtscModulation>(
+                        settings.get<TunerFrontendSettings::atsc>().modulation),
+            });
+            break;
+        case TunerFrontendSettings::atsc3:
+            frontendSettings.atsc3({
+                .frequency = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::atsc3>().frequency),
+                .bandwidth = static_cast<FrontendAtsc3Bandwidth>(
+                        settings.get<TunerFrontendSettings::atsc3>().bandwidth),
+                .demodOutputFormat = static_cast<FrontendAtsc3DemodOutputFormat>(
+                        settings.get<TunerFrontendSettings::atsc3>().demodOutputFormat),
+                .plpSettings = getAtsc3PlpSettings(settings.get<TunerFrontendSettings::atsc3>()),
+            });
+            break;
+        case TunerFrontendSettings::cable:
+            frontendSettings.dvbc({
+                .frequency = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::cable>().frequency),
+                .modulation = static_cast<FrontendDvbcModulation>(
+                        settings.get<TunerFrontendSettings::cable>().modulation),
+                .fec = static_cast<FrontendInnerFec>(
+                        settings.get<TunerFrontendSettings::cable>().innerFec),
+                .symbolRate = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::cable>().symbolRate),
+                .outerFec = static_cast<FrontendDvbcOuterFec>(
+                        settings.get<TunerFrontendSettings::cable>().outerFec),
+                .annex = static_cast<FrontendDvbcAnnex>(
+                        settings.get<TunerFrontendSettings::cable>().annex),
+                .spectralInversion = static_cast<FrontendDvbcSpectralInversion>(
+                        settings.get<TunerFrontendSettings::cable>().spectralInversion),
+            });
+            break;
+        case TunerFrontendSettings::dvbs:
+            frontendSettings.dvbs({
+                .frequency = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::dvbs>().frequency),
+                .modulation = static_cast<FrontendDvbsModulation>(
+                        settings.get<TunerFrontendSettings::dvbs>().modulation),
+                .coderate = getDvbsCodeRate(
+                        settings.get<TunerFrontendSettings::dvbs>().codeRate),
+                .symbolRate = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::dvbs>().symbolRate),
+                .rolloff = static_cast<FrontendDvbsRolloff>(
+                        settings.get<TunerFrontendSettings::dvbs>().rolloff),
+                .pilot = static_cast<FrontendDvbsPilot>(
+                        settings.get<TunerFrontendSettings::dvbs>().pilot),
+                .inputStreamId = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::dvbs>().inputStreamId),
+                .standard = static_cast<FrontendDvbsStandard>(
+                        settings.get<TunerFrontendSettings::dvbs>().standard),
+                .vcmMode = static_cast<FrontendDvbsVcmMode>(
+                        settings.get<TunerFrontendSettings::dvbs>().vcm),
+            });
+            break;
+        case TunerFrontendSettings::dvbt:
+            frontendSettings.dvbt({
+                .frequency = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::dvbt>().frequency),
+                .transmissionMode = static_cast<FrontendDvbtTransmissionMode>(
+                        settings.get<TunerFrontendSettings::dvbt>().transmissionMode),
+                .bandwidth = static_cast<FrontendDvbtBandwidth>(
+                        settings.get<TunerFrontendSettings::dvbt>().bandwidth),
+                .constellation = static_cast<FrontendDvbtConstellation>(
+                        settings.get<TunerFrontendSettings::dvbt>().constellation),
+                .hierarchy = static_cast<FrontendDvbtHierarchy>(
+                        settings.get<TunerFrontendSettings::dvbt>().hierarchy),
+                .hpCoderate = static_cast<FrontendDvbtCoderate>(
+                        settings.get<TunerFrontendSettings::dvbt>().hpCodeRate),
+                .lpCoderate = static_cast<FrontendDvbtCoderate>(
+                        settings.get<TunerFrontendSettings::dvbt>().lpCodeRate),
+                .guardInterval = static_cast<FrontendDvbtGuardInterval>(
+                        settings.get<TunerFrontendSettings::dvbt>().guardInterval),
+                .isHighPriority = settings.get<TunerFrontendSettings::dvbt>().isHighPriority,
+                .standard = static_cast<FrontendDvbtStandard>(
+                        settings.get<TunerFrontendSettings::dvbt>().standard),
+                .isMiso = settings.get<TunerFrontendSettings::dvbt>().isMiso,
+                .plpMode = static_cast<FrontendDvbtPlpMode>(
+                        settings.get<TunerFrontendSettings::dvbt>().plpMode),
+                .plpId = static_cast<uint8_t>(
+                        settings.get<TunerFrontendSettings::dvbt>().plpId),
+                .plpGroupId = static_cast<uint8_t>(
+                        settings.get<TunerFrontendSettings::dvbt>().plpGroupId),
+            });
+            break;
+        case TunerFrontendSettings::isdbs:
+            frontendSettings.isdbs({
+                .frequency = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::isdbs>().frequency),
+                .streamId = static_cast<uint16_t>(
+                        settings.get<TunerFrontendSettings::isdbs>().streamId),
+                .streamIdType = static_cast<FrontendIsdbsStreamIdType>(
+                        settings.get<TunerFrontendSettings::isdbs>().streamIdType),
+                .modulation = static_cast<FrontendIsdbsModulation>(
+                        settings.get<TunerFrontendSettings::isdbs>().modulation),
+                .coderate = static_cast<FrontendIsdbsCoderate>(
+                        settings.get<TunerFrontendSettings::isdbs>().codeRate),
+                .symbolRate = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::isdbs>().symbolRate),
+                .rolloff = static_cast<FrontendIsdbsRolloff>(
+                        settings.get<TunerFrontendSettings::isdbs>().rolloff),
+            });
+            break;
+        case TunerFrontendSettings::isdbs3:
+            frontendSettings.isdbs3({
+                .frequency = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::isdbs3>().frequency),
+                .streamId = static_cast<uint16_t>(
+                        settings.get<TunerFrontendSettings::isdbs3>().streamId),
+                .streamIdType = static_cast<FrontendIsdbsStreamIdType>(
+                        settings.get<TunerFrontendSettings::isdbs3>().streamIdType),
+                .modulation = static_cast<FrontendIsdbs3Modulation>(
+                        settings.get<TunerFrontendSettings::isdbs3>().modulation),
+                .coderate = static_cast<FrontendIsdbs3Coderate>(
+                        settings.get<TunerFrontendSettings::isdbs3>().codeRate),
+                .symbolRate = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::isdbs3>().symbolRate),
+                .rolloff = static_cast<FrontendIsdbs3Rolloff>(
+                        settings.get<TunerFrontendSettings::isdbs3>().rolloff),
+            });
+            break;
+        case TunerFrontendSettings::isdbt:
+            frontendSettings.isdbt({
+                .frequency = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::isdbt>().frequency),
+                .modulation = static_cast<FrontendIsdbtModulation>(
+                        settings.get<TunerFrontendSettings::isdbt>().modulation),
+                .bandwidth = static_cast<FrontendIsdbtBandwidth>(
+                        settings.get<TunerFrontendSettings::isdbt>().bandwidth),
+                .mode = static_cast<FrontendIsdbtMode>(
+                        settings.get<TunerFrontendSettings::isdbt>().mode),
+                .coderate = static_cast<FrontendIsdbtCoderate>(
+                        settings.get<TunerFrontendSettings::isdbt>().codeRate),
+                .guardInterval = static_cast<FrontendIsdbtGuardInterval>(
+                        settings.get<TunerFrontendSettings::isdbt>().guardInterval),
+                .serviceAreaId = static_cast<uint32_t>(
+                        settings.get<TunerFrontendSettings::isdbt>().serviceAreaId),
+            });
+            break;
+        default:
+            break;
+    }
+    return frontendSettings;
+}
 }  // namespace android
diff --git a/services/tuner/TunerFrontend.h b/services/tuner/TunerFrontend.h
index 99cdcdf..431022d 100644
--- a/services/tuner/TunerFrontend.h
+++ b/services/tuner/TunerFrontend.h
@@ -41,6 +41,7 @@
 using ::android::hardware::tv::tuner::V1_0::FrontendId;
 using ::android::hardware::tv::tuner::V1_0::FrontendScanMessage;
 using ::android::hardware::tv::tuner::V1_0::FrontendScanMessageType;
+using ::android::hardware::tv::tuner::V1_0::FrontendSettings;;
 using ::android::hardware::tv::tuner::V1_0::IFrontend;
 using ::android::hardware::tv::tuner::V1_1::IFrontendCallback;
 using ::android::hardware::tv::tuner::V1_1::FrontendScanMessageExt1_1;
@@ -85,6 +86,7 @@
     hidl_vec<FrontendAtsc3PlpSettings> getAtsc3PlpSettings(
             const TunerFrontendAtsc3Settings& settings);
     FrontendDvbsCodeRate getDvbsCodeRate(const TunerFrontendDvbsCodeRate& codeRate);
+    FrontendSettings getHidlFrontendSettings(const TunerFrontendSettings& settings);
 
     int mId;
     sp<IFrontend> mFrontend;
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerDemux.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerDemux.aidl
index f6de618..fa2c1ff 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerDemux.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerDemux.aidl
@@ -44,4 +44,9 @@
      * Open a DVR (Digital Video Record) instance in the demux.
      */
     ITunerDvr openDvr(in int dvbType, in int bufferSize, in ITunerDvrCallback cb);
+
+    /**
+     * Releases the ITunerDemux instance.
+     */
+    void close();
 }
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerFilter.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerFilter.aidl
index 37166aa..1d5544f 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerFilter.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerFilter.aidl
@@ -16,7 +16,9 @@
 
 package android.media.tv.tuner;
 
+import android.hardware.common.NativeHandle;
 import android.media.tv.tuner.TunerFilterConfiguration;
+import android.media.tv.tuner.TunerFilterSharedHandleInfo;
 
 /**
  * Tuner Filter interface handles tuner related operations.
@@ -40,6 +42,16 @@
     void configure(in TunerFilterConfiguration config);
 
     /**
+     * Get the a/v shared memory handle
+     */
+    TunerFilterSharedHandleInfo getAvSharedHandleInfo();
+
+    /**
+     * Release the handle reported by the HAL for AV memory.
+     */
+    void releaseAvHandle(in NativeHandle handle, in long avDataId);
+
+    /**
      * Start the filter.
      */
     void start();
@@ -53,4 +65,9 @@
      * Flush the filter.
      */
     void flush();
+
+    /**
+     * Close the filter.
+     */
+    void close();
 }
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerFilterCallback.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerFilterCallback.aidl
index f9f86ac..e7a52a7 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerFilterCallback.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerFilterCallback.aidl
@@ -32,5 +32,5 @@
     /**
      * Notify the client that a new filter event happened.
      */
-    void onFilterEvent(out TunerFilterEvent[] filterEvent);
+    void onFilterEvent(in TunerFilterEvent[] filterEvent);
 }
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterSharedHandleInfo.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterSharedHandleInfo.aidl
new file mode 100644
index 0000000..122dfc3
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterSharedHandleInfo.aidl
@@ -0,0 +1,29 @@
+/**
+ * Copyright 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.
+ */
+
+package android.media.tv.tuner;
+
+import android.hardware.common.NativeHandle;
+
+/**
+ * Filter Shared Handle Information.
+ *
+ * {@hide}
+ */
+parcelable TunerFilterSharedHandleInfo {
+    NativeHandle handle;
+    long size;
+}
\ No newline at end of file