Complete TunerFrontend aidl interface and implementation

Test: make
Bug: 159067322
Change-Id: I97bc2431be1ba7b0a807b6dd06b609ad2c885dde
diff --git a/services/tuner/Android.bp b/services/tuner/Android.bp
index 1cb3037..5980b45 100644
--- a/services/tuner/Android.bp
+++ b/services/tuner/Android.bp
@@ -111,6 +111,7 @@
 
     shared_libs: [
         "android.hardware.tv.tuner@1.0",
+        "android.hardware.tv.tuner@1.1",
         "libbase",
         "libbinder",
         "libfmq",
diff --git a/services/tuner/TunerFrontend.cpp b/services/tuner/TunerFrontend.cpp
index a919f98..b85e58b 100644
--- a/services/tuner/TunerFrontend.cpp
+++ b/services/tuner/TunerFrontend.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "TunerFrontend"
 
 #include "TunerFrontend.h"
+#include "TunerLnb.h"
 
 using ::aidl::android::media::tv::tuner::TunerFrontendAtsc3PlpSettings;
 using ::aidl::android::media::tv::tuner::TunerFrontendScanAtsc3PlpInfo;
@@ -206,12 +207,68 @@
     return Status::fromServiceSpecificError(static_cast<int32_t>(status));
 }
 
-Status TunerFrontend::setLnb(int /*lnbHandle*/) {
-    return Status::ok();
+Status TunerFrontend::setLnb(const shared_ptr<ITunerLnb>& lnb) {
+    if (mFrontend == NULL) {
+        ALOGD("IFrontend is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result status = mFrontend->setLnb(static_cast<TunerLnb*>(lnb.get())->getId());
+    if (status == Result::SUCCESS) {
+        return Status::ok();
+    }
+
+    return Status::fromServiceSpecificError(static_cast<int32_t>(status));
 }
 
-Status TunerFrontend::setLna(bool /*bEnable*/) {
-    return Status::ok();
+Status TunerFrontend::setLna(bool bEnable) {
+    if (mFrontend == NULL) {
+        ALOGD("IFrontend is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result status = mFrontend->setLna(bEnable);
+    if (status == Result::SUCCESS) {
+        return Status::ok();
+    }
+
+    return Status::fromServiceSpecificError(static_cast<int32_t>(status));
+}
+
+Status TunerFrontend::linkCiCamToFrontend(int ciCamId, int32_t* _aidl_return) {
+    if (mFrontend_1_1 == NULL) {
+        ALOGD("IFrontend_1_1 is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    int ltsId;
+    Result status;
+    mFrontend_1_1->linkCiCam(static_cast<uint32_t>(ciCamId),
+            [&](Result r, uint32_t id) {
+                status = r;
+                ltsId = id;
+            });
+
+    if (status == Result::SUCCESS) {
+        *_aidl_return = ltsId;
+        return Status::ok();
+    }
+
+    return Status::fromServiceSpecificError(static_cast<int32_t>(status));
+}
+
+Status TunerFrontend::unlinkCiCamToFrontend(int ciCamId) {
+    if (mFrontend_1_1 == NULL) {
+        ALOGD("IFrontend_1_1 is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result status = mFrontend_1_1->unlinkCiCam(ciCamId);
+    if (status == Result::SUCCESS) {
+        return Status::ok();
+    }
+
+    return Status::fromServiceSpecificError(static_cast<int32_t>(status));
 }
 
 Status TunerFrontend::close() {
diff --git a/services/tuner/TunerFrontend.h b/services/tuner/TunerFrontend.h
index 729640c..22fd509 100644
--- a/services/tuner/TunerFrontend.h
+++ b/services/tuner/TunerFrontend.h
@@ -27,6 +27,7 @@
 using Status = ::ndk::ScopedAStatus;
 using ::aidl::android::media::tv::tuner::BnTunerFrontend;
 using ::aidl::android::media::tv::tuner::ITunerFrontendCallback;
+using ::aidl::android::media::tv::tuner::ITunerLnb;
 using ::aidl::android::media::tv::tuner::TunerFrontendAtsc3Settings;
 using ::aidl::android::media::tv::tuner::TunerFrontendDvbsCodeRate;
 using ::aidl::android::media::tv::tuner::TunerFrontendScanMessage;
@@ -65,8 +66,10 @@
     Status stopTune() override;
     Status scan(const TunerFrontendSettings& settings, int frontendScanType) override;
     Status stopScan() override;
-    Status setLnb(int lnbHandle) override;
+    Status setLnb(const shared_ptr<ITunerLnb>& lnb) override;
     Status setLna(bool bEnable) override;
+    Status linkCiCamToFrontend(int ciCamId, int32_t* _aidl_return) override;
+    Status unlinkCiCamToFrontend(int ciCamId) override;
     Status close() override;
     Status getStatus(const vector<int32_t>& statusTypes,
             vector<TunerFrontendStatus>* _aidl_return) override;
diff --git a/services/tuner/TunerLnb.h b/services/tuner/TunerLnb.h
index e80b97e..500d072 100644
--- a/services/tuner/TunerLnb.h
+++ b/services/tuner/TunerLnb.h
@@ -49,6 +49,8 @@
     Status sendDiseqcMessage(const vector<uint8_t>& diseqcMessage) override;
     Status close() override;
 
+    int getId() { return mId; }
+
     struct LnbCallback : public ILnbCallback {
         LnbCallback(const shared_ptr<ITunerLnbCallback> tunerLnbCallback)
                 : mTunerLnbCallback(tunerLnbCallback) {};
diff --git a/services/tuner/TunerService.cpp b/services/tuner/TunerService.cpp
index b356039..4f6f16c 100644
--- a/services/tuner/TunerService.cpp
+++ b/services/tuner/TunerService.cpp
@@ -17,7 +17,6 @@
 #define LOG_TAG "TunerService"
 
 #include <android/binder_manager.h>
-#include <fmq/ConvertMQDescriptors.h>
 #include <utils/Log.h>
 #include "TunerService.h"
 #include "TunerFrontend.h"
@@ -46,6 +45,7 @@
 using ::android::hardware::tv::tuner::V1_0::ILnb;
 using ::android::hardware::tv::tuner::V1_0::LnbId;
 using ::android::hardware::tv::tuner::V1_0::Result;
+using ::android::hardware::tv::tuner::V1_1::FrontendDtmbCapabilities;
 
 namespace android {
 
@@ -58,8 +58,8 @@
     AServiceManager_addService(service->asBinder().get(), getServiceName());
 }
 
-bool TunerService::getITuner() {
-    ALOGD("getITuner");
+bool TunerService::hasITuner() {
+    ALOGD("hasITuner");
     if (mTuner != nullptr) {
         return true;
     }
@@ -71,10 +71,26 @@
     return true;
 }
 
+bool TunerService::hasITuner_1_1() {
+    ALOGD("hasITuner_1_1");
+    if (mTuner_1_1 != nullptr) {
+        return true;
+    }
+    if (!hasITuner()) {
+        return false;
+    }
+    mTuner_1_1 = ::android::hardware::tv::tuner::V1_1::ITuner::castFrom(mTuner);
+    if (mTuner_1_1 == nullptr) {
+        ALOGE("Failed to get ITuner_1_1 service");
+        return false;
+    }
+    return true;
+}
+
 Status TunerService::openDemux(
         int /* demuxHandle */, std::shared_ptr<ITunerDemux>* _aidl_return) {
     ALOGD("openDemux");
-    if (!getITuner()) {
+    if (!hasITuner()) {
         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::NOT_INITIALIZED));
     }
     Result res;
@@ -99,7 +115,7 @@
 
 Status TunerService::getDemuxCaps(TunerDemuxCapabilities* _aidl_return) {
     ALOGD("getDemuxCaps");
-    if (!getITuner()) {
+    if (!hasITuner()) {
         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::NOT_INITIALIZED));
     }
     Result res;
@@ -117,48 +133,8 @@
     return Status::fromServiceSpecificError(static_cast<int32_t>(res));
 }
 
-Result TunerService::configFilter() {
-    ALOGD("configFilter");
-    if (mFilter == NULL) {
-        ALOGD("Failed to configure filter: filter not found");
-        return Result::NOT_INITIALIZED;
-    }
-    DemuxFilterSettings filterSettings;
-    DemuxTsFilterSettings tsFilterSettings {
-        .tpid = 256,
-    };
-    DemuxFilterAvSettings filterAvSettings {
-        .isPassthrough = false,
-    };
-    tsFilterSettings.filterSettings.av(filterAvSettings);
-    filterSettings.ts(tsFilterSettings);
-    Result res = mFilter->configure(filterSettings);
-
-    if (res != Result::SUCCESS) {
-        ALOGD("config filter failed, res = %d", res);
-        return res;
-    }
-
-    Result getQueueDescResult = Result::UNKNOWN_ERROR;
-    mFilter->getQueueDesc(
-            [&](Result r, const MQDescriptorSync<uint8_t>& desc) {
-                mFilterMQDesc = desc;
-                getQueueDescResult = r;
-                ALOGD("getFilterQueueDesc");
-            });
-    if (getQueueDescResult == Result::SUCCESS) {
-        unsafeHidlToAidlMQDescriptor<uint8_t, int8_t, SynchronizedReadWrite>(
-                mFilterMQDesc,  &mAidlMQDesc);
-        mAidlMq = new (nothrow) AidlMessageQueue(mAidlMQDesc);
-        EventFlag::createEventFlag(mAidlMq->getEventFlagWord(), &mEventFlag);
-    } else {
-        ALOGD("get MQDesc failed, res = %d", getQueueDescResult);
-    }
-    return getQueueDescResult;
-}
-
 Status TunerService::getFrontendIds(vector<int32_t>* ids) {
-    if (!getITuner()) {
+    if (!hasITuner()) {
         return Status::fromServiceSpecificError(
                 static_cast<int32_t>(Result::NOT_INITIALIZED));
     }
@@ -173,17 +149,15 @@
     return Status::ok();
 }
 
-Status TunerService::getFrontendInfo(
-        int32_t frontendHandle, TunerFrontendInfo* _aidl_return) {
-    if (mTuner == nullptr) {
+Status TunerService::getFrontendInfo(int32_t id, TunerFrontendInfo* _aidl_return) {
+    if (!hasITuner()) {
         ALOGE("ITuner service is not init.");
         return ::ndk::ScopedAStatus::fromServiceSpecificError(
                 static_cast<int32_t>(Result::UNAVAILABLE));
     }
 
     FrontendInfo info;
-    int feId = getResourceIdFromHandle(frontendHandle, FRONTEND);
-    Result res = getHidlFrontendInfo(feId, info);
+    Result res = getHidlFrontendInfo(id, info);
     if (res != Result::SUCCESS) {
         return Status::fromServiceSpecificError(static_cast<int32_t>(res));
     }
@@ -193,9 +167,41 @@
     return Status::ok();
 }
 
+Status TunerService::getFrontendDtmbCapabilities(
+        int32_t id, TunerFrontendDtmbCapabilities* _aidl_return) {
+    if (!hasITuner_1_1()) {
+        ALOGE("ITuner_1_1 service is not init.");
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(
+                static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result res;
+    FrontendDtmbCapabilities dtmbCaps;
+    mTuner_1_1->getFrontendDtmbCapabilities(id,
+            [&](Result r, const FrontendDtmbCapabilities& caps) {
+        dtmbCaps = caps;
+        res = r;
+    });
+    if (res != Result::SUCCESS) {
+        return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+    }
+
+    TunerFrontendDtmbCapabilities aidlDtmbCaps{
+        .transmissionModeCap = (int)dtmbCaps.transmissionModeCap,
+        .bandwidthCap = (int)dtmbCaps.bandwidthCap,
+        .modulationCap = (int)dtmbCaps.modulationCap,
+        .codeRateCap = (int)dtmbCaps.codeRateCap,
+        .guardIntervalCap = (int)dtmbCaps.guardIntervalCap,
+        .interleaveModeCap = (int)dtmbCaps.interleaveModeCap,
+    };
+
+    *_aidl_return = aidlDtmbCaps;
+    return Status::ok();
+}
+
 Status TunerService::openFrontend(
         int32_t frontendHandle, shared_ptr<ITunerFrontend>* _aidl_return) {
-    if (mTuner == nullptr) {
+    if (!hasITuner()) {
         ALOGE("ITuner service is not init.");
         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
     }
@@ -214,25 +220,8 @@
     return Status::ok();
 }
 
-Status TunerService::getFmqSyncReadWrite(
-        MQDescriptor<int8_t, SynchronizedReadWrite>* mqDesc, bool* _aidl_return) {
-    ALOGD("getFmqSyncReadWrite");
-    // TODO: put the following methods AIDL, and should be called from clients.
-    configFilter();
-    mFilter->start();
-    if (mqDesc == nullptr) {
-        ALOGD("getFmqSyncReadWrite null MQDescriptor.");
-        *_aidl_return = false;
-    } else {
-        ALOGD("getFmqSyncReadWrite true");
-        *_aidl_return = true;
-        *mqDesc = move(mAidlMQDesc);
-    }
-    return ndk::ScopedAStatus::ok();
-}
-
 Status TunerService::openLnb(int lnbHandle, shared_ptr<ITunerLnb>* _aidl_return) {
-    if (!getITuner()) {
+    if (!hasITuner()) {
         ALOGD("get ITuner failed");
         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
     }
@@ -253,7 +242,7 @@
 }
 
 Status TunerService::openLnbByName(const string& lnbName, shared_ptr<ITunerLnb>* _aidl_return) {
-    if (!getITuner()) {
+    if (!hasITuner()) {
         ALOGE("get ITuner failed");
         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
     }
@@ -276,7 +265,7 @@
 
 Status TunerService::openDescrambler(int32_t /*descramblerHandle*/,
             std::shared_ptr<ITunerDescrambler>* _aidl_return) {
-    if (!getITuner()) {
+    if (!hasITuner()) {
         ALOGD("get ITuner failed");
         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
     }
@@ -297,7 +286,7 @@
 }
 
 Status TunerService::updateTunerResources() {
-    if (!getITuner()) {
+    if (!hasITuner()) {
         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
     }
 
@@ -453,7 +442,7 @@
         case FrontendType::DVBC: {
             TunerFrontendCableCapabilities cableCaps{
                 .modulationCap = (int)halInfo.frontendCaps.dvbcCaps().modulationCap,
-                .codeRateCap = (int)halInfo.frontendCaps.dvbcCaps().fecCap,
+                .codeRateCap = (int64_t)halInfo.frontendCaps.dvbcCaps().fecCap,
                 .annexCap = (int)halInfo.frontendCaps.dvbcCaps().annexCap,
             };
             caps.set<TunerFrontendCapabilities::cableCaps>(cableCaps);
diff --git a/services/tuner/TunerService.h b/services/tuner/TunerService.h
index 24cc71e..ce085cb 100644
--- a/services/tuner/TunerService.h
+++ b/services/tuner/TunerService.h
@@ -19,7 +19,7 @@
 
 #include <aidl/android/media/tv/tunerresourcemanager/ITunerResourceManager.h>
 #include <aidl/android/media/tv/tuner/BnTunerService.h>
-#include <android/hardware/tv/tuner/1.0/ITuner.h>
+#include <android/hardware/tv/tuner/1.1/ITuner.h>
 #include <fmq/AidlMessageQueue.h>
 #include <fmq/EventFlag.h>
 #include <fmq/MessageQueue.h>
@@ -33,6 +33,7 @@
 using ::aidl::android::media::tv::tuner::ITunerFrontend;
 using ::aidl::android::media::tv::tuner::ITunerLnb;
 using ::aidl::android::media::tv::tuner::TunerDemuxCapabilities;
+using ::aidl::android::media::tv::tuner::TunerFrontendDtmbCapabilities;
 using ::aidl::android::media::tv::tuner::TunerFrontendInfo;
 using ::aidl::android::media::tv::tunerresourcemanager::ITunerResourceManager;
 
@@ -98,10 +99,10 @@
 
     Status getFrontendIds(vector<int32_t>* ids) override;
     Status getFrontendInfo(int32_t id, TunerFrontendInfo* _aidl_return) override;
+    Status getFrontendDtmbCapabilities(
+            int32_t id, TunerFrontendDtmbCapabilities* _aidl_return) override;
     Status openFrontend(
             int32_t frontendHandle, shared_ptr<ITunerFrontend>* _aidl_return) override;
-    Status getFmqSyncReadWrite(
-            MQDescriptor<int8_t, SynchronizedReadWrite>* mqDesc, bool* _aidl_return) override;
     Status openLnb(int lnbHandle, shared_ptr<ITunerLnb>* _aidl_return) override;
     Status openLnbByName(const string& lnbName, shared_ptr<ITunerLnb>* _aidl_return) override;
     Status openDemux(int32_t demuxHandle, std::shared_ptr<ITunerDemux>* _aidl_return) override;
@@ -123,8 +124,8 @@
     }
 
 private:
-    bool getITuner();
-    Result configFilter();
+    bool hasITuner();
+    bool hasITuner_1_1();
 
     void updateFrontendResources();
     void updateLnbResources();
@@ -136,15 +137,10 @@
     TunerFrontendInfo convertToAidlFrontendInfo(FrontendInfo halInfo);
 
     sp<ITuner> mTuner;
-    sp<IFilter> mFilter;
+    sp<::android::hardware::tv::tuner::V1_1::ITuner> mTuner_1_1;
 
     shared_ptr<ITunerResourceManager> mTunerResourceManager;
     int mResourceRequestCount = 0;
-
-    AidlMessageQueue* mAidlMq;
-    MQDescriptorSync<uint8_t> mFilterMQDesc;
-    AidlMQDesc mAidlMQDesc;
-    EventFlag* mEventFlag;
 };
 
 } // namespace android
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerFrontend.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerFrontend.aidl
index 254e16a..ef0255a 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerFrontend.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerFrontend.aidl
@@ -17,6 +17,7 @@
 package android.media.tv.tuner;
 
 import android.media.tv.tuner.ITunerFrontendCallback;
+import android.media.tv.tuner.ITunerLnb;
 import android.media.tv.tuner.TunerFrontendSettings;
 import android.media.tv.tuner.TunerFrontendStatus;
 
@@ -61,9 +62,9 @@
     /**
      * Sets Low-Noise Block downconverter (LNB) for satellite frontend.
      *
-     * @param lnbHandle lnb handle in use.
+     * @param tuner lnb interface.
      */
-    void setLnb(in int lnbHandle);
+    void setLnb(in ITunerLnb lnb);
 
     /**
      * Enable or Disable Low Noise Amplifier (LNA).
@@ -73,6 +74,18 @@
     void setLna(in boolean bEnable);
 
     /**
+     * Link Frontend to the cicam with given id.
+     *
+     * @return lts id
+     */
+    int linkCiCamToFrontend(in int ciCamId);
+
+    /**
+     * Unink Frontend to the cicam with given id.
+     */
+    void unlinkCiCamToFrontend(in int ciCamId);
+
+    /**
      * Releases the ITunerFrontend instance.
      */
     void close();
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
index 11d95ea..bea8811 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
@@ -24,6 +24,7 @@
 import android.media.tv.tuner.ITunerFrontend;
 import android.media.tv.tuner.ITunerLnb;
 import android.media.tv.tuner.TunerDemuxCapabilities;
+import android.media.tv.tuner.TunerFrontendDtmbCapabilities;
 import android.media.tv.tuner.TunerFrontendInfo;
 
 /**
@@ -48,6 +49,11 @@
     TunerFrontendInfo getFrontendInfo(in int frontendHandle);
 
     /**
+     * Get Dtmb Frontend Capabilities.
+     */
+    TunerFrontendDtmbCapabilities getFrontendDtmbCapabilities(in int id);
+
+    /**
      * Open a Tuner Frontend interface.
      *
      * @param frontendHandle the handle of the frontend granted by TRM.
@@ -55,13 +61,6 @@
      */
     ITunerFrontend openFrontend(in int frontendHandle);
 
-    /*
-     * Gets synchronized fast message queue.
-     *
-     * @return true if succeeds, false otherwise.
-     */
-    boolean getFmqSyncReadWrite(out MQDescriptor<byte, SynchronizedReadWrite> mqDesc);
-
     /**
      * Open a new interface of ITunerLnb given a lnbHandle.
      *
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendCableCapabilities.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendCableCapabilities.aidl
index 7df452a..b880c60 100644
--- a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendCableCapabilities.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendCableCapabilities.aidl
@@ -30,7 +30,7 @@
     /**
      * Code Rate capability
      */
-    int codeRateCap; // inner FEC will converge to codeRate
+    long codeRateCap; // inner FEC will converge to codeRate
 
     /**
      * Annex capability
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFrontendDtmbCapabilities.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendDtmbCapabilities.aidl
new file mode 100644
index 0000000..e8e4933
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFrontendDtmbCapabilities.aidl
@@ -0,0 +1,36 @@
+/**
+ * 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;
+
+/**
+ * DTMB Frontend Capabilities interface.
+ *
+ * {@hide}
+ */
+parcelable TunerFrontendDtmbCapabilities {
+    int transmissionModeCap;
+
+    int bandwidthCap;
+
+    int modulationCap;
+
+    int codeRateCap;
+
+    int guardIntervalCap;
+
+    int interleaveModeCap;
+}