Add the PTS field for recording-time indexing in the DemuxFilterEvent

Test: atest VtsHalTvTunerV1_1TargetTest
Bug: 158816517
Change-Id: Ib29fd0f55aaae2fb44b77f754cceb5152fc7158d
diff --git a/tv/tuner/1.1/default/Android.bp b/tv/tuner/1.1/default/Android.bp
index 7e45864..4401f7c 100644
--- a/tv/tuner/1.1/default/Android.bp
+++ b/tv/tuner/1.1/default/Android.bp
@@ -4,14 +4,14 @@
     vendor: true,
     relative_install_path: "hw",
     srcs: [
+        "Demux.cpp",
+        "Descrambler.cpp",
+        "Dvr.cpp",
         "Filter.cpp",
         "Frontend.cpp",
-        "Descrambler.cpp",
-        "Demux.cpp",
-        "Dvr.cpp",
+        "Lnb.cpp",
         "TimeFilter.cpp",
         "Tuner.cpp",
-        "Lnb.cpp",
         "service.cpp",
     ],
 
diff --git a/tv/tuner/1.1/default/Demux.cpp b/tv/tuner/1.1/default/Demux.cpp
index f501d74..007d5eb 100644
--- a/tv/tuner/1.1/default/Demux.cpp
+++ b/tv/tuner/1.1/default/Demux.cpp
@@ -312,6 +312,16 @@
     }
 }
 
+void Demux::sendFrontendInputToRecord(vector<uint8_t> data, uint16_t pid, uint64_t pts) {
+    sendFrontendInputToRecord(data);
+    set<uint64_t>::iterator it;
+    for (it = mRecordFilterIds.begin(); it != mRecordFilterIds.end(); it++) {
+        if (pid == mFilters[*it]->getTpid()) {
+            mFilters[*it]->updatePts(pts);
+        }
+    }
+}
+
 bool Demux::startBroadcastFilterDispatcher() {
     set<uint64_t>::iterator it;
 
@@ -389,9 +399,11 @@
                 ALOGE("[Demux] playback es data failed to be filtered. Ending thread");
                 break;
             }
+            continue;
         }
         // Our current implementation filter the data and write it into the filter FMQ immediately
         // after the DATA_READY from the VTS/framework
+        // This is for the non-ES data source, real playback use case handling.
         if (!mDvrPlayback->readPlaybackFMQ(true /*isVirtualFrontend*/, mIsRecording) ||
             !mDvrPlayback->startFilterDispatcher(true /*isVirtualFrontend*/, mIsRecording)) {
             ALOGE("[Demux] playback data failed to be filtered. Ending thread");
diff --git a/tv/tuner/1.1/default/Demux.h b/tv/tuner/1.1/default/Demux.h
index f38f006..3623d0f 100644
--- a/tv/tuner/1.1/default/Demux.h
+++ b/tv/tuner/1.1/default/Demux.h
@@ -100,6 +100,7 @@
     void startBroadcastTsFilter(vector<uint8_t> data);
 
     void sendFrontendInputToRecord(vector<uint8_t> data);
+    void sendFrontendInputToRecord(vector<uint8_t> data, uint16_t pid, uint64_t pts);
     bool startRecordFilterDispatcher();
 
   private:
diff --git a/tv/tuner/1.1/default/Dvr.cpp b/tv/tuner/1.1/default/Dvr.cpp
index 02d6a42..bf4c77e 100644
--- a/tv/tuner/1.1/default/Dvr.cpp
+++ b/tv/tuner/1.1/default/Dvr.cpp
@@ -217,9 +217,11 @@
                 break;
             }
             maySendPlaybackStatusCallback();
+            continue;
         }
         // Our current implementation filter the data and write it into the filter FMQ immediately
         // after the DATA_READY from the VTS/framework
+        // This is for the non-ES data source, real playback use case handling.
         if (!readPlaybackFMQ(false /*isVirtualFrontend*/, false /*isRecording*/) ||
             !startFilterDispatcher(false /*isVirtualFrontend*/, false /*isRecording*/)) {
             ALOGE("[Dvr] playback data failed to be filtered. Ending thread");
@@ -380,20 +382,19 @@
     for (int i = 0; i < totalFrames; i++) {
         frameData.resize(esMeta[i].len);
         pid = esMeta[i].isAudio ? audioPid : videoPid;
-        memcpy(dataOutputBuffer.data() + esMeta[i].startIndex, frameData.data(), esMeta[i].len);
-        // Send to the media filter
-        if (isVirtualFrontend && isRecording) {
-            // TODO validate record
-            mDemux->sendFrontendInputToRecord(frameData);
-        } else {
+        memcpy(frameData.data(), dataOutputBuffer.data() + esMeta[i].startIndex, esMeta[i].len);
+        // Send to the media filters or record filters
+        if (!isRecording) {
             for (it = mFilters.begin(); it != mFilters.end(); it++) {
                 if (pid == mDemux->getFilterTpid(it->first)) {
                     mDemux->updateMediaFilterOutput(it->first, frameData,
                                                     static_cast<uint64_t>(esMeta[i].pts));
-                    startFilterDispatcher(isVirtualFrontend, isRecording);
                 }
             }
+        } else {
+            mDemux->sendFrontendInputToRecord(frameData, pid, static_cast<uint64_t>(esMeta[i].pts));
         }
+        startFilterDispatcher(isVirtualFrontend, isRecording);
     }
 
     return true;
diff --git a/tv/tuner/1.1/default/Filter.cpp b/tv/tuner/1.1/default/Filter.cpp
index 108baf7..2d6214d 100644
--- a/tv/tuner/1.1/default/Filter.cpp
+++ b/tv/tuner/1.1/default/Filter.cpp
@@ -35,7 +35,6 @@
     mType = type;
     mFilterId = filterId;
     mBufferSize = bufferSize;
-    mCallback = cb;
     mDemux = demux;
 
     switch (mType.mainType) {
@@ -69,6 +68,13 @@
         default:
             break;
     }
+
+    sp<V1_1::IFilterCallback> filterCallback_v1_1 = V1_1::IFilterCallback::castFrom(cb);
+    if (filterCallback_v1_1 != NULL) {
+        mCallback_1_1 = filterCallback_v1_1;
+    } else {
+        mCallback = cb;
+    }
 }
 
 Filter::~Filter() {}
@@ -99,7 +105,7 @@
 Return<void> Filter::getQueueDesc(getQueueDesc_cb _hidl_cb) {
     ALOGV("%s", __FUNCTION__);
 
-    mIsUsingFMQ = true;
+    mIsUsingFMQ = mIsRecordFilter ? false : true;
 
     _hidl_cb(Result::SUCCESS, *mFilterMQ->getDesc());
     return Void();
@@ -214,7 +220,7 @@
     // For the first time of filter output, implementation needs to send the filter
     // Event Callback without waiting for the DATA_CONSUMED to init the process.
     while (mFilterThreadRunning) {
-        if (mFilterEvent.events.size() == 0) {
+        if (mFilterEvent.events.size() == 0 && mFilterEvent_1_1.events.size() == 0) {
             if (DEBUG_FILTER) {
                 ALOGD("[Filter] wait for filter data output.");
             }
@@ -222,15 +228,26 @@
             continue;
         }
         // After successfully write, send a callback and wait for the read to be done
-        mCallback->onFilterEvent(mFilterEvent);
-        freeAvHandle();
-        mFilterEvent.events.resize(0);
-        mFilterStatus = DemuxFilterStatus::DATA_READY;
-        if (mCallback == nullptr) {
-            ALOGD("[Filter] filter %" PRIu64 " does not hava callback. Ending thread", mFilterId);
-            break;
+        if (mFilterEvent_1_1.events.size() > 0) {
+            if (mCallback_1_1 == nullptr) {
+                ALOGE("[Filter] IFilterCallback_1_1 has not been configured yet. Can't send event");
+                mFilterThreadRunning = false;
+                break;
+            }
+            mCallback_1_1->onFilterEvent_1_1(mFilterEvent_1_1);
+            mFilterEvent_1_1.events.resize(0);
+        } else {
+            mCallback->onFilterEvent(mFilterEvent);
+            mFilterEvent.events.resize(0);
         }
-        mCallback->onFilterStatus(mFilterStatus);
+
+        freeAvHandle();
+        mFilterStatus = DemuxFilterStatus::DATA_READY;
+        if (mCallback != nullptr) {
+            mCallback->onFilterStatus(mFilterStatus);
+        } else if (mCallback_1_1 != nullptr) {
+            mCallback_1_1->onFilterStatus(mFilterStatus);
+        }
         break;
     }
 
@@ -258,8 +275,13 @@
                     continue;
                 }
                 // After successfully write, send a callback and wait for the read to be done
-                mCallback->onFilterEvent(mFilterEvent);
-                mFilterEvent.events.resize(0);
+                if (mCallback != nullptr) {
+                    mCallback->onFilterEvent(mFilterEvent);
+                    mFilterEvent.events.resize(0);
+                } else if (mCallback_1_1 != nullptr) {
+                    mCallback_1_1->onFilterEvent_1_1(mFilterEvent_1_1);
+                    mFilterEvent_1_1.events.resize(0);
+                }
                 break;
             }
             // We do not wait for the last read to be done
@@ -297,7 +319,11 @@
     DemuxFilterStatus newStatus = checkFilterStatusChange(
             availableToWrite, availableToRead, ceil(fmqSize * 0.75), ceil(fmqSize * 0.25));
     if (mFilterStatus != newStatus) {
-        mCallback->onFilterStatus(newStatus);
+        if (mCallback != nullptr) {
+            mCallback->onFilterStatus(newStatus);
+        } else if (mCallback_1_1 != nullptr) {
+            mCallback_1_1->onFilterStatus(newStatus);
+        }
         mFilterStatus = newStatus;
     }
 }
@@ -577,6 +603,27 @@
         return Result::UNKNOWN_ERROR;
     }
 
+    V1_0::DemuxFilterTsRecordEvent recordEvent;
+    recordEvent = {
+            .byteNumber = mRecordFilterOutput.size(),
+    };
+    V1_1::DemuxFilterTsRecordEvent recordEvent_1_1;
+    recordEvent_1_1 = {
+            .tsRecordEvent_1_0 = recordEvent,
+            .pts = (mPts == 0) ? time(NULL) * 900000 : mPts,
+    };
+
+    int size;
+    if (mCallback_1_1 != nullptr) {
+        size = mFilterEvent_1_1.events.size();
+        mFilterEvent_1_1.events.resize(size + 1);
+        mFilterEvent_1_1.events[size].tsRecord(recordEvent_1_1);
+    } else if (mCallback != nullptr) {
+        size = mFilterEvent.events.size();
+        mFilterEvent.events.resize(size + 1);
+        mFilterEvent.events[size].tsRecord(recordEvent);
+    }
+
     mRecordFilterOutput.clear();
     return Result::SUCCESS;
 }
diff --git a/tv/tuner/1.1/default/Filter.h b/tv/tuner/1.1/default/Filter.h
index d5801d4..8e6fe38 100644
--- a/tv/tuner/1.1/default/Filter.h
+++ b/tv/tuner/1.1/default/Filter.h
@@ -18,6 +18,7 @@
 #define ANDROID_HARDWARE_TV_TUNER_V1_1_FILTER_H_
 
 #include <android/hardware/tv/tuner/1.1/IFilter.h>
+#include <android/hardware/tv/tuner/1.1/IFilterCallback.h>
 #include <fmq/MessageQueue.h>
 #include <inttypes.h>
 #include <ion/ion.h>
@@ -102,7 +103,12 @@
     /**
      * Filter callbacks used on filter events or FMQ status
      */
-    sp<IFilterCallback> mCallback;
+    sp<IFilterCallback> mCallback = nullptr;
+
+    /**
+     * V1_1 Filter callbacks used on filter events or FMQ status
+     */
+    sp<V1_1::IFilterCallback> mCallback_1_1 = nullptr;
 
     uint64_t mFilterId;
     uint32_t mBufferSize;
@@ -122,6 +128,7 @@
     bool mIsUsingFMQ = false;
     EventFlag* mFilterEventFlag;
     DemuxFilterEvent mFilterEvent;
+    V1_1::DemuxFilterEvent mFilterEvent_1_1;
 
     // Thread handlers
     pthread_t mFilterThread;
diff --git a/tv/tuner/1.1/default/Tuner.cpp b/tv/tuner/1.1/default/Tuner.cpp
index 0a0667e..87a4d36 100644
--- a/tv/tuner/1.1/default/Tuner.cpp
+++ b/tv/tuner/1.1/default/Tuner.cpp
@@ -233,11 +233,10 @@
 
 void Tuner::removeDemux(uint32_t demuxId) {
     map<uint32_t, uint32_t>::iterator it;
-    for (it = mFrontendToDemux.begin(); it != mFrontendToDemux.end();) {
+    for (it = mFrontendToDemux.begin(); it != mFrontendToDemux.end(); it++) {
         if (it->second == demuxId) {
             it = mFrontendToDemux.erase(it);
-        } else {
-            it++;
+            break;
         }
     }
     mDemuxes.erase(demuxId);
diff --git a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc
index 9e228f7..abff430 100644
--- a/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc
+++ b/tv/tuner/1.1/default/android.hardware.tv.tuner@1.1-service-lazy.rc
@@ -1,4 +1,5 @@
 service vendor.tuner-hal-1-1 /vendor/bin/hw/android.hardware.tv.tuner@1.1-service-lazy
+    interface android.hardware.tv.tuner@1.0::ITuner default
     interface android.hardware.tv.tuner@1.1::ITuner default
     oneshot
     disabled