Complete TunerDescrambler aidl interface and implementation

Test: make
Bug: 159067322
Change-Id: I84322f8597080643ad5bbb829eb92f3dcd1493db
diff --git a/services/tuner/TunerDemux.h b/services/tuner/TunerDemux.h
index 9f294c6..2a9836b 100644
--- a/services/tuner/TunerDemux.h
+++ b/services/tuner/TunerDemux.h
@@ -56,6 +56,8 @@
     Status disconnectCiCam() override;
     Status close() override;
 
+    int getId() { return mDemuxId; }
+
 private:
     sp<IDemux> mDemux;
     int mDemuxId;
diff --git a/services/tuner/TunerDescrambler.cpp b/services/tuner/TunerDescrambler.cpp
new file mode 100644
index 0000000..6b2889d
--- /dev/null
+++ b/services/tuner/TunerDescrambler.cpp
@@ -0,0 +1,120 @@
+/**
+ * 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.
+ */
+
+#define LOG_TAG "TunerDescrambler"
+
+#include "TunerFilter.h"
+#include "TunerDemux.h"
+#include "TunerDescrambler.h"
+
+using ::android::hardware::tv::tuner::V1_0::Result;
+
+using namespace std;
+
+namespace android {
+
+TunerDescrambler::TunerDescrambler(sp<IDescrambler> descrambler) {
+    mDescrambler = descrambler;
+}
+
+TunerDescrambler::~TunerDescrambler() {
+    mDescrambler = nullptr;
+}
+
+Status TunerDescrambler::setDemuxSource(const std::shared_ptr<ITunerDemux>& demux) {
+    if (mDescrambler == nullptr) {
+        ALOGE("IDescrambler is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result res = mDescrambler->setDemuxSource(static_cast<TunerDemux*>(demux.get())->getId());
+    if (res != Result::SUCCESS) {
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
+    }
+    return Status::ok();
+}
+
+Status TunerDescrambler::setKeyToken(const vector<uint8_t>& keyToken) {
+    if (mDescrambler == nullptr) {
+        ALOGE("IDescrambler is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result res = mDescrambler->setKeyToken(keyToken);
+    if (res != Result::SUCCESS) {
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
+    }
+    return Status::ok();
+}
+
+Status TunerDescrambler::addPid(const TunerDemuxPid& pid,
+        const shared_ptr<ITunerFilter>& optionalSourceFilter) {
+    if (mDescrambler == nullptr) {
+        ALOGE("IDescrambler is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result res = mDescrambler->addPid(getHidlDemuxPid(pid),
+            static_cast<TunerFilter*>(optionalSourceFilter.get())->getHalFilter());
+    if (res != Result::SUCCESS) {
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
+    }
+    return Status::ok();
+}
+
+Status TunerDescrambler::removePid(const TunerDemuxPid& pid,
+        const shared_ptr<ITunerFilter>& optionalSourceFilter) {
+    if (mDescrambler == nullptr) {
+        ALOGE("IDescrambler is not initialized");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result res = mDescrambler->removePid(getHidlDemuxPid(pid),
+            static_cast<TunerFilter*>(optionalSourceFilter.get())->getHalFilter());
+    if (res != Result::SUCCESS) {
+        return ::ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(res));
+    }
+    return Status::ok();
+}
+
+Status TunerDescrambler::close() {
+    if (mDescrambler == nullptr) {
+        ALOGE("IDescrambler is not initialized.");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result res = mDescrambler->close();
+    if (res != Result::SUCCESS) {
+        return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+    }
+    return Status::ok();
+}
+
+DemuxPid TunerDescrambler::getHidlDemuxPid(const TunerDemuxPid& pid) {
+    DemuxPid hidlPid;
+    switch (pid.getTag()) {
+        case TunerDemuxPid::tPid: {
+            hidlPid.tPid((uint16_t)pid.tPid);
+            break;
+        }
+        case TunerDemuxPid::mmtpPid: {
+            hidlPid.mmtpPid((uint16_t)pid.mmtpPid);
+            break;
+        }
+    }
+    return hidlPid;
+}
+}  // namespace android
diff --git a/services/tuner/TunerDescrambler.h b/services/tuner/TunerDescrambler.h
new file mode 100644
index 0000000..1970fb7
--- /dev/null
+++ b/services/tuner/TunerDescrambler.h
@@ -0,0 +1,54 @@
+/**
+ * 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.
+ */
+
+#ifndef ANDROID_MEDIA_TUNERDESCRAMBLER_H
+#define ANDROID_MEDIA_TUNERDESCRAMBLER_H
+
+#include <aidl/android/media/tv/tuner/BnTunerDescrambler.h>
+#include <android/hardware/tv/tuner/1.0/ITuner.h>
+
+using Status = ::ndk::ScopedAStatus;
+using ::aidl::android::media::tv::tuner::BnTunerDescrambler;
+using ::aidl::android::media::tv::tuner::ITunerDemux;
+using ::aidl::android::media::tv::tuner::ITunerFilter;
+using ::aidl::android::media::tv::tuner::TunerDemuxPid;
+using ::android::hardware::tv::tuner::V1_0::DemuxPid;
+using ::android::hardware::tv::tuner::V1_0::IDescrambler;
+
+namespace android {
+
+class TunerDescrambler : public BnTunerDescrambler {
+
+public:
+    TunerDescrambler(sp<IDescrambler> descrambler);
+    virtual ~TunerDescrambler();
+    Status setDemuxSource(const shared_ptr<ITunerDemux>& demux) override;
+    Status setKeyToken(const vector<uint8_t>& keyToken) override;
+    Status addPid(const TunerDemuxPid& pid,
+            const shared_ptr<ITunerFilter>& optionalSourceFilter) override;
+    Status removePid(const TunerDemuxPid& pid,
+            const shared_ptr<ITunerFilter>& optionalSourceFilter) override;
+    Status close() override;
+
+private:
+    DemuxPid getHidlDemuxPid(const TunerDemuxPid& pid);
+
+    sp<IDescrambler> mDescrambler;
+};
+
+} // namespace android
+
+#endif // ANDROID_MEDIA_TUNERDESCRAMBLER_H
diff --git a/services/tuner/TunerService.cpp b/services/tuner/TunerService.cpp
index 4376188..b356039 100644
--- a/services/tuner/TunerService.cpp
+++ b/services/tuner/TunerService.cpp
@@ -23,6 +23,7 @@
 #include "TunerFrontend.h"
 #include "TunerLnb.h"
 #include "TunerDemux.h"
+#include "TunerDescrambler.h"
 
 using ::aidl::android::media::tv::tuner::TunerFrontendAnalogCapabilities;
 using ::aidl::android::media::tv::tuner::TunerFrontendAtsc3Capabilities;
@@ -273,6 +274,28 @@
     return Status::ok();
 }
 
+Status TunerService::openDescrambler(int32_t /*descramblerHandle*/,
+            std::shared_ptr<ITunerDescrambler>* _aidl_return) {
+    if (!getITuner()) {
+        ALOGD("get ITuner failed");
+        return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+    }
+
+    Result status;
+    sp<IDescrambler> descrambler;
+    //int id = getResourceIdFromHandle(descramblerHandle, DESCRAMBLER);
+    mTuner->openDescrambler([&](Result r, const sp<IDescrambler>& descramblerSp) {
+        status = r;
+        descrambler = descramblerSp;
+    });
+    if (status != Result::SUCCESS) {
+        return Status::fromServiceSpecificError(static_cast<int32_t>(status));
+    }
+
+    *_aidl_return = ::ndk::SharedRefBase::make<TunerDescrambler>(descrambler);
+    return Status::ok();
+}
+
 Status TunerService::updateTunerResources() {
     if (!getITuner()) {
         return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
diff --git a/services/tuner/TunerService.h b/services/tuner/TunerService.h
index e18b793..24cc71e 100644
--- a/services/tuner/TunerService.h
+++ b/services/tuner/TunerService.h
@@ -29,6 +29,7 @@
 using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
 using ::aidl::android::media::tv::tuner::BnTunerService;
 using ::aidl::android::media::tv::tuner::ITunerDemux;
+using ::aidl::android::media::tv::tuner::ITunerDescrambler;
 using ::aidl::android::media::tv::tuner::ITunerFrontend;
 using ::aidl::android::media::tv::tuner::ITunerLnb;
 using ::aidl::android::media::tv::tuner::TunerDemuxCapabilities;
@@ -55,6 +56,7 @@
 using ::android::hardware::tv::tuner::V1_0::FrontendId;
 using ::android::hardware::tv::tuner::V1_0::FrontendInfo;
 using ::android::hardware::tv::tuner::V1_0::IDemux;
+using ::android::hardware::tv::tuner::V1_0::IDescrambler;
 using ::android::hardware::tv::tuner::V1_0::IFilter;
 using ::android::hardware::tv::tuner::V1_0::IFilterCallback;
 using ::android::hardware::tv::tuner::V1_0::ITuner;
@@ -94,6 +96,20 @@
     TunerService();
     virtual ~TunerService();
 
+    Status getFrontendIds(vector<int32_t>* ids) override;
+    Status getFrontendInfo(int32_t id, TunerFrontendInfo* _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;
+    Status getDemuxCaps(TunerDemuxCapabilities* _aidl_return) override;
+    Status openDescrambler(int32_t descramblerHandle,
+            std::shared_ptr<ITunerDescrambler>* _aidl_return) override;
+    Status updateTunerResources() override;
+
     // TODO: create a map between resource id and handles.
     static int getResourceIdFromHandle(int resourceHandle, int /*type*/) {
         return (resourceHandle & 0x00ff0000) >> 16;
@@ -106,18 +122,6 @@
                 | (mResourceRequestCount++ & 0xffff);
     }
 
-    Status getFrontendIds(vector<int32_t>* ids) override;
-    Status getFrontendInfo(int32_t frontendHandle, TunerFrontendInfo* _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;
-    Status getDemuxCaps(TunerDemuxCapabilities* _aidl_return) override;
-    Status updateTunerResources() override;
-
 private:
     bool getITuner();
     Result configFilter();
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerDescrambler.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerDescrambler.aidl
new file mode 100644
index 0000000..7370eee
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerDescrambler.aidl
@@ -0,0 +1,53 @@
+/**
+ * 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.ITunerDemux;
+import android.media.tv.tuner.ITunerFilter;
+import android.media.tv.tuner.TunerDemuxPid;
+
+/**
+ * Tuner Demux interface handles tuner related operations.
+ *
+ * {@hide}
+ */
+interface ITunerDescrambler {
+    /**
+     * Set a demux as source of the descrambler.
+     */
+    void setDemuxSource(in ITunerDemux tunerDemux);
+
+    /**
+     * Set a key token to link descrambler to a key slot.
+     */
+    void setKeyToken(in byte[] keyToken);
+
+    /**
+     * Add packets' PID to the descrambler for descrambling.
+     */
+    void addPid(in TunerDemuxPid pid, in ITunerFilter optionalSourceFilter);
+
+    /**
+     * Remove packets' PID from the descrambler.
+     */
+    void removePid(in TunerDemuxPid pid, in ITunerFilter optionalSourceFilter);
+
+    /**
+     * Close a new interface of ITunerDescrambler.
+     */
+    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 c6259ae..11d95ea 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerService.aidl
@@ -20,6 +20,7 @@
 import android.hardware.common.fmq.SynchronizedReadWrite;
 import android.hardware.common.fmq.UnsynchronizedWrite;
 import android.media.tv.tuner.ITunerDemux;
+import android.media.tv.tuner.ITunerDescrambler;
 import android.media.tv.tuner.ITunerFrontend;
 import android.media.tv.tuner.ITunerLnb;
 import android.media.tv.tuner.TunerDemuxCapabilities;
@@ -89,6 +90,13 @@
      */
     TunerDemuxCapabilities getDemuxCaps();
 
+    /* Open a new interface of ITunerDescrambler given a descramblerHandle.
+     *
+     * @param descramblerHandle the handle of the descrambler granted by TRM.
+     * @return a newly created ITunerDescrambler interface.
+     */
+    ITunerDescrambler openDescrambler(in int descramblerHandle);
+
     /**
      * Update Tuner Resources in TunerResourceManager.
      */
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerDemuxPid.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerDemuxPid.aidl
new file mode 100644
index 0000000..51c6378
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerDemuxPid.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;
+
+/**
+ * Demux PID interface.
+ *
+ * {@hide}
+ */
+union TunerDemuxPid {
+    int tPid;
+
+    int mmtpPid;
+}