Add TEMI filter, releasing AV handle and CI-CAM

Test: Manual
bug: 135708935
Change-Id: I21701185feb274dc1e8b3cff3db59b9d3f73edf1
diff --git a/tv/tuner/1.0/IDemux.hal b/tv/tuner/1.0/IDemux.hal
index 9e799b4..16fc392 100644
--- a/tv/tuner/1.0/IDemux.hal
+++ b/tv/tuner/1.0/IDemux.hal
@@ -25,7 +25,6 @@
 /**
  * Demultiplexer(Demux) takes a single multiplexed input and splits it into
  * one or more output.
- *
  */
 interface IDemux {
     /**
@@ -134,4 +133,30 @@
      */
     openDvr(DvrType type, uint32_t bufferSize, IDvrCallback cb)
         generates (Result result, IDvr dvr);
+
+    /**
+     * Connect Conditional Access Modules (CAM) through Common Interface (CI)
+     *
+     * It is used by the client to connect CI-CAM. The demux uses the output
+     * from the frontend as the input by default, and must change to use the
+     * output from CI-CAM as the input after this call take place.
+     *
+     * @param ciCamId specify CI-CAM Id to connect.
+     * @return result Result status of the operation.
+     *         SUCCESS if successful,
+     *         UNKNOWN_ERROR if failed for other reasons.
+     */
+    connectCiCam(uint32_t ciCamId) generates (Result result);
+
+    /**
+     * Disconnect Conditional Access Modules (CAM)
+     *
+     * It is used by the client to disconnect CI-CAM. The demux will use the
+     * output from the frontend as the input after this call take place.
+     *
+     * @return result Result status of the operation.
+     *         SUCCESS if successful,
+     *         UNKNOWN_ERROR if failed for other reasons.
+     */
+    disconnectCiCam() generates (Result result);
 };
diff --git a/tv/tuner/1.0/IFilter.hal b/tv/tuner/1.0/IFilter.hal
index deaf3d4..3ed09f6 100644
--- a/tv/tuner/1.0/IFilter.hal
+++ b/tv/tuner/1.0/IFilter.hal
@@ -113,6 +113,21 @@
     getId() generates (Result result, uint32_t filterId);
 
     /**
+     * Release the handle reported by the HAL for AV memory.
+     *
+     * It is used by the client to notify the HAL that the AV handle won't be
+     * used any more in client side, so that the HAL can mark the memory
+     * presented by file descripor in the handle as released.
+     *
+     * @param avMemory A handle associated to the memory for audio or video.
+     * @return result Result status of the operation.
+     *         SUCCESS if successful,
+     *         INVALID_ARGUMENT if failed for wrong parameter.
+     *         UNKNOWN_ERROR if failed for other reasons.
+     */
+    releaseAvHandle(handle avMemory) generates (Result result);
+
+    /**
      * Set the filter's data source.
      *
      * A filter uses demux as data source by default. If the data was packetized
diff --git a/tv/tuner/1.0/default/Demux.cpp b/tv/tuner/1.0/default/Demux.cpp
index c5921f7..71a26ab 100644
--- a/tv/tuner/1.0/default/Demux.cpp
+++ b/tv/tuner/1.0/default/Demux.cpp
@@ -147,6 +147,20 @@
     return Void();
 }
 
+Return<Result> Demux::connectCiCam(uint32_t ciCamId) {
+    ALOGV("%s", __FUNCTION__);
+
+    mCiCamId = ciCamId;
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Demux::disconnectCiCam() {
+    ALOGV("%s", __FUNCTION__);
+
+    return Result::SUCCESS;
+}
+
 Result Demux::removeFilter(uint32_t filterId) {
     ALOGV("%s", __FUNCTION__);
 
diff --git a/tv/tuner/1.0/default/Demux.h b/tv/tuner/1.0/default/Demux.h
index a9756cc..037429d 100644
--- a/tv/tuner/1.0/default/Demux.h
+++ b/tv/tuner/1.0/default/Demux.h
@@ -76,6 +76,10 @@
     virtual Return<void> openDvr(DvrType type, uint32_t bufferSize, const sp<IDvrCallback>& cb,
                                  openDvr_cb _hidl_cb) override;
 
+    virtual Return<Result> connectCiCam(uint32_t ciCamId) override;
+
+    virtual Return<Result> disconnectCiCam() override;
+
     // Functions interacts with Tuner Service
     void stopBroadcastInput();
     Result removeFilter(uint32_t filterId);
@@ -118,6 +122,7 @@
     void startTsFilter(vector<uint8_t> data);
 
     uint32_t mDemuxId;
+    uint32_t mCiCamId;
     /**
      * Record the last used filter id. Initial value is -1.
      * Filter Id starts with 0.
diff --git a/tv/tuner/1.0/default/Filter.cpp b/tv/tuner/1.0/default/Filter.cpp
index 3d8a977..befd1e6 100644
--- a/tv/tuner/1.0/default/Filter.cpp
+++ b/tv/tuner/1.0/default/Filter.cpp
@@ -120,6 +120,12 @@
     return Result::SUCCESS;
 }
 
+Return<Result> Filter::releaseAvHandle(const hidl_handle& /*avMemory*/) {
+    ALOGV("%s", __FUNCTION__);
+
+    return Result::SUCCESS;
+}
+
 Return<Result> Filter::close() {
     ALOGV("%s", __FUNCTION__);
 
@@ -289,6 +295,9 @@
                 case DemuxTsFilterType::RECORD:
                     startRecordFilterHandler();
                     break;
+                case DemuxTsFilterType::TEMI:
+                    startTemiFilterHandler();
+                    break;
             }
             break;
         case DemuxFilterMainType::MMTP:
@@ -419,6 +428,11 @@
     return Result::SUCCESS;
 }
 
+Result Filter::startTemiFilterHandler() {
+    // TODO handle starting TEMI filter
+    return Result::SUCCESS;
+}
+
 bool Filter::writeSectionsAndCreateEvent(vector<uint8_t> data) {
     // TODO check how many sections has been read
     ALOGD("[Filter] section hander");
@@ -453,4 +467,4 @@
 }  // namespace tuner
 }  // namespace tv
 }  // namespace hardware
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/tv/tuner/1.0/default/Filter.h b/tv/tuner/1.0/default/Filter.h
index 21d4297..fbd965a 100644
--- a/tv/tuner/1.0/default/Filter.h
+++ b/tv/tuner/1.0/default/Filter.h
@@ -68,6 +68,8 @@
 
     virtual Return<Result> flush() override;
 
+    virtual Return<Result> releaseAvHandle(const hidl_handle& avMemory) override;
+
     virtual Return<Result> close() override;
 
     /**
@@ -129,6 +131,7 @@
     Result startMediaFilterHandler();
     Result startRecordFilterHandler();
     Result startPcrFilterHandler();
+    Result startTemiFilterHandler();
     Result startFilterLoop();
 
     void deleteEventFlag();
@@ -176,4 +179,4 @@
 }  // namespace hardware
 }  // namespace android
 
-#endif  // ANDROID_HARDWARE_TV_TUNER_V1_0_FILTER_H_
\ No newline at end of file
+#endif  // ANDROID_HARDWARE_TV_TUNER_V1_0_FILTER_H_
diff --git a/tv/tuner/1.0/types.hal b/tv/tuner/1.0/types.hal
index fa00a6e..707f5df 100644
--- a/tv/tuner/1.0/types.hal
+++ b/tv/tuner/1.0/types.hal
@@ -1759,6 +1759,12 @@
      * buffer of the record.
      */
     RECORD,
+    /**
+     * A filter to filter out Timed External Media Information (TEMI) according
+     * to ISO/IEC 13818-1:2013/ DAM 6 from input stream, and send TEMI event to
+     * client through onFilterEvent.
+     */
+    TEMI,
 };
 
 /**
@@ -2170,7 +2176,8 @@
 
     safe_union FilterSettings {
         /**
-         * Not additional parameters. it's used by PCR, TS subtype filters.
+         * Not additional parameters. it's used by PCR, TS, TEMI subtype
+         * filters.
          */
         Monostate noinit;
 
@@ -2461,6 +2468,27 @@
 };
 
 /**
+ *  Filter Event for Timed External Media Information (TEMI) data.
+ */
+struct DemuxFilterTemiEvent {
+    /**
+     * Presentation Time Stamp for audio or video frame. It based on 90KHz has
+     * the same format as PTS (Presentation Time Stamp) in ISO/IEC 13818-1.
+     */
+    uint64_t pts;
+
+    /**
+     * TEMI Descriptor Tag
+     */
+    uint8_t descrTag;
+
+    /**
+     * TEMI Descriptor
+     */
+    vec<uint8_t> descrData;
+};
+
+/**
  *  Filter Event for MMTP Record data.
  */
 struct DemuxFilterMmtpRecordEvent {
@@ -2521,6 +2549,8 @@
         DemuxFilterDownloadEvent download;
 
         DemuxFilterIpPayloadEvent ipPayload;
+
+        DemuxFilterTemiEvent temi;
     };
 
     /**
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index c666226..da3e300 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -159,6 +159,7 @@
     RECORD,
     MMTPRECORD,
     DOWNLOAD,
+    TEMI,
 };
 
 struct PlaybackConf {
@@ -821,6 +822,9 @@
                 case DemuxTsFilterType::RECORD:
                     eventType = FilterEventType::RECORD;
                     break;
+                case DemuxTsFilterType::TEMI:
+                    eventType = FilterEventType::TEMI;
+                    break;
             }
             break;
         case DemuxFilterMainType::MMTP: