Merge changes from topic "Tuner HAL demux and descrambler"

* changes:
  Tuner HAL VTS for Demux and Descrambler Interface.
  Tuner HAL default implementation for Demux and Descrambler Interface.
  Add Demux and Descrambler interface to Tuner HAL Test: Manual bug: 135709729
diff --git a/tv/tuner/1.0/Android.bp b/tv/tuner/1.0/Android.bp
index b54413d..986518b 100644
--- a/tv/tuner/1.0/Android.bp
+++ b/tv/tuner/1.0/Android.bp
@@ -8,6 +8,9 @@
     },
     srcs: [
         "types.hal",
+        "IDemux.hal",
+        "IDemuxCallback.hal",
+        "IDescrambler.hal",
         "IFrontend.hal",
         "IFrontendCallback.hal",
         "ITuner.hal",
diff --git a/tv/tuner/1.0/IDemux.hal b/tv/tuner/1.0/IDemux.hal
new file mode 100644
index 0000000..938bc44
--- /dev/null
+++ b/tv/tuner/1.0/IDemux.hal
@@ -0,0 +1,37 @@
+package android.hardware.tv.tuner@1.0;
+
+import IDemuxCallback;
+
+/**
+ * Demultiplexer(Demux) takes a single multiplexed input and splits it into
+ * one or more output.
+ *
+ */
+interface IDemux {
+
+    /**
+     * Set a frontend resource as data input of the demux
+     *
+     * It is used by the client to specify a hardware frontend as data source of
+     * this demux instance. A demux instance can have only one data source.
+     *
+     * @return result Result status of the operation.
+     *         SUCCESS if successful,
+     *         INVALID_STATE if failed for wrong state.
+     *         UNKNOWN_ERROR if failed for other reasons.
+     */
+    setFrontendDataSource(FrontendId frontendId) generates (Result result);
+
+    /**
+     * Close the Demux instance
+     *
+     * It is used by the client to release the demux instance. HAL clear
+     * underneath resource. client mustn't access the instance any more.
+     *
+     * @return result Result status of the operation.
+     *         SUCCESS if successful,
+     *         UNKNOWN_ERROR if failed for other reasons.
+     */
+    close() generates (Result result);
+};
+
diff --git a/tv/tuner/1.0/IDemuxCallback.hal b/tv/tuner/1.0/IDemuxCallback.hal
new file mode 100644
index 0000000..c67c5f2
--- /dev/null
+++ b/tv/tuner/1.0/IDemuxCallback.hal
@@ -0,0 +1,11 @@
+package android.hardware.tv.tuner@1.0;
+
+interface IDemuxCallback {
+    /**
+     * Notify the client that a new filter event happened.
+     *
+     * @param filterEvent a demux filter event.
+     */
+     oneway onFilterEvent(DemuxFilterEvent filterEvent);
+};
+
diff --git a/tv/tuner/1.0/IDescrambler.hal b/tv/tuner/1.0/IDescrambler.hal
new file mode 100644
index 0000000..4d6cf3c
--- /dev/null
+++ b/tv/tuner/1.0/IDescrambler.hal
@@ -0,0 +1,35 @@
+package android.hardware.tv.tuner@1.0;
+
+/**
+ * Descrambler is used to descramble input data.
+ *
+ */
+interface IDescrambler {
+
+    /**
+     * Set a demux as source of the descrambler
+     *
+     * It is used by the client to specify a demux as source of this
+     * descrambler. A descrambler instance can have only one source, and
+     * this method can be only called once.
+     *
+     * @return result Result status of the operation.
+     *         SUCCESS if successful,
+     *         INVALID_STATE if failed for wrong state.
+     *         UNKNOWN_ERROR if failed for other reasons.
+     */
+    setDemuxSource(DemuxId demuxId) generates (Result result);
+
+    /**
+     * Release the descrambler instance
+     *
+     * It is used by the client to release the descrambler instance. HAL clear
+     * underneath resource. client mustn't access the instance any more.
+     *
+     * @return result Result status of the operation.
+     *         SUCCESS if successful,
+     *         UNKNOWN_ERROR if failed for other reasons.
+     */
+     close() generates (Result result);
+};
+
diff --git a/tv/tuner/1.0/ITuner.hal b/tv/tuner/1.0/ITuner.hal
index 5a5f547..61a9d63 100644
--- a/tv/tuner/1.0/ITuner.hal
+++ b/tv/tuner/1.0/ITuner.hal
@@ -16,6 +16,8 @@
 
 package android.hardware.tv.tuner@1.0;
 
+import IDemux;
+import IDescrambler;
 import IFrontend;
 
 /**
@@ -48,5 +50,30 @@
     openFrontendById(FrontendId frontendId)
         generates (Result result, IFrontend frontend);
 
-};
+    /**
+     * Create a new instance of Demux.
+     *
+     * It is used by the client to create a Demux instance.
+     *
+     * @return result Result status of the operation.
+     *         SUCCESS if successful,
+     *         UNKNOWN_ERROR if creation failed for other reasons.
+     * @return demuxId newly created demux id.
+     * @return demux the newly created demux interface.
+     */
+     openDemux()
+         generates (Result result, DemuxId demuxId, IDemux demux);
 
+    /**
+     * Create a new instance of Descrambler.
+     *
+     * It is used by the client to create a Descrambler instance.
+     *
+     * @return result Result status of the operation.
+     *         SUCCESS if successful,
+     *         UNKNOWN_ERROR if creation failed for other reasons.
+     * @return descrambler the newly created descrambler interface.
+     */
+     openDescrambler()
+         generates (Result result, IDescrambler descrambler);
+};
diff --git a/tv/tuner/1.0/default/Android.bp b/tv/tuner/1.0/default/Android.bp
index cc8d1f5..21c9f1b 100644
--- a/tv/tuner/1.0/default/Android.bp
+++ b/tv/tuner/1.0/default/Android.bp
@@ -5,6 +5,8 @@
     relative_install_path: "hw",
     srcs: [
         "Frontend.cpp",
+        "Descrambler.cpp",
+        "Demux.cpp",
         "Tuner.cpp",
         "service.cpp",
     ],
diff --git a/tv/tuner/1.0/default/Demux.cpp b/tv/tuner/1.0/default/Demux.cpp
new file mode 100644
index 0000000..6f7c68b
--- /dev/null
+++ b/tv/tuner/1.0/default/Demux.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 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 "android.hardware.tv.tuner@1.0-Demux"
+
+#include "Demux.h"
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+Demux::Demux(uint32_t demuxId) {
+    mDemuxId = demuxId;
+}
+
+Demux::~Demux() {}
+
+Return<Result> Demux::setFrontendDataSource(uint32_t frontendId) {
+    ALOGV("%s", __FUNCTION__);
+
+    mSourceFrontendId = frontendId;
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Demux::close() {
+    ALOGV("%s", __FUNCTION__);
+
+    return Result::SUCCESS;
+    ;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/tuner/1.0/default/Demux.h b/tv/tuner/1.0/default/Demux.h
new file mode 100644
index 0000000..52f3933
--- /dev/null
+++ b/tv/tuner/1.0/default/Demux.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2019 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_HARDWARE_TV_TUNER_V1_0_DEMUX_H_
+#define ANDROID_HARDWARE_TV_TUNER_V1_0_DEMUX_H_
+
+#include <android/hardware/tv/tuner/1.0/IDemux.h>
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::tv::tuner::V1_0::IDemux;
+using ::android::hardware::tv::tuner::V1_0::Result;
+
+class Demux : public IDemux {
+  public:
+    Demux(uint32_t demuxId);
+
+    virtual Return<Result> setFrontendDataSource(uint32_t frontendId) override;
+
+    virtual Return<Result> close() override;
+
+  private:
+    virtual ~Demux();
+    uint32_t mDemuxId;
+    uint32_t mSourceFrontendId;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_TV_TUNER_V1_0_DEMUX_H_
diff --git a/tv/tuner/1.0/default/Descrambler.cpp b/tv/tuner/1.0/default/Descrambler.cpp
new file mode 100644
index 0000000..1af1a2c
--- /dev/null
+++ b/tv/tuner/1.0/default/Descrambler.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 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 "android.hardware.tv.tuner@1.0-Descrambler"
+
+#include <android/hardware/tv/tuner/1.0/IFrontendCallback.h>
+#include <utils/Log.h>
+
+#include "Descrambler.h"
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+Descrambler::Descrambler() {}
+
+Descrambler::~Descrambler() {}
+
+Return<Result> Descrambler::setDemuxSource(uint32_t demuxId) {
+    ALOGV("%s", __FUNCTION__);
+    if (mDemuxSet) {
+        ALOGW("[   WARN   ] Descrambler has already been set with a demux id %d", mSourceDemuxId);
+        return Result::INVALID_STATE;
+    }
+    mDemuxSet = true;
+    mSourceDemuxId = demuxId;
+
+    return Result::SUCCESS;
+}
+
+Return<Result> Descrambler::close() {
+    ALOGV("%s", __FUNCTION__);
+    mDemuxSet = false;
+
+    return Result::SUCCESS;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
diff --git a/tv/tuner/1.0/default/Descrambler.h b/tv/tuner/1.0/default/Descrambler.h
new file mode 100644
index 0000000..2ec8412
--- /dev/null
+++ b/tv/tuner/1.0/default/Descrambler.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2019 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_HARDWARE_TV_TUNER_V1_0_DESCRAMBLER_H_
+#define ANDROID_HARDWARE_TV_TUNER_V1_0_DESCRAMBLER_H_
+
+#include <android/hardware/tv/tuner/1.0/IDescrambler.h>
+#include <android/hardware/tv/tuner/1.0/ITuner.h>
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::tv::tuner::V1_0::IDescrambler;
+using ::android::hardware::tv::tuner::V1_0::Result;
+
+class Descrambler : public IDescrambler {
+  public:
+    Descrambler();
+
+    virtual Return<Result> setDemuxSource(uint32_t demuxId) override;
+
+    virtual Return<Result> close() override;
+
+  private:
+    virtual ~Descrambler();
+    uint32_t mSourceDemuxId;
+    bool mDemuxSet = false;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace tuner
+}  // namespace tv
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_TV_TUNER_V1_DESCRAMBLER_H_
diff --git a/tv/tuner/1.0/default/Tuner.cpp b/tv/tuner/1.0/default/Tuner.cpp
index 67ec754..68b3436 100644
--- a/tv/tuner/1.0/default/Tuner.cpp
+++ b/tv/tuner/1.0/default/Tuner.cpp
@@ -19,6 +19,8 @@
 #include "Tuner.h"
 #include <android/hardware/tv/tuner/1.0/IFrontendCallback.h>
 #include <utils/Log.h>
+#include "Demux.h"
+#include "Descrambler.h"
 #include "Frontend.h"
 
 namespace android {
@@ -28,6 +30,8 @@
 namespace V1_0 {
 namespace implementation {
 
+using ::android::hardware::tv::tuner::V1_0::DemuxId;
+
 Tuner::Tuner() {
     // Static Frontends array to maintain local frontends information
     // Array index matches their FrontendId in the default impl
@@ -71,6 +75,26 @@
     return Void();
 }
 
+Return<void> Tuner::openDemux(openDemux_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    DemuxId demuxId = mLastUsedId + 1;
+    mLastUsedId += 1;
+    sp<IDemux> demux = new Demux(demuxId);
+
+    _hidl_cb(Result::SUCCESS, demuxId, demux);
+    return Void();
+}
+
+Return<void> Tuner::openDescrambler(openDescrambler_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    sp<IDescrambler> descrambler = new Descrambler();
+
+    _hidl_cb(Result::SUCCESS, descrambler);
+    return Void();
+}
+
 }  // namespace implementation
 }  // namespace V1_0
 }  // namespace tuner
diff --git a/tv/tuner/1.0/default/Tuner.h b/tv/tuner/1.0/default/Tuner.h
index 2152c89..12e9594 100644
--- a/tv/tuner/1.0/default/Tuner.h
+++ b/tv/tuner/1.0/default/Tuner.h
@@ -37,12 +37,19 @@
     virtual Return<void> openFrontendById(uint32_t frontendId,
                                           openFrontendById_cb _hidl_cb) override;
 
+    virtual Return<void> openDemux(openDemux_cb _hidl_cb) override;
+
+    virtual Return<void> openDescrambler(openDescrambler_cb _hidl_cb) override;
+
   private:
     virtual ~Tuner();
     // Static mFrontends array to maintain local frontends information
     vector<sp<Frontend>> mFrontends;
     // To maintain how many Frontends we have
     int mFrontendSize;
+    // The last used demux id. Initial value is -1.
+    // First used id will be 0.
+    int mLastUsedId = -1;
 };
 
 }  // namespace implementation
diff --git a/tv/tuner/1.0/types.hal b/tv/tuner/1.0/types.hal
index 1ca7fda..3fa9641 100644
--- a/tv/tuner/1.0/types.hal
+++ b/tv/tuner/1.0/types.hal
@@ -137,3 +137,53 @@
      */
     LOST_LOCK,
 };
+
+/* Demux ID is used to associate with a hardware demux resource. */
+typedef uint32_t DemuxId;
+
+/* Filter ID is used to associate with a hardware filter resource. */
+typedef uint32_t DemuxFilterId;
+
+/**
+ * Filter Type according to ISO/IEC 13818-1
+ */
+@export
+enum DemuxFilterType : uint32_t {
+    /**
+     * A filter to filter section data out from input stream.
+     */
+    SECTION,
+    /**
+     * A filter to filter PES data out from input stream.
+     */
+    PES,
+    /**
+     * A filter to filter TS payload out from input stream.
+     */
+    TS,
+    /**
+     * A filter to filter Audio Metadata out from input stream.
+     */
+    AUDIO,
+    /**
+     * A filter to filter Vidoe Metadata out from input stream.
+     */
+    VIDEO,
+    /**
+     * A filter to set PCR channel from input stream.
+     */
+    PCR,
+    /**
+     * A filter to filter data directly to output buffer for record.
+     */
+    RECORD,
+};
+
+/**
+ * Filter Event.
+ */
+struct DemuxFilterEvent {
+     DemuxFilterId filterId;
+     DemuxFilterType filterType;
+};
+
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index 4840a02..c652944 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -19,6 +19,9 @@
 #include <VtsHalHidlTargetTestBase.h>
 #include <VtsHalHidlTargetTestEnvBase.h>
 #include <android-base/logging.h>
+#include <android/hardware/tv/tuner/1.0/IDemux.h>
+#include <android/hardware/tv/tuner/1.0/IDemuxCallback.h>
+#include <android/hardware/tv/tuner/1.0/IDescrambler.h>
 #include <android/hardware/tv/tuner/1.0/IFrontend.h>
 #include <android/hardware/tv/tuner/1.0/IFrontendCallback.h>
 #include <android/hardware/tv/tuner/1.0/ITuner.h>
@@ -52,6 +55,9 @@
 using android::hardware::tv::tuner::V1_0::FrontendId;
 using android::hardware::tv::tuner::V1_0::FrontendInnerFec;
 using android::hardware::tv::tuner::V1_0::FrontendSettings;
+using android::hardware::tv::tuner::V1_0::IDemux;
+using android::hardware::tv::tuner::V1_0::IDemuxCallback;
+using android::hardware::tv::tuner::V1_0::IDescrambler;
 using android::hardware::tv::tuner::V1_0::IFrontend;
 using android::hardware::tv::tuner::V1_0::IFrontendCallback;
 using android::hardware::tv::tuner::V1_0::ITuner;
@@ -146,11 +152,19 @@
 
     sp<IFrontend> mFrontend;
     sp<FrontendCallback> mFrontendCallback;
+    sp<IDescrambler> mDescrambler;
+    sp<IDemux> mDemux;
+    uint32_t mDemuxId;
 
     ::testing::AssertionResult createFrontend(int32_t frontendId);
     ::testing::AssertionResult tuneFrontend(int32_t frontendId);
     ::testing::AssertionResult stopTuneFrontend(int32_t frontendId);
     ::testing::AssertionResult closeFrontend(int32_t frontendId);
+    ::testing::AssertionResult createDemux();
+    ::testing::AssertionResult createDemuxWithFrontend(int32_t frontendId);
+    ::testing::AssertionResult closeDemux();
+    ::testing::AssertionResult createDescrambler();
+    ::testing::AssertionResult closeDescrambler();
 };
 
 ::testing::AssertionResult TunerHidlTest::createFrontend(int32_t frontendId) {
@@ -215,6 +229,78 @@
     return ::testing::AssertionResult(status == Result::SUCCESS);
 }
 
+::testing::AssertionResult TunerHidlTest::createDemux() {
+    Result status;
+
+    mService->openDemux([&](Result result, uint32_t demuxId, const sp<IDemux>& demux) {
+        mDemux = demux;
+        mDemuxId = demuxId;
+        status = result;
+    });
+    return ::testing::AssertionResult(status == Result::SUCCESS);
+}
+
+::testing::AssertionResult TunerHidlTest::createDemuxWithFrontend(int32_t frontendId) {
+    Result status;
+
+    if (createDemux() == ::testing::AssertionFailure()) {
+        return ::testing::AssertionFailure();
+    }
+
+    if (createFrontend(frontendId) == ::testing::AssertionFailure()) {
+        return ::testing::AssertionFailure();
+    }
+
+    status = mDemux->setFrontendDataSource(frontendId);
+
+    return ::testing::AssertionResult(status == Result::SUCCESS);
+}
+
+::testing::AssertionResult TunerHidlTest::closeDemux() {
+    Result status;
+    if (createDemux() == ::testing::AssertionFailure()) {
+        return ::testing::AssertionFailure();
+    }
+
+    status = mDemux->close();
+    return ::testing::AssertionResult(status == Result::SUCCESS);
+}
+
+::testing::AssertionResult TunerHidlTest::createDescrambler() {
+    Result status;
+
+    mService->openDescrambler([&](Result result, const sp<IDescrambler>& descrambler) {
+        mDescrambler = descrambler;
+        status = result;
+    });
+    if (status != Result::SUCCESS) {
+        return ::testing::AssertionFailure();
+    }
+
+    if (createDemux() == ::testing::AssertionFailure()) {
+        return ::testing::AssertionFailure();
+    }
+
+    status = mDescrambler->setDemuxSource(mDemuxId);
+    if (status != Result::SUCCESS) {
+        return ::testing::AssertionFailure();
+    }
+
+    // Test if demux source can be set more than once.
+    status = mDescrambler->setDemuxSource(mDemuxId);
+    return ::testing::AssertionResult(status == Result::INVALID_STATE);
+}
+
+::testing::AssertionResult TunerHidlTest::closeDescrambler() {
+    Result status;
+    if (createDescrambler() == ::testing::AssertionFailure()) {
+        return ::testing::AssertionFailure();
+    }
+
+    status = mDescrambler->close();
+    return ::testing::AssertionResult(status == Result::SUCCESS);
+}
+
 TEST_F(TunerHidlTest, CreateFrontend) {
     Result status;
     hidl_vec<FrontendId> feIds;
@@ -295,6 +381,50 @@
     }
 }
 
+TEST_F(TunerHidlTest, CreateDemux) {
+    description("Create Demux");
+
+    ASSERT_TRUE(createDemux());
+}
+
+TEST_F(TunerHidlTest, CreateDemuxWithFrontend) {
+    Result status;
+    hidl_vec<FrontendId> feIds;
+
+    description("Create Demux with Frontend");
+    mService->getFrontendIds([&](Result result, const hidl_vec<FrontendId>& frontendIds) {
+        status = result;
+        feIds = frontendIds;
+    });
+
+    if (feIds.size() == 0) {
+        ALOGW("[   WARN   ] Frontend isn't available");
+        return;
+    }
+
+    for (size_t i = 0; i < feIds.size(); i++) {
+        ASSERT_TRUE(createDemuxWithFrontend(feIds[i]));
+    }
+}
+
+TEST_F(TunerHidlTest, CloseDemux) {
+    description("Close Demux");
+
+    ASSERT_TRUE(closeDemux());
+}
+
+TEST_F(TunerHidlTest, CreateDescrambler) {
+    description("Create Descrambler");
+
+    ASSERT_TRUE(createDescrambler());
+}
+
+TEST_F(TunerHidlTest, CloseDescrambler) {
+    description("Close Descrambler");
+
+    ASSERT_TRUE(closeDescrambler());
+}
+
 }  // namespace
 
 int main(int argc, char** argv) {