Add new features to tuner service.

*) Add AAC formats backward compatibility.
*) Support dumping frontend hardware information.
*) Add DemuxFilterMediaEvent ScIndexMask backward compatibility.
*) Move setLna to TunerService and add Hidl backward compatibility.

Bug: 205265630
Bug: 184017033
Bug: 202978951
Bug: 203623028
Test: atest android.media.tv.tuner.cts on AIDL and HIDL HALs
Change-Id: I491da4e21649b61b25734fc1f9bf64bb77f52a87
diff --git a/services/tuner/TunerFrontend.cpp b/services/tuner/TunerFrontend.cpp
index e86e8e1..a5ef2bb 100644
--- a/services/tuner/TunerFrontend.cpp
+++ b/services/tuner/TunerFrontend.cpp
@@ -115,16 +115,6 @@
     return mFrontend->setLnb(static_cast<TunerLnb*>(lnb.get())->getId());
 }
 
-::ndk::ScopedAStatus TunerFrontend::setLna(bool bEnable) {
-    if (mFrontend == nullptr) {
-        ALOGD("IFrontend is not initialized");
-        return ::ndk::ScopedAStatus::fromServiceSpecificError(
-                static_cast<int32_t>(Result::UNAVAILABLE));
-    }
-
-    return mFrontend->setLna(bEnable);
-}
-
 ::ndk::ScopedAStatus TunerFrontend::linkCiCamToFrontend(int32_t ciCamId, int32_t* _aidl_return) {
     if (mFrontend == nullptr) {
         ALOGD("IFrontend is not initialized");
@@ -174,6 +164,16 @@
     return ::ndk::ScopedAStatus::ok();
 }
 
+::ndk::ScopedAStatus TunerFrontend::getHardwareInfo(std::string* _aidl_return) {
+    if (mFrontend == nullptr) {
+        ALOGD("IFrontend is not initialized");
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    return mFrontend->getHardwareInfo(_aidl_return);
+}
+
 /////////////// FrontendCallback ///////////////////////
 ::ndk::ScopedAStatus TunerFrontend::FrontendCallback::onEvent(FrontendEventType frontendEventType) {
     ALOGV("FrontendCallback::onEvent, type=%d", frontendEventType);
diff --git a/services/tuner/TunerFrontend.h b/services/tuner/TunerFrontend.h
index 417d969..418a751 100644
--- a/services/tuner/TunerFrontend.h
+++ b/services/tuner/TunerFrontend.h
@@ -56,13 +56,13 @@
                               FrontendScanType in_frontendScanType) override;
     ::ndk::ScopedAStatus stopScan() override;
     ::ndk::ScopedAStatus setLnb(const shared_ptr<ITunerLnb>& in_lnb) override;
-    ::ndk::ScopedAStatus setLna(bool in_bEnable) override;
     ::ndk::ScopedAStatus linkCiCamToFrontend(int32_t in_ciCamId, int32_t* _aidl_return) override;
     ::ndk::ScopedAStatus unlinkCiCamToFrontend(int32_t in_ciCamId) override;
     ::ndk::ScopedAStatus close() override;
     ::ndk::ScopedAStatus getStatus(const vector<FrontendStatusType>& in_statusTypes,
                                    vector<FrontendStatus>* _aidl_return) override;
     ::ndk::ScopedAStatus getFrontendId(int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus getHardwareInfo(std::string* _aidl_return) override;
 
     struct FrontendCallback : public BnFrontendCallback {
         FrontendCallback(const shared_ptr<ITunerFrontendCallback> tunerFrontendCallback)
diff --git a/services/tuner/TunerService.cpp b/services/tuner/TunerService.cpp
index 36e4cd1..335578d 100644
--- a/services/tuner/TunerService.cpp
+++ b/services/tuner/TunerService.cpp
@@ -260,6 +260,16 @@
     return ::ndk::ScopedAStatus::ok();
 }
 
+::ndk::ScopedAStatus TunerService::setLna(bool bEnable) {
+    if (!hasITuner()) {
+        ALOGD("get ITuner failed");
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    return mTuner->setLna(bEnable);
+}
+
 string TunerService::addFilterToShared(const shared_ptr<TunerFilter>& sharedFilter) {
     Mutex::Autolock _l(mSharedFiltersLock);
 
diff --git a/services/tuner/TunerService.h b/services/tuner/TunerService.h
index 7bf50b6..f144744 100644
--- a/services/tuner/TunerService.h
+++ b/services/tuner/TunerService.h
@@ -76,6 +76,7 @@
     ::ndk::ScopedAStatus openSharedFilter(const string& in_filterToken,
                                           const shared_ptr<ITunerFilterCallback>& in_cb,
                                           shared_ptr<ITunerFilter>* _aidl_return) override;
+    ::ndk::ScopedAStatus setLna(bool in_bEnable) override;
 
     string addFilterToShared(const shared_ptr<TunerFilter>& sharedFilter);
     void removeSharedFilter(const shared_ptr<TunerFilter>& sharedFilter);
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerFrontend.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerFrontend.aidl
index 771a647..96f285f 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerFrontend.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerFrontend.aidl
@@ -69,13 +69,6 @@
     void setLnb(in ITunerLnb lnb);
 
     /**
-     * Enable or Disable Low Noise Amplifier (LNA).
-     *
-     * @param bEnable enable Lna or not.
-     */
-    void setLna(in boolean bEnable);
-
-    /**
      * Link Frontend to the cicam with given id.
      *
      * @return lts id
@@ -101,4 +94,9 @@
      * Gets the id of the frontend.
      */
     int getFrontendId();
+
+    /**
+     * Request hardware information about the frontend.
+     */
+    String getHardwareInfo();
 }
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
index e6a1a5c..248077b 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
@@ -104,4 +104,11 @@
      * @return a newly created ITunerFilter interface.
      */
     ITunerFilter openSharedFilter(in String filterToken, in ITunerFilterCallback cb);
+
+    /**
+     * Enable or Disable Low Noise Amplifier (LNA).
+     *
+     * @param bEnable enable Lna or not.
+     */
+    void setLna(in boolean bEnable);
 }
diff --git a/services/tuner/hidl/TunerHidlFilter.cpp b/services/tuner/hidl/TunerHidlFilter.cpp
index b738b57..a5bbf39 100644
--- a/services/tuner/hidl/TunerHidlFilter.cpp
+++ b/services/tuner/hidl/TunerHidlFilter.cpp
@@ -29,6 +29,7 @@
 #include "TunerHidlService.h"
 
 using ::aidl::android::hardware::tv::tuner::AudioExtraMetaData;
+using ::aidl::android::hardware::tv::tuner::AudioStreamType;
 using ::aidl::android::hardware::tv::tuner::Constant;
 using ::aidl::android::hardware::tv::tuner::DemuxAlpFilterSettings;
 using ::aidl::android::hardware::tv::tuner::DemuxAlpFilterSettingsFilterSettings;
@@ -604,7 +605,11 @@
 
 bool TunerHidlFilter::getHidlAvStreamType(const AvStreamType avStreamType, HidlAvStreamType& type) {
     if (isAudioFilter()) {
-        type.audio(static_cast<HidlAudioStreamType>(avStreamType.get<AvStreamType::audio>()));
+        AudioStreamType audio = avStreamType.get<AvStreamType::audio>();
+        if (static_cast<int32_t>(audio) > static_cast<int32_t>(HidlAudioStreamType::DRA)) {
+            return false;
+        }
+        type.audio(static_cast<HidlAudioStreamType>(audio));
         return true;
     }
 
@@ -1044,6 +1049,8 @@
         media.avDataId = static_cast<int64_t>(mediaEvent.avDataId);
         media.mpuSequenceNumber = static_cast<int32_t>(mediaEvent.mpuSequenceNumber);
         media.isPesPrivateData = mediaEvent.isPesPrivateData;
+        media.scIndexMask.set<DemuxFilterScIndexMask::scIndex>(
+                static_cast<int32_t>(DemuxScIndex::UNDEFINED));
 
         if (mediaEvent.extraMetaData.getDiscriminator() ==
             HidlDemuxFilterMediaEvent::ExtraMetaData::hidl_discriminator::audio) {
diff --git a/services/tuner/hidl/TunerHidlFrontend.cpp b/services/tuner/hidl/TunerHidlFrontend.cpp
index 1f28406..057f24a 100644
--- a/services/tuner/hidl/TunerHidlFrontend.cpp
+++ b/services/tuner/hidl/TunerHidlFrontend.cpp
@@ -22,6 +22,7 @@
 #include <aidl/android/hardware/tv/tuner/Result.h>
 
 #include "TunerHidlLnb.h"
+#include "TunerHidlService.h"
 
 using ::aidl::android::hardware::tv::tuner::FrontendAnalogSettings;
 using ::aidl::android::hardware::tv::tuner::FrontendAnalogSifStandard;
@@ -309,21 +310,6 @@
     return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
 }
 
-::ndk::ScopedAStatus TunerHidlFrontend::setLna(bool bEnable) {
-    if (mFrontend == nullptr) {
-        ALOGD("IFrontend is not initialized");
-        return ::ndk::ScopedAStatus::fromServiceSpecificError(
-                static_cast<int32_t>(Result::UNAVAILABLE));
-    }
-
-    HidlResult status = mFrontend->setLna(bEnable);
-    if (status == HidlResult::SUCCESS) {
-        return ::ndk::ScopedAStatus::ok();
-    }
-
-    return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
-}
-
 ::ndk::ScopedAStatus TunerHidlFrontend::linkCiCamToFrontend(int32_t ciCamId,
                                                             int32_t* _aidl_return) {
     if (mFrontend_1_1 == nullptr) {
@@ -369,6 +355,8 @@
                 static_cast<int32_t>(Result::UNAVAILABLE));
     }
 
+    TunerHidlService::getTunerService()->removeFrontend(this->ref<TunerHidlFrontend>());
+
     HidlResult status = mFrontend->close();
     mFrontend = nullptr;
     mFrontend_1_1 = nullptr;
@@ -434,6 +422,21 @@
     return ::ndk::ScopedAStatus::ok();
 }
 
+::ndk::ScopedAStatus TunerHidlFrontend::getHardwareInfo(std::string* _aidl_return) {
+    _aidl_return->clear();
+    return ::ndk::ScopedAStatus::fromServiceSpecificError(
+            static_cast<int32_t>(Result::UNAVAILABLE));
+}
+
+void TunerHidlFrontend::setLna(bool bEnable) {
+    if (mFrontend == nullptr) {
+        ALOGD("IFrontend is not initialized");
+        return;
+    }
+
+    mFrontend->setLna(bEnable);
+}
+
 /////////////// FrontendCallback ///////////////////////
 Return<void> TunerHidlFrontend::FrontendCallback::onEvent(HidlFrontendEventType frontendEventType) {
     ALOGV("FrontendCallback::onEvent, type=%d", frontendEventType);
diff --git a/services/tuner/hidl/TunerHidlFrontend.h b/services/tuner/hidl/TunerHidlFrontend.h
index 6a3a04a..7ff278c 100644
--- a/services/tuner/hidl/TunerHidlFrontend.h
+++ b/services/tuner/hidl/TunerHidlFrontend.h
@@ -76,13 +76,15 @@
                               FrontendScanType in_frontendScanType) override;
     ::ndk::ScopedAStatus stopScan() override;
     ::ndk::ScopedAStatus setLnb(const shared_ptr<ITunerLnb>& in_lnb) override;
-    ::ndk::ScopedAStatus setLna(bool in_bEnable) override;
     ::ndk::ScopedAStatus linkCiCamToFrontend(int32_t in_ciCamId, int32_t* _aidl_return) override;
     ::ndk::ScopedAStatus unlinkCiCamToFrontend(int32_t in_ciCamId) override;
     ::ndk::ScopedAStatus close() override;
     ::ndk::ScopedAStatus getStatus(const vector<FrontendStatusType>& in_statusTypes,
                                    vector<FrontendStatus>* _aidl_return) override;
     ::ndk::ScopedAStatus getFrontendId(int32_t* _aidl_return) override;
+    ::ndk::ScopedAStatus getHardwareInfo(std::string* _aidl_return) override;
+
+    void setLna(bool in_bEnable);
 
     struct FrontendCallback : public HidlIFrontendCallback {
         FrontendCallback(const shared_ptr<ITunerFrontendCallback> tunerFrontendCallback)
diff --git a/services/tuner/hidl/TunerHidlService.cpp b/services/tuner/hidl/TunerHidlService.cpp
index f4b0cde..f4aa61a 100644
--- a/services/tuner/hidl/TunerHidlService.cpp
+++ b/services/tuner/hidl/TunerHidlService.cpp
@@ -74,7 +74,10 @@
     updateTunerResources();
 }
 
-TunerHidlService::~TunerHidlService() {}
+TunerHidlService::~TunerHidlService() {
+    mOpenedFrontends.clear();
+    mLnaStatus = -1;
+}
 
 binder_status_t TunerHidlService::instantiate() {
     if (HidlITuner::getService() == nullptr) {
@@ -237,7 +240,17 @@
     if (status != HidlResult::SUCCESS) {
         return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(status));
     }
-    *_aidl_return = ::ndk::SharedRefBase::make<TunerHidlFrontend>(frontend, id);
+
+    shared_ptr<TunerHidlFrontend> tunerFrontend =
+            ::ndk::SharedRefBase::make<TunerHidlFrontend>(frontend, id);
+    if (mLnaStatus != -1) {
+        tunerFrontend->setLna(mLnaStatus == 1);
+    }
+    {
+        Mutex::Autolock _l(mOpenedFrontendsLock);
+        mOpenedFrontends.insert(tunerFrontend);
+    }
+    *_aidl_return = tunerFrontend;
     return ::ndk::ScopedAStatus::ok();
 }
 
@@ -355,6 +368,25 @@
     return ::ndk::ScopedAStatus::ok();
 }
 
+::ndk::ScopedAStatus TunerHidlService::setLna(bool bEnable) {
+    if (!hasITuner()) {
+        ALOGE("get ITuner failed");
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    mLnaStatus = bEnable ? 1 : 0;
+
+    {
+        Mutex::Autolock _l(mOpenedFrontendsLock);
+        for (auto it = mOpenedFrontends.begin(); it != mOpenedFrontends.end(); ++it) {
+            (*it)->setLna(mLnaStatus == 1);
+        }
+    }
+
+    return ::ndk::ScopedAStatus::ok();
+}
+
 string TunerHidlService::addFilterToShared(const shared_ptr<TunerHidlFilter>& sharedFilter) {
     Mutex::Autolock _l(mSharedFiltersLock);
 
@@ -372,6 +404,16 @@
     mSharedFilters.erase(to_string(reinterpret_cast<std::uintptr_t>(sharedFilter.get())));
 }
 
+void TunerHidlService::removeFrontend(const shared_ptr<TunerHidlFrontend>& frontend) {
+    Mutex::Autolock _l(mOpenedFrontendsLock);
+    for (auto it = mOpenedFrontends.begin(); it != mOpenedFrontends.end(); ++it) {
+        if (it->get() == frontend.get()) {
+            mOpenedFrontends.erase(it);
+            break;
+        }
+    }
+}
+
 void TunerHidlService::updateTunerResources() {
     if (!hasITuner()) {
         ALOGE("Failed to updateTunerResources");
diff --git a/services/tuner/hidl/TunerHidlService.h b/services/tuner/hidl/TunerHidlService.h
index 2b8750e..4cff7cf 100644
--- a/services/tuner/hidl/TunerHidlService.h
+++ b/services/tuner/hidl/TunerHidlService.h
@@ -24,8 +24,11 @@
 #include <android/hardware/tv/tuner/1.1/ITuner.h>
 #include <utils/Mutex.h>
 
+#include <unordered_set>
+
 #include "TunerHelper.h"
 #include "TunerHidlFilter.h"
+#include "TunerHidlFrontend.h"
 
 using ::aidl::android::hardware::tv::tuner::DemuxCapabilities;
 using ::aidl::android::hardware::tv::tuner::DemuxFilterEvent;
@@ -85,9 +88,11 @@
     ::ndk::ScopedAStatus openSharedFilter(const string& in_filterToken,
                                           const shared_ptr<ITunerFilterCallback>& in_cb,
                                           shared_ptr<ITunerFilter>* _aidl_return) override;
+    ::ndk::ScopedAStatus setLna(bool in_bEnable) override;
 
     string addFilterToShared(const shared_ptr<TunerHidlFilter>& sharedFilter);
     void removeSharedFilter(const shared_ptr<TunerHidlFilter>& sharedFilter);
+    void removeFrontend(const shared_ptr<TunerHidlFrontend>& frontend);
 
     static shared_ptr<TunerHidlService> getTunerService();
 
@@ -108,6 +113,9 @@
     int mTunerVersion = TUNER_HAL_VERSION_UNKNOWN;
     Mutex mSharedFiltersLock;
     map<string, shared_ptr<TunerHidlFilter>> mSharedFilters;
+    Mutex mOpenedFrontendsLock;
+    unordered_set<shared_ptr<TunerHidlFrontend>> mOpenedFrontends;
+    int mLnaStatus = -1;
 
     static shared_ptr<TunerHidlService> sTunerService;
 };