Impement filter settings, configuration and callback

Bug: 177530961
Test: mmm
Change-Id: I64a4a448512d791c54a9b741076f3b3dbe63ecf9
diff --git a/services/tuner/Android.bp b/services/tuner/Android.bp
index b9e26c4..1cb3037 100644
--- a/services/tuner/Android.bp
+++ b/services/tuner/Android.bp
@@ -23,6 +23,7 @@
         ":tv_tuner_aidl",
     ],
     imports: [
+        "android.hardware.common",
         "android.hardware.common.fmq",
     ],
 
@@ -85,6 +86,7 @@
 
     static_libs: [
         "android.hardware.common.fmq-unstable-ndk_platform",
+        "libaidlcommonsupport",
     ],
 
     include_dirs: [
diff --git a/services/tuner/TunerFilter.cpp b/services/tuner/TunerFilter.cpp
index 18a84a6..e4f1926 100644
--- a/services/tuner/TunerFilter.cpp
+++ b/services/tuner/TunerFilter.cpp
@@ -16,8 +16,11 @@
 
 #define LOG_TAG "TunerFilter"
 
+#include <aidlcommonsupport/NativeHandle.h>
 #include "TunerFilter.h"
 
+using ::android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
+using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterSettings;
 using ::android::hardware::tv::tuner::V1_0::Result;
 
 namespace android {
@@ -34,6 +37,13 @@
     mFilterCallback = nullptr;
 }
 
+DemuxFilterAvSettings TunerFilter::getAvSettings(const TunerFilterSettings& settings) {
+    DemuxFilterAvSettings av {
+        .isPassthrough = settings.get<TunerFilterSettings::av>().isPassthrough,
+    };
+    return av;
+}
+
 Status TunerFilter::getId(int32_t* _aidl_return) {
     if (mFilter == nullptr) {
         ALOGE("IFilter is not initialized");
@@ -46,7 +56,7 @@
         mId = filterId;
     });
     if (res != Result::SUCCESS) {
-        return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
+        return Status::fromServiceSpecificError(static_cast<int32_t>(res));
     }
     *_aidl_return = mId;
     return Status::ok();
@@ -70,14 +80,126 @@
     return Status::ok();
 }
 
+Status TunerFilter::configure(const TunerFilterConfiguration& config) {
+    if (mFilter == nullptr) {
+        ALOGE("IFilter is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    // TODO: more filter types.
+    TunerFilterSettings tunerSettings;
+    DemuxFilterSettings halSettings;
+    switch (config.getTag()) {
+        case TunerFilterConfiguration::ts: {
+            uint16_t tpid = static_cast<uint16_t>(config.get<TunerFilterConfiguration::ts>().tpid);
+            tunerSettings = config.get<TunerFilterConfiguration::ts>().filterSettings;
+            DemuxTsFilterSettings ts {
+                .tpid = tpid,
+            };
+
+            switch (tunerSettings.getTag()) {
+                case TunerFilterSettings::av: {
+                    ts.filterSettings.av(getAvSettings(tunerSettings));
+                    break;
+                }
+            }
+            break;
+        }
+    }
+    Result res = mFilter->configure(halSettings);
+    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");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+    Result res = mFilter->start();
+    if (res != Result::SUCCESS) {
+        return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+    }
+    return Status::ok();
+}
+
+Status TunerFilter::stop() {
+    if (mFilter == nullptr) {
+        ALOGE("IFilter is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+    Result res = mFilter->stop();
+    if (res != Result::SUCCESS) {
+        return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+    }
+    return Status::ok();
+}
+
+Status TunerFilter::flush() {
+    if (mFilter == nullptr) {
+        ALOGE("IFilter is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+    Result res = mFilter->flush();
+    if (res != Result::SUCCESS) {
+        return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+    }
+    return Status::ok();
+}
+
 /////////////// FilterCallback ///////////////////////
 
+void TunerFilter::FilterCallback::getMediaEvent(
+        std::vector<DemuxFilterEvent::Event>& events, std::vector<TunerFilterEvent>& res) {
+    for (DemuxFilterEvent::Event e : events) {
+        DemuxFilterMediaEvent mediaEvent = e.media();
+        TunerFilterMediaEvent tunerMedia;
+
+        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.isSecureMemory = mediaEvent.isSecureMemory;
+        tunerMedia.avDataId = static_cast<long>(mediaEvent.avDataId);
+        tunerMedia.mpuSequenceNumber = static_cast<int>(mediaEvent.mpuSequenceNumber);
+        tunerMedia.isPesPrivateData = mediaEvent.isPesPrivateData;
+
+        if (mediaEvent.avMemory.getNativeHandle() != nullptr) {
+            tunerMedia.avMemory = dupToAidl(mediaEvent.avMemory.getNativeHandle());
+        }
+
+        TunerFilterEvent tunerEvent;
+        tunerEvent.set<TunerFilterEvent::media>(std::move(tunerMedia));
+        res.push_back(std::move(tunerEvent));
+    }
+}
+
 Return<void> TunerFilter::FilterCallback::onFilterStatus(DemuxFilterStatus status) {
     mTunerFilterCallback->onFilterStatus((int)status);
     return Void();
 }
 
-Return<void> TunerFilter::FilterCallback::onFilterEvent(const DemuxFilterEvent&) {
+Return<void> TunerFilter::FilterCallback::onFilterEvent(const DemuxFilterEvent& filterEvent) {
+    ALOGD("FilterCallback::onFilterEvent");
+    std::vector<DemuxFilterEvent::Event> events = filterEvent.events;
+    std::vector<TunerFilterEvent> tunerEvent;
+
+    if (!events.empty()) {
+        DemuxFilterEvent::Event event = events[0];
+        switch (event.getDiscriminator()) {
+            case DemuxFilterEvent::Event::hidl_discriminator::media: {
+                getMediaEvent(events, tunerEvent);
+                break;
+            }
+            default: {
+                break;
+            }
+        }
+    }
+    mTunerFilterCallback->onFilterEvent(&tunerEvent);
     return Void();
 }
 
diff --git a/services/tuner/TunerFilter.h b/services/tuner/TunerFilter.h
index e7e436a..3259e37 100644
--- a/services/tuner/TunerFilter.h
+++ b/services/tuner/TunerFilter.h
@@ -26,9 +26,15 @@
 using Status = ::ndk::ScopedAStatus;
 using ::aidl::android::media::tv::tuner::BnTunerFilter;
 using ::aidl::android::media::tv::tuner::ITunerFilterCallback;
+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::TunerFilterSettings;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
+using ::android::hardware::tv::tuner::V1_0::DemuxFilterAvSettings;
 using ::android::hardware::tv::tuner::V1_0::DemuxFilterEvent;
+using ::android::hardware::tv::tuner::V1_0::DemuxFilterMediaEvent;
 using ::android::hardware::tv::tuner::V1_0::DemuxFilterStatus;
 using ::android::hardware::tv::tuner::V1_0::IFilter;
 using ::android::hardware::tv::tuner::V1_0::IFilterCallback;
@@ -43,6 +49,10 @@
     virtual ~TunerFilter();
     Status getId(int32_t* _aidl_return) override;
     Status getId64Bit(int64_t* _aidl_return) override;
+    Status configure(const TunerFilterConfiguration& config) override;
+    Status start() override;
+    Status stop() override;
+    Status flush() override;
 
     struct FilterCallback : public IFilterCallback {
         FilterCallback(const std::shared_ptr<ITunerFilterCallback> tunerFilterCallback)
@@ -50,11 +60,14 @@
 
         virtual Return<void> onFilterEvent(const DemuxFilterEvent& filterEvent);
         virtual Return<void> onFilterStatus(DemuxFilterStatus status);
+        void getMediaEvent(
+                std::vector<DemuxFilterEvent::Event>& events, std::vector<TunerFilterEvent>& res);
 
         std::shared_ptr<ITunerFilterCallback> mTunerFilterCallback;
     };
 
 private:
+    DemuxFilterAvSettings getAvSettings(const TunerFilterSettings& settings);
     sp<IFilter> mFilter;
     sp<::android::hardware::tv::tuner::V1_1::IFilter> mFilter_1_1;
     sp<IFilterCallback> mFilterCallback;
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerFilter.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerFilter.aidl
index 8855725..37166aa 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerFilter.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerFilter.aidl
@@ -16,6 +16,8 @@
 
 package android.media.tv.tuner;
 
+import android.media.tv.tuner.TunerFilterConfiguration;
+
 /**
  * Tuner Filter interface handles tuner related operations.
  *
@@ -31,4 +33,24 @@
      * Get the 64-bit filter Id.
      */
     long getId64Bit();
+
+    /**
+     * Configure the filter.
+     */
+    void configure(in TunerFilterConfiguration config);
+
+    /**
+     * Start the filter.
+     */
+    void start();
+
+    /**
+     * Stop the filter.
+     */
+    void stop();
+
+    /**
+     * Flush the filter.
+     */
+    void flush();
 }
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerFilterCallback.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerFilterCallback.aidl
index 2733d3c..f9f86ac 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerFilterCallback.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerFilterCallback.aidl
@@ -16,6 +16,8 @@
 
 package android.media.tv.tuner;
 
+import android.media.tv.tuner.TunerFilterEvent;
+
 /**
  * TunerFilterCallback interface handles tuner filter related callbacks.
  *
@@ -26,4 +28,9 @@
      * Notify the client a new status of a filter.
      */
     void onFilterStatus(int status);
+
+    /**
+     * Notify the client that a new filter event happened.
+     */
+    void onFilterEvent(out TunerFilterEvent[] filterEvent);
 }
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterAvSettings.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterAvSettings.aidl
new file mode 100644
index 0000000..6bf88f0
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterAvSettings.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;
+
+/**
+ * Filter Settings for a Video and Audio.
+ *
+ * {@hide}
+ */
+parcelable TunerFilterAvSettings {
+    /**
+     * true if the filter output goes to decoder directly in pass through mode.
+     */
+    boolean isPassthrough;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterConfiguration.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterConfiguration.aidl
new file mode 100644
index 0000000..c208dde
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterConfiguration.aidl
@@ -0,0 +1,28 @@
+/**
+ * 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.media.tv.tuner.TunerFilterTsConfiguration;
+
+/**
+ * Filter configuration.
+ *
+ * {@hide}
+ */
+union TunerFilterConfiguration {
+    TunerFilterTsConfiguration ts;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterEvent.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterEvent.aidl
new file mode 100644
index 0000000..ad95112
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterEvent.aidl
@@ -0,0 +1,28 @@
+/**
+ * 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.media.tv.tuner.TunerFilterMediaEvent;
+
+/**
+ * Filter events.
+ *
+ * {@hide}
+ */
+union TunerFilterEvent {
+    TunerFilterMediaEvent media;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterMediaEvent.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterMediaEvent.aidl
new file mode 100644
index 0000000..486a15c
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterMediaEvent.aidl
@@ -0,0 +1,75 @@
+/**
+ * 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 Event for Audio or Video Filter.
+ *
+ * {@hide}
+ */
+parcelable TunerFilterMediaEvent {
+    int streamId;
+
+    /**
+     * true if PTS is present in PES header.
+     */
+    boolean isPtsPresent;
+
+    /**
+     * Presentation Time Stamp for audio or video frame. It based on 90KHz has
+     * the same format as PTS (Presentation Time Stamp).
+     */
+    long pts;
+
+    /**
+     * Data size in bytes of audio or video frame
+     */
+    int dataLength;
+
+    /**
+     *  The offset in the memory block which is shared among multiple
+     *  MediaEvents.
+     */
+    int offset;
+
+    /**
+     * A handle associated to the memory where audio or video data stays.
+     */
+    NativeHandle avMemory;
+
+    /**
+     * True if the avMemory is in secure area, and isn't mappable.
+     */
+    boolean isSecureMemory;
+
+    /**
+     * An Id is used by HAL to provide additional information for AV data.
+     * For secure audio, it's the audio handle used by Audio Track.
+     */
+    long avDataId;
+
+    /**
+     * MPU sequence number of filtered data (only for MMTP)
+     */
+    int mpuSequenceNumber;
+
+    boolean isPesPrivateData;
+
+    // TODO: add ExtraMetaData
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterSettings.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterSettings.aidl
new file mode 100644
index 0000000..8b9e9c2
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterSettings.aidl
@@ -0,0 +1,28 @@
+/**
+ * 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.media.tv.tuner.TunerFilterAvSettings;
+
+/**
+ * Filter Settings.
+ *
+ * {@hide}
+ */
+union TunerFilterSettings {
+    TunerFilterAvSettings av;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterTsConfiguration.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterTsConfiguration.aidl
new file mode 100644
index 0000000..5b94988
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterTsConfiguration.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.media.tv.tuner.TunerFilterSettings;
+
+/**
+ * Filter Settings for a TS filter.
+ *
+ * {@hide}
+ */
+parcelable TunerFilterTsConfiguration {
+    int tpid;
+    TunerFilterSettings filterSettings;
+}