Add IDemux getSyncHwId/getAcSyncTime tests in Tuner VTS

Test: atest VtsHalTvTunerV1_0TargetTest
Bug: 150953857
Change-Id: I6e19de3666e9a0edc9db12f002db3ce45c940a2f
diff --git a/tv/tuner/1.0/default/Demux.cpp b/tv/tuner/1.0/default/Demux.cpp
index 4e5ae4b..da56041 100644
--- a/tv/tuner/1.0/default/Demux.cpp
+++ b/tv/tuner/1.0/default/Demux.cpp
@@ -60,13 +60,7 @@
     ALOGV("%s", __FUNCTION__);
 
     uint32_t filterId;
-    if (!mUnusedFilterIds.empty()) {
-        filterId = *mUnusedFilterIds.begin();
-
-        mUnusedFilterIds.erase(filterId);
-    } else {
-        filterId = ++mLastUsedFilterId;
-    }
+    filterId = ++mLastUsedFilterId;
 
     mUsedFilterIds.insert(filterId);
 
@@ -84,6 +78,9 @@
     }
 
     mFilters[filterId] = filter;
+    if (filter->isPcrFilter()) {
+        mPcrFilterIds.insert(filterId);
+    }
     bool result = true;
     if (mDvr != nullptr && mDvr->getType() == DvrType::PLAYBACK) {
         result = mDvr->addPlaybackFilter(filter);
@@ -102,19 +99,53 @@
     return Void();
 }
 
-Return<void> Demux::getAvSyncHwId(const sp<IFilter>& /* filter */, getAvSyncHwId_cb _hidl_cb) {
+Return<void> Demux::getAvSyncHwId(const sp<IFilter>& filter, getAvSyncHwId_cb _hidl_cb) {
     ALOGV("%s", __FUNCTION__);
 
-    AvSyncHwId avSyncHwId = 0;
+    uint32_t avSyncHwId = -1;
+    int id;
+    Result status;
 
-    _hidl_cb(Result::SUCCESS, avSyncHwId);
+    filter->getId([&](Result result, uint32_t filterId) {
+        id = filterId;
+        status = result;
+    });
+
+    if (status != Result::SUCCESS) {
+        ALOGE("[Demux] Can't get filter Id.");
+        _hidl_cb(Result::INVALID_STATE, avSyncHwId);
+        return Void();
+    }
+
+    if (!mFilters[id]->isMediaFilter()) {
+        ALOGE("[Demux] Given filter is not a media filter.");
+        _hidl_cb(Result::INVALID_ARGUMENT, avSyncHwId);
+        return Void();
+    }
+
+    if (!mPcrFilterIds.empty()) {
+        ALOGE("[Demux] No PCR filter opened.");
+        // Return the lowest pcr filter id in the default implementation as the av sync id
+        _hidl_cb(Result::SUCCESS, *mPcrFilterIds.begin());
+        return Void();
+    }
+
+    _hidl_cb(Result::INVALID_STATE, avSyncHwId);
     return Void();
 }
 
-Return<void> Demux::getAvSyncTime(AvSyncHwId /* avSyncHwId */, getAvSyncTime_cb _hidl_cb) {
+Return<void> Demux::getAvSyncTime(AvSyncHwId avSyncHwId, getAvSyncTime_cb _hidl_cb) {
     ALOGV("%s", __FUNCTION__);
 
-    uint64_t avSyncTime = 0;
+    uint64_t avSyncTime = -1;
+    if (mPcrFilterIds.empty()) {
+        _hidl_cb(Result::INVALID_STATE, avSyncTime);
+        return Void();
+    }
+    if (avSyncHwId != *mPcrFilterIds.begin()) {
+        _hidl_cb(Result::INVALID_ARGUMENT, avSyncTime);
+        return Void();
+    }
 
     _hidl_cb(Result::SUCCESS, avSyncTime);
     return Void();
@@ -123,7 +154,6 @@
 Return<Result> Demux::close() {
     ALOGV("%s", __FUNCTION__);
 
-    mUnusedFilterIds.clear();
     mUsedFilterIds.clear();
     mLastUsedFilterId = -1;
 
@@ -171,7 +201,6 @@
     // resetFilterRecords(filterId);
     mUsedFilterIds.erase(filterId);
     mRecordFilterIds.erase(filterId);
-    mUnusedFilterIds.insert(filterId);
     mFilters.erase(filterId);
 
     return Result::SUCCESS;
diff --git a/tv/tuner/1.0/default/Demux.h b/tv/tuner/1.0/default/Demux.h
index 3c91daf..6c46b0d 100644
--- a/tv/tuner/1.0/default/Demux.h
+++ b/tv/tuner/1.0/default/Demux.h
@@ -130,6 +130,7 @@
 
     uint32_t mDemuxId;
     uint32_t mCiCamId;
+    set<uint32_t> mPcrFilterIds;
     /**
      * Record the last used filter id. Initial value is -1.
      * Filter Id starts with 0.
@@ -141,13 +142,6 @@
      */
     set<uint32_t> mUsedFilterIds;
     /**
-     * Record all the unused filter Ids within mLastUsedFilterId.
-     * Removed filter Id should be added into this set.
-     * When this set is not empty, ids here should be allocated first
-     * and added into usedFilterIds.
-     */
-    set<uint32_t> mUnusedFilterIds;
-    /**
      * Record all the attached record filter Ids.
      * Any removed filter id should be removed from this set.
      */
diff --git a/tv/tuner/1.0/default/Filter.cpp b/tv/tuner/1.0/default/Filter.cpp
index fef7a35..8bca70c 100644
--- a/tv/tuner/1.0/default/Filter.cpp
+++ b/tv/tuner/1.0/default/Filter.cpp
@@ -37,6 +37,32 @@
     mBufferSize = bufferSize;
     mCallback = cb;
     mDemux = demux;
+
+    switch (mType.mainType) {
+        case DemuxFilterMainType::TS:
+            if (mType.subType.tsFilterType() == DemuxTsFilterType::AUDIO ||
+                mType.subType.tsFilterType() == DemuxTsFilterType::VIDEO) {
+                mIsMediaFilter = true;
+            }
+            if (mType.subType.tsFilterType() == DemuxTsFilterType::PCR) {
+                mIsPcrFilter = true;
+            }
+            break;
+        case DemuxFilterMainType::MMTP:
+            if (mType.subType.mmtpFilterType() == DemuxMmtpFilterType::AUDIO ||
+                mType.subType.mmtpFilterType() == DemuxMmtpFilterType::VIDEO) {
+                mIsMediaFilter = true;
+            }
+            break;
+        case DemuxFilterMainType::IP:
+            break;
+        case DemuxFilterMainType::TLV:
+            break;
+        case DemuxFilterMainType::ALP:
+            break;
+        default:
+            break;
+    }
 }
 
 Filter::~Filter() {}
@@ -73,16 +99,8 @@
     switch (mType.mainType) {
         case DemuxFilterMainType::TS:
             mTpid = settings.ts().tpid;
-            if (mType.subType.tsFilterType() == DemuxTsFilterType::AUDIO ||
-                mType.subType.tsFilterType() == DemuxTsFilterType::VIDEO) {
-                mIsMediaFilter = true;
-            }
             break;
         case DemuxFilterMainType::MMTP:
-            if (mType.subType.mmtpFilterType() == DemuxMmtpFilterType::AUDIO ||
-                mType.subType.mmtpFilterType() == DemuxMmtpFilterType::VIDEO) {
-                mIsMediaFilter = true;
-            }
             break;
         case DemuxFilterMainType::IP:
             break;
diff --git a/tv/tuner/1.0/default/Filter.h b/tv/tuner/1.0/default/Filter.h
index 9b49ad8..09e9604 100644
--- a/tv/tuner/1.0/default/Filter.h
+++ b/tv/tuner/1.0/default/Filter.h
@@ -89,6 +89,8 @@
     void attachFilterToRecord(const sp<Dvr> dvr);
     void detachFilterFromRecord();
     void freeAvHandle();
+    bool isMediaFilter() { return mIsMediaFilter; };
+    bool isPcrFilter() { return mIsPcrFilter; };
 
   private:
     // Tuner service
@@ -104,6 +106,7 @@
     uint32_t mBufferSize;
     DemuxFilterType mType;
     bool mIsMediaFilter = false;
+    bool mIsPcrFilter = false;
     DemuxFilterSettings mFilterSettings;
 
     uint16_t mTpid;
diff --git a/tv/tuner/1.0/vts/functional/DemuxTests.cpp b/tv/tuner/1.0/vts/functional/DemuxTests.cpp
index b1d8a0a..6c32534 100644
--- a/tv/tuner/1.0/vts/functional/DemuxTests.cpp
+++ b/tv/tuner/1.0/vts/functional/DemuxTests.cpp
@@ -38,4 +38,25 @@
     auto status = mDemux->close();
     mDemux = nullptr;
     return AssertionResult(status.isOk());
+}
+
+void DemuxTests::getAvSyncId(sp<IFilter> filter, uint32_t& avSyncHwId) {
+    ASSERT_TRUE(mDemux) << "Demux is not opened yet.";
+    Result status;
+    mDemux->getAvSyncHwId(filter, [&](Result result, uint32_t id) {
+        status = result;
+        avSyncHwId = id;
+    });
+    ASSERT_TRUE(status == Result::SUCCESS) << "Fail to get avSyncHwId.";
+}
+
+void DemuxTests::getAvSyncTime(uint32_t avSyncId) {
+    ASSERT_TRUE(mDemux) << "Demux is not opened yet.";
+    Result status;
+    uint64_t syncTime;
+    mDemux->getAvSyncTime(avSyncId, [&](Result result, uint64_t time) {
+        status = result;
+        syncTime = time;
+    });
+    ASSERT_TRUE(status == Result::SUCCESS) << "Fail to get avSyncTime.";
 }
\ No newline at end of file
diff --git a/tv/tuner/1.0/vts/functional/DemuxTests.h b/tv/tuner/1.0/vts/functional/DemuxTests.h
index 6e1e395..0443c67 100644
--- a/tv/tuner/1.0/vts/functional/DemuxTests.h
+++ b/tv/tuner/1.0/vts/functional/DemuxTests.h
@@ -31,6 +31,7 @@
 using android::hardware::Return;
 using android::hardware::Void;
 using android::hardware::tv::tuner::V1_0::IDemux;
+using android::hardware::tv::tuner::V1_0::IFilter;
 using android::hardware::tv::tuner::V1_0::ITuner;
 using android::hardware::tv::tuner::V1_0::Result;
 
@@ -42,6 +43,8 @@
 
     AssertionResult openDemux(sp<IDemux>& demux, uint32_t& demuxId);
     AssertionResult setDemuxFrontendDataSource(uint32_t frontendId);
+    void getAvSyncId(sp<IFilter> filter, uint32_t& avSyncHwId);
+    void getAvSyncTime(uint32_t avSyncId);
     AssertionResult closeDemux();
 
   protected:
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index c44f77d..9ac42da 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -263,6 +263,41 @@
     ASSERT_TRUE(mFrontendTests.closeFrontend());
 }
 
+TEST_P(TunerDemuxHidlTest, getAvSyncTime) {
+    description("Get the A/V sync time from a PCR filter.");
+    uint32_t feId;
+    uint32_t demuxId;
+    sp<IDemux> demux;
+    uint32_t mediaFilterId;
+    uint32_t pcrFilterId;
+    uint32_t avSyncHwId;
+    sp<IFilter> mediaFilter;
+
+    mFrontendTests.getFrontendIdByType(frontendArray[DVBT].type, feId);
+    ASSERT_TRUE(feId != INVALID_ID);
+    ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+    ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+    ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+    ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+    mFilterTests.setDemux(demux);
+    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_VIDEO1].type,
+                                               filterArray[TS_VIDEO1].bufferSize));
+    ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(mediaFilterId));
+    ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_VIDEO1].settings, mediaFilterId));
+    mediaFilter = mFilterTests.getFilterById(mediaFilterId);
+    ASSERT_TRUE(mFilterTests.openFilterInDemux(filterArray[TS_PCR0].type,
+                                               filterArray[TS_PCR0].bufferSize));
+    ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId(pcrFilterId));
+    ASSERT_TRUE(mFilterTests.configFilter(filterArray[TS_PCR0].settings, pcrFilterId));
+    mDemuxTests.getAvSyncId(mediaFilter, avSyncHwId);
+    ASSERT_TRUE(pcrFilterId == avSyncHwId);
+    mDemuxTests.getAvSyncTime(pcrFilterId);
+    ASSERT_TRUE(mFilterTests.closeFilter(pcrFilterId));
+    ASSERT_TRUE(mFilterTests.closeFilter(mediaFilterId));
+    ASSERT_TRUE(mDemuxTests.closeDemux());
+    ASSERT_TRUE(mFrontendTests.closeFrontend());
+}
+
 TEST_P(TunerFilterHidlTest, StartFilterInDemux) {
     description("Open and start a filter in Demux.");
     // TODO use paramterized tests
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h
index 21a9855..6dddc38 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.h
@@ -68,6 +68,7 @@
 
         mFrontendTests.setService(mService);
         mDemuxTests.setService(mService);
+        mFilterTests.setService(mService);
     }
 
   protected:
@@ -78,6 +79,7 @@
     sp<ITuner> mService;
     FrontendTests mFrontendTests;
     DemuxTests mDemuxTests;
+    FilterTests mFilterTests;
 };
 
 class TunerFilterHidlTest : public testing::TestWithParam<std::string> {