Merge "Lights: parameterized VTS tests."
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index a6bd29a..67ec149 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -4066,75 +4066,61 @@
*
* This test checks that if rollback protection is implemented, DeleteKey invalidates a formerly
* valid key blob.
- *
- * TODO(swillden): Update to incorporate changes in rollback resistance semantics.
*/
TEST_F(KeyDeletionTest, DeleteKey) {
- ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(2048, 65537)
- .Digest(Digest::NONE)
- .Padding(PaddingMode::NONE)
- .Authorization(TAG_NO_AUTH_REQUIRED)));
+ auto error = GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(2048, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .Authorization(TAG_ROLLBACK_RESISTANCE));
+ ASSERT_TRUE(error == ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE || error == ErrorCode::OK);
// Delete must work if rollback protection is implemented
- AuthorizationSet hardwareEnforced(key_characteristics_.hardwareEnforced);
- bool rollback_protected = hardwareEnforced.Contains(TAG_ROLLBACK_RESISTANCE);
+ if (error == ErrorCode::OK) {
+ AuthorizationSet hardwareEnforced(key_characteristics_.hardwareEnforced);
+ ASSERT_TRUE(hardwareEnforced.Contains(TAG_ROLLBACK_RESISTANCE));
- if (rollback_protected) {
ASSERT_EQ(ErrorCode::OK, DeleteKey(true /* keep key blob */));
- } else {
- auto delete_result = DeleteKey(true /* keep key blob */);
- ASSERT_TRUE(delete_result == ErrorCode::OK | delete_result == ErrorCode::UNIMPLEMENTED);
- }
- string message = "12345678901234567890123456789012";
- AuthorizationSet begin_out_params;
-
- if (rollback_protected) {
+ string message = "12345678901234567890123456789012";
+ AuthorizationSet begin_out_params;
EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
Begin(KeyPurpose::SIGN, key_blob_,
AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE),
&begin_out_params, &op_handle_));
- } else {
- EXPECT_EQ(ErrorCode::OK,
- Begin(KeyPurpose::SIGN, key_blob_,
- AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE),
- &begin_out_params, &op_handle_));
+ AbortIfNeeded();
+ key_blob_ = HidlBuf();
}
- AbortIfNeeded();
- key_blob_ = HidlBuf();
}
/**
* KeyDeletionTest.DeleteInvalidKey
*
- * This test checks that the HAL excepts invalid key blobs.
- *
- * TODO(swillden): Update to incorporate changes in rollback resistance semantics.
+ * This test checks that the HAL excepts invalid key blobs..
*/
TEST_F(KeyDeletionTest, DeleteInvalidKey) {
// Generate key just to check if rollback protection is implemented
- ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(2048, 65537)
- .Digest(Digest::NONE)
- .Padding(PaddingMode::NONE)
- .Authorization(TAG_NO_AUTH_REQUIRED)));
+ auto error = GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(2048, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .Authorization(TAG_ROLLBACK_RESISTANCE));
+ ASSERT_TRUE(error == ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE || error == ErrorCode::OK);
// Delete must work if rollback protection is implemented
- AuthorizationSet hardwareEnforced(key_characteristics_.hardwareEnforced);
- bool rollback_protected = hardwareEnforced.Contains(TAG_ROLLBACK_RESISTANCE);
+ if (error == ErrorCode::OK) {
+ AuthorizationSet hardwareEnforced(key_characteristics_.hardwareEnforced);
+ ASSERT_TRUE(hardwareEnforced.Contains(TAG_ROLLBACK_RESISTANCE));
- // Delete the key we don't care about the result at this point.
- DeleteKey();
+ // Delete the key we don't care about the result at this point.
+ DeleteKey();
- // Now create an invalid key blob and delete it.
- key_blob_ = HidlBuf("just some garbage data which is not a valid key blob");
+ // Now create an invalid key blob and delete it.
+ key_blob_ = HidlBuf("just some garbage data which is not a valid key blob");
- if (rollback_protected) {
ASSERT_EQ(ErrorCode::OK, DeleteKey());
- } else {
- auto delete_result = DeleteKey();
- ASSERT_TRUE(delete_result == ErrorCode::OK | delete_result == ErrorCode::UNIMPLEMENTED);
}
}
@@ -4148,39 +4134,34 @@
* device has been wiped manually (e.g., fastboot flashall -w), and new FBE/FDE keys have
* been provisioned. Use this test only on dedicated testing devices that have no valuable
* credentials stored in Keystore/Keymaster.
- *
- * TODO(swillden): Update to incorporate changes in rollback resistance semantics.
*/
TEST_F(KeyDeletionTest, DeleteAllKeys) {
if (!arm_deleteAllKeys) return;
- ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
- .RsaSigningKey(2048, 65537)
- .Digest(Digest::NONE)
- .Padding(PaddingMode::NONE)
- .Authorization(TAG_NO_AUTH_REQUIRED)));
+ auto error = GenerateKey(AuthorizationSetBuilder()
+ .RsaSigningKey(2048, 65537)
+ .Digest(Digest::NONE)
+ .Padding(PaddingMode::NONE)
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .Authorization(TAG_ROLLBACK_RESISTANCE));
+ ASSERT_TRUE(error == ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE || error == ErrorCode::OK);
// Delete must work if rollback protection is implemented
- AuthorizationSet hardwareEnforced(key_characteristics_.hardwareEnforced);
- bool rollback_protected = hardwareEnforced.Contains(TAG_ROLLBACK_RESISTANCE);
+ if (error == ErrorCode::OK) {
+ AuthorizationSet hardwareEnforced(key_characteristics_.hardwareEnforced);
+ ASSERT_TRUE(hardwareEnforced.Contains(TAG_ROLLBACK_RESISTANCE));
- ASSERT_EQ(ErrorCode::OK, DeleteAllKeys());
+ ASSERT_EQ(ErrorCode::OK, DeleteAllKeys());
- string message = "12345678901234567890123456789012";
- AuthorizationSet begin_out_params;
+ string message = "12345678901234567890123456789012";
+ AuthorizationSet begin_out_params;
- if (rollback_protected) {
EXPECT_EQ(ErrorCode::INVALID_KEY_BLOB,
Begin(KeyPurpose::SIGN, key_blob_,
AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE),
&begin_out_params, &op_handle_));
- } else {
- EXPECT_EQ(ErrorCode::OK,
- Begin(KeyPurpose::SIGN, key_blob_,
- AuthorizationSetBuilder().Digest(Digest::NONE).Padding(PaddingMode::NONE),
- &begin_out_params, &op_handle_));
+ AbortIfNeeded();
+ key_blob_ = HidlBuf();
}
- AbortIfNeeded();
- key_blob_ = HidlBuf();
}
using UpgradeKeyTest = KeymasterHidlTest;
diff --git a/tv/tuner/1.0/Android.bp b/tv/tuner/1.0/Android.bp
new file mode 100644
index 0000000..b54413d
--- /dev/null
+++ b/tv/tuner/1.0/Android.bp
@@ -0,0 +1,20 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.tv.tuner@1.0",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "types.hal",
+ "IFrontend.hal",
+ "IFrontendCallback.hal",
+ "ITuner.hal",
+ ],
+ interfaces: [
+ "android.hidl.base@1.0",
+ ],
+ gen_java: false,
+ gen_java_constants: true,
+}
diff --git a/tv/tuner/1.0/IFrontend.hal b/tv/tuner/1.0/IFrontend.hal
new file mode 100644
index 0000000..05cee91
--- /dev/null
+++ b/tv/tuner/1.0/IFrontend.hal
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+package android.hardware.tv.tuner@1.0;
+
+import IFrontendCallback;
+
+/**
+ * A Tuner Frontend is used to tune to a frequency and lock signal. It provide
+ * live data feed to Tuner Demux interface.
+ */
+interface IFrontend {
+ /**
+ * Set the callback
+ *
+ * It is used by the client to receive events from the Frontend.
+ * Only one callback for one Frontend instance is supported. The callback
+ * will be replaced if it's set again.
+ *
+ * @param callback Callback object to pass Frontend events to the system.
+ * The previously registered callback must be replaced with this one.
+ * It can be null.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if callback can't be set at current stage,
+ * UNKNOWN_ERROR if callback setting failed for other reasons.
+ */
+ setCallback(IFrontendCallback callback) generates (Result result);
+
+ /**
+ * Tuning Frontend
+ *
+ * It is used by the client to lock a frequency by providing signal
+ * delivery information. If previous tuning isn't completed, this call must
+ * stop previous tuning, and start a new tuning. Tune is a async call.
+ * LOCKED or NO_SIGNAL eventi is sent back to caller through callback.
+ *
+ * @param settings Signal delivery information which frontend can use to
+ * search and lock the signal.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if tuning can't be applied at current stage,
+ * UNKNOWN_ERROR if tuning failed for other reasons.
+ */
+ tune(FrontendSettings settings) generates (Result result);
+
+ /**
+ * Stop the tuning
+ *
+ * It is used by the client to stop a previous tuning.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successfully stop tuning.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ stopTune() generates (Result result);
+
+ /**
+ * Release the Frontend instance
+ *
+ * It is used by the client to release the frontend 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/IFrontendCallback.hal b/tv/tuner/1.0/IFrontendCallback.hal
new file mode 100644
index 0000000..e907049
--- /dev/null
+++ b/tv/tuner/1.0/IFrontendCallback.hal
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+package android.hardware.tv.tuner@1.0;
+
+interface IFrontendCallback {
+ /**
+ * Notify the client that a new event happened on the frontend.
+ *
+ * @param frontendEventType the event type.
+ */
+ oneway onEvent(FrontendEventType frontendEventType);
+
+ /**
+ * The callback function that must be called by HAL implementation to notify
+ * the client of new DiSEqC message.
+ *
+ * @param diseqcMessage a byte array of data for DiSEqC (Digital Satellite
+ * Equipment Control) message which is specified by EUTELSAT Bus Functional
+ * Specification Version 4.2.
+ */
+ oneway onDiseqcMessage(vec<uint8_t> diseqcMessage);
+};
+
diff --git a/tv/tuner/1.0/ITuner.hal b/tv/tuner/1.0/ITuner.hal
new file mode 100644
index 0000000..5a5f547
--- /dev/null
+++ b/tv/tuner/1.0/ITuner.hal
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+package android.hardware.tv.tuner@1.0;
+
+import IFrontend;
+
+/**
+ * Top level interface to manage Frontend, Demux and Decrambler hardware
+ * resouces which are needed for Android TV.
+ */
+interface ITuner {
+ /**
+ * Get Frontend IDs
+ *
+ * It is used by the client to get all available frontends' IDs.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * UNKNOWN_ERROR if tuning failed for other reasons.
+ * @return frontendIds an array of FrontendId for the available frontends.
+ */
+ getFrontendIds() generates (Result result, vec<FrontendId> frontendIds);
+
+ /**
+ * Create a new instance of Frontend given a frontendId.
+ *
+ * It is used by the client to create a frontend instance.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * UNKNOWN_ERROR if creation failed for other reasons.
+ * @return frontend the newly created frontend interface.
+ */
+ openFrontendById(FrontendId frontendId)
+ generates (Result result, IFrontend frontend);
+
+};
+
diff --git a/tv/tuner/1.0/default/Android.bp b/tv/tuner/1.0/default/Android.bp
new file mode 100644
index 0000000..cc8d1f5
--- /dev/null
+++ b/tv/tuner/1.0/default/Android.bp
@@ -0,0 +1,43 @@
+cc_defaults {
+ name: "tuner_service_defaults",
+ defaults: ["hidl_defaults"],
+ vendor: true,
+ relative_install_path: "hw",
+ srcs: [
+ "Frontend.cpp",
+ "Tuner.cpp",
+ "service.cpp",
+ ],
+
+ compile_multilib: "first",
+
+ shared_libs: [
+ "android.hardware.tv.tuner@1.0",
+ "android.hidl.memory@1.0",
+ "libhidlbase",
+ "libhidlmemory",
+ "libhidltransport",
+ "liblog",
+ "libstagefright_foundation",
+ "libutils",
+ ],
+ header_libs: [
+ "media_plugin_headers",
+ ],
+}
+
+cc_binary {
+ name: "android.hardware.tv.tuner@1.0-service",
+ vintf_fragments: ["android.hardware.tv.tuner@1.0-service.xml"],
+ defaults: ["tuner_service_defaults"],
+ init_rc: ["android.hardware.tv.tuner@1.0-service.rc"],
+}
+
+cc_binary {
+ name: "android.hardware.tv.tuner@1.0-service-lazy",
+ vintf_fragments: ["android.hardware.tv.tuner@1.0-service-lazy.xml"],
+ overrides: ["android.hardware.tv.tuner@1.0-service"],
+ defaults: ["tuner_service_defaults"],
+ init_rc: ["android.hardware.tv.tuner@1.0-service-lazy.rc"],
+ cflags: ["-DLAZY_SERVICE"],
+}
diff --git a/tv/tuner/1.0/default/Frontend.cpp b/tv/tuner/1.0/default/Frontend.cpp
new file mode 100644
index 0000000..3dcc2b1
--- /dev/null
+++ b/tv/tuner/1.0/default/Frontend.cpp
@@ -0,0 +1,93 @@
+/*
+ * 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-Frontend"
+
+#include "Frontend.h"
+#include <android/hardware/tv/tuner/1.0/IFrontendCallback.h>
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+Frontend::Frontend() {
+ // Init callback to nullptr
+ mCallback = nullptr;
+}
+
+Frontend::Frontend(FrontendType type, FrontendId id) {
+ mType = type;
+ mId = id;
+ // Init callback to nullptr
+ mCallback = nullptr;
+}
+
+Frontend::~Frontend() {}
+
+Return<Result> Frontend::close() {
+ ALOGV("%s", __FUNCTION__);
+ // Reset callback
+ mCallback = nullptr;
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Frontend::setCallback(const sp<IFrontendCallback>& callback) {
+ ALOGV("%s", __FUNCTION__);
+ if (callback == nullptr) {
+ ALOGW("[ WARN ] Set Frontend callback with nullptr");
+ return Result::INVALID_ARGUMENT;
+ }
+
+ mCallback = callback;
+ return Result::SUCCESS;
+}
+
+Return<Result> Frontend::tune(const FrontendSettings& /* settings */) {
+ ALOGV("%s", __FUNCTION__);
+ if (mCallback == nullptr) {
+ ALOGW("[ WARN ] Frontend callback is not set when tune");
+ return Result::INVALID_STATE;
+ }
+
+ mCallback->onEvent(FrontendEventType::NO_SIGNAL);
+ return Result::SUCCESS;
+}
+
+Return<Result> Frontend::stopTune() {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+FrontendType Frontend::getFrontendType() {
+ return mType;
+}
+
+FrontendId Frontend::getFrontendId() {
+ return mId;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace tuner
+} // namespace tv
+} // namespace hardware
+} // namespace android
diff --git a/tv/tuner/1.0/default/Frontend.h b/tv/tuner/1.0/default/Frontend.h
new file mode 100644
index 0000000..f77a0d8
--- /dev/null
+++ b/tv/tuner/1.0/default/Frontend.h
@@ -0,0 +1,69 @@
+/*
+ * 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_FRONTEND_H_
+#define ANDROID_HARDWARE_TV_TUNER_V1_0_FRONTEND_H_
+
+#include <android/hardware/tv/tuner/1.0/IFrontend.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::FrontendId;
+using ::android::hardware::tv::tuner::V1_0::FrontendType;
+using ::android::hardware::tv::tuner::V1_0::IFrontend;
+using ::android::hardware::tv::tuner::V1_0::IFrontendCallback;
+using ::android::hardware::tv::tuner::V1_0::Result;
+
+class Frontend : public IFrontend {
+ public:
+ Frontend();
+ Frontend(FrontendType type, FrontendId id);
+
+ virtual Return<Result> close() override;
+
+ virtual Return<Result> setCallback(const sp<IFrontendCallback>& callback) override;
+
+ virtual Return<Result> tune(const FrontendSettings& settings) override;
+
+ virtual Return<Result> stopTune() override;
+
+ FrontendType getFrontendType();
+
+ FrontendId getFrontendId();
+
+ private:
+ virtual ~Frontend();
+ sp<IFrontendCallback> mCallback;
+ FrontendType mType = FrontendType::UNDEFINED;
+ FrontendId mId = 0;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace tuner
+} // namespace tv
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_TV_TUNER_V1_0_FRONTEND_H_
diff --git a/tv/tuner/1.0/default/Tuner.cpp b/tv/tuner/1.0/default/Tuner.cpp
new file mode 100644
index 0000000..67ec754
--- /dev/null
+++ b/tv/tuner/1.0/default/Tuner.cpp
@@ -0,0 +1,79 @@
+/*
+ * 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-Tuner"
+
+#include "Tuner.h"
+#include <android/hardware/tv/tuner/1.0/IFrontendCallback.h>
+#include <utils/Log.h>
+#include "Frontend.h"
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+Tuner::Tuner() {
+ // Static Frontends array to maintain local frontends information
+ // Array index matches their FrontendId in the default impl
+ mFrontendSize = 8;
+ mFrontends.resize(mFrontendSize);
+ mFrontends[0] = new Frontend();
+ mFrontends[1] = new Frontend(FrontendType::ATSC, 1);
+ mFrontends[2] = new Frontend(FrontendType::DVBC, 2);
+ mFrontends[3] = new Frontend(FrontendType::DVBS, 3);
+ mFrontends[4] = new Frontend(FrontendType::DVBT, 4);
+ mFrontends[5] = new Frontend(FrontendType::ISDBT, 5);
+ mFrontends[6] = new Frontend(FrontendType::ANALOG, 6);
+ mFrontends[7] = new Frontend(FrontendType::ATSC, 7);
+}
+
+Tuner::~Tuner() {}
+
+Return<void> Tuner::getFrontendIds(getFrontendIds_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ vector<FrontendId> frontendIds;
+ frontendIds.resize(mFrontendSize);
+ for (int i = 0; i < mFrontendSize; i++) {
+ frontendIds[i] = mFrontends[i]->getFrontendId();
+ }
+
+ _hidl_cb(Result::SUCCESS, frontendIds);
+ return Void();
+}
+
+Return<void> Tuner::openFrontendById(uint32_t frontendId, openFrontendById_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ if (frontendId >= mFrontendSize || frontendId < 0) {
+ ALOGW("[ WARN ] Frontend with id %d isn't available", frontendId);
+ _hidl_cb(Result::UNAVAILABLE, nullptr);
+ return Void();
+ }
+
+ _hidl_cb(Result::SUCCESS, mFrontends[frontendId]);
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace tuner
+} // namespace tv
+} // namespace hardware
+} // namespace android
diff --git a/tv/tuner/1.0/default/Tuner.h b/tv/tuner/1.0/default/Tuner.h
new file mode 100644
index 0000000..2152c89
--- /dev/null
+++ b/tv/tuner/1.0/default/Tuner.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_TUNER_H_
+#define ANDROID_HARDWARE_TV_TUNER_V1_0_TUNER_H_
+
+#include <android/hardware/tv/tuner/1.0/ITuner.h>
+#include "Frontend.h"
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+class Tuner : public ITuner {
+ public:
+ Tuner();
+ virtual Return<void> getFrontendIds(getFrontendIds_cb _hidl_cb) override;
+
+ virtual Return<void> openFrontendById(uint32_t frontendId,
+ openFrontendById_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;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace tuner
+} // namespace tv
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_TV_TUNER_V1_0_TUNER_H_
diff --git a/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service-lazy.rc b/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service-lazy.rc
new file mode 100644
index 0000000..ad72fae
--- /dev/null
+++ b/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service-lazy.rc
@@ -0,0 +1,9 @@
+service vendor.tuner-hal-1-0 /vendor/bin/hw/android.hardware.tv.tuner@1.0-service-lazy
+ interface android.hardware.tv.tuner@1.0::ITuner default
+ oneshot
+ disabled
+ class hal
+ user media
+ group mediadrm drmrpc
+ ioprio rt 4
+ writepid /dev/cpuset/foreground/tasks
\ No newline at end of file
diff --git a/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service-lazy.xml b/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service-lazy.xml
new file mode 100644
index 0000000..4bcfe10
--- /dev/null
+++ b/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service-lazy.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.tv.tuner</name>
+ <transport>hwbinder</transport>
+ <version>1.0</version>
+ <interface>
+ <name>ITuner</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
\ No newline at end of file
diff --git a/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service.rc b/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service.rc
new file mode 100644
index 0000000..6d59ed7
--- /dev/null
+++ b/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service.rc
@@ -0,0 +1,6 @@
+service vendor.tuner-hal-1-0 /vendor/bin/hw/android.hardware.tv.tuner@1.0-service
+ class hal
+ user media
+ group mediadrm drmrpc
+ ioprio rt 4
+ writepid /dev/cpuset/foreground/tasks
\ No newline at end of file
diff --git a/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service.xml b/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service.xml
new file mode 100644
index 0000000..4bcfe10
--- /dev/null
+++ b/tv/tuner/1.0/default/android.hardware.tv.tuner@1.0-service.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.tv.tuner</name>
+ <transport>hwbinder</transport>
+ <version>1.0</version>
+ <interface>
+ <name>ITuner</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
\ No newline at end of file
diff --git a/tv/tuner/1.0/default/service.cpp b/tv/tuner/1.0/default/service.cpp
new file mode 100644
index 0000000..581d269
--- /dev/null
+++ b/tv/tuner/1.0/default/service.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright 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_NDEBUG 0
+#ifdef LAZY_SERVICE
+#define LOG_TAG "android.hardware.tv.tuner@1.0-service-lazy"
+#else
+#define LOG_TAG "android.hardware.tv.tuner@1.0-service"
+#endif
+
+#include <binder/ProcessState.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/LegacySupport.h>
+
+#include "Tuner.h"
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::LazyServiceRegistrar;
+using android::hardware::tv::tuner::V1_0::ITuner;
+using android::hardware::tv::tuner::V1_0::implementation::Tuner;
+
+#ifdef LAZY_SERVICE
+const bool kLazyService = true;
+#else
+const bool kLazyService = false;
+#endif
+
+int main() {
+ configureRpcThreadpool(8, true /* callerWillJoin */);
+
+ // Setup hwbinder service
+ android::sp<ITuner> service = new Tuner();
+ android::status_t status;
+ if (kLazyService) {
+ auto serviceRegistrar = std::make_shared<LazyServiceRegistrar>();
+ status = serviceRegistrar->registerService(service);
+ } else {
+ status = service->registerAsService();
+ }
+ LOG_ALWAYS_FATAL_IF(status != android::OK, "Error while registering tuner service: %d", status);
+
+ joinRpcThreadpool();
+ return 0;
+}
diff --git a/tv/tuner/1.0/types.hal b/tv/tuner/1.0/types.hal
new file mode 100644
index 0000000..1ca7fda
--- /dev/null
+++ b/tv/tuner/1.0/types.hal
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+
+package android.hardware.tv.tuner@1.0;
+
+import android.hidl.safe_union@1.0;
+
+@export
+enum Result : int32_t {
+ SUCCESS,
+ UNAVAILABLE,
+ NOT_INITIALIZED,
+ INVALID_STATE,
+ INVALID_ARGUMENT,
+ OUT_OF_MEMORY,
+ UNKNOWN_ERROR,
+};
+
+/**
+ * Frontend ID.
+ */
+typedef uint32_t FrontendId;
+
+/**
+ * Frontend Types.
+ */
+@export
+enum FrontendType : uint32_t {
+ UNDEFINED = 0,
+ ANALOG,
+ ATSC,
+ DVBC,
+ DVBS,
+ DVBT,
+ ISDBT,
+};
+
+/**
+ * Inner Forward Error Correction type as specified in ETSI EN 300 468 V1.15.1
+ * It's a 4-bit field specifying the inner FEC scheme used according to the
+ * table 35 in the spec.
+ */
+@export
+enum FrontendInnerFec : uint32_t {
+ /* Not defined */
+ FEC_UNDEFINED = 0,
+ /* 1/2 conv. code rate */
+ FEC_1_2 = 1 << 0,
+ /* 2/3 conv. code rate */
+ FEC_2_3 = 1 << 1,
+ /* 3/4 conv. code rate */
+ FEC_3_4 = 1 << 2,
+ /* 5/6 conv. code rate */
+ FEC_5_6 = 1 << 3,
+ /* 7/8 conv. code rate */
+ FEC_7_8 = 1 << 4,
+ /* 8/9 conv. code rate */
+ FEC_8_9 = 1 << 5,
+ /* 3/5 conv. code rate */
+ FEC_3_5 = 1 << 6,
+ /* 4/5 conv. code rate */
+ FEC_4_5 = 1 << 7,
+ /* 9/10 conv. code rate */
+ FEC_9_10 = 1 << 8,
+ /* hardware is able to detect and set FEC automatically */
+ FEC_AUTO = 1 << 9,
+};
+
+/**
+ * Modulation Type for ATSC.
+ */
+@export
+enum FrontendAtscModulation : uint32_t {
+ UNDEFINED = 0,
+ MOD_8VSB = 1 << 0,
+ MOD_16VSB = 1 << 1,
+};
+
+/**
+ * Signal Setting for ATSC Frontend.
+ */
+struct FrontendAtscSettings {
+ /** Signal frequencey in Herhz */
+ uint32_t frequency;
+ FrontendAtscModulation modulation;
+};
+
+/**
+ * Signal Setting for DVBT Frontend.
+ */
+struct FrontendDvbtSettings {
+ /** Signal frequencey in Herhz */
+ uint32_t frequency;
+ FrontendAtscModulation modulation;
+ FrontendInnerFec fec;
+};
+
+/**
+ * Modulation Type for ATSC.
+ */
+safe_union FrontendSettings {
+ FrontendAtscSettings atsc;
+ FrontendDvbtSettings dvbt;
+};
+
+/**
+ * Frontend Event Type.
+ */
+@export
+enum FrontendEventType : uint32_t {
+ /**
+ * If frontend locked the signal which is specified by tune method, HAL sent
+ * Locked event.
+ */
+ LOCKED,
+ /**
+ * If frontend can't locked the signal which is specified by tune method,
+ * HAL sent NO_SIGNAL event.
+ */
+ NO_SIGNAL,
+ /**
+ * If frontend detect that the locked signal get lost, HAL sent LOST_LOCK
+ * event.
+ */
+ LOST_LOCK,
+};
diff --git a/tv/tuner/1.0/vts/functional/Android.bp b/tv/tuner/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..faf566c
--- /dev/null
+++ b/tv/tuner/1.0/vts/functional/Android.bp
@@ -0,0 +1,32 @@
+//
+// 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.
+//
+
+cc_test {
+ name: "VtsHalTvTunerV1_0TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: ["VtsHalTvTunerV1_0TargetTest.cpp"],
+ static_libs: [
+ "android.hardware.tv.tuner@1.0",
+ "android.hidl.allocator@1.0",
+ "android.hidl.memory@1.0",
+ "libhidlallocatorutils",
+ "libhidlmemory",
+ ],
+ shared_libs: [
+ "libbinder",
+ ],
+ test_suites: ["general-tests"],
+}
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
new file mode 100644
index 0000000..4840a02
--- /dev/null
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -0,0 +1,307 @@
+/*
+ * 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 "Tuner_hidl_hal_test"
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
+#include <android-base/logging.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>
+#include <android/hardware/tv/tuner/1.0/types.h>
+#include <binder/MemoryDealer.h>
+#include <hidl/HidlSupport.h>
+#include <hidl/HidlTransportSupport.h>
+#include <hidl/Status.h>
+#include <hidlmemory/FrameworkUtils.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
+
+#define WAIT_TIMEOUT 3000000000
+
+using android::Condition;
+using android::IMemory;
+using android::IMemoryHeap;
+using android::MemoryDealer;
+using android::Mutex;
+using android::sp;
+using android::hardware::fromHeap;
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
+using android::hardware::HidlMemory;
+using android::hardware::Return;
+using android::hardware::Void;
+using android::hardware::tv::tuner::V1_0::FrontendAtscModulation;
+using android::hardware::tv::tuner::V1_0::FrontendAtscSettings;
+using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings;
+using android::hardware::tv::tuner::V1_0::FrontendEventType;
+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::IFrontend;
+using android::hardware::tv::tuner::V1_0::IFrontendCallback;
+using android::hardware::tv::tuner::V1_0::ITuner;
+using android::hardware::tv::tuner::V1_0::Result;
+
+namespace {
+
+class FrontendCallback : public IFrontendCallback {
+ public:
+ virtual Return<void> onEvent(FrontendEventType frontendEventType) override {
+ android::Mutex::Autolock autoLock(mMsgLock);
+ mEventReceived = true;
+ mEventType = frontendEventType;
+ mMsgCondition.signal();
+ return Void();
+ }
+
+ virtual Return<void> onDiseqcMessage(const hidl_vec<uint8_t>& diseqcMessage) override {
+ android::Mutex::Autolock autoLock(mMsgLock);
+ mDiseqcMessageReceived = true;
+ mEventMessage = diseqcMessage;
+ mMsgCondition.signal();
+ return Void();
+ }
+
+ void testOnEvent(sp<IFrontend>& frontend, FrontendSettings settings);
+ void testOnDiseqcMessage(sp<IFrontend>& frontend, FrontendSettings settings);
+
+ private:
+ bool mEventReceived = false;
+ bool mDiseqcMessageReceived = false;
+ FrontendEventType mEventType;
+ hidl_vec<uint8_t> mEventMessage;
+ android::Mutex mMsgLock;
+ android::Condition mMsgCondition;
+};
+
+void FrontendCallback::testOnEvent(sp<IFrontend>& frontend, FrontendSettings settings) {
+ Result result = frontend->tune(settings);
+
+ EXPECT_TRUE(result == Result::SUCCESS);
+
+ android::Mutex::Autolock autoLock(mMsgLock);
+ while (!mEventReceived) {
+ if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+ EXPECT_TRUE(false) << "event not received within timeout";
+ return;
+ }
+ }
+}
+
+void FrontendCallback::testOnDiseqcMessage(sp<IFrontend>& frontend, FrontendSettings settings) {
+ Result result = frontend->tune(settings);
+
+ EXPECT_TRUE(result == Result::SUCCESS);
+
+ android::Mutex::Autolock autoLock(mMsgLock);
+ while (!mDiseqcMessageReceived) {
+ if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
+ EXPECT_TRUE(false) << "diseqc message not received within timeout";
+ return;
+ }
+ }
+}
+
+// Test environment for Tuner HIDL HAL.
+class TunerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+ public:
+ // get the test environment singleton
+ static TunerHidlEnvironment* Instance() {
+ static TunerHidlEnvironment* instance = new TunerHidlEnvironment;
+ return instance;
+ }
+
+ virtual void registerTestServices() override { registerTestService<ITuner>(); }
+};
+
+class TunerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ public:
+ virtual void SetUp() override {
+ mService = ::testing::VtsHalHidlTargetTestBase::getService<ITuner>(
+ TunerHidlEnvironment::Instance()->getServiceName<ITuner>());
+ ASSERT_NE(mService, nullptr);
+ }
+
+ sp<ITuner> mService;
+
+ protected:
+ static void description(const std::string& description) {
+ RecordProperty("description", description);
+ }
+
+ sp<IFrontend> mFrontend;
+ sp<FrontendCallback> mFrontendCallback;
+
+ ::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 TunerHidlTest::createFrontend(int32_t frontendId) {
+ Result status;
+
+ mService->openFrontendById(frontendId, [&](Result result, const sp<IFrontend>& frontend) {
+ mFrontend = frontend;
+ status = result;
+ });
+ if (status != Result::SUCCESS) {
+ return ::testing::AssertionFailure();
+ }
+
+ mFrontendCallback = new FrontendCallback();
+ auto callbackStatus = mFrontend->setCallback(mFrontendCallback);
+
+ return ::testing::AssertionResult(callbackStatus.isOk());
+}
+
+::testing::AssertionResult TunerHidlTest::tuneFrontend(int32_t frontendId) {
+ if (createFrontend(frontendId) == ::testing::AssertionFailure()) {
+ return ::testing::AssertionFailure();
+ }
+
+ // Frontend Settings for testing
+ FrontendSettings frontendSettings;
+ FrontendAtscSettings frontendAtscSettings{
+ .frequency = 0,
+ .modulation = FrontendAtscModulation::UNDEFINED,
+ };
+ frontendSettings.atsc() = frontendAtscSettings;
+ mFrontendCallback->testOnEvent(mFrontend, frontendSettings);
+
+ FrontendDvbtSettings frontendDvbtSettings{
+ .frequency = 0,
+ .modulation = FrontendAtscModulation::UNDEFINED,
+ .fec = FrontendInnerFec::FEC_UNDEFINED,
+ };
+ frontendSettings.dvbt(frontendDvbtSettings);
+ mFrontendCallback->testOnEvent(mFrontend, frontendSettings);
+
+ return ::testing::AssertionResult(true);
+}
+
+::testing::AssertionResult TunerHidlTest::stopTuneFrontend(int32_t frontendId) {
+ Result status;
+ if (createFrontend(frontendId) == ::testing::AssertionFailure()) {
+ return ::testing::AssertionFailure();
+ }
+
+ status = mFrontend->stopTune();
+ return ::testing::AssertionResult(status == Result::SUCCESS);
+}
+
+::testing::AssertionResult TunerHidlTest::closeFrontend(int32_t frontendId) {
+ Result status;
+ if (createFrontend(frontendId) == ::testing::AssertionFailure()) {
+ return ::testing::AssertionFailure();
+ }
+
+ status = mFrontend->close();
+ return ::testing::AssertionResult(status == Result::SUCCESS);
+}
+
+TEST_F(TunerHidlTest, CreateFrontend) {
+ Result status;
+ hidl_vec<FrontendId> feIds;
+
+ description("Create Frontends");
+ 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(createFrontend(feIds[i]));
+ }
+}
+
+TEST_F(TunerHidlTest, TuneFrontend) {
+ Result status;
+ hidl_vec<FrontendId> feIds;
+
+ description("Tune Frontends and check callback onEvent");
+ 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(tuneFrontend(feIds[i]));
+ }
+}
+
+TEST_F(TunerHidlTest, StopTuneFrontend) {
+ Result status;
+ hidl_vec<FrontendId> feIds;
+
+ description("stopTune Frontends");
+ 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(stopTuneFrontend(feIds[i]));
+ }
+}
+
+TEST_F(TunerHidlTest, CloseFrontend) {
+ Result status;
+ hidl_vec<FrontendId> feIds;
+
+ description("Close Frontends");
+ 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(closeFrontend(feIds[i]));
+ }
+}
+
+} // namespace
+
+int main(int argc, char** argv) {
+ ::testing::AddGlobalTestEnvironment(TunerHidlEnvironment::Instance());
+ ::testing::InitGoogleTest(&argc, argv);
+ TunerHidlEnvironment::Instance()->init(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ LOG(INFO) << "Test result = " << status;
+ return status;
+}