Merge "Update cas@1.1 hal to cas@1.2."
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..98e125b
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,8 @@
+{
+ "presubmit": [
+ {
+ "name": "hidl_implementation_test"
+ }
+ ]
+}
+
diff --git a/audio/common/all-versions/test/utility/include/utility/AssertOk.h b/audio/common/all-versions/test/utility/include/utility/AssertOk.h
index 5ac2fdc..03a6305 100644
--- a/audio/common/all-versions/test/utility/include/utility/AssertOk.h
+++ b/audio/common/all-versions/test/utility/include/utility/AssertOk.h
@@ -114,6 +114,27 @@
#define ASSERT_RESULT(expected, ret) ASSERT_PRED_FORMAT2(detail::assertResult, expected, ret)
#define EXPECT_RESULT(expected, ret) EXPECT_PRED_FORMAT2(detail::assertResult, expected, ret)
+/** Unpack the provided result.
+ * If the result is not OK, register a failure and return the default initializer value. */
+template <class R>
+static R extract(const Return<R>& ret) {
+ if (!ret.isOk()) {
+ EXPECT_IS_OK(ret);
+ return R{};
+ }
+ return ret;
+}
+
+template <class Result, class Value>
+static void expectValueOrFailure(Result res, Value expectedValue, Value actualValue,
+ Result expectedFailure) {
+ if (res == Result::OK) {
+ ASSERT_EQ(expectedValue, actualValue);
+ } else {
+ ASSERT_EQ(expectedFailure, res) << "Unexpected result " << toString(res);
+ }
+}
+
} // namespace utility
} // namespace test
} // namespace common
diff --git a/audio/common/all-versions/test/utility/include/utility/EnvironmentTearDown.h b/audio/common/all-versions/test/utility/include/utility/EnvironmentTearDown.h
index 0e416f3..2b240ce 100644
--- a/audio/common/all-versions/test/utility/include/utility/EnvironmentTearDown.h
+++ b/audio/common/all-versions/test/utility/include/utility/EnvironmentTearDown.h
@@ -20,9 +20,6 @@
#include <functional>
#include <list>
-#include <VtsHalHidlTargetTestEnvBase.h>
-#include <gtest/gtest.h>
-
namespace android {
namespace hardware {
namespace audio {
@@ -34,18 +31,20 @@
* Avoid destroying static objects after main return.
* Post main return destruction leads to incorrect gtest timing measurements as
* well as harder debuging if anything goes wrong during destruction. */
-class Environment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
+class EnvironmentTearDown {
+ public:
using TearDownFunc = std::function<void()>;
void registerTearDown(TearDownFunc&& tearDown) { tearDowns.push_front(std::move(tearDown)); }
- private:
- void HidlTearDown() override {
+ protected:
+ void executeAllTearDowns() {
// Call the tear downs in reverse order of insertion
for (auto& tearDown : tearDowns) {
tearDown();
}
}
+
+ private:
std::list<TearDownFunc> tearDowns;
};
diff --git a/audio/core/all-versions/vts/functional/2.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/2.0/AudioPrimaryHidlHalTest.cpp
index 7906bf1..c189464 100644
--- a/audio/core/all-versions/vts/functional/2.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/2.0/AudioPrimaryHidlHalTest.cpp
@@ -60,19 +60,20 @@
"deconnection",
testConnectedState(stream.get()))
-TEST_IO_STREAM(GetHwAvSync, "Get hardware sync can not fail", ASSERT_IS_OK(device->getHwAvSync()));
+TEST_IO_STREAM(GetHwAvSync, "Get hardware sync can not fail",
+ ASSERT_IS_OK(getDevice()->getHwAvSync()));
-TEST_F(AudioPrimaryHidlTest, setMode) {
+TEST_P(AudioPrimaryHidlTest, setMode) {
doc::test("Make sure setMode always succeeds if mode is valid and fails otherwise");
// Test Invalid values
for (AudioMode mode : {AudioMode::INVALID, AudioMode::CURRENT, AudioMode::CNT}) {
SCOPED_TRACE("mode=" + toString(mode));
- ASSERT_RESULT(Result::INVALID_ARGUMENTS, device->setMode(mode));
+ ASSERT_RESULT(Result::INVALID_ARGUMENTS, getDevice()->setMode(mode));
}
// Test valid values
for (AudioMode mode : {AudioMode::IN_CALL, AudioMode::IN_COMMUNICATION, AudioMode::RINGTONE,
AudioMode::NORMAL /* Make sure to leave the test in normal mode */}) {
SCOPED_TRACE("mode=" + toString(mode));
- ASSERT_OK(device->setMode(mode));
+ ASSERT_OK(getDevice()->setMode(mode));
}
}
diff --git a/audio/core/all-versions/vts/functional/2.0/EnvironmentTearDown.h b/audio/core/all-versions/vts/functional/2.0/EnvironmentTearDown.h
new file mode 100644
index 0000000..6373e39
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/2.0/EnvironmentTearDown.h
@@ -0,0 +1,34 @@
+/*
+ * 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_AUDIO_CORE_2_0_ENVIRONMENT_TEARDOWN_H
+#define ANDROID_HARDWARE_AUDIO_CORE_2_0_ENVIRONMENT_TEARDOWN_H
+
+#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+
+#include "utility/EnvironmentTearDown.h"
+
+class Environment : public ::android::hardware::audio::common::test::utility::EnvironmentTearDown,
+ public ::testing::VtsHalHidlTargetTestEnvBase {
+ private:
+ void HidlTearDown() override {
+ executeAllTearDowns();
+ VtsHalHidlTargetTestEnvBase::HidlTearDown();
+ }
+};
+
+#endif // ANDROID_HARDWARE_AUDIO_CORE_2_0_ENVIRONMENT_TEARDOWN_H
diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
index 2703b2b..b8defb6 100644
--- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp
@@ -16,25 +16,14 @@
#include "AudioPrimaryHidlHalTest.h"
-static void waitForDeviceDestruction() {
- // FIXME: there is no way to know when the remote IDevice is being destroyed
- // Binder does not support testing if an object is alive, thus
- // wait for 100ms to let the binder destruction propagates and
- // the remote device has the time to be destroyed.
- // flushCommand makes sure all local command are sent, thus should reduce
- // the latency between local and remote destruction.
- IPCThreadState::self()->flushCommands();
- usleep(100);
-}
-
-TEST_F(AudioHidlTest, OpenPrimaryDeviceUsingGetDevice) {
+TEST_P(AudioHidlTest, OpenPrimaryDeviceUsingGetDevice) {
doc::test("Calling openDevice(\"primary\") should return the primary device.");
struct WaitExecutor {
- ~WaitExecutor() { waitForDeviceDestruction(); }
+ ~WaitExecutor() { DeviceManager::waitForInstanceDestruction(); }
} waitExecutor; // Make sure we wait for the device destruction on exiting from the test.
Result result;
sp<IDevice> baseDevice;
- ASSERT_OK(devicesFactory->openDevice("primary", returnIn(result, baseDevice)));
+ ASSERT_OK(getDevicesFactory()->openDevice("primary", returnIn(result, baseDevice)));
if (result != Result::OK && isPrimaryDeviceOptional()) {
GTEST_SKIP() << "No primary device on this factory"; // returns
}
@@ -50,10 +39,10 @@
/////////////////////////// get(Active)Microphones ///////////////////////////
//////////////////////////////////////////////////////////////////////////////
-TEST_F(AudioPrimaryHidlTest, GetMicrophonesTest) {
+TEST_P(AudioPrimaryHidlTest, GetMicrophonesTest) {
doc::test("Make sure getMicrophones always succeeds");
hidl_vec<MicrophoneInfo> microphones;
- ASSERT_OK(device->getMicrophones(returnIn(res, microphones)));
+ ASSERT_OK(getDevice()->getMicrophones(returnIn(res, microphones)));
ASSERT_OK(res);
if (microphones.size() > 0) {
// When there is microphone on the phone, try to open an input stream
@@ -75,15 +64,15 @@
}
sp<IStreamIn> stream;
AudioConfig suggestedConfig{};
- ASSERT_OK(device->openInputStream(ioHandle, microphone.deviceAddress, config, flags,
- initMetadata,
- returnIn(res, stream, suggestedConfig)));
+ ASSERT_OK(getDevice()->openInputStream(ioHandle, microphone.deviceAddress, config,
+ flags, initMetadata,
+ returnIn(res, stream, suggestedConfig)));
if (res != Result::OK) {
ASSERT_TRUE(stream == nullptr);
AudioConfig suggestedConfigRetry{};
- ASSERT_OK(device->openInputStream(ioHandle, microphone.deviceAddress,
- suggestedConfig, flags, initMetadata,
- returnIn(res, stream, suggestedConfigRetry)));
+ ASSERT_OK(getDevice()->openInputStream(
+ ioHandle, microphone.deviceAddress, suggestedConfig, flags, initMetadata,
+ returnIn(res, stream, suggestedConfigRetry)));
}
ASSERT_OK(res);
hidl_vec<MicrophoneInfo> activeMicrophones;
@@ -131,7 +120,7 @@
}
}
-TEST_F(AudioPrimaryHidlTest, SetConnectedState) {
+TEST_P(AudioPrimaryHidlTest, SetConnectedState) {
doc::test("Check that the HAL can be notified of device connection and deconnection");
using AD = AudioDevice;
for (auto deviceType : {AD::OUT_HDMI, AD::OUT_WIRED_HEADPHONE, AD::IN_USB_HEADSET}) {
@@ -140,7 +129,7 @@
SCOPED_TRACE("state=" + ::testing::PrintToString(state));
DeviceAddress address = {};
address.device = deviceType;
- auto ret = device->setConnectedState(address, state);
+ auto ret = getDevice()->setConnectedState(address, state);
ASSERT_TRUE(ret.isOk());
if (ret == Result::NOT_SUPPORTED) {
doc::partialTest("setConnectedState is not supported");
@@ -153,9 +142,7 @@
// Because there is no way of knowing if the devices were connected before
// calling setConnectedState, there is no way to restore the HAL to its
// initial state. To workaround this, destroy the HAL at the end of this test.
- device.clear();
- waitForDeviceDestruction();
- ASSERT_NO_FATAL_FAILURE(initPrimaryDevice());
+ ASSERT_TRUE(DeviceManager::getInstance().resetPrimary(getFactoryName()));
}
static void testGetDevices(IStream* stream, AudioDevice expectedDevice) {
@@ -199,7 +186,7 @@
}
ASSERT_OK(res);
}
-TEST_IO_STREAM(GetHwAvSync, "Get hardware sync can not fail", checkGetHwAVSync(device.get()));
+TEST_IO_STREAM(GetHwAvSync, "Get hardware sync can not fail", checkGetHwAVSync(getDevice().get()));
TEST_P(InputStreamTest, updateSinkMetadata) {
doc::test("The HAL should not crash on metadata change");
@@ -259,58 +246,58 @@
ASSERT_OK(stream->updateSourceMetadata(initMetadata));
}
-TEST_F(AudioPrimaryHidlTest, setMode) {
+TEST_P(AudioPrimaryHidlTest, setMode) {
doc::test("Make sure setMode always succeeds if mode is valid and fails otherwise");
// Test Invalid values
for (int mode : {-2, -1, int(AudioMode::IN_COMMUNICATION) + 1}) {
- ASSERT_RESULT(Result::INVALID_ARGUMENTS, device->setMode(AudioMode(mode)))
- << "mode=" << mode;
+ ASSERT_RESULT(Result::INVALID_ARGUMENTS, getDevice()->setMode(AudioMode(mode)))
+ << "mode=" << mode;
}
// Test valid values
for (AudioMode mode : {AudioMode::IN_CALL, AudioMode::IN_COMMUNICATION, AudioMode::RINGTONE,
AudioMode::NORMAL /* Make sure to leave the test in normal mode */}) {
- ASSERT_OK(device->setMode(mode)) << "mode=" << toString(mode);
+ ASSERT_OK(getDevice()->setMode(mode)) << "mode=" << toString(mode);
}
}
-TEST_F(AudioPrimaryHidlTest, setBtHfpSampleRate) {
+TEST_P(AudioPrimaryHidlTest, setBtHfpSampleRate) {
doc::test(
"Make sure setBtHfpSampleRate either succeeds or "
"indicates that it is not supported at all, or that the provided value is invalid");
for (auto samplingRate : {8000, 16000, 22050, 24000}) {
- ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, device->setBtHfpSampleRate(samplingRate));
+ ASSERT_RESULT(okOrNotSupportedOrInvalidArgs, getDevice()->setBtHfpSampleRate(samplingRate));
}
}
-TEST_F(AudioPrimaryHidlTest, setBtHfpVolume) {
+TEST_P(AudioPrimaryHidlTest, setBtHfpVolume) {
doc::test(
"Make sure setBtHfpVolume is either not supported or "
"only succeed if volume is in [0,1]");
- auto ret = device->setBtHfpVolume(0.0);
+ auto ret = getDevice()->setBtHfpVolume(0.0);
ASSERT_TRUE(ret.isOk());
if (ret == Result::NOT_SUPPORTED) {
doc::partialTest("setBtHfpVolume is not supported");
return;
}
- testUnitaryGain([](float volume) { return device->setBtHfpVolume(volume); });
+ testUnitaryGain([this](float volume) { return getDevice()->setBtHfpVolume(volume); });
}
-TEST_F(AudioPrimaryHidlTest, setBtScoHeadsetDebugName) {
+TEST_P(AudioPrimaryHidlTest, setBtScoHeadsetDebugName) {
doc::test(
"Make sure setBtScoHeadsetDebugName either succeeds or "
"indicates that it is not supported");
- ASSERT_RESULT(okOrNotSupported, device->setBtScoHeadsetDebugName("test"));
+ ASSERT_RESULT(okOrNotSupported, getDevice()->setBtScoHeadsetDebugName("test"));
}
-TEST_F(AudioPrimaryHidlTest, updateRotation) {
+TEST_P(AudioPrimaryHidlTest, updateRotation) {
doc::test("Check that the hal can receive the current rotation");
for (Rotation rotation : {Rotation::DEG_0, Rotation::DEG_90, Rotation::DEG_180,
Rotation::DEG_270, Rotation::DEG_0}) {
- ASSERT_RESULT(okOrNotSupported, device->updateRotation(rotation));
+ ASSERT_RESULT(okOrNotSupported, getDevice()->updateRotation(rotation));
}
}
-TEST_F(BoolAccessorPrimaryHidlTest, setGetBtHfpEnabled) {
+TEST_P(BoolAccessorPrimaryHidlTest, setGetBtHfpEnabled) {
doc::test("Query and set the BT HFP state");
testAccessors<OPTIONAL>("BtHfpEnabled", Initial{false, OPTIONAL}, {true},
&IPrimaryDevice::setBtHfpEnabled, &IPrimaryDevice::getBtHfpEnabled);
diff --git a/audio/core/all-versions/vts/functional/6.0/EnvironmentTearDown.h b/audio/core/all-versions/vts/functional/6.0/EnvironmentTearDown.h
new file mode 100644
index 0000000..593759f
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/6.0/EnvironmentTearDown.h
@@ -0,0 +1,35 @@
+/*
+ * 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_AUDIO_CORE_6_0_ENVIRONMENT_TEARDOWN_H
+#define ANDROID_HARDWARE_AUDIO_CORE_6_0_ENVIRONMENT_TEARDOWN_H
+
+#include <gtest/gtest.h>
+
+#include "utility/EnvironmentTearDown.h"
+
+class Environment : public ::android::hardware::audio::common::test::utility::EnvironmentTearDown,
+ public ::testing::Environment {
+ public:
+ void init(int* /*argc*/, char** /*argv*/) {} // emulate VtsHalHidlTargetTestEnvBase
+ private:
+ void TearDown() override { executeAllTearDowns(); }
+};
+
+// FIXME: Will be removed while making getDeviceParameters to use the config
+static constexpr const char* kDefaultServiceName = "default";
+
+#endif // ANDROID_HARDWARE_AUDIO_CORE_6_0_ENVIRONMENT_TEARDOWN_H
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index fb96323..e59ab98 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -23,6 +23,7 @@
#include <initializer_list>
#include <limits>
#include <list>
+#include <map>
#include <string>
#include <vector>
@@ -31,7 +32,9 @@
#include <hwbinder/IPCThreadState.h>
+#if MAJOR_VERSION <= 5
#include <VtsHalHidlTargetTestBase.h>
+#endif
#include <android-base/logging.h>
@@ -44,16 +47,25 @@
#include <Serializer.h>
#include <fmq/EventFlag.h>
#include <fmq/MessageQueue.h>
+#if MAJOR_VERSION >= 6
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+#endif
#include <common/all-versions/VersionUtils.h>
#include "utility/AssertOk.h"
#include "utility/Documentation.h"
-#include "utility/EnvironmentTearDown.h"
#include "utility/PrettyPrintAudioTypes.h"
#include "utility/ReturnIn.h"
#include "utility/ValidateXml.h"
+#if MAJOR_VERSION <= 5
+#include "2.0/EnvironmentTearDown.h"
+#elif MAJOR_VERSION >= 6
+#include "6.0/EnvironmentTearDown.h"
+#endif
+
/** Provide version specific functions that are used in the generic tests */
#if MAJOR_VERSION == 2
#include "2.0/AudioPrimaryHidlHalUtils.h"
@@ -105,14 +117,23 @@
class AudioHidlTestEnvironment : public ::Environment {
public:
- virtual void registerTestServices() override { registerTestService<IDevicesFactory>(); }
+#if MAJOR_VERSION <= 5
+ void registerTestServices() override { registerTestService<IDevicesFactory>(); }
+#endif
};
// Instance to register global tearDown
static AudioHidlTestEnvironment* environment;
+#define AUDIO_PRIMARY_HIDL_HAL_TEST
+#include "DeviceManager.h"
+
+#if MAJOR_VERSION <= 5
class HidlTest : public ::testing::VtsHalHidlTargetTestBase {
- protected:
+#elif MAJOR_VERSION >= 6
+class HidlTest : public ::testing::Test {
+#endif
+ protected:
// Convenient member to store results
Result res;
};
@@ -201,6 +222,21 @@
ASSERT_TRUE(mPrimaryConfig) << "Could not find primary module in configuration file: "
<< policyConfig.getFilePath();
}
+
+ protected:
+ sp<IDevicesFactory> getDevicesFactory(const std::string& factoryName) const {
+ return DevicesFactoryManager::getInstance().get(factoryName);
+ }
+
+ sp<IPrimaryDevice> getPrimaryDevice(const std::string& factoryName) const {
+ return DeviceManager::getInstance().getPrimary(factoryName);
+ }
+
+ bool isPrimaryDeviceOptional(const std::string& factoryName) const {
+ // It's OK not to have "primary" device on non-default audio HAL service.
+ return factoryName != kDefaultServiceName;
+ }
+
sp<const HwModule> mPrimaryConfig = nullptr;
};
@@ -209,41 +245,85 @@
}
//////////////////////////////////////////////////////////////////////////////
+//////////////////// Test parameter types and definitions ////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+enum { PARAM_FACTORY_NAME, PARAM_DEVICE_NAME };
+using DeviceParameter = std::tuple<std::string, std::string>;
+
+static inline std::string DeviceParameterToString(
+ const ::testing::TestParamInfo<DeviceParameter>& info) {
+#if MAJOR_VERSION <= 5
+ return std::get<PARAM_DEVICE_NAME>(info.param);
+#elif MAJOR_VERSION >= 6
+ const auto factoryName =
+ ::android::hardware::PrintInstanceNameToString(::testing::TestParamInfo<std::string>{
+ std::get<PARAM_FACTORY_NAME>(info.param), info.index});
+ const auto& deviceName = std::get<PARAM_DEVICE_NAME>(info.param);
+ return !deviceName.empty() ? factoryName + "_" + deviceName : factoryName;
+#endif
+}
+
+#if MAJOR_VERSION <= 5
+// For V2..5 the factory is looked up using the instance name passed
+// in the environment, only one factory is returned. This is because the VTS
+// framework will call the test for each instance. Only the primary device of
+// the factory specified in the environment is tested.
+const std::vector<DeviceParameter>& getDeviceParameters() {
+ static std::vector<DeviceParameter> parameters = {
+ {environment->getServiceName<IDevicesFactory>(), DeviceManager::kPrimaryDevice}};
+ return parameters;
+}
+#elif MAJOR_VERSION >= 6
+// FIXME: Will be replaced with code that analyzes the audio policy config file.
+const std::vector<DeviceParameter>& getDeviceParameters() {
+ static std::vector<DeviceParameter> parameters = [] {
+ const auto instances =
+ ::android::hardware::getAllHalInstanceNames(IDevicesFactory::descriptor);
+ std::vector<DeviceParameter> result;
+ result.reserve(instances.size());
+ for (const auto& instance : instances) {
+ result.emplace_back(instance, DeviceManager::kPrimaryDevice);
+ }
+ return result;
+ }();
+ return parameters;
+}
+#endif
+
+class AudioHidlTestWithDeviceParameter : public AudioPolicyConfigTest,
+ public ::testing::WithParamInterface<DeviceParameter> {
+ protected:
+ const std::string& getFactoryName() const { return std::get<PARAM_FACTORY_NAME>(GetParam()); }
+ bool isPrimaryDeviceOptional() const {
+ return AudioPolicyConfigTest::isPrimaryDeviceOptional(getFactoryName());
+ }
+ sp<IDevicesFactory> getDevicesFactory() const {
+ return AudioPolicyConfigTest::getDevicesFactory(getFactoryName());
+ }
+ sp<IPrimaryDevice> getPrimaryDevice() const {
+ return AudioPolicyConfigTest::getPrimaryDevice(getFactoryName());
+ }
+};
+
+//////////////////////////////////////////////////////////////////////////////
////////////////////// getService audio_devices_factory //////////////////////
//////////////////////////////////////////////////////////////////////////////
// Test all audio devices
-class AudioHidlTest : public AudioPolicyConfigTest {
- public:
- static void SetUpTestSuite() {
- devicesFactory = ::testing::VtsHalHidlTargetTestBase::getService<IDevicesFactory>(
- environment->getServiceName<IDevicesFactory>());
- }
-
- static void TearDownTestSuite() { devicesFactory.clear(); }
-
- void SetUp() override {
- ASSERT_NO_FATAL_FAILURE(AudioPolicyConfigTest::SetUp()); // setup base
- // Failures during SetUpTestSuite do not cause test termination.
- ASSERT_TRUE(devicesFactory != nullptr);
- }
-
- protected:
- // Cache the devicesFactory retrieval to speed up each test by ~0.5s
- static sp<IDevicesFactory> devicesFactory;
-
- static bool isPrimaryDeviceOptional() {
- // It's OK not to have "primary" device on non-default audio HAL service.
- return environment->getServiceName<IDevicesFactory>() != kDefaultServiceName;
+class AudioHidlTest : public AudioHidlTestWithDeviceParameter {
+ public:
+ void SetUp() override {
+ ASSERT_NO_FATAL_FAILURE(AudioHidlTestWithDeviceParameter::SetUp()); // setup base
+ ASSERT_TRUE(getDevicesFactory() != nullptr);
}
};
-sp<IDevicesFactory> AudioHidlTest::devicesFactory;
-TEST_F(AudioHidlTest, GetAudioDevicesFactoryService) {
+TEST_P(AudioHidlTest, GetAudioDevicesFactoryService) {
doc::test("Test the getService");
}
-TEST_F(AudioHidlTest, OpenDeviceInvalidParameter) {
+TEST_P(AudioHidlTest, OpenDeviceInvalidParameter) {
doc::test("Test passing an invalid parameter to openDevice");
Result result;
sp<IDevice> device;
@@ -252,11 +332,14 @@
#elif MAJOR_VERSION >= 4
auto invalidDevice = "Non existing device";
#endif
- ASSERT_OK(devicesFactory->openDevice(invalidDevice, returnIn(result, device)));
+ ASSERT_OK(getDevicesFactory()->openDevice(invalidDevice, returnIn(result, device)));
ASSERT_EQ(Result::INVALID_ARGUMENTS, result);
ASSERT_TRUE(device == nullptr);
}
+INSTANTIATE_TEST_CASE_P(AudioHidl, AudioHidlTest, ::testing::ValuesIn(getDeviceParameters()),
+ &DeviceParameterToString);
+
//////////////////////////////////////////////////////////////////////////////
/////////////////////////////// openDevice primary ///////////////////////////
//////////////////////////////////////////////////////////////////////////////
@@ -264,57 +347,30 @@
// Test the primary device
class AudioPrimaryHidlTest : public AudioHidlTest {
public:
- static void SetUpTestSuite() {
- ASSERT_NO_FATAL_FAILURE(AudioHidlTest::SetUpTestSuite());
- ASSERT_NO_FATAL_FAILURE(initPrimaryDevice());
- }
-
- static void TearDownTestSuite() {
- device.clear();
- AudioHidlTest::TearDownTestSuite();
- }
-
void SetUp() override {
ASSERT_NO_FATAL_FAILURE(AudioHidlTest::SetUp()); // setup base
- if (device == nullptr && isPrimaryDeviceOptional()) {
+ if (getDevice() == nullptr && isPrimaryDeviceOptional()) {
GTEST_SKIP() << "No primary device on this factory";
}
- ASSERT_TRUE(device != nullptr);
+ ASSERT_TRUE(getDevice() != nullptr);
}
protected:
- // Cache the device opening to speed up each test by ~0.5s
- static sp<IPrimaryDevice> device;
-
- static void initPrimaryDevice() {
- // Failures during test suite set up do not cause test termination.
- ASSERT_TRUE(devicesFactory != nullptr);
- Result result;
-#if MAJOR_VERSION == 2
- sp<IDevice> baseDevice;
- ASSERT_OK(devicesFactory->openDevice(IDevicesFactory::Device::PRIMARY,
- returnIn(result, baseDevice)));
- ASSERT_OK(result);
- ASSERT_TRUE(baseDevice != nullptr);
-
- device = IPrimaryDevice::castFrom(baseDevice);
-#elif MAJOR_VERSION >= 4
- ASSERT_OK(devicesFactory->openPrimaryDevice(returnIn(result, device)));
- ASSERT_OK(result);
-#endif
- }
+ sp<IPrimaryDevice> getDevice() const { return getPrimaryDevice(); }
};
-sp<IPrimaryDevice> AudioPrimaryHidlTest::device;
-TEST_F(AudioPrimaryHidlTest, OpenPrimaryDevice) {
+TEST_P(AudioPrimaryHidlTest, OpenPrimaryDevice) {
doc::test("Test the openDevice (called during setup)");
}
-TEST_F(AudioPrimaryHidlTest, Init) {
+TEST_P(AudioPrimaryHidlTest, Init) {
doc::test("Test that the audio primary hal initialized correctly");
- ASSERT_OK(device->initCheck());
+ ASSERT_OK(getDevice()->initCheck());
}
+INSTANTIATE_TEST_CASE_P(AudioPrimaryHidl, AudioPrimaryHidlTest,
+ ::testing::ValuesIn(getDeviceParameters()), &DeviceParameterToString);
+
//////////////////////////////////////////////////////////////////////////////
///////////////////// {set,get}{Master,Mic}{Mute,Volume} /////////////////////
//////////////////////////////////////////////////////////////////////////////
@@ -339,7 +395,7 @@
optionality == OPTIONAL ? Result::NOT_SUPPORTED : Result::OK};
Property initialValue = expectedInitial.value;
- ASSERT_OK((device.get()->*getter)(returnIn(res, initialValue)));
+ ASSERT_OK((getDevice().get()->*getter)(returnIn(res, initialValue)));
ASSERT_RESULT(expectedResults, res);
if (res == Result::OK && expectedInitial.check == REQUIRED) {
EXPECT_EQ(expectedInitial.value, initialValue);
@@ -350,7 +406,7 @@
for (Property setValue : valuesToTest) {
SCOPED_TRACE("Test " + propertyName + " getter and setter for " +
testing::PrintToString(setValue));
- auto ret = (device.get()->*setter)(setValue);
+ auto ret = (getDevice().get()->*setter)(setValue);
ASSERT_RESULT(expectedResults, ret);
if (ret == Result::NOT_SUPPORTED) {
doc::partialTest(propertyName + " setter is not supported");
@@ -358,7 +414,7 @@
}
Property getValue;
// Make sure the getter returns the same value just set
- ASSERT_OK((device.get()->*getter)(returnIn(res, getValue)));
+ ASSERT_OK((getDevice().get()->*getter)(returnIn(res, getValue)));
ASSERT_RESULT(expectedResults, res);
if (res == Result::NOT_SUPPORTED) {
doc::partialTest(propertyName + " getter is not supported");
@@ -370,31 +426,34 @@
for (Property invalidValue : invalidValues) {
SCOPED_TRACE("Try to set " + propertyName + " with the invalid value " +
testing::PrintToString(invalidValue));
- EXPECT_RESULT(invalidArgsOrNotSupported, (device.get()->*setter)(invalidValue));
+ EXPECT_RESULT(invalidArgsOrNotSupported, (getDevice().get()->*setter)(invalidValue));
}
// Restore initial value
- EXPECT_RESULT(expectedResults, (device.get()->*setter)(initialValue));
+ EXPECT_RESULT(expectedResults, (getDevice().get()->*setter)(initialValue));
}
};
using BoolAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<bool>;
-TEST_F(BoolAccessorPrimaryHidlTest, MicMuteTest) {
+TEST_P(BoolAccessorPrimaryHidlTest, MicMuteTest) {
doc::test("Check that the mic can be muted and unmuted");
testAccessors("mic mute", Initial{false}, {true}, &IDevice::setMicMute, &IDevice::getMicMute);
// TODO: check that the mic is really muted (all sample are 0)
}
-TEST_F(BoolAccessorPrimaryHidlTest, MasterMuteTest) {
+TEST_P(BoolAccessorPrimaryHidlTest, MasterMuteTest) {
doc::test("If master mute is supported, try to mute and unmute the master output");
testAccessors<OPTIONAL>("master mute", Initial{false}, {true}, &IDevice::setMasterMute,
&IDevice::getMasterMute);
// TODO: check that the master volume is really muted
}
+INSTANTIATE_TEST_CASE_P(BoolAccessorPrimaryHidl, BoolAccessorPrimaryHidlTest,
+ ::testing::ValuesIn(getDeviceParameters()), &DeviceParameterToString);
+
using FloatAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<float>;
-TEST_F(FloatAccessorPrimaryHidlTest, MasterVolumeTest) {
+TEST_P(FloatAccessorPrimaryHidlTest, MasterVolumeTest) {
doc::test("Test the master volume if supported");
testAccessors<OPTIONAL>(
"master volume", Initial{1}, {0, 0.5}, &IDevice::setMasterVolume, &IDevice::getMasterVolume,
@@ -402,20 +461,19 @@
// TODO: check that the master volume is really changed
}
+INSTANTIATE_TEST_CASE_P(FloatAccessorPrimaryHidl, FloatAccessorPrimaryHidlTest,
+ ::testing::ValuesIn(getDeviceParameters()), &DeviceParameterToString);
+
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////// AudioPatches ////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
class AudioPatchPrimaryHidlTest : public AudioPrimaryHidlTest {
protected:
- bool areAudioPatchesSupported() {
- auto result = device->supportsAudioPatches();
- EXPECT_IS_OK(result);
- return result;
- }
+ bool areAudioPatchesSupported() { return extract(getDevice()->supportsAudioPatches()); }
};
-TEST_F(AudioPatchPrimaryHidlTest, AudioPatches) {
+TEST_P(AudioPatchPrimaryHidlTest, AudioPatches) {
doc::test("Test if audio patches are supported");
if (!areAudioPatchesSupported()) {
doc::partialTest("Audio patches are not supported");
@@ -424,6 +482,9 @@
// TODO: test audio patches
}
+INSTANTIATE_TEST_CASE_P(AudioPatchPrimaryHidl, AudioPatchPrimaryHidlTest,
+ ::testing::ValuesIn(getDeviceParameters()), &DeviceParameterToString);
+
//////////////////////////////////////////////////////////////////////////////
//////////////// Required and recommended audio format support ///////////////
// From:
@@ -433,8 +494,7 @@
/////////// TODO: move to the beginning of the file for easier update ////////
//////////////////////////////////////////////////////////////////////////////
-class AudioConfigPrimaryTest : public AudioPatchPrimaryHidlTest {
- public:
+struct ConfigHelper {
// for retro compatibility only test the primary device IN_BUILTIN_MIC
// FIXME: in the next audio HAL version, test all available devices
static bool primaryHasMic() {
@@ -506,21 +566,51 @@
}
};
+// Nesting a tuple in another tuple allows to use GTest Combine function to generate
+// all combinations of devices and configs.
+enum { PARAM_DEVICE, PARAM_CONFIG };
+using DeviceConfigParameter = std::tuple<DeviceParameter, AudioConfig>;
+
/** Generate a test name based on an audio config.
*
* As the only parameter changing are channel mask and sample rate,
* only print those ones in the test name.
*/
-static string generateTestName(const testing::TestParamInfo<AudioConfig>& info) {
- const AudioConfig& config = info.param;
- return to_string(info.index) + "__" + to_string(config.sampleRateHz) + "_" +
+static string DeviceConfigParameterToString(
+ const testing::TestParamInfo<DeviceConfigParameter>& info) {
+ const AudioConfig& config = std::get<PARAM_CONFIG>(info.param);
+ const auto deviceName = DeviceParameterToString(::testing::TestParamInfo<DeviceParameter>{
+ std::get<PARAM_DEVICE>(info.param), info.index});
+ return (deviceName.empty() ? "" : deviceName + "_") + to_string(info.index) + "__" +
+ to_string(config.sampleRateHz) + "_" +
// "MONO" is more clear than "FRONT_LEFT"
((config.channelMask == mkEnumBitfield(AudioChannelMask::OUT_MONO) ||
config.channelMask == mkEnumBitfield(AudioChannelMask::IN_MONO))
- ? "MONO"
- : ::testing::PrintToString(config.channelMask));
+ ? "MONO"
+ : ::testing::PrintToString(config.channelMask));
}
+class AudioHidlTestWithDeviceConfigParameter
+ : public AudioPolicyConfigTest,
+ public ::testing::WithParamInterface<DeviceConfigParameter> {
+ protected:
+ const std::string& getFactoryName() const {
+ return std::get<PARAM_FACTORY_NAME>(std::get<PARAM_DEVICE>(GetParam()));
+ }
+ bool isPrimaryDeviceOptional() const {
+ return AudioPolicyConfigTest::isPrimaryDeviceOptional(getFactoryName());
+ }
+ sp<IDevicesFactory> getDevicesFactory() const {
+ return AudioPolicyConfigTest::getDevicesFactory(getFactoryName());
+ }
+ sp<IPrimaryDevice> getPrimaryDevice() const {
+ return AudioPolicyConfigTest::getPrimaryDevice(getFactoryName());
+ }
+ const AudioConfig& getConfig() const { return std::get<PARAM_CONFIG>(GetParam()); }
+ // FIXME: Split out tests that don't require primary device
+ sp<IPrimaryDevice> getDevice() const { return getPrimaryDevice(); }
+};
+
//////////////////////////////////////////////////////////////////////////////
///////////////////////////// getInputBufferSize /////////////////////////////
//////////////////////////////////////////////////////////////////////////////
@@ -529,12 +619,21 @@
// android.hardware.microphone
// how to get this value ? is it a property ???
-class AudioCaptureConfigPrimaryTest : public AudioConfigPrimaryTest,
- public ::testing::WithParamInterface<AudioConfig> {
- protected:
+class AudioCaptureConfigPrimaryTest : public AudioHidlTestWithDeviceConfigParameter {
+ public:
+ void SetUp() override {
+ ASSERT_NO_FATAL_FAILURE(AudioHidlTestWithDeviceConfigParameter::SetUp()); // setup base
+ ASSERT_TRUE(getDevicesFactory() != nullptr);
+ if (getDevice() == nullptr && isPrimaryDeviceOptional()) {
+ GTEST_SKIP() << "No primary device on this factory";
+ }
+ ASSERT_TRUE(getDevice() != nullptr);
+ }
+
+ protected:
void inputBufferSizeTest(const AudioConfig& audioConfig, bool supportRequired) {
uint64_t bufferSize;
- ASSERT_OK(device->getInputBufferSize(audioConfig, returnIn(res, bufferSize)));
+ ASSERT_OK(getDevice()->getInputBufferSize(audioConfig, returnIn(res, bufferSize)));
switch (res) {
case Result::INVALID_ARGUMENTS:
@@ -558,16 +657,19 @@
doc::test(
"Input buffer size must be retrievable for a format with required "
"support.");
- inputBufferSizeTest(GetParam(), true);
+ inputBufferSizeTest(getConfig(), true);
}
INSTANTIATE_TEST_CASE_P(
- RequiredInputBufferSize, RequiredInputBufferSizeTest,
- ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()),
- &generateTestName);
+ RequiredInputBufferSize, RequiredInputBufferSizeTest,
+ ::testing::Combine(
+ ::testing::ValuesIn(getDeviceParameters()),
+ ::testing::ValuesIn(ConfigHelper::getRequiredSupportCaptureAudioConfig())),
+ &DeviceConfigParameterToString);
INSTANTIATE_TEST_CASE_P(
- SupportedInputBufferSize, RequiredInputBufferSizeTest,
- ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()),
- &generateTestName);
+ SupportedInputBufferSize, RequiredInputBufferSizeTest,
+ ::testing::Combine(::testing::ValuesIn(getDeviceParameters()),
+ ::testing::ValuesIn(ConfigHelper::getSupportedCaptureAudioConfig())),
+ &DeviceConfigParameterToString);
// Test that the recommended capture config are supported or lead to a
// INVALID_ARGUMENTS return
@@ -576,21 +678,23 @@
doc::test(
"Input buffer size should be retrievable for a format with recommended "
"support.");
- inputBufferSizeTest(GetParam(), false);
+ inputBufferSizeTest(getConfig(), false);
}
INSTANTIATE_TEST_CASE_P(
- RecommendedCaptureAudioConfigSupport, OptionalInputBufferSizeTest,
- ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()),
- &generateTestName);
+ RecommendedCaptureAudioConfigSupport, OptionalInputBufferSizeTest,
+ ::testing::Combine(
+ ::testing::ValuesIn(getDeviceParameters()),
+ ::testing::ValuesIn(ConfigHelper::getRecommendedSupportCaptureAudioConfig())),
+ &DeviceConfigParameterToString);
//////////////////////////////////////////////////////////////////////////////
/////////////////////////////// setScreenState ///////////////////////////////
//////////////////////////////////////////////////////////////////////////////
-TEST_F(AudioPrimaryHidlTest, setScreenState) {
+TEST_P(AudioPrimaryHidlTest, setScreenState) {
doc::test("Check that the hal can receive the screen state");
for (bool turnedOn : {false, true, true, false, false}) {
- ASSERT_RESULT(okOrNotSupported, device->setScreenState(turnedOn));
+ ASSERT_RESULT(okOrNotSupported, getDevice()->setScreenState(turnedOn));
}
}
@@ -598,15 +702,15 @@
//////////////////////////// {get,set}Parameters /////////////////////////////
//////////////////////////////////////////////////////////////////////////////
-TEST_F(AudioPrimaryHidlTest, getParameters) {
+TEST_P(AudioPrimaryHidlTest, getParameters) {
doc::test("Check that the hal can set and get parameters");
hidl_vec<ParameterValue> context;
hidl_vec<hidl_string> keys;
hidl_vec<ParameterValue> values;
- ASSERT_OK(Parameters::get(device, keys, returnIn(res, values)));
- ASSERT_OK(Parameters::set(device, values));
+ ASSERT_OK(Parameters::get(getDevice(), keys, returnIn(res, values)));
+ ASSERT_OK(Parameters::set(getDevice(), values));
values.resize(0);
- ASSERT_OK(Parameters::set(device, values));
+ ASSERT_OK(Parameters::set(getDevice(), values));
}
//////////////////////////////////////////////////////////////////////////////
@@ -647,14 +751,14 @@
EXPECT_EQ(0, close(fds[1])) << errno;
}
-TEST_F(AudioPrimaryHidlTest, DebugDump) {
+TEST_P(AudioPrimaryHidlTest, DebugDump) {
doc::test("Check that the hal can dump its state without error");
- testDebugDump([](const auto& handle) { return dump(device, handle); });
+ testDebugDump([this](const auto& handle) { return dump(getDevice(), handle); });
}
-TEST_F(AudioPrimaryHidlTest, DebugDumpInvalidArguments) {
+TEST_P(AudioPrimaryHidlTest, DebugDumpInvalidArguments) {
doc::test("Check that the hal dump doesn't crash on invalid arguments");
- ASSERT_OK(dump(device, hidl_handle()));
+ ASSERT_OK(dump(getDevice(), hidl_handle()));
}
//////////////////////////////////////////////////////////////////////////////
@@ -662,9 +766,17 @@
//////////////////////////////////////////////////////////////////////////////
template <class Stream>
-class OpenStreamTest : public AudioConfigPrimaryTest,
- public ::testing::WithParamInterface<AudioConfig> {
- protected:
+class OpenStreamTest : public AudioHidlTestWithDeviceConfigParameter {
+ protected:
+ void SetUp() override {
+ ASSERT_NO_FATAL_FAILURE(AudioHidlTestWithDeviceConfigParameter::SetUp()); // setup base
+ ASSERT_TRUE(getDevicesFactory() != nullptr);
+ if (getDevice() == nullptr && isPrimaryDeviceOptional()) {
+ GTEST_SKIP() << "No primary device on this factory";
+ }
+ ASSERT_TRUE(getDevice() != nullptr);
+ }
+
template <class Open>
void testOpen(Open openStream, const AudioConfig& config) {
// FIXME: Open a stream without an IOHandle
@@ -699,15 +811,31 @@
Return<Result> closeStream() {
open = false;
- return stream->close();
+ auto res = stream->close();
+ stream.clear();
+ waitForStreamDestruction();
+ return res;
}
- private:
+ static void waitForStreamDestruction() {
+ // FIXME: there is no way to know when the remote IStream is being destroyed
+ // Binder does not support testing if an object is alive, thus
+ // wait for 100ms to let the binder destruction propagates and
+ // the remote device has the time to be destroyed.
+ // flushCommand makes sure all local command are sent, thus should reduce
+ // the latency between local and remote destruction.
+ IPCThreadState::self()->flushCommands();
+ usleep(100 * 1000);
+ }
+
+ bool areAudioPatchesSupported() { return extract(getDevice()->supportsAudioPatches()); }
+
+ private:
void TearDown() override {
if (open) {
- ASSERT_OK(stream->close());
+ ASSERT_OK(closeStream());
}
- AudioConfigPrimaryTest::TearDown();
+ AudioPolicyConfigTest::TearDown();
}
protected:
@@ -724,18 +852,19 @@
ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
if (IsSkipped()) return; // do not attempt to use 'device'
address.device = AudioDevice::OUT_DEFAULT;
- const AudioConfig& config = GetParam();
+ const AudioConfig& config = getConfig();
// TODO: test all flag combination
auto flags = mkEnumBitfield(AudioOutputFlag::NONE);
testOpen(
- [&](AudioIoHandle handle, AudioConfig config, auto cb) {
+ [&](AudioIoHandle handle, AudioConfig config, auto cb) {
#if MAJOR_VERSION == 2
- return device->openOutputStream(handle, address, config, flags, cb);
+ return getDevice()->openOutputStream(handle, address, config, flags, cb);
#elif MAJOR_VERSION >= 4
- return device->openOutputStream(handle, address, config, flags, initMetadata, cb);
+ return getDevice()->openOutputStream(handle, address, config, flags,
+ initMetadata, cb);
#endif
- },
- config);
+ },
+ config);
}
#if MAJOR_VERSION >= 4
@@ -753,18 +882,23 @@
// Open done in SetUp
}
INSTANTIATE_TEST_CASE_P(
- RequiredOutputStreamConfigSupport, OutputStreamTest,
- ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportPlaybackAudioConfig()),
- &generateTestName);
+ RequiredOutputStreamConfigSupport, OutputStreamTest,
+ ::testing::Combine(
+ ::testing::ValuesIn(getDeviceParameters()),
+ ::testing::ValuesIn(ConfigHelper::getRequiredSupportPlaybackAudioConfig())),
+ &DeviceConfigParameterToString);
INSTANTIATE_TEST_CASE_P(
- SupportedOutputStreamConfig, OutputStreamTest,
- ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedPlaybackAudioConfig()),
- &generateTestName);
+ SupportedOutputStreamConfig, OutputStreamTest,
+ ::testing::Combine(::testing::ValuesIn(getDeviceParameters()),
+ ::testing::ValuesIn(ConfigHelper::getSupportedPlaybackAudioConfig())),
+ &DeviceConfigParameterToString);
INSTANTIATE_TEST_CASE_P(
- RecommendedOutputStreamConfigSupport, OutputStreamTest,
- ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportPlaybackAudioConfig()),
- &generateTestName);
+ RecommendedOutputStreamConfigSupport, OutputStreamTest,
+ ::testing::Combine(
+ ::testing::ValuesIn(getDeviceParameters()),
+ ::testing::ValuesIn(ConfigHelper::getRecommendedSupportPlaybackAudioConfig())),
+ &DeviceConfigParameterToString);
////////////////////////////// openInputStream //////////////////////////////
@@ -773,14 +907,15 @@
ASSERT_NO_FATAL_FAILURE(OpenStreamTest::SetUp()); // setup base
if (IsSkipped()) return; // do not attempt to use 'device'
address.device = AudioDevice::IN_DEFAULT;
- const AudioConfig& config = GetParam();
+ const AudioConfig& config = getConfig();
// TODO: test all supported flags and source
auto flags = mkEnumBitfield(AudioInputFlag::NONE);
testOpen(
- [&](AudioIoHandle handle, AudioConfig config, auto cb) {
- return device->openInputStream(handle, address, config, flags, initMetadata, cb);
- },
- config);
+ [&](AudioIoHandle handle, AudioConfig config, auto cb) {
+ return getDevice()->openInputStream(handle, address, config, flags,
+ initMetadata, cb);
+ },
+ config);
}
protected:
@@ -798,34 +933,28 @@
// Open done in setup
}
INSTANTIATE_TEST_CASE_P(
- RequiredInputStreamConfigSupport, InputStreamTest,
- ::testing::ValuesIn(AudioConfigPrimaryTest::getRequiredSupportCaptureAudioConfig()),
- &generateTestName);
+ RequiredInputStreamConfigSupport, InputStreamTest,
+ ::testing::Combine(
+ ::testing::ValuesIn(getDeviceParameters()),
+ ::testing::ValuesIn(ConfigHelper::getRequiredSupportCaptureAudioConfig())),
+ &DeviceConfigParameterToString);
INSTANTIATE_TEST_CASE_P(
- SupportedInputStreamConfig, InputStreamTest,
- ::testing::ValuesIn(AudioConfigPrimaryTest::getSupportedCaptureAudioConfig()),
- &generateTestName);
+ SupportedInputStreamConfig, InputStreamTest,
+ ::testing::Combine(::testing::ValuesIn(getDeviceParameters()),
+ ::testing::ValuesIn(ConfigHelper::getSupportedCaptureAudioConfig())),
+ &DeviceConfigParameterToString);
INSTANTIATE_TEST_CASE_P(
- RecommendedInputStreamConfigSupport, InputStreamTest,
- ::testing::ValuesIn(AudioConfigPrimaryTest::getRecommendedSupportCaptureAudioConfig()),
- &generateTestName);
+ RecommendedInputStreamConfigSupport, InputStreamTest,
+ ::testing::Combine(
+ ::testing::ValuesIn(getDeviceParameters()),
+ ::testing::ValuesIn(ConfigHelper::getRecommendedSupportCaptureAudioConfig())),
+ &DeviceConfigParameterToString);
//////////////////////////////////////////////////////////////////////////////
////////////////////////////// IStream getters ///////////////////////////////
//////////////////////////////////////////////////////////////////////////////
-/** Unpack the provided result.
- * If the result is not OK, register a failure and return an undefined value. */
-template <class R>
-static R extract(Return<R> ret) {
- if (!ret.isOk()) {
- EXPECT_IS_OK(ret);
- return R{};
- }
- return ret;
-}
-
/* Could not find a way to write a test for two parametrized class fixure
* thus use this macro do duplicate tests for Input and Output stream */
#define TEST_IO_STREAM(test_name, documentation, code) \
@@ -1003,8 +1132,14 @@
ASSERT_RESULT(invalidStateOrNotSupported, stream->stop()))
TEST_IO_STREAM(close, "Make sure a stream can be closed", ASSERT_OK(closeStream()))
-TEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice", ASSERT_OK(closeStream());
- ASSERT_RESULT(Result::INVALID_STATE, closeStream()))
+// clang-format off
+TEST_IO_STREAM(closeTwice, "Make sure a stream can not be closed twice",
+ auto streamCopy = stream;
+ ASSERT_OK(closeStream());
+ ASSERT_RESULT(Result::INVALID_STATE, streamCopy->close());
+ streamCopy.clear();
+ waitForStreamDestruction())
+// clang-format on
static void testCreateTooBigMmapBuffer(IStream* stream) {
MmapBufferInfo info;
@@ -1169,11 +1304,7 @@
struct Capability {
Capability(IStreamOut* stream) {
EXPECT_OK(stream->supportsPauseAndResume(returnIn(pause, resume)));
- auto ret = stream->supportsDrain();
- EXPECT_IS_OK(ret);
- if (ret.isOk()) {
- drain = ret;
- }
+ drain = extract(stream->supportsDrain());
}
bool pause = false;
bool resume = false;
@@ -1185,19 +1316,6 @@
Capability(stream.get());
}
-template <class Value>
-static void checkInvalidStateOr0(Result res, Value value) {
- switch (res) {
- case Result::INVALID_STATE:
- break;
- case Result::OK:
- ASSERT_EQ(0U, value);
- break;
- default:
- FAIL() << "Unexpected result " << toString(res);
- }
-}
-
TEST_P(OutputStreamTest, GetRenderPosition) {
doc::test("A new stream render position should be 0 or INVALID_STATE");
uint32_t dspFrames;
@@ -1206,7 +1324,7 @@
doc::partialTest("getRenderPosition is not supported");
return;
}
- checkInvalidStateOr0(res, dspFrames);
+ expectValueOrFailure(res, 0U, dspFrames, Result::INVALID_STATE);
}
TEST_P(OutputStreamTest, GetNextWriteTimestamp) {
@@ -1217,7 +1335,7 @@
doc::partialTest("getNextWriteTimestamp is not supported");
return;
}
- checkInvalidStateOr0(res, timestampUs);
+ expectValueOrFailure(res, uint64_t{0}, timestampUs, Result::INVALID_STATE);
}
/** Stub implementation of out stream callback. */
@@ -1344,19 +1462,19 @@
/////////////////////////////// PrimaryDevice ////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
-TEST_F(AudioPrimaryHidlTest, setVoiceVolume) {
+TEST_P(AudioPrimaryHidlTest, setVoiceVolume) {
doc::test("Make sure setVoiceVolume only succeed if volume is in [0,1]");
- testUnitaryGain([](float volume) { return device->setVoiceVolume(volume); });
+ testUnitaryGain([this](float volume) { return getDevice()->setVoiceVolume(volume); });
}
-TEST_F(BoolAccessorPrimaryHidlTest, BtScoNrecEnabled) {
+TEST_P(BoolAccessorPrimaryHidlTest, BtScoNrecEnabled) {
doc::test("Query and set the BT SCO NR&EC state");
testAccessors<OPTIONAL>("BtScoNrecEnabled", Initial{false, OPTIONAL}, {true},
&IPrimaryDevice::setBtScoNrecEnabled,
&IPrimaryDevice::getBtScoNrecEnabled);
}
-TEST_F(BoolAccessorPrimaryHidlTest, setGetBtScoWidebandEnabled) {
+TEST_P(BoolAccessorPrimaryHidlTest, setGetBtScoWidebandEnabled) {
doc::test("Query and set the SCO whideband state");
testAccessors<OPTIONAL>("BtScoWideband", Initial{false, OPTIONAL}, {true},
&IPrimaryDevice::setBtScoWidebandEnabled,
@@ -1364,15 +1482,17 @@
}
using TtyModeAccessorPrimaryHidlTest = AccessorPrimaryHidlTest<IPrimaryDevice::TtyMode>;
-TEST_F(TtyModeAccessorPrimaryHidlTest, setGetTtyMode) {
+TEST_P(TtyModeAccessorPrimaryHidlTest, setGetTtyMode) {
doc::test("Query and set the TTY mode state");
testAccessors<OPTIONAL>(
"TTY mode", Initial{IPrimaryDevice::TtyMode::OFF},
{IPrimaryDevice::TtyMode::HCO, IPrimaryDevice::TtyMode::VCO, IPrimaryDevice::TtyMode::FULL},
&IPrimaryDevice::setTtyMode, &IPrimaryDevice::getTtyMode);
}
+INSTANTIATE_TEST_CASE_P(TtyModeAccessorPrimaryHidl, TtyModeAccessorPrimaryHidlTest,
+ ::testing::ValuesIn(getDeviceParameters()), &DeviceParameterToString);
-TEST_F(BoolAccessorPrimaryHidlTest, setGetHac) {
+TEST_P(BoolAccessorPrimaryHidlTest, setGetHac) {
doc::test("Query and set the HAC state");
testAccessors<OPTIONAL>("HAC", Initial{false}, {true}, &IPrimaryDevice::setHacEnabled,
&IPrimaryDevice::getHacEnabled);
@@ -1384,9 +1504,13 @@
int main(int argc, char** argv) {
environment = new AudioHidlTestEnvironment;
+ // For V2..5 it's critical to initialize environment before GTest.
+ // The environment parses the service name from the command line,
+ // then it can be used in GTest parameter generators which are
+ // initialized during the call to InitGoogleTest.
+ environment->init(&argc, argv);
::testing::AddGlobalTestEnvironment(environment);
::testing::InitGoogleTest(&argc, argv);
- environment->init(&argc, argv);
int status = RUN_ALL_TESTS();
return status;
}
diff --git a/audio/core/all-versions/vts/functional/DeviceManager.h b/audio/core/all-versions/vts/functional/DeviceManager.h
new file mode 100644
index 0000000..b6e2db0
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/DeviceManager.h
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ */
+
+// Code in this file uses 'environment'
+#ifndef AUDIO_PRIMARY_HIDL_HAL_TEST
+#error Must be included from AudioPrimaryHidlTest.h
+#endif
+
+template <class Derived, class Key, class Interface>
+class InterfaceManager {
+ public:
+ sp<Interface> get(const Key& name) {
+ auto existing = instances.find(name);
+ if (existing != instances.end()) return existing->second;
+ auto [inserted, _] = instances.emplace(name, Derived::createInterfaceInstance(name));
+ if (inserted->second) {
+ environment->registerTearDown([name]() { (void)Derived::getInstance().reset(name); });
+ }
+ return inserted->second;
+ }
+
+ // The test must check that reset was successful. Reset failure means that the test code
+ // is holding a strong reference to the device.
+ bool reset(const Key& name) __attribute__((warn_unused_result)) {
+ auto iter = instances.find(name);
+ if (iter == instances.end()) return true;
+ ::android::wp<Interface> weak = iter->second;
+ instances.erase(iter);
+ if (weak.promote() != nullptr) return false;
+ waitForInstanceDestruction();
+ return true;
+ }
+
+ static void waitForInstanceDestruction() {
+ // FIXME: there is no way to know when the remote IDevice is being destroyed
+ // Binder does not support testing if an object is alive, thus
+ // wait for 100ms to let the binder destruction propagates and
+ // the remote device has the time to be destroyed.
+ // flushCommand makes sure all local command are sent, thus should reduce
+ // the latency between local and remote destruction.
+ IPCThreadState::self()->flushCommands();
+ usleep(100 * 1000);
+ }
+
+ protected:
+ std::map<Key, sp<Interface>> instances;
+};
+
+class DevicesFactoryManager
+ : public InterfaceManager<DevicesFactoryManager, std::string, IDevicesFactory> {
+ public:
+ static DevicesFactoryManager& getInstance() {
+ static DevicesFactoryManager instance;
+ return instance;
+ }
+ static sp<IDevicesFactory> createInterfaceInstance(const std::string& name) {
+#if MAJOR_VERSION <= 5
+ return ::testing::VtsHalHidlTargetTestBase::getService<IDevicesFactory>(name);
+#elif MAJOR_VERSION >= 6
+ return IDevicesFactory::getService(name);
+#endif
+ }
+};
+
+using FactoryAndDevice = std::tuple<std::string, std::string>;
+class DeviceManager : public InterfaceManager<DeviceManager, FactoryAndDevice, IDevice> {
+ public:
+ static DeviceManager& getInstance() {
+ static DeviceManager instance;
+ return instance;
+ }
+ static sp<IDevice> createInterfaceInstance(const FactoryAndDevice& factoryAndDevice) {
+ auto [factoryName, name] = factoryAndDevice;
+ sp<IDevicesFactory> factory = DevicesFactoryManager::getInstance().get(factoryName);
+ return name == kPrimaryDevice ? openPrimaryDevice(factory) : openDevice(factory, name);
+ }
+ using InterfaceManager::reset;
+
+ static constexpr const char* kPrimaryDevice = "primary";
+
+ sp<IDevice> get(const std::string& factoryName, const std::string& name) {
+ return InterfaceManager::get(std::make_tuple(factoryName, name));
+ }
+ sp<IPrimaryDevice> getPrimary(const std::string& factoryName) {
+ sp<IDevice> device = get(factoryName, kPrimaryDevice);
+ return device != nullptr ? IPrimaryDevice::castFrom(device) : nullptr;
+ }
+ bool reset(const std::string& factoryName, const std::string& name)
+ __attribute__((warn_unused_result)) {
+ return InterfaceManager::reset(std::make_tuple(factoryName, name));
+ }
+ bool resetPrimary(const std::string& factoryName) __attribute__((warn_unused_result)) {
+ return reset(factoryName, kPrimaryDevice);
+ }
+
+ private:
+ static sp<IDevice> openDevice(const sp<IDevicesFactory>& factory, const std::string& name) {
+ if (factory == nullptr) return nullptr;
+ sp<IDevice> device;
+#if MAJOR_VERSION >= 4
+ Result result;
+ auto ret = factory->openDevice(name, returnIn(result, device));
+ if (!ret.isOk() || result != Result::OK || device == nullptr) {
+ ALOGW("Device %s can not be opened, transaction: %s, result %d, device %p",
+ name.c_str(), ret.description().c_str(), result, device.get());
+ return nullptr;
+ }
+#else
+ (void)name;
+#endif
+ return device;
+ }
+
+ static sp<IDevice> openPrimaryDevice(const sp<IDevicesFactory>& factory) {
+ if (factory == nullptr) return nullptr;
+ Result result;
+ sp<IDevice> device;
+#if MAJOR_VERSION == 2
+ auto ret = factory->openDevice(IDevicesFactory::Device::PRIMARY, returnIn(result, device));
+#elif MAJOR_VERSION >= 4
+ auto ret = factory->openPrimaryDevice(returnIn(result, device));
+#endif
+ if (!ret.isOk() || result != Result::OK || device == nullptr) {
+ ALOGW("Primary device can not be opened, transaction: %s, result %d, device %p",
+ ret.description().c_str(), result, device.get());
+ return nullptr;
+ }
+ return device;
+ }
+};
diff --git a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
index c4c7f7c..3c712b5 100644
--- a/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
+++ b/audio/effect/all-versions/vts/functional/VtsHalAudioEffectTargetTest.cpp
@@ -28,8 +28,14 @@
#include <common/all-versions/VersionUtils.h>
+#if MAJOR_VERSION <= 5
#include <VtsHalHidlTargetTestBase.h>
#include <VtsHalHidlTargetTestEnvBase.h>
+#elif MAJOR_VERSION >= 6
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+#endif
using ::android::sp;
using ::android::hardware::hidl_handle;
@@ -49,6 +55,11 @@
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
#endif
+#if MAJOR_VERSION <= 5
+// For HAL versions 2..5 Vts Environment and Test base classes are used.
+// The tests are non-parametrized.
+#define EFFECT_TEST TEST_F
+
// Test environment for Audio Effects Factory HIDL HAL.
class AudioEffectsFactoryHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
public:
@@ -71,6 +82,18 @@
ASSERT_NE(effectsFactory, nullptr);
}
+#elif MAJOR_VERSION >= 6
+// For HAL version 6 and above, standard GTest Environment and Test base classes are used.
+// The tests are parametrized by the IEffectsFactory instance name.
+#define EFFECT_TEST TEST_P
+
+class AudioEffectsFactoryHidlTest : public ::testing::TestWithParam<std::string> {
+ public:
+ void SetUp() override {
+ effectsFactory = IEffectsFactory::getService(GetParam());
+ ASSERT_NE(effectsFactory, nullptr);
+ }
+#endif // The rest of the AudioEffectsFactoryHidlTest class definition is the same.
void TearDown() override { effectsFactory.clear(); }
protected:
@@ -81,7 +104,7 @@
sp<IEffectsFactory> effectsFactory;
};
-TEST_F(AudioEffectsFactoryHidlTest, EnumerateEffects) {
+EFFECT_TEST(AudioEffectsFactoryHidlTest, EnumerateEffects) {
description("Verify that EnumerateEffects returns at least one effect");
Result retval = Result::NOT_INITIALIZED;
size_t effectCount = 0;
@@ -95,7 +118,7 @@
EXPECT_GT(effectCount, 0u);
}
-TEST_F(AudioEffectsFactoryHidlTest, CreateEffect) {
+EFFECT_TEST(AudioEffectsFactoryHidlTest, CreateEffect) {
description("Verify that an effect can be created via CreateEffect");
bool gotEffect = false;
Uuid effectUuid;
@@ -123,7 +146,7 @@
EXPECT_NE(nullptr, effect.get());
}
-TEST_F(AudioEffectsFactoryHidlTest, GetDescriptor) {
+EFFECT_TEST(AudioEffectsFactoryHidlTest, GetDescriptor) {
description(
"Verify that effects factory can provide an effect descriptor via "
"GetDescriptor");
@@ -146,7 +169,7 @@
EXPECT_TRUE(ret.isOk());
}
-TEST_F(AudioEffectsFactoryHidlTest, DebugDumpInvalidArgument) {
+EFFECT_TEST(AudioEffectsFactoryHidlTest, DebugDumpInvalidArgument) {
description("Verify that debugDump doesn't crash on invalid arguments");
#if MAJOR_VERSION == 2
Return<void> ret = effectsFactory->debugDump(hidl_handle());
@@ -168,10 +191,17 @@
std::array<uint8_t, 6>{{0x11, 0x26, 0x0e, 0xb6, 0x3c, 0xf1}}};
// The main test class for Audio Effect HIDL HAL.
+#if MAJOR_VERSION <= 5
class AudioEffectHidlTest : public ::testing::VtsHalHidlTargetTestBase {
public:
void SetUp() override {
effectsFactory = ::testing::VtsHalHidlTargetTestBase::getService<IEffectsFactory>();
+#elif MAJOR_VERSION >= 6
+class AudioEffectHidlTest : public ::testing::TestWithParam<std::string> {
+ public:
+ void SetUp() override {
+ effectsFactory = IEffectsFactory::getService(GetParam());
+#endif
ASSERT_NE(nullptr, effectsFactory.get());
findAndCreateEffect(getEffectType());
@@ -250,14 +280,14 @@
static_cast<audio_channel_mask_t>(currentConfig.outputCfg.channels));
}
-TEST_F(AudioEffectHidlTest, Close) {
+EFFECT_TEST(AudioEffectHidlTest, Close) {
description("Verify that an effect can be closed");
Return<Result> ret = effect->close();
EXPECT_TRUE(ret.isOk());
EXPECT_EQ(Result::OK, ret);
}
-TEST_F(AudioEffectHidlTest, GetDescriptor) {
+EFFECT_TEST(AudioEffectHidlTest, GetDescriptor) {
description("Verify that an effect can return its own descriptor via GetDescriptor");
Result retval = Result::NOT_INITIALIZED;
Uuid actualType;
@@ -272,7 +302,7 @@
EXPECT_EQ(getEffectType(), actualType);
}
-TEST_F(AudioEffectHidlTest, GetSetConfig) {
+EFFECT_TEST(AudioEffectHidlTest, GetSetConfig) {
description(
"Verify that it is possible to manipulate effect config via Get / "
"SetConfig");
@@ -291,26 +321,26 @@
EXPECT_EQ(Result::OK, ret2);
}
-TEST_F(AudioEffectHidlTest, GetConfigReverse) {
+EFFECT_TEST(AudioEffectHidlTest, GetConfigReverse) {
description("Verify that GetConfigReverse does not crash");
Return<void> ret = effect->getConfigReverse([&](Result, const EffectConfig&) {});
EXPECT_TRUE(ret.isOk());
}
-TEST_F(AudioEffectHidlTest, GetSupportedAuxChannelsConfigs) {
+EFFECT_TEST(AudioEffectHidlTest, GetSupportedAuxChannelsConfigs) {
description("Verify that GetSupportedAuxChannelsConfigs does not crash");
Return<void> ret = effect->getSupportedAuxChannelsConfigs(
0, [&](Result, const hidl_vec<EffectAuxChannelsConfig>&) {});
EXPECT_TRUE(ret.isOk());
}
-TEST_F(AudioEffectHidlTest, GetAuxChannelsConfig) {
+EFFECT_TEST(AudioEffectHidlTest, GetAuxChannelsConfig) {
description("Verify that GetAuxChannelsConfig does not crash");
Return<void> ret = effect->getAuxChannelsConfig([&](Result, const EffectAuxChannelsConfig&) {});
EXPECT_TRUE(ret.isOk());
}
-TEST_F(AudioEffectHidlTest, SetAuxChannelsConfig) {
+EFFECT_TEST(AudioEffectHidlTest, SetAuxChannelsConfig) {
description("Verify that SetAuxChannelsConfig does not crash");
Return<Result> ret = effect->setAuxChannelsConfig(EffectAuxChannelsConfig());
EXPECT_TRUE(ret.isOk());
@@ -349,7 +379,7 @@
} // namespace hardware
} // namespace android
-TEST_F(AudioEffectHidlTest, Reset) {
+EFFECT_TEST(AudioEffectHidlTest, Reset) {
description("Verify that Reset preserves effect configuration");
Result retval = Result::NOT_INITIALIZED;
EffectConfig originalConfig;
@@ -374,7 +404,7 @@
EXPECT_EQ(originalConfig, configAfterReset);
}
-TEST_F(AudioEffectHidlTest, DisableEnableDisable) {
+EFFECT_TEST(AudioEffectHidlTest, DisableEnableDisable) {
description("Verify Disable -> Enable -> Disable sequence for an effect");
Return<Result> ret = effect->disable();
EXPECT_TRUE(ret.isOk());
@@ -387,14 +417,14 @@
EXPECT_EQ(Result::OK, ret);
}
-TEST_F(AudioEffectHidlTest, SetDevice) {
+EFFECT_TEST(AudioEffectHidlTest, SetDevice) {
description("Verify that SetDevice works for an output chain effect");
Return<Result> ret = effect->setDevice(mkEnumBitfield(AudioDevice::OUT_SPEAKER));
EXPECT_TRUE(ret.isOk());
EXPECT_EQ(Result::OK, ret);
}
-TEST_F(AudioEffectHidlTest, SetAndGetVolume) {
+EFFECT_TEST(AudioEffectHidlTest, SetAndGetVolume) {
description("Verify that SetAndGetVolume method works for an effect");
uint32_t channelCount;
getChannelCount(&channelCount);
@@ -410,7 +440,7 @@
EXPECT_EQ(Result::OK, retval);
}
-TEST_F(AudioEffectHidlTest, VolumeChangeNotification) {
+EFFECT_TEST(AudioEffectHidlTest, VolumeChangeNotification) {
description("Verify that effect accepts VolumeChangeNotification");
uint32_t channelCount;
getChannelCount(&channelCount);
@@ -424,32 +454,32 @@
EXPECT_EQ(Result::OK, ret);
}
-TEST_F(AudioEffectHidlTest, SetAudioMode) {
+EFFECT_TEST(AudioEffectHidlTest, SetAudioMode) {
description("Verify that SetAudioMode works for an effect");
Return<Result> ret = effect->setAudioMode(AudioMode::NORMAL);
EXPECT_TRUE(ret.isOk());
EXPECT_EQ(Result::OK, ret);
}
-TEST_F(AudioEffectHidlTest, SetConfigReverse) {
+EFFECT_TEST(AudioEffectHidlTest, SetConfigReverse) {
description("Verify that SetConfigReverse does not crash");
Return<Result> ret = effect->setConfigReverse(EffectConfig(), nullptr, nullptr);
EXPECT_TRUE(ret.isOk());
}
-TEST_F(AudioEffectHidlTest, SetInputDevice) {
+EFFECT_TEST(AudioEffectHidlTest, SetInputDevice) {
description("Verify that SetInputDevice does not crash");
Return<Result> ret = effect->setInputDevice(mkEnumBitfield(AudioDevice::IN_BUILTIN_MIC));
EXPECT_TRUE(ret.isOk());
}
-TEST_F(AudioEffectHidlTest, SetAudioSource) {
+EFFECT_TEST(AudioEffectHidlTest, SetAudioSource) {
description("Verify that SetAudioSource does not crash");
Return<Result> ret = effect->setAudioSource(AudioSource::MIC);
EXPECT_TRUE(ret.isOk());
}
-TEST_F(AudioEffectHidlTest, Offload) {
+EFFECT_TEST(AudioEffectHidlTest, Offload) {
description("Verify that calling Offload method does not crash");
EffectOffloadParameter offloadParam;
offloadParam.isOffload = false;
@@ -458,7 +488,7 @@
EXPECT_TRUE(ret.isOk());
}
-TEST_F(AudioEffectHidlTest, PrepareForProcessing) {
+EFFECT_TEST(AudioEffectHidlTest, PrepareForProcessing) {
description("Verify that PrepareForProcessing method works for an effect");
Result retval = Result::NOT_INITIALIZED;
Return<void> ret = effect->prepareForProcessing(
@@ -467,7 +497,7 @@
EXPECT_EQ(Result::OK, retval);
}
-TEST_F(AudioEffectHidlTest, SetProcessBuffers) {
+EFFECT_TEST(AudioEffectHidlTest, SetProcessBuffers) {
description("Verify that SetProcessBuffers works for an effect");
sp<IAllocator> ashmem = IAllocator::getService("ashmem");
ASSERT_NE(nullptr, ashmem.get());
@@ -486,41 +516,41 @@
EXPECT_EQ(Result::OK, ret2);
}
-TEST_F(AudioEffectHidlTest, Command) {
+EFFECT_TEST(AudioEffectHidlTest, Command) {
description("Verify that Command does not crash");
Return<void> ret =
effect->command(0, hidl_vec<uint8_t>(), 0, [&](int32_t, const hidl_vec<uint8_t>&) {});
EXPECT_TRUE(ret.isOk());
}
-TEST_F(AudioEffectHidlTest, SetParameter) {
+EFFECT_TEST(AudioEffectHidlTest, SetParameter) {
description("Verify that SetParameter does not crash");
Return<Result> ret = effect->setParameter(hidl_vec<uint8_t>(), hidl_vec<uint8_t>());
EXPECT_TRUE(ret.isOk());
}
-TEST_F(AudioEffectHidlTest, GetParameter) {
+EFFECT_TEST(AudioEffectHidlTest, GetParameter) {
description("Verify that GetParameter does not crash");
Return<void> ret =
effect->getParameter(hidl_vec<uint8_t>(), 0, [&](Result, const hidl_vec<uint8_t>&) {});
EXPECT_TRUE(ret.isOk());
}
-TEST_F(AudioEffectHidlTest, GetSupportedConfigsForFeature) {
+EFFECT_TEST(AudioEffectHidlTest, GetSupportedConfigsForFeature) {
description("Verify that GetSupportedConfigsForFeature does not crash");
Return<void> ret = effect->getSupportedConfigsForFeature(
0, 0, 0, [&](Result, uint32_t, const hidl_vec<uint8_t>&) {});
EXPECT_TRUE(ret.isOk());
}
-TEST_F(AudioEffectHidlTest, GetCurrentConfigForFeature) {
+EFFECT_TEST(AudioEffectHidlTest, GetCurrentConfigForFeature) {
description("Verify that GetCurrentConfigForFeature does not crash");
Return<void> ret =
effect->getCurrentConfigForFeature(0, 0, [&](Result, const hidl_vec<uint8_t>&) {});
EXPECT_TRUE(ret.isOk());
}
-TEST_F(AudioEffectHidlTest, SetCurrentConfigForFeature) {
+EFFECT_TEST(AudioEffectHidlTest, SetCurrentConfigForFeature) {
description("Verify that SetCurrentConfigForFeature does not crash");
Return<Result> ret = effect->setCurrentConfigForFeature(0, hidl_vec<uint8_t>());
EXPECT_TRUE(ret.isOk());
@@ -606,21 +636,21 @@
ASSERT_EQ(Result::OK, retval);
}
-TEST_F(EqualizerAudioEffectHidlTest, GetNumBands) {
+EFFECT_TEST(EqualizerAudioEffectHidlTest, GetNumBands) {
description("Verify that Equalizer effect reports at least one band");
uint16_t numBands = 0;
getNumBands(&numBands);
EXPECT_GT(numBands, 0);
}
-TEST_F(EqualizerAudioEffectHidlTest, GetLevelRange) {
+EFFECT_TEST(EqualizerAudioEffectHidlTest, GetLevelRange) {
description("Verify that Equalizer effect reports adequate band level range");
int16_t minLevel = 0x7fff, maxLevel = 0;
getLevelRange(&minLevel, &maxLevel);
EXPECT_GT(maxLevel, minLevel);
}
-TEST_F(EqualizerAudioEffectHidlTest, GetSetBandLevel) {
+EFFECT_TEST(EqualizerAudioEffectHidlTest, GetSetBandLevel) {
description("Verify that manipulating band levels works for Equalizer effect");
uint16_t numBands = 0;
getNumBands(&numBands);
@@ -649,7 +679,7 @@
}
}
-TEST_F(EqualizerAudioEffectHidlTest, GetBandCenterFrequencyAndRange) {
+EFFECT_TEST(EqualizerAudioEffectHidlTest, GetBandCenterFrequencyAndRange) {
description("Verify that Equalizer effect reports adequate band frequency range");
uint16_t numBands = 0;
getNumBands(&numBands);
@@ -664,7 +694,7 @@
}
}
-TEST_F(EqualizerAudioEffectHidlTest, GetBandForFrequency) {
+EFFECT_TEST(EqualizerAudioEffectHidlTest, GetBandForFrequency) {
description("Verify that Equalizer effect supports GetBandForFrequency correctly");
uint16_t numBands = 0;
getNumBands(&numBands);
@@ -693,14 +723,14 @@
}
}
-TEST_F(EqualizerAudioEffectHidlTest, GetPresetNames) {
+EFFECT_TEST(EqualizerAudioEffectHidlTest, GetPresetNames) {
description("Verify that Equalizer effect reports at least one preset");
size_t presetCount;
getPresetCount(&presetCount);
EXPECT_GT(presetCount, 0u);
}
-TEST_F(EqualizerAudioEffectHidlTest, GetSetCurrentPreset) {
+EFFECT_TEST(EqualizerAudioEffectHidlTest, GetSetCurrentPreset) {
description("Verify that manipulating the current preset for Equalizer effect");
size_t presetCount;
getPresetCount(&presetCount);
@@ -723,7 +753,7 @@
}
}
-TEST_F(EqualizerAudioEffectHidlTest, GetSetAllProperties) {
+EFFECT_TEST(EqualizerAudioEffectHidlTest, GetSetAllProperties) {
description(
"Verify that setting band levels and presets works via Get / "
"SetAllProperties for Equalizer effect");
@@ -787,7 +817,7 @@
sp<ILoudnessEnhancerEffect> enhancer;
};
-TEST_F(LoudnessEnhancerAudioEffectHidlTest, GetSetTargetGain) {
+EFFECT_TEST(LoudnessEnhancerAudioEffectHidlTest, GetSetTargetGain) {
description(
"Verify that manipulating the target gain works for Loudness Enhancer "
"effect");
@@ -808,6 +838,7 @@
EXPECT_EQ(gain, actualGain);
}
+#if MAJOR_VERSION <= 5
int main(int argc, char** argv) {
::testing::AddGlobalTestEnvironment(AudioEffectsFactoryHidlEnvironment::Instance());
::testing::InitGoogleTest(&argc, argv);
@@ -816,3 +847,17 @@
LOG(INFO) << "Test result = " << status;
return status;
}
+#elif MAJOR_VERSION >= 6
+INSTANTIATE_TEST_SUITE_P(
+ EffectsFactory, AudioEffectsFactoryHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IEffectsFactory::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+INSTANTIATE_TEST_SUITE_P(
+ Equalizer, EqualizerAudioEffectHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IEffectsFactory::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+INSTANTIATE_TEST_SUITE_P(
+ LoudnessEnhancer, LoudnessEnhancerAudioEffectHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IEffectsFactory::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+#endif
diff --git a/biometrics/fingerprint/2.1/vts/functional/Android.bp b/biometrics/fingerprint/2.1/vts/functional/Android.bp
index 60228f2..c418032 100644
--- a/biometrics/fingerprint/2.1/vts/functional/Android.bp
+++ b/biometrics/fingerprint/2.1/vts/functional/Android.bp
@@ -19,6 +19,6 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalBiometricsFingerprintV2_1TargetTest.cpp"],
static_libs: ["android.hardware.biometrics.fingerprint@2.1"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/boot/1.0/vts/functional/Android.bp b/boot/1.0/vts/functional/Android.bp
index 5d1a9cb..5244b95 100644
--- a/boot/1.0/vts/functional/Android.bp
+++ b/boot/1.0/vts/functional/Android.bp
@@ -19,5 +19,5 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalBootV1_0TargetTest.cpp"],
static_libs: ["android.hardware.boot@1.0"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/boot/1.0/vts/functional/VtsHalBootV1_0TargetTest.cpp b/boot/1.0/vts/functional/VtsHalBootV1_0TargetTest.cpp
index 2f2052c..fbddf6d 100644
--- a/boot/1.0/vts/functional/VtsHalBootV1_0TargetTest.cpp
+++ b/boot/1.0/vts/functional/VtsHalBootV1_0TargetTest.cpp
@@ -21,8 +21,9 @@
#include <android/hardware/boot/1.0/IBootControl.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <unordered_set>
@@ -37,30 +38,17 @@
using std::unordered_set;
using std::vector;
-// Test environment for Boot HIDL HAL.
-class BootHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static BootHidlEnvironment* Instance() {
- static BootHidlEnvironment* instance = new BootHidlEnvironment;
- return instance;
+// The main test class for the Boot HIDL HAL.
+class BootHidlTest : public ::testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ boot = IBootControl::getService(GetParam());
+ ASSERT_NE(boot, nullptr);
}
- virtual void registerTestServices() override { registerTestService<IBootControl>(); }
-};
+ virtual void TearDown() override {}
-// The main test class for the Boot HIDL HAL.
-class BootHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- public:
- virtual void SetUp() override {
- boot = ::testing::VtsHalHidlTargetTestBase::getService<IBootControl>(
- BootHidlEnvironment::Instance()->getServiceName<IBootControl>());
- ASSERT_NE(boot, nullptr);
- }
-
- virtual void TearDown() override {}
-
- sp<IBootControl> boot;
+ sp<IBootControl> boot;
};
auto generate_callback(CommandResult *dest) {
@@ -68,108 +56,105 @@
}
// Sanity check Boot::getNumberSlots().
-TEST_F(BootHidlTest, GetNumberSlots) {
- uint32_t slots = boot->getNumberSlots();
- EXPECT_LE((uint32_t)2, slots);
+TEST_P(BootHidlTest, GetNumberSlots) {
+ uint32_t slots = boot->getNumberSlots();
+ EXPECT_LE((uint32_t)2, slots);
}
// Sanity check Boot::getCurrentSlot().
-TEST_F(BootHidlTest, GetCurrentSlot) {
- Slot curSlot = boot->getCurrentSlot();
- uint32_t slots = boot->getNumberSlots();
- EXPECT_LT(curSlot, slots);
+TEST_P(BootHidlTest, GetCurrentSlot) {
+ Slot curSlot = boot->getCurrentSlot();
+ uint32_t slots = boot->getNumberSlots();
+ EXPECT_LT(curSlot, slots);
}
// Sanity check Boot::markBootSuccessful().
-TEST_F(BootHidlTest, MarkBootSuccessful) {
- CommandResult cr;
- Return<void> result = boot->markBootSuccessful(generate_callback(&cr));
- ASSERT_TRUE(result.isOk());
- if (cr.success) {
- Slot curSlot = boot->getCurrentSlot();
- BoolResult ret = boot->isSlotMarkedSuccessful(curSlot);
- EXPECT_EQ(BoolResult::TRUE, ret);
- }
+TEST_P(BootHidlTest, MarkBootSuccessful) {
+ CommandResult cr;
+ Return<void> result = boot->markBootSuccessful(generate_callback(&cr));
+ ASSERT_TRUE(result.isOk());
+ if (cr.success) {
+ Slot curSlot = boot->getCurrentSlot();
+ BoolResult ret = boot->isSlotMarkedSuccessful(curSlot);
+ EXPECT_EQ(BoolResult::TRUE, ret);
+ }
}
// Sanity check Boot::setActiveBootSlot() on good and bad inputs.
-TEST_F(BootHidlTest, SetActiveBootSlot) {
- for (Slot s = 0; s < 2; s++) {
- CommandResult cr;
- Return<void> result = boot->setActiveBootSlot(s, generate_callback(&cr));
- EXPECT_TRUE(result.isOk());
- }
- {
- // Restore original flags to avoid problems on reboot
- CommandResult cr;
- Return<void> result = boot->markBootSuccessful(generate_callback(&cr));
- EXPECT_TRUE(result.isOk());
- EXPECT_TRUE(cr.success);
- }
- {
- CommandResult cr;
- uint32_t slots = boot->getNumberSlots();
- Return<void> result =
- boot->setActiveBootSlot(slots, generate_callback(&cr));
- ASSERT_TRUE(result.isOk());
- EXPECT_EQ(false, cr.success);
- }
+TEST_P(BootHidlTest, SetActiveBootSlot) {
+ for (Slot s = 0; s < 2; s++) {
+ CommandResult cr;
+ Return<void> result = boot->setActiveBootSlot(s, generate_callback(&cr));
+ EXPECT_TRUE(result.isOk());
+ }
+ {
+ // Restore original flags to avoid problems on reboot
+ CommandResult cr;
+ Return<void> result = boot->markBootSuccessful(generate_callback(&cr));
+ EXPECT_TRUE(result.isOk());
+ EXPECT_TRUE(cr.success);
+ }
+ {
+ CommandResult cr;
+ uint32_t slots = boot->getNumberSlots();
+ Return<void> result = boot->setActiveBootSlot(slots, generate_callback(&cr));
+ ASSERT_TRUE(result.isOk());
+ EXPECT_EQ(false, cr.success);
+ }
}
// Sanity check Boot::setSlotAsUnbootable() on good and bad inputs.
-TEST_F(BootHidlTest, SetSlotAsUnbootable) {
- {
- CommandResult cr;
- Slot curSlot = boot->getCurrentSlot();
- Slot otherSlot = curSlot ? 0 : 1;
- Return<void> result =
- boot->setSlotAsUnbootable(otherSlot, generate_callback(&cr));
- EXPECT_TRUE(result.isOk());
- if (cr.success) {
- EXPECT_EQ(BoolResult::FALSE, boot->isSlotBootable(otherSlot));
+TEST_P(BootHidlTest, SetSlotAsUnbootable) {
+ {
+ CommandResult cr;
+ Slot curSlot = boot->getCurrentSlot();
+ Slot otherSlot = curSlot ? 0 : 1;
+ Return<void> result = boot->setSlotAsUnbootable(otherSlot, generate_callback(&cr));
+ EXPECT_TRUE(result.isOk());
+ if (cr.success) {
+ EXPECT_EQ(BoolResult::FALSE, boot->isSlotBootable(otherSlot));
- // Restore original flags to avoid problems on reboot
- result = boot->setActiveBootSlot(otherSlot, generate_callback(&cr));
- EXPECT_TRUE(result.isOk());
- EXPECT_TRUE(cr.success);
- result = boot->setActiveBootSlot(curSlot, generate_callback(&cr));
- EXPECT_TRUE(result.isOk());
- EXPECT_TRUE(cr.success);
- result = boot->markBootSuccessful(generate_callback(&cr));
- EXPECT_TRUE(result.isOk());
- EXPECT_TRUE(cr.success);
+ // Restore original flags to avoid problems on reboot
+ result = boot->setActiveBootSlot(otherSlot, generate_callback(&cr));
+ EXPECT_TRUE(result.isOk());
+ EXPECT_TRUE(cr.success);
+ result = boot->setActiveBootSlot(curSlot, generate_callback(&cr));
+ EXPECT_TRUE(result.isOk());
+ EXPECT_TRUE(cr.success);
+ result = boot->markBootSuccessful(generate_callback(&cr));
+ EXPECT_TRUE(result.isOk());
+ EXPECT_TRUE(cr.success);
+ }
}
- }
- {
- CommandResult cr;
- uint32_t slots = boot->getNumberSlots();
- Return<void> result =
- boot->setSlotAsUnbootable(slots, generate_callback(&cr));
- EXPECT_TRUE(result.isOk());
- EXPECT_EQ(false, cr.success);
- }
+ {
+ CommandResult cr;
+ uint32_t slots = boot->getNumberSlots();
+ Return<void> result = boot->setSlotAsUnbootable(slots, generate_callback(&cr));
+ EXPECT_TRUE(result.isOk());
+ EXPECT_EQ(false, cr.success);
+ }
}
// Sanity check Boot::isSlotBootable() on good and bad inputs.
-TEST_F(BootHidlTest, IsSlotBootable) {
- for (Slot s = 0; s < 2; s++) {
- EXPECT_NE(BoolResult::INVALID_SLOT, boot->isSlotBootable(s));
- }
- uint32_t slots = boot->getNumberSlots();
- EXPECT_EQ(BoolResult::INVALID_SLOT, boot->isSlotBootable(slots));
+TEST_P(BootHidlTest, IsSlotBootable) {
+ for (Slot s = 0; s < 2; s++) {
+ EXPECT_NE(BoolResult::INVALID_SLOT, boot->isSlotBootable(s));
+ }
+ uint32_t slots = boot->getNumberSlots();
+ EXPECT_EQ(BoolResult::INVALID_SLOT, boot->isSlotBootable(slots));
}
// Sanity check Boot::isSlotMarkedSuccessful() on good and bad inputs.
-TEST_F(BootHidlTest, IsSlotMarkedSuccessful) {
- for (Slot s = 0; s < 2; s++) {
- EXPECT_NE(BoolResult::INVALID_SLOT, boot->isSlotMarkedSuccessful(s));
- }
- uint32_t slots = boot->getNumberSlots();
- EXPECT_EQ(BoolResult::INVALID_SLOT, boot->isSlotMarkedSuccessful(slots));
+TEST_P(BootHidlTest, IsSlotMarkedSuccessful) {
+ for (Slot s = 0; s < 2; s++) {
+ EXPECT_NE(BoolResult::INVALID_SLOT, boot->isSlotMarkedSuccessful(s));
+ }
+ uint32_t slots = boot->getNumberSlots();
+ EXPECT_EQ(BoolResult::INVALID_SLOT, boot->isSlotMarkedSuccessful(slots));
}
// Sanity check Boot::getSuffix() on good and bad inputs.
-TEST_F(BootHidlTest, GetSuffix) {
+TEST_P(BootHidlTest, GetSuffix) {
string suffixStr;
unordered_set<string> suffixes;
auto cb = [&](hidl_string suffix) { suffixStr = suffix.c_str(); };
@@ -191,11 +176,7 @@
}
}
-int main(int argc, char **argv) {
- ::testing::AddGlobalTestEnvironment(BootHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- BootHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, BootHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IBootControl::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 34cbe26..541cfc6 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -223,7 +223,7 @@
</hal>
<hal format="hidl" optional="false">
<name>android.hardware.health</name>
- <version>2.0</version>
+ <version>2.1</version>
<interface>
<name>IHealth</name>
<instance>default</instance>
diff --git a/configstore/1.0/vts/functional/Android.bp b/configstore/1.0/vts/functional/Android.bp
index 008b59d..31d4b1c 100644
--- a/configstore/1.0/vts/functional/Android.bp
+++ b/configstore/1.0/vts/functional/Android.bp
@@ -19,6 +19,6 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalConfigstoreV1_0TargetTest.cpp"],
static_libs: ["android.hardware.configstore@1.0"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/configstore/1.0/vts/functional/VtsHalConfigstoreV1_0TargetTest.cpp b/configstore/1.0/vts/functional/VtsHalConfigstoreV1_0TargetTest.cpp
index 70b5830..8a1a313 100644
--- a/configstore/1.0/vts/functional/VtsHalConfigstoreV1_0TargetTest.cpp
+++ b/configstore/1.0/vts/functional/VtsHalConfigstoreV1_0TargetTest.cpp
@@ -16,11 +16,12 @@
#define LOG_TAG "ConfigstoreHidlHalTest"
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <android-base/logging.h>
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
#include <android/hardware/configstore/1.0/types.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <unistd.h>
using ::android::hardware::configstore::V1_0::ISurfaceFlingerConfigs;
@@ -35,25 +36,12 @@
#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
#define EXPECT_OK(ret) EXPECT_TRUE(ret.isOk())
-// Test environment for Configstore HIDL HAL.
-class ConfigstoreHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static ConfigstoreHidlEnvironment* Instance() {
- static ConfigstoreHidlEnvironment* instance = new ConfigstoreHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<ISurfaceFlingerConfigs>(); }
-};
-
-class ConfigstoreHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class ConfigstoreHidlTest : public ::testing::TestWithParam<std::string> {
public:
sp<ISurfaceFlingerConfigs> sfConfigs;
virtual void SetUp() override {
- sfConfigs = ::testing::VtsHalHidlTargetTestBase::getService<ISurfaceFlingerConfigs>(
- ConfigstoreHidlEnvironment::Instance()->getServiceName<ISurfaceFlingerConfigs>());
+ sfConfigs = ISurfaceFlingerConfigs::getService(GetParam());
ASSERT_NE(sfConfigs, nullptr);
}
@@ -63,7 +51,7 @@
/**
* Ensure all ISurfaceFlingerConfigs.hal function calls are successful.
*/
-TEST_F(ConfigstoreHidlTest, TestFunctionCalls) {
+TEST_P(ConfigstoreHidlTest, TestFunctionCalls) {
bool tmp;
Return<void> status = sfConfigs->vsyncEventPhaseOffsetNs(
@@ -118,7 +106,7 @@
/**
* Ensure repeated call to the same function returns the same result.
*/
-TEST_F(ConfigstoreHidlTest, TestSameReturnValue) {
+TEST_P(ConfigstoreHidlTest, TestSameReturnValue) {
int64_t original_ret;
Return<void> status = sfConfigs->vsyncEventPhaseOffsetNs(
[&original_ret](OptionalInt64 arg) { original_ret = arg.value; });
@@ -135,7 +123,7 @@
* Make sure the constrains of hasWideColorDisplay, hasHDRDisplay
* are enforced.
*/
-TEST_F(ConfigstoreHidlTest, TestColorConstrainsBasic) {
+TEST_P(ConfigstoreHidlTest, TestColorConstrainsBasic) {
bool hasWideColorDisplay;
bool hasHDRDisplay;
@@ -152,11 +140,7 @@
}
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(ConfigstoreHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- ConfigstoreHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, ConfigstoreHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(ISurfaceFlingerConfigs::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/current.txt b/current.txt
index 87649d2..3ccc531 100644
--- a/current.txt
+++ b/current.txt
@@ -589,12 +589,17 @@
74049a402be913963edfdd80828a53736570e9d8124a1bf18166b6ed46a6b0ab android.hardware.boot@1.1::types
34515afa2bb792d3c6d8495a5f5d907d179c8507ca5e55c10050d02ae1d516ef android.hardware.neuralnetworks@1.3::IDevice
b74fe72cfe438f50e772e6a307657ff449d5bde83c15dd1f140ff2edbe73499c android.hardware.neuralnetworks@1.3::types
-04395b26be33db17747c3d3b0e8066d323f891ff4f9f3b3ddb490b2f3f844a18 android.hardware.wifi@1.4::IWifi
-270f0eb670dfd9bc5cd718e09711f2534fa8425f54d06c1a46523ca156b509e2 android.hardware.wifi.supplicant@1.3::ISupplicant
-dd4b7cfbb6e1c6ff011c33920762ad89dd02240c63a4d3a3d5037f154eae3e3b android.hardware.wifi.supplicant@1.3::ISupplicantStaIface
-619fc9839ec6e369cfa9b28e3e9412e6885720ff8f9b5750c1b6ffb905120391 android.hardware.wifi.supplicant@1.3::ISupplicantStaIfaceCallback
-6fe09b18e913608579638594788198ec45bb2369e567d7df661db46c4f0e5f08 android.hardware.wifi.supplicant@1.3::ISupplicantStaNetwork
-91931b05bd70ea6bdffbe075086183f803379571788564e28854207620eb75cf android.hardware.wifi.supplicant@1.3::types
544049dcda3f943ad67d83d5277f06681a3782982a9af5a78b5d4e8d295d061a android.hardware.vibrator@1.4::IVibrator
5e1c12efbbba89c9143d10b1b90eceff8bc79aa079f5106215b528e104fef101 android.hardware.vibrator@1.4::IVibratorCallback
033eae03c09ebc75e82db37bc39995dfaa9086745577b44d9e14e9ccb48bd8cc android.hardware.vibrator@1.4::types
+3e01d4446cd69fd1c48f8572efd97487bc179564b32bd795800b97bbe10be37b android.hardware.wifi@1.4::IWifi
+a64467bae843569f0d465c5be7f0c7a5b987985b55a3ef4794dd5afc68538650 android.hardware.wifi.supplicant@1.3::ISupplicant
+0a7ff83fd0326b82232e1609da98f34960be11335df72fc407ad238d7bd0e081 android.hardware.wifi.supplicant@1.3::ISupplicantStaIface
+619fc9839ec6e369cfa9b28e3e9412e6885720ff8f9b5750c1b6ffb905120391 android.hardware.wifi.supplicant@1.3::ISupplicantStaIfaceCallback
+c9273429fcf98d797d3bb07fdba6f1be95bf960f9255cde169fd1ca4db85f856 android.hardware.wifi.supplicant@1.3::ISupplicantStaNetwork
+b0f8c9cd61a45a8c1b4a8e40913ecaea0921011cbe2305a6fa5a2feaa0d36c30 android.hardware.wifi.supplicant@1.3::types
+41c602462ccd1b19cfd645994be4de4c07fc197ff58a54e84476b31908e61e21 android.hardware.radio@1.5::types
+a8691c71747c3f14f7a043598e856425077f755e55990507a9132ad62f8ab3f7 android.hardware.radio@1.5::IRadio
+a62a93faf173b14a6175b683ebf61ffa568dc61f81e369d2dce7b1265e86cf2f android.hardware.radio@1.5::IRadioIndication
+15daf260aaf6781b911450bc94e1a164901f9c0fe0bda68f8434f0a903f66e05 android.hardware.radio@1.5::IRadioResponse
+
diff --git a/dumpstate/1.0/vts/functional/Android.bp b/dumpstate/1.0/vts/functional/Android.bp
index fc64d05..3bac281 100644
--- a/dumpstate/1.0/vts/functional/Android.bp
+++ b/dumpstate/1.0/vts/functional/Android.bp
@@ -18,5 +18,5 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalDumpstateV1_0TargetTest.cpp"],
static_libs: ["android.hardware.dumpstate@1.0"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/dumpstate/1.0/vts/functional/VtsHalDumpstateV1_0TargetTest.cpp b/dumpstate/1.0/vts/functional/VtsHalDumpstateV1_0TargetTest.cpp
index 57ebf2a..96b13c5 100644
--- a/dumpstate/1.0/vts/functional/VtsHalDumpstateV1_0TargetTest.cpp
+++ b/dumpstate/1.0/vts/functional/VtsHalDumpstateV1_0TargetTest.cpp
@@ -21,32 +21,19 @@
#include <android/hardware/dumpstate/1.0/IDumpstateDevice.h>
#include <cutils/native_handle.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <log/log.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
-
using ::android::hardware::dumpstate::V1_0::IDumpstateDevice;
using ::android::hardware::Return;
using ::android::sp;
-// Test environment for Dumpstate HIDL HAL.
-class DumpstateHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static DumpstateHidlEnvironment* Instance() {
- static DumpstateHidlEnvironment* instance = new DumpstateHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IDumpstateDevice>(); }
-};
-
-class DumpstateHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- public:
+class DumpstateHidlTest : public ::testing::TestWithParam<std::string> {
+ public:
virtual void SetUp() override {
- dumpstate = ::testing::VtsHalHidlTargetTestBase::getService<IDumpstateDevice>(
- DumpstateHidlEnvironment::Instance()->getServiceName<IDumpstateDevice>());
+ dumpstate = IDumpstateDevice::getService(GetParam());
ASSERT_NE(dumpstate, nullptr) << "Could not get HIDL instance";
}
@@ -54,14 +41,14 @@
};
// Negative test: make sure dumpstateBoard() doesn't crash when passed a null pointer.
-TEST_F(DumpstateHidlTest, TestNullHandle) {
+TEST_P(DumpstateHidlTest, TestNullHandle) {
Return<void> status = dumpstate->dumpstateBoard(nullptr);
ASSERT_TRUE(status.isOk()) << "Status should be ok: " << status.description();
}
// Negative test: make sure dumpstateBoard() ignores a handle with no FD.
-TEST_F(DumpstateHidlTest, TestHandleWithNoFd) {
+TEST_P(DumpstateHidlTest, TestHandleWithNoFd) {
native_handle_t* handle = native_handle_create(0, 0);
ASSERT_NE(handle, nullptr) << "Could not create native_handle";
@@ -74,7 +61,7 @@
}
// Positive test: make sure dumpstateBoard() writes something to the FD.
-TEST_F(DumpstateHidlTest, TestOk) {
+TEST_P(DumpstateHidlTest, TestOk) {
// Index 0 corresponds to the read end of the pipe; 1 to the write end.
int fds[2];
ASSERT_EQ(0, pipe2(fds, O_NONBLOCK)) << errno;
@@ -94,7 +81,7 @@
}
// Positive test: make sure dumpstateBoard() doesn't crash with two FDs.
-TEST_F(DumpstateHidlTest, TestHandleWithTwoFds) {
+TEST_P(DumpstateHidlTest, TestHandleWithTwoFds) {
int fds1[2];
int fds2[2];
ASSERT_EQ(0, pipe2(fds1, O_NONBLOCK)) << errno;
@@ -111,11 +98,7 @@
native_handle_close(handle);
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(DumpstateHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- DumpstateHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- ALOGI("Test result = %d", status);
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, DumpstateHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IDumpstateDevice::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
index d910169..e2f2670 100644
--- a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
+++ b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
@@ -26,12 +26,11 @@
using mapper::V2_1::IMapper;
using renderengine::DisplaySettings;
using renderengine::LayerSettings;
+using renderengine::RenderEngineCreationArgs;
-TestRenderEngine::TestRenderEngine(common::V1_1::PixelFormat hwcFormat,
- uint32_t renderEngineFeatures) {
- mFormat = hwcFormat;
- mRenderEngine = renderengine::RenderEngine::create(
- static_cast<int32_t>(mFormat), renderEngineFeatures, mMaxFrameBufferAcquireBuffers);
+TestRenderEngine::TestRenderEngine(const RenderEngineCreationArgs& args) {
+ mFormat = static_cast<common::V1_1::PixelFormat>(args.pixelFormat);
+ mRenderEngine = renderengine::RenderEngine::create(args);
}
void TestRenderEngine::setRenderLayers(std::vector<std::shared_ptr<TestLayer>> layers) {
diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h
index 0ac5a22..b936cab 100644
--- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h
+++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/RenderEngineVts.h
@@ -35,11 +35,14 @@
using mapper::V2_1::IMapper;
using renderengine::DisplaySettings;
+using renderengine::RenderEngineCreationArgs;
using vts::Gralloc;
class TestRenderEngine {
public:
- TestRenderEngine(common::V1_1::PixelFormat hwcFormat, uint32_t renderEngineFeatures);
+ static constexpr uint32_t sMaxFrameBufferAcquireBuffers = 2;
+
+ TestRenderEngine(const RenderEngineCreationArgs& args);
~TestRenderEngine() = default;
void setRenderLayers(std::vector<std::shared_ptr<TestLayer>> layers);
@@ -51,7 +54,6 @@
void checkColorBuffer(std::vector<V2_2::IComposerClient::Color>& expectedColors);
private:
- static constexpr uint32_t mMaxFrameBufferAcquireBuffers = 2;
common::V1_1::PixelFormat mFormat;
std::vector<renderengine::LayerSettings> mCompositionLayers;
std::unique_ptr<renderengine::RenderEngine> mRenderEngine;
diff --git a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
index ade7a38..6a6f7de 100644
--- a/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
+++ b/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp
@@ -103,9 +103,14 @@
ASSERT_NO_FATAL_FAILURE(
mTestRenderEngine = std::unique_ptr<TestRenderEngine>(new TestRenderEngine(
- PixelFormat::RGBA_8888,
- renderengine::RenderEngine::USE_COLOR_MANAGEMENT |
- renderengine::RenderEngine::USE_HIGH_PRIORITY_CONTEXT)));
+ renderengine::RenderEngineCreationArgs::Builder()
+ .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
+ .setImageCacheSize(TestRenderEngine::sMaxFrameBufferAcquireBuffers)
+ .setUseColorManagerment(true)
+ .setEnableProtectedContext(false)
+ .setPrecacheToneMapperShaderOnly(false)
+ .setContextPriority(renderengine::RenderEngine::ContextPriority::HIGH)
+ .build())));
renderengine::DisplaySettings clientCompositionDisplay;
clientCompositionDisplay.physicalDisplay = Rect(mDisplayWidth, mDisplayHeight);
diff --git a/health/2.0/default/Health.cpp b/health/2.0/default/Health.cpp
index a2b81d1..c0c5a40 100644
--- a/health/2.0/default/Health.cpp
+++ b/health/2.0/default/Health.cpp
@@ -148,7 +148,14 @@
// Retrieve all information and call healthd_mode_ops->battery_update, which calls
// notifyListeners.
- bool chargerOnline = battery_monitor_->update();
+ battery_monitor_->updateValues();
+ struct BatteryProperties props = getBatteryProperties(battery_monitor_.get());
+ bool log = healthd_board_battery_update(&props);
+ if (log) {
+ battery_monitor_->logValues();
+ }
+ healthd_mode_ops->battery_update(&props);
+ bool chargerOnline = battery_monitor_->isChargerOnline();
// adjust uevent / wakealarm periods
healthd_battery_update_internal(chargerOnline);
diff --git a/health/2.1/Android.bp b/health/2.1/Android.bp
new file mode 100644
index 0000000..254bfc0
--- /dev/null
+++ b/health/2.1/Android.bp
@@ -0,0 +1,20 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.health@2.1",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "types.hal",
+ "IHealth.hal",
+ "IHealthInfoCallback.hal",
+ ],
+ interfaces: [
+ "android.hardware.health@1.0",
+ "android.hardware.health@2.0",
+ "android.hidl.base@1.0",
+ ],
+ gen_java: true,
+}
diff --git a/health/2.1/IHealth.hal b/health/2.1/IHealth.hal
new file mode 100644
index 0000000..8a5152a
--- /dev/null
+++ b/health/2.1/IHealth.hal
@@ -0,0 +1,80 @@
+/*
+ * 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.health@2.1;
+
+import @2.0::IHealth;
+import @2.0::Result;
+import HealthConfig;
+import HealthInfo;
+import IHealthInfoCallback;
+
+/**
+ * IHealth manages health info and posts events on registered callbacks.
+ *
+ * An implementation of @2.1::IHealth must be able to handle both
+ * @2.0::IHealthInfoCallback and @2.1::IHealthInfoCallback.
+ * - When registerCallback() is called, an implementation must cast the callback
+ * to @2.1::IHealthInfoCallback.
+ * - If the cast is successful, when a health info broadcast is sent, the
+ * implementation must call
+ * @2.1::IHealthInfoCallback.healthInfoChanged_2_1(). All fields introduced
+ * in 2.1 must be set appropriately. The implementation must not call
+ * @2.0::IHealthInfoCallback.healthInfoChanged().
+ * - If the cast is unsuccessful, the implementation must call
+ * @2.0::IHealthInfoCallback.healthInfoChanged().
+ * - When unregisterCallback() is called, from then on, updates must not be sent
+ * through either healthInfoChanged_2_1() or healthInfoChanged().
+ *
+ * Passthrough implementations are not required to send health info to all
+ * callbacks periodically, but they must do so when update() is called.
+ * Binderized implementations must send health info to all callbacks
+ * periodically. The intervals between two notifications must be retrieved from
+ * the passthrough implementation through the getHealthConfig() function.
+ */
+interface IHealth extends @2.0::IHealth {
+ /**
+ * Get configuration of this HAL.
+ *
+ * @return result SUCCESS if successful,
+ * NOT_SUPPORTED if this API is not supported,
+ * UNKNOWN for other errors.
+ * @return config HAL configuration, to be ignored if result is not
+ * SUCCESS.
+ */
+ getHealthConfig() generates (Result result, HealthConfig config);
+
+ /**
+ * Get Health Information.
+ *
+ * @return result SUCCESS if successful,
+ * NOT_SUPPORTED if this API is not supported,
+ * UNKNOWN for other errors.
+ * @return value Health information, to be ignored if result is not
+ * SUCCESS.
+ */
+ getHealthInfo_2_1() generates (Result result, @2.1::HealthInfo value);
+
+ /**
+ * Return whether the screen should be kept on in charger mode.
+ *
+ * @return result SUCCESS if successful,
+ * NOT_SUPPORTED if this API is not supported,
+ * UNKNOWN for other errors.
+ * @return value whether screen should be kept on.
+ */
+ shouldKeepScreenOn() generates (Result result, bool value);
+};
diff --git a/health/2.1/IHealthInfoCallback.hal b/health/2.1/IHealthInfoCallback.hal
new file mode 100644
index 0000000..275f018
--- /dev/null
+++ b/health/2.1/IHealthInfoCallback.hal
@@ -0,0 +1,36 @@
+/*
+ * 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.health@2.1;
+
+import @2.0::IHealthInfoCallback;
+
+/**
+ * IHealthInfoCallback is the updated callback interface to
+ * {@link IHealth.registerCallback}.
+ *
+ * A @2.1::IHealthInfoCallback must implement healthInfoChanged_2_1(). The
+ * inherited healthInfoChanged() function is never called when the HAL
+ * implementation post events. See documentation on @2.1::IHealth for details.
+ */
+interface IHealthInfoCallback extends @2.0::IHealthInfoCallback {
+ /**
+ * An implementation of IHealth must call healthInfoChanged on all
+ * registered callbacks after health info changes.
+ * @param info the updated HealthInfo
+ */
+ oneway healthInfoChanged_2_1(HealthInfo info);
+};
diff --git a/health/2.1/types.hal b/health/2.1/types.hal
new file mode 100644
index 0000000..efd8d6f
--- /dev/null
+++ b/health/2.1/types.hal
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2017 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.health@2.1;
+
+import @1.0::HealthConfig;
+import @2.0::HealthInfo;
+
+/**
+ * Battery capacity level. This enum provides additional information along side
+ * with the battery capacity.
+ * Clients of this HAL must use this value before inferring it from the
+ * battery capacity.
+ */
+enum BatteryCapacityLevel : int32_t {
+ /**
+ * Battery capacity level is unknown.
+ * Battery capacity level must be set to this value if and only if battery
+ * is not present.
+ */
+ UNKNOWN = 0,
+ /**
+ * Battery is at critical level. The Android framework must schedule a
+ * shutdown when it sees this value from the HAL.
+ */
+ CRITICAL,
+ /**
+ * Battery is low. The Android framework may limit the performance of
+ * the device when it sees this value from the HAL.
+ */
+ LOW,
+ /**
+ * Battery level is normal.
+ */
+ NORMAL,
+ /**
+ * Battery level is high.
+ */
+ HIGH,
+ /**
+ * Battery is full. It must be set to FULL if and only if battery level is
+ * 100.
+ */
+ FULL,
+};
+
+/**
+ * Combined Health Information.
+ */
+struct HealthInfo {
+ /**
+ * V2.0 HealthInfo.
+ * If a member is unsupported, it is filled with:
+ * - 0 (for integers);
+ * - false (for booleans);
+ * - empty string (for strings);
+ * - UNKNOWN (for BatteryStatus and BatteryHealth).
+ */
+ @2.0::HealthInfo legacy;
+
+ /**
+ * Battery capacity level. See BatteryCapacityLevel for more details.
+ */
+ BatteryCapacityLevel batteryCapacityLevel;
+
+ /**
+ * Estimated time to fully charge the device (in seconds).
+ * Value must be 0 if and only if batteryCapacityLevel is FULL or UNKNOWN.
+ * Otherwise, value must be positive.
+ */
+ int64_t batteryChargeTimeToFullNowSeconds;
+
+ /**
+ * Estimated battery full capacity (in microamp hours, uAh).
+ * Value must be 0 if unknown.
+ * Value must be positive if known, and must be between [50%, 120%] of
+ * batteryFullCharge (the designed capacity).
+ */
+ int32_t batteryFullCapacityUah;
+};
+
+/**
+ * Combined configuration of a health HAL implementation.
+ */
+struct HealthConfig {
+ /**
+ * 1.0 version of health config.
+ */
+ @1.0::HealthConfig battery;
+
+ /**
+ * Minimum battery level for charger to reboot into Android (in percent).
+ * Value should be in range [0, 100].
+ */
+ int32_t bootMinCap;
+};
diff --git a/health/2.1/vts/OWNERS b/health/2.1/vts/OWNERS
new file mode 100644
index 0000000..20450ba
--- /dev/null
+++ b/health/2.1/vts/OWNERS
@@ -0,0 +1,3 @@
+elsk@google.com
+hridya@google.com
+sspatil@google.com
diff --git a/health/2.1/vts/functional/Android.bp b/health/2.1/vts/functional/Android.bp
new file mode 100644
index 0000000..5aa873a
--- /dev/null
+++ b/health/2.1/vts/functional/Android.bp
@@ -0,0 +1,29 @@
+//
+// 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: "VtsHalHealthV2_1TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: ["VtsHalHealthV2_1TargetTest.cpp"],
+ static_libs: [
+ "libgflags",
+ "libgmock",
+ "android.hardware.health@1.0",
+ "android.hardware.health@2.0",
+ "android.hardware.health@2.1",
+ ],
+ test_suites: ["general-tests"],
+}
diff --git a/health/2.1/vts/functional/VtsHalHealthV2_1TargetTest.cpp b/health/2.1/vts/functional/VtsHalHealthV2_1TargetTest.cpp
new file mode 100644
index 0000000..7df4926
--- /dev/null
+++ b/health/2.1/vts/functional/VtsHalHealthV2_1TargetTest.cpp
@@ -0,0 +1,269 @@
+/*
+ * 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 "health_hidl_hal_test"
+
+#include <mutex>
+#include <set>
+#include <string>
+
+#include <android-base/logging.h>
+#include <android/hardware/health/1.0/types.h>
+#include <android/hardware/health/2.0/types.h>
+#include <android/hardware/health/2.1/IHealth.h>
+#include <android/hardware/health/2.1/IHealthInfoCallback.h>
+#include <android/hardware/health/2.1/types.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+using ::android::hardware::health::V1_0::BatteryStatus;
+using ::android::hardware::health::V2_0::Result;
+using ::testing::AnyOf;
+using ::testing::AssertionFailure;
+using ::testing::AssertionResult;
+using ::testing::AssertionSuccess;
+using namespace std::chrono_literals;
+
+using ::android::hardware::health::V1_0::toString;
+using ::android::hardware::health::V2_0::toString;
+using ::android::hardware::health::V2_1::toString;
+
+// Return expr if it is evaluated to false.
+#define TEST_AND_RETURN(expr) \
+ do { \
+ auto res = (expr); \
+ if (!res) return res; \
+ } while (0)
+
+// Return a descriptive AssertionFailure() if expr is evaluated to false.
+#define TEST_AND_RETURN_FAILURE(expr) \
+ do { \
+ auto res = (expr); \
+ if (!res) { \
+ return AssertionFailure() << #expr " is false"; \
+ } \
+ } while (0)
+
+namespace android {
+namespace hardware {
+namespace health {
+
+namespace V2_0 {
+std::ostream& operator<<(std::ostream& os, const Result& res) {
+ return os << toString(res);
+}
+} // namespace V2_0
+
+namespace V2_1 {
+
+class HealthHidlTest : public testing::TestWithParam<std::string> {
+ public:
+ virtual void SetUp() override {
+ service_ = IHealth::getService(GetParam());
+ ASSERT_NE(nullptr, service_.get()) << "Instance '" << GetParam() << "'' is not available.";
+ }
+
+ sp<IHealth> service_;
+};
+
+class CallbackBase {
+ public:
+ Return<void> healthInfoChangedInternal() {
+ std::lock_guard<std::mutex> lock(mutex_);
+ invoked_ = true;
+ invoked_notify_.notify_all();
+ return Void();
+ }
+ template <typename R, typename P>
+ bool waitInvoke(std::chrono::duration<R, P> duration) {
+ std::unique_lock<std::mutex> lock(mutex_);
+ bool r = invoked_notify_.wait_for(lock, duration, [this] { return this->invoked_; });
+ invoked_ = false;
+ return r;
+ }
+
+ private:
+ std::mutex mutex_;
+ std::condition_variable invoked_notify_;
+ bool invoked_ = false;
+};
+
+class Callback_2_0 : public android::hardware::health::V2_0::IHealthInfoCallback,
+ public CallbackBase {
+ Return<void> healthInfoChanged(const android::hardware::health::V2_0::HealthInfo&) override {
+ return healthInfoChangedInternal();
+ }
+};
+
+class Callback_2_1 : public android::hardware::health::V2_1::IHealthInfoCallback,
+ public CallbackBase {
+ Return<void> healthInfoChanged(const android::hardware::health::V2_0::HealthInfo&) override {
+ ADD_FAILURE() << "android::hardware::health::V2_1::IHealthInfoCallback::healthInfoChanged "
+ << "is called, but it shouldn't be";
+ return Void();
+ }
+ Return<void> healthInfoChanged_2_1(const HealthInfo&) override {
+ return healthInfoChangedInternal();
+ }
+};
+
+template <typename T>
+AssertionResult IsOk(const Return<T>& r) {
+ return r.isOk() ? AssertionSuccess() : (AssertionFailure() << r.description());
+}
+
+// Both IsOk() and Result::SUCCESS
+AssertionResult ResultIsSuccess(const Return<Result>& r) {
+ if (!r.isOk()) {
+ return AssertionFailure() << r.description();
+ }
+ if (static_cast<Result>(r) != Result::SUCCESS) {
+ return AssertionFailure() << toString(static_cast<Result>(r));
+ }
+ return AssertionSuccess();
+}
+
+/**
+ * Test whether callbacks work. Tested functions are IHealth::registerCallback,
+ * unregisterCallback, and update.
+ */
+template <typename Callback>
+AssertionResult TestCallbacks(sp<IHealth> service) {
+ sp<Callback> first = new Callback();
+ sp<Callback> second = new Callback();
+
+ TEST_AND_RETURN(ResultIsSuccess(service->registerCallback(first)));
+ TEST_AND_RETURN(ResultIsSuccess(service->registerCallback(second)));
+
+ // registerCallback may or may not invoke the callback immediately, so the test needs
+ // to wait for the invocation. If the implementation chooses not to invoke the callback
+ // immediately, just wait for some time.
+ first->waitInvoke(200ms);
+ second->waitInvoke(200ms);
+
+ // assert that the first callback is invoked when update is called.
+ TEST_AND_RETURN(ResultIsSuccess(service->update()));
+
+ TEST_AND_RETURN_FAILURE(first->waitInvoke(1s));
+ TEST_AND_RETURN_FAILURE(second->waitInvoke(1s));
+
+ TEST_AND_RETURN(ResultIsSuccess(service->unregisterCallback(first)));
+
+ // clear any potentially pending callbacks result from wakealarm / kernel events
+ // If there is none, just wait for some time.
+ first->waitInvoke(200ms);
+ second->waitInvoke(200ms);
+
+ // assert that the second callback is still invoked even though the first is unregistered.
+ TEST_AND_RETURN(ResultIsSuccess(service->update()));
+
+ TEST_AND_RETURN_FAILURE(!first->waitInvoke(200ms));
+ TEST_AND_RETURN_FAILURE(second->waitInvoke(1s));
+
+ TEST_AND_RETURN(ResultIsSuccess(service->unregisterCallback(second)));
+ return AssertionSuccess();
+}
+
+TEST_P(HealthHidlTest, Callbacks_2_0) {
+ EXPECT_TRUE(TestCallbacks<Callback_2_0>(service_));
+}
+
+TEST_P(HealthHidlTest, Callbacks_2_1) {
+ EXPECT_TRUE(TestCallbacks<Callback_2_1>(service_));
+}
+
+template <typename Callback>
+AssertionResult TestUnregisterNonExistentCallback(sp<IHealth> service) {
+ sp<Callback> callback = new Callback();
+ auto ret = service->unregisterCallback(callback);
+ TEST_AND_RETURN(IsOk(ret));
+ if (static_cast<Result>(ret) != Result::NOT_FOUND) {
+ return AssertionFailure()
+ << "Unregistering non-existent callback should return NOT_FOUND, but returned "
+ << static_cast<Result>(ret);
+ }
+ return AssertionSuccess();
+}
+
+TEST_P(HealthHidlTest, UnregisterNonExistentCallback_2_0) {
+ EXPECT_TRUE(TestUnregisterNonExistentCallback<Callback_2_0>(service_));
+}
+
+TEST_P(HealthHidlTest, UnregisterNonExistentCallback_2_1) {
+ EXPECT_TRUE(TestUnregisterNonExistentCallback<Callback_2_1>(service_));
+}
+
+template <typename T>
+AssertionResult IsEnum(T value) {
+ for (auto it : hidl_enum_range<T>()) {
+ if (it == value) {
+ return AssertionSuccess();
+ }
+ }
+
+ return AssertionFailure() << static_cast<std::underlying_type_t<T>>(value) << " is not valid";
+}
+
+/*
+ * Tests the values returned by getHealthInfo() from interface IHealth.
+ */
+TEST_P(HealthHidlTest, getHealthInfo_2_1) {
+ EXPECT_TRUE(IsOk(service_->getHealthInfo_2_1([](auto result, const auto& value) {
+ if (result == Result::NOT_SUPPORTED) {
+ return;
+ }
+ ASSERT_EQ(Result::SUCCESS, result);
+ const auto& legacy = value.legacy.legacy;
+
+ EXPECT_TRUE(IsEnum(value.batteryCapacityLevel)) << " BatteryCapacityLevel";
+ EXPECT_GE(value.batteryChargeTimeToFullNowSeconds, 0);
+
+ EXPECT_GE(value.batteryFullCapacityUah, 0) << "batteryFullCapacityUah is unknown";
+ EXPECT_GE(value.batteryFullCapacityUah, legacy.batteryFullCharge * 0.50);
+ EXPECT_LE(value.batteryFullCapacityUah, legacy.batteryFullCharge * 1.20);
+ })));
+}
+
+TEST_P(HealthHidlTest, getHealthConfig) {
+ EXPECT_TRUE(IsOk(service_->getHealthConfig([](auto result, const auto&) {
+ EXPECT_THAT(result, AnyOf(Result::SUCCESS, Result::NOT_SUPPORTED));
+ })));
+}
+
+TEST_P(HealthHidlTest, shouldKeepScreenOn) {
+ EXPECT_TRUE(IsOk(service_->shouldKeepScreenOn([](auto result, const auto&) {
+ EXPECT_THAT(result, AnyOf(Result::SUCCESS, Result::NOT_SUPPORTED));
+ })));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ , HealthHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IHealth::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
+} // namespace V2_1
+} // namespace health
+} // namespace hardware
+} // namespace android
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ LOG(INFO) << "Test result = " << status;
+ return status;
+}
diff --git a/keymaster/4.0/vts/OWNERS b/keymaster/4.0/vts/OWNERS
index 376c12b..abfb2e0 100644
--- a/keymaster/4.0/vts/OWNERS
+++ b/keymaster/4.0/vts/OWNERS
@@ -1,3 +1,4 @@
+jbires@google.com
jdanis@google.com
swillden@google.com
yim@google.com
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 0ac7e48..c5acf8c 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -4413,6 +4413,35 @@
}
/*
+ * AttestationTest.AttestationApplicationIDLengthProperlyEncoded
+ *
+ * Verifies that the Attestation Application ID software enforced tag has a proper length encoding.
+ * Some implementations break strict encoding rules by encoding a length between 127 and 256 in one
+ * byte. Proper DER encoding specifies that for lengths greather than 127, one byte should be used
+ * to specify how many following bytes will be used to encode the length.
+ */
+TEST_F(AttestationTest, AttestationApplicationIDLengthProperlyEncoded) {
+ auto creation_time = std::chrono::system_clock::now();
+ ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+ .Authorization(TAG_NO_AUTH_REQUIRED)
+ .EcdsaSigningKey(EcCurve::P_256)
+ .Digest(Digest::SHA_2_256)));
+
+ hidl_vec<hidl_vec<uint8_t>> cert_chain;
+ const string app_id(143, 'a');
+ ASSERT_EQ(ErrorCode::OK,
+ AttestKey(AuthorizationSetBuilder()
+ .Authorization(TAG_ATTESTATION_CHALLENGE, HidlBuf("challenge"))
+ .Authorization(TAG_ATTESTATION_APPLICATION_ID, HidlBuf(app_id)),
+ &cert_chain));
+ EXPECT_GE(cert_chain.size(), 2U);
+
+ EXPECT_TRUE(verify_attestation_record("challenge", app_id, //
+ key_characteristics_.softwareEnforced, //
+ key_characteristics_.hardwareEnforced, //
+ SecLevel(), cert_chain[0], creation_time));
+}
+/*
* AttestationTest.AesAttestation
*
* Verifies that attesting to AES keys fails in the expected way.
diff --git a/memtrack/1.0/vts/functional/Android.bp b/memtrack/1.0/vts/functional/Android.bp
index d682e0b..9e5cf6d 100644
--- a/memtrack/1.0/vts/functional/Android.bp
+++ b/memtrack/1.0/vts/functional/Android.bp
@@ -19,5 +19,5 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalMemtrackV1_0TargetTest.cpp"],
static_libs: ["android.hardware.memtrack@1.0"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/memtrack/1.0/vts/functional/VtsHalMemtrackV1_0TargetTest.cpp b/memtrack/1.0/vts/functional/VtsHalMemtrackV1_0TargetTest.cpp
index 691ecca..cccedca 100644
--- a/memtrack/1.0/vts/functional/VtsHalMemtrackV1_0TargetTest.cpp
+++ b/memtrack/1.0/vts/functional/VtsHalMemtrackV1_0TargetTest.cpp
@@ -20,8 +20,9 @@
#include <android/hardware/memtrack/1.0/IMemtrack.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <fcntl.h>
#include <algorithm>
@@ -39,23 +40,10 @@
using std::vector;
using std::count_if;
-// Test environment for Memtrack HIDL HAL.
-class MemtrackHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static MemtrackHidlEnvironment* Instance() {
- static MemtrackHidlEnvironment* instance = new MemtrackHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IMemtrack>(); }
-};
-
-class MemtrackHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class MemtrackHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- memtrack = ::testing::VtsHalHidlTargetTestBase::getService<IMemtrack>(
- MemtrackHidlEnvironment::Instance()->getServiceName<IMemtrack>());
+ memtrack = IMemtrack::getService(GetParam());
ASSERT_NE(memtrack, nullptr);
}
@@ -93,7 +81,7 @@
/* Sanity check results when getMemory() is passed a negative PID
*/
-TEST_F(MemtrackHidlTest, BadPidTest) {
+TEST_P(MemtrackHidlTest, BadPidTest) {
MemtrackStatus s;
hidl_vec<MemtrackRecord> v;
auto cb = generate_cb(&s, &v);
@@ -108,7 +96,7 @@
/* Sanity check results when getMemory() is passed a bad memory usage type
*/
-TEST_F(MemtrackHidlTest, BadTypeTest) {
+TEST_P(MemtrackHidlTest, BadTypeTest) {
MemtrackStatus s;
hidl_vec<MemtrackRecord> v;
auto cb = generate_cb(&s, &v);
@@ -121,7 +109,7 @@
* for all memory types, including valid flag combinations for every
* MemtrackRecord returned.
*/
-TEST_F(MemtrackHidlTest, GetMemoryTest) {
+TEST_P(MemtrackHidlTest, GetMemoryTest) {
/* Opening this device causes the kernel to provide memtrack with memory
* info for this process.
*/
@@ -172,11 +160,7 @@
static_cast<uint32_t>(MemtrackType::NUM_TYPES));
}
-int main(int argc, char **argv) {
- ::testing::AddGlobalTestEnvironment(MemtrackHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- MemtrackHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, MemtrackHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IMemtrack::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/nfc/1.0/vts/functional/Android.bp b/nfc/1.0/vts/functional/Android.bp
index c2e365e..40b82bb 100644
--- a/nfc/1.0/vts/functional/Android.bp
+++ b/nfc/1.0/vts/functional/Android.bp
@@ -21,5 +21,5 @@
static_libs: [
"android.hardware.nfc@1.0",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/nfc/1.0/vts/functional/AndroidTest.xml b/nfc/1.0/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..364672b
--- /dev/null
+++ b/nfc/1.0/vts/functional/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs VtsHalNfcV1_0TargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
+ </target_preparer>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsHalNfcV1_0TargetTest->/data/local/tmp/VtsHalNfcV1_0TargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsHalNfcV1_0TargetTest" />
+ <option name="native-test-timeout" value="180000"/>
+ </test>
+</configuration>
diff --git a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
index e17c961..1feae9d 100644
--- a/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
+++ b/nfc/1.0/vts/functional/VtsHalNfcV1_0TargetTest.cpp
@@ -20,11 +20,12 @@
#include <android/hardware/nfc/1.0/INfc.h>
#include <android/hardware/nfc/1.0/INfcClientCallback.h>
#include <android/hardware/nfc/1.0/types.h>
+#include <gtest/gtest.h>
#include <hardware/nfc.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <VtsHalHidlTargetCallbackBase.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
using ::android::hardware::nfc::V1_0::INfc;
using ::android::hardware::nfc::V1_0::INfcClientCallback;
@@ -94,26 +95,11 @@
};
};
-// Test environment for Nfc HIDL HAL.
-class NfcHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static NfcHidlEnvironment* Instance() {
- static NfcHidlEnvironment* instance = new NfcHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<INfc>(); }
- private:
- NfcHidlEnvironment() {}
-};
-
// The main test class for NFC HIDL HAL.
-class NfcHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class NfcHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- nfc_ = ::testing::VtsHalHidlTargetTestBase::getService<INfc>(
- NfcHidlEnvironment::Instance()->getServiceName<INfc>());
+ nfc_ = INfc::getService(GetParam());
ASSERT_NE(nfc_, nullptr);
nfc_cb_ = new NfcClientCallback();
@@ -186,7 +172,7 @@
* Since open and close calls are a part of SetUp() and TearDown(),
* the function definition is intentionally kept empty
*/
-TEST_F(NfcHidlTest, OpenAndClose) {}
+TEST_P(NfcHidlTest, OpenAndClose) {}
/*
* WriteCoreReset:
@@ -194,7 +180,7 @@
* Waits for CORE_RESET_RSP
* Checks the status, version number and configuration status
*/
-TEST_F(NfcHidlTest, WriteCoreReset) {
+TEST_P(NfcHidlTest, WriteCoreReset) {
std::vector<uint8_t> cmd = CORE_RESET_CMD;
NfcData data = cmd;
EXPECT_EQ(data.size(), nfc_->write(data));
@@ -229,7 +215,7 @@
* Waits for CORE_RESET_RSP
* Checks the status, version number and configuration status
*/
-TEST_F(NfcHidlTest, WriteCoreResetConfigReset) {
+TEST_P(NfcHidlTest, WriteCoreResetConfigReset) {
std::vector<uint8_t> cmd = CORE_RESET_CMD_CONFIG_RESET;
NfcData data = cmd;
EXPECT_EQ(data.size(), nfc_->write(data));
@@ -264,7 +250,7 @@
* Waits for response
* Checks SYNTAX_ERROR status
*/
-TEST_F(NfcHidlTest, WriteInvalidCommand) {
+TEST_P(NfcHidlTest, WriteInvalidCommand) {
// Send an Error Command
std::vector<uint8_t> cmd = INVALID_COMMAND;
NfcData data = cmd;
@@ -285,7 +271,7 @@
* Send CORE_CONN_CREATE_CMD for loop-back mode
* Check the response
*/
-TEST_F(NfcHidlTest, WriteInvalidAndThenValidCommand) {
+TEST_P(NfcHidlTest, WriteInvalidAndThenValidCommand) {
std::vector<uint8_t> cmd = CORE_RESET_CMD;
NfcData data = cmd;
EXPECT_EQ(data.size(), nfc_->write(data));
@@ -349,7 +335,7 @@
* Checks the data received
* Repeat to send total of 1Mb data
*/
-TEST_F(NfcHidlTest, Bandwidth) {
+TEST_P(NfcHidlTest, Bandwidth) {
std::vector<uint8_t> cmd = CORE_RESET_CMD;
NfcData data = cmd;
EXPECT_EQ(data.size(), nfc_->write(data));
@@ -437,7 +423,7 @@
* Waits for NfcEvent.OPEN_CPLT
* Checks status
*/
-TEST_F(NfcHidlTest, PowerCycle) {
+TEST_P(NfcHidlTest, PowerCycle) {
EXPECT_EQ(NfcStatus::OK, nfc_->powerCycle());
// Wait for NfcEvent.OPEN_CPLT
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
@@ -451,7 +437,7 @@
* Calls powerCycle() after close()
* Checks status
*/
-TEST_F(NfcHidlTest, PowerCycleAfterClose) {
+TEST_P(NfcHidlTest, PowerCycleAfterClose) {
EXPECT_EQ(NfcStatus::OK, nfc_->close());
// Wait for CLOSE_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
@@ -474,7 +460,7 @@
* Calls coreInitialized() with different data
* Waits for NfcEvent.POST_INIT_CPLT
*/
-TEST_F(NfcHidlTest, CoreInitialized) {
+TEST_P(NfcHidlTest, CoreInitialized) {
NfcData data;
data.resize(1);
// These parameters might lead to device specific proprietary behavior
@@ -501,7 +487,7 @@
* Calls controlGranted()
* Checks the return value
*/
-TEST_F(NfcHidlTest, ControlGranted) {
+TEST_P(NfcHidlTest, ControlGranted) {
EXPECT_EQ(NfcStatus::OK, nfc_->controlGranted());
}
@@ -510,7 +496,7 @@
* Call controlGranted() after close
* Checks the return value
*/
-TEST_F(NfcHidlTest, ControlGrantedAfterClose) {
+TEST_P(NfcHidlTest, ControlGrantedAfterClose) {
EXPECT_EQ(NfcStatus::OK, nfc_->close());
// Wait for CLOSE_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
@@ -532,7 +518,7 @@
* Calls prediscover()
* Checks the return value
*/
-TEST_F(NfcHidlTest, PreDiscover) {
+TEST_P(NfcHidlTest, PreDiscover) {
EXPECT_EQ(NfcStatus::OK, nfc_->prediscover());
}
@@ -541,7 +527,7 @@
* Call prediscover() after close
* Checks the return value
*/
-TEST_F(NfcHidlTest, PreDiscoverAfterClose) {
+TEST_P(NfcHidlTest, PreDiscoverAfterClose) {
EXPECT_EQ(NfcStatus::OK, nfc_->close());
// Wait for CLOSE_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
@@ -564,7 +550,7 @@
* Calls close() multiple times
* Checks status
*/
-TEST_F(NfcHidlTest, CloseAfterClose) {
+TEST_P(NfcHidlTest, CloseAfterClose) {
EXPECT_EQ(NfcStatus::OK, nfc_->close());
// Wait for CLOSE_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
@@ -587,15 +573,18 @@
* Calls open() multiple times
* Checks status
*/
-TEST_F(NfcHidlTest, OpenAfterOpen) {
+TEST_P(NfcHidlTest, OpenAfterOpen) {
EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
EXPECT_EQ(NfcStatus::OK, nfc_->open(nfc_cb_));
}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, NfcHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(INfc::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(NfcHidlEnvironment::Instance());
::testing::InitGoogleTest(&argc, argv);
- NfcHidlEnvironment::Instance()->init(&argc, argv);
std::system("svc nfc disable"); /* Turn off NFC */
sleep(5);
diff --git a/nfc/1.1/vts/functional/Android.bp b/nfc/1.1/vts/functional/Android.bp
index 6698c5a..8da0ce3 100644
--- a/nfc/1.1/vts/functional/Android.bp
+++ b/nfc/1.1/vts/functional/Android.bp
@@ -22,5 +22,5 @@
"android.hardware.nfc@1.0",
"android.hardware.nfc@1.1",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/nfc/1.1/vts/functional/VtsHalNfcV1_1TargetTest.cpp b/nfc/1.1/vts/functional/VtsHalNfcV1_1TargetTest.cpp
index 0b7c88b..13537e4 100644
--- a/nfc/1.1/vts/functional/VtsHalNfcV1_1TargetTest.cpp
+++ b/nfc/1.1/vts/functional/VtsHalNfcV1_1TargetTest.cpp
@@ -21,11 +21,12 @@
#include <android/hardware/nfc/1.1/INfc.h>
#include <android/hardware/nfc/1.1/INfcClientCallback.h>
#include <android/hardware/nfc/1.1/types.h>
+#include <gtest/gtest.h>
#include <hardware/nfc.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <VtsHalHidlTargetCallbackBase.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
using ::android::hardware::nfc::V1_1::INfc;
using ::android::hardware::nfc::V1_1::INfcClientCallback;
@@ -83,25 +84,11 @@
};
};
-// Test environment for Nfc HIDL HAL.
-class NfcHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static NfcHidlEnvironment* Instance() {
- static NfcHidlEnvironment* instance = new NfcHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<INfc>(); }
- private:
- NfcHidlEnvironment() {}
-};
-
// The main test class for NFC HIDL HAL.
-class NfcHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class NfcHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- nfc_ = ::testing::VtsHalHidlTargetTestBase::getService<INfc>();
+ nfc_ = INfc::getService(GetParam());
ASSERT_NE(nfc_, nullptr);
nfc_cb_ = new NfcClientCallback();
@@ -151,7 +138,7 @@
* calls factoryReset()
* checks status
*/
-TEST_F(NfcHidlTest, FactoryReset) {
+TEST_P(NfcHidlTest, FactoryReset) {
nfc_->factoryReset();
EXPECT_EQ(NfcStatus::OK, nfc_->close());
@@ -174,7 +161,7 @@
* Makes an open call, waits for NfcEvent.OPEN_CPLT
* Immediately calls closeforPowerOffCase() and waits for NfcEvent.CLOSE_CPLT
*/
-TEST_F(NfcHidlTest, OpenAndCloseForPowerOff) {
+TEST_P(NfcHidlTest, OpenAndCloseForPowerOff) {
EXPECT_EQ(NfcStatus::OK, nfc_->closeForPowerOffCase());
// Wait for CLOSE_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
@@ -195,7 +182,7 @@
* Calls closeForPowerOffCase()
* Calls close() - checks failed status
*/
-TEST_F(NfcHidlTest, CloseForPowerCaseOffAfterClose) {
+TEST_P(NfcHidlTest, CloseForPowerCaseOffAfterClose) {
EXPECT_EQ(NfcStatus::OK, nfc_->closeForPowerOffCase());
// Wait for CLOSE_CPLT event
auto res = nfc_cb_->WaitForCallback(kCallbackNameSendEvent);
@@ -218,16 +205,19 @@
* Calls getConfig()
* checks if fields in NfcConfig are populated correctly
*/
-TEST_F(NfcHidlTest, GetConfig) {
+TEST_P(NfcHidlTest, GetConfig) {
nfc_->getConfig([](NfcConfig config) {
EXPECT_GE(config.maxIsoDepTransceiveLength, MIN_ISO_DEP_TRANSCEIVE_LENGTH);
});
}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, NfcHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(INfc::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(NfcHidlEnvironment::Instance());
::testing::InitGoogleTest(&argc, argv);
- NfcHidlEnvironment::Instance()->init(&argc, argv);
std::system("svc nfc disable"); /* Turn off NFC */
sleep(5);
diff --git a/nfc/1.2/vts/functional/Android.bp b/nfc/1.2/vts/functional/Android.bp
index 13b254c..7b50a36 100644
--- a/nfc/1.2/vts/functional/Android.bp
+++ b/nfc/1.2/vts/functional/Android.bp
@@ -23,4 +23,5 @@
"android.hardware.nfc@1.1",
"android.hardware.nfc@1.2",
],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/nfc/1.2/vts/functional/VtsHalNfcV1_2TargetTest.cpp b/nfc/1.2/vts/functional/VtsHalNfcV1_2TargetTest.cpp
index 54d3127..3ec088d 100644
--- a/nfc/1.2/vts/functional/VtsHalNfcV1_2TargetTest.cpp
+++ b/nfc/1.2/vts/functional/VtsHalNfcV1_2TargetTest.cpp
@@ -20,11 +20,12 @@
#include <android/hardware/nfc/1.1/INfcClientCallback.h>
#include <android/hardware/nfc/1.2/INfc.h>
#include <android/hardware/nfc/1.2/types.h>
+#include <gtest/gtest.h>
#include <hardware/nfc.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <VtsHalHidlTargetCallbackBase.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
using ::android::sp;
using ::android::hardware::hidl_vec;
@@ -83,26 +84,11 @@
};
};
-// Test environment for Nfc HIDL HAL.
-class NfcHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static NfcHidlEnvironment* Instance() {
- static NfcHidlEnvironment* instance = new NfcHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<INfc>(); }
-
- private:
- NfcHidlEnvironment() {}
-};
-
// The main test class for NFC HIDL HAL.
-class NfcHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class NfcHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- nfc_ = ::testing::VtsHalHidlTargetTestBase::getService<INfc>();
+ nfc_ = INfc::getService(GetParam());
ASSERT_NE(nfc_, nullptr);
nfc_cb_ = new NfcClientCallback();
@@ -152,7 +138,7 @@
* Calls getConfig()
* checks if fields in NfcConfig are populated correctly
*/
-TEST_F(NfcHidlTest, GetExtendedConfig) {
+TEST_P(NfcHidlTest, GetExtendedConfig) {
nfc_->getConfig_1_2([](NfcConfig config) {
for (uint8_t uicc : config.offHostRouteUicc) {
EXPECT_GE(uicc, MIN_OFFHOST_ROUTE_ID);
@@ -169,10 +155,13 @@
});
}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, NfcHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(INfc::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(NfcHidlEnvironment::Instance());
::testing::InitGoogleTest(&argc, argv);
- NfcHidlEnvironment::Instance()->init(&argc, argv);
std::system("svc nfc disable"); /* Turn off NFC */
sleep(5);
diff --git a/power/1.0/vts/functional/Android.bp b/power/1.0/vts/functional/Android.bp
index a716f02..5d5676d 100644
--- a/power/1.0/vts/functional/Android.bp
+++ b/power/1.0/vts/functional/Android.bp
@@ -19,5 +19,5 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalPowerV1_0TargetTest.cpp"],
static_libs: ["android.hardware.power@1.0"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/power/1.0/vts/functional/VtsHalPowerV1_0TargetTest.cpp b/power/1.0/vts/functional/VtsHalPowerV1_0TargetTest.cpp
index 999b2b4..ba08ee7 100644
--- a/power/1.0/vts/functional/VtsHalPowerV1_0TargetTest.cpp
+++ b/power/1.0/vts/functional/VtsHalPowerV1_0TargetTest.cpp
@@ -21,9 +21,9 @@
#include <android-base/unique_fd.h>
#include <android/hardware/power/1.0/IPower.h>
-
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <fcntl.h>
#include <algorithm>
@@ -45,23 +45,10 @@
#define AVAILABLE_GOVERNORS_PATH \
"/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors"
-// Test environment for Power HIDL HAL.
-class PowerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static PowerHidlEnvironment* Instance() {
- static PowerHidlEnvironment* instance = new PowerHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IPower>(); }
-};
-
-class PowerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class PowerHidlTest : public testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- power = ::testing::VtsHalHidlTargetTestBase::getService<IPower>(
- PowerHidlEnvironment::Instance()->getServiceName<IPower>());
+ power = IPower::getService(GetParam());
ASSERT_NE(power, nullptr);
}
@@ -71,7 +58,7 @@
};
// Sanity check Power::setInteractive.
-TEST_F(PowerHidlTest, SetInteractive) {
+TEST_P(PowerHidlTest, SetInteractive) {
Return<void> ret;
ret = power->setInteractive(true);
@@ -83,7 +70,7 @@
// Test Power::setInteractive and Power::powerHint(Launch)
// with each available CPU governor, if available
-TEST_F(PowerHidlTest, TryDifferentGovernors) {
+TEST_P(PowerHidlTest, TryDifferentGovernors) {
Return<void> ret;
unique_fd fd1(open(CPU_GOVERNOR_PATH, O_RDWR));
@@ -125,7 +112,7 @@
}
// Sanity check Power::powerHint on good and bad inputs.
-TEST_F(PowerHidlTest, PowerHint) {
+TEST_P(PowerHidlTest, PowerHint) {
PowerHint badHint = static_cast<PowerHint>(0xA);
auto hints = {PowerHint::VSYNC, PowerHint::INTERACTION,
PowerHint::VIDEO_ENCODE, PowerHint::VIDEO_DECODE,
@@ -163,7 +150,7 @@
}
// Sanity check Power::setFeature() on good and bad inputs.
-TEST_F(PowerHidlTest, SetFeature) {
+TEST_P(PowerHidlTest, SetFeature) {
Return<void> ret;
ret = power->setFeature(Feature::POWER_FEATURE_DOUBLE_TAP_TO_WAKE, true);
ASSERT_TRUE(ret.isOk());
@@ -178,7 +165,7 @@
}
// Sanity check Power::getPlatformLowPowerStats().
-TEST_F(PowerHidlTest, GetPlatformLowPowerStats) {
+TEST_P(PowerHidlTest, GetPlatformLowPowerStats) {
hidl_vec<PowerStatePlatformSleepState> vec;
Status s;
auto cb = [&vec, &s](hidl_vec<PowerStatePlatformSleepState> states,
@@ -191,11 +178,7 @@
ASSERT_TRUE(s == Status::SUCCESS || s == Status::FILESYSTEM_ERROR);
}
-int main(int argc, char **argv) {
- ::testing::AddGlobalTestEnvironment(PowerHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- PowerHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, PowerHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IPower::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/power/1.1/vts/functional/Android.bp b/power/1.1/vts/functional/Android.bp
index de75984..d9a32df 100644
--- a/power/1.1/vts/functional/Android.bp
+++ b/power/1.1/vts/functional/Android.bp
@@ -22,5 +22,5 @@
"android.hardware.power@1.0",
"android.hardware.power@1.1",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/power/1.1/vts/functional/VtsHalPowerV1_1TargetTest.cpp b/power/1.1/vts/functional/VtsHalPowerV1_1TargetTest.cpp
index 4427b15..e9a722c 100644
--- a/power/1.1/vts/functional/VtsHalPowerV1_1TargetTest.cpp
+++ b/power/1.1/vts/functional/VtsHalPowerV1_1TargetTest.cpp
@@ -17,9 +17,9 @@
#define LOG_TAG "power_hidl_hal_test"
#include <android-base/logging.h>
#include <android/hardware/power/1.1/IPower.h>
-
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
using ::android::hardware::power::V1_1::IPower;
using ::android::hardware::power::V1_1::PowerStateSubsystem;
@@ -29,23 +29,10 @@
using ::android::hardware::Return;
using ::android::sp;
-// Test environment for Power HIDL HAL.
-class PowerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static PowerHidlEnvironment* Instance() {
- static PowerHidlEnvironment* instance = new PowerHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IPower>(); }
-};
-
-class PowerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class PowerHidlTest : public testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- power = ::testing::VtsHalHidlTargetTestBase::getService<IPower>(
- PowerHidlEnvironment::Instance()->getServiceName<IPower>());
+ power = IPower::getService(GetParam());
ASSERT_NE(power, nullptr);
}
@@ -55,7 +42,7 @@
};
// Sanity check Power::getSubsystemLowPowerStats().
-TEST_F(PowerHidlTest, GetSubsystemLowPowerStats) {
+TEST_P(PowerHidlTest, GetSubsystemLowPowerStats) {
hidl_vec<PowerStateSubsystem> vec;
Status s;
auto cb = [&vec, &s](hidl_vec<PowerStateSubsystem> subsystems,
@@ -70,7 +57,7 @@
}
// Sanity check Power::powerHintAsync on good and bad inputs.
-TEST_F(PowerHidlTest, PowerHintAsync) {
+TEST_P(PowerHidlTest, PowerHintAsync) {
PowerHint badHint = static_cast<PowerHint>(0xA);
auto hints = {PowerHint::VSYNC, PowerHint::INTERACTION, PowerHint::VIDEO_ENCODE,
PowerHint::VIDEO_DECODE, PowerHint::LOW_POWER, PowerHint::SUSTAINED_PERFORMANCE,
@@ -104,11 +91,7 @@
} while (std::next_permutation(hints2.begin(), hints2.end(), compareHints));
}
-int main(int argc, char **argv) {
- ::testing::AddGlobalTestEnvironment(PowerHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- PowerHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, PowerHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IPower::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/power/1.2/vts/functional/Android.bp b/power/1.2/vts/functional/Android.bp
index f424bfa..5385faa 100644
--- a/power/1.2/vts/functional/Android.bp
+++ b/power/1.2/vts/functional/Android.bp
@@ -23,5 +23,5 @@
"android.hardware.power@1.1",
"android.hardware.power@1.2",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/power/1.2/vts/functional/VtsHalPowerV1_2TargetTest.cpp b/power/1.2/vts/functional/VtsHalPowerV1_2TargetTest.cpp
index 5e92997..a5ecf5d 100644
--- a/power/1.2/vts/functional/VtsHalPowerV1_2TargetTest.cpp
+++ b/power/1.2/vts/functional/VtsHalPowerV1_2TargetTest.cpp
@@ -17,9 +17,9 @@
#define LOG_TAG "power_hidl_hal_test"
#include <android-base/logging.h>
#include <android/hardware/power/1.2/IPower.h>
-
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
using ::android::sp;
using ::android::hardware::hidl_vec;
@@ -27,23 +27,10 @@
using ::android::hardware::power::V1_2::IPower;
using ::android::hardware::power::V1_2::PowerHint;
-// Test environment for Power HIDL HAL.
-class PowerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static PowerHidlEnvironment* Instance() {
- static PowerHidlEnvironment* instance = new PowerHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IPower>(); }
-};
-
-class PowerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class PowerHidlTest : public testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- power = ::testing::VtsHalHidlTargetTestBase::getService<IPower>(
- PowerHidlEnvironment::Instance()->getServiceName<IPower>());
+ power = IPower::getService(GetParam());
ASSERT_NE(power, nullptr);
}
@@ -51,7 +38,7 @@
};
// Sanity check Power::PowerHintAsync_1_2 on good and bad inputs.
-TEST_F(PowerHidlTest, PowerHintAsync_1_2) {
+TEST_P(PowerHidlTest, PowerHintAsync_1_2) {
std::vector<PowerHint> hints;
for (uint32_t i = static_cast<uint32_t>(PowerHint::VSYNC);
i <= static_cast<uint32_t>(PowerHint::CAMERA_SHOT); ++i) {
@@ -89,11 +76,8 @@
} while (std::next_permutation(hints2.begin(), hints2.end(), compareHints));
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(PowerHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- PowerHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, PowerHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IPower::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
diff --git a/power/1.3/vts/functional/Android.bp b/power/1.3/vts/functional/Android.bp
index 06f6e7a..77e8619 100644
--- a/power/1.3/vts/functional/Android.bp
+++ b/power/1.3/vts/functional/Android.bp
@@ -24,5 +24,5 @@
"android.hardware.power@1.2",
"android.hardware.power@1.3",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/power/1.3/vts/functional/VtsHalPowerV1_3TargetTest.cpp b/power/1.3/vts/functional/VtsHalPowerV1_3TargetTest.cpp
index af1a1d8..3cf2adc 100644
--- a/power/1.3/vts/functional/VtsHalPowerV1_3TargetTest.cpp
+++ b/power/1.3/vts/functional/VtsHalPowerV1_3TargetTest.cpp
@@ -17,9 +17,9 @@
#define LOG_TAG "power_hidl_hal_test"
#include <android-base/logging.h>
#include <android/hardware/power/1.3/IPower.h>
-
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
using ::android::sp;
using ::android::hardware::hidl_vec;
@@ -27,38 +27,21 @@
using ::android::hardware::power::V1_3::IPower;
using ::android::hardware::power::V1_3::PowerHint;
-// Test environment for Power HIDL HAL.
-class PowerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static PowerHidlEnvironment* Instance() {
- static PowerHidlEnvironment* instance = new PowerHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IPower>(); }
-};
-
-class PowerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class PowerHidlTest : public testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- power = ::testing::VtsHalHidlTargetTestBase::getService<IPower>(
- PowerHidlEnvironment::Instance()->getServiceName<IPower>());
+ power = IPower::getService(GetParam());
ASSERT_NE(power, nullptr);
}
sp<IPower> power;
};
-TEST_F(PowerHidlTest, PowerHintAsync_1_3) {
+TEST_P(PowerHidlTest, PowerHintAsync_1_3) {
ASSERT_TRUE(power->powerHintAsync_1_3(PowerHint::EXPENSIVE_RENDERING, 0).isOk());
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(PowerHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- PowerHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, PowerHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IPower::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/power/stats/1.0/vts/functional/Android.bp b/power/stats/1.0/vts/functional/Android.bp
index f564cbe..ab47061 100644
--- a/power/stats/1.0/vts/functional/Android.bp
+++ b/power/stats/1.0/vts/functional/Android.bp
@@ -33,4 +33,5 @@
"libfmq",
"libutils",
],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/power/stats/1.0/vts/functional/VtsHalPowerStatsV1_0TargetTest.cpp b/power/stats/1.0/vts/functional/VtsHalPowerStatsV1_0TargetTest.cpp
index 835a47b..3359669 100644
--- a/power/stats/1.0/vts/functional/VtsHalPowerStatsV1_0TargetTest.cpp
+++ b/power/stats/1.0/vts/functional/VtsHalPowerStatsV1_0TargetTest.cpp
@@ -16,13 +16,15 @@
#define LOG_TAG "android.power.stats.vts"
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <android-base/logging.h>
#include <android/hardware/power/stats/1.0/IPowerStats.h>
#include <fmq/MessageQueue.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
#include <hidl/MQDescriptor.h>
+#include <hidl/ServiceManagement.h>
#include <inttypes.h>
+
#include <algorithm>
#include <random>
#include <thread>
@@ -49,23 +51,11 @@
} // namespace
typedef hardware::MessageQueue<EnergyData, kSynchronizedReadWrite> MessageQueueSync;
-// Test environment for Power HIDL HAL.
-class PowerStatsHidlEnv : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static PowerStatsHidlEnv* Instance() {
- static PowerStatsHidlEnv* instance = new PowerStatsHidlEnv;
- return instance;
- }
- virtual void registerTestServices() override { registerTestService<IPowerStats>(); }
-};
-
-class PowerStatsHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class PowerStatsHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- service_ = ::testing::VtsHalHidlTargetTestBase::getService<IPowerStats>(
- PowerStatsHidlEnv::Instance()->getServiceName<IPowerStats>());
+ service_ = IPowerStats::getService(GetParam());
ASSERT_NE(service_, nullptr);
}
@@ -157,7 +147,7 @@
}
// Each PowerEntity must have a valid name
-TEST_F(PowerStatsHidlTest, ValidatePowerEntityNames) {
+TEST_P(PowerStatsHidlTest, ValidatePowerEntityNames) {
hidl_vec<PowerEntityInfo> infos;
getInfos(infos);
for (auto info : infos) {
@@ -166,18 +156,18 @@
}
// Each PowerEntity must have a unique ID
-TEST_F(PowerStatsHidlTest, ValidatePowerEntityIds) {
+TEST_P(PowerStatsHidlTest, ValidatePowerEntityIds) {
hidl_vec<PowerEntityInfo> infos;
getInfos(infos);
- set<uint32_t> ids;
+ std::set<uint32_t> ids;
for (auto info : infos) {
ASSERT_TRUE(ids.insert(info.powerEntityId).second);
}
}
// Each PowerEntityStateSpace must have an associated PowerEntityInfo
-TEST_F(PowerStatsHidlTest, ValidateStateInfoAssociation) {
+TEST_P(PowerStatsHidlTest, ValidateStateInfoAssociation) {
hidl_vec<PowerEntityInfo> infos;
getInfos(infos);
@@ -195,7 +185,7 @@
}
// Each state must have a valid name
-TEST_F(PowerStatsHidlTest, ValidateStateNames) {
+TEST_P(PowerStatsHidlTest, ValidateStateNames) {
hidl_vec<PowerEntityStateSpace> stateSpaces;
getStateSpaces(stateSpaces);
@@ -207,12 +197,12 @@
}
// Each state must have an ID that is unique to the PowerEntityStateSpace
-TEST_F(PowerStatsHidlTest, ValidateStateUniqueIds) {
+TEST_P(PowerStatsHidlTest, ValidateStateUniqueIds) {
hidl_vec<PowerEntityStateSpace> stateSpaces;
getStateSpaces(stateSpaces);
for (auto stateSpace : stateSpaces) {
- set<uint32_t> stateIds;
+ std::set<uint32_t> stateIds;
for (auto state : stateSpace.states) {
ASSERT_TRUE(stateIds.insert(state.powerEntityStateId).second);
}
@@ -221,7 +211,7 @@
// getPowerEntityStateInfo must support passing in requested IDs
// Results must contain state space information for all requested IDs
-TEST_F(PowerStatsHidlTest, ValidateStateInfoAssociationSelect) {
+TEST_P(PowerStatsHidlTest, ValidateStateInfoAssociationSelect) {
std::vector<uint32_t> randomIds;
getRandomIds(randomIds);
@@ -244,7 +234,7 @@
}
// Requested state space info must match initially obtained stateinfos
-TEST_F(PowerStatsHidlTest, ValidateStateInfoSelect) {
+TEST_P(PowerStatsHidlTest, ValidateStateInfoSelect) {
hidl_vec<PowerEntityStateSpace> stateSpaces;
getStateSpaces(stateSpaces);
if (stateSpaces.size() == 0) {
@@ -279,7 +269,7 @@
// stateResidencyResults must contain results for every PowerEntityStateSpace
// returned by getPowerEntityStateInfo
-TEST_F(PowerStatsHidlTest, ValidateResidencyResultsAssociation) {
+TEST_P(PowerStatsHidlTest, ValidateResidencyResultsAssociation) {
hidl_vec<PowerEntityStateSpace> stateSpaces;
getStateSpaces(stateSpaces);
@@ -311,7 +301,7 @@
// getPowerEntityStateResidencyData must support passing in requested IDs
// stateResidencyResults must contain results for each PowerEntityStateSpace
// returned by getPowerEntityStateInfo
-TEST_F(PowerStatsHidlTest, ValidateResidencyResultsAssociationSelect) {
+TEST_P(PowerStatsHidlTest, ValidateResidencyResultsAssociationSelect) {
std::vector<uint32_t> randomIds;
getRandomIds(randomIds);
if (randomIds.empty()) {
@@ -346,7 +336,7 @@
}
}
-TEST_F(PowerStatsHidlTest, ValidateRailInfo) {
+TEST_P(PowerStatsHidlTest, ValidateRailInfo) {
hidl_vec<RailInfo> rails[2];
Status s;
auto cb = [&rails, &s](hidl_vec<RailInfo> rail_subsys, Status status) {
@@ -359,7 +349,7 @@
/* Rails size should be non-zero on SUCCESS*/
ASSERT_NE(rails[0].size(), 0);
/* check if indices returned are unique*/
- set<uint32_t> ids;
+ std::set<uint32_t> ids;
for (auto rail : rails[0]) {
ASSERT_TRUE(ids.insert(rail.index).second);
}
@@ -402,7 +392,7 @@
}
}
-TEST_F(PowerStatsHidlTest, ValidateAllPowerData) {
+TEST_P(PowerStatsHidlTest, ValidateAllPowerData) {
hidl_vec<EnergyData> measurements[2];
Status s;
auto cb = [&measurements, &s](hidl_vec<EnergyData> measure, Status status) {
@@ -451,7 +441,7 @@
}
}
-TEST_F(PowerStatsHidlTest, ValidateFilteredPowerData) {
+TEST_P(PowerStatsHidlTest, ValidateFilteredPowerData) {
hidl_vec<RailInfo> rails;
hidl_vec<EnergyData> measurements;
hidl_vec<uint32_t> indices;
@@ -559,23 +549,19 @@
}
}
-TEST_F(PowerStatsHidlTest, StreamEnergyData) {
+TEST_P(PowerStatsHidlTest, StreamEnergyData) {
std::time_t seed = std::time(nullptr);
std::srand(seed);
std::thread thread1 = std::thread(readEnergy, service_, std::rand() % 5000);
thread1.join();
}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, PowerStatsHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IPowerStats::descriptor)),
+ android::hardware::PrintInstanceNameToString);
+
} // namespace vts
} // namespace stats
} // namespace power
} // namespace android
-
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(android::power::stats::vts::PowerStatsHidlEnv::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- android::power::stats::vts::PowerStatsHidlEnv::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
diff --git a/radio/1.5/Android.bp b/radio/1.5/Android.bp
new file mode 100644
index 0000000..06a2a6e
--- /dev/null
+++ b/radio/1.5/Android.bp
@@ -0,0 +1,25 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.radio@1.5",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "types.hal",
+ "IRadio.hal",
+ "IRadioIndication.hal",
+ "IRadioResponse.hal",
+ ],
+ interfaces: [
+ "android.hardware.radio@1.0",
+ "android.hardware.radio@1.1",
+ "android.hardware.radio@1.2",
+ "android.hardware.radio@1.3",
+ "android.hardware.radio@1.4",
+ "android.hidl.base@1.0",
+ "android.hidl.safe_union@1.0",
+ ],
+ gen_java: true,
+}
diff --git a/radio/1.5/IRadio.hal b/radio/1.5/IRadio.hal
new file mode 100644
index 0000000..de20dd0
--- /dev/null
+++ b/radio/1.5/IRadio.hal
@@ -0,0 +1,30 @@
+/*
+ * 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.radio@1.5;
+
+import @1.4::IRadio;
+
+/**
+ * This interface is used by telephony and telecom to talk to cellular radio.
+ * All the functions have minimum one parameter:
+ * serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the
+ * duration of a method call. If clients provide colliding serials (including passing the same
+ * serial to different methods), multiple responses (one for each method call) must still be served.
+ * setResponseFunctions must work with @1.5::IRadioResponse and @1.5::IRadioIndication.
+ */
+interface IRadio extends @1.4::IRadio {
+};
diff --git a/radio/1.5/IRadioIndication.hal b/radio/1.5/IRadioIndication.hal
new file mode 100644
index 0000000..d488404
--- /dev/null
+++ b/radio/1.5/IRadioIndication.hal
@@ -0,0 +1,26 @@
+/*
+ * 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.radio@1.5;
+
+import @1.0::RadioIndicationType;
+import @1.4::IRadioIndication;
+
+/**
+ * Interface declaring unsolicited radio indications.
+ */
+interface IRadioIndication extends @1.4::IRadioIndication {
+};
diff --git a/radio/1.5/IRadioResponse.hal b/radio/1.5/IRadioResponse.hal
new file mode 100644
index 0000000..d4c4f76
--- /dev/null
+++ b/radio/1.5/IRadioResponse.hal
@@ -0,0 +1,26 @@
+/*
+ * 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.radio@1.5;
+
+import @1.0::RadioResponseInfo;
+import @1.4::IRadioResponse;
+
+/**
+ * Interface declaring response functions to solicited radio requests.
+ */
+interface IRadioResponse extends @1.4::IRadioResponse {
+};
diff --git a/radio/1.5/types.hal b/radio/1.5/types.hal
new file mode 100644
index 0000000..a639a8d
--- /dev/null
+++ b/radio/1.5/types.hal
@@ -0,0 +1,17 @@
+/*
+ * 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.radio@1.5;
diff --git a/radio/1.5/vts/OWNERS b/radio/1.5/vts/OWNERS
new file mode 100644
index 0000000..3629a6c
--- /dev/null
+++ b/radio/1.5/vts/OWNERS
@@ -0,0 +1,10 @@
+# Telephony team
+refuhoo@google.com
+amitmahajan@google.com
+jackyu@google.com
+fionaxu@google.com
+# more to add
+
+# VTS team
+yuexima@google.com
+dshi@google.com
\ No newline at end of file
diff --git a/radio/1.5/vts/functional/Android.bp b/radio/1.5/vts/functional/Android.bp
new file mode 100644
index 0000000..85c4f99
--- /dev/null
+++ b/radio/1.5/vts/functional/Android.bp
@@ -0,0 +1,40 @@
+//
+// 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: "VtsHalRadioV1_5TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: [
+ "radio_hidl_hal_api.cpp",
+ "radio_hidl_hal_test.cpp",
+ "radio_response.cpp",
+ "radio_indication.cpp",
+ "VtsHalRadioV1_5TargetTest.cpp",
+ ],
+ static_libs: [
+ "RadioVtsTestUtilBase",
+ "android.hardware.radio@1.5",
+ "android.hardware.radio@1.4",
+ "android.hardware.radio@1.3",
+ "android.hardware.radio@1.2",
+ "android.hardware.radio@1.1",
+ "android.hardware.radio@1.0",
+ "android.hardware.radio.config@1.0",
+ "android.hardware.radio.config@1.1",
+ ],
+ header_libs: ["radio.util.header@1.0"],
+ test_suites: ["general-tests"]
+}
diff --git a/radio/1.5/vts/functional/VtsHalRadioV1_5TargetTest.cpp b/radio/1.5/vts/functional/VtsHalRadioV1_5TargetTest.cpp
new file mode 100644
index 0000000..b72febd
--- /dev/null
+++ b/radio/1.5/vts/functional/VtsHalRadioV1_5TargetTest.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#include <radio_hidl_hal_utils_v1_5.h>
+
+int main(int argc, char** argv) {
+ ::testing::AddGlobalTestEnvironment(RadioHidlEnvironment::Instance());
+ ::testing::InitGoogleTest(&argc, argv);
+ RadioHidlEnvironment::Instance()->init(&argc, argv);
+ int status = RUN_ALL_TESTS();
+ LOG(INFO) << "Test result = " << status;
+ return status;
+}
\ No newline at end of file
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_api.cpp b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
new file mode 100644
index 0000000..b86fa5f
--- /dev/null
+++ b/radio/1.5/vts/functional/radio_hidl_hal_api.cpp
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+#include <radio_hidl_hal_utils_v1_5.h>
+
+#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_test.cpp b/radio/1.5/vts/functional/radio_hidl_hal_test.cpp
new file mode 100644
index 0000000..a5d236d
--- /dev/null
+++ b/radio/1.5/vts/functional/radio_hidl_hal_test.cpp
@@ -0,0 +1,94 @@
+/*
+ * 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.
+ */
+
+#include <radio_hidl_hal_utils_v1_5.h>
+
+void RadioHidlTest_v1_5::SetUp() {
+ radio_v1_5 = ::testing::VtsHalHidlTargetTestBase::getService<
+ ::android::hardware::radio::V1_5::IRadio>(
+ RadioHidlEnvironment::Instance()
+ ->getServiceName<::android::hardware::radio::V1_5::IRadio>(
+ hidl_string(RADIO_SERVICE_NAME)));
+ if (radio_v1_5 == NULL) {
+ sleep(60);
+ radio_v1_5 = ::testing::VtsHalHidlTargetTestBase::getService<
+ ::android::hardware::radio::V1_5::IRadio>(
+ RadioHidlEnvironment::Instance()
+ ->getServiceName<::android::hardware::radio::V1_5::IRadio>(
+ hidl_string(RADIO_SERVICE_NAME)));
+ }
+ ASSERT_NE(nullptr, radio_v1_5.get());
+
+ radioRsp_v1_5 = new (std::nothrow) RadioResponse_v1_5(*this);
+ ASSERT_NE(nullptr, radioRsp_v1_5.get());
+
+ count_ = 0;
+
+ radioInd_v1_5 = new (std::nothrow) RadioIndication_v1_5(*this);
+ ASSERT_NE(nullptr, radioInd_v1_5.get());
+
+ radio_v1_5->setResponseFunctions(radioRsp_v1_5, radioInd_v1_5);
+
+ updateSimCardStatus();
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_5->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_5->rspInfo.serial);
+ EXPECT_EQ(RadioError::NONE, radioRsp_v1_5->rspInfo.error);
+
+ sp<::android::hardware::radio::config::V1_1::IRadioConfig> radioConfig =
+ ::testing::VtsHalHidlTargetTestBase::getService<
+ ::android::hardware::radio::config::V1_1::IRadioConfig>();
+
+ /* Enforce Vts tesing with RadioConfig is existed. */
+ ASSERT_NE(nullptr, radioConfig.get());
+
+ /* Enforce Vts Testing with Sim Status Present only. */
+ EXPECT_EQ(CardState::PRESENT, cardStatus.base.base.cardState);
+}
+
+/*
+ * Notify that the response message is received.
+ */
+void RadioHidlTest_v1_5::notify(int receivedSerial) {
+ std::unique_lock<std::mutex> lock(mtx_);
+ if (serial == receivedSerial) {
+ count_++;
+ cv_.notify_one();
+ }
+}
+
+/*
+ * Wait till the response message is notified or till TIMEOUT_PERIOD.
+ */
+std::cv_status RadioHidlTest_v1_5::wait() {
+ std::unique_lock<std::mutex> lock(mtx_);
+
+ std::cv_status status = std::cv_status::no_timeout;
+ auto now = std::chrono::system_clock::now();
+ while (count_ == 0) {
+ status = cv_.wait_until(lock, now + std::chrono::seconds(TIMEOUT_PERIOD));
+ if (status == std::cv_status::timeout) {
+ return status;
+ }
+ }
+ count_--;
+ return status;
+}
+
+void RadioHidlTest_v1_5::updateSimCardStatus() {
+ serial = GetRandomSerialNumber();
+ radio_v1_5->getIccCardStatus(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+}
diff --git a/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
new file mode 100644
index 0000000..799702b
--- /dev/null
+++ b/radio/1.5/vts/functional/radio_hidl_hal_utils_v1_5.h
@@ -0,0 +1,760 @@
+/*
+ * 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.
+ */
+
+#include <android-base/logging.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+#include <VtsHalHidlTargetTestEnvBase.h>
+#include <chrono>
+#include <condition_variable>
+#include <mutex>
+
+#include <android/hardware/radio/config/1.1/IRadioConfig.h>
+
+#include <android/hardware/radio/1.5/IRadio.h>
+#include <android/hardware/radio/1.5/IRadioIndication.h>
+#include <android/hardware/radio/1.5/IRadioResponse.h>
+#include <android/hardware/radio/1.5/types.h>
+
+#include "vts_test_util.h"
+
+using namespace ::android::hardware::radio::V1_5;
+using namespace ::android::hardware::radio::V1_4;
+using namespace ::android::hardware::radio::V1_3;
+using namespace ::android::hardware::radio::V1_2;
+using namespace ::android::hardware::radio::V1_1;
+using namespace ::android::hardware::radio::V1_0;
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+
+#define TIMEOUT_PERIOD 75
+#define MODEM_EMERGENCY_CALL_ESTABLISH_TIME 3
+#define MODEM_EMERGENCY_CALL_DISCONNECT_TIME 3
+
+#define RADIO_SERVICE_NAME "slot1"
+
+class RadioHidlTest_v1_5;
+extern ::android::hardware::radio::V1_4::CardStatus cardStatus;
+
+/* Callback class for radio respons v1_5 */
+class RadioResponse_v1_5 : public ::android::hardware::radio::V1_5::IRadioResponse {
+ protected:
+ RadioHidlTest_v1_5& parent_v1_5;
+
+ public:
+ hidl_vec<RadioBandMode> radioBandModes;
+
+ RadioResponseInfo rspInfo;
+
+ // Call
+ hidl_vec<::android::hardware::radio::V1_2::Call> currentCalls;
+
+ // Modem
+ bool isModemEnabled;
+ bool enableModemResponseToggle;
+
+ ::android::hardware::hidl_bitfield<::android::hardware::radio::V1_4::RadioAccessFamily>
+ networkTypeBitmapResponse;
+
+ // Data
+ ::android::hardware::radio::V1_4::DataRegStateResult dataRegResp;
+
+ // SimLock status
+ ::android::hardware::radio::V1_4::CarrierRestrictionsWithPriority carrierRestrictionsResp;
+ ::android::hardware::radio::V1_4::SimLockMultiSimPolicy multiSimPolicyResp;
+
+ RadioResponse_v1_5(RadioHidlTest_v1_5& parent_v1_5);
+ virtual ~RadioResponse_v1_5() = default;
+
+ Return<void> getIccCardStatusResponse(
+ const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::CardStatus& cardStatus);
+
+ Return<void> supplyIccPinForAppResponse(const RadioResponseInfo& info,
+ int32_t remainingRetries);
+
+ Return<void> supplyIccPukForAppResponse(const RadioResponseInfo& info,
+ int32_t remainingRetries);
+
+ Return<void> supplyIccPin2ForAppResponse(const RadioResponseInfo& info,
+ int32_t remainingRetries);
+
+ Return<void> supplyIccPuk2ForAppResponse(const RadioResponseInfo& info,
+ int32_t remainingRetries);
+
+ Return<void> changeIccPinForAppResponse(const RadioResponseInfo& info,
+ int32_t remainingRetries);
+
+ Return<void> changeIccPin2ForAppResponse(const RadioResponseInfo& info,
+ int32_t remainingRetries);
+
+ Return<void> supplyNetworkDepersonalizationResponse(const RadioResponseInfo& info,
+ int32_t remainingRetries);
+
+ Return<void> getCurrentCallsResponse(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<::android::hardware::radio::V1_0::Call>& calls);
+
+ Return<void> dialResponse(const RadioResponseInfo& info);
+
+ Return<void> getIMSIForAppResponse(const RadioResponseInfo& info,
+ const ::android::hardware::hidl_string& imsi);
+
+ Return<void> hangupConnectionResponse(const RadioResponseInfo& info);
+
+ Return<void> hangupWaitingOrBackgroundResponse(const RadioResponseInfo& info);
+
+ Return<void> hangupForegroundResumeBackgroundResponse(const RadioResponseInfo& info);
+
+ Return<void> switchWaitingOrHoldingAndActiveResponse(const RadioResponseInfo& info);
+
+ Return<void> conferenceResponse(const RadioResponseInfo& info);
+
+ Return<void> rejectCallResponse(const RadioResponseInfo& info);
+
+ Return<void> getLastCallFailCauseResponse(const RadioResponseInfo& info,
+ const LastCallFailCauseInfo& failCauseInfo);
+
+ Return<void> getSignalStrengthResponse(
+ const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::SignalStrength& sigStrength);
+
+ Return<void> getVoiceRegistrationStateResponse(
+ const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::VoiceRegStateResult& voiceRegResponse);
+
+ Return<void> getDataRegistrationStateResponse(
+ const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_0::DataRegStateResult& dataRegResponse);
+
+ Return<void> getOperatorResponse(const RadioResponseInfo& info,
+ const ::android::hardware::hidl_string& longName,
+ const ::android::hardware::hidl_string& shortName,
+ const ::android::hardware::hidl_string& numeric);
+
+ Return<void> setRadioPowerResponse(const RadioResponseInfo& info);
+
+ Return<void> sendDtmfResponse(const RadioResponseInfo& info);
+
+ Return<void> sendSmsResponse(const RadioResponseInfo& info, const SendSmsResult& sms);
+
+ Return<void> sendSMSExpectMoreResponse(const RadioResponseInfo& info, const SendSmsResult& sms);
+
+ Return<void> setupDataCallResponse(
+ const RadioResponseInfo& info,
+ const android::hardware::radio::V1_0::SetupDataCallResult& dcResponse);
+
+ Return<void> iccIOForAppResponse(const RadioResponseInfo& info, const IccIoResult& iccIo);
+
+ Return<void> sendUssdResponse(const RadioResponseInfo& info);
+
+ Return<void> cancelPendingUssdResponse(const RadioResponseInfo& info);
+
+ Return<void> getClirResponse(const RadioResponseInfo& info, int32_t n, int32_t m);
+
+ Return<void> setClirResponse(const RadioResponseInfo& info);
+
+ Return<void> getCallForwardStatusResponse(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<CallForwardInfo>& call_forwardInfos);
+
+ Return<void> setCallForwardResponse(const RadioResponseInfo& info);
+
+ Return<void> getCallWaitingResponse(const RadioResponseInfo& info, bool enable,
+ int32_t serviceClass);
+
+ Return<void> setCallWaitingResponse(const RadioResponseInfo& info);
+
+ Return<void> acknowledgeLastIncomingGsmSmsResponse(const RadioResponseInfo& info);
+
+ Return<void> acceptCallResponse(const RadioResponseInfo& info);
+
+ Return<void> deactivateDataCallResponse(const RadioResponseInfo& info);
+
+ Return<void> getFacilityLockForAppResponse(const RadioResponseInfo& info, int32_t response);
+
+ Return<void> setFacilityLockForAppResponse(const RadioResponseInfo& info, int32_t retry);
+
+ Return<void> setBarringPasswordResponse(const RadioResponseInfo& info);
+
+ Return<void> getNetworkSelectionModeResponse(const RadioResponseInfo& info, bool manual);
+
+ Return<void> setNetworkSelectionModeAutomaticResponse(const RadioResponseInfo& info);
+
+ Return<void> setNetworkSelectionModeManualResponse(const RadioResponseInfo& info);
+
+ Return<void> getAvailableNetworksResponse(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<OperatorInfo>& networkInfos);
+
+ Return<void> startDtmfResponse(const RadioResponseInfo& info);
+
+ Return<void> stopDtmfResponse(const RadioResponseInfo& info);
+
+ Return<void> getBasebandVersionResponse(const RadioResponseInfo& info,
+ const ::android::hardware::hidl_string& version);
+
+ Return<void> separateConnectionResponse(const RadioResponseInfo& info);
+
+ Return<void> setMuteResponse(const RadioResponseInfo& info);
+
+ Return<void> getMuteResponse(const RadioResponseInfo& info, bool enable);
+
+ Return<void> getClipResponse(const RadioResponseInfo& info, ClipStatus status);
+
+ Return<void> getDataCallListResponse(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<
+ android::hardware::radio::V1_0::SetupDataCallResult>& dcResponse);
+
+ Return<void> sendOemRilRequestRawResponse(const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<uint8_t>& data);
+
+ Return<void> sendOemRilRequestStringsResponse(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& data);
+
+ Return<void> setSuppServiceNotificationsResponse(const RadioResponseInfo& info);
+
+ Return<void> writeSmsToSimResponse(const RadioResponseInfo& info, int32_t index);
+
+ Return<void> deleteSmsOnSimResponse(const RadioResponseInfo& info);
+
+ Return<void> setBandModeResponse(const RadioResponseInfo& info);
+
+ Return<void> getAvailableBandModesResponse(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<RadioBandMode>& bandModes);
+
+ Return<void> sendEnvelopeResponse(const RadioResponseInfo& info,
+ const ::android::hardware::hidl_string& commandResponse);
+
+ Return<void> sendTerminalResponseToSimResponse(const RadioResponseInfo& info);
+
+ Return<void> handleStkCallSetupRequestFromSimResponse(const RadioResponseInfo& info);
+
+ Return<void> explicitCallTransferResponse(const RadioResponseInfo& info);
+
+ Return<void> setPreferredNetworkTypeResponse(const RadioResponseInfo& info);
+
+ Return<void> getPreferredNetworkTypeResponse(const RadioResponseInfo& info,
+ PreferredNetworkType nwType);
+
+ Return<void> getNeighboringCidsResponse(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<NeighboringCell>& cells);
+
+ Return<void> setLocationUpdatesResponse(const RadioResponseInfo& info);
+
+ Return<void> setCdmaSubscriptionSourceResponse(const RadioResponseInfo& info);
+
+ Return<void> setCdmaRoamingPreferenceResponse(const RadioResponseInfo& info);
+
+ Return<void> getCdmaRoamingPreferenceResponse(const RadioResponseInfo& info,
+ CdmaRoamingType type);
+
+ Return<void> setTTYModeResponse(const RadioResponseInfo& info);
+
+ Return<void> getTTYModeResponse(const RadioResponseInfo& info, TtyMode mode);
+
+ Return<void> setPreferredVoicePrivacyResponse(const RadioResponseInfo& info);
+
+ Return<void> getPreferredVoicePrivacyResponse(const RadioResponseInfo& info, bool enable);
+
+ Return<void> sendCDMAFeatureCodeResponse(const RadioResponseInfo& info);
+
+ Return<void> sendBurstDtmfResponse(const RadioResponseInfo& info);
+
+ Return<void> sendCdmaSmsResponse(const RadioResponseInfo& info, const SendSmsResult& sms);
+
+ Return<void> acknowledgeLastIncomingCdmaSmsResponse(const RadioResponseInfo& info);
+
+ Return<void> getGsmBroadcastConfigResponse(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<GsmBroadcastSmsConfigInfo>& configs);
+
+ Return<void> setGsmBroadcastConfigResponse(const RadioResponseInfo& info);
+
+ Return<void> setGsmBroadcastActivationResponse(const RadioResponseInfo& info);
+
+ Return<void> getCdmaBroadcastConfigResponse(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<CdmaBroadcastSmsConfigInfo>& configs);
+
+ Return<void> setCdmaBroadcastConfigResponse(const RadioResponseInfo& info);
+
+ Return<void> setCdmaBroadcastActivationResponse(const RadioResponseInfo& info);
+
+ Return<void> getCDMASubscriptionResponse(const RadioResponseInfo& info,
+ const ::android::hardware::hidl_string& mdn,
+ const ::android::hardware::hidl_string& hSid,
+ const ::android::hardware::hidl_string& hNid,
+ const ::android::hardware::hidl_string& min,
+ const ::android::hardware::hidl_string& prl);
+
+ Return<void> writeSmsToRuimResponse(const RadioResponseInfo& info, uint32_t index);
+
+ Return<void> deleteSmsOnRuimResponse(const RadioResponseInfo& info);
+
+ Return<void> getDeviceIdentityResponse(const RadioResponseInfo& info,
+ const ::android::hardware::hidl_string& imei,
+ const ::android::hardware::hidl_string& imeisv,
+ const ::android::hardware::hidl_string& esn,
+ const ::android::hardware::hidl_string& meid);
+
+ Return<void> exitEmergencyCallbackModeResponse(const RadioResponseInfo& info);
+
+ Return<void> getSmscAddressResponse(const RadioResponseInfo& info,
+ const ::android::hardware::hidl_string& smsc);
+
+ Return<void> setSmscAddressResponse(const RadioResponseInfo& info);
+
+ Return<void> reportSmsMemoryStatusResponse(const RadioResponseInfo& info);
+
+ Return<void> reportStkServiceIsRunningResponse(const RadioResponseInfo& info);
+
+ Return<void> getCdmaSubscriptionSourceResponse(const RadioResponseInfo& info,
+ CdmaSubscriptionSource source);
+
+ Return<void> requestIsimAuthenticationResponse(
+ const RadioResponseInfo& info, const ::android::hardware::hidl_string& response);
+
+ Return<void> acknowledgeIncomingGsmSmsWithPduResponse(const RadioResponseInfo& info);
+
+ Return<void> sendEnvelopeWithStatusResponse(const RadioResponseInfo& info,
+ const IccIoResult& iccIo);
+
+ Return<void> getVoiceRadioTechnologyResponse(
+ const RadioResponseInfo& info, ::android::hardware::radio::V1_0::RadioTechnology rat);
+
+ Return<void> getCellInfoListResponse(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<::android::hardware::radio::V1_0::CellInfo>&
+ cellInfo);
+
+ Return<void> setCellInfoListRateResponse(const RadioResponseInfo& info);
+
+ Return<void> setInitialAttachApnResponse(const RadioResponseInfo& info);
+
+ Return<void> getImsRegistrationStateResponse(const RadioResponseInfo& info, bool isRegistered,
+ RadioTechnologyFamily ratFamily);
+
+ Return<void> sendImsSmsResponse(const RadioResponseInfo& info, const SendSmsResult& sms);
+
+ Return<void> iccTransmitApduBasicChannelResponse(const RadioResponseInfo& info,
+ const IccIoResult& result);
+
+ Return<void> iccOpenLogicalChannelResponse(
+ const RadioResponseInfo& info, int32_t channelId,
+ const ::android::hardware::hidl_vec<int8_t>& selectResponse);
+
+ Return<void> iccCloseLogicalChannelResponse(const RadioResponseInfo& info);
+
+ Return<void> iccTransmitApduLogicalChannelResponse(const RadioResponseInfo& info,
+ const IccIoResult& result);
+
+ Return<void> nvReadItemResponse(const RadioResponseInfo& info,
+ const ::android::hardware::hidl_string& result);
+
+ Return<void> nvWriteItemResponse(const RadioResponseInfo& info);
+
+ Return<void> nvWriteCdmaPrlResponse(const RadioResponseInfo& info);
+
+ Return<void> nvResetConfigResponse(const RadioResponseInfo& info);
+
+ Return<void> setUiccSubscriptionResponse(const RadioResponseInfo& info);
+
+ Return<void> setDataAllowedResponse(const RadioResponseInfo& info);
+
+ Return<void> getHardwareConfigResponse(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<HardwareConfig>& config);
+
+ Return<void> requestIccSimAuthenticationResponse(const RadioResponseInfo& info,
+ const IccIoResult& result);
+
+ Return<void> setDataProfileResponse(const RadioResponseInfo& info);
+
+ Return<void> requestShutdownResponse(const RadioResponseInfo& info);
+
+ Return<void> getRadioCapabilityResponse(
+ const RadioResponseInfo& info,
+ const android::hardware::radio::V1_0::RadioCapability& rc);
+
+ Return<void> setRadioCapabilityResponse(
+ const RadioResponseInfo& info,
+ const android::hardware::radio::V1_0::RadioCapability& rc);
+
+ Return<void> startLceServiceResponse(const RadioResponseInfo& info,
+ const LceStatusInfo& statusInfo);
+
+ Return<void> stopLceServiceResponse(const RadioResponseInfo& info,
+ const LceStatusInfo& statusInfo);
+
+ Return<void> pullLceDataResponse(const RadioResponseInfo& info, const LceDataInfo& lceInfo);
+
+ Return<void> getModemActivityInfoResponse(const RadioResponseInfo& info,
+ const ActivityStatsInfo& activityInfo);
+
+ Return<void> setAllowedCarriersResponse(const RadioResponseInfo& info, int32_t numAllowed);
+
+ Return<void> getAllowedCarriersResponse(const RadioResponseInfo& info, bool allAllowed,
+ const CarrierRestrictions& carriers);
+
+ Return<void> sendDeviceStateResponse(const RadioResponseInfo& info);
+
+ Return<void> setIndicationFilterResponse(const RadioResponseInfo& info);
+
+ Return<void> setSimCardPowerResponse(const RadioResponseInfo& info);
+
+ Return<void> acknowledgeRequest(int32_t serial);
+
+ /* 1.1 Api */
+ Return<void> setCarrierInfoForImsiEncryptionResponse(const RadioResponseInfo& info);
+
+ Return<void> setSimCardPowerResponse_1_1(const RadioResponseInfo& info);
+
+ Return<void> startNetworkScanResponse(const RadioResponseInfo& info);
+
+ Return<void> stopNetworkScanResponse(const RadioResponseInfo& info);
+
+ Return<void> startKeepaliveResponse(const RadioResponseInfo& info,
+ const KeepaliveStatus& status);
+
+ Return<void> stopKeepaliveResponse(const RadioResponseInfo& info);
+
+ /* 1.2 Api */
+ Return<void> setSignalStrengthReportingCriteriaResponse(const RadioResponseInfo& info);
+
+ Return<void> setLinkCapacityReportingCriteriaResponse(const RadioResponseInfo& info);
+
+ Return<void> getIccCardStatusResponse_1_2(
+ const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_2::CardStatus& card_status);
+
+ Return<void> getCurrentCallsResponse_1_2(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::Call>& calls);
+
+ Return<void> getSignalStrengthResponse_1_2(
+ const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_2::SignalStrength& sig_strength);
+
+ Return<void> getSignalStrengthResponse_1_4(
+ const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_4::SignalStrength& sig_strength);
+
+ Return<void> getCellInfoListResponse_1_2(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::CellInfo>&
+ cellInfo);
+
+ Return<void> getVoiceRegistrationStateResponse_1_2(
+ const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_2::VoiceRegStateResult& voiceRegResponse);
+
+ Return<void> getDataRegistrationStateResponse_1_2(
+ const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_2::DataRegStateResult& dataRegResponse);
+
+ /* 1.3 Api */
+ Return<void> setSystemSelectionChannelsResponse(const RadioResponseInfo& info);
+
+ Return<void> enableModemResponse(const RadioResponseInfo& info);
+
+ Return<void> getModemStackStatusResponse(const RadioResponseInfo& info, const bool enabled);
+
+ /* 1.4 Api */
+ Return<void> emergencyDialResponse(const RadioResponseInfo& info);
+
+ Return<void> startNetworkScanResponse_1_4(const RadioResponseInfo& info);
+
+ Return<void> getCellInfoListResponse_1_4(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<::android::hardware::radio::V1_4::CellInfo>&
+ cellInfo);
+
+ Return<void> getDataRegistrationStateResponse_1_4(
+ const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_4::DataRegStateResult& dataRegResponse);
+
+ Return<void> getIccCardStatusResponse_1_4(
+ const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_4::CardStatus& card_status);
+
+ Return<void> getPreferredNetworkTypeBitmapResponse(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_bitfield<
+ ::android::hardware::radio::V1_4::RadioAccessFamily>
+ networkTypeBitmap);
+
+ Return<void> setPreferredNetworkTypeBitmapResponse(const RadioResponseInfo& info);
+
+ Return<void> getDataCallListResponse_1_4(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<
+ ::android::hardware::radio::V1_4::SetupDataCallResult>& dcResponse);
+
+ Return<void> setupDataCallResponse_1_4(
+ const RadioResponseInfo& info,
+ const android::hardware::radio::V1_4::SetupDataCallResult& dcResponse);
+
+ Return<void> setAllowedCarriersResponse_1_4(const RadioResponseInfo& info);
+
+ Return<void> getAllowedCarriersResponse_1_4(const RadioResponseInfo& info,
+ const CarrierRestrictionsWithPriority& carriers,
+ SimLockMultiSimPolicy multiSimPolicy);
+};
+
+/* Callback class for radio indication */
+class RadioIndication_v1_5 : public ::android::hardware::radio::V1_5::IRadioIndication {
+ protected:
+ RadioHidlTest_v1_5& parent_v1_5;
+
+ public:
+ RadioIndication_v1_5(RadioHidlTest_v1_5& parent_v1_5);
+ virtual ~RadioIndication_v1_5() = default;
+
+ /* 1.4 Api */
+ Return<void> currentEmergencyNumberList(
+ RadioIndicationType type,
+ const ::android::hardware::hidl_vec<EmergencyNumber>& emergencyNumberList);
+
+ Return<void> cellInfoList_1_4(
+ RadioIndicationType type,
+ const ::android::hardware::hidl_vec<::android::hardware::radio::V1_4::CellInfo>&
+ records);
+
+ Return<void> networkScanResult_1_4(
+ RadioIndicationType type,
+ const ::android::hardware::radio::V1_4::NetworkScanResult& result);
+
+ Return<void> currentPhysicalChannelConfigs_1_4(
+ RadioIndicationType type,
+ const ::android::hardware::hidl_vec<
+ ::android::hardware::radio::V1_4::PhysicalChannelConfig>& configs);
+
+ Return<void> dataCallListChanged_1_4(
+ RadioIndicationType type,
+ const ::android::hardware::hidl_vec<
+ android::hardware::radio::V1_4::SetupDataCallResult>& dcList);
+
+ /* 1.2 Api */
+ Return<void> networkScanResult_1_2(
+ RadioIndicationType type,
+ const ::android::hardware::radio::V1_2::NetworkScanResult& result);
+
+ Return<void> cellInfoList_1_2(
+ RadioIndicationType type,
+ const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::CellInfo>&
+ records);
+
+ Return<void> currentLinkCapacityEstimate(
+ RadioIndicationType type,
+ const ::android::hardware::radio::V1_2::LinkCapacityEstimate& lce);
+
+ Return<void> currentPhysicalChannelConfigs(
+ RadioIndicationType type,
+ const ::android::hardware::hidl_vec<
+ ::android::hardware::radio::V1_2::PhysicalChannelConfig>& configs);
+
+ Return<void> currentSignalStrength_1_2(
+ RadioIndicationType type,
+ const ::android::hardware::radio::V1_2::SignalStrength& signalStrength);
+
+ Return<void> currentSignalStrength_1_4(
+ RadioIndicationType type,
+ const ::android::hardware::radio::V1_4::SignalStrength& signalStrength);
+
+ /* 1.1 Api */
+ Return<void> carrierInfoForImsiEncryption(RadioIndicationType info);
+
+ Return<void> networkScanResult(
+ RadioIndicationType type,
+ const ::android::hardware::radio::V1_1::NetworkScanResult& result);
+
+ Return<void> keepaliveStatus(RadioIndicationType type, const KeepaliveStatus& status);
+
+ /* 1.0 Api */
+ Return<void> radioStateChanged(RadioIndicationType type, RadioState radioState);
+
+ Return<void> callStateChanged(RadioIndicationType type);
+
+ Return<void> networkStateChanged(RadioIndicationType type);
+
+ Return<void> newSms(RadioIndicationType type,
+ const ::android::hardware::hidl_vec<uint8_t>& pdu);
+
+ Return<void> newSmsStatusReport(RadioIndicationType type,
+ const ::android::hardware::hidl_vec<uint8_t>& pdu);
+
+ Return<void> newSmsOnSim(RadioIndicationType type, int32_t recordNumber);
+
+ Return<void> onUssd(RadioIndicationType type, UssdModeType modeType,
+ const ::android::hardware::hidl_string& msg);
+
+ Return<void> nitzTimeReceived(RadioIndicationType type,
+ const ::android::hardware::hidl_string& nitzTime,
+ uint64_t receivedTime);
+
+ Return<void> currentSignalStrength(
+ RadioIndicationType type,
+ const ::android::hardware::radio::V1_0::SignalStrength& signalStrength);
+
+ Return<void> dataCallListChanged(
+ RadioIndicationType type,
+ const ::android::hardware::hidl_vec<
+ android::hardware::radio::V1_0::SetupDataCallResult>& dcList);
+
+ Return<void> suppSvcNotify(RadioIndicationType type, const SuppSvcNotification& suppSvc);
+
+ Return<void> stkSessionEnd(RadioIndicationType type);
+
+ Return<void> stkProactiveCommand(RadioIndicationType type,
+ const ::android::hardware::hidl_string& cmd);
+
+ Return<void> stkEventNotify(RadioIndicationType type,
+ const ::android::hardware::hidl_string& cmd);
+
+ Return<void> stkCallSetup(RadioIndicationType type, int64_t timeout);
+
+ Return<void> simSmsStorageFull(RadioIndicationType type);
+
+ Return<void> simRefresh(RadioIndicationType type, const SimRefreshResult& refreshResult);
+
+ Return<void> callRing(RadioIndicationType type, bool isGsm, const CdmaSignalInfoRecord& record);
+
+ Return<void> simStatusChanged(RadioIndicationType type);
+
+ Return<void> cdmaNewSms(RadioIndicationType type, const CdmaSmsMessage& msg);
+
+ Return<void> newBroadcastSms(RadioIndicationType type,
+ const ::android::hardware::hidl_vec<uint8_t>& data);
+
+ Return<void> cdmaRuimSmsStorageFull(RadioIndicationType type);
+
+ Return<void> restrictedStateChanged(RadioIndicationType type, PhoneRestrictedState state);
+
+ Return<void> enterEmergencyCallbackMode(RadioIndicationType type);
+
+ Return<void> cdmaCallWaiting(RadioIndicationType type,
+ const CdmaCallWaiting& callWaitingRecord);
+
+ Return<void> cdmaOtaProvisionStatus(RadioIndicationType type, CdmaOtaProvisionStatus status);
+
+ Return<void> cdmaInfoRec(RadioIndicationType type, const CdmaInformationRecords& records);
+
+ Return<void> indicateRingbackTone(RadioIndicationType type, bool start);
+
+ Return<void> resendIncallMute(RadioIndicationType type);
+
+ Return<void> cdmaSubscriptionSourceChanged(RadioIndicationType type,
+ CdmaSubscriptionSource cdmaSource);
+
+ Return<void> cdmaPrlChanged(RadioIndicationType type, int32_t version);
+
+ Return<void> exitEmergencyCallbackMode(RadioIndicationType type);
+
+ Return<void> rilConnected(RadioIndicationType type);
+
+ Return<void> voiceRadioTechChanged(RadioIndicationType type,
+ ::android::hardware::radio::V1_0::RadioTechnology rat);
+
+ Return<void> cellInfoList(
+ RadioIndicationType type,
+ const ::android::hardware::hidl_vec<::android::hardware::radio::V1_0::CellInfo>&
+ records);
+
+ Return<void> imsNetworkStateChanged(RadioIndicationType type);
+
+ Return<void> subscriptionStatusChanged(RadioIndicationType type, bool activate);
+
+ Return<void> srvccStateNotify(RadioIndicationType type, SrvccState state);
+
+ Return<void> hardwareConfigChanged(
+ RadioIndicationType type, const ::android::hardware::hidl_vec<HardwareConfig>& configs);
+
+ Return<void> radioCapabilityIndication(
+ RadioIndicationType type, const android::hardware::radio::V1_0::RadioCapability& rc);
+
+ Return<void> onSupplementaryServiceIndication(RadioIndicationType type,
+ const StkCcUnsolSsResult& ss);
+
+ Return<void> stkCallControlAlphaNotify(RadioIndicationType type,
+ const ::android::hardware::hidl_string& alpha);
+
+ Return<void> lceData(RadioIndicationType type, const LceDataInfo& lce);
+
+ Return<void> pcoData(RadioIndicationType type, const PcoDataInfo& pco);
+
+ Return<void> modemReset(RadioIndicationType type,
+ const ::android::hardware::hidl_string& reason);
+};
+
+// Test environment for Radio HIDL HAL.
+class RadioHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
+ public:
+ // get the test environment singleton
+ static RadioHidlEnvironment* Instance() {
+ static RadioHidlEnvironment* instance = new RadioHidlEnvironment;
+ return instance;
+ }
+ virtual void registerTestServices() override {
+ registerTestService<::android::hardware::radio::V1_5::IRadio>();
+ }
+
+ private:
+ RadioHidlEnvironment() {}
+};
+
+// The main test class for Radio HIDL.
+class RadioHidlTest_v1_5 : public ::testing::VtsHalHidlTargetTestBase {
+ protected:
+ std::mutex mtx_;
+ std::condition_variable cv_;
+ int count_;
+
+ /* Serial number for radio request */
+ int serial;
+
+ /* Clear Potential Established Calls */
+ void clearPotentialEstablishedCalls();
+
+ /* Update Sim Card Status */
+ void updateSimCardStatus();
+
+ public:
+ virtual void SetUp() override;
+
+ /* Used as a mechanism to inform the test about data/event callback */
+ void notify(int receivedSerial);
+
+ /* Test code calls this function to wait for response */
+ std::cv_status wait();
+
+ /* radio service handle */
+ sp<::android::hardware::radio::V1_5::IRadio> radio_v1_5;
+
+ /* radio response handle */
+ sp<RadioResponse_v1_5> radioRsp_v1_5;
+
+ /* radio indication handle */
+ sp<RadioIndication_v1_5> radioInd_v1_5;
+};
diff --git a/radio/1.5/vts/functional/radio_indication.cpp b/radio/1.5/vts/functional/radio_indication.cpp
new file mode 100644
index 0000000..b63b745
--- /dev/null
+++ b/radio/1.5/vts/functional/radio_indication.cpp
@@ -0,0 +1,330 @@
+/*
+ * 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.
+ */
+
+#include <radio_hidl_hal_utils_v1_5.h>
+
+RadioIndication_v1_5::RadioIndication_v1_5(RadioHidlTest_v1_5& parent) : parent_v1_5(parent) {}
+
+/* 1.4 Apis */
+Return<void> RadioIndication_v1_5::currentPhysicalChannelConfigs_1_4(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::hidl_vec<
+ ::android::hardware::radio::V1_4::PhysicalChannelConfig>& /*configs*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::networkScanResult_1_4(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::radio::V1_4::NetworkScanResult& /*result*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::cellInfoList_1_4(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::hidl_vec<
+ ::android::hardware::radio::V1_4::CellInfo>& /*records*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::currentEmergencyNumberList(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::hidl_vec<EmergencyNumber>& /*emergencyNumberList*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::dataCallListChanged_1_4(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::hidl_vec<android::hardware::radio::V1_4::SetupDataCallResult>&
+ /*dcList*/) {
+ return Void();
+}
+
+/* 1.2 Apis */
+Return<void> RadioIndication_v1_5::networkScanResult_1_2(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::radio::V1_2::NetworkScanResult& /*result*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::cellInfoList_1_2(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::hidl_vec<
+ ::android::hardware::radio::V1_2::CellInfo>& /*records*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::currentLinkCapacityEstimate(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::radio::V1_2::LinkCapacityEstimate& /*lce*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::currentPhysicalChannelConfigs(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::hidl_vec<
+ ::android::hardware::radio::V1_2::PhysicalChannelConfig>& /*configs*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::currentSignalStrength_1_2(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::radio::V1_2::SignalStrength& /*signalStrength*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::currentSignalStrength_1_4(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::radio::V1_4::SignalStrength& /*signalStrength*/) {
+ return Void();
+}
+
+/* 1.1 Apis */
+Return<void> RadioIndication_v1_5::carrierInfoForImsiEncryption(RadioIndicationType /*info*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::networkScanResult(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::radio::V1_1::NetworkScanResult& /*result*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::keepaliveStatus(RadioIndicationType /*type*/,
+ const KeepaliveStatus& /*status*/) {
+ return Void();
+}
+
+/* 1.0 Apis */
+Return<void> RadioIndication_v1_5::radioStateChanged(RadioIndicationType /*type*/,
+ RadioState /*radioState*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::callStateChanged(RadioIndicationType /*type*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::networkStateChanged(RadioIndicationType /*type*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::newSms(RadioIndicationType /*type*/,
+ const ::android::hardware::hidl_vec<uint8_t>& /*pdu*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::newSmsStatusReport(
+ RadioIndicationType /*type*/, const ::android::hardware::hidl_vec<uint8_t>& /*pdu*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::newSmsOnSim(RadioIndicationType /*type*/,
+ int32_t /*recordNumber*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::onUssd(RadioIndicationType /*type*/, UssdModeType /*modeType*/,
+ const ::android::hardware::hidl_string& /*msg*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::nitzTimeReceived(
+ RadioIndicationType /*type*/, const ::android::hardware::hidl_string& /*nitzTime*/,
+ uint64_t /*receivedTime*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::currentSignalStrength(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::radio::V1_0::SignalStrength& /*signalStrength*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::dataCallListChanged(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::hidl_vec<android::hardware::radio::V1_0::SetupDataCallResult>&
+ /*dcList*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::suppSvcNotify(RadioIndicationType /*type*/,
+ const SuppSvcNotification& /*suppSvc*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::stkSessionEnd(RadioIndicationType /*type*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::stkProactiveCommand(
+ RadioIndicationType /*type*/, const ::android::hardware::hidl_string& /*cmd*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::stkEventNotify(RadioIndicationType /*type*/,
+ const ::android::hardware::hidl_string& /*cmd*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::stkCallSetup(RadioIndicationType /*type*/, int64_t /*timeout*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::simSmsStorageFull(RadioIndicationType /*type*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::simRefresh(RadioIndicationType /*type*/,
+ const SimRefreshResult& /*refreshResult*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::callRing(RadioIndicationType /*type*/, bool /*isGsm*/,
+ const CdmaSignalInfoRecord& /*record*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::simStatusChanged(RadioIndicationType /*type*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::cdmaNewSms(RadioIndicationType /*type*/,
+ const CdmaSmsMessage& /*msg*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::newBroadcastSms(
+ RadioIndicationType /*type*/, const ::android::hardware::hidl_vec<uint8_t>& /*data*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::cdmaRuimSmsStorageFull(RadioIndicationType /*type*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::restrictedStateChanged(RadioIndicationType /*type*/,
+ PhoneRestrictedState /*state*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::enterEmergencyCallbackMode(RadioIndicationType /*type*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::cdmaCallWaiting(RadioIndicationType /*type*/,
+ const CdmaCallWaiting& /*callWaitingRecord*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::cdmaOtaProvisionStatus(RadioIndicationType /*type*/,
+ CdmaOtaProvisionStatus /*status*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::cdmaInfoRec(RadioIndicationType /*type*/,
+ const CdmaInformationRecords& /*records*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::indicateRingbackTone(RadioIndicationType /*type*/,
+ bool /*start*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::resendIncallMute(RadioIndicationType /*type*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::cdmaSubscriptionSourceChanged(
+ RadioIndicationType /*type*/, CdmaSubscriptionSource /*cdmaSource*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::cdmaPrlChanged(RadioIndicationType /*type*/,
+ int32_t /*version*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::exitEmergencyCallbackMode(RadioIndicationType /*type*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::rilConnected(RadioIndicationType /*type*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::voiceRadioTechChanged(
+ RadioIndicationType /*type*/, ::android::hardware::radio::V1_0::RadioTechnology /*rat*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::cellInfoList(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::hidl_vec<
+ ::android::hardware::radio::V1_0::CellInfo>& /*records*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::imsNetworkStateChanged(RadioIndicationType /*type*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::subscriptionStatusChanged(RadioIndicationType /*type*/,
+ bool /*activate*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::srvccStateNotify(RadioIndicationType /*type*/,
+ SrvccState /*state*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::hardwareConfigChanged(
+ RadioIndicationType /*type*/,
+ const ::android::hardware::hidl_vec<HardwareConfig>& /*configs*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::radioCapabilityIndication(
+ RadioIndicationType /*type*/,
+ const android::hardware::radio::V1_0::RadioCapability& /*rc*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::onSupplementaryServiceIndication(
+ RadioIndicationType /*type*/, const StkCcUnsolSsResult& /*ss*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::stkCallControlAlphaNotify(
+ RadioIndicationType /*type*/, const ::android::hardware::hidl_string& /*alpha*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::lceData(RadioIndicationType /*type*/,
+ const LceDataInfo& /*lce*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::pcoData(RadioIndicationType /*type*/,
+ const PcoDataInfo& /*pco*/) {
+ return Void();
+}
+
+Return<void> RadioIndication_v1_5::modemReset(RadioIndicationType /*type*/,
+ const ::android::hardware::hidl_string& /*reason*/) {
+ return Void();
+}
diff --git a/radio/1.5/vts/functional/radio_response.cpp b/radio/1.5/vts/functional/radio_response.cpp
new file mode 100644
index 0000000..1e5cc47
--- /dev/null
+++ b/radio/1.5/vts/functional/radio_response.cpp
@@ -0,0 +1,887 @@
+/*
+ * 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.
+ */
+
+#include <radio_hidl_hal_utils_v1_5.h>
+
+::android::hardware::radio::V1_4::CardStatus cardStatus;
+
+RadioResponse_v1_5::RadioResponse_v1_5(RadioHidlTest_v1_5& parent) : parent_v1_5(parent) {}
+
+/* 1.0 Apis */
+Return<void> RadioResponse_v1_5::getIccCardStatusResponse(
+ const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::CardStatus& /*card_status*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::supplyIccPinForAppResponse(const RadioResponseInfo& /*info*/,
+ int32_t /*remainingRetries*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::supplyIccPukForAppResponse(const RadioResponseInfo& /*info*/,
+ int32_t /*remainingRetries*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::supplyIccPin2ForAppResponse(const RadioResponseInfo& /*info*/,
+ int32_t /*remainingRetries*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::supplyIccPuk2ForAppResponse(const RadioResponseInfo& /*info*/,
+ int32_t /*remainingRetries*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::changeIccPinForAppResponse(const RadioResponseInfo& /*info*/,
+ int32_t /*remainingRetries*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::changeIccPin2ForAppResponse(const RadioResponseInfo& /*info*/,
+ int32_t /*remainingRetries*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::supplyNetworkDepersonalizationResponse(
+ const RadioResponseInfo& /*info*/, int32_t /*remainingRetries*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getCurrentCallsResponse(
+ const RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_vec<::android::hardware::radio::V1_0::Call>& /*calls*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::dialResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getIMSIForAppResponse(
+ const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*imsi*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::hangupConnectionResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::hangupWaitingOrBackgroundResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::hangupForegroundResumeBackgroundResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::switchWaitingOrHoldingAndActiveResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::conferenceResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::rejectCallResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getLastCallFailCauseResponse(
+ const RadioResponseInfo& /*info*/, const LastCallFailCauseInfo& /*failCauseInfo*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getSignalStrengthResponse(
+ const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::SignalStrength& /*sig_strength*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getVoiceRegistrationStateResponse(
+ const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::VoiceRegStateResult& /*voiceRegResponse*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getDataRegistrationStateResponse(
+ const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_0::DataRegStateResult& /*dataRegResponse*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getOperatorResponse(
+ const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*longName*/,
+ const ::android::hardware::hidl_string& /*shortName*/,
+ const ::android::hardware::hidl_string& /*numeric*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setRadioPowerResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::sendDtmfResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::sendSmsResponse(const RadioResponseInfo& /*info*/,
+ const SendSmsResult& /*sms*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::sendSMSExpectMoreResponse(const RadioResponseInfo& /*info*/,
+ const SendSmsResult& /*sms*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setupDataCallResponse(
+ const RadioResponseInfo& /*info*/,
+ const android::hardware::radio::V1_0::SetupDataCallResult& /*dcResponse*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::iccIOForAppResponse(const RadioResponseInfo& /*info*/,
+ const IccIoResult& /*iccIo*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::sendUssdResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::cancelPendingUssdResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getClirResponse(const RadioResponseInfo& /*info*/, int32_t /*n*/,
+ int32_t /*m*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setClirResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getCallForwardStatusResponse(
+ const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec<CallForwardInfo>&
+ /*callForwardInfos*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setCallForwardResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getCallWaitingResponse(const RadioResponseInfo& /*info*/,
+ bool /*enable*/, int32_t /*serviceClass*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setCallWaitingResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::acknowledgeLastIncomingGsmSmsResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::acceptCallResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::deactivateDataCallResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getFacilityLockForAppResponse(const RadioResponseInfo& /*info*/,
+ int32_t /*response*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setFacilityLockForAppResponse(const RadioResponseInfo& /*info*/,
+ int32_t /*retry*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setBarringPasswordResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getNetworkSelectionModeResponse(const RadioResponseInfo& /*info*/,
+ bool /*manual*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setNetworkSelectionModeAutomaticResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setNetworkSelectionModeManualResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getAvailableNetworksResponse(
+ const RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_vec<OperatorInfo>& /*networkInfos*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::startDtmfResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::stopDtmfResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getBasebandVersionResponse(
+ const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*version*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::separateConnectionResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setMuteResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getMuteResponse(const RadioResponseInfo& /*info*/,
+ bool /*enable*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getClipResponse(const RadioResponseInfo& /*info*/,
+ ClipStatus /*status*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getDataCallListResponse(
+ const RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_vec<android::hardware::radio::V1_0::SetupDataCallResult>&
+ /*dcResponse*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::sendOemRilRequestRawResponse(
+ const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_vec<uint8_t>& /*data*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::sendOemRilRequestStringsResponse(
+ const RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& /*data*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setSuppServiceNotificationsResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::writeSmsToSimResponse(const RadioResponseInfo& /*info*/,
+ int32_t /*index*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::deleteSmsOnSimResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setBandModeResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getAvailableBandModesResponse(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<RadioBandMode>& bandModes) {
+ rspInfo = info;
+ radioBandModes = bandModes;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::sendEnvelopeResponse(
+ const RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_string& /*commandResponse*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::sendTerminalResponseToSimResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::handleStkCallSetupRequestFromSimResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::explicitCallTransferResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setPreferredNetworkTypeResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getPreferredNetworkTypeResponse(const RadioResponseInfo& /*info*/,
+ PreferredNetworkType /*nw_type*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getNeighboringCidsResponse(
+ const RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_vec<NeighboringCell>& /*cells*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setLocationUpdatesResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setCdmaSubscriptionSourceResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setCdmaRoamingPreferenceResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getCdmaRoamingPreferenceResponse(const RadioResponseInfo& /*info*/,
+ CdmaRoamingType /*type*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setTTYModeResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getTTYModeResponse(const RadioResponseInfo& /*info*/,
+ TtyMode /*mode*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setPreferredVoicePrivacyResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getPreferredVoicePrivacyResponse(const RadioResponseInfo& /*info*/,
+ bool /*enable*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::sendCDMAFeatureCodeResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::sendBurstDtmfResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::sendCdmaSmsResponse(const RadioResponseInfo& /*info*/,
+ const SendSmsResult& /*sms*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::acknowledgeLastIncomingCdmaSmsResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getGsmBroadcastConfigResponse(
+ const RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_vec<GsmBroadcastSmsConfigInfo>& /*configs*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setGsmBroadcastConfigResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setGsmBroadcastActivationResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getCdmaBroadcastConfigResponse(
+ const RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_vec<CdmaBroadcastSmsConfigInfo>& /*configs*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setCdmaBroadcastConfigResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setCdmaBroadcastActivationResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getCDMASubscriptionResponse(
+ const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*mdn*/,
+ const ::android::hardware::hidl_string& /*hSid*/,
+ const ::android::hardware::hidl_string& /*hNid*/,
+ const ::android::hardware::hidl_string& /*min*/,
+ const ::android::hardware::hidl_string& /*prl*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::writeSmsToRuimResponse(const RadioResponseInfo& /*info*/,
+ uint32_t /*index*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::deleteSmsOnRuimResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getDeviceIdentityResponse(
+ const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*imei*/,
+ const ::android::hardware::hidl_string& /*imeisv*/,
+ const ::android::hardware::hidl_string& /*esn*/,
+ const ::android::hardware::hidl_string& /*meid*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::exitEmergencyCallbackModeResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getSmscAddressResponse(
+ const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*smsc*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setSmscAddressResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::reportSmsMemoryStatusResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::reportStkServiceIsRunningResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getCdmaSubscriptionSourceResponse(
+ const RadioResponseInfo& /*info*/, CdmaSubscriptionSource /*source*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::requestIsimAuthenticationResponse(
+ const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*response*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::acknowledgeIncomingGsmSmsWithPduResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::sendEnvelopeWithStatusResponse(const RadioResponseInfo& /*info*/,
+ const IccIoResult& /*iccIo*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getVoiceRadioTechnologyResponse(
+ const RadioResponseInfo& /*info*/,
+ ::android::hardware::radio::V1_0::RadioTechnology /*rat*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getCellInfoListResponse(
+ const RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_vec<
+ ::android::hardware::radio::V1_0::CellInfo>& /*cellInfo*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setCellInfoListRateResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setInitialAttachApnResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getImsRegistrationStateResponse(
+ const RadioResponseInfo& /*info*/, bool /*isRegistered*/,
+ RadioTechnologyFamily /*ratFamily*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::sendImsSmsResponse(const RadioResponseInfo& /*info*/,
+ const SendSmsResult& /*sms*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::iccTransmitApduBasicChannelResponse(
+ const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::iccOpenLogicalChannelResponse(
+ const RadioResponseInfo& /*info*/, int32_t /*channelId*/,
+ const ::android::hardware::hidl_vec<int8_t>& /*selectResponse*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::iccCloseLogicalChannelResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::iccTransmitApduLogicalChannelResponse(
+ const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::nvReadItemResponse(
+ const RadioResponseInfo& /*info*/, const ::android::hardware::hidl_string& /*result*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::nvWriteItemResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::nvWriteCdmaPrlResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::nvResetConfigResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setUiccSubscriptionResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setDataAllowedResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getHardwareConfigResponse(
+ const RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_vec<HardwareConfig>& /*config*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::requestIccSimAuthenticationResponse(
+ const RadioResponseInfo& /*info*/, const IccIoResult& /*result*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setDataProfileResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::requestShutdownResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getRadioCapabilityResponse(
+ const RadioResponseInfo& /*info*/,
+ const android::hardware::radio::V1_0::RadioCapability& /*rc*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setRadioCapabilityResponse(
+ const RadioResponseInfo& /*info*/,
+ const android::hardware::radio::V1_0::RadioCapability& /*rc*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::startLceServiceResponse(const RadioResponseInfo& /*info*/,
+ const LceStatusInfo& /*statusInfo*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::stopLceServiceResponse(const RadioResponseInfo& /*info*/,
+ const LceStatusInfo& /*statusInfo*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::pullLceDataResponse(const RadioResponseInfo& /*info*/,
+ const LceDataInfo& /*lceInfo*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getModemActivityInfoResponse(
+ const RadioResponseInfo& /*info*/, const ActivityStatsInfo& /*activityInfo*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setAllowedCarriersResponse(const RadioResponseInfo& /*info*/,
+ int32_t /*numAllowed*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getAllowedCarriersResponse(
+ const RadioResponseInfo& /*info*/, bool /*allAllowed*/,
+ const CarrierRestrictions& /*carriers*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::sendDeviceStateResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setIndicationFilterResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setSimCardPowerResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::acknowledgeRequest(int32_t /*serial*/) {
+ return Void();
+}
+
+/* 1.1 Apis */
+Return<void> RadioResponse_v1_5::setCarrierInfoForImsiEncryptionResponse(
+ const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setSimCardPowerResponse_1_1(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::startNetworkScanResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::stopNetworkScanResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::startKeepaliveResponse(const RadioResponseInfo& /*info*/,
+ const KeepaliveStatus& /*status*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::stopKeepaliveResponse(const RadioResponseInfo& /*info*/) {
+ return Void();
+}
+
+/* 1.2 Apis */
+Return<void> RadioResponse_v1_5::setSignalStrengthReportingCriteriaResponse(
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setLinkCapacityReportingCriteriaResponse(
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getIccCardStatusResponse_1_2(
+ const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_2::CardStatus& /*card_status*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getCurrentCallsResponse_1_2(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<::android::hardware::radio::V1_2::Call>& calls) {
+ rspInfo = info;
+ currentCalls = calls;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getSignalStrengthResponse_1_2(
+ const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_2::SignalStrength& /*sig_strength*/) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getSignalStrengthResponse_1_4(
+ const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_4::SignalStrength& /*sig_strength*/) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getCellInfoListResponse_1_2(
+ const RadioResponseInfo& /*info*/,
+ const ::android::hardware::hidl_vec<
+ ::android::hardware::radio::V1_2::CellInfo>& /*cellInfo*/) {
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getVoiceRegistrationStateResponse_1_2(
+ const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_2::VoiceRegStateResult& /*voiceRegResponse*/) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getDataRegistrationStateResponse_1_2(
+ const RadioResponseInfo& /*info*/,
+ const ::android::hardware::radio::V1_2::DataRegStateResult& /*dataRegResponse*/) {
+ return Void();
+}
+
+/* 1.3 Apis */
+Return<void> RadioResponse_v1_5::setSystemSelectionChannelsResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::enableModemResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getModemStackStatusResponse(const RadioResponseInfo& info,
+ const bool enabled) {
+ rspInfo = info;
+ isModemEnabled = enabled;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+/* 1.4 Apis */
+Return<void> RadioResponse_v1_5::emergencyDialResponse(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::startNetworkScanResponse_1_4(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getDataRegistrationStateResponse_1_4(
+ const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_4::DataRegStateResult& dataRegResponse) {
+ rspInfo = info;
+ dataRegResp = dataRegResponse;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getCellInfoListResponse_1_4(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<
+ ::android::hardware::radio::V1_4::CellInfo>& /*cellInfo*/) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getIccCardStatusResponse_1_4(
+ const RadioResponseInfo& info,
+ const ::android::hardware::radio::V1_4::CardStatus& card_status) {
+ rspInfo = info;
+ cardStatus = card_status;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getPreferredNetworkTypeBitmapResponse(
+ const RadioResponseInfo& info, const ::android::hardware::hidl_bitfield<
+ ::android::hardware::radio::V1_4::RadioAccessFamily>
+ networkTypeBitmap) {
+ rspInfo = info;
+ networkTypeBitmapResponse = networkTypeBitmap;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setPreferredNetworkTypeBitmapResponse(
+ const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getDataCallListResponse_1_4(
+ const RadioResponseInfo& info,
+ const ::android::hardware::hidl_vec<::android::hardware::radio::V1_4::SetupDataCallResult>&
+ /*dcResponse*/) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setupDataCallResponse_1_4(
+ const RadioResponseInfo& info,
+ const android::hardware::radio::V1_4::SetupDataCallResult& /*dcResponse*/) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::setAllowedCarriersResponse_1_4(const RadioResponseInfo& info) {
+ rspInfo = info;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
+
+Return<void> RadioResponse_v1_5::getAllowedCarriersResponse_1_4(
+ const RadioResponseInfo& info, const CarrierRestrictionsWithPriority& carriers,
+ SimLockMultiSimPolicy multiSimPolicy) {
+ rspInfo = info;
+ carrierRestrictionsResp = carriers;
+ multiSimPolicyResp = multiSimPolicy;
+ parent_v1_5.notify(info.serial);
+ return Void();
+}
diff --git a/sensors/2.0/multihal/HalProxy.cpp b/sensors/2.0/multihal/HalProxy.cpp
index b78806a..49c5a0d 100644
--- a/sensors/2.0/multihal/HalProxy.cpp
+++ b/sensors/2.0/multihal/HalProxy.cpp
@@ -330,7 +330,7 @@
Return<void> HalProxy::onDynamicSensorsDisconnected(
const hidl_vec<int32_t>& dynamicSensorHandlesRemoved, int32_t subHalIndex) {
- // TODO: Block this call until all pending events are flushed from queue
+ // TODO(b/143302327): Block this call until all pending events are flushed from queue
std::vector<int32_t> sensorHandles;
{
std::lock_guard<std::mutex> lock(mDynamicSensorsMutex);
@@ -457,7 +457,8 @@
}
void HalProxy::handlePendingWrites() {
- // TODO: Find a way to optimize locking strategy maybe using two mutexes instead of one.
+ // TODO(b/143302327): Find a way to optimize locking strategy maybe using two mutexes instead of
+ // one.
std::unique_lock<std::mutex> lock(mEventQueueWriteMutex);
while (mThreadsRun.load()) {
mEventQueueWriteCV.wait(
@@ -485,8 +486,8 @@
}
lock.lock();
if (pendingWriteEvents.size() > eventQueueSize) {
- // TODO: Check if this erase operation is too inefficient. It will copy all the
- // events ahead of it down to fill gap off array at front after the erase.
+ // TODO(b/143302327): Check if this erase operation is too inefficient. It will copy
+ // all the events ahead of it down to fill gap off array at front after the erase.
pendingWriteEvents.erase(pendingWriteEvents.begin(),
pendingWriteEvents.begin() + eventQueueSize);
} else {
@@ -554,8 +555,8 @@
numToWrite = std::min(events.size(), mEventQueue->availableToWrite());
if (numToWrite > 0) {
if (mEventQueue->write(events.data(), numToWrite)) {
- // TODO: While loop if mEventQueue->avaiableToWrite > 0 to possibly fit in more
- // writes immediately
+ // TODO(b/143302327): While loop if mEventQueue->avaiableToWrite > 0 to possibly fit
+ // in more writes immediately
mEventQueueFlag->wake(static_cast<uint32_t>(EventQueueFlagBits::READ_AND_PROCESS));
} else {
numToWrite = 0;
@@ -563,8 +564,8 @@
}
}
if (numToWrite < events.size()) {
- // TODO: Bound the mPendingWriteEventsQueue so that we do not trigger OOMs if framework
- // stalls
+ // TODO(b/143302327): Bound the mPendingWriteEventsQueue so that we do not trigger OOMs if
+ // framework stalls
std::vector<Event> eventsLeft(events.begin() + numToWrite, events.end());
mPendingWriteEventsQueue.push({eventsLeft, numWakeupEvents});
mEventQueueWriteCV.notify_one();
@@ -655,7 +656,7 @@
" w/ index %zu.",
mSubHalIndex);
}
- mHalProxy->postEventsToMessageQueue(events, numWakeupEvents, std::move(wakelock));
+ mHalProxy->postEventsToMessageQueue(processedEvents, numWakeupEvents, std::move(wakelock));
}
ScopedWakelock HalProxyCallback::createScopedWakelock(bool lock) {
diff --git a/sensors/2.0/multihal/tests/Android.bp b/sensors/2.0/multihal/tests/Android.bp
index 50a55f9..e7f9499 100644
--- a/sensors/2.0/multihal/tests/Android.bp
+++ b/sensors/2.0/multihal/tests/Android.bp
@@ -27,6 +27,7 @@
"android.hardware.sensors@2.0",
"libcutils",
"libfmq",
+ "libhardware",
"libhidlbase",
"liblog",
"libpower",
@@ -85,6 +86,7 @@
"libbase",
"libcutils",
"libfmq",
+ "libhardware",
"libhidlbase",
"liblog",
"libpower",
diff --git a/sensors/2.0/multihal/tests/HalProxy_test.cpp b/sensors/2.0/multihal/tests/HalProxy_test.cpp
index 75a4c22..1fd35d1 100644
--- a/sensors/2.0/multihal/tests/HalProxy_test.cpp
+++ b/sensors/2.0/multihal/tests/HalProxy_test.cpp
@@ -692,6 +692,38 @@
EXPECT_EQ(proxy.injectSensorData(event), Result::BAD_VALUE);
}
+TEST(HalProxyTest, PostedEventSensorHandleSubHalIndexValid) {
+ constexpr size_t kQueueSize = 5;
+ constexpr int32_t subhal1Index = 0;
+ constexpr int32_t subhal2Index = 1;
+ AllSensorsSubHal subhal1;
+ AllSensorsSubHal subhal2;
+ std::vector<ISensorsSubHal*> subHals{&subhal1, &subhal2};
+
+ std::unique_ptr<EventMessageQueue> eventQueue = makeEventFMQ(kQueueSize);
+ std::unique_ptr<WakeupMessageQueue> wakeLockQueue = makeWakelockFMQ(kQueueSize);
+ ::android::sp<ISensorsCallback> callback = new SensorsCallback();
+ HalProxy proxy(subHals);
+ proxy.initialize(*eventQueue->getDesc(), *wakeLockQueue->getDesc(), callback);
+
+ int32_t sensorHandleToPost = 0x00000001;
+ Event eventIn = makeAccelerometerEvent();
+ eventIn.sensorHandle = sensorHandleToPost;
+ std::vector<Event> eventsToPost{eventIn};
+ subhal1.postEvents(eventsToPost, false);
+
+ Event eventOut;
+ EXPECT_TRUE(eventQueue->read(&eventOut));
+
+ EXPECT_EQ(eventOut.sensorHandle, (subhal1Index << 24) | sensorHandleToPost);
+
+ subhal2.postEvents(eventsToPost, false);
+
+ EXPECT_TRUE(eventQueue->read(&eventOut));
+
+ EXPECT_EQ(eventOut.sensorHandle, (subhal2Index << 24) | sensorHandleToPost);
+}
+
// Helper implementations follow
void testSensorsListFromProxyAndSubHal(const std::vector<SensorInfo>& proxySensorsList,
const std::vector<SensorInfo>& subHalSensorsList) {
diff --git a/sensors/2.0/multihal/tests/fake_subhal/Sensor.cpp b/sensors/2.0/multihal/tests/fake_subhal/Sensor.cpp
index 4d53665..de89a00 100644
--- a/sensors/2.0/multihal/tests/fake_subhal/Sensor.cpp
+++ b/sensors/2.0/multihal/tests/fake_subhal/Sensor.cpp
@@ -16,6 +16,7 @@
#include "Sensor.h"
+#include <hardware/sensors.h>
#include <utils/SystemClock.h>
#include <cmath>
@@ -31,14 +32,21 @@
using ::android::hardware::sensors::V1_0::SensorFlagBits;
using ::android::hardware::sensors::V1_0::SensorStatus;
-static constexpr float kDefaultMaxDelayUs = 10 * 1000 * 1000;
-
-Sensor::Sensor(ISensorsEventCallback* callback)
+Sensor::Sensor(int32_t sensorHandle, ISensorsEventCallback* callback)
: mIsEnabled(false),
mSamplingPeriodNs(0),
mLastSampleTimeNs(0),
mCallback(callback),
mMode(OperationMode::NORMAL) {
+ mSensorInfo.sensorHandle = sensorHandle;
+ mSensorInfo.vendor = "Vendor String";
+ mSensorInfo.version = 1;
+ constexpr float kDefaultMaxDelayUs = 1000 * 1000;
+ mSensorInfo.maxDelay = kDefaultMaxDelayUs;
+ mSensorInfo.fifoReservedEventCount = 0;
+ mSensorInfo.fifoMaxEventCount = 0;
+ mSensorInfo.requiredPermission = "";
+ mSensorInfo.flags = 0;
mRunThread = std::thread(startThread, this);
}
@@ -171,8 +179,10 @@
return result;
}
-OnChangeSensor::OnChangeSensor(ISensorsEventCallback* callback)
- : Sensor(callback), mPreviousEventSet(false) {}
+OnChangeSensor::OnChangeSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
+ : Sensor(sensorHandle, callback), mPreviousEventSet(false) {
+ mSensorInfo.flags |= SensorFlagBits::ON_CHANGE_MODE;
+}
void OnChangeSensor::activate(bool enable) {
Sensor::activate(enable);
@@ -196,175 +206,139 @@
return outputEvents;
}
-AccelSensor::AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback) : Sensor(callback) {
- mSensorInfo.sensorHandle = sensorHandle;
+ContinuousSensor::ContinuousSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
+ : Sensor(sensorHandle, callback) {
+ mSensorInfo.flags |= SensorFlagBits::CONTINUOUS_MODE;
+}
+
+AccelSensor::AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
+ : ContinuousSensor(sensorHandle, callback) {
mSensorInfo.name = "Accel Sensor";
- mSensorInfo.vendor = "Vendor String";
- mSensorInfo.version = 1;
mSensorInfo.type = SensorType::ACCELEROMETER;
- mSensorInfo.typeAsString = "";
+ mSensorInfo.typeAsString = SENSOR_STRING_TYPE_ACCELEROMETER;
mSensorInfo.maxRange = 78.4f; // +/- 8g
mSensorInfo.resolution = 1.52e-5;
mSensorInfo.power = 0.001f; // mA
mSensorInfo.minDelay = 20 * 1000; // microseconds
- mSensorInfo.maxDelay = kDefaultMaxDelayUs;
- mSensorInfo.fifoReservedEventCount = 0;
- mSensorInfo.fifoMaxEventCount = 0;
- mSensorInfo.requiredPermission = "";
- mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::DATA_INJECTION);
-};
+ mSensorInfo.flags |= SensorFlagBits::DATA_INJECTION;
+}
+
+std::vector<Event> AccelSensor::readEvents() {
+ std::vector<Event> events;
+ Event event;
+ event.sensorHandle = mSensorInfo.sensorHandle;
+ event.sensorType = mSensorInfo.type;
+ event.timestamp = ::android::elapsedRealtimeNano();
+ event.u.vec3.x = 0;
+ event.u.vec3.y = 0;
+ event.u.vec3.z = -9.815;
+ event.u.vec3.status = SensorStatus::ACCURACY_HIGH;
+ events.push_back(event);
+ return events;
+}
PressureSensor::PressureSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
- : Sensor(callback) {
- mSensorInfo.sensorHandle = sensorHandle;
+ : ContinuousSensor(sensorHandle, callback) {
mSensorInfo.name = "Pressure Sensor";
- mSensorInfo.vendor = "Vendor String";
- mSensorInfo.version = 1;
mSensorInfo.type = SensorType::PRESSURE;
- mSensorInfo.typeAsString = "";
+ mSensorInfo.typeAsString = SENSOR_STRING_TYPE_PRESSURE;
mSensorInfo.maxRange = 1100.0f; // hPa
mSensorInfo.resolution = 0.005f; // hPa
mSensorInfo.power = 0.001f; // mA
mSensorInfo.minDelay = 100 * 1000; // microseconds
- mSensorInfo.maxDelay = kDefaultMaxDelayUs;
- mSensorInfo.fifoReservedEventCount = 0;
- mSensorInfo.fifoMaxEventCount = 0;
- mSensorInfo.requiredPermission = "";
- mSensorInfo.flags = 0;
-};
+}
MagnetometerSensor::MagnetometerSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
- : Sensor(callback) {
- mSensorInfo.sensorHandle = sensorHandle;
+ : ContinuousSensor(sensorHandle, callback) {
mSensorInfo.name = "Magnetic Field Sensor";
- mSensorInfo.vendor = "Vendor String";
- mSensorInfo.version = 1;
mSensorInfo.type = SensorType::MAGNETIC_FIELD;
- mSensorInfo.typeAsString = "";
+ mSensorInfo.typeAsString = SENSOR_STRING_TYPE_MAGNETIC_FIELD;
mSensorInfo.maxRange = 1300.0f;
mSensorInfo.resolution = 0.01f;
mSensorInfo.power = 0.001f; // mA
mSensorInfo.minDelay = 20 * 1000; // microseconds
- mSensorInfo.maxDelay = kDefaultMaxDelayUs;
- mSensorInfo.fifoReservedEventCount = 0;
- mSensorInfo.fifoMaxEventCount = 0;
- mSensorInfo.requiredPermission = "";
- mSensorInfo.flags = 0;
-};
+}
LightSensor::LightSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
- : OnChangeSensor(callback) {
- mSensorInfo.sensorHandle = sensorHandle;
+ : OnChangeSensor(sensorHandle, callback) {
mSensorInfo.name = "Light Sensor";
- mSensorInfo.vendor = "Vendor String";
- mSensorInfo.version = 1;
mSensorInfo.type = SensorType::LIGHT;
- mSensorInfo.typeAsString = "";
+ mSensorInfo.typeAsString = SENSOR_STRING_TYPE_LIGHT;
mSensorInfo.maxRange = 43000.0f;
mSensorInfo.resolution = 10.0f;
mSensorInfo.power = 0.001f; // mA
mSensorInfo.minDelay = 200 * 1000; // microseconds
- mSensorInfo.maxDelay = kDefaultMaxDelayUs;
- mSensorInfo.fifoReservedEventCount = 0;
- mSensorInfo.fifoMaxEventCount = 0;
- mSensorInfo.requiredPermission = "";
- mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE);
-};
+}
ProximitySensor::ProximitySensor(int32_t sensorHandle, ISensorsEventCallback* callback)
- : OnChangeSensor(callback) {
- mSensorInfo.sensorHandle = sensorHandle;
+ : OnChangeSensor(sensorHandle, callback) {
mSensorInfo.name = "Proximity Sensor";
- mSensorInfo.vendor = "Vendor String";
- mSensorInfo.version = 1;
mSensorInfo.type = SensorType::PROXIMITY;
- mSensorInfo.typeAsString = "";
+ mSensorInfo.typeAsString = SENSOR_STRING_TYPE_PROXIMITY;
mSensorInfo.maxRange = 5.0f;
mSensorInfo.resolution = 1.0f;
mSensorInfo.power = 0.012f; // mA
mSensorInfo.minDelay = 200 * 1000; // microseconds
- mSensorInfo.maxDelay = kDefaultMaxDelayUs;
- mSensorInfo.fifoReservedEventCount = 0;
- mSensorInfo.fifoMaxEventCount = 0;
- mSensorInfo.requiredPermission = "";
- mSensorInfo.flags =
- static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE | SensorFlagBits::WAKE_UP);
-};
+ mSensorInfo.flags |= SensorFlagBits::WAKE_UP;
+}
-GyroSensor::GyroSensor(int32_t sensorHandle, ISensorsEventCallback* callback) : Sensor(callback) {
- mSensorInfo.sensorHandle = sensorHandle;
+GyroSensor::GyroSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
+ : ContinuousSensor(sensorHandle, callback) {
mSensorInfo.name = "Gyro Sensor";
- mSensorInfo.vendor = "Vendor String";
- mSensorInfo.version = 1;
mSensorInfo.type = SensorType::GYROSCOPE;
- mSensorInfo.typeAsString = "";
+ mSensorInfo.typeAsString = SENSOR_STRING_TYPE_GYROSCOPE;
mSensorInfo.maxRange = 1000.0f * M_PI / 180.0f;
mSensorInfo.resolution = 1000.0f * M_PI / (180.0f * 32768.0f);
mSensorInfo.power = 0.001f;
mSensorInfo.minDelay = 2.5f * 1000; // microseconds
- mSensorInfo.maxDelay = kDefaultMaxDelayUs;
- mSensorInfo.fifoReservedEventCount = 0;
- mSensorInfo.fifoMaxEventCount = 0;
- mSensorInfo.requiredPermission = "";
- mSensorInfo.flags = 0;
-};
+}
+
+std::vector<Event> GyroSensor::readEvents() {
+ std::vector<Event> events;
+ Event event;
+ event.sensorHandle = mSensorInfo.sensorHandle;
+ event.sensorType = mSensorInfo.type;
+ event.timestamp = ::android::elapsedRealtimeNano();
+ event.u.vec3.x = 0;
+ event.u.vec3.y = 0;
+ event.u.vec3.z = 0;
+ event.u.vec3.status = SensorStatus::ACCURACY_HIGH;
+ events.push_back(event);
+ return events;
+}
AmbientTempSensor::AmbientTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
- : OnChangeSensor(callback) {
- mSensorInfo.sensorHandle = sensorHandle;
+ : OnChangeSensor(sensorHandle, callback) {
mSensorInfo.name = "Ambient Temp Sensor";
- mSensorInfo.vendor = "Vendor String";
- mSensorInfo.version = 1;
mSensorInfo.type = SensorType::AMBIENT_TEMPERATURE;
- mSensorInfo.typeAsString = "";
+ mSensorInfo.typeAsString = SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE;
mSensorInfo.maxRange = 80.0f;
mSensorInfo.resolution = 0.01f;
mSensorInfo.power = 0.001f;
mSensorInfo.minDelay = 40 * 1000; // microseconds
- mSensorInfo.maxDelay = kDefaultMaxDelayUs;
- mSensorInfo.fifoReservedEventCount = 0;
- mSensorInfo.fifoMaxEventCount = 0;
- mSensorInfo.requiredPermission = "";
- mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE);
-};
+}
DeviceTempSensor::DeviceTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback)
- : OnChangeSensor(callback) {
- mSensorInfo.sensorHandle = sensorHandle;
+ : ContinuousSensor(sensorHandle, callback) {
mSensorInfo.name = "Device Temp Sensor";
- mSensorInfo.vendor = "Vendor String";
- mSensorInfo.version = 1;
mSensorInfo.type = SensorType::TEMPERATURE;
- mSensorInfo.typeAsString = "";
+ mSensorInfo.typeAsString = SENSOR_STRING_TYPE_TEMPERATURE;
mSensorInfo.maxRange = 80.0f;
mSensorInfo.resolution = 0.01f;
mSensorInfo.power = 0.001f;
mSensorInfo.minDelay = 40 * 1000; // microseconds
- mSensorInfo.maxDelay = kDefaultMaxDelayUs;
- mSensorInfo.fifoReservedEventCount = 0;
- mSensorInfo.fifoMaxEventCount = 0;
- mSensorInfo.requiredPermission = "";
- mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE);
}
RelativeHumiditySensor::RelativeHumiditySensor(int32_t sensorHandle,
ISensorsEventCallback* callback)
- : OnChangeSensor(callback) {
- mSensorInfo.sensorHandle = sensorHandle;
+ : OnChangeSensor(sensorHandle, callback) {
mSensorInfo.name = "Relative Humidity Sensor";
- mSensorInfo.vendor = "Vendor String";
- mSensorInfo.version = 1;
mSensorInfo.type = SensorType::RELATIVE_HUMIDITY;
- mSensorInfo.typeAsString = "";
+ mSensorInfo.typeAsString = SENSOR_STRING_TYPE_RELATIVE_HUMIDITY;
mSensorInfo.maxRange = 100.0f;
mSensorInfo.resolution = 0.1f;
mSensorInfo.power = 0.001f;
mSensorInfo.minDelay = 40 * 1000; // microseconds
- mSensorInfo.maxDelay = kDefaultMaxDelayUs;
- mSensorInfo.fifoReservedEventCount = 0;
- mSensorInfo.fifoMaxEventCount = 0;
- mSensorInfo.requiredPermission = "";
- mSensorInfo.flags = static_cast<uint32_t>(SensorFlagBits::ON_CHANGE_MODE);
}
} // namespace implementation
diff --git a/sensors/2.0/multihal/tests/fake_subhal/Sensor.h b/sensors/2.0/multihal/tests/fake_subhal/Sensor.h
index 980ea54..60f5d3d 100644
--- a/sensors/2.0/multihal/tests/fake_subhal/Sensor.h
+++ b/sensors/2.0/multihal/tests/fake_subhal/Sensor.h
@@ -45,7 +45,7 @@
class Sensor {
public:
- Sensor(ISensorsEventCallback* callback);
+ Sensor(int32_t sensorHandle, ISensorsEventCallback* callback);
virtual ~Sensor();
const SensorInfo& getSensorInfo() const;
@@ -81,7 +81,7 @@
class OnChangeSensor : public Sensor {
public:
- OnChangeSensor(ISensorsEventCallback* callback);
+ OnChangeSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
virtual void activate(bool enable) override;
@@ -93,14 +93,40 @@
bool mPreviousEventSet;
};
-class AccelSensor : public Sensor {
+class ContinuousSensor : public Sensor {
public:
- AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
+ ContinuousSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
};
-class GyroSensor : public Sensor {
+class AccelSensor : public ContinuousSensor {
+ public:
+ AccelSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
+
+ protected:
+ std::vector<Event> readEvents() override;
+};
+
+class GyroSensor : public ContinuousSensor {
public:
GyroSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
+
+ protected:
+ std::vector<Event> readEvents() override;
+};
+
+class DeviceTempSensor : public ContinuousSensor {
+ public:
+ DeviceTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
+};
+
+class PressureSensor : public ContinuousSensor {
+ public:
+ PressureSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
+};
+
+class MagnetometerSensor : public ContinuousSensor {
+ public:
+ MagnetometerSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
};
class AmbientTempSensor : public OnChangeSensor {
@@ -108,21 +134,6 @@
AmbientTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
};
-class DeviceTempSensor : public OnChangeSensor {
- public:
- DeviceTempSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
-};
-
-class PressureSensor : public Sensor {
- public:
- PressureSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
-};
-
-class MagnetometerSensor : public Sensor {
- public:
- MagnetometerSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
-};
-
class LightSensor : public OnChangeSensor {
public:
LightSensor(int32_t sensorHandle, ISensorsEventCallback* callback);
diff --git a/sensors/2.0/multihal/tests/fake_subhal/SensorsSubHal.cpp b/sensors/2.0/multihal/tests/fake_subhal/SensorsSubHal.cpp
index 0da4246..ff5ff38 100644
--- a/sensors/2.0/multihal/tests/fake_subhal/SensorsSubHal.cpp
+++ b/sensors/2.0/multihal/tests/fake_subhal/SensorsSubHal.cpp
@@ -172,11 +172,11 @@
AddSensor<GyroSensor>();
AddSensor<MagnetometerSensor>();
AddSensor<PressureSensor>();
+ AddSensor<DeviceTempSensor>();
}
OnChangeSensorsSubHal::OnChangeSensorsSubHal() {
AddSensor<AmbientTempSensor>();
- AddSensor<DeviceTempSensor>();
AddSensor<LightSensor>();
AddSensor<ProximitySensor>();
AddSensor<RelativeHumiditySensor>();
@@ -187,8 +187,8 @@
AddSensor<GyroSensor>();
AddSensor<MagnetometerSensor>();
AddSensor<PressureSensor>();
- AddSensor<AmbientTempSensor>();
AddSensor<DeviceTempSensor>();
+ AddSensor<AmbientTempSensor>();
AddSensor<LightSensor>();
AddSensor<ProximitySensor>();
AddSensor<RelativeHumiditySensor>();
diff --git a/tv/tuner/1.0/Android.bp b/tv/tuner/1.0/Android.bp
index 09265f7..d78f3f2 100644
--- a/tv/tuner/1.0/Android.bp
+++ b/tv/tuner/1.0/Android.bp
@@ -9,15 +9,21 @@
srcs: [
"types.hal",
"IDemux.hal",
- "IDemuxCallback.hal",
"IDescrambler.hal",
+ "IDvr.hal",
+ "IDvrCallback.hal",
+ "IFilter.hal",
+ "IFilterCallback.hal",
"IFrontend.hal",
"IFrontendCallback.hal",
"ILnb.hal",
+ "ILnbCallback.hal",
+ "ITimeFilter.hal",
"ITuner.hal",
],
interfaces: [
"android.hidl.base@1.0",
+ "android.hidl.safe_union@1.0",
],
gen_java: false,
gen_java_constants: true,
diff --git a/tv/tuner/1.0/IDemux.hal b/tv/tuner/1.0/IDemux.hal
index 7fd7e26..9e799b4 100644
--- a/tv/tuner/1.0/IDemux.hal
+++ b/tv/tuner/1.0/IDemux.hal
@@ -16,7 +16,11 @@
package android.hardware.tv.tuner@1.0;
-import IDemuxCallback;
+import IDvr;
+import IDvrCallback;
+import IFilter;
+import IFilterCallback;
+import ITimeFilter;
/**
* Demultiplexer(Demux) takes a single multiplexed input and splits it into
@@ -24,7 +28,6 @@
*
*/
interface IDemux {
-
/**
* Set a frontend resource as data input of the demux
*
@@ -39,134 +42,51 @@
setFrontendDataSource(FrontendId frontendId) generates (Result result);
/**
- * Add a filter to the demux
+ * Open a new filter in the demux
*
- * It is used by the client to add a filter to the demux.
+ * It is used by the client to open a filter in the demux.
*
* @param type the type of the filter to be added.
- * @param bufferSize the buffer size of the filter to be added. It's used to
- * create a FMQ(Fast Message Queue) to hold data output from the filter.
+ * @param bufferSize the buffer size of the filter to be opened. It's used
+ * to create a FMQ(Fast Message Queue) to hold data output from the filter.
* @param cb the callback for the filter to be used to send notifications
* back to the client.
* @return result Result status of the operation.
* SUCCESS if successful,
* INVALID_STATE if failed for wrong state.
* UNKNOWN_ERROR if failed for other reasons.
- * @return filterId the ID of the newly added filter.
+ * @return filter the filter instance of the newly added.
*/
- addFilter(DemuxFilterType type, uint32_t bufferSize, IDemuxCallback cb)
- generates (Result result, DemuxFilterId filterId);
+ openFilter(DemuxFilterType type, uint32_t bufferSize, IFilterCallback cb)
+ generates (Result result, IFilter filter);
/**
- * Get the descriptor of the filter's FMQ
+ * Open time filter of the demux
*
- * It is used by the client to get the descriptor of the filter's Fast
- * Message Queue. The data in FMQ is filtered out from MPEG transport
- * stream. The data is organized to data blocks which may have
- * different length. The length's information of one or multiple data blocks
- * is sent to client through DemuxFilterEvent.
+ * It is used by the client to open time filter of the demux.
*
- * @param filterId the ID of the filter.
* @return result Result status of the operation.
* SUCCESS if successful,
- * INVALID_ARGUMENT if failed for wrong filter ID.
+ * UNAVAILABLE if time filter is not supported.
* INVALID_STATE if failed for wrong state.
* UNKNOWN_ERROR if failed for other reasons.
- * @return queue the descriptor of the filter's FMQ
+ * @return timeFilter the time filter instance of the newly added.
*/
- getFilterQueueDesc(DemuxFilterId filterId)
- generates (Result result, fmq_sync<uint8_t> queue);
-
- /**
- * Configure the filter.
- *
- * It is used by the client to configure the filter so that it can filter out
- * intended data.
- *
- * @param filterId the ID of the filter.
- * @param settings the settings of the filter.
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * INVALID_ARGUMENT if failed for wrong filter ID.
- * INVALID_STATE if failed for wrong state.
- * UNKNOWN_ERROR if failed for other reasons.
- */
- configureFilter(DemuxFilterId filterId, DemuxFilterSettings settings)
- generates(Result result);
-
- /**
- * Start the filter.
- *
- * It is used by the client to ask the filter to start filtering data.
- *
- * @param filterId the ID of the filter.
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * INVALID_ARGUMENT if failed for wrong filter ID.
- * INVALID_STATE if failed for wrong state.
- * UNKNOWN_ERROR if failed for other reasons.
- */
- startFilter(DemuxFilterId filterId) generates (Result result);
-
- /**
- * Stop the filter.
- *
- * It is used by the client to ask the filter to stop filterring data.
- * It won't discard the data already filtered out by the filter. The filter
- * will be stopped and removed automatically if the demux is closed.
- *
- * @param filterId the ID of the filter.
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * INVALID_ARGUMENT if failed for wrong filter ID.
- * INVALID_STATE if failed for wrong state.
- * UNKNOWN_ERROR if failed for other reasons.
- */
- stopFilter(DemuxFilterId filterId) generates (Result result);
-
- /**
- * Flush the filter.
- *
- * It is used by the client to ask the filter to flush the data which is
- * already produced but not consumed yet.
- *
- * @param filterId the ID of the filter.
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * INVALID_ARGUMENT if failed for wrong filter ID.
- * INVALID_STATE if failed for wrong state.
- * UNKNOWN_ERROR if failed for other reasons.
- */
- flushFilter(DemuxFilterId filterId) generates (Result result);
-
- /**
- * Remove a filter from the demux
- *
- * It is used by the client to remove a filter from the demux.
- *
- * @param filterId the ID of the removed filter.
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * INVALID_ARGUMENT if failed for wrong filter ID.
- * INVALID_STATE if failed for wrong state.
- * UNKNOWN_ERROR if failed for other reasons.
- */
- removeFilter(DemuxFilterId filterId) generates (Result result);
+ openTimeFilter() generates (Result result, ITimeFilter timeFilter);
/**
* Get hardware sync ID for audio and video.
*
* It is used by the client to get the hardware sync ID for audio and video.
*
- * @param filterId the ID of the filter.
+ * @param filter the filter instance.
* @return result Result status of the operation.
* SUCCESS if successful,
* INVALID_ARGUMENT if failed for a wrong filter ID.
* UNKNOWN_ERROR if failed for other reasons.
* @return avSyncHwId the id of hardware A/V sync.
*/
- getAvSyncHwId(DemuxFilterId filterId)
- generates (Result result, AvSyncHwId avSyncHwId);
+ getAvSyncHwId(IFilter filter) generates (Result result, AvSyncHwId avSyncHwId);
/**
* Get current time stamp to use for A/V sync
@@ -182,8 +102,7 @@
* @return time the current time stamp of hardware A/V sync. The time stamp
* based on 90KHz has the same format as PTS (Presentation Time Stamp).
*/
- getAvSyncTime(AvSyncHwId avSyncHwId)
- generates (Result result, uint64_t time);
+ getAvSyncTime(AvSyncHwId avSyncHwId) generates (Result result, uint64_t time);
/**
* Close the Demux instance
@@ -198,218 +117,21 @@
close() generates (Result result);
/**
- * Add output to the demux
+ * Open a DVR (Digital Video Record) instance in the demux
*
- * It is used by the client to record output data from selected filters.
+ * It is used by the client to record and playback.
*
+ * @param type specify which kind of DVR to open.
* @param bufferSize the buffer size of the output to be added. It's used to
* create a FMQ(Fast Message Queue) to hold data from selected filters.
- * @param cb the callback for the demux to be used to send notifications
+ * @param cb the callback for the DVR to be used to send notifications
* back to the client.
* @return result Result status of the operation.
* SUCCESS if successful,
* OUT_OF_MEMORY if failed for not enough memory.
* UNKNOWN_ERROR if failed for other reasons.
+ * @return dvr a DVR instance.
*/
- addOutput(uint32_t bufferSize, IDemuxCallback cb) generates (Result result);
-
- /**
- * Get the descriptor of the output's FMQ
- *
- * It is used by the client to get the descriptor of the output's Fast
- * Message Queue. The data in FMQ is muxed packets output from selected
- * filters. The packet's format is specified by DemuxDataFormat in
- * DemuxOutputSettings.
- *
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * UNKNOWN_ERROR if failed for other reasons.
- * @return queue the descriptor of the output's FMQ
- */
- getOutputQueueDesc() generates (Result result, fmq_sync<uint8_t> queue);
-
- /**
- * Configure the demux's output.
- *
- * It is used by the client to configure the demux's output for recording.
- *
- * @param settings the settings of the demux's output.
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * INVALID_STATE if failed for wrong state.
- * UNKNOWN_ERROR if failed for other reasons.
- */
- configureOutput(DemuxOutputSettings settings) generates (Result result);
-
- /**
- * Attach one filter to the demux's output.
- *
- * It is used by the client to mux one filter's output to demux's output.
- *
- * @param filterId the ID of the attached filter.
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * INVALID_STATE if failed for wrong state.
- * UNKNOWN_ERROR if failed for other reasons.
- */
- attachOutputFilter(DemuxFilterId filterId) generates (Result result);
-
- /**
- * Detach one filter from the demux's output.
- *
- * It is used by the client to remove one filter's output from demux's
- * output.
- *
- * @param filterId the ID of the detached filter.
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * INVALID_STATE if failed for wrong state.
- * UNKNOWN_ERROR if failed for other reasons.
- */
- detachOutputFilter(DemuxFilterId filterId) generates (Result result);
-
- /**
- * Start to take data to the demux's output.
- *
- * It is used by the client to ask the output to start to take data from
- * attached filters.
- *
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * INVALID_STATE if failed for wrong state.
- * UNKNOWN_ERROR if failed for other reasons.
- */
- startOutput() generates (Result result);
-
- /**
- * Stop to take data to the demux's output.
- *
- * It is used by the client to ask the output to stop to take data from
- * attached filters.
- *
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * INVALID_STATE if failed for wrong state.
- * UNKNOWN_ERROR if failed for other reasons.
- */
- stopOutput() generates (Result result);
-
- /**
- * Flush unconsumed data in the demux's output.
- *
- * It is used by the client to ask the demux to flush the data which is
- * already produced but not consumed yet in the demux's output.
- *
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * INVALID_STATE if failed for wrong state.
- * UNKNOWN_ERROR if failed for other reasons.
- */
- flushOutput() generates (Result result);
-
- /**
- * Remove the demux's output.
- *
- * It is used by the client to remove the demux's output.
- *
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * INVALID_STATE if failed for wrong state.
- * UNKNOWN_ERROR if failed for other reasons.
- */
- removeOutput() generates (Result result);
-
- /**
- * Add input to the demux
- *
- * It is used by the client to add the demux's input for playback content.
- *
- * @param bufferSize the buffer size of the demux's input to be added.
- * It's used to create a FMQ(Fast Message Queue) to hold input data.
- * @param cb the callback for the demux to be used to send notifications
- * back to the client.
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * OUT_OF_MEMORY if failed for not enough memory.
- * UNKNOWN_ERROR if failed for other reasons.
- */
- addInput(uint32_t bufferSize, IDemuxCallback cb) generates (Result result);
-
- /**
- * Get the descriptor of the input's FMQ
- *
- * It is used by the client to get the descriptor of the input's Fast
- * Message Queue. The data in FMQ is fed by client. Data format is specifed
- * by DemuxDataFormat in DemuxInputSettings.
- *
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * UNKNOWN_ERROR if failed for other reasons.
- * @return queue the descriptor of the output's FMQ
- */
- getInputQueueDesc() generates (Result result, fmq_sync<uint8_t> queue);
-
- /**
- * Configure the demux's input.
- *
- * It is used by the client to configure the demux's input for playback.
- *
- * @param settings the settings of the demux's input.
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * INVALID_STATE if failed for wrong state.
- * UNKNOWN_ERROR if failed for other reasons.
- */
- configureInput(DemuxInputSettings settings) generates (Result result);
-
- /**
- * Start to consume the data from the demux's input.
- *
- * It is used by the client to ask the demux to start to consume data from
- * the demux's input.
- *
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * INVALID_STATE if failed for wrong state.
- * UNKNOWN_ERROR if failed for other reasons.
- */
- startInput() generates (Result result);
-
- /**
- * Stop to consume the data from the demux's input.
- *
- * It is used by the client to ask the demux to stop to consume data from
- * the demux's input.
- *
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * INVALID_STATE if failed for wrong state.
- * UNKNOWN_ERROR if failed for other reasons.
- */
- stopInput() generates (Result result);
-
- /**
- * Flush unconsumed data in the demux's input.
- *
- * It is used by the client to ask the demux to flush the data which is
- * already produced but not consumed yet in the demux's input.
- *
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * INVALID_STATE if failed for wrong state.
- * UNKNOWN_ERROR if failed for other reasons.
- */
- flushInput() generates (Result result);
-
- /**
- * Remove the demux's input.
- *
- * It is used by the client to remove the demux's input.
- *
- * @return result Result status of the operation.
- * SUCCESS if successful,
- * INVALID_STATE if failed for wrong state.
- * UNKNOWN_ERROR if failed for other reasons.
- */
- removeInput() generates (Result result);
+ openDvr(DvrType type, uint32_t bufferSize, IDvrCallback cb)
+ generates (Result result, IDvr dvr);
};
diff --git a/tv/tuner/1.0/IDemuxCallback.hal b/tv/tuner/1.0/IDemuxCallback.hal
deleted file mode 100644
index 7bce9ef..0000000
--- a/tv/tuner/1.0/IDemuxCallback.hal
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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 IDemuxCallback {
- /**
- * Notify the client that a new filter event happened.
- *
- * @param filterEvent a demux filter event.
- */
- oneway onFilterEvent(DemuxFilterEvent filterEvent);
-
- /**
- * Notify the client a new status of a demux filter.
- *
- * @param filterId the demux filter ID.
- * @param status a new status of the demux filter.
- */
- oneway onFilterStatus(DemuxFilterId filterId, DemuxFilterStatus status);
-
- /**
- * Notify the client a new status of the demux's output.
- *
- * @param status a new status of the demux's output.
- */
- oneway onOutputStatus(DemuxOutputStatus status);
-
- /**
- * Notify the client a new status of the demux's input.
- *
- * @param status a new status of the demux's input.
- */
- oneway onInputStatus(DemuxInputStatus status);
-};
-
diff --git a/tv/tuner/1.0/IDescrambler.hal b/tv/tuner/1.0/IDescrambler.hal
index 61ff1df..7f98865 100644
--- a/tv/tuner/1.0/IDescrambler.hal
+++ b/tv/tuner/1.0/IDescrambler.hal
@@ -15,6 +15,9 @@
*/
package android.hardware.tv.tuner@1.0;
+
+import IFilter;
+
/**
* Descrambler is used to descramble input data.
*
@@ -59,12 +62,13 @@
* packets from different PIDs.
*
* @param pid the PID of packets to start to be descrambled.
+ * @param filter an optional filter instance to identify upper stream.
* @return result Result status of the operation.
* SUCCESS if successful,
* INVALID_STATE if failed for wrong state.
* UNKNOWN_ERROR if failed for other reasons.
*/
- addPid(DemuxTpid pid) generates (Result result);
+ addPid(DemuxPid pid, IFilter optionalSourceFilter) generates (Result result);
/**
* Remove packets' PID from the descrambler
@@ -73,12 +77,13 @@
* descrambler stop to descramble.
*
* @param pid the PID of packets to stop to be descrambled.
+ * @param filter an optional filter instance to identify upper stream.
* @return result Result status of the operation.
* SUCCESS if successful,
* INVALID_STATE if failed for wrong state.
* UNKNOWN_ERROR if failed for other reasons.
*/
- removePid(DemuxTpid pid) generates (Result result);
+ removePid(DemuxPid pid, IFilter optionalSourceFilter) generates (Result result);
/**
* Release the descrambler instance
@@ -92,4 +97,3 @@
*/
close() generates (Result result);
};
-
diff --git a/tv/tuner/1.0/IDvr.hal b/tv/tuner/1.0/IDvr.hal
new file mode 100644
index 0000000..f57e4b6
--- /dev/null
+++ b/tv/tuner/1.0/IDvr.hal
@@ -0,0 +1,133 @@
+/*
+ * 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 IFilter;
+
+/**
+ * Digtal Video Record (DVR) interface provides record control on Demux's
+ * output buffer and playback control on Demux's input buffer.
+ */
+interface IDvr {
+ /**
+ * Get the descriptor of the DVR's FMQ
+ *
+ * It is used by the client to get the descriptor of the DVR's Fast
+ * Message Queue. The FMQ is used to transfer record or playback data
+ * between the client and the HAL.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * UNKNOWN_ERROR if failed for other reasons.
+ * @return queue the descriptor of the DVR's FMQ
+ */
+ getQueueDesc() generates (Result result, fmq_sync<uint8_t> queue);
+
+ /**
+ * Configure the DVR.
+ *
+ * It is used by the client to configure the DVR interface.
+ *
+ * @param settings the settings of the DVR interface.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ configure(DvrSettings settings) generates (Result result);
+
+ /**
+ * Attach one filter to DVR interface for recording.
+ *
+ * It is used by the client to add the data filtered out from the filter
+ * to record.
+ *
+ * @param filter the instance of the attached filter.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ attachFilter(IFilter filter) generates (Result result);
+
+ /**
+ * Detach one filter from the DVR's recording.
+ *
+ * It is used by the client to remove the data of the filter from DVR's
+ * recording.
+ *
+ * @param filter the instance of the detached filter.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ detachFilter(IFilter filter) generates (Result result);
+
+ /**
+ * Start DVR.
+ *
+ * It is used by the client to ask the DVR to start consuming playback data
+ * or producing data for record.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ start() generates (Result result);
+
+ /**
+ * Stop DVR.
+ *
+ * It is used by the client to ask the DVR to stop consuming playback data
+ * or producing data for record.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ stop() generates (Result result);
+
+ /**
+ * Flush DVR data.
+ *
+ * It is used by the client to ask the DVR to flush the data which is
+ * not consumed by HAL for playback or the client for record yet.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ flush() generates (Result result);
+
+ /**
+ * close the DVR instance to release resource for DVR.
+ *
+ * It is used by the client to close the DVR instance, and HAL clears
+ * underneath resource for this DVR instance. Client mustn't access the
+ * instance any more and all methods should return a failure.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ close() generates (Result result);
+};
diff --git a/tv/tuner/1.0/IDvrCallback.hal b/tv/tuner/1.0/IDvrCallback.hal
new file mode 100644
index 0000000..337eddc
--- /dev/null
+++ b/tv/tuner/1.0/IDvrCallback.hal
@@ -0,0 +1,33 @@
+/*
+ * 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 IDvrCallback {
+ /**
+ * Notify the client a new status of the demux's record.
+ *
+ * @param status a new status of the demux's record.
+ */
+ oneway onRecordStatus(RecordStatus status);
+
+ /**
+ * Notify the client a new status of the demux's playback.
+ *
+ * @param status a new status of the demux's playback.
+ */
+ oneway onPlaybackStatus(PlaybackStatus status);
+};
diff --git a/tv/tuner/1.0/IFilter.hal b/tv/tuner/1.0/IFilter.hal
new file mode 100644
index 0000000..deaf3d4
--- /dev/null
+++ b/tv/tuner/1.0/IFilter.hal
@@ -0,0 +1,143 @@
+/*
+ * 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 IFilterCallback;
+
+/**
+ * The Filter is used to filter wanted data according to the filter's
+ * configuration.
+ */
+interface IFilter {
+ /**
+ * Get the descriptor of the filter's FMQ
+ *
+ * It is used by the client to get the descriptor of the filter's Fast
+ * Message Queue. The data in FMQ is filtered out from demux input or upper
+ * stream's filter. The data is origanized to data blocks which may have
+ * different length. The length's information of one or multiple data blocks
+ * is sent to client through DemuxFilterEvent. The data in each block
+ * follows the stardard specified by filter's type.
+ * E.X. one data block from the filter with Main_Type==TS and Sub_Type==PES
+ * is Packetized Elementary Stream from Transport Stream according to
+ * ISO/IEC 13818-1.
+ *
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * UNAVAILABLE if the filter doesn't have FMQ.
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ * @return queue the descriptor of the filter's FMQ
+ */
+ getQueueDesc() generates (Result result, fmq_sync<uint8_t> queue);
+
+ /**
+ * Configure the filter.
+ *
+ * It is used by the client to configure the filter so that it can filter out
+ * intended data.
+ *
+ * @param settings the settings of the filter.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ configure(DemuxFilterSettings settings) generates (Result result);
+
+ /**
+ * Start the filter.
+ *
+ * It is used by the client to ask the filter to start filterring data.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ start() generates (Result result);
+
+ /**
+ * Stop the filter.
+ *
+ * It is used by the client to ask the filter to stop filterring data.
+ * It won't discard the data already filtered out by the filter. The filter
+ * will be stopped and removed automatically if the demux is closed.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ stop() generates (Result result);
+
+ /**
+ * Flush the filter.
+ *
+ * It is used by the client to ask the filter to flush the data which is
+ * already produced but not consumed yet.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ flush() generates (Result result);
+
+ /**
+ * Get the filter Id.
+ *
+ * It is used by the client to ask the hardware resource id for the filter.
+ *
+ * @param filterId the hardware resource Id for the filter.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ getId() generates (Result result, uint32_t filterId);
+
+ /**
+ * Set the filter's data source.
+ *
+ * A filter uses demux as data source by default. If the data was packetized
+ * by multiple protocols, multiple filters may need to work together to
+ * extract all protocols' header. Then a filter's data source can be output
+ * from another filter.
+ *
+ * @param filter the filter instance which provides data input. Switch to
+ * use demux as data source if the filter instance is NULL.
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ setDataSource(IFilter filter) generates (Result result);
+
+ /**
+ * Release the Filter instance
+ *
+ * It is used by the client to release the Filter 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/IFilterCallback.hal b/tv/tuner/1.0/IFilterCallback.hal
new file mode 100644
index 0000000..a0ff62e
--- /dev/null
+++ b/tv/tuner/1.0/IFilterCallback.hal
@@ -0,0 +1,33 @@
+/*
+ * 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 IFilterCallback {
+ /**
+ * Notify the client that a new filter event happened.
+ *
+ * @param filterEvent a filter event.
+ */
+ oneway onFilterEvent(DemuxFilterEvent filterEvent);
+
+ /**
+ * Notify the client a new status of a filter.
+ *
+ * @param status a new status of the filter.
+ */
+ oneway onFilterStatus(DemuxFilterStatus status);
+};
diff --git a/tv/tuner/1.0/IFrontend.hal b/tv/tuner/1.0/IFrontend.hal
index 83e390d..756ab46 100644
--- a/tv/tuner/1.0/IFrontend.hal
+++ b/tv/tuner/1.0/IFrontend.hal
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.hardware.tv.tuner@1.0;
import IFrontendCallback;
@@ -128,7 +129,8 @@
* @return statuses an array of statuses which response the caller's
* request.
*/
- getStatus(vec<FrontendStatusType> statusTypes) generates (Result result, vec<FrontendStatus> statuses);
+ getStatus(vec<FrontendStatusType> statusTypes)
+ generates (Result result, vec<FrontendStatus> statuses);
/**
* Sets Low-Noise Block downconverter (LNB) for satellite frontend.
diff --git a/tv/tuner/1.0/IFrontendCallback.hal b/tv/tuner/1.0/IFrontendCallback.hal
index 8896a09..88b96c4 100644
--- a/tv/tuner/1.0/IFrontendCallback.hal
+++ b/tv/tuner/1.0/IFrontendCallback.hal
@@ -26,16 +26,6 @@
/**
* 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);
-
- /**
- * The callback function that must be called by HAL implementation to notify
* the client of scan messages.
*
* @param type the type of scan message.
diff --git a/tv/tuner/1.0/ILnb.hal b/tv/tuner/1.0/ILnb.hal
index 6b7119e..5070519 100644
--- a/tv/tuner/1.0/ILnb.hal
+++ b/tv/tuner/1.0/ILnb.hal
@@ -13,8 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package android.hardware.tv.tuner@1.0;
+import ILnbCallback;
+
/**
* A Tuner LNB (low-noise block downconverter) is used by satellite frontend
* to receive the microwave signal from the satellite, amplify it, and
@@ -22,6 +25,23 @@
*/
interface ILnb {
/**
+ * Set the lnb callback.
+ *
+ * ILnbCallback is used by the client to receive events from the Lnb.
+ * Only one callback per ILnb instance is supported. The callback
+ * will be replaced if it's set again.
+ *
+ * @param callback Callback object to pass Lnb 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(ILnbCallback callback) generates (Result result);
+
+ /**
* Set the lnb's power voltage.
*
* @param voltage the power's voltage the Lnb to use.
@@ -30,7 +50,7 @@
* INVALID_ARGUMENT if the selected voltage isn't allowed,
* UNKNOWN_ERROR if failed for other reasons.
*/
- setVoltage(FrontendLnbVoltage voltage) generates (Result result);
+ setVoltage(LnbVoltage voltage) generates (Result result);
/**
* Set the lnb's tone mode.
@@ -41,7 +61,7 @@
* INVALID_ARGUMENT if the selected tone mode isn't allowed,
* UNKNOWN_ERROR if failed for other reasons.
*/
- setTone(FrontendLnbTone tone) generates (Result result);
+ setTone(LnbTone tone) generates (Result result);
/**
* Select the lnb's position.
@@ -52,7 +72,7 @@
* INVALID_ARGUMENT if the selected position isn't allowed,
* UNKNOWN_ERROR if failed for other reasons.
*/
- setSatellitePosition(FrontendLnbPosition position) generates (Result result);
+ setSatellitePosition(LnbPosition position) generates (Result result);
/**
* Sends DiSEqC (Digital Satellite Equipment Control) message.
diff --git a/tv/tuner/1.0/ILnbCallback.hal b/tv/tuner/1.0/ILnbCallback.hal
new file mode 100644
index 0000000..68e9c35
--- /dev/null
+++ b/tv/tuner/1.0/ILnbCallback.hal
@@ -0,0 +1,36 @@
+/*
+ * 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 ILnbCallback {
+ /**
+ * Notify the client that a new event happened on the Lnb.
+ *
+ * @param LnbEventType the event type.
+ */
+ oneway onEvent(LnbEventType lnbEventType);
+
+ /**
+ * 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/ITimeFilter.hal b/tv/tuner/1.0/ITimeFilter.hal
new file mode 100644
index 0000000..ce285db
--- /dev/null
+++ b/tv/tuner/1.0/ITimeFilter.hal
@@ -0,0 +1,88 @@
+/*
+ * 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;
+
+/**
+ * Timer Filter is used by Demux to filter data based on time stamp.
+ */
+interface ITimeFilter {
+ /**
+ * Set time stamp for time based filter.
+ *
+ * It is used by the client to set initial time stamp and enable time
+ * filtering. The time will be incremented locally. The demux discards
+ * the content which time stamp is older than the time in the time filter.
+ *
+ * @param timeStamp initial time stamp for the time filter. It based on
+ * 90KHz has the same format as PTS (Presentation Time Stamp).
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ setTimeStamp(uint64_t timeStamp) generates (Result result);
+
+ /**
+ * Clear the time stamp in the time filter.
+ *
+ * It is used by the client to clear the time value of the time filter,
+ * then disable time filter.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * UNKNOWN_ERROR if failed for other reasons.
+ */
+ clearTimeStamp() generates (Result result);
+
+ /**
+ * Get the current time in the time filter.
+ *
+ * It is used by the client to inquiry current time in the time filter.
+ *
+ * @return result Result status of the operation.
+ * SUCCESS if successful,
+ * INVALID_STATE if failed for wrong state.
+ * UNKNOWN_ERROR if failed for other reasons.
+ * @return timeStamp current time stamp in the time filter.
+ */
+ getTimeStamp() generates (Result result, uint64_t timeStamp);
+
+ /**
+ * Get the time from the beginning of current data source.
+ *
+ * It is used by the client to inquiry the time stamp from the beginning
+ * of current 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.
+ * @return timeStamp time stamp from the beginning of current data source.
+ */
+ getSourceTime() generates (Result result, uint64_t timeStamp);
+
+ /**
+ * Close the Time Filter 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/ITuner.hal b/tv/tuner/1.0/ITuner.hal
index 1cf0e38..2712c13 100644
--- a/tv/tuner/1.0/ITuner.hal
+++ b/tv/tuner/1.0/ITuner.hal
@@ -23,7 +23,7 @@
/**
* Top level interface to manage Frontend, Demux and Decrambler hardware
- * resources which are needed for Android TV.
+ * resouces which are needed for Android TV.
*/
interface ITuner {
/**
@@ -50,8 +50,7 @@
* UNKNOWN_ERROR if creation failed for other reasons.
* @return frontend the newly created frontend interface.
*/
- openFrontendById(FrontendId frontendId)
- generates (Result result, IFrontend frontend);
+ openFrontendById(FrontendId frontendId) generates (Result result, IFrontend frontend);
/**
* Create a new instance of Demux.
@@ -64,8 +63,7 @@
* @return demuxId newly created demux id.
* @return demux the newly created demux interface.
*/
- openDemux()
- generates (Result result, DemuxId demuxId, IDemux demux);
+ openDemux() generates (Result result, DemuxId demuxId, IDemux demux);
/**
* Retrieve the Demux's Capabilities.
@@ -87,8 +85,7 @@
* UNKNOWN_ERROR if creation failed for other reasons.
* @return descrambler the newly created descrambler interface.
*/
- openDescrambler()
- generates (Result result, IDescrambler descrambler);
+ openDescrambler() generates (Result result, IDescrambler descrambler);
/**
* Retrieve the frontend's information.
@@ -99,8 +96,7 @@
* UNKNOWN_ERROR if the inquiry failed for other reasons.
* @return info the frontend's information.
*/
- getFrontendInfo(FrontendId frontendId)
- generates (Result result, FrontendInfo info);
+ getFrontendInfo(FrontendId frontendId) generates (Result result, FrontendInfo info);
/**
* Get low-noise block downconverter (LNB) IDs.
@@ -126,7 +122,5 @@
* UNKNOWN_ERROR if creation failed for other reasons.
* @return lnb the newly created Lnb interface.
*/
- openLnbById(LnbId lnbId)
- generates (Result result, ILnb lnb);
+ openLnbById(LnbId lnbId) generates (Result result, ILnb lnb);
};
-
diff --git a/tv/tuner/1.0/default/Android.bp b/tv/tuner/1.0/default/Android.bp
index 0ae8bcd..989e25c 100644
--- a/tv/tuner/1.0/default/Android.bp
+++ b/tv/tuner/1.0/default/Android.bp
@@ -4,9 +4,12 @@
vendor: true,
relative_install_path: "hw",
srcs: [
+ "Filter.cpp",
"Frontend.cpp",
"Descrambler.cpp",
"Demux.cpp",
+ "Dvr.cpp",
+ "TimeFilter.cpp",
"Tuner.cpp",
"Lnb.cpp",
"service.cpp",
diff --git a/tv/tuner/1.0/default/Demux.cpp b/tv/tuner/1.0/default/Demux.cpp
index 8bb79f9..c5921f7 100644
--- a/tv/tuner/1.0/default/Demux.cpp
+++ b/tv/tuner/1.0/default/Demux.cpp
@@ -28,45 +28,6 @@
#define WAIT_TIMEOUT 3000000000
-const std::vector<uint8_t> fakeDataInputBuffer{
- 0x00, 0x00, 0x00, 0x01, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0xc0, 0x1e, 0xdb,
- 0x01, 0x40, 0x16, 0xec, 0x04, 0x40, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x03,
- 0xc5, 0x8b, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x68, 0xca, 0x8c, 0xb2, 0x00, 0x00, 0x01, 0x06,
- 0x05, 0xff, 0xff, 0x70, 0xdc, 0x45, 0xe9, 0xbd, 0xe6, 0xd9, 0x48, 0xb7, 0x96, 0x2c, 0xd8,
- 0x20, 0xd9, 0x23, 0xee, 0xef, 0x78, 0x32, 0x36, 0x34, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x72,
- 0x65, 0x20, 0x31, 0x34, 0x32, 0x20, 0x2d, 0x20, 0x48, 0x2e, 0x32, 0x36, 0x34, 0x2f, 0x4d,
- 0x50, 0x45, 0x47, 0x2d, 0x34, 0x20, 0x41, 0x56, 0x43, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x63,
- 0x20, 0x2d, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x32, 0x30, 0x30,
- 0x33, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x20, 0x2d, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f,
- 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x6c, 0x61, 0x6e, 0x2e, 0x6f,
- 0x72, 0x67, 0x2f, 0x78, 0x32, 0x36, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x2d, 0x20,
- 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x63, 0x61, 0x62, 0x61, 0x63, 0x3d,
- 0x30, 0x20, 0x72, 0x65, 0x66, 0x3d, 0x32, 0x20, 0x64, 0x65, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
- 0x3d, 0x31, 0x3a, 0x30, 0x3a, 0x30, 0x20, 0x61, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x65, 0x3d,
- 0x30, 0x78, 0x31, 0x3a, 0x30, 0x78, 0x31, 0x31, 0x31, 0x20, 0x6d, 0x65, 0x3d, 0x68, 0x65,
- 0x78, 0x20, 0x73, 0x75, 0x62, 0x6d, 0x65, 0x3d, 0x37, 0x20, 0x70, 0x73, 0x79, 0x3d, 0x31,
- 0x20, 0x70, 0x73, 0x79, 0x5f, 0x72, 0x64, 0x3d, 0x31, 0x2e, 0x30, 0x30, 0x3a, 0x30, 0x2e,
- 0x30, 0x30, 0x20, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x66, 0x3d, 0x31, 0x20,
- 0x6d, 0x65, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x31, 0x36, 0x20, 0x63, 0x68, 0x72,
- 0x6f, 0x6d, 0x61, 0x5f, 0x6d, 0x65, 0x3d, 0x31, 0x20, 0x74, 0x72, 0x65, 0x6c, 0x6c, 0x69,
- 0x73, 0x3d, 0x31, 0x20, 0x38, 0x78, 0x38, 0x64, 0x63, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x71,
- 0x6d, 0x3d, 0x30, 0x20, 0x64, 0x65, 0x61, 0x64, 0x7a, 0x6f, 0x6e, 0x65, 0x3d, 0x32, 0x31,
- 0x2c, 0x31, 0x31, 0x20, 0x66, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x73, 0x6b, 0x69, 0x70, 0x3d,
- 0x31, 0x20, 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x61, 0x5f, 0x71, 0x70, 0x5f, 0x6f, 0x66, 0x66,
- 0x73, 0x65, 0x74, 0x3d, 0x2d, 0x32, 0x20, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d,
- 0x36, 0x30, 0x20, 0x6c, 0x6f, 0x6f, 0x6b, 0x61, 0x68, 0x65, 0x61, 0x64, 0x5f, 0x74, 0x68,
- 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x35, 0x20, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x64, 0x5f,
- 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x73, 0x3d, 0x30, 0x20, 0x6e, 0x72, 0x3d, 0x30, 0x20,
- 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x3d, 0x31, 0x20, 0x69, 0x6e, 0x74, 0x65,
- 0x72, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x3d, 0x30, 0x20, 0x62, 0x6c, 0x75, 0x72, 0x61, 0x79,
- 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x3d, 0x30, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74,
- 0x72, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x69, 0x6e, 0x74, 0x72, 0x61, 0x3d, 0x30, 0x20,
- 0x62, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x3d, 0x30, 0x20, 0x77, 0x65, 0x69, 0x67, 0x68,
- 0x74, 0x70, 0x3d, 0x30, 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x3d, 0x32, 0x35, 0x30,
- 0x20, 0x6b, 0x65, 0x79, 0x69, 0x6e, 0x74, 0x5f, 0x6d, 0x69, 0x6e, 0x3d, 0x32, 0x35, 0x20,
- 0x73, 0x63, 0x65, 0x6e, 0x65,
-};
-
Demux::Demux(uint32_t demuxId, sp<Tuner> tuner) {
mDemuxId = demuxId;
mTunerService = tuner;
@@ -93,8 +54,8 @@
return startBroadcastInputLoop();
}
-Return<void> Demux::addFilter(DemuxFilterType type, uint32_t bufferSize,
- const sp<IDemuxCallback>& cb, addFilter_cb _hidl_cb) {
+Return<void> Demux::openFilter(const DemuxFilterType& type, uint32_t bufferSize,
+ const sp<IFilterCallback>& cb, openFilter_cb _hidl_cb) {
ALOGV("%s", __FUNCTION__);
uint32_t filterId;
@@ -105,137 +66,39 @@
mUnusedFilterIds.erase(filterId);
} else {
filterId = ++mLastUsedFilterId;
-
- mFilterCallbacks.resize(filterId + 1);
- mFilterMQs.resize(filterId + 1);
- mFilterEvents.resize(filterId + 1);
- mFilterEventFlags.resize(filterId + 1);
- mFilterThreadRunning.resize(filterId + 1);
- mFilterThreads.resize(filterId + 1);
- mFilterPids.resize(filterId + 1);
- mFilterOutputs.resize(filterId + 1);
- mFilterStatus.resize(filterId + 1);
}
mUsedFilterIds.insert(filterId);
- if ((type != DemuxFilterType::PCR || type != DemuxFilterType::TS) && cb == nullptr) {
+ if (cb == nullptr) {
ALOGW("callback can't be null");
- _hidl_cb(Result::INVALID_ARGUMENT, filterId);
+ _hidl_cb(Result::INVALID_ARGUMENT, new Filter());
return Void();
}
- // Add callback
- mFilterCallbacks[filterId] = cb;
+ sp<Filter> filter = new Filter(type, filterId, bufferSize, cb, this);
- // Mapping from the filter ID to the filter event
- DemuxFilterEvent event{
- .filterId = filterId,
- .filterType = type,
- };
- mFilterEvents[filterId] = event;
-
- if (!createFilterMQ(bufferSize, filterId)) {
- _hidl_cb(Result::UNKNOWN_ERROR, -1);
+ if (!filter->createFilterMQ()) {
+ _hidl_cb(Result::UNKNOWN_ERROR, filter);
return Void();
}
- _hidl_cb(Result::SUCCESS, filterId);
+ mFilters[filterId] = filter;
+
+ _hidl_cb(Result::SUCCESS, filter);
return Void();
}
-Return<void> Demux::getFilterQueueDesc(uint32_t filterId, getFilterQueueDesc_cb _hidl_cb) {
+Return<void> Demux::openTimeFilter(openTimeFilter_cb _hidl_cb) {
ALOGV("%s", __FUNCTION__);
- if (mUsedFilterIds.find(filterId) == mUsedFilterIds.end()) {
- ALOGW("No filter with id: %d exists to get desc", filterId);
- _hidl_cb(Result::INVALID_ARGUMENT, FilterMQ::Descriptor());
- return Void();
- }
+ sp<TimeFilter> timeFilter = new TimeFilter(this);
- _hidl_cb(Result::SUCCESS, *mFilterMQs[filterId]->getDesc());
+ _hidl_cb(Result::SUCCESS, timeFilter);
return Void();
}
-Return<Result> Demux::configureFilter(uint32_t filterId, const DemuxFilterSettings& settings) {
- ALOGV("%s", __FUNCTION__);
-
- switch (mFilterEvents[filterId].filterType) {
- case DemuxFilterType::SECTION:
- mFilterPids[filterId] = settings.section().tpid;
- break;
- case DemuxFilterType::PES:
- mFilterPids[filterId] = settings.pesData().tpid;
- break;
- case DemuxFilterType::TS:
- mFilterPids[filterId] = settings.ts().tpid;
- break;
- case DemuxFilterType::AUDIO:
- mFilterPids[filterId] = settings.audio().tpid;
- break;
- case DemuxFilterType::VIDEO:
- mFilterPids[filterId] = settings.video().tpid;
- break;
- case DemuxFilterType::RECORD:
- mFilterPids[filterId] = settings.record().tpid;
- break;
- case DemuxFilterType::PCR:
- mFilterPids[filterId] = settings.pcr().tpid;
- break;
- default:
- return Result::UNKNOWN_ERROR;
- }
- return Result::SUCCESS;
-}
-
-Return<Result> Demux::startFilter(uint32_t filterId) {
- ALOGV("%s", __FUNCTION__);
- Result result;
-
- if (mUsedFilterIds.find(filterId) == mUsedFilterIds.end()) {
- ALOGW("No filter with id: %d exists to start filter", filterId);
- return Result::INVALID_ARGUMENT;
- }
-
- result = startFilterLoop(filterId);
-
- return result;
-}
-
-Return<Result> Demux::stopFilter(uint32_t filterId) {
- ALOGV("%s", __FUNCTION__);
-
- mFilterThreadRunning[filterId] = false;
-
- std::lock_guard<std::mutex> lock(mFilterThreadLock);
-
- return Result::SUCCESS;
-}
-
-Return<Result> Demux::flushFilter(uint32_t filterId) {
- ALOGV("%s", __FUNCTION__);
-
- // temp implementation to flush the FMQ
- int size = mFilterMQs[filterId]->availableToRead();
- char* buffer = new char[size];
- mOutputMQ->read((unsigned char*)&buffer[0], size);
- delete[] buffer;
- mFilterStatus[filterId] = DemuxFilterStatus::DATA_READY;
-
- return Result::SUCCESS;
-}
-
-Return<Result> Demux::removeFilter(uint32_t filterId) {
- ALOGV("%s", __FUNCTION__);
-
- // resetFilterRecords(filterId);
- mUsedFilterIds.erase(filterId);
- mUnusedFilterIds.insert(filterId);
-
- return Result::SUCCESS;
-}
-
-Return<void> Demux::getAvSyncHwId(uint32_t /* filterId */, getAvSyncHwId_cb _hidl_cb) {
+Return<void> Demux::getAvSyncHwId(const sp<IFilter>& /* filter */, getAvSyncHwId_cb _hidl_cb) {
ALOGV("%s", __FUNCTION__);
AvSyncHwId avSyncHwId = 0;
@@ -256,588 +119,81 @@
Return<Result> Demux::close() {
ALOGV("%s", __FUNCTION__);
- set<uint32_t>::iterator it;
- mInputThread = 0;
- mOutputThread = 0;
- mFilterThreads.clear();
mUnusedFilterIds.clear();
mUsedFilterIds.clear();
- mFilterCallbacks.clear();
- mFilterMQs.clear();
- mFilterEvents.clear();
- mFilterEventFlags.clear();
- mFilterOutputs.clear();
- mFilterPids.clear();
mLastUsedFilterId = -1;
return Result::SUCCESS;
}
-Return<Result> Demux::addOutput(uint32_t bufferSize, const sp<IDemuxCallback>& cb) {
+Return<void> Demux::openDvr(DvrType type, uint32_t bufferSize, const sp<IDvrCallback>& cb,
+ openDvr_cb _hidl_cb) {
ALOGV("%s", __FUNCTION__);
- // Create a synchronized FMQ that supports blocking read/write
- std::unique_ptr<FilterMQ> tmpFilterMQ =
- std::unique_ptr<FilterMQ>(new (std::nothrow) FilterMQ(bufferSize, true));
- if (!tmpFilterMQ->isValid()) {
- ALOGW("Failed to create output FMQ");
- return Result::UNKNOWN_ERROR;
- }
-
- mOutputMQ = std::move(tmpFilterMQ);
-
- if (EventFlag::createEventFlag(mOutputMQ->getEventFlagWord(), &mOutputEventFlag) != OK) {
- return Result::UNKNOWN_ERROR;
- }
-
- mOutputCallback = cb;
-
- return Result::SUCCESS;
-}
-
-Return<void> Demux::getOutputQueueDesc(getOutputQueueDesc_cb _hidl_cb) {
- ALOGV("%s", __FUNCTION__);
-
- if (!mOutputMQ) {
- _hidl_cb(Result::NOT_INITIALIZED, FilterMQ::Descriptor());
+ if (cb == nullptr) {
+ ALOGW("DVR callback can't be null");
+ _hidl_cb(Result::INVALID_ARGUMENT, new Dvr());
return Void();
}
- _hidl_cb(Result::SUCCESS, *mOutputMQ->getDesc());
- return Void();
-}
+ sp<Dvr> dvr = new Dvr(type, bufferSize, cb, this);
-Return<Result> Demux::configureOutput(const DemuxOutputSettings& settings) {
- ALOGV("%s", __FUNCTION__);
-
- mOutputConfigured = true;
- mOutputSettings = settings;
- return Result::SUCCESS;
-}
-
-Return<Result> Demux::attachOutputFilter(uint32_t /*filterId*/) {
- ALOGV("%s", __FUNCTION__);
-
- return Result::SUCCESS;
-}
-
-Return<Result> Demux::detachOutputFilter(uint32_t /* filterId */) {
- ALOGV("%s", __FUNCTION__);
-
- return Result::SUCCESS;
-}
-
-Return<Result> Demux::startOutput() {
- ALOGV("%s", __FUNCTION__);
-
- return Result::SUCCESS;
-}
-
-Return<Result> Demux::stopOutput() {
- ALOGV("%s", __FUNCTION__);
-
- return Result::SUCCESS;
-}
-
-Return<Result> Demux::flushOutput() {
- ALOGV("%s", __FUNCTION__);
-
- return Result::SUCCESS;
-}
-
-Return<Result> Demux::removeOutput() {
- ALOGV("%s", __FUNCTION__);
-
- return Result::SUCCESS;
-}
-
-Return<Result> Demux::addInput(uint32_t bufferSize, const sp<IDemuxCallback>& cb) {
- ALOGV("%s", __FUNCTION__);
-
- // Create a synchronized FMQ that supports blocking read/write
- std::unique_ptr<FilterMQ> tmpInputMQ =
- std::unique_ptr<FilterMQ>(new (std::nothrow) FilterMQ(bufferSize, true));
- if (!tmpInputMQ->isValid()) {
- ALOGW("Failed to create input FMQ");
- return Result::UNKNOWN_ERROR;
- }
-
- mInputMQ = std::move(tmpInputMQ);
-
- if (EventFlag::createEventFlag(mInputMQ->getEventFlagWord(), &mInputEventFlag) != OK) {
- return Result::UNKNOWN_ERROR;
- }
-
- mInputCallback = cb;
-
- return Result::SUCCESS;
-}
-
-Return<void> Demux::getInputQueueDesc(getInputQueueDesc_cb _hidl_cb) {
- ALOGV("%s", __FUNCTION__);
-
- if (!mInputMQ) {
- _hidl_cb(Result::NOT_INITIALIZED, FilterMQ::Descriptor());
+ if (!dvr->createDvrMQ()) {
+ _hidl_cb(Result::UNKNOWN_ERROR, dvr);
return Void();
}
- _hidl_cb(Result::SUCCESS, *mInputMQ->getDesc());
+ _hidl_cb(Result::SUCCESS, dvr);
return Void();
}
-Return<Result> Demux::configureInput(const DemuxInputSettings& settings) {
+Result Demux::removeFilter(uint32_t filterId) {
ALOGV("%s", __FUNCTION__);
- mInputConfigured = true;
- mInputSettings = settings;
+ // resetFilterRecords(filterId);
+ mUsedFilterIds.erase(filterId);
+ mUnusedFilterIds.insert(filterId);
+ mFilters.erase(filterId);
return Result::SUCCESS;
}
-Return<Result> Demux::startInput() {
- ALOGV("%s", __FUNCTION__);
-
- if (!mInputCallback) {
- return Result::NOT_INITIALIZED;
- }
-
- if (!mInputConfigured) {
- return Result::INVALID_STATE;
- }
-
- pthread_create(&mInputThread, NULL, __threadLoopInput, this);
- pthread_setname_np(mInputThread, "demux_input_waiting_loop");
-
- // TODO start another thread to send filter status callback to the framework
-
- return Result::SUCCESS;
-}
-
-Return<Result> Demux::stopInput() {
- ALOGV("%s", __FUNCTION__);
-
- mInputThreadRunning = false;
-
- std::lock_guard<std::mutex> lock(mInputThreadLock);
-
- return Result::SUCCESS;
-}
-
-Return<Result> Demux::flushInput() {
- ALOGV("%s", __FUNCTION__);
-
- return Result::SUCCESS;
-}
-
-Return<Result> Demux::removeInput() {
- ALOGV("%s", __FUNCTION__);
-
- mInputMQ = nullptr;
-
- return Result::SUCCESS;
-}
-
-Result Demux::startFilterLoop(uint32_t filterId) {
- struct ThreadArgs* threadArgs = (struct ThreadArgs*)malloc(sizeof(struct ThreadArgs));
- threadArgs->user = this;
- threadArgs->filterId = filterId;
-
- pthread_t mFilterThread;
- pthread_create(&mFilterThread, NULL, __threadLoopFilter, (void*)threadArgs);
- mFilterThreads[filterId] = mFilterThread;
- pthread_setname_np(mFilterThread, "demux_filter_waiting_loop");
-
- return Result::SUCCESS;
-}
-
-Result Demux::startSectionFilterHandler(uint32_t filterId) {
- if (mFilterOutputs[filterId].empty()) {
- return Result::SUCCESS;
- }
- if (!writeSectionsAndCreateEvent(filterId, mFilterOutputs[filterId])) {
- ALOGD("[Demux] filter %d fails to write into FMQ. Ending thread", filterId);
- return Result::UNKNOWN_ERROR;
- }
-
- mFilterOutputs[filterId].clear();
-
- return Result::SUCCESS;
-}
-
-Result Demux::startPesFilterHandler(uint32_t filterId) {
- std::lock_guard<std::mutex> lock(mFilterEventLock);
- if (mFilterOutputs[filterId].empty()) {
- return Result::SUCCESS;
- }
-
- for (int i = 0; i < mFilterOutputs[filterId].size(); i += 188) {
- if (mPesSizeLeft == 0) {
- uint32_t prefix = (mFilterOutputs[filterId][i + 4] << 16) |
- (mFilterOutputs[filterId][i + 5] << 8) |
- mFilterOutputs[filterId][i + 6];
- ALOGD("[Demux] prefix %d", prefix);
- if (prefix == 0x000001) {
- // TODO handle mulptiple Pes filters
- mPesSizeLeft =
- (mFilterOutputs[filterId][i + 8] << 8) | mFilterOutputs[filterId][i + 9];
- mPesSizeLeft += 6;
- ALOGD("[Demux] pes data length %d", mPesSizeLeft);
- } else {
- continue;
- }
- }
-
- int endPoint = min(184, mPesSizeLeft);
- // append data and check size
- vector<uint8_t>::const_iterator first = mFilterOutputs[filterId].begin() + i + 4;
- vector<uint8_t>::const_iterator last = mFilterOutputs[filterId].begin() + i + 4 + endPoint;
- mPesOutput.insert(mPesOutput.end(), first, last);
- // size does not match then continue
- mPesSizeLeft -= endPoint;
- if (mPesSizeLeft > 0) {
- continue;
- }
- // size match then create event
- if (!writeDataToFilterMQ(mPesOutput, filterId)) {
- mFilterOutputs[filterId].clear();
- return Result::INVALID_STATE;
- }
- maySendFilterStatusCallback(filterId);
- DemuxFilterPesEvent pesEvent;
- pesEvent = {
- // temp dump meta data
- .streamId = mPesOutput[3],
- .dataLength = static_cast<uint16_t>(mPesOutput.size()),
- };
- ALOGD("[Demux] assembled pes data length %d", pesEvent.dataLength);
-
- int size = mFilterEvents[filterId].events.size();
- mFilterEvents[filterId].events.resize(size + 1);
- mFilterEvents[filterId].events[size].pes(pesEvent);
- mPesOutput.clear();
- }
-
- mFilterOutputs[filterId].clear();
-
- return Result::SUCCESS;
-}
-
-Result Demux::startTsFilterHandler() {
- // TODO handle starting TS filter
- return Result::SUCCESS;
-}
-
-Result Demux::startMediaFilterHandler(uint32_t filterId) {
- DemuxFilterMediaEvent mediaEvent;
- mediaEvent = {
- // temp dump meta data
- .pts = 0,
- .dataLength = 530,
- .secureMemory = nullptr,
- };
- mFilterEvents[filterId].events.resize(1);
- mFilterEvents[filterId].events[0].media() = mediaEvent;
-
- mFilterOutputs[filterId].clear();
- // TODO handle write FQM for media stream
- return Result::SUCCESS;
-}
-
-Result Demux::startRecordFilterHandler(uint32_t filterId) {
- DemuxFilterRecordEvent recordEvent;
- recordEvent = {
- // temp dump meta data
- .tpid = 0,
- .packetNum = 0,
- };
- recordEvent.indexMask.tsIndexMask() = 0x01;
- mFilterEvents[filterId].events.resize(1);
- mFilterEvents[filterId].events[0].ts() = recordEvent;
-
- mFilterOutputs[filterId].clear();
- return Result::SUCCESS;
-}
-
-Result Demux::startPcrFilterHandler() {
- // TODO handle starting PCR filter
- return Result::SUCCESS;
-}
-
-bool Demux::createFilterMQ(uint32_t bufferSize, uint32_t filterId) {
- ALOGV("%s", __FUNCTION__);
-
- // Create a synchronized FMQ that supports blocking read/write
- std::unique_ptr<FilterMQ> tmpFilterMQ =
- std::unique_ptr<FilterMQ>(new (std::nothrow) FilterMQ(bufferSize, true));
- if (!tmpFilterMQ->isValid()) {
- ALOGW("Failed to create FMQ of filter with id: %d", filterId);
- return false;
- }
-
- mFilterMQs[filterId] = std::move(tmpFilterMQ);
-
- EventFlag* filterEventFlag;
- if (EventFlag::createEventFlag(mFilterMQs[filterId]->getEventFlagWord(), &filterEventFlag) !=
- OK) {
- return false;
- }
- mFilterEventFlags[filterId] = filterEventFlag;
-
- return true;
-}
-
-bool Demux::writeSectionsAndCreateEvent(uint32_t filterId, vector<uint8_t> data) {
- // TODO check how many sections has been read
- std::lock_guard<std::mutex> lock(mFilterEventLock);
- if (!writeDataToFilterMQ(data, filterId)) {
- return false;
- }
- int size = mFilterEvents[filterId].events.size();
- mFilterEvents[filterId].events.resize(size + 1);
- DemuxFilterSectionEvent secEvent;
- secEvent = {
- // temp dump meta data
- .tableId = 0,
- .version = 1,
- .sectionNum = 1,
- .dataLength = static_cast<uint16_t>(data.size()),
- };
- mFilterEvents[filterId].events[size].section(secEvent);
- return true;
-}
-
-bool Demux::writeDataToFilterMQ(const std::vector<uint8_t>& data, uint32_t filterId) {
- std::lock_guard<std::mutex> lock(mWriteLock);
- if (mFilterMQs[filterId]->write(data.data(), data.size())) {
- return true;
- }
- return false;
-}
-
-bool Demux::readInputFMQ() {
- // Read input data from the input FMQ
- int size = mInputMQ->availableToRead();
- int inputPacketSize = mInputSettings.packetSize;
- vector<uint8_t> dataOutputBuffer;
- dataOutputBuffer.resize(inputPacketSize);
-
- // Dispatch the packet to the PID matching filter output buffer
- for (int i = 0; i < size / inputPacketSize; i++) {
- if (!mInputMQ->read(dataOutputBuffer.data(), inputPacketSize)) {
- return false;
- }
- startTsFilter(dataOutputBuffer);
- }
-
- return true;
-}
-
void Demux::startTsFilter(vector<uint8_t> data) {
set<uint32_t>::iterator it;
for (it = mUsedFilterIds.begin(); it != mUsedFilterIds.end(); it++) {
uint16_t pid = ((data[1] & 0x1f) << 8) | ((data[2] & 0xff));
- ALOGW("start ts filter pid: %d", pid);
- if (pid == mFilterPids[*it]) {
- mFilterOutputs[*it].insert(mFilterOutputs[*it].end(), data.begin(), data.end());
+ if (DEBUG_FILTER) {
+ ALOGW("start ts filter pid: %d", pid);
+ }
+ if (pid == mFilters[*it]->getTpid()) {
+ mFilters[*it]->updateFilterOutput(data);
}
}
}
bool Demux::startFilterDispatcher() {
- Result result;
set<uint32_t>::iterator it;
// Handle the output data per filter type
for (it = mUsedFilterIds.begin(); it != mUsedFilterIds.end(); it++) {
- switch (mFilterEvents[*it].filterType) {
- case DemuxFilterType::SECTION:
- result = startSectionFilterHandler(*it);
- break;
- case DemuxFilterType::PES:
- result = startPesFilterHandler(*it);
- break;
- case DemuxFilterType::TS:
- result = startTsFilterHandler();
- break;
- case DemuxFilterType::AUDIO:
- case DemuxFilterType::VIDEO:
- result = startMediaFilterHandler(*it);
- break;
- case DemuxFilterType::RECORD:
- result = startRecordFilterHandler(*it);
- break;
- case DemuxFilterType::PCR:
- result = startPcrFilterHandler();
- break;
- default:
- return false;
+ if (mFilters[*it]->startFilterHandler() != Result::SUCCESS) {
+ return false;
}
}
- return result == Result::SUCCESS;
+ return true;
}
-void* Demux::__threadLoopFilter(void* threadArg) {
- Demux* const self = static_cast<Demux*>(((struct ThreadArgs*)threadArg)->user);
- self->filterThreadLoop(((struct ThreadArgs*)threadArg)->filterId);
- return 0;
+Result Demux::startFilterHandler(uint32_t filterId) {
+ return mFilters[filterId]->startFilterHandler();
}
-void* Demux::__threadLoopInput(void* user) {
- Demux* const self = static_cast<Demux*>(user);
- self->inputThreadLoop();
- return 0;
+void Demux::updateFilterOutput(uint16_t filterId, vector<uint8_t> data) {
+ mFilters[filterId]->updateFilterOutput(data);
}
-void Demux::filterThreadLoop(uint32_t filterId) {
- ALOGD("[Demux] filter %d threadLoop start.", filterId);
- std::lock_guard<std::mutex> lock(mFilterThreadLock);
- mFilterThreadRunning[filterId] = true;
-
- // For the first time of filter output, implementation needs to send the filter
- // Event Callback without waiting for the DATA_CONSUMED to init the process.
- while (mFilterThreadRunning[filterId]) {
- if (mFilterEvents[filterId].events.size() == 0) {
- ALOGD("[Demux] wait for filter data output.");
- usleep(1000 * 1000);
- continue;
- }
- // After successfully write, send a callback and wait for the read to be done
- mFilterCallbacks[filterId]->onFilterEvent(mFilterEvents[filterId]);
- mFilterEvents[filterId].events.resize(0);
- mFilterStatus[filterId] = DemuxFilterStatus::DATA_READY;
- mFilterCallbacks[filterId]->onFilterStatus(filterId, mFilterStatus[filterId]);
- break;
- }
-
- while (mFilterThreadRunning[filterId]) {
- uint32_t efState = 0;
- // We do not wait for the last round of writen data to be read to finish the thread
- // because the VTS can verify the reading itself.
- for (int i = 0; i < SECTION_WRITE_COUNT; i++) {
- while (mFilterThreadRunning[filterId]) {
- status_t status = mFilterEventFlags[filterId]->wait(
- static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED), &efState,
- WAIT_TIMEOUT, true /* retry on spurious wake */);
- if (status != OK) {
- ALOGD("[Demux] wait for data consumed");
- continue;
- }
- break;
- }
-
- if (mFilterCallbacks[filterId] == nullptr) {
- ALOGD("[Demux] filter %d does not hava callback. Ending thread", filterId);
- break;
- }
-
- maySendFilterStatusCallback(filterId);
-
- while (mFilterThreadRunning[filterId]) {
- std::lock_guard<std::mutex> lock(mFilterEventLock);
- if (mFilterEvents[filterId].events.size() == 0) {
- continue;
- }
- // After successfully write, send a callback and wait for the read to be done
- mFilterCallbacks[filterId]->onFilterEvent(mFilterEvents[filterId]);
- mFilterEvents[filterId].events.resize(0);
- break;
- }
- // We do not wait for the last read to be done
- // VTS can verify the read result itself.
- if (i == SECTION_WRITE_COUNT - 1) {
- ALOGD("[Demux] filter %d writing done. Ending thread", filterId);
- break;
- }
- }
- mFilterThreadRunning[filterId] = false;
- }
-
- ALOGD("[Demux] filter thread ended.");
-}
-
-void Demux::inputThreadLoop() {
- ALOGD("[Demux] input threadLoop start.");
- std::lock_guard<std::mutex> lock(mInputThreadLock);
- mInputThreadRunning = true;
-
- while (mInputThreadRunning) {
- uint32_t efState = 0;
- status_t status =
- mInputEventFlag->wait(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY),
- &efState, WAIT_TIMEOUT, true /* retry on spurious wake */);
- if (status != OK) {
- ALOGD("[Demux] wait for data ready on the input FMQ");
- continue;
- }
- // Our current implementation filter the data and write it into the filter FMQ immediately
- // after the DATA_READY from the VTS/framework
- if (!readInputFMQ() || !startFilterDispatcher()) {
- ALOGD("[Demux] input data failed to be filtered. Ending thread");
- break;
- }
-
- maySendInputStatusCallback();
- }
-
- mInputThreadRunning = false;
- ALOGD("[Demux] input thread ended.");
-}
-
-void Demux::maySendInputStatusCallback() {
- std::lock_guard<std::mutex> lock(mInputStatusLock);
- int availableToRead = mInputMQ->availableToRead();
- int availableToWrite = mInputMQ->availableToWrite();
-
- DemuxInputStatus newStatus =
- checkInputStatusChange(availableToWrite, availableToRead, mInputSettings.highThreshold,
- mInputSettings.lowThreshold);
- if (mIntputStatus != newStatus) {
- mInputCallback->onInputStatus(newStatus);
- mIntputStatus = newStatus;
- }
-}
-
-void Demux::maySendFilterStatusCallback(uint32_t filterId) {
- std::lock_guard<std::mutex> lock(mFilterStatusLock);
- int availableToRead = mFilterMQs[filterId]->availableToRead();
- int availableToWrite = mFilterMQs[filterId]->availableToWrite();
- int fmqSize = mFilterMQs[filterId]->getQuantumCount();
-
- DemuxFilterStatus newStatus =
- checkFilterStatusChange(filterId, availableToWrite, availableToRead,
- ceil(fmqSize * 0.75), ceil(fmqSize * 0.25));
- if (mFilterStatus[filterId] != newStatus) {
- mFilterCallbacks[filterId]->onFilterStatus(filterId, newStatus);
- mFilterStatus[filterId] = newStatus;
- }
-}
-
-DemuxInputStatus Demux::checkInputStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
- uint32_t highThreshold, uint32_t lowThreshold) {
- if (availableToWrite == 0) {
- return DemuxInputStatus::SPACE_FULL;
- } else if (availableToRead > highThreshold) {
- return DemuxInputStatus::SPACE_ALMOST_FULL;
- } else if (availableToRead < lowThreshold) {
- return DemuxInputStatus::SPACE_ALMOST_EMPTY;
- } else if (availableToRead == 0) {
- return DemuxInputStatus::SPACE_EMPTY;
- }
- return mIntputStatus;
-}
-
-DemuxFilterStatus Demux::checkFilterStatusChange(uint32_t filterId, uint32_t availableToWrite,
- uint32_t availableToRead, uint32_t highThreshold,
- uint32_t lowThreshold) {
- if (availableToWrite == 0) {
- return DemuxFilterStatus::OVERFLOW;
- } else if (availableToRead > highThreshold) {
- return DemuxFilterStatus::HIGH_WATER;
- } else if (availableToRead < lowThreshold) {
- return DemuxFilterStatus::LOW_WATER;
- }
- return mFilterStatus[filterId];
+uint16_t Demux::getFilterTpid(uint32_t filterId) {
+ return mFilters[filterId]->getTpid();
}
Result Demux::startBroadcastInputLoop() {
@@ -876,6 +232,7 @@
for (int i = 0; i < writePacketAmount; i++) {
inputData.read(buffer, packetSize);
if (!inputData) {
+ mKeepFetchingDataFromFrontend = false;
mBroadcastInputThreadRunning = false;
break;
}
@@ -888,7 +245,7 @@
startTsFilter(byteBuffer);
}
startFilterDispatcher();
- sleep(1);
+ usleep(100);
}
}
@@ -898,6 +255,7 @@
}
void Demux::stopBroadcastInput() {
+ ALOGD("[Demux] stop frontend on demux");
mKeepFetchingDataFromFrontend = false;
mBroadcastInputThreadRunning = false;
std::lock_guard<std::mutex> lock(mBroadcastInputThreadLock);
diff --git a/tv/tuner/1.0/default/Demux.h b/tv/tuner/1.0/default/Demux.h
index ba0b9b0..a9756cc 100644
--- a/tv/tuner/1.0/default/Demux.h
+++ b/tv/tuner/1.0/default/Demux.h
@@ -21,7 +21,10 @@
#include <fmq/MessageQueue.h>
#include <math.h>
#include <set>
+#include "Dvr.h"
+#include "Filter.h"
#include "Frontend.h"
+#include "TimeFilter.h"
#include "Tuner.h"
using namespace std;
@@ -38,13 +41,17 @@
using ::android::hardware::MessageQueue;
using ::android::hardware::MQDescriptorSync;
using ::android::hardware::tv::tuner::V1_0::IDemux;
-using ::android::hardware::tv::tuner::V1_0::IDemuxCallback;
+using ::android::hardware::tv::tuner::V1_0::IDvrCallback;
+using ::android::hardware::tv::tuner::V1_0::IFilterCallback;
using ::android::hardware::tv::tuner::V1_0::Result;
using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
-class Tuner;
+class Dvr;
+class Filter;
class Frontend;
+class TimeFilter;
+class Tuner;
class Demux : public IDemux {
public:
@@ -54,63 +61,27 @@
virtual Return<Result> setFrontendDataSource(uint32_t frontendId) override;
- virtual Return<Result> close() override;
+ virtual Return<void> openFilter(const DemuxFilterType& type, uint32_t bufferSize,
+ const sp<IFilterCallback>& cb, openFilter_cb _hidl_cb) override;
- virtual Return<void> addFilter(DemuxFilterType type, uint32_t bufferSize,
- const sp<IDemuxCallback>& cb, addFilter_cb _hidl_cb) override;
+ virtual Return<void> openTimeFilter(openTimeFilter_cb _hidl_cb) override;
- virtual Return<void> getFilterQueueDesc(uint32_t filterId,
- getFilterQueueDesc_cb _hidl_cb) override;
-
- virtual Return<Result> configureFilter(uint32_t filterId,
- const DemuxFilterSettings& settings) override;
-
- virtual Return<Result> startFilter(uint32_t filterId) override;
-
- virtual Return<Result> stopFilter(uint32_t filterId) override;
-
- virtual Return<Result> flushFilter(uint32_t filterId) override;
-
- virtual Return<Result> removeFilter(uint32_t filterId) override;
-
- virtual Return<void> getAvSyncHwId(uint32_t filterId, getAvSyncHwId_cb _hidl_cb) override;
+ virtual Return<void> getAvSyncHwId(const sp<IFilter>& filter,
+ getAvSyncHwId_cb _hidl_cb) override;
virtual Return<void> getAvSyncTime(AvSyncHwId avSyncHwId, getAvSyncTime_cb _hidl_cb) override;
- virtual Return<Result> addInput(uint32_t bufferSize, const sp<IDemuxCallback>& cb) override;
+ virtual Return<Result> close() override;
- virtual Return<void> getInputQueueDesc(getInputQueueDesc_cb _hidl_cb) override;
-
- virtual Return<Result> configureInput(const DemuxInputSettings& settings) override;
-
- virtual Return<Result> startInput() override;
-
- virtual Return<Result> stopInput() override;
-
- virtual Return<Result> flushInput() override;
-
- virtual Return<Result> removeInput() override;
-
- virtual Return<Result> addOutput(uint32_t bufferSize, const sp<IDemuxCallback>& cb) override;
-
- virtual Return<void> getOutputQueueDesc(getOutputQueueDesc_cb _hidl_cb) override;
-
- virtual Return<Result> configureOutput(const DemuxOutputSettings& settings) override;
-
- virtual Return<Result> attachOutputFilter(uint32_t filterId) override;
-
- virtual Return<Result> detachOutputFilter(uint32_t filterId) override;
-
- virtual Return<Result> startOutput() override;
-
- virtual Return<Result> stopOutput() override;
-
- virtual Return<Result> flushOutput() override;
-
- virtual Return<Result> removeOutput() override;
+ virtual Return<void> openDvr(DvrType type, uint32_t bufferSize, const sp<IDvrCallback>& cb,
+ openDvr_cb _hidl_cb) override;
// Functions interacts with Tuner Service
void stopBroadcastInput();
+ Result removeFilter(uint32_t filterId);
+ Result startFilterHandler(uint32_t filterId);
+ void updateFilterOutput(uint16_t filterId, vector<uint8_t> data);
+ uint16_t getFilterTpid(uint32_t filterId);
private:
// Tuner service
@@ -126,19 +97,9 @@
uint32_t filterId;
};
- /**
- * Filter handlers to handle the data filtering.
- * They are also responsible to write the filtered output into the filter FMQ
- * and update the filterEvent bound with the same filterId.
- */
- Result startSectionFilterHandler(uint32_t filterId);
- Result startPesFilterHandler(uint32_t filterId);
- Result startTsFilterHandler();
- Result startMediaFilterHandler(uint32_t filterId);
- Result startRecordFilterHandler(uint32_t filterId);
- Result startPcrFilterHandler();
- Result startFilterLoop(uint32_t filterId);
Result startBroadcastInputLoop();
+ static void* __threadLoopBroadcast(void* user);
+ void broadcastInputThreadLoop();
/**
* To create a FilterMQ with the the next available Filter ID.
@@ -147,32 +108,14 @@
*
* Return false is any of the above processes fails.
*/
- bool createFilterMQ(uint32_t bufferSize, uint32_t filterId);
- bool createMQ(FilterMQ* queue, EventFlag* eventFlag, uint32_t bufferSize);
void deleteEventFlag();
- bool writeDataToFilterMQ(const std::vector<uint8_t>& data, uint32_t filterId);
bool readDataFromMQ();
- bool writeSectionsAndCreateEvent(uint32_t filterId, vector<uint8_t> data);
- void maySendInputStatusCallback();
- void maySendFilterStatusCallback(uint32_t filterId);
- DemuxInputStatus checkInputStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
- uint32_t highThreshold, uint32_t lowThreshold);
- DemuxFilterStatus checkFilterStatusChange(uint32_t filterId, uint32_t availableToWrite,
- uint32_t availableToRead, uint32_t highThreshold,
- uint32_t lowThreshold);
/**
* A dispatcher to read and dispatch input data to all the started filters.
* Each filter handler handles the data filtering/output writing/filterEvent updating.
*/
- bool readInputFMQ();
- void startTsFilter(vector<uint8_t> data);
bool startFilterDispatcher();
- static void* __threadLoopFilter(void* data);
- static void* __threadLoopInput(void* user);
- static void* __threadLoopBroadcast(void* user);
- void filterThreadLoop(uint32_t filterId);
- void inputThreadLoop();
- void broadcastInputThreadLoop();
+ void startTsFilter(vector<uint8_t> data);
uint32_t mDemuxId;
/**
@@ -196,40 +139,13 @@
* A list of created FilterMQ ptrs.
* The array number is the filter ID.
*/
- vector<uint16_t> mFilterPids;
- vector<vector<uint8_t>> mFilterOutputs;
- vector<unique_ptr<FilterMQ>> mFilterMQs;
- vector<EventFlag*> mFilterEventFlags;
- vector<DemuxFilterEvent> mFilterEvents;
- unique_ptr<FilterMQ> mInputMQ;
- unique_ptr<FilterMQ> mOutputMQ;
- EventFlag* mInputEventFlag;
- EventFlag* mOutputEventFlag;
- /**
- * Demux callbacks used on filter events or IO buffer status
- */
- vector<sp<IDemuxCallback>> mFilterCallbacks;
- sp<IDemuxCallback> mInputCallback;
- sp<IDemuxCallback> mOutputCallback;
- bool mInputConfigured = false;
- bool mOutputConfigured = false;
- DemuxInputSettings mInputSettings;
- DemuxOutputSettings mOutputSettings;
+ std::map<uint32_t, sp<Filter>> mFilters;
// Thread handlers
- pthread_t mInputThread;
- pthread_t mOutputThread;
pthread_t mBroadcastInputThread;
- vector<pthread_t> mFilterThreads;
-
- // FMQ status local records
- DemuxInputStatus mIntputStatus;
- vector<DemuxFilterStatus> mFilterStatus;
/**
* If a specific filter's writing loop is still running
*/
- vector<bool> mFilterThreadRunning;
- bool mInputThreadRunning;
bool mBroadcastInputThreadRunning;
bool mKeepFetchingDataFromFrontend;
/**
@@ -237,28 +153,16 @@
*/
std::mutex mWriteLock;
/**
- * Lock to protect writes to the filter event
- */
- // TODO make each filter separate event lock
- std::mutex mFilterEventLock;
- /**
* Lock to protect writes to the input status
*/
- std::mutex mInputStatusLock;
- std::mutex mFilterStatusLock;
std::mutex mBroadcastInputThreadLock;
- std::mutex mFilterThreadLock;
- std::mutex mInputThreadLock;
- /**
- * How many times a filter should write
- * TODO make this dynamic/random/can take as a parameter
- */
- const uint16_t SECTION_WRITE_COUNT = 10;
// temp handle single PES filter
// TODO handle mulptiple Pes filters
int mPesSizeLeft = 0;
vector<uint8_t> mPesOutput;
+
+ const bool DEBUG_FILTER = false;
};
} // namespace implementation
diff --git a/tv/tuner/1.0/default/Descrambler.cpp b/tv/tuner/1.0/default/Descrambler.cpp
index 085f2c8..e3f5b22 100644
--- a/tv/tuner/1.0/default/Descrambler.cpp
+++ b/tv/tuner/1.0/default/Descrambler.cpp
@@ -50,13 +50,15 @@
return Result::SUCCESS;
}
-Return<Result> Descrambler::addPid(uint16_t /* pid */) {
+Return<Result> Descrambler::addPid(const DemuxPid& /* pid */,
+ const sp<IFilter>& /* optionalSourceFilter */) {
ALOGV("%s", __FUNCTION__);
return Result::SUCCESS;
}
-Return<Result> Descrambler::removePid(uint16_t /* pid */) {
+Return<Result> Descrambler::removePid(const DemuxPid& /* pid */,
+ const sp<IFilter>& /* optionalSourceFilter */) {
ALOGV("%s", __FUNCTION__);
return Result::SUCCESS;
diff --git a/tv/tuner/1.0/default/Descrambler.h b/tv/tuner/1.0/default/Descrambler.h
index 436adcf..c889820 100644
--- a/tv/tuner/1.0/default/Descrambler.h
+++ b/tv/tuner/1.0/default/Descrambler.h
@@ -40,9 +40,11 @@
virtual Return<Result> setKeyToken(const hidl_vec<uint8_t>& keyToken) override;
- virtual Return<Result> addPid(uint16_t pid) override;
+ virtual Return<Result> addPid(const DemuxPid& pid,
+ const sp<IFilter>& optionalSourceFilter) override;
- virtual Return<Result> removePid(uint16_t pid) override;
+ virtual Return<Result> removePid(const DemuxPid& pid,
+ const sp<IFilter>& optionalSourceFilter) override;
virtual Return<Result> close() override;
diff --git a/tv/tuner/1.0/default/Dvr.cpp b/tv/tuner/1.0/default/Dvr.cpp
new file mode 100644
index 0000000..eb38f90
--- /dev/null
+++ b/tv/tuner/1.0/default/Dvr.cpp
@@ -0,0 +1,280 @@
+/*
+ * 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-Dvr"
+
+#include "Dvr.h"
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+#define WAIT_TIMEOUT 3000000000
+
+Dvr::Dvr() {}
+
+Dvr::Dvr(DvrType type, uint32_t bufferSize, const sp<IDvrCallback>& cb, sp<Demux> demux) {
+ mType = type;
+ mBufferSize = bufferSize;
+ mCallback = cb;
+ mDemux = demux;
+}
+
+Dvr::~Dvr() {}
+
+Return<void> Dvr::getQueueDesc(getQueueDesc_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ _hidl_cb(Result::SUCCESS, *mDvrMQ->getDesc());
+ return Void();
+}
+
+Return<Result> Dvr::configure(const DvrSettings& settings) {
+ ALOGV("%s", __FUNCTION__);
+
+ mDvrSettings = settings;
+ mDvrConfigured = true;
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Dvr::attachFilter(const sp<IFilter>& filter) {
+ ALOGV("%s", __FUNCTION__);
+
+ uint32_t filterId;
+ Result status;
+
+ filter->getId([&](Result result, uint32_t id) {
+ filterId = id;
+ status = result;
+ });
+
+ if (status != Result::SUCCESS) {
+ return status;
+ }
+
+ mFilters[filterId] = filter;
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Dvr::detachFilter(const sp<IFilter>& filter) {
+ ALOGV("%s", __FUNCTION__);
+
+ uint32_t filterId;
+ Result status;
+
+ filter->getId([&](Result result, uint32_t id) {
+ filterId = id;
+ status = result;
+ });
+
+ if (status != Result::SUCCESS) {
+ return status;
+ }
+
+ std::map<uint32_t, sp<IFilter>>::iterator it;
+
+ it = mFilters.find(filterId);
+ if (it != mFilters.end()) {
+ mFilters.erase(filterId);
+ }
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Dvr::start() {
+ ALOGV("%s", __FUNCTION__);
+
+ if (!mCallback) {
+ return Result::NOT_INITIALIZED;
+ }
+
+ if (!mDvrConfigured) {
+ return Result::INVALID_STATE;
+ }
+
+ if (mType == DvrType::PLAYBACK) {
+ pthread_create(&mDvrThread, NULL, __threadLoopPlayback, this);
+ pthread_setname_np(mDvrThread, "playback_waiting_loop");
+ } else if (mType == DvrType::RECORD) {
+ /*pthread_create(&mInputThread, NULL, __threadLoopInput, this);
+ pthread_setname_np(mInputThread, "playback_waiting_loop");*/
+ }
+
+ // TODO start another thread to send filter status callback to the framework
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Dvr::stop() {
+ ALOGV("%s", __FUNCTION__);
+
+ mDvrThreadRunning = false;
+
+ std::lock_guard<std::mutex> lock(mDvrThreadLock);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Dvr::flush() {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Dvr::close() {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+bool Dvr::createDvrMQ() {
+ ALOGV("%s", __FUNCTION__);
+
+ // Create a synchronized FMQ that supports blocking read/write
+ std::unique_ptr<DvrMQ> tmpDvrMQ =
+ std::unique_ptr<DvrMQ>(new (std::nothrow) DvrMQ(mBufferSize, true));
+ if (!tmpDvrMQ->isValid()) {
+ ALOGW("Failed to create FMQ of DVR");
+ return false;
+ }
+
+ mDvrMQ = std::move(tmpDvrMQ);
+
+ if (EventFlag::createEventFlag(mDvrMQ->getEventFlagWord(), &mDvrEventFlag) != OK) {
+ return false;
+ }
+
+ return true;
+}
+
+void* Dvr::__threadLoopPlayback(void* user) {
+ Dvr* const self = static_cast<Dvr*>(user);
+ self->playbackThreadLoop();
+ return 0;
+}
+
+void Dvr::playbackThreadLoop() {
+ ALOGD("[Dvr] playback threadLoop start.");
+ std::lock_guard<std::mutex> lock(mDvrThreadLock);
+ mDvrThreadRunning = true;
+
+ while (mDvrThreadRunning) {
+ uint32_t efState = 0;
+ status_t status =
+ mDvrEventFlag->wait(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY),
+ &efState, WAIT_TIMEOUT, true /* retry on spurious wake */);
+ if (status != OK) {
+ ALOGD("[Dvr] wait for data ready on the playback FMQ");
+ continue;
+ }
+ // Our current implementation filter the data and write it into the filter FMQ immediately
+ // after the DATA_READY from the VTS/framework
+ if (!readPlaybackFMQ() || !startFilterDispatcher()) {
+ ALOGD("[Dvr] playback data failed to be filtered. Ending thread");
+ break;
+ }
+
+ maySendPlaybackStatusCallback();
+ }
+
+ mDvrThreadRunning = false;
+ ALOGD("[Dvr] playback thread ended.");
+}
+
+void Dvr::maySendPlaybackStatusCallback() {
+ std::lock_guard<std::mutex> lock(mPlaybackStatusLock);
+ int availableToRead = mDvrMQ->availableToRead();
+ int availableToWrite = mDvrMQ->availableToWrite();
+
+ PlaybackStatus newStatus = checkPlaybackStatusChange(availableToWrite, availableToRead,
+ mDvrSettings.playback().highThreshold,
+ mDvrSettings.playback().lowThreshold);
+ if (mPlaybackStatus != newStatus) {
+ mCallback->onPlaybackStatus(newStatus);
+ mPlaybackStatus = newStatus;
+ }
+}
+
+PlaybackStatus Dvr::checkPlaybackStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
+ uint32_t highThreshold, uint32_t lowThreshold) {
+ if (availableToWrite == 0) {
+ return PlaybackStatus::SPACE_FULL;
+ } else if (availableToRead > highThreshold) {
+ return PlaybackStatus::SPACE_ALMOST_FULL;
+ } else if (availableToRead < lowThreshold) {
+ return PlaybackStatus::SPACE_ALMOST_EMPTY;
+ } else if (availableToRead == 0) {
+ return PlaybackStatus::SPACE_EMPTY;
+ }
+ return mPlaybackStatus;
+}
+
+bool Dvr::readPlaybackFMQ() {
+ // Read playback data from the input FMQ
+ int size = mDvrMQ->availableToRead();
+ int playbackPacketSize = mDvrSettings.playback().packetSize;
+ vector<uint8_t> dataOutputBuffer;
+ dataOutputBuffer.resize(playbackPacketSize);
+
+ // Dispatch the packet to the PID matching filter output buffer
+ for (int i = 0; i < size / playbackPacketSize; i++) {
+ if (!mDvrMQ->read(dataOutputBuffer.data(), playbackPacketSize)) {
+ return false;
+ }
+ startTpidFilter(dataOutputBuffer);
+ }
+
+ return true;
+}
+
+void Dvr::startTpidFilter(vector<uint8_t> data) {
+ std::map<uint32_t, sp<IFilter>>::iterator it;
+ for (it = mFilters.begin(); it != mFilters.end(); it++) {
+ uint16_t pid = ((data[1] & 0x1f) << 8) | ((data[2] & 0xff));
+ if (DEBUG_DVR) {
+ ALOGW("[Dvr] start ts filter pid: %d", pid);
+ }
+ if (pid == mDemux->getFilterTpid(it->first)) {
+ mDemux->updateFilterOutput(it->first, data);
+ }
+ }
+}
+
+bool Dvr::startFilterDispatcher() {
+ std::map<uint32_t, sp<IFilter>>::iterator it;
+
+ // Handle the output data per filter type
+ for (it = mFilters.begin(); it != mFilters.end(); it++) {
+ if (mDemux->startFilterHandler(it->first) != Result::SUCCESS) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace tuner
+} // namespace tv
+} // namespace hardware
+} // namespace android
\ No newline at end of file
diff --git a/tv/tuner/1.0/default/Dvr.h b/tv/tuner/1.0/default/Dvr.h
new file mode 100644
index 0000000..fbb778c
--- /dev/null
+++ b/tv/tuner/1.0/default/Dvr.h
@@ -0,0 +1,151 @@
+/*
+ * 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_DVR_H_
+#define ANDROID_HARDWARE_TV_TUNER_V1_0_DVR_H_
+
+#include <android/hardware/tv/tuner/1.0/IDvr.h>
+#include <fmq/MessageQueue.h>
+#include <math.h>
+#include <set>
+#include "Demux.h"
+#include "Frontend.h"
+#include "Tuner.h"
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::EventFlag;
+using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::MQDescriptorSync;
+using ::android::hardware::tv::tuner::V1_0::IDemux;
+using ::android::hardware::tv::tuner::V1_0::IDvrCallback;
+using ::android::hardware::tv::tuner::V1_0::Result;
+
+using DvrMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+
+class Demux;
+class Filter;
+class Frontend;
+class Tuner;
+
+class Dvr : public IDvr {
+ public:
+ Dvr();
+
+ Dvr(DvrType type, uint32_t bufferSize, const sp<IDvrCallback>& cb, sp<Demux> demux);
+
+ ~Dvr();
+
+ virtual Return<void> getQueueDesc(getQueueDesc_cb _hidl_cb) override;
+
+ virtual Return<Result> configure(const DvrSettings& settings) override;
+
+ virtual Return<Result> attachFilter(const sp<IFilter>& filter) override;
+
+ virtual Return<Result> detachFilter(const sp<IFilter>& filter) override;
+
+ virtual Return<Result> start() override;
+
+ virtual Return<Result> stop() override;
+
+ virtual Return<Result> flush() override;
+
+ virtual Return<Result> close() override;
+
+ /**
+ * To create a DvrMQ and its Event Flag.
+ *
+ * Return false is any of the above processes fails.
+ */
+ bool createDvrMQ();
+
+ private:
+ // Demux service
+ sp<Demux> mDemux;
+
+ DvrType mType;
+ uint32_t mBufferSize;
+ sp<IDvrCallback> mCallback;
+ std::map<uint32_t, sp<IFilter>> mFilters;
+
+ void deleteEventFlag();
+ bool readDataFromMQ();
+ void maySendPlaybackStatusCallback();
+ void maySendRecordStatusCallback();
+ PlaybackStatus checkPlaybackStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
+ uint32_t highThreshold, uint32_t lowThreshold);
+ /**
+ * A dispatcher to read and dispatch input data to all the started filters.
+ * Each filter handler handles the data filtering/output writing/filterEvent updating.
+ */
+ bool readPlaybackFMQ();
+ void startTpidFilter(vector<uint8_t> data);
+ bool startFilterDispatcher();
+ static void* __threadLoopPlayback(void* user);
+ static void* __threadLoopBroadcast(void* user);
+ void playbackThreadLoop();
+ void broadcastInputThreadLoop();
+
+ unique_ptr<DvrMQ> mDvrMQ;
+ EventFlag* mDvrEventFlag;
+ /**
+ * Demux callbacks used on filter events or IO buffer status
+ */
+ bool mDvrConfigured = false;
+ DvrSettings mDvrSettings;
+
+ // Thread handlers
+ pthread_t mDvrThread;
+ pthread_t mBroadcastInputThread;
+
+ // FMQ status local records
+ PlaybackStatus mPlaybackStatus;
+ /**
+ * If a specific filter's writing loop is still running
+ */
+ bool mDvrThreadRunning;
+ bool mBroadcastInputThreadRunning;
+ bool mKeepFetchingDataFromFrontend;
+ /**
+ * Lock to protect writes to the FMQs
+ */
+ std::mutex mWriteLock;
+ /**
+ * Lock to protect writes to the input status
+ */
+ std::mutex mPlaybackStatusLock;
+ std::mutex mBroadcastInputThreadLock;
+ std::mutex mDvrThreadLock;
+
+ const bool DEBUG_DVR = false;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace tuner
+} // namespace tv
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_TV_TUNER_V1_0_DVR_H_
\ No newline at end of file
diff --git a/tv/tuner/1.0/default/Filter.cpp b/tv/tuner/1.0/default/Filter.cpp
new file mode 100644
index 0000000..3d8a977
--- /dev/null
+++ b/tv/tuner/1.0/default/Filter.cpp
@@ -0,0 +1,456 @@
+/*
+ * 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-Filter"
+
+#include "Filter.h"
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+#define WAIT_TIMEOUT 3000000000
+
+Filter::Filter() {}
+
+Filter::Filter(DemuxFilterType type, uint32_t filterId, uint32_t bufferSize,
+ const sp<IFilterCallback>& cb, sp<Demux> demux) {
+ mType = type;
+ mFilterId = filterId;
+ mBufferSize = bufferSize;
+ mCallback = cb;
+ mDemux = demux;
+}
+
+Filter::~Filter() {}
+
+Return<void> Filter::getId(getId_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ _hidl_cb(Result::SUCCESS, mFilterId);
+ return Void();
+}
+
+Return<Result> Filter::setDataSource(const sp<IFilter>& filter) {
+ ALOGV("%s", __FUNCTION__);
+
+ mDataSource = filter;
+ mIsDataSourceDemux = false;
+
+ return Result::SUCCESS;
+}
+
+Return<void> Filter::getQueueDesc(getQueueDesc_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ _hidl_cb(Result::SUCCESS, *mFilterMQ->getDesc());
+ return Void();
+}
+
+Return<Result> Filter::configure(const DemuxFilterSettings& settings) {
+ ALOGV("%s", __FUNCTION__);
+
+ mFilterSettings = settings;
+ switch (mType.mainType) {
+ case DemuxFilterMainType::TS:
+ mTpid = settings.ts().tpid;
+ break;
+ case DemuxFilterMainType::MMTP:
+ /*mmtpSettings*/
+ break;
+ case DemuxFilterMainType::IP:
+ /*ipSettings*/
+ break;
+ case DemuxFilterMainType::TLV:
+ /*tlvSettings*/
+ break;
+ case DemuxFilterMainType::ALP:
+ /*alpSettings*/
+ break;
+ default:
+ break;
+ }
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Filter::start() {
+ ALOGV("%s", __FUNCTION__);
+
+ return startFilterLoop();
+}
+
+Return<Result> Filter::stop() {
+ ALOGV("%s", __FUNCTION__);
+
+ mFilterThreadRunning = false;
+
+ std::lock_guard<std::mutex> lock(mFilterThreadLock);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Filter::flush() {
+ ALOGV("%s", __FUNCTION__);
+
+ // temp implementation to flush the FMQ
+ int size = mFilterMQ->availableToRead();
+ char* buffer = new char[size];
+ mFilterMQ->read((unsigned char*)&buffer[0], size);
+ delete[] buffer;
+ mFilterStatus = DemuxFilterStatus::DATA_READY;
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Filter::close() {
+ ALOGV("%s", __FUNCTION__);
+
+ return mDemux->removeFilter(mFilterId);
+}
+
+bool Filter::createFilterMQ() {
+ ALOGV("%s", __FUNCTION__);
+
+ // Create a synchronized FMQ that supports blocking read/write
+ std::unique_ptr<FilterMQ> tmpFilterMQ =
+ std::unique_ptr<FilterMQ>(new (std::nothrow) FilterMQ(mBufferSize, true));
+ if (!tmpFilterMQ->isValid()) {
+ ALOGW("Failed to create FMQ of filter with id: %d", mFilterId);
+ return false;
+ }
+
+ mFilterMQ = std::move(tmpFilterMQ);
+
+ if (EventFlag::createEventFlag(mFilterMQ->getEventFlagWord(), &mFilterEventFlag) != OK) {
+ return false;
+ }
+
+ return true;
+}
+
+Result Filter::startFilterLoop() {
+ pthread_create(&mFilterThread, NULL, __threadLoopFilter, this);
+ pthread_setname_np(mFilterThread, "filter_waiting_loop");
+
+ return Result::SUCCESS;
+}
+
+void* Filter::__threadLoopFilter(void* user) {
+ Filter* const self = static_cast<Filter*>(user);
+ self->filterThreadLoop();
+ return 0;
+}
+
+void Filter::filterThreadLoop() {
+ ALOGD("[Filter] filter %d threadLoop start.", mFilterId);
+ std::lock_guard<std::mutex> lock(mFilterThreadLock);
+ mFilterThreadRunning = true;
+
+ // For the first time of filter output, implementation needs to send the filter
+ // Event Callback without waiting for the DATA_CONSUMED to init the process.
+ while (mFilterThreadRunning) {
+ if (mFilterEvent.events.size() == 0) {
+ ALOGD("[Filter] wait for filter data output.");
+ usleep(1000 * 1000);
+ continue;
+ }
+ // After successfully write, send a callback and wait for the read to be done
+ mCallback->onFilterEvent(mFilterEvent);
+ mFilterEvent.events.resize(0);
+ mFilterStatus = DemuxFilterStatus::DATA_READY;
+ mCallback->onFilterStatus(mFilterStatus);
+ break;
+ }
+
+ while (mFilterThreadRunning) {
+ uint32_t efState = 0;
+ // We do not wait for the last round of written data to be read to finish the thread
+ // because the VTS can verify the reading itself.
+ for (int i = 0; i < SECTION_WRITE_COUNT; i++) {
+ while (mFilterThreadRunning) {
+ status_t status = mFilterEventFlag->wait(
+ static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED), &efState,
+ WAIT_TIMEOUT, true /* retry on spurious wake */);
+ if (status != OK) {
+ ALOGD("[Filter] wait for data consumed");
+ continue;
+ }
+ break;
+ }
+
+ if (mCallback == nullptr) {
+ ALOGD("[Filter] filter %d does not hava callback. Ending thread", mFilterId);
+ break;
+ }
+
+ maySendFilterStatusCallback();
+
+ while (mFilterThreadRunning) {
+ std::lock_guard<std::mutex> lock(mFilterEventLock);
+ if (mFilterEvent.events.size() == 0) {
+ continue;
+ }
+ // After successfully write, send a callback and wait for the read to be done
+ mCallback->onFilterEvent(mFilterEvent);
+ mFilterEvent.events.resize(0);
+ break;
+ }
+ // We do not wait for the last read to be done
+ // VTS can verify the read result itself.
+ if (i == SECTION_WRITE_COUNT - 1) {
+ ALOGD("[Filter] filter %d writing done. Ending thread", mFilterId);
+ break;
+ }
+ }
+ mFilterThreadRunning = false;
+ }
+
+ ALOGD("[Filter] filter thread ended.");
+}
+
+void Filter::maySendFilterStatusCallback() {
+ std::lock_guard<std::mutex> lock(mFilterStatusLock);
+ int availableToRead = mFilterMQ->availableToRead();
+ int availableToWrite = mFilterMQ->availableToWrite();
+ int fmqSize = mFilterMQ->getQuantumCount();
+
+ DemuxFilterStatus newStatus = checkFilterStatusChange(
+ availableToWrite, availableToRead, ceil(fmqSize * 0.75), ceil(fmqSize * 0.25));
+ if (mFilterStatus != newStatus) {
+ mCallback->onFilterStatus(newStatus);
+ mFilterStatus = newStatus;
+ }
+}
+
+DemuxFilterStatus Filter::checkFilterStatusChange(uint32_t availableToWrite,
+ uint32_t availableToRead, uint32_t highThreshold,
+ uint32_t lowThreshold) {
+ if (availableToWrite == 0) {
+ return DemuxFilterStatus::OVERFLOW;
+ } else if (availableToRead > highThreshold) {
+ return DemuxFilterStatus::HIGH_WATER;
+ } else if (availableToRead < lowThreshold) {
+ return DemuxFilterStatus::LOW_WATER;
+ }
+ return mFilterStatus;
+}
+
+uint16_t Filter::getTpid() {
+ return mTpid;
+}
+
+void Filter::updateFilterOutput(vector<uint8_t> data) {
+ std::lock_guard<std::mutex> lock(mFilterOutputLock);
+ ALOGD("[Filter] handler output updated");
+ mFilterOutput.insert(mFilterOutput.end(), data.begin(), data.end());
+}
+
+Result Filter::startFilterHandler() {
+ std::lock_guard<std::mutex> lock(mFilterOutputLock);
+ switch (mType.mainType) {
+ case DemuxFilterMainType::TS:
+ switch (mType.subType.tsFilterType()) {
+ case DemuxTsFilterType::UNDEFINED:
+ break;
+ case DemuxTsFilterType::SECTION:
+ startSectionFilterHandler();
+ break;
+ case DemuxTsFilterType::PES:
+ startPesFilterHandler();
+ break;
+ case DemuxTsFilterType::TS:
+ startTsFilterHandler();
+ break;
+ case DemuxTsFilterType::AUDIO:
+ case DemuxTsFilterType::VIDEO:
+ startMediaFilterHandler();
+ break;
+ case DemuxTsFilterType::PCR:
+ startPcrFilterHandler();
+ break;
+ case DemuxTsFilterType::RECORD:
+ startRecordFilterHandler();
+ break;
+ }
+ break;
+ case DemuxFilterMainType::MMTP:
+ /*mmtpSettings*/
+ break;
+ case DemuxFilterMainType::IP:
+ /*ipSettings*/
+ break;
+ case DemuxFilterMainType::TLV:
+ /*tlvSettings*/
+ break;
+ case DemuxFilterMainType::ALP:
+ /*alpSettings*/
+ break;
+ default:
+ break;
+ }
+ return Result::SUCCESS;
+}
+
+Result Filter::startSectionFilterHandler() {
+ if (mFilterOutput.empty()) {
+ return Result::SUCCESS;
+ }
+ if (!writeSectionsAndCreateEvent(mFilterOutput)) {
+ ALOGD("[Filter] filter %d fails to write into FMQ. Ending thread", mFilterId);
+ return Result::UNKNOWN_ERROR;
+ }
+
+ mFilterOutput.clear();
+
+ return Result::SUCCESS;
+}
+
+Result Filter::startPesFilterHandler() {
+ std::lock_guard<std::mutex> lock(mFilterEventLock);
+ if (mFilterOutput.empty()) {
+ return Result::SUCCESS;
+ }
+
+ for (int i = 0; i < mFilterOutput.size(); i += 188) {
+ if (mPesSizeLeft == 0) {
+ uint32_t prefix = (mFilterOutput[i + 4] << 16) | (mFilterOutput[i + 5] << 8) |
+ mFilterOutput[i + 6];
+ ALOGD("[Filter] prefix %d", prefix);
+ if (prefix == 0x000001) {
+ // TODO handle mulptiple Pes filters
+ mPesSizeLeft = (mFilterOutput[i + 8] << 8) | mFilterOutput[i + 9];
+ mPesSizeLeft += 6;
+ ALOGD("[Filter] pes data length %d", mPesSizeLeft);
+ } else {
+ continue;
+ }
+ }
+
+ int endPoint = min(184, mPesSizeLeft);
+ // append data and check size
+ vector<uint8_t>::const_iterator first = mFilterOutput.begin() + i + 4;
+ vector<uint8_t>::const_iterator last = mFilterOutput.begin() + i + 4 + endPoint;
+ mPesOutput.insert(mPesOutput.end(), first, last);
+ // size does not match then continue
+ mPesSizeLeft -= endPoint;
+ ALOGD("[Filter] pes data left %d", mPesSizeLeft);
+ if (mPesSizeLeft > 0) {
+ continue;
+ }
+ // size match then create event
+ if (!writeDataToFilterMQ(mPesOutput)) {
+ ALOGD("[Filter] pes data write failed");
+ mFilterOutput.clear();
+ return Result::INVALID_STATE;
+ }
+ maySendFilterStatusCallback();
+ DemuxFilterPesEvent pesEvent;
+ pesEvent = {
+ // temp dump meta data
+ .streamId = mPesOutput[3],
+ .dataLength = static_cast<uint16_t>(mPesOutput.size()),
+ };
+ ALOGD("[Filter] assembled pes data length %d", pesEvent.dataLength);
+
+ int size = mFilterEvent.events.size();
+ mFilterEvent.events.resize(size + 1);
+ mFilterEvent.events[size].pes(pesEvent);
+ mPesOutput.clear();
+ }
+
+ mFilterOutput.clear();
+
+ return Result::SUCCESS;
+}
+
+Result Filter::startTsFilterHandler() {
+ // TODO handle starting TS filter
+ return Result::SUCCESS;
+}
+
+Result Filter::startMediaFilterHandler() {
+ DemuxFilterMediaEvent mediaEvent;
+ mediaEvent = {
+ // temp dump meta data
+ .pts = 0,
+ .dataLength = 530,
+ .avMemory = nullptr,
+ .isSecureMemory = false,
+ };
+ mFilterEvent.events.resize(1);
+ mFilterEvent.events[0].media(mediaEvent);
+
+ mFilterOutput.clear();
+ // TODO handle write FQM for media stream
+ return Result::SUCCESS;
+}
+
+Result Filter::startRecordFilterHandler() {
+ DemuxFilterTsRecordEvent tsRecordEvent;
+ tsRecordEvent.pid.tPid(0);
+ tsRecordEvent.indexMask.tsIndexMask(0x01);
+ mFilterEvent.events.resize(1);
+ mFilterEvent.events[0].tsRecord(tsRecordEvent);
+
+ mFilterOutput.clear();
+ return Result::SUCCESS;
+}
+
+Result Filter::startPcrFilterHandler() {
+ // TODO handle starting PCR filter
+ return Result::SUCCESS;
+}
+
+bool Filter::writeSectionsAndCreateEvent(vector<uint8_t> data) {
+ // TODO check how many sections has been read
+ ALOGD("[Filter] section hander");
+ std::lock_guard<std::mutex> lock(mFilterEventLock);
+ if (!writeDataToFilterMQ(data)) {
+ return false;
+ }
+ int size = mFilterEvent.events.size();
+ mFilterEvent.events.resize(size + 1);
+ DemuxFilterSectionEvent secEvent;
+ secEvent = {
+ // temp dump meta data
+ .tableId = 0,
+ .version = 1,
+ .sectionNum = 1,
+ .dataLength = static_cast<uint16_t>(data.size()),
+ };
+ mFilterEvent.events[size].section(secEvent);
+ return true;
+}
+
+bool Filter::writeDataToFilterMQ(const std::vector<uint8_t>& data) {
+ std::lock_guard<std::mutex> lock(mWriteLock);
+ if (mFilterMQ->write(data.data(), data.size())) {
+ return true;
+ }
+ return false;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace tuner
+} // namespace tv
+} // namespace hardware
+} // namespace android
\ No newline at end of file
diff --git a/tv/tuner/1.0/default/Filter.h b/tv/tuner/1.0/default/Filter.h
new file mode 100644
index 0000000..21d4297
--- /dev/null
+++ b/tv/tuner/1.0/default/Filter.h
@@ -0,0 +1,179 @@
+/*
+ * 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_FILTER_H_
+#define ANDROID_HARDWARE_TV_TUNER_V1_0_FILTER_H_
+
+#include <android/hardware/tv/tuner/1.0/IFilter.h>
+#include <fmq/MessageQueue.h>
+#include <math.h>
+#include <set>
+#include "Demux.h"
+#include "Frontend.h"
+
+using namespace std;
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::EventFlag;
+using ::android::hardware::kSynchronizedReadWrite;
+using ::android::hardware::MessageQueue;
+using ::android::hardware::MQDescriptorSync;
+using ::android::hardware::tv::tuner::V1_0::IDemux;
+using ::android::hardware::tv::tuner::V1_0::IFilterCallback;
+using ::android::hardware::tv::tuner::V1_0::Result;
+
+using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+
+class Demux;
+
+class Filter : public IFilter {
+ public:
+ Filter();
+
+ Filter(DemuxFilterType type, uint32_t filterId, uint32_t bufferSize,
+ const sp<IFilterCallback>& cb, sp<Demux> demux);
+
+ ~Filter();
+
+ virtual Return<void> getId(getId_cb _hidl_cb) override;
+
+ virtual Return<Result> setDataSource(const sp<IFilter>& filter) override;
+
+ virtual Return<void> getQueueDesc(getQueueDesc_cb _hidl_cb) override;
+
+ virtual Return<Result> configure(const DemuxFilterSettings& settings) override;
+
+ virtual Return<Result> start() override;
+
+ virtual Return<Result> stop() override;
+
+ virtual Return<Result> flush() override;
+
+ virtual Return<Result> close() override;
+
+ /**
+ * To create a FilterMQ and its Event Flag.
+ *
+ * Return false is any of the above processes fails.
+ */
+ bool createFilterMQ();
+ uint16_t getTpid();
+ void updateFilterOutput(vector<uint8_t> data);
+ Result startFilterHandler();
+
+ private:
+ // Tuner service
+ sp<Demux> mDemux;
+ /**
+ * Filter callbacks used on filter events or FMQ status
+ */
+ sp<IFilterCallback> mCallback;
+
+ uint32_t mFilterId;
+ uint32_t mBufferSize;
+ DemuxFilterType mType;
+ DemuxFilterSettings mFilterSettings;
+
+ uint16_t mTpid;
+ sp<IFilter> mDataSource;
+ bool mIsDataSourceDemux = true;
+ vector<uint8_t> mFilterOutput;
+ unique_ptr<FilterMQ> mFilterMQ;
+ EventFlag* mFilterEventFlag;
+ DemuxFilterEvent mFilterEvent;
+
+ // Thread handlers
+ pthread_t mFilterThread;
+
+ // FMQ status local records
+ DemuxFilterStatus mFilterStatus;
+ /**
+ * If a specific filter's writing loop is still running
+ */
+ bool mFilterThreadRunning;
+ bool mKeepFetchingDataFromFrontend;
+
+ /**
+ * How many times a filter should write
+ * TODO make this dynamic/random/can take as a parameter
+ */
+ const uint16_t SECTION_WRITE_COUNT = 10;
+
+ /**
+ * Filter handlers to handle the data filtering.
+ * They are also responsible to write the filtered output into the filter FMQ
+ * and update the filterEvent bound with the same filterId.
+ */
+ Result startSectionFilterHandler();
+ Result startPesFilterHandler();
+ Result startTsFilterHandler();
+ Result startMediaFilterHandler();
+ Result startRecordFilterHandler();
+ Result startPcrFilterHandler();
+ Result startFilterLoop();
+
+ void deleteEventFlag();
+ bool writeDataToFilterMQ(const std::vector<uint8_t>& data);
+ bool readDataFromMQ();
+ bool writeSectionsAndCreateEvent(vector<uint8_t> data);
+ void maySendFilterStatusCallback();
+ DemuxFilterStatus checkFilterStatusChange(uint32_t availableToWrite, uint32_t availableToRead,
+ uint32_t highThreshold, uint32_t lowThreshold);
+ /**
+ * A dispatcher to read and dispatch input data to all the started filters.
+ * Each filter handler handles the data filtering/output writing/filterEvent updating.
+ */
+ void startTsFilter(vector<uint8_t> data);
+ bool startFilterDispatcher();
+ static void* __threadLoopFilter(void* user);
+ void filterThreadLoop();
+
+ /**
+ * Lock to protect writes to the FMQs
+ */
+ std::mutex mWriteLock;
+ /**
+ * Lock to protect writes to the filter event
+ */
+ // TODO make each filter separate event lock
+ std::mutex mFilterEventLock;
+ /**
+ * Lock to protect writes to the input status
+ */
+ std::mutex mFilterStatusLock;
+ std::mutex mFilterThreadLock;
+ std::mutex mFilterOutputLock;
+
+ // temp handle single PES filter
+ // TODO handle mulptiple Pes filters
+ int mPesSizeLeft = 0;
+ vector<uint8_t> mPesOutput;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace tuner
+} // namespace tv
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_TV_TUNER_V1_0_FILTER_H_
\ No newline at end of file
diff --git a/tv/tuner/1.0/default/Frontend.h b/tv/tuner/1.0/default/Frontend.h
index 07fa7b9..eab43a3 100644
--- a/tv/tuner/1.0/default/Frontend.h
+++ b/tv/tuner/1.0/default/Frontend.h
@@ -75,7 +75,7 @@
FrontendType mType = FrontendType::UNDEFINED;
FrontendId mId = 0;
- const string FRONTEND_STREAM_FILE = "/vendor/etc/test1.ts";
+ const string FRONTEND_STREAM_FILE = "/vendor/etc/dumpTs3.ts";
string mSourceStreamFile;
std::ifstream mFrontendData;
};
diff --git a/tv/tuner/1.0/default/Lnb.cpp b/tv/tuner/1.0/default/Lnb.cpp
index 1446f7f..51931d6 100644
--- a/tv/tuner/1.0/default/Lnb.cpp
+++ b/tv/tuner/1.0/default/Lnb.cpp
@@ -30,19 +30,25 @@
Lnb::~Lnb() {}
-Return<Result> Lnb::setVoltage(FrontendLnbVoltage /* voltage */) {
+Return<Result> Lnb::setCallback(const sp<ILnbCallback>& /* callback */) {
ALOGV("%s", __FUNCTION__);
return Result::SUCCESS;
}
-Return<Result> Lnb::setTone(FrontendLnbTone /* tone */) {
+Return<Result> Lnb::setVoltage(LnbVoltage /* voltage */) {
ALOGV("%s", __FUNCTION__);
return Result::SUCCESS;
}
-Return<Result> Lnb::setSatellitePosition(FrontendLnbPosition /* position */) {
+Return<Result> Lnb::setTone(LnbTone /* tone */) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> Lnb::setSatellitePosition(LnbPosition /* position */) {
ALOGV("%s", __FUNCTION__);
return Result::SUCCESS;
diff --git a/tv/tuner/1.0/default/Lnb.h b/tv/tuner/1.0/default/Lnb.h
index 4c251f7..f285cb9 100644
--- a/tv/tuner/1.0/default/Lnb.h
+++ b/tv/tuner/1.0/default/Lnb.h
@@ -29,20 +29,23 @@
namespace V1_0 {
namespace implementation {
-using ::android::hardware::tv::tuner::V1_0::FrontendLnbPosition;
-using ::android::hardware::tv::tuner::V1_0::FrontendLnbTone;
-using ::android::hardware::tv::tuner::V1_0::FrontendLnbVoltage;
+using ::android::hardware::tv::tuner::V1_0::ILnbCallback;
+using ::android::hardware::tv::tuner::V1_0::LnbPosition;
+using ::android::hardware::tv::tuner::V1_0::LnbTone;
+using ::android::hardware::tv::tuner::V1_0::LnbVoltage;
using ::android::hardware::tv::tuner::V1_0::Result;
class Lnb : public ILnb {
public:
Lnb();
- virtual Return<Result> setVoltage(FrontendLnbVoltage voltage) override;
+ virtual Return<Result> setCallback(const sp<ILnbCallback>& callback) override;
- virtual Return<Result> setTone(FrontendLnbTone tone) override;
+ virtual Return<Result> setVoltage(LnbVoltage voltage) override;
- virtual Return<Result> setSatellitePosition(FrontendLnbPosition position) override;
+ virtual Return<Result> setTone(LnbTone tone) override;
+
+ virtual Return<Result> setSatellitePosition(LnbPosition position) override;
virtual Return<Result> sendDiseqcMessage(const hidl_vec<uint8_t>& diseqcMessage) override;
diff --git a/tv/tuner/1.0/default/TimeFilter.cpp b/tv/tuner/1.0/default/TimeFilter.cpp
new file mode 100644
index 0000000..0b1fd1c
--- /dev/null
+++ b/tv/tuner/1.0/default/TimeFilter.cpp
@@ -0,0 +1,78 @@
+/*
+ * 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-TimeFilter"
+
+#include "TimeFilter.h"
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace tv {
+namespace tuner {
+namespace V1_0 {
+namespace implementation {
+
+TimeFilter::TimeFilter() {}
+
+TimeFilter::TimeFilter(sp<Demux> demux) {
+ mDemux = demux;
+}
+
+TimeFilter::~TimeFilter() {}
+
+Return<Result> TimeFilter::setTimeStamp(uint64_t /* timeStamp */) {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<Result> TimeFilter::clearTimeStamp() {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+Return<void> TimeFilter::getTimeStamp(getTimeStamp_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ uint64_t timeStamp = 0;
+
+ _hidl_cb(Result::SUCCESS, timeStamp);
+ return Void();
+}
+
+Return<void> TimeFilter::getSourceTime(getSourceTime_cb _hidl_cb) {
+ ALOGV("%s", __FUNCTION__);
+
+ uint64_t time = 0;
+
+ _hidl_cb(Result::SUCCESS, time);
+ return Void();
+}
+
+Return<Result> TimeFilter::close() {
+ ALOGV("%s", __FUNCTION__);
+
+ return Result::SUCCESS;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace tuner
+} // namespace tv
+} // namespace hardware
+} // namespace android
\ No newline at end of file
diff --git a/tv/tuner/1.0/default/TimeFilter.h b/tv/tuner/1.0/default/TimeFilter.h
new file mode 100644
index 0000000..7131df8
--- /dev/null
+++ b/tv/tuner/1.0/default/TimeFilter.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_TIMEFILTER_H_
+#define ANDROID_HARDWARE_TV_TUNER_V1_0_TIMEFILTER_H_
+
+#include <android/hardware/tv/tuner/1.0/ITimeFilter.h>
+#include "Demux.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::IFilterCallback;
+using ::android::hardware::tv::tuner::V1_0::Result;
+
+using FilterMQ = MessageQueue<uint8_t, kSynchronizedReadWrite>;
+
+class Demux;
+
+class TimeFilter : public ITimeFilter {
+ public:
+ TimeFilter();
+
+ TimeFilter(sp<Demux> demux);
+
+ ~TimeFilter();
+
+ virtual Return<Result> setTimeStamp(uint64_t timeStamp) override;
+
+ virtual Return<Result> clearTimeStamp() override;
+
+ virtual Return<void> getTimeStamp(getTimeStamp_cb _hidl_cb) override;
+
+ virtual Return<void> getSourceTime(getSourceTime_cb _hidl_cb) override;
+
+ virtual Return<Result> close() override;
+
+ private:
+ sp<Demux> mDemux;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace tuner
+} // namespace tv
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_TV_TUNER_V1_0_TIMEFILTER_H_
\ No newline at end of file
diff --git a/tv/tuner/1.0/types.hal b/tv/tuner/1.0/types.hal
index 890c1ed..fa00a6e 100644
--- a/tv/tuner/1.0/types.hal
+++ b/tv/tuner/1.0/types.hal
@@ -17,6 +17,7 @@
package android.hardware.tv.tuner@1.0;
import android.hidl.safe_union@1.0;
+import android.hidl.safe_union@1.0::Monostate;
@export
enum Result : int32_t {
@@ -41,9 +42,13 @@
enum FrontendType : uint32_t {
UNDEFINED = 0,
ANALOG,
- /* Advanced Television Systems Committee (ATSC) Standard A/72. */
+ /**
+ * Advanced Television Systems Committee (ATSC) Standard A/72.
+ */
ATSC,
- /* Advanced Television Systems Committee (ATSC 3.0) Standard A/300. */
+ /**
+ * Advanced Television Systems Committee (ATSC 3.0) Standard A/300.
+ */
ATSC3,
/**
* Digital Video Broadcasting - Cable
@@ -62,15 +67,18 @@
* ETSI EN 302 755 V1.4.1.
*/
DVBT,
- /* Integrated Services Digital Broadcasting-Satellite (ISDB-S)
+ /**
+ * Integrated Services Digital Broadcasting-Satellite (ISDB-S)
* ARIB STD-B20 is technical document of ISDB-S.
*/
ISDBS,
- /* Integrated Services Digital Broadcasting-Satellite (ISDB-S)
+ /**
+ * Integrated Services Digital Broadcasting-Satellite (ISDB-S)
* ARIB STD-B44 is technical document of ISDB-S3.
*/
ISDBS3,
- /* Integrated Services Digital Broadcasting-Terrestrial (ISDB-T or SBTVD)
+ /**
+ * Integrated Services Digital Broadcasting-Terrestrial (ISDB-T or SBTVD)
* ABNT NBR 15603 is technical document of ISDB-T.
*/
ISDBT,
@@ -82,79 +90,153 @@
*/
@export
enum FrontendInnerFec : uint64_t {
- /* Not defined */
+ /**
+ * Not defined
+ */
FEC_UNDEFINED = 0,
- /* hardware is able to detect and set FEC automatically */
+ /**
+ * hardware is able to detect and set FEC automatically
+ */
AUTO = 1 << 0,
- /* 1/2 conv. code rate */
+ /**
+ * 1/2 conv. code rate
+ */
FEC_1_2 = 1 << 1,
- /* 1/3 conv. code rate */
+ /**
+ * 1/3 conv. code rate
+ */
FEC_1_3 = 1 << 2,
- /* 1/4 conv. code rate */
+ /**
+ * 1/4 conv. code rate
+ */
FEC_1_4 = 1 << 3,
- /* 1/5 conv. code rate */
+ /**
+ * 1/5 conv. code rate
+ */
FEC_1_5 = 1 << 4,
- /* 2/3 conv. code rate */
+ /**
+ * 2/3 conv. code rate
+ */
FEC_2_3 = 1 << 5,
- /* 2/5 conv. code rate */
+ /**
+ * 2/5 conv. code rate
+ */
FEC_2_5 = 1 << 6,
- /* 2/9 conv. code rate */
+ /**
+ * 2/9 conv. code rate
+ */
FEC_2_9 = 1 << 7,
- /* 3/4 conv. code rate */
+ /**
+ * 3/4 conv. code rate
+ */
FEC_3_4 = 1 << 8,
- /* 3/5 conv. code rate */
+ /**
+ * 3/5 conv. code rate
+ */
FEC_3_5 = 1 << 9,
- /* 4/5 conv. code rate */
+ /**
+ * 4/5 conv. code rate
+ */
FEC_4_5 = 1 << 10,
- /* 4/15 conv. code rate */
+ /**
+ * 4/15 conv. code rate
+ */
FEC_4_15 = 1 << 11,
- /* 5/6 conv. code rate */
+ /**
+ * 5/6 conv. code rate
+ */
FEC_5_6 = 1 << 12,
- /* 5/9 conv. code rate */
+ /**
+ * 5/9 conv. code rate
+ */
FEC_5_9 = 1 << 13,
- /* 6/7 conv. code rate */
+ /**
+ * 6/7 conv. code rate
+ */
FEC_6_7 = 1 << 14,
- /* 7/8 conv. code rate */
+ /**
+ * 7/8 conv. code rate
+ */
FEC_7_8 = 1 << 15,
- /* 7/9 conv. code rate */
+ /**
+ * 7/9 conv. code rate
+ */
FEC_7_9 = 1 << 16,
- /* 7/15 conv. code rate */
+ /**
+ * 7/15 conv. code rate
+ */
FEC_7_15 = 1 << 17,
- /* 8/9 conv. code rate */
+ /**
+ * 8/9 conv. code rate
+ */
FEC_8_9 = 1 << 18,
- /* 8/15 conv. code rate */
+ /**
+ * 8/15 conv. code rate
+ */
FEC_8_15 = 1 << 19,
- /* 9/10 conv. code rate */
+ /**
+ * 9/10 conv. code rate
+ */
FEC_9_10 = 1 << 20,
- /* 9/20 conv. code rate */
+ /**
+ * 9/20 conv. code rate
+ */
FEC_9_20 = 1 << 21,
- /* 11/15 conv. code rate */
+ /**
+ * 11/15 conv. code rate
+ */
FEC_11_15 = 1 << 22,
- /* 11/20 conv. code rate */
+ /**
+ * 11/20 conv. code rate
+ */
FEC_11_20 = 1 << 23,
- /* 11/45 conv. code rate */
+ /**
+ * 11/45 conv. code rate
+ */
FEC_11_45 = 1 << 24,
- /* 13/18 conv. code rate */
+ /**
+ * 13/18 conv. code rate
+ */
FEC_13_18 = 1 << 25,
- /* 13/45 conv. code rate */
+ /**
+ * 13/45 conv. code rate
+ */
FEC_13_45 = 1 << 26,
- /* 14/45 conv. code rate */
+ /**
+ * 14/45 conv. code rate
+ */
FEC_14_45 = 1 << 27,
- /* 23/36 conv. code rate */
+ /**
+ * 23/36 conv. code rate
+ */
FEC_23_36 = 1 << 28,
- /* 25/36 conv. code rate */
+ /**
+ * 25/36 conv. code rate
+ */
FEC_25_36 = 1 << 29,
- /* 26/45 conv. code rate */
+ /**
+ * 26/45 conv. code rate
+ */
FEC_26_45 = 1 << 30,
- /* 28/45 conv. code rate */
+ /**
+ * 28/45 conv. code rate
+ */
FEC_28_45 = 1 << 31,
- /* 29/45 conv. code rate */
+ /**
+ * 29/45 conv. code rate
+ */
FEC_29_45 = 1 << 32,
- /* 31/45 conv. code rate */
+ /**
+ * 31/45 conv. code rate
+ */
FEC_31_45 = 1 << 33,
- /* 32/45 conv. code rate */
+ /**
+ * 32/45 conv. code rate
+ */
FEC_32_45 = 1 << 34,
- /* 77/90 conv. code rate */
+ /**
+ * 77/90 conv. code rate
+ */
FEC_77_90 = 1 << 35,
};
@@ -164,9 +246,11 @@
@export
enum FrontendAtscModulation : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set modulation automatically */
- AUTO = 1 << 0,
- MOD_8VSB = 1 << 2,
+ /**
+ * hardware is able to detect and set modulation automatically
+ */
+ AUTO = 1 << 0,
+ MOD_8VSB = 1 << 2,
MOD_16VSB = 1 << 3,
};
@@ -174,8 +258,11 @@
* Signal Settings for an ATSC Frontend.
*/
struct FrontendAtscSettings {
- /** Signal frequency in Hertz */
+ /**
+ * Signal frequency in Hertz
+ */
uint32_t frequency;
+
FrontendAtscModulation modulation;
};
@@ -183,7 +270,9 @@
* Capabilities for ATSC Frontend.
*/
struct FrontendAtscCapabilities {
- /** Modulation capability */
+ /**
+ * Modulation capability
+ */
bitfield<FrontendAtscModulation> modulationCap;
};
@@ -193,12 +282,14 @@
@export
enum FrontendAtsc3Modulation : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set modulation automatically */
- AUTO = 1 << 0,
- MOD_QPSK = 1 << 1,
- MOD_16QAM = 1 << 2,
- MOD_64QAM = 1 << 3,
- MOD_256QAM = 1 << 4,
+ /**
+ * hardware is able to detect and set modulation automatically
+ */
+ AUTO = 1 << 0,
+ MOD_QPSK = 1 << 1,
+ MOD_16QAM = 1 << 2,
+ MOD_64QAM = 1 << 3,
+ MOD_256QAM = 1 << 4,
MOD_1024QAM = 1 << 5,
MOD_4096QAM = 1 << 6,
};
@@ -209,7 +300,9 @@
@export
enum FrontendAtsc3Bandwidth : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set bandwidth automatically */
+ /**
+ * hardware is able to detect and set bandwidth automatically
+ */
AUTO = 1 << 0,
BANDWIDTH_6MHZ = 1 << 1,
BANDWIDTH_7MHZ = 1 << 2,
@@ -222,10 +315,12 @@
@export
enum FrontendAtsc3TimeInterleaveMode : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set TimeInterleaveMode automatically */
+ /**
+ * hardware is able to detect and set TimeInterleaveMode automatically
+ */
AUTO = 1 << 0,
- CTI = 1 << 1,
- HTI = 1 << 2,
+ CTI = 1 << 1,
+ HTI = 1 << 2,
};
/**
@@ -234,20 +329,22 @@
@export
enum FrontendAtsc3CodeRate : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set Coderate automatically */
- AUTO = 1 << 0,
- CODERATE_2_15 = 1 << 1,
- CODERATE_3_15 = 1 << 2,
- CODERATE_4_15 = 1 << 3,
- CODERATE_5_15 = 1 << 4,
- CODERATE_6_15 = 1 << 5,
- CODERATE_7_15 = 1 << 6,
- CODERATE_8_15 = 1 << 7,
- CODERATE_9_15 = 1 << 8,
- CODERATE_10_15 = 1 << 9,
- CODERATE_11_15 = 1 << 10,
- CODERATE_12_15 = 1 << 11,
- CODERATE_13_15 = 1 << 12,
+ /**
+ * hardware is able to detect and set Coderate automatically
+ */
+ AUTO = 1 << 0,
+ CODERATE_2_15 = 1 << 1,
+ CODERATE_3_15 = 1 << 2,
+ CODERATE_4_15 = 1 << 3,
+ CODERATE_5_15 = 1 << 4,
+ CODERATE_6_15 = 1 << 5,
+ CODERATE_7_15 = 1 << 6,
+ CODERATE_8_15 = 1 << 7,
+ CODERATE_9_15 = 1 << 8,
+ CODERATE_10_15 = 1 << 9,
+ CODERATE_11_15 = 1 << 10,
+ CODERATE_12_15 = 1 << 11,
+ CODERATE_13_15 = 1 << 12,
};
/**
@@ -256,14 +353,16 @@
@export
enum FrontendAtsc3Fec : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set FEC automatically */
- AUTO = 1 << 0,
+ /**
+ * hardware is able to detect and set FEC automatically
+ */
+ AUTO = 1 << 0,
BCH_LDPC_16K = 1 << 1,
BCH_LDPC_64K = 1 << 2,
CRC_LDPC_16K = 1 << 3,
CRC_LDPC_64K = 1 << 4,
- LDPC_16K = 1 << 5,
- LDPC_64K = 1 << 6,
+ LDPC_16K = 1 << 5,
+ LDPC_64K = 1 << 6,
};
/**
@@ -271,12 +370,18 @@
*/
@export
enum FrontendAtsc3DemodOutputFormat : uint8_t {
- /** Dummy. Scan uses this. */
+ /**
+ * Dummy. Scan uses this.
+ */
UNDEFINED = 0,
- /** ALP format. Typically used in US region. */
+ /**
+ * ALP format. Typically used in US region.
+ */
ATSC3_LINKLAYER_PACKET = 1 << 0,
- /** BaseBand packet format. Typically used in Korea region. */
- BASEBAND_PACKET = 1 << 1,
+ /**
+ * BaseBand packet format. Typically used in Korea region.
+ */
+ BASEBAND_PACKET = 1 << 1,
};
/**
@@ -284,9 +389,13 @@
*/
struct FrontendAtsc3PlpSettings {
uint8_t plpId;
+
FrontendAtsc3Modulation modulation;
+
FrontendAtsc3TimeInterleaveMode interleaveMode;
+
FrontendAtsc3CodeRate codeRate;
+
FrontendAtsc3Fec fec;
};
@@ -294,11 +403,18 @@
* Signal Settings for an ATSC3 Frontend.
*/
struct FrontendAtsc3Settings {
- /** Signal frequency in Hertz */
+ /**
+ * Signal frequency in Hertz
+ */
uint32_t frequency;
- /** Bandwidth of tuning band. */
+
+ /**
+ * Bandwidth of tuning band.
+ */
FrontendAtsc3Bandwidth bandwidth;
+
FrontendAtsc3DemodOutputFormat demodOutputFormat;
+
vec<FrontendAtsc3PlpSettings> plpSettings;
};
@@ -306,17 +422,34 @@
* Capabilities for ATSC3 Frontend.
*/
struct FrontendAtsc3Capabilities {
- /** Bandwidth capability */
+ /**
+ * Bandwidth capability
+ */
bitfield<FrontendAtsc3Bandwidth> bandwidthCap;
- /** Modulation capability */
+
+ /**
+ * Modulation capability
+ */
bitfield<FrontendAtsc3Modulation> modulationCap;
- /** TimeInterleaveMode capability */
+
+ /**
+ * TimeInterleaveMode capability
+ */
bitfield<FrontendAtsc3TimeInterleaveMode> timeInterleaveModeCap;
- /** CodeRate capability */
+
+ /**
+ * CodeRate capability
+ */
bitfield<FrontendAtsc3CodeRate> codeRateCap;
- /** FEC capability */
+
+ /**
+ * FEC capability
+ */
bitfield<FrontendAtsc3Fec> fecCap;
- /** Demodulator Output Format capability */
+
+ /**
+ * Demodulator Output Format capability
+ */
bitfield<FrontendAtsc3DemodOutputFormat> demodOutputFormatCap;
};
@@ -326,7 +459,9 @@
@export
enum FrontendDvbsModulation : int32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set Modulation automatically */
+ /**
+ * hardware is able to detect and set Modulation automatically
+ */
AUTO = 1 << 0,
MOD_QPSK = 1 << 1,
MOD_8PSK = 1 << 2,
@@ -340,7 +475,9 @@
MOD_64APSK = 1 << 10,
MOD_128APSK = 1 << 11,
MOD_256APSK = 1 << 12,
- /** Reserved for Proprietary modulation */
+ /**
+ * Reserved for Proprietary modulation
+ */
MOD_RESERVED = 1 << 13,
};
@@ -374,10 +511,17 @@
*/
struct FrontendDvbsCodeRate {
FrontendInnerFec fec;
+
bool isLinear;
- /* true if enable short frame */
+
+ /**
+ * true if enable short frame
+ */
bool isShortFrames;
- /* bits number in 1000 symbol. 0 if use the default. */
+
+ /**
+ * bits number in 1000 symbol. 0 if use the default.
+ */
uint32_t bitsPer1000Symbol;
};
@@ -396,15 +540,26 @@
* Signal Settings for an DVBS Frontend.
*/
struct FrontendDvbsSettings {
- /** Signal frequency in Hertz */
+ /**
+ * Signal frequency in Hertz
+ */
uint32_t frequency;
+
FrontendDvbsModulation modulation;
+
FrontendDvbsCodeRate coderate;
- /** Symbols per second */
+
+ /**
+ * Symbols per second
+ */
uint32_t symbolRate;
+
FrontendDvbsRolloff rolloff;
+
FrontendDvbsPilot pilot;
+
uint32_t inputStreamId;
+
FrontendDvbsStandard standard;
};
@@ -413,8 +568,10 @@
*/
struct FrontendDvbsCapabilities {
bitfield<FrontendDvbsModulation> modulationCap;
+
bitfield<FrontendInnerFec> innerfecCap;
- bitfield<FrontendDvbsStandard> standard;
+
+ bitfield<FrontendDvbsStandard> standard;
};
/**
@@ -423,7 +580,9 @@
@export
enum FrontendDvbcModulation : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set Modulation automatically */
+ /**
+ * hardware is able to detect and set Modulation automatically
+ */
AUTO = 1 << 0,
MOD_16QAM = 1 << 1,
MOD_32QAM = 1 << 2,
@@ -467,14 +626,24 @@
* Signal Settings for an DVBC Frontend.
*/
struct FrontendDvbcSettings {
- /** Signal frequency in Hertz */
+ /**
+ * Signal frequency in Hertz
+ */
uint32_t frequency;
+
FrontendDvbcModulation modulation;
+
FrontendInnerFec fec;
- /** Symbols per second */
+
+ /**
+ * Symbols per second
+ */
uint32_t symbolRate;
+
FrontendDvbcOuterFec outerFec;
+
FrontendDvbcAnnex annex;
+
FrontendDvbcSpectralInversion spectralInversion;
};
@@ -483,7 +652,9 @@
*/
struct FrontendDvbcCapabilities {
bitfield<FrontendDvbcModulation> modulationCap;
+
bitfield<FrontendInnerFec> fecCap;
+
bitfield<FrontendDvbcAnnex> annexCap;
};
@@ -493,7 +664,9 @@
@export
enum FrontendDvbtBandwidth : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set Bandwidth automatically */
+ /**
+ * hardware is able to detect and set Bandwidth automatically
+ */
AUTO = 1 << 0,
BANDWIDTH_8MHZ = 1 << 1,
BANDWIDTH_7MHZ = 1 << 2,
@@ -509,7 +682,9 @@
@export
enum FrontendDvbtConstellation : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set Constellation automatically */
+ /**
+ * hardware is able to detect and set Constellation automatically
+ */
AUTO = 1 << 0,
CONSTELLATION_QPSK = 1 << 1,
CONSTELLATION_16QAM = 1 << 2,
@@ -523,7 +698,9 @@
@export
enum FrontendDvbtHierarchy : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set Hierarchy automatically */
+ /**
+ * hardware is able to detect and set Hierarchy automatically
+ */
AUTO = 1 << 0,
HIERARCHY_NON_NATIVE = 1 << 1,
HIERARCHY_1_NATIVE = 1 << 2,
@@ -541,7 +718,9 @@
@export
enum FrontendDvbtCoderate : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set Hierarchy automatically */
+ /**
+ * hardware is able to detect and set Hierarchy automatically
+ */
AUTO = 1 << 0,
CODERATE_1_2 = 1 << 1,
CODERATE_2_3 = 1 << 2,
@@ -560,7 +739,9 @@
@export
enum FrontendDvbtGuardInterval : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set Guard Interval automatically */
+ /**
+ * hardware is able to detect and set Guard Interval automatically
+ */
AUTO = 1 << 0,
INTERVAL_1_32 = 1 << 1,
INTERVAL_1_16 = 1 << 2,
@@ -577,7 +758,9 @@
@export
enum FrontendDvbtTransmissionMode : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set Transmission Mode automatically */
+ /**
+ * hardware is able to detect and set Transmission Mode automatically
+ */
AUTO = 1 << 0,
MODE_2K = 1 << 1,
MODE_8K = 1 << 2,
@@ -607,27 +790,50 @@
};
/**
- * Signal Setting for DVBT Frontend.
+ * Signal Settings for DVBT Frontend.
*/
struct FrontendDvbtSettings {
- /** Signal frequency in Hertz */
+ /**
+ * Signal frequency in Hertz
+ */
uint32_t frequency;
+
FrontendDvbtTransmissionMode transmissionMode;
+
FrontendDvbtBandwidth bandwidth;
+
FrontendDvbtConstellation constellation;
+
FrontendDvbtHierarchy hierarchy;
- /** Code Rate for High Priority level */
+
+ /**
+ * Code Rate for High Priority level
+ */
FrontendDvbtCoderate hpCoderate;
- /** Code Rate for Low Priority level */
+
+ /**
+ * Code Rate for Low Priority level
+ */
FrontendDvbtCoderate lpCoderate;
+
FrontendDvbtGuardInterval guardInterval;
+
bool isHighPriority;
+
FrontendDvbtStandard standard;
+
bool isMiso;
+
FrontendDvbtPlpMode plpMode;
- /** Physical Layer Pipe (PLP) Id */
+
+ /**
+ * Physical Layer Pipe (PLP) Id
+ */
uint8_t plpId;
- /** Group Id for Physical Layer Pipe (PLP) */
+
+ /**
+ * Group Id for Physical Layer Pipe (PLP)
+ */
uint8_t plpGroupId;
};
@@ -636,12 +842,19 @@
*/
struct FrontendDvbtCapabilities {
bitfield<FrontendDvbtTransmissionMode> transmissionModeCap;
+
bitfield<FrontendDvbtBandwidth> bandwidthCap;
+
bitfield<FrontendDvbtConstellation> constellationCap;
+
bitfield<FrontendDvbtCoderate> coderateCap;
+
bitfield<FrontendDvbtHierarchy> hierarchyCap;
+
bitfield<FrontendDvbtGuardInterval> guardIntervalCap;
+
bool isT2Supported;
+
bool isMisoSupported;
};
@@ -660,11 +873,13 @@
@export
enum FrontendIsdbsModulation : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set Modulation automatically */
- AUTO = 1 << 0,
- MOD_BPSK = 1 << 1,
- MOD_QPSK = 1 << 2,
- MOD_TC8PSK = 1 << 3,
+ /**
+ * hardware is able to detect and set Modulation automatically
+ */
+ AUTO = 1 << 0,
+ MOD_BPSK = 1 << 1,
+ MOD_QPSK = 1 << 2,
+ MOD_TC8PSK = 1 << 3,
};
/**
@@ -673,13 +888,15 @@
@export
enum FrontendIsdbsCoderate : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set Code Rate automatically */
- AUTO = 1 << 0,
- CODERATE_1_2 = 1 << 1,
- CODERATE_2_3 = 1 << 2,
- CODERATE_3_4 = 1 << 3,
- CODERATE_5_6 = 1 << 4,
- CODERATE_7_8 = 1 << 5,
+ /**
+ * hardware is able to detect and set Code Rate automatically
+ */
+ AUTO = 1 << 0,
+ CODERATE_1_2 = 1 << 1,
+ CODERATE_2_3 = 1 << 2,
+ CODERATE_3_4 = 1 << 3,
+ CODERATE_5_6 = 1 << 4,
+ CODERATE_7_8 = 1 << 5,
};
/**
@@ -692,17 +909,27 @@
};
/**
- * Signal Setting for ISDBS Frontend.
+ * Signal Settings for ISDBS Frontend.
*/
struct FrontendIsdbsSettings {
- /** Signal frequency in Hertz */
+ /**
+ * Signal frequency in Hertz
+ */
uint32_t frequency;
+
uint16_t streamId;
+
FrontendIsdbsStreamIdType streamIdType;
+
FrontendIsdbsModulation modulation;
+
FrontendIsdbsCoderate coderate;
- /** Symbols per second */
+
+ /**
+ * Symbols per second
+ */
uint32_t symbolRate;
+
FrontendIsdbsRolloff rolloff;
};
@@ -711,6 +938,7 @@
*/
struct FrontendIsdbsCapabilities {
bitfield<FrontendIsdbsModulation> modulationCap;
+
bitfield<FrontendIsdbsCoderate> coderateCap;
};
@@ -729,13 +957,15 @@
@export
enum FrontendIsdbs3Modulation : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set Modulation automatically */
- AUTO = 1 << 5,
- MOD_BPSK = 1 << 1,
- MOD_QPSK = 1 << 2,
- MOD_8PSK = 1 << 3,
- MOD_16APSK = 1 << 4,
- MOD_32APSK = 1 << 5,
+ /**
+ * hardware is able to detect and set Modulation automatically
+ */
+ AUTO = 1 << 5,
+ MOD_BPSK = 1 << 1,
+ MOD_QPSK = 1 << 2,
+ MOD_8PSK = 1 << 3,
+ MOD_16APSK = 1 << 4,
+ MOD_32APSK = 1 << 5,
};
/**
@@ -744,33 +974,45 @@
@export
enum FrontendIsdbs3Coderate : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set Code Rate automatically */
- AUTO = 1 << 0,
- CODERATE_1_3 = 1 << 1,
- CODERATE_2_5 = 1 << 2,
- CODERATE_1_2 = 1 << 3,
- CODERATE_3_5 = 1 << 4,
- CODERATE_2_3 = 1 << 5,
- CODERATE_3_4 = 1 << 6,
- CODERATE_7_9 = 1 << 7,
- CODERATE_4_5 = 1 << 8,
- CODERATE_5_6 = 1 << 9,
- CODERATE_7_8 = 1 << 10,
- CODERATE_9_10 = 1 << 11,
+ /**
+ * hardware is able to detect and set Code Rate automatically
+ */
+ AUTO = 1 << 0,
+ CODERATE_1_3 = 1 << 1,
+ CODERATE_2_5 = 1 << 2,
+ CODERATE_1_2 = 1 << 3,
+ CODERATE_3_5 = 1 << 4,
+ CODERATE_2_3 = 1 << 5,
+ CODERATE_3_4 = 1 << 6,
+ CODERATE_7_9 = 1 << 7,
+ CODERATE_4_5 = 1 << 8,
+ CODERATE_5_6 = 1 << 9,
+ CODERATE_7_8 = 1 << 10,
+ CODERATE_9_10 = 1 << 11,
};
/**
- * Signal Setting for ISDBS3 Frontend.
+ * Signal Settings for ISDBS3 Frontend.
*/
struct FrontendIsdbs3Settings {
- /** Signal frequency in Hertz */
+ /**
+ * Signal frequency in Hertz
+ */
uint32_t frequency;
+
uint16_t streamId;
+
FrontendIsdbsStreamIdType streamIdType;
+
FrontendIsdbs3Modulation modulation;
+
FrontendIsdbs3Coderate coderate;
- /** Symbols per second */
+
+ /**
+ * Symbols per second
+ */
uint32_t symbolRate;
+
FrontendIsdbs3Rolloff rolloff;
};
@@ -779,6 +1021,7 @@
*/
struct FrontendIsdbs3Capabilities {
bitfield<FrontendIsdbs3Modulation> modulationCap;
+
bitfield<FrontendIsdbs3Coderate> coderateCap;
};
@@ -788,7 +1031,9 @@
@export
enum FrontendIsdbtMode : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set Mode automatically */
+ /**
+ * hardware is able to detect and set Mode automatically
+ */
AUTO = 1 << 0,
MODE_1 = 1 << 1,
MODE_2 = 1 << 2,
@@ -801,7 +1046,9 @@
@export
enum FrontendIsdbtBandwidth : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set Bandwidth automatically */
+ /**
+ * hardware is able to detect and set Bandwidth automatically
+ */
AUTO = 1 << 0,
BANDWIDTH_8MHZ = 1 << 1,
BANDWIDTH_7MHZ = 1 << 2,
@@ -814,7 +1061,9 @@
@export
enum FrontendIsdbtModulation : uint32_t {
UNDEFINED = 0,
- /** hardware is able to detect and set Modulation automatically */
+ /**
+ * hardware is able to detect and set Modulation automatically
+ */
AUTO = 1 << 0,
MOD_DQPSK = 1 << 1,
MOD_QPSK = 1 << 2,
@@ -822,23 +1071,29 @@
MOD_64QAM = 1 << 4,
};
-/** Code Rate for ISDBT. */
typedef FrontendDvbtCoderate FrontendIsdbtCoderate;
-/** Guard Interval for ISDBT. */
typedef FrontendDvbtGuardInterval FrontendIsdbtGuardInterval;
/**
- * Signal Setting for ISDBT Frontend.
+ * Signal Settings for ISDBT Frontend.
*/
struct FrontendIsdbtSettings {
- /** Signal frequency in Hertz */
+ /**
+ * Signal frequency in Hertz
+ */
uint32_t frequency;
+
FrontendIsdbtModulation modulation;
+
FrontendIsdbtBandwidth bandwidth;
+
FrontendIsdbtMode mode;
+
FrontendIsdbtCoderate coderate;
+
FrontendIsdbtGuardInterval guardInterval;
+
uint32_t serviceAreaId;
};
@@ -847,9 +1102,13 @@
*/
struct FrontendIsdbtCapabilities {
bitfield<FrontendIsdbtMode> modeCap;
+
bitfield<FrontendIsdbtBandwidth> bandwidthCap;
+
bitfield<FrontendIsdbtModulation> constellationCap;
+
bitfield<FrontendIsdbtCoderate> coderateCap;
+
bitfield<FrontendIsdbtGuardInterval> guardIntervalCap;
};
@@ -872,7 +1131,7 @@
UNDEFINED = 0,
BG = 1 << 0,
BG_A2 = 1 << 1,
- BG_NICAM = 1 << 2,
+ BG_NICAM = 1 << 2,
I = 1 << 3,
DK = 1 << 4,
DK1 = 1 << 5,
@@ -890,12 +1149,16 @@
};
/**
- * Signal Setting for Analog Frontend.
+ * Signal Settings for Analog Frontend.
*/
struct FrontendAnalogSettings {
- /** Signal frequency in Hertz */
+ /**
+ * Signal frequency in Hertz
+ */
uint32_t frequency;
+
FrontendAnalogType type;
+
FrontendAnalogSifStandard sifStandard;
};
@@ -904,21 +1167,30 @@
*/
struct FrontendAnalogCapabilities {
bitfield<FrontendAnalogType> typeCap;
+
bitfield<FrontendAnalogSifStandard> sifStandardCap;
};
/**
- * Signal Setting for Frontend.
+ * Signal Settings for Frontend.
*/
safe_union FrontendSettings {
FrontendAnalogSettings analog;
+
FrontendAtscSettings atsc;
+
FrontendAtsc3Settings atsc3;
+
FrontendDvbsSettings dvbs;
+
FrontendDvbcSettings dvbc;
+
FrontendDvbtSettings dvbt;
+
FrontendIsdbsSettings isdbs;
+
FrontendIsdbs3Settings isdbs3;
+
FrontendIsdbtSettings isdbt;
};
@@ -935,25 +1207,45 @@
* Scan Message Type for Frontend.
*/
enum FrontendScanMessageType : uint32_t {
- /** Scan locked the signal. */
+ /**
+ * Scan locked the signal.
+ */
LOCKED,
- /** Scan stopped. */
+ /**
+ * Scan stopped.
+ */
END,
- /** Scan progress report. */
+ /**
+ * Scan progress report.
+ */
PROGRESS_PERCENT,
- /** Locked frequency report. */
+ /**
+ * Locked frequency report.
+ */
FREQUENCY,
- /** Locked symbol rate. */
+ /**
+ * Locked symbol rate.
+ */
SYMBOL_RATE,
- /** Locked Plp Ids for DVBT2 frontend. */
+ /**
+ * Locked Plp Ids for DVBT2 frontend.
+ */
PLP_IDS,
- /** Locked group Ids for DVBT2 frontend. */
+ /**
+ * Locked group Ids for DVBT2 frontend.
+ */
GROUP_IDS,
- /** Stream Ids. */
+ /**
+ * Stream Ids.
+ */
INPUT_STREAM_IDS,
- /** Locked signal standard. */
+ /**
+ * Locked signal standard.
+ */
STANDARD,
- /** PLP status in a tuned frequency band for ATSC3 frontend. */
+ /**
+ * PLP status in a tuned frequency band for ATSC3 frontend.
+ */
ATSC3_PLP_INFO,
};
@@ -962,6 +1254,7 @@
*/
struct FrontendScanAtsc3PlpInfo {
uint8_t plpId;
+
bool bLlsFlag;
};
@@ -970,21 +1263,39 @@
*/
safe_union FrontendScanMessage {
bool isLocked;
+
bool isEnd;
- /** scan progress percent (0..100) */
+
+ /**
+ * scan progress percent (0..100)
+ */
uint8_t progressPercent;
- /** Signal frequency in Hertz */
+
+ /**
+ * Signal frequency in Hertz
+ */
uint32_t frequency;
- /** Symbols per second */
+
+ /**
+ * Symbols per second
+ */
uint32_t symbolRate;
+
vec<uint8_t> plpIds;
+
vec<uint8_t> groupIds;
+
vec<uint16_t> inputStreamIds;
+
safe_union standard {
FrontendDvbsStandard sStd;
+
FrontendDvbtStandard tStd;
} std;
- /** A list of PLP status in a tuned frequency band for ATSC3 frontend. */
+
+ /**
+ * A list of PLP status in a tuned frequency band for ATSC3 frontend.
+ */
vec<FrontendScanAtsc3PlpInfo> atsc3PlpInfos;
};
@@ -1008,22 +1319,6 @@
* event.
*/
LOST_LOCK,
- /**
- * If frontend detect that incoming Diseqc message is overflow.
- */
- DISEQC_RX_OVERFLOW,
- /**
- * If frontend detect that outgoing Diseqc message isn't delivered on time.
- */
- DISEQC_RX_TIMEOUT,
- /**
- * If frontend detect that the incoming Diseqc message has parity error.
- */
- DISEQC_RX_PARITY_ERROR,
- /**
- * If frontend detect that the LNB is overload.
- */
- LNB_OVERLOAD,
};
/**
@@ -1031,60 +1326,106 @@
*/
@export
enum FrontendStatusType : uint32_t {
- /** Lock status for Demod. */
+ /**
+ * Lock status for Demod.
+ */
DEMOD_LOCK,
- /** Signal to Noise Ratio. */
+ /**
+ * Signal to Noise Ratio.
+ */
SNR,
- /** Bit Error Ratio. */
+ /**
+ * Bit Error Ratio.
+ */
BER,
- /** Packages Error Ratio. */
+ /**
+ * Packages Error Ratio.
+ */
PER,
- /** Bit Error Ratio before FEC. */
+ /**
+ * Bit Error Ratio before FEC.
+ */
PRE_BER,
- /*
+ /**
* Signal Quality (0..100). Good data over total data in percent can be
* used as a way to present Signal Quality.
*/
SIGNAL_QUALITY,
- /** Signal Strength. */
+ /**
+ * Signal Strength.
+ */
SIGNAL_STRENGTH,
- /** Symbol Rate. */
+ /**
+ * Symbol Rate.
+ */
SYMBOL_RATE,
- /** Forward Error Correction Type. */
+ /**
+ * Forward Error Correction Type.
+ */
FEC,
- /** Modulation Type. */
+ /**
+ * Modulation Type.
+ */
MODULATION,
- /** Spectral Inversion Type. */
+ /**
+ * Spectral Inversion Type.
+ */
SPECTRAL,
- /** LNB Voltage. */
+ /**
+ * LNB Voltage.
+ */
LNB_VOLTAGE,
- /** Physical Layer Pipe ID. */
+ /**
+ * Physical Layer Pipe ID.
+ */
PLP_ID,
- /** Status for Emergency Warning Broadcasting System. */
+ /**
+ * Status for Emergency Warning Broadcasting System.
+ */
EWBS,
- /** Automatic Gain Control. */
+ /**
+ * Automatic Gain Control.
+ */
AGC,
- /** Low Noise Amplifier. */
+ /**
+ * Low Noise Amplifier.
+ */
LNA,
- /** Lock status for stream. */
- STREAM_LOCK,
- /** Error status by layer. */
+ /**
+ * Error status by layer.
+ */
LAYER_ERROR,
- /** CN value by VBER. */
+ /**
+ * CN value by VBER.
+ */
VBER_CN,
- /** CN value by LBER. */
+ /**
+ * CN value by LBER.
+ */
LBER_CN,
- /** CN value by XER. */
+ /**
+ * CN value by XER.
+ */
XER_CN,
- /** Moduration Error Ratio. */
+ /**
+ * Moduration Error Ratio.
+ */
MER,
- /** Difference between tuning frequency and actual locked frequency. */
+ /**
+ * Difference between tuning frequency and actual locked frequency.
+ */
FREQ_OFFSET,
- /* Hierarchy for DVBT. */
+ /**
+ * Hierarchy for DVBT.
+ */
HIERARCHY,
- /** Lock status for RF. */
+ /**
+ * Lock status for RF.
+ */
RF_LOCK,
- /** PLP information in a frequency band for ATSC3.0 frontend. */
+ /**
+ * PLP information in a frequency band for ATSC3.0 frontend.
+ */
ATSC3_PLP_INFO,
};
@@ -1092,23 +1433,34 @@
* Status for each tuning PLPs
*/
struct FrontendStatusAtsc3PlpInfo {
- /** PLP Id value. */
+ /**
+ * PLP Id value.
+ */
uint8_t plpId;
- /** Demod Lock/Unlock status of this particular PLP. */
+
+ /**
+ * Demod Lock/Unlock status of this particular PLP.
+ */
bool isLocked;
- /** Uncorrectable Error Counts (UEC) of this particular PLP since last tune operation. */
+
+ /**
+ * Uncorrectable Error Counts (UEC) of this particular PLP since last tune operation.
+ */
uint32_t uec;
};
-
/**
* Modulation Type for Frontend's status.
*/
safe_union FrontendModulationStatus {
FrontendDvbcModulation dvbc;
+
FrontendDvbsModulation dvbs;
+
FrontendIsdbsModulation isdbs;
+
FrontendIsdbs3Modulation isdbs3;
+
FrontendIsdbtModulation isdbt;
};
@@ -1116,46 +1468,99 @@
* The status for Frontend.
*/
safe_union FrontendStatus {
- /** Lock status for Demod in True/False. */
+ /**
+ * Lock status for Demod in True/False.
+ */
bool isDemodLocked;
- /** SNR value measured by 0.001 dB. */
+
+ /**
+ * SNR value measured by 0.001 dB.
+ */
int32_t snr;
- /** The number of error bit per 1 billion bits. */
+
+ /**
+ * The number of error bit per 1 billion bits.
+ */
uint32_t ber;
- /** The number of error package per 1 billion packages. */
+
+ /**
+ * The number of error package per 1 billion packages.
+ */
uint32_t per;
- /** The number of error bit per 1 billion bits before FEC. */
+
+ /**
+ * The number of error bit per 1 billion bits before FEC.
+ */
uint32_t preBer;
- /** Signal Quality in percent. */
+
+ /**
+ * Signal Quality in percent.
+ */
uint32_t signalQuality;
- /** Signal Strength measured by 0.001 dBm. */
+
+ /**
+ * Signal Strength measured by 0.001 dBm.
+ */
int32_t signalStrength;
- /** Symbols per second */
+
+ /**
+ * Symbols per second
+ */
uint32_t symbolRate;
+
FrontendInnerFec innerFec;
+
FrontendModulationStatus modulation;
+
FrontendDvbcSpectralInversion inversion;
- FrontendLnbVoltage lnbVoltage;
+
+ LnbVoltage lnbVoltage;
+
uint8_t plpId;
+
bool isEWBS;
- /** AGC value is normalized from 0 to 255. */
+
+ /**
+ * AGC value is normalized from 0 to 255.
+ */
uint8_t agc;
+
bool isLnaOn;
- bool isStreamLock;
+
vec<bool> isLayerError;
- /** CN value by VBER measured by 0.001 dB */
+
+ /**
+ * CN value by VBER measured by 0.001 dB
+ */
int32_t vberCn;
- /** CN value by LBER measured by 0.001 dB */
+
+ /**
+ * CN value by LBER measured by 0.001 dB
+ */
int32_t lberCn;
- /** CN value by XER measured by 0.001 dB */
+
+ /**
+ * CN value by XER measured by 0.001 dB
+ */
int32_t xerCn;
- /** MER value measured by 0.001 dB */
+
+ /**
+ * MER value measured by 0.001 dB
+ */
int32_t mer;
- /** Frequency difference in Hertz. */
+
+ /**
+ * Frequency difference in Hertz.
+ */
int32_t freqOffset;
+
FrontendDvbtHierarchy hierarchy;
+
bool isRfLocked;
- /** A list of PLP status for tuned PLPs for ATSC3 frontend. */
+
+ /**
+ * A list of PLP status for tuned PLPs for ATSC3 frontend.
+ */
vec<FrontendStatusAtsc3PlpInfo> plpInfo;
};
@@ -1164,32 +1569,60 @@
*/
struct FrontendInfo {
FrontendType type;
- /** Frequency in Hertz */
+
+ /**
+ * Frequency in Hertz
+ */
uint32_t minFrequency;
- /** Frequency in Hertz */
+
+ /**
+ * Frequency in Hertz
+ */
uint32_t maxFrequency;
- /** Minimum symbols per second */
+
+ /**
+ * Minimum symbols per second
+ */
uint32_t minSymbolRate;
- /** Maximum symbols per second */
+
+ /**
+ * Maximum symbols per second
+ */
uint32_t maxSymbolRate;
- /** Range in Hertz */
+
+ /**
+ * Range in Hertz
+ */
uint32_t acquireRange;
- /*
+
+ /**
* Frontends are assigned with the same exclusiveGroupId if they can't
* function at same time. For instance, they share same hardware module.
*/
uint32_t exclusiveGroupId;
- /** A list of supported status types which client can inquiry */
+
+ /**
+ * A list of supported status types which client can inquiry
+ */
vec<FrontendStatusType> statusCaps;
+
safe_union FrontendCapabilities {
FrontendAnalogCapabilities analogCaps;
+
FrontendAtscCapabilities atscCaps;
+
FrontendAtsc3Capabilities atsc3Caps;
+
FrontendDvbsCapabilities dvbsCaps;
+
FrontendDvbcCapabilities dvbcCaps;
+
FrontendDvbtCapabilities dvbtCaps;
+
FrontendIsdbsCapabilities isdbsCaps;
+
FrontendIsdbs3Capabilities isdbs3Caps;
+
FrontendIsdbtCapabilities isdbtCaps;
} frontendCaps;
};
@@ -1204,7 +1637,7 @@
* Power Voltage Type for LNB.
*/
@export
-enum FrontendLnbVoltage : uint32_t {
+enum LnbVoltage : uint32_t {
NONE,
VOLTAGE_5V,
VOLTAGE_11V,
@@ -1220,7 +1653,7 @@
* Tone Type for LNB.
*/
@export
-enum FrontendLnbTone : int32_t {
+enum LnbTone : int32_t {
NONE,
CONTINUOUS,
};
@@ -1229,41 +1662,92 @@
* The Position of LNB.
*/
@export
-enum FrontendLnbPosition : int32_t {
+enum LnbPosition : int32_t {
UNDEFINED,
POSITION_A,
POSITION_B,
};
+/**
+ * Lnb Event Type.
+ */
+@export
+enum LnbEventType : uint32_t {
+ DISEQC_RX_OVERFLOW,
+ /**
+ * If LNB detect that outgoing Diseqc message isn't delivered on time.
+ */
+ DISEQC_RX_TIMEOUT,
+ /**
+ * If LNB detect that the incoming Diseqc message has parity error.
+ */
+ DISEQC_RX_PARITY_ERROR,
+ /**
+ * If LNB detect that the LNB is overload.
+ */
+ LNB_OVERLOAD,
+};
+
/* 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
+ * Filter Main Type specifies the protocol that the filter use to extract data
+ * from input stream.
*/
@export
-enum DemuxFilterType : uint32_t {
+enum DemuxFilterMainType : uint32_t {
/**
- * A filter to filter section data out from input stream.
+ * Transport Stream according to ISO/IEC 13818-1.
+ */
+ TS = 1 << 0,
+ /**
+ * MPEG Media Transport Protocol according to ISO/IEC 23008-1.
+ */
+ MMTP = 1 << 1,
+ /**
+ * Internet Protocol.
+ */
+ IP = 1 << 2,
+ /**
+ * Type Length Value according to ITU-R BT.1869.
+ */
+ TLV = 1 << 3,
+ /**
+ * ATSC Link-Layer Protocol according to A/330 ATSC3.0.
+ */
+ ALP = 1 << 4,
+};
+
+/**
+ * TS Filter Type according to ISO/IEC 13818-1
+ */
+@export
+enum DemuxTsFilterType : uint32_t {
+ UNDEFINED,
+ /**
+ * A filter to filter Section data out from input stream, and queue the
+ * data to the filter's FMQ (Fast Message Queue).
*/
SECTION,
/**
- * A filter to filter PES data out from input stream.
+ * A filter to filter Packetized Elementary Stream data out from input
+ * stream, and queue the data to the filter's FMQ.
*/
PES,
/**
- * A filter to filter TS payload out from input stream.
+ * A filter to filter a Transport Stream out from input stream, and queue
+ * the data to the filter's FMQ.
*/
TS,
/**
- * A filter to filter Audio Metadata out from input stream.
+ * A filter to filter Audio data out from input stream, and send Audio's
+ * Metadata to client through onFilterEvent.
*/
AUDIO,
/**
- * A filter to filter Video Metadata out from input stream.
+ * A filter to filter Video data out from input stream, and send Video's
+ * Metadata to client through onFilterEvent.
*/
VIDEO,
/**
@@ -1271,20 +1755,172 @@
*/
PCR,
/**
- * A filter to filter data directly to output buffer for record.
+ * A filter to filter data out from input stream, and queue the data to the
+ * buffer of the record.
*/
RECORD,
};
+/**
+ * MMTP Filter Type according to ISO/IEC 23008-1
+ */
+@export
+enum DemuxMmtpFilterType : uint32_t {
+ UNDEFINED,
+ /**
+ * A filter to filter signaling data out from input stream, and queue the
+ * data to the filter's FMQ (Fast Message Queue).
+ */
+ SECTION,
+ /**
+ * A filter to filter MFU (Media fragment unit) out from input stream, and
+ * queue the data to the filter's FMQ.
+ */
+ PES,
+ /**
+ * A filter to filter a MMTP stream out from input stream, and queue the
+ * data to the filter's FMQ.
+ */
+ MMTP,
+ /**
+ * A filter to filter Audio data out from input stream, and send Audio's
+ * Metadata to client through onFilterEvent.
+ */
+ AUDIO,
+ /**
+ * A filter to filter Video data out from input stream, and send Video's
+ * Metadata to client through onFilterEvent.
+ */
+ VIDEO,
+ /**
+ * A filter to filter data out from input stream, and queue the data to the
+ * buffer of the record.
+ */
+ RECORD,
+ /**
+ * A filter to filter application data out from input stream, and queue the
+ * data to the filter's FMQ.
+ */
+ DOWNLOAD,
+};
+
+/**
+ * IP Filter Type.
+ */
+@export
+enum DemuxIpFilterType : uint32_t {
+ UNDEFINED,
+ /**
+ * A filter to filter section data out from input stream, and queue the
+ * data to the filter's FMQ (Fast Message Queue).
+ */
+ SECTION,
+ /**
+ * A filter to set NTP (Network Time Procotol) channel from input stream.
+ */
+ NTP,
+ /**
+ * A filter to strip out IP message header and queue the data to the
+ * filter's FMQ.
+ */
+ IP_PAYLOAD,
+ /**
+ * A filter to filter a IP stream out from input stream. The output can be
+ * either upper stream of another filter or queued to the filter's FMQ.
+ */
+ IP,
+ /**
+ * A filter to strip out IP message header and be a data source of another
+ * filter.
+ */
+ PAYLOAD_THROUGH,
+};
+
+/**
+ * TLV Filter Type according to ITU-R BT.1869.
+ */
+@export
+enum DemuxTlvFilterType : uint32_t {
+ UNDEFINED,
+ /**
+ * A filter to filter signaling data out from input stream, and queue the
+ * data to the filter's FMQ (Fast Message Queue).
+ */
+ SECTION,
+ /**
+ * A filter to filter a TLV stream out from input stream. The output can be
+ * either upper stream of another filter or queued to the filter's FMQ.
+ */
+ TLV,
+ /**
+ * A filter to strip out TLV message header and be a data source of another
+ * filter.
+ */
+ PAYLOAD_THROUGH,
+};
+
+/**
+ * ALP Filter Type according to A/330 ATSC3.0.
+ */
+@export
+enum DemuxAlpFilterType : uint32_t {
+ UNDEFINED,
+ /**
+ * A filter to filter signaling data out from input stream, and queue the
+ * data to the filter's FMQ (Fast Message Queue).
+ */
+ SECTION,
+ /**
+ * A filter to set PTP (Precision Time Protocol) channel from input stream.
+ */
+ PTP,
+ /**
+ * A filter to strip out ALP message header and be a data source of another
+ * filter.
+ */
+ PAYLOAD_THROUGH,
+};
+
+/**
+ * Demux Filter Type.
+ */
+struct DemuxFilterType {
+ DemuxFilterMainType mainType;
+
+ safe_union DemuxFilterSubType {
+ DemuxTsFilterType tsFilterType;
+
+ DemuxMmtpFilterType mmtpFilterType;
+
+ DemuxIpFilterType ipFilterType;
+
+ DemuxTlvFilterType tlvFilterType;
+
+ DemuxAlpFilterType alpFilterType;
+ } subType;
+};
+
/* Packet ID is used to specify packets in transport stream. */
typedef uint16_t DemuxTpid;
+/* Packet ID is used to specify packets in MMTP */
+typedef uint16_t DemuxMmtpPid;
+
+/**
+ * Demux Packet ID.
+ */
+safe_union DemuxPid {
+ DemuxTpid tPid;
+
+ DemuxMmtpPid mmtpPid;
+};
+
@export
enum Constant : uint16_t {
/**
* An invalid packet ID in transport stream according to ISO/IEC 13818-1.
*/
- INVALID_TPID = 0xFFFF,
+ INVALID_TS_PID = 0xFFFF,
/**
* An invalid Stream ID.
*/
@@ -1304,7 +1940,7 @@
* The available data amount in the filter buffer is at low level which is
* set to 25 percent by default.
*/
- LOW_WATER = 1 << 1,
+ LOW_WATER = 1 << 1,
/**
* The available data amount in the filter buffer is at high level which is
* set to 75 percent by default.
@@ -1314,18 +1950,122 @@
* The data in the filter buffer is full and newly filtered data is being
* discarded.
*/
- OVERFLOW = 1 << 3,
+ OVERFLOW = 1 << 3,
};
/**
- * Bits Setting for Section Filter.
+ * Indexes can be tagged through TS (Transport Stream) header.
+ */
+@export
+enum DemuxTsIndex : uint32_t {
+ FIRST_PACKET = 1 << 0,
+ PAYLOAD_UNIT_START_INDICATOR = 1 << 1,
+ CHANGE_TO_NOT_SCRAMBLED = 1 << 2,
+ CHANGE_TO_EVEN_SCRAMBLED = 1 << 3,
+ CHANGE_TO_ODD_SCRAMBLED = 1 << 4,
+ DISCONTINUITY_INDICATOR = 1 << 5,
+ RANDOM_ACCESS_INDICATOR = 1 << 6,
+ PRIORITY_INDICATOR = 1 << 7,
+ PCR_FLAG = 1 << 8,
+ OPCR_FLAG = 1 << 9,
+ SPLICING_POINT_FLAG = 1 << 10,
+ PRIVATE_DATA = 1 << 11,
+ ADAPTATION_EXTENSION_FLAG = 1 << 12,
+};
+
+/**
+ * Indexes can be tagged by Start Code in PES (Packetized Elementary Stream)
+ * according to ISO/IEC 13818-1.
+ */
+@export
+enum DemuxScIndex : uint32_t {
+ /**
+ * Start Code is for a new I Frame
+ */
+ I_FRAME = 1 << 0,
+ /**
+ * Start Code is for a new P Frame
+ */
+ P_FRAME = 1 << 1,
+ /**
+ * Start Code is for a new B Frame
+ */
+ B_FRAME = 1 << 2,
+ /**
+ * Start Code is for a new Sequence
+ */
+ SEQUENCE = 1 << 3,
+};
+
+/**
+ * Indexes can be tagged by NAL unit group in HEVC
+ * according to ISO/IEC 23008-2.
+ */
+@export
+enum DemuxScHevcIndex : uint32_t {
+ SPS = 1 << 0,
+ AUD = 1 << 1,
+ SLICE_CE_BLA_W_LP = 1 << 2,
+ SLICE_BLA_W_RADL = 1 << 3,
+ SLICE_BLA_N_LP = 1 << 4,
+ SLICE_IDR_W_RADL = 1 << 5,
+ SLICE_IDR_N_LP = 1 << 6,
+ SLICE_TRAIL_CRA = 1 << 7,
+};
+
+/**
+ * Index type to be used in the filter for record
+ */
+@export
+enum DemuxRecordIndexType : uint32_t {
+ /**
+ * Don't use index
+ */
+ NONE,
+ /**
+ * Use TS index
+ */
+ TS,
+ /**
+ * Use Start Code index
+ */
+ SC,
+ /**
+ * Use Start Code index for HEVC
+ */
+ SC_HEVC,
+};
+
+/**
+ * Filter Settings for Record data.
+ */
+struct DemuxFilterRecordSettings {
+ DemuxRecordIndexType indexType;
+
+ safe_union IndexMask {
+ bitfield<DemuxTsIndex> tsIndexMask;
+
+ bitfield<DemuxScIndex> scIndexMask;
+
+ bitfield<DemuxScHevcIndex> scHevcIndexMask;
+ } indexMask;
+};
+
+/**
+ * Bits Settings for Section Filter.
*/
struct DemuxFilterSectionBits {
- /* The bytes are configured for Section Filter */
+ /**
+ * The bytes are configured for Section Filter
+ */
vec<uint8_t> filter;
- /* Active bits in the configured bytes to be used for filtering */
+
+ /**
+ * Active bits in the configured bytes to be used for filtering
+ */
vec<uint8_t> mask;
- /*
+
+ /**
* Do positive match at the bit position of the configured bytes when the
* bit at same position of the mode is 0.
* Do negative match at the bit position of the configured bytes when the
@@ -1338,45 +2078,56 @@
* Filter Settings for Section data according to ISO/IEC 13818-1.
*/
struct DemuxFilterSectionSettings {
- DemuxTpid tpid;
- DemuxFilterSectionBits bits;
- /* Table ID for Section Filter */
- uint16_t tableId;
- /* Version number for Section Filter */
- uint16_t version;
- /* true if the filter checks CRC and discards data with wrong CRC */
+ safe_union Condition {
+ DemuxFilterSectionBits sectionBits;
+
+ struct TableInfo {
+ /**
+ * Table ID for Section Filter
+ */
+ uint16_t tableId;
+
+ /**
+ * Version number for Section Filter
+ */
+ uint16_t version;
+ } tableInfo;
+ } condition;
+
+ /**
+ * true if the filter checks CRC and discards data with wrong CRC
+ */
bool isCheckCrc;
- /* true if the filter repeats the data with the same version */
+
+ /**
+ * true if the filter repeats the data with the same version
+ */
bool isRepeat;
- /* true if the filter output raw data */
+
+ /**
+ * true if the filter send onFilterStatus instead of onFilterEvent.
+ */
bool isRaw;
};
-/* Stream ID is used to specify one elementary stream */
typedef uint16_t DemuxStreamId;
/**
* Filter Settings for a PES Data.
*/
struct DemuxFilterPesDataSettings {
- DemuxTpid tpid;
DemuxStreamId streamId;
- /* true if the filter output raw data */
+
+ /**
+ * true if the filter send onFilterStatus instead of onFilterEvent.
+ */
bool isRaw;
};
/**
- * Filter Settings for a TS Data.
+ * Filter Settings for a Video and Audio.
*/
-struct DemuxFilterTsSettings {
- DemuxTpid tpid;
-};
-
-/**
- * Filter Settings for a Audio.
- */
-struct DemuxFilterAudioSettings {
- DemuxTpid tpid;
+struct DemuxFilterAvSettings {
/**
* true if the filter output goes to decoder directly in pass through mode.
*/
@@ -1384,107 +2135,181 @@
};
/**
- * Filter Settings for a Video.
+ * Filter Settings for a Download.
*/
-struct DemuxFilterVideoSettings {
+struct DemuxFilterDownloadSettings {
+ uint32_t downloadId;
+};
+
+/**
+ * IP Settings for a IP filter.
+ */
+struct DemuxIpAddress {
+ safe_union SrcIpAddress {
+ uint8_t[4] v4;
+
+ uint8_t[16] v6;
+ } srcIpAddress;
+
+ safe_union DstIpAddress {
+ uint8_t[4] v4;
+
+ uint8_t[16] v6;
+ } dstIpAddress;
+
+ uint16_t srcPort;
+
+ uint16_t dstPort;
+};
+
+/**
+ * Filter Settings for a TS filter.
+ */
+struct DemuxTsFilterSettings {
DemuxTpid tpid;
+
+ safe_union FilterSettings {
+ /**
+ * Not additional parameters. it's used by PCR, TS subtype filters.
+ */
+ Monostate noinit;
+
+ DemuxFilterSectionSettings section;
+
+ DemuxFilterAvSettings av;
+
+ DemuxFilterPesDataSettings pesData;
+
+ DemuxFilterRecordSettings record;
+ } filterSettings;
+};
+
+/**
+ * Filter Settings for a MMTP filter.
+ */
+struct DemuxMmtpFilterSettings {
+ DemuxMmtpPid mmtpPid;
+
+ safe_union FilterSettings {
+ /**
+ * Not additional parameters. it's used by MMTP subtype filters.
+ */
+ Monostate noinit;
+
+ DemuxFilterSectionSettings section;
+
+ DemuxFilterAvSettings av;
+
+ DemuxFilterPesDataSettings pesData;
+
+ DemuxFilterRecordSettings record;
+
+ DemuxFilterDownloadSettings download;
+ } filterSettings;
+};
+
+/**
+ * Filter Settings for a IP filter.
+ */
+struct DemuxIpFilterSettings {
+ DemuxIpAddress ipAddr;
+
+ safe_union FilterSettings {
+ /**
+ * Not additional parameters. it's used by NTP, IP_PAYLOAD,
+ * PAYLOAD_THROUGH subtype filters.
+ */
+ Monostate noinit;
+
+ DemuxFilterSectionSettings section;
+
+ DemuxFilterPesDataSettings pesData;
+
+ /**
+ * true if the data from IP subtype go to next filter directly
+ */
+ bool bPassthrough;
+ } filterSettings;
+};
+
+/**
+ * Filter Settings for a TLV filter.
+ */
+struct DemuxTlvFilterSettings {
+ uint8_t packetType;
+
/**
- * true if the filter output goes to decoder directly in pass through mode.
+ * true if the filtered data is commpressed ip packet
*/
- bool isPassthrough;
+ bool bIsCompressedIpPacket;
+
+ safe_union FilterSettings {
+ /**
+ * Not additional parameters. it's used by PAYLOAD_THROUGH subtype
+ * filters.
+ */
+ Monostate noinit;
+
+ DemuxFilterSectionSettings section;
+
+ /**
+ * true if the data from TLV subtype go to next filter directly
+ */
+ bool bPassthrough;
+ } filterSettings;
};
/**
- * Filter Settings for a PCR (Program Clock Reference).
- */
-struct DemuxFilterPcrSettings {
- DemuxTpid tpid;
-};
-
-/**
- * Indexes can be tagged through TS (Transport Stream) header.
+ * ALP Length Type
*/
@export
-enum DemuxTsIndex : uint32_t {
- FIRST_PACKET = 1 << 0,
- PAYLOAD_UNIT_START_INDICATOR = 1 << 1,
- CHANGE_TO_NOT_SCRAMBLED = 1 << 2,
- CHANGE_TO_EVEN_SCRAMBLED = 1 << 3,
- CHANGE_TO_ODD_SCRAMBLED = 1 << 4,
- DISCONTINUITY_INDICATOR = 1 << 5,
- RANDOM_ACCESS_INDICATOR = 1 << 6,
- PRIORITY_INDICATOR = 1 << 7,
- PCR_FLAG = 1 << 8,
- OPCR_FLAG = 1 << 9,
- SPLICING_POINT_FLAG = 1 << 10,
- PRIVATE_DATA = 1 << 11,
- ADAPTATION_EXTENSION_FLAG = 1 << 12,
+enum DemuxAlpLengthType : uint8_t {
+ UNDEFINED = 0,
+ /**
+ * Length does NOT include additional header. Used in US region.
+ */
+ WITHOUT_ADDITIONAL_HEADER,
+ /**
+ * Length includes additional header. Used in Korea region.
+ */
+ WITH_ADDITIONAL_HEADER,
};
/**
- * A mask of TS indexes
- *
- * It's a combination of TS indexes.
+ * Filter Settings for a ALP filter.
*/
-typedef bitfield<DemuxTsIndex> DemuxTsIndexMask;
+struct DemuxAlpFilterSettings {
+ /**
+ * 0: IpV4, 2:Compressed Ip, 4:Signaling.
+ */
+ uint8_t packetType;
-/**
- * Indexes can be tagged by Start Code in PES (Packetized Elementary Stream)
- * according to ISO/IEC 13818-1.
- */
-@export
-enum DemuxScIndex : uint32_t {
- /* Start Code is for a new I Frame */
- I_FRAME = 1 << 0,
- /* Start Code is for a new P Frame */
- P_FRAME = 1 << 1,
- /* Start Code is for a new B Frame */
- B_FRAME = 1 << 2,
- /* Start Code is for a new Sequence */
- SEQUENCE = 1 << 3,
-};
+ DemuxAlpLengthType lengthType;
-/**
- * A mask of Start Code Indexes
- *
- * It's a combination of Start Code Indexes.
- */
-typedef bitfield<DemuxScIndex> DemuxScIndexMask;
+ safe_union FilterSettings {
+ /**
+ * Not additional parameters. it's used by PTP, PAYLOAD_THROUGH subtype
+ * filters.
+ */
+ Monostate noinit;
-/* Index type to be used in the filter for record */
-@export
-enum DemuxRecordIndexType : uint32_t {
- /* Don't use index */
- NONE,
- /* Use TS index */
- TS,
- /* Use Start Code index */
- SC,
-};
-
-/**
- * Filter Settings for Record data.
- */
-struct DemuxFilterRecordSettings {
- DemuxTpid tpid;
- DemuxRecordIndexType indexType;
- safe_union IndexMask {
- DemuxTsIndexMask tsIndexMask;
- DemuxScIndexMask scIndexMask;
- } indexMask;
+ DemuxFilterSectionSettings section;
+ } filterSettings;
};
/**
* Filter Settings.
*/
safe_union DemuxFilterSettings {
- DemuxFilterSectionSettings section;
- DemuxFilterPesDataSettings pesData;
- DemuxFilterTsSettings ts;
- DemuxFilterAudioSettings audio;
- DemuxFilterVideoSettings video;
- DemuxFilterPcrSettings pcr;
- DemuxFilterRecordSettings record;
+ DemuxTsFilterSettings ts;
+
+ DemuxMmtpFilterSettings mmtp;
+
+ DemuxIpFilterSettings ip;
+
+ DemuxTlvFilterSettings tlv;
+
+ DemuxAlpFilterSettings alp;
};
/**
@@ -1493,38 +2318,106 @@
*/
@export
enum DemuxQueueNotifyBits : uint32_t {
- /* client writes data and notify HAL the data is ready. */
+ /**
+ * client writes data and notify HAL the data is ready.
+ */
DATA_READY = 1 << 0,
- /* client reads data and notify HAL the data is consumed. */
- DATA_CONSUMED = 1 << 1
+ /**
+ * client reads data and notify HAL the data is consumed.
+ */
+ DATA_CONSUMED = 1 << 1,
};
/**
* Filter Event for Section Filter.
*/
struct DemuxFilterSectionEvent {
- /* Table ID of filtered data */
+ /**
+ * Table ID of filtered data
+ */
uint16_t tableId;
- /* Version number of filtered data */
+
+ /**
+ * Version number of filtered data
+ */
uint16_t version;
- /* Section number of filtered data */
+
+ /**
+ * Section number of filtered data
+ */
uint16_t sectionNum;
- /* Data size in bytes of filtered data */
+
+ /**
+ * Data size in bytes of filtered data
+ */
uint16_t dataLength;
};
/**
+ * Extra Meta Data from AD (Audio Descriptor) according to
+ * ETSI TS 101 154 V2.1.1.
+ */
+struct AudioExtraMetaData {
+ uint8_t adFade;
+
+ uint8_t adPan;
+
+ uint8_t versionTextTag;
+
+ uint8_t adGainCenter;
+
+ uint8_t adGainFront;
+
+ uint8_t adGainSurround;
+};
+
+/**
* Filter Event for Audio or Video Filter.
*/
struct DemuxFilterMediaEvent {
- /* Presentation Time Stamp for audio or video frame. It based on 90KHz has
+ DemuxStreamId streamId;
+
+ /**
+ * true if PTS is present in PES header.
+ */
+ bool isPtsPresent;
+
+ /**
+ * Presentation Time Stamp for audio or video frame. It based on 90KHz has
* the same format as PTS (Presentation Time Stamp).
*/
uint64_t pts;
- /* Data size in bytes of audio or video frame */
- uint16_t dataLength;
- /* A handle associated to the memory where audio or video data stays. */
- handle secureMemory;
+
+ /**
+ * Data size in bytes of audio or video frame
+ */
+ uint32_t dataLength;
+
+ /**
+ * A handle associated to the memory where audio or video data stays.
+ */
+ handle avMemory;
+
+ /**
+ * True if the avMemory is in secure area, and isn't mappable.
+ */
+ bool isSecureMemory;
+
+ /**
+ * MPU sequence number of filtered data (only for MMTP)
+ */
+ uint32_t mpuSequenceNumber;
+
+ bool isPesPrivateData;
+
+ safe_union ExtraMetaData {
+ /**
+ * Not additional parameters. it's used for video.
+ */
+ Monostate noinit;
+
+ AudioExtraMetaData audio;
+ } extraMetaData;
};
/**
@@ -1532,176 +2425,309 @@
*/
struct DemuxFilterPesEvent {
DemuxStreamId streamId;
- /* Data size in bytes of PES data */
+
+ /**
+ * Data size in bytes of PES data
+ */
+ uint16_t dataLength;
+
+ /**
+ * MPU sequence number of filtered data (only for MMTP)
+ */
+ uint32_t mpuSequenceNumber;
+};
+
+/**
+ * Filter Event for TS Record data.
+ */
+struct DemuxFilterTsRecordEvent {
+ DemuxPid pid;
+
+ /**
+ * Indexes of record output
+ */
+ safe_union IndexMask {
+ bitfield<DemuxTsIndex> tsIndexMask;
+
+ bitfield<DemuxScIndex> scIndexMask;
+
+ bitfield<DemuxScHevcIndex> scHevcIndexMask;
+ } indexMask;
+
+ /**
+ * Byte number from beginning of the filter's output
+ */
+ uint64_t byteNumber;
+};
+
+/**
+ * Filter Event for MMTP Record data.
+ */
+struct DemuxFilterMmtpRecordEvent {
+ bitfield<DemuxScHevcIndex> scHevcIndexMask;
+
+ /**
+ * Byte number from beginning of the filter's output
+ */
+ uint64_t byteNumber;
+};
+
+/**
+ * Filter Event for Download data.
+ */
+struct DemuxFilterDownloadEvent {
+ uint32_t itemId;
+
+ /**
+ * MPU sequence number of filtered data (only for MMTP)
+ */
+ uint32_t mpuSequenceNumber;
+
+ uint32_t itemFragmentIndex;
+
+ uint32_t lastItemFragmentIndex;
+
+ /**
+ * Data size in bytes of filtered data
+ */
uint16_t dataLength;
};
/**
- * Filter Event for Record data.
+ * Filter Event for IP payload data.
*/
-struct DemuxFilterRecordEvent {
- DemuxTpid tpid;
- /* Indexes of record output */
- safe_union IndexMask {
- DemuxTsIndexMask tsIndexMask;
- DemuxScIndexMask scIndexMask;
- } indexMask;
- /* Packet number from beginning of the filter's output */
- uint64_t packetNum;
+struct DemuxFilterIpPayloadEvent {
+ /**
+ * Data size in bytes of IP data
+ */
+ uint16_t dataLength;
};
/**
* Filter Event.
*/
struct DemuxFilterEvent {
- DemuxFilterId filterId;
- DemuxFilterType filterType;
safe_union Event {
DemuxFilterSectionEvent section;
+
DemuxFilterMediaEvent media;
+
DemuxFilterPesEvent pes;
- DemuxFilterRecordEvent ts;
+
+ DemuxFilterTsRecordEvent tsRecord;
+
+ DemuxFilterMmtpRecordEvent mmtpRecord;
+
+ DemuxFilterDownloadEvent download;
+
+ DemuxFilterIpPayloadEvent ipPayload;
};
- /* An array of events */
+
+ /**
+ * An array of events
+ */
vec<Event> events;
};
-/**
- * A hardware resource ID to be used for audio and video hardware sync.
- */
typedef uint32_t AvSyncHwId;
-/**
- * A token to be used to link descrambler and key slot. It's opaque to
- * framework and apps.
- */
typedef vec<uint8_t> TunerKeyToken;
/**
* A data format in demux's output or input according to ISO/IEC 13818-1.
*/
@export
-enum DemuxDataFormat : uint32_t {
- /* Data is Transport Stream. */
+enum DataFormat : uint32_t {
+ /**
+ * Data is Transport Stream.
+ */
TS,
- /* Data is Packetized Elementary Stream. */
+ /**
+ * Data is Packetized Elementary Stream.
+ */
PES,
- /* Data is Elementary Stream. */
+ /**
+ * Data is Elementary Stream.
+ */
ES,
- /* Data is TLV (type-length-value) Stream for JP SHV */
+ /**
+ * Data is TLV (type-length-value) Stream for JP SHV
+ */
SHV_TLV,
};
-/**
- * A status of the demux's output.
- */
-typedef DemuxFilterStatus DemuxOutputStatus;
+typedef DemuxFilterStatus RecordStatus;
/**
- * The Settings for the demux's output.
+ * The Settings for the record in DVR.
*/
-struct DemuxOutputSettings {
+struct RecordSettings {
/**
* Register for interested status events so that the HAL can send these
* status events back to client.
*/
- bitfield<DemuxOutputStatus> statusMask;
+ bitfield<RecordStatus> statusMask;
+
/**
- * Unconsumed data size in bytes in the output. The HAL uses it to trigger
- * DemuxOutputStatus::LOW_WATER.
+ * Unconsumed data size in bytes in the record. The HAL uses it to trigger
+ * OutputStatus::LOW_WATER.
*/
uint32_t lowThreshold;
+
/**
- * Unconsumed data size in bytes in the output. The HAL uses it to trigger
- * DemuxOutputStatus::High_WATER.
+ * Unconsumed data size in bytes in the record. The HAL uses it to trigger
+ * OutputStatus::High_WATER.
*/
uint32_t highThreshold;
+
/**
- * The data format in the output.
+ * The data format in the record.
*/
- DemuxDataFormat dataFormat;
+ DataFormat dataFormat;
+
/**
- * The packet size in bytes in the output.
+ * The packet size in bytes in the record.
*/
uint8_t packetSize;
};
/**
- * A status of the demux's input.
+ * A status of the playback in DVR.
*/
@export
-enum DemuxInputStatus : uint32_t {
+enum PlaybackStatus : uint32_t {
/**
- * The space of the demux's input is empty.
+ * The space of the demux's playback is empty.
*/
- SPACE_EMPTY = 1 << 0,
+ SPACE_EMPTY = 1 << 0,
/**
- * The spece of the demux's input is almost empty.
+ * The spece of the demux's playback is almost empty.
*/
SPACE_ALMOST_EMPTY = 1 << 1,
/**
- * The space of the demux's input is almost full.
+ * The space of the demux's playback is almost full.
*/
- SPACE_ALMOST_FULL = 1 << 2,
+ SPACE_ALMOST_FULL = 1 << 2,
/**
- * The space of the demux's input is full.
+ * The space of the demux's playback is full.
*/
- SPACE_FULL = 1 << 3,
+ SPACE_FULL = 1 << 3,
};
/**
- * The Settings for the demux's input.
+ * The Setting for the playback in DVR.
*/
-@export
-struct DemuxInputSettings {
+struct PlaybackSettings {
/**
* Register for interested status events so that the HAL can send these
* status events back to client.
*/
- bitfield<DemuxInputStatus> statusMask;
+ bitfield<PlaybackStatus> statusMask;
+
/**
- * Unused space size in bytes in the input. The HAL uses it to trigger
- * DemuxInputStatus::SPACE_ALMOST_EMPTY.
+ * Unused space size in bytes in the playback. The HAL uses it to trigger
+ * InputStatus::SPACE_ALMOST_EMPTY.
*/
uint32_t lowThreshold;
+
/**
- * Unused space size in bytes in the input. The HAL uses it to trigger
- * DemuxInputStatus::SPACE_ALMOST_FULL.
+ * Unused space size in bytes in the playback. The HAL uses it to trigger
+ * InputStatus::SPACE_ALMOST_FULL.
*/
uint32_t highThreshold;
+
/**
- * The data format in the input.
+ * The data format in the playback.
*/
- DemuxDataFormat dataFormat;
+ DataFormat dataFormat;
+
/**
- * The packet size in bytes in the input.
+ * The packet size in bytes in the playback.
*/
uint8_t packetSize;
};
/**
+ * The type of DVR.
+ */
+@export
+enum DvrType : uint8_t {
+ RECORD,
+ PLAYBACK,
+};
+
+/**
+ * The Setting for DVR.
+ */
+safe_union DvrSettings {
+ RecordSettings record;
+
+ PlaybackSettings playback;
+};
+
+/**
* Capabilities for Demux.
*/
-@export
struct DemuxCapabilities {
- /* The number of Demux to be supported. */
+ /**
+ * The number of Demux to be supported.
+ */
uint32_t numDemux;
- /* The number of Input to be supported. */
- uint32_t numInput;
- /* The number of Output to be supported. */
- uint32_t numOutput;
- /* The number of TS Filter to be supported. */
+
+ /**
+ * The number of record to be supported.
+ */
+ uint32_t numRecord;
+
+ /**
+ * The number of playback to be supported.
+ */
+ uint32_t numPlayback;
+
+ /**
+ * The number of TS Filter to be supported.
+ */
uint32_t numTsFilter;
- /* The number of Section Filter to be supported. */
+
+ /**
+ * The number of Section Filter to be supported.
+ */
uint32_t numSectionFilter;
- /* The number of Audio Filter to be supported. */
+
+ /**
+ * The number of Audio Filter to be supported.
+ */
uint32_t numAudioFilter;
- /* The number of Video Filter to be supported. */
+
+ /**
+ * The number of Video Filter to be supported.
+ */
uint32_t numVideoFilter;
- /* The number of PES Filter to be supported. */
+
+ /**
+ * The number of PES Filter to be supported.
+ */
uint32_t numPesFilter;
- /* The number of PCR Filter to be supported. */
+
+ /**
+ * The number of PCR Filter to be supported.
+ */
uint32_t numPcrFilter;
- /* The maximum number of bytes is supported in the mask of Section Filter. */
+
+ /**
+ * The maximum number of bytes is supported in the mask of Section Filter.
+ */
uint32_t numBytesInSectionFilter;
+
+ bitfield<DemuxFilterMainType> filterCaps;
+
+ /**
+ * The array has same elements as DemuxFilterMainType. linkCaps[i] presents
+ * filter's capability as soource for the ith type in DemuxFilterMainType.
+ * The jth bit of linkCaps[i] is 1 if the output of ith type filter can be
+ * data source for the filter type j.
+ */
+ vec<bitfield<DemuxFilterMainType>> linkCaps;
+
+ bool bTimeFilter;
};
diff --git a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
index 7936185..c666226 100644
--- a/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
+++ b/tv/tuner/1.0/vts/functional/VtsHalTvTunerV1_0TargetTest.cpp
@@ -20,8 +20,11 @@
#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/IDvr.h>
+#include <android/hardware/tv/tuner/1.0/IDvrCallback.h>
+#include <android/hardware/tv/tuner/1.0/IFilter.h>
+#include <android/hardware/tv/tuner/1.0/IFilterCallback.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>
@@ -57,8 +60,9 @@
using android::hardware::MQDescriptorSync;
using android::hardware::Return;
using android::hardware::Void;
-using android::hardware::tv::tuner::V1_0::DemuxDataFormat;
+using android::hardware::tv::tuner::V1_0::DataFormat;
using android::hardware::tv::tuner::V1_0::DemuxFilterEvent;
+using android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
using android::hardware::tv::tuner::V1_0::DemuxFilterPesDataSettings;
using android::hardware::tv::tuner::V1_0::DemuxFilterPesEvent;
using android::hardware::tv::tuner::V1_0::DemuxFilterSectionEvent;
@@ -66,10 +70,11 @@
using android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
using android::hardware::tv::tuner::V1_0::DemuxFilterStatus;
using android::hardware::tv::tuner::V1_0::DemuxFilterType;
-using android::hardware::tv::tuner::V1_0::DemuxInputSettings;
-using android::hardware::tv::tuner::V1_0::DemuxInputStatus;
-using android::hardware::tv::tuner::V1_0::DemuxOutputStatus;
using android::hardware::tv::tuner::V1_0::DemuxQueueNotifyBits;
+using android::hardware::tv::tuner::V1_0::DemuxTsFilterSettings;
+using android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
+using android::hardware::tv::tuner::V1_0::DvrSettings;
+using android::hardware::tv::tuner::V1_0::DvrType;
using android::hardware::tv::tuner::V1_0::FrontendAtscModulation;
using android::hardware::tv::tuner::V1_0::FrontendAtscSettings;
using android::hardware::tv::tuner::V1_0::FrontendDvbtSettings;
@@ -80,11 +85,17 @@
using android::hardware::tv::tuner::V1_0::FrontendScanMessageType;
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::IDvr;
+using android::hardware::tv::tuner::V1_0::IDvrCallback;
+using android::hardware::tv::tuner::V1_0::IFilter;
+using android::hardware::tv::tuner::V1_0::IFilterCallback;
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::PlaybackSettings;
+using android::hardware::tv::tuner::V1_0::PlaybackStatus;
+using android::hardware::tv::tuner::V1_0::RecordStatus;
using android::hardware::tv::tuner::V1_0::Result;
namespace {
@@ -131,17 +142,28 @@
0x73, 0x63, 0x65, 0x6e, 0x65,
};
-const uint16_t FMQ_SIZE_4K = 0x1000;
+// const uint16_t FMQ_SIZE_4K = 0x1000;
const uint32_t FMQ_SIZE_1M = 0x100000;
+const uint32_t FMQ_SIZE_16M = 0x1000000;
struct FilterConf {
DemuxFilterType type;
DemuxFilterSettings setting;
};
-struct InputConf {
+enum FilterEventType : uint8_t {
+ UNDEFINED,
+ SECTION,
+ MEDIA,
+ PES,
+ RECORD,
+ MMTPRECORD,
+ DOWNLOAD,
+};
+
+struct PlaybackConf {
string inputDataFile;
- DemuxInputSettings setting;
+ PlaybackSettings setting;
};
class FrontendCallback : public IFrontendCallback {
@@ -154,14 +176,6 @@
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();
- }
-
virtual Return<void> onScanMessage(FrontendScanMessageType /* type */,
const FrontendScanMessage& /* message */) override {
android::Mutex::Autolock autoLock(mMsgLock);
@@ -211,14 +225,14 @@
}
}
-class DemuxCallback : public IDemuxCallback {
+class FilterCallback : public IFilterCallback {
public:
virtual Return<void> onFilterEvent(const DemuxFilterEvent& filterEvent) override {
android::Mutex::Autolock autoLock(mMsgLock);
// Temprarily we treat the first coming back filter data on the matching pid a success
// once all of the MQ are cleared, means we got all the expected output
- mFilterIdToEvent[filterEvent.filterId] = filterEvent;
- readFilterEventData(filterEvent.filterId);
+ mFilterIdToEvent = filterEvent;
+ readFilterEventData();
mPidFilterOutputCount++;
// mFilterIdToMQ.erase(filterEvent.filterId);
@@ -227,96 +241,50 @@
return Void();
}
- virtual Return<void> onFilterStatus(uint32_t /*filterId*/,
- const DemuxFilterStatus /*status*/) override {
+ virtual Return<void> onFilterStatus(const DemuxFilterStatus /*status*/) override {
return Void();
}
- virtual Return<void> onOutputStatus(DemuxOutputStatus /*status*/) override { return Void(); }
+ void setFilterId(uint32_t filterId) { mFilterId = filterId; }
+ void setFilterEventType(FilterEventType type) { mFilterEventType = type; }
- virtual Return<void> onInputStatus(DemuxInputStatus status) override {
- // android::Mutex::Autolock autoLock(mMsgLock);
- ALOGW("[vts] input status %d", status);
- switch (status) {
- case DemuxInputStatus::SPACE_EMPTY:
- case DemuxInputStatus::SPACE_ALMOST_EMPTY:
- ALOGW("[vts] keep inputing %d", status);
- mKeepWritingInputFMQ = true;
- break;
- case DemuxInputStatus::SPACE_ALMOST_FULL:
- case DemuxInputStatus::SPACE_FULL:
- ALOGW("[vts] stop inputing %d", status);
- mKeepWritingInputFMQ = false;
- break;
- }
- return Void();
- }
-
- void testOnFilterEvent(uint32_t filterId);
void testFilterDataOutput();
- void stopInputThread();
- void startPlaybackInputThread(InputConf inputConf, MQDesc& inputMQDescriptor);
void startFilterEventThread(DemuxFilterEvent event);
- static void* __threadLoopInput(void* threadArgs);
static void* __threadLoopFilter(void* threadArgs);
- void inputThreadLoop(InputConf* inputConf, bool* keepWritingInputFMQ);
void filterThreadLoop(DemuxFilterEvent& event);
- void updateFilterMQ(uint32_t filterId, MQDesc& filterMQDescriptor);
- void updateGoldenOutputMap(uint32_t filterId, string goldenOutputFile);
- bool readFilterEventData(uint32_t filterId);
+ void updateFilterMQ(MQDesc& filterMQDescriptor);
+ void updateGoldenOutputMap(string goldenOutputFile);
+ bool readFilterEventData();
private:
- struct InputThreadArgs {
- DemuxCallback* user;
- InputConf* inputConf;
- bool* keepWritingInputFMQ;
- };
struct FilterThreadArgs {
- DemuxCallback* user;
+ FilterCallback* user;
DemuxFilterEvent event;
};
uint16_t mDataLength = 0;
std::vector<uint8_t> mDataOutputBuffer;
- bool mFilterEventReceived;
- std::map<uint32_t, string> mFilterIdToGoldenOutput;
+ string mFilterIdToGoldenOutput;
- std::map<uint32_t, std::unique_ptr<FilterMQ>> mFilterIdToMQ;
- std::unique_ptr<FilterMQ> mInputMQ;
- std::map<uint32_t, EventFlag*> mFilterIdToMQEventFlag;
- std::map<uint32_t, DemuxFilterEvent> mFilterIdToEvent;
- EventFlag* mInputMQEventFlag;
+ uint32_t mFilterId;
+ FilterEventType mFilterEventType;
+ std::unique_ptr<FilterMQ> mFilterIdToMQ;
+ EventFlag* mFilterIdToMQEventFlag;
+ DemuxFilterEvent mFilterIdToEvent;
android::Mutex mMsgLock;
android::Mutex mFilterOutputLock;
- android::Mutex mInputThreadLock;
android::Condition mMsgCondition;
android::Condition mFilterOutputCondition;
- bool mKeepWritingInputFMQ = true;
- bool mInputThreadRunning;
- pthread_t mInputThread;
pthread_t mFilterThread;
int mPidFilterOutputCount = 0;
};
-void DemuxCallback::startPlaybackInputThread(InputConf inputConf, MQDesc& inputMQDescriptor) {
- mInputMQ = std::make_unique<FilterMQ>(inputMQDescriptor, true /* resetPointers */);
- EXPECT_TRUE(mInputMQ);
- struct InputThreadArgs* threadArgs =
- (struct InputThreadArgs*)malloc(sizeof(struct InputThreadArgs));
- threadArgs->user = this;
- threadArgs->inputConf = &inputConf;
- threadArgs->keepWritingInputFMQ = &mKeepWritingInputFMQ;
-
- pthread_create(&mInputThread, NULL, __threadLoopInput, (void*)threadArgs);
- pthread_setname_np(mInputThread, "test_playback_input_loop");
-}
-
-void DemuxCallback::startFilterEventThread(DemuxFilterEvent event) {
+void FilterCallback::startFilterEventThread(DemuxFilterEvent event) {
struct FilterThreadArgs* threadArgs =
(struct FilterThreadArgs*)malloc(sizeof(struct FilterThreadArgs));
threadArgs->user = this;
@@ -326,7 +294,7 @@
pthread_setname_np(mFilterThread, "test_playback_input_loop");
}
-void DemuxCallback::testFilterDataOutput() {
+void FilterCallback::testFilterDataOutput() {
android::Mutex::Autolock autoLock(mMsgLock);
while (mPidFilterOutputCount < 1) {
if (-ETIMEDOUT == mMsgCondition.waitRelative(mMsgLock, WAIT_TIMEOUT)) {
@@ -338,95 +306,25 @@
ALOGW("[vts] pass and stop");
}
-void DemuxCallback::stopInputThread() {
- mInputThreadRunning = false;
- mKeepWritingInputFMQ = false;
-
- android::Mutex::Autolock autoLock(mInputThreadLock);
+void FilterCallback::updateFilterMQ(MQDesc& filterMQDescriptor) {
+ mFilterIdToMQ = std::make_unique<FilterMQ>(filterMQDescriptor, true /* resetPointers */);
+ EXPECT_TRUE(mFilterIdToMQ);
+ EXPECT_TRUE(EventFlag::createEventFlag(mFilterIdToMQ->getEventFlagWord(),
+ &mFilterIdToMQEventFlag) == android::OK);
}
-void DemuxCallback::updateFilterMQ(uint32_t filterId, MQDesc& filterMQDescriptor) {
- mFilterIdToMQ[filterId] =
- std::make_unique<FilterMQ>(filterMQDescriptor, true /* resetPointers */);
- EXPECT_TRUE(mFilterIdToMQ[filterId]);
- EXPECT_TRUE(EventFlag::createEventFlag(mFilterIdToMQ[filterId]->getEventFlagWord(),
- &mFilterIdToMQEventFlag[filterId]) == android::OK);
+void FilterCallback::updateGoldenOutputMap(string goldenOutputFile) {
+ mFilterIdToGoldenOutput = goldenOutputFile;
}
-void DemuxCallback::updateGoldenOutputMap(uint32_t filterId, string goldenOutputFile) {
- mFilterIdToGoldenOutput[filterId] = goldenOutputFile;
-}
-
-void* DemuxCallback::__threadLoopInput(void* threadArgs) {
- DemuxCallback* const self =
- static_cast<DemuxCallback*>(((struct InputThreadArgs*)threadArgs)->user);
- self->inputThreadLoop(((struct InputThreadArgs*)threadArgs)->inputConf,
- ((struct InputThreadArgs*)threadArgs)->keepWritingInputFMQ);
- return 0;
-}
-
-void DemuxCallback::inputThreadLoop(InputConf* inputConf, bool* keepWritingInputFMQ) {
- android::Mutex::Autolock autoLock(mInputThreadLock);
- mInputThreadRunning = true;
-
- // Create the EventFlag that is used to signal the HAL impl that data have been
- // written into the Input FMQ
- EventFlag* inputMQEventFlag;
- EXPECT_TRUE(EventFlag::createEventFlag(mInputMQ->getEventFlagWord(), &inputMQEventFlag) ==
- android::OK);
-
- // open the stream and get its length
- std::ifstream inputData(inputConf->inputDataFile, std::ifstream::binary);
- int writeSize = inputConf->setting.packetSize * 6;
- char* buffer = new char[writeSize];
- ALOGW("[vts] input thread loop start %s", inputConf->inputDataFile.c_str());
- if (!inputData.is_open()) {
- mInputThreadRunning = false;
- ALOGW("[vts] Error %s", strerror(errno));
- }
-
- while (mInputThreadRunning) {
- // move the stream pointer for packet size * 6 every read until the end
- while (*keepWritingInputFMQ) {
- inputData.read(buffer, writeSize);
- if (!inputData) {
- int leftSize = inputData.gcount();
- if (leftSize == 0) {
- mInputThreadRunning = false;
- break;
- }
- inputData.clear();
- inputData.read(buffer, leftSize);
- // Write the left over of the input data and quit the thread
- if (leftSize > 0) {
- EXPECT_TRUE(mInputMQ->write((unsigned char*)&buffer[0], leftSize));
- inputMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
- }
- mInputThreadRunning = false;
- break;
- }
- // Write input FMQ and notify the Tuner Implementation
- EXPECT_TRUE(mInputMQ->write((unsigned char*)&buffer[0], writeSize));
- inputMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
- inputData.seekg(writeSize, inputData.cur);
- sleep(1);
- }
- }
-
- ALOGW("[vts] Input thread end.");
-
- delete[] buffer;
- inputData.close();
-}
-
-void* DemuxCallback::__threadLoopFilter(void* threadArgs) {
- DemuxCallback* const self =
- static_cast<DemuxCallback*>(((struct FilterThreadArgs*)threadArgs)->user);
+void* FilterCallback::__threadLoopFilter(void* threadArgs) {
+ FilterCallback* const self =
+ static_cast<FilterCallback*>(((struct FilterThreadArgs*)threadArgs)->user);
self->filterThreadLoop(((struct FilterThreadArgs*)threadArgs)->event);
return 0;
}
-void DemuxCallback::filterThreadLoop(DemuxFilterEvent& /* event */) {
+void FilterCallback::filterThreadLoop(DemuxFilterEvent& /* event */) {
android::Mutex::Autolock autoLock(mFilterOutputLock);
// Read from mFilterIdToMQ[event.filterId] per event and filter type
@@ -439,30 +337,184 @@
// end thread
}
-bool DemuxCallback::readFilterEventData(uint32_t filterId) {
+bool FilterCallback::readFilterEventData() {
bool result = false;
- DemuxFilterEvent filterEvent = mFilterIdToEvent[filterId];
- ALOGW("[vts] reading from filter FMQ %d", filterId);
+ DemuxFilterEvent filterEvent = mFilterIdToEvent;
+ ALOGW("[vts] reading from filter FMQ %d", mFilterId);
// todo separate filter handlers
for (int i = 0; i < filterEvent.events.size(); i++) {
- DemuxFilterPesEvent event = filterEvent.events[i].pes();
- mDataLength = event.dataLength;
+ switch (mFilterEventType) {
+ case FilterEventType::SECTION:
+ mDataLength = filterEvent.events[i].section().dataLength;
+ break;
+ case FilterEventType::PES:
+ mDataLength = filterEvent.events[i].pes().dataLength;
+ break;
+ case FilterEventType::MEDIA:
+ break;
+ case FilterEventType::RECORD:
+ break;
+ case FilterEventType::MMTPRECORD:
+ break;
+ case FilterEventType::DOWNLOAD:
+ break;
+ default:
+ break;
+ }
// EXPECT_TRUE(mDataLength == goldenDataOutputBuffer.size()) << "buffer size does not
// match";
mDataOutputBuffer.resize(mDataLength);
- result = mFilterIdToMQ[filterId]->read(mDataOutputBuffer.data(), mDataLength);
+ result = mFilterIdToMQ->read(mDataOutputBuffer.data(), mDataLength);
EXPECT_TRUE(result) << "can't read from Filter MQ";
/*for (int i = 0; i < mDataLength; i++) {
EXPECT_TRUE(goldenDataOutputBuffer[i] == mDataOutputBuffer[i]) << "data does not match";
}*/
}
- mFilterIdToMQEventFlag[filterId]->wake(
- static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
+ mFilterIdToMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_CONSUMED));
return result;
}
+class DvrCallback : public IDvrCallback {
+ public:
+ virtual Return<void> onRecordStatus(RecordStatus /*status*/) override { return Void(); }
+
+ virtual Return<void> onPlaybackStatus(PlaybackStatus status) override {
+ // android::Mutex::Autolock autoLock(mMsgLock);
+ ALOGW("[vts] playback status %d", status);
+ switch (status) {
+ case PlaybackStatus::SPACE_EMPTY:
+ case PlaybackStatus::SPACE_ALMOST_EMPTY:
+ ALOGW("[vts] keep playback inputing %d", status);
+ mKeepWritingPlaybackFMQ = true;
+ break;
+ case PlaybackStatus::SPACE_ALMOST_FULL:
+ case PlaybackStatus::SPACE_FULL:
+ ALOGW("[vts] stop playback inputing %d", status);
+ mKeepWritingPlaybackFMQ = false;
+ break;
+ }
+ return Void();
+ }
+
+ void testFilterDataOutput();
+ void stopPlaybackThread();
+
+ void startPlaybackInputThread(PlaybackConf playbackConf, MQDesc& playbackMQDescriptor);
+ static void* __threadLoopPlayback(void* threadArgs);
+ void playbackThreadLoop(PlaybackConf* playbackConf, bool* keepWritingPlaybackFMQ);
+
+ private:
+ struct PlaybackThreadArgs {
+ DvrCallback* user;
+ PlaybackConf* playbackConf;
+ bool* keepWritingPlaybackFMQ;
+ };
+ uint16_t mDataLength = 0;
+ std::vector<uint8_t> mDataOutputBuffer;
+
+ std::map<uint32_t, std::unique_ptr<FilterMQ>> mFilterIdToMQ;
+ std::unique_ptr<FilterMQ> mPlaybackMQ;
+ std::map<uint32_t, EventFlag*> mFilterIdToMQEventFlag;
+ std::map<uint32_t, DemuxFilterEvent> mFilterIdToEvent;
+ EventFlag* mPlaybackMQEventFlag;
+
+ android::Mutex mMsgLock;
+ android::Mutex mPlaybackThreadLock;
+ android::Condition mMsgCondition;
+
+ bool mKeepWritingPlaybackFMQ = true;
+ bool mPlaybackThreadRunning;
+ pthread_t mPlaybackThread;
+
+ int mPidFilterOutputCount = 0;
+};
+
+void DvrCallback::startPlaybackInputThread(PlaybackConf playbackConf,
+ MQDesc& playbackMQDescriptor) {
+ mPlaybackMQ = std::make_unique<FilterMQ>(playbackMQDescriptor, true /* resetPointers */);
+ EXPECT_TRUE(mPlaybackMQ);
+ struct PlaybackThreadArgs* threadArgs =
+ (struct PlaybackThreadArgs*)malloc(sizeof(struct PlaybackThreadArgs));
+ threadArgs->user = this;
+ threadArgs->playbackConf = &playbackConf;
+ threadArgs->keepWritingPlaybackFMQ = &mKeepWritingPlaybackFMQ;
+
+ pthread_create(&mPlaybackThread, NULL, __threadLoopPlayback, (void*)threadArgs);
+ pthread_setname_np(mPlaybackThread, "test_playback_input_loop");
+}
+
+void DvrCallback::stopPlaybackThread() {
+ mPlaybackThreadRunning = false;
+ mKeepWritingPlaybackFMQ = false;
+
+ android::Mutex::Autolock autoLock(mPlaybackThreadLock);
+}
+
+void* DvrCallback::__threadLoopPlayback(void* threadArgs) {
+ DvrCallback* const self =
+ static_cast<DvrCallback*>(((struct PlaybackThreadArgs*)threadArgs)->user);
+ self->playbackThreadLoop(((struct PlaybackThreadArgs*)threadArgs)->playbackConf,
+ ((struct PlaybackThreadArgs*)threadArgs)->keepWritingPlaybackFMQ);
+ return 0;
+}
+
+void DvrCallback::playbackThreadLoop(PlaybackConf* playbackConf, bool* keepWritingPlaybackFMQ) {
+ android::Mutex::Autolock autoLock(mPlaybackThreadLock);
+ mPlaybackThreadRunning = true;
+
+ // Create the EventFlag that is used to signal the HAL impl that data have been
+ // written into the Playback FMQ
+ EventFlag* playbackMQEventFlag;
+ EXPECT_TRUE(EventFlag::createEventFlag(mPlaybackMQ->getEventFlagWord(), &playbackMQEventFlag) ==
+ android::OK);
+
+ // open the stream and get its length
+ std::ifstream inputData(playbackConf->inputDataFile, std::ifstream::binary);
+ int writeSize = playbackConf->setting.packetSize * 6;
+ char* buffer = new char[writeSize];
+ ALOGW("[vts] playback thread loop start %s", playbackConf->inputDataFile.c_str());
+ if (!inputData.is_open()) {
+ mPlaybackThreadRunning = false;
+ ALOGW("[vts] Error %s", strerror(errno));
+ }
+
+ while (mPlaybackThreadRunning) {
+ // move the stream pointer for packet size * 6 every read until the end
+ while (*keepWritingPlaybackFMQ) {
+ inputData.read(buffer, writeSize);
+ if (!inputData) {
+ int leftSize = inputData.gcount();
+ if (leftSize == 0) {
+ mPlaybackThreadRunning = false;
+ break;
+ }
+ inputData.clear();
+ inputData.read(buffer, leftSize);
+ // Write the left over of the input data and quit the thread
+ if (leftSize > 0) {
+ EXPECT_TRUE(mPlaybackMQ->write((unsigned char*)&buffer[0], leftSize));
+ playbackMQEventFlag->wake(
+ static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
+ }
+ mPlaybackThreadRunning = false;
+ break;
+ }
+ // Write input FMQ and notify the Tuner Implementation
+ EXPECT_TRUE(mPlaybackMQ->write((unsigned char*)&buffer[0], writeSize));
+ playbackMQEventFlag->wake(static_cast<uint32_t>(DemuxQueueNotifyBits::DATA_READY));
+ inputData.seekg(writeSize, inputData.cur);
+ sleep(1);
+ }
+ }
+
+ ALOGW("[vts] Playback thread end.");
+
+ delete[] buffer;
+ inputData.close();
+}
+
// Test environment for Tuner HIDL HAL.
class TunerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
public:
@@ -494,16 +546,21 @@
sp<FrontendCallback> mFrontendCallback;
sp<IDescrambler> mDescrambler;
sp<IDemux> mDemux;
- sp<DemuxCallback> mDemuxCallback;
+ sp<IDvr> mDvr;
+ sp<IFilter> mFilter;
+ std::map<uint32_t, sp<IFilter>> mFilters;
+ std::map<uint32_t, sp<FilterCallback>> mFilterCallbacks;
+ sp<FilterCallback> mFilterCallback;
+ sp<DvrCallback> mDvrCallback;
MQDesc mFilterMQDescriptor;
- MQDesc mInputMQDescriptor;
+ MQDesc mPlaybackMQDescriptor;
vector<uint32_t> mUsedFilterIds;
uint32_t mDemuxId;
uint32_t mFilterId;
- pthread_t mInputThread;
- bool mInputThreadRunning;
+ pthread_t mPlaybackshread;
+ bool mPlaybackThreadRunning;
::testing::AssertionResult createFrontend(int32_t frontendId);
::testing::AssertionResult tuneFrontend(int32_t frontendId);
@@ -512,16 +569,16 @@
::testing::AssertionResult createDemux();
::testing::AssertionResult createDemuxWithFrontend(int32_t frontendId,
FrontendSettings settings);
- ::testing::AssertionResult getInputMQDescriptor();
- ::testing::AssertionResult addInputToDemux(DemuxInputSettings setting);
+ ::testing::AssertionResult getPlaybackMQDescriptor();
+ ::testing::AssertionResult addPlaybackToDemux(PlaybackSettings setting);
::testing::AssertionResult addFilterToDemux(DemuxFilterType type, DemuxFilterSettings setting);
- ::testing::AssertionResult getFilterMQDescriptor(const uint32_t filterId);
+ ::testing::AssertionResult getFilterMQDescriptor();
::testing::AssertionResult closeDemux();
::testing::AssertionResult createDescrambler();
::testing::AssertionResult closeDescrambler();
::testing::AssertionResult playbackDataFlowTest(vector<FilterConf> filterConf,
- InputConf inputConf,
+ PlaybackConf playbackConf,
vector<string> goldenOutputFiles);
::testing::AssertionResult broadcastDataFlowTest(vector<FilterConf> filterConf,
vector<string> goldenOutputFiles);
@@ -665,39 +722,43 @@
return ::testing::AssertionResult(status == Result::SUCCESS);
}
-::testing::AssertionResult TunerHidlTest::addInputToDemux(DemuxInputSettings setting) {
+::testing::AssertionResult TunerHidlTest::addPlaybackToDemux(PlaybackSettings setting) {
Result status;
if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
return ::testing::AssertionFailure();
}
- // Create demux callback
- if (!mDemuxCallback) {
- mDemuxCallback = new DemuxCallback();
- }
+ // Create dvr callback
+ mDvrCallback = new DvrCallback();
// Add playback input to the local demux
- status = mDemux->addInput(FMQ_SIZE_1M, mDemuxCallback);
+ mDemux->openDvr(DvrType::PLAYBACK, FMQ_SIZE_1M, mDvrCallback,
+ [&](Result result, const sp<IDvr>& dvr) {
+ mDvr = dvr;
+ status = result;
+ });
if (status != Result::SUCCESS) {
return ::testing::AssertionFailure();
}
- status = mDemux->configureInput(setting);
+ DvrSettings dvrSetting;
+ dvrSetting.playback(setting);
+ status = mDvr->configure(dvrSetting);
return ::testing::AssertionResult(status == Result::SUCCESS);
}
-::testing::AssertionResult TunerHidlTest::getInputMQDescriptor() {
+::testing::AssertionResult TunerHidlTest::getPlaybackMQDescriptor() {
Result status;
- if (!mDemux && createDemux() == ::testing::AssertionFailure()) {
+ if ((!mDemux && createDemux() == ::testing::AssertionFailure()) || !mDvr) {
return ::testing::AssertionFailure();
}
- mDemux->getInputQueueDesc([&](Result result, const MQDesc& inputMQDesc) {
- mInputMQDescriptor = inputMQDesc;
+ mDvr->getQueueDesc([&](Result result, const MQDesc& dvrMQDesc) {
+ mPlaybackMQDescriptor = dvrMQDesc;
status = result;
});
@@ -713,13 +774,20 @@
}
// Create demux callback
- if (!mDemuxCallback) {
- mDemuxCallback = new DemuxCallback();
- }
+ mFilterCallback = new FilterCallback();
// Add filter to the local demux
- mDemux->addFilter(type, FMQ_SIZE_4K, mDemuxCallback, [&](Result result, uint32_t filterId) {
- // TODO use a map to save all the filter id and FMQ
+ mDemux->openFilter(type, FMQ_SIZE_16M, mFilterCallback,
+ [&](Result result, const sp<IFilter>& filter) {
+ mFilter = filter;
+ status = result;
+ });
+
+ if (status != Result::SUCCESS) {
+ return ::testing::AssertionFailure();
+ }
+
+ mFilter->getId([&](Result result, uint32_t filterId) {
mFilterId = filterId;
status = result;
});
@@ -728,20 +796,64 @@
return ::testing::AssertionFailure();
}
+ mFilterCallback->setFilterId(mFilterId);
+
+ FilterEventType eventType = FilterEventType::UNDEFINED;
+ switch (type.mainType) {
+ case DemuxFilterMainType::TS:
+ switch (type.subType.tsFilterType()) {
+ case DemuxTsFilterType::UNDEFINED:
+ break;
+ case DemuxTsFilterType::SECTION:
+ eventType = FilterEventType::SECTION;
+ break;
+ case DemuxTsFilterType::PES:
+ eventType = FilterEventType::PES;
+ break;
+ case DemuxTsFilterType::TS:
+ break;
+ case DemuxTsFilterType::AUDIO:
+ case DemuxTsFilterType::VIDEO:
+ eventType = FilterEventType::MEDIA;
+ break;
+ case DemuxTsFilterType::PCR:
+ break;
+ case DemuxTsFilterType::RECORD:
+ eventType = FilterEventType::RECORD;
+ break;
+ }
+ break;
+ case DemuxFilterMainType::MMTP:
+ /*mmtpSettings*/
+ break;
+ case DemuxFilterMainType::IP:
+ /*ipSettings*/
+ break;
+ case DemuxFilterMainType::TLV:
+ /*tlvSettings*/
+ break;
+ case DemuxFilterMainType::ALP:
+ /*alpSettings*/
+ break;
+ default:
+ break;
+ }
+ mFilterCallback->setFilterEventType(eventType);
+
// Configure the filter
- status = mDemux->configureFilter(mFilterId, setting);
+ status = mFilter->configure(setting);
return ::testing::AssertionResult(status == Result::SUCCESS);
}
-::testing::AssertionResult TunerHidlTest::getFilterMQDescriptor(const uint32_t filterId) {
+::testing::AssertionResult TunerHidlTest::getFilterMQDescriptor() {
Result status;
- if (!mDemux) {
+ if (!mDemux || !mFilter) {
return ::testing::AssertionFailure();
}
- mDemux->getFilterQueueDesc(filterId, [&](Result result, const MQDesc& filterMQDesc) {
+ mFilter->getQueueDesc([&](Result result, const MQDesc& filterMQDesc) {
mFilterMQDescriptor = filterMQDesc;
status = result;
});
@@ -750,7 +862,8 @@
}
::testing::AssertionResult TunerHidlTest::playbackDataFlowTest(
- vector<FilterConf> filterConf, InputConf inputConf, vector<string> /*goldenOutputFiles*/) {
+ vector<FilterConf> filterConf, PlaybackConf playbackConf,
+ vector<string> /*goldenOutputFiles*/) {
Result status;
int filterIdsSize;
// Filter Configuration Module
@@ -758,45 +871,58 @@
if (addFilterToDemux(filterConf[i].type, filterConf[i].setting) ==
::testing::AssertionFailure() ||
// TODO use a map to save the FMQs/EvenFlags and pass to callback
- getFilterMQDescriptor(mFilterId) == ::testing::AssertionFailure()) {
+ getFilterMQDescriptor() == ::testing::AssertionFailure()) {
return ::testing::AssertionFailure();
}
filterIdsSize = mUsedFilterIds.size();
mUsedFilterIds.resize(filterIdsSize + 1);
mUsedFilterIds[filterIdsSize] = mFilterId;
- mDemuxCallback->updateFilterMQ(mFilterId, mFilterMQDescriptor);
- // mDemuxCallback->updateGoldenOutputMap(mFilterId, goldenOutputFiles[i]);
- status = mDemux->startFilter(mFilterId);
+ mFilters[mFilterId] = mFilter;
+ mFilterCallbacks[mFilterId] = mFilterCallback;
+ mFilterCallback->updateFilterMQ(mFilterMQDescriptor);
+ // mDemuxCallback->updateGoldenOutputMap(goldenOutputFiles[i]);
+ status = mFilter->start();
if (status != Result::SUCCESS) {
return ::testing::AssertionFailure();
}
}
// Playback Input Module
- DemuxInputSettings inputSetting = inputConf.setting;
- if (addInputToDemux(inputSetting) == ::testing::AssertionFailure() ||
- getInputMQDescriptor() == ::testing::AssertionFailure()) {
+ PlaybackSettings playbackSetting = playbackConf.setting;
+ if (addPlaybackToDemux(playbackSetting) == ::testing::AssertionFailure() ||
+ getPlaybackMQDescriptor() == ::testing::AssertionFailure()) {
return ::testing::AssertionFailure();
}
- mDemuxCallback->startPlaybackInputThread(inputConf, mInputMQDescriptor);
- status = mDemux->startInput();
+ for (int i = 0; i <= filterIdsSize; i++) {
+ if (mDvr->attachFilter(mFilters[mUsedFilterIds[i]]) != Result::SUCCESS) {
+ return ::testing::AssertionFailure();
+ }
+ }
+ mDvrCallback->startPlaybackInputThread(playbackConf, mPlaybackMQDescriptor);
+ status = mDvr->start();
if (status != Result::SUCCESS) {
return ::testing::AssertionFailure();
}
// Data Verify Module
- mDemuxCallback->testFilterDataOutput();
- mDemuxCallback->stopInputThread();
+ std::map<uint32_t, sp<FilterCallback>>::iterator it;
+ for (it = mFilterCallbacks.begin(); it != mFilterCallbacks.end(); it++) {
+ it->second->testFilterDataOutput();
+ }
+ mDvrCallback->stopPlaybackThread();
// Clean Up Module
for (int i = 0; i <= filterIdsSize; i++) {
- if (mDemux->stopFilter(mUsedFilterIds[i]) != Result::SUCCESS) {
+ if (mFilters[mUsedFilterIds[i]]->stop() != Result::SUCCESS) {
return ::testing::AssertionFailure();
}
}
- if (mDemux->stopInput() != Result::SUCCESS) {
+ if (mDvr->stop() != Result::SUCCESS) {
return ::testing::AssertionFailure();
}
+ mUsedFilterIds.clear();
+ mFilterCallbacks.clear();
+ mFilters.clear();
return closeDemux();
}
@@ -831,31 +957,39 @@
if (addFilterToDemux(filterConf[i].type, filterConf[i].setting) ==
::testing::AssertionFailure() ||
// TODO use a map to save the FMQs/EvenFlags and pass to callback
- getFilterMQDescriptor(mFilterId) == ::testing::AssertionFailure()) {
+ getFilterMQDescriptor() == ::testing::AssertionFailure()) {
return ::testing::AssertionFailure();
}
filterIdsSize = mUsedFilterIds.size();
mUsedFilterIds.resize(filterIdsSize + 1);
mUsedFilterIds[filterIdsSize] = mFilterId;
- mDemuxCallback->updateFilterMQ(mFilterId, mFilterMQDescriptor);
- status = mDemux->startFilter(mFilterId);
+ mFilters[mFilterId] = mFilter;
+ mFilterCallbacks[mFilterId] = mFilterCallback;
+ mFilterCallback->updateFilterMQ(mFilterMQDescriptor);
+ status = mFilter->start();
if (status != Result::SUCCESS) {
return ::testing::AssertionFailure();
}
}
// Data Verify Module
- mDemuxCallback->testFilterDataOutput();
+ std::map<uint32_t, sp<FilterCallback>>::iterator it;
+ for (it = mFilterCallbacks.begin(); it != mFilterCallbacks.end(); it++) {
+ it->second->testFilterDataOutput();
+ }
// Clean Up Module
for (int i = 0; i <= filterIdsSize; i++) {
- if (mDemux->stopFilter(mUsedFilterIds[i]) != Result::SUCCESS) {
+ if (mFilters[mUsedFilterIds[i]]->stop() != Result::SUCCESS) {
return ::testing::AssertionFailure();
}
}
if (mFrontend->stopTune() != Result::SUCCESS) {
return ::testing::AssertionFailure();
}
+ mUsedFilterIds.clear();
+ mFilterCallbacks.clear();
+ mFilters.clear();
return closeDemux();
}
@@ -992,7 +1126,7 @@
/*
* DATA FLOW TESTS
*/
-TEST_F(TunerHidlTest, PlaybackDataFlowWithPesFilterTest) {
+TEST_F(TunerHidlTest, PlaybackDataFlowWithSectionFilterTest) {
description("Feed ts data from playback and configure pes filter to get output");
// todo modulize the filter conf parser
@@ -1000,32 +1134,39 @@
filterConf.resize(1);
DemuxFilterSettings filterSetting;
- DemuxFilterPesDataSettings pesFilterSetting{
+ DemuxTsFilterSettings tsFilterSetting{
.tpid = 18,
};
- filterSetting.pesData(pesFilterSetting);
- FilterConf pesFilterConf{
- .type = DemuxFilterType::PES,
+ DemuxFilterSectionSettings sectionFilterSetting;
+ tsFilterSetting.filterSettings.section(sectionFilterSetting);
+ filterSetting.ts(tsFilterSetting);
+
+ DemuxFilterType type{
+ .mainType = DemuxFilterMainType::TS,
+ };
+ type.subType.tsFilterType(DemuxTsFilterType::SECTION);
+ FilterConf sectionFilterConf{
+ .type = type,
.setting = filterSetting,
};
- filterConf[0] = pesFilterConf;
+ filterConf[0] = sectionFilterConf;
- DemuxInputSettings inputSetting{
+ PlaybackSettings playbackSetting{
.statusMask = 0xf,
.lowThreshold = 0x1000,
.highThreshold = 0x07fff,
- .dataFormat = DemuxDataFormat::TS,
+ .dataFormat = DataFormat::TS,
.packetSize = 188,
};
- InputConf inputConf{
+ PlaybackConf playbackConf{
.inputDataFile = "/vendor/etc/test1.ts",
- .setting = inputSetting,
+ .setting = playbackSetting,
};
vector<string> goldenOutputFiles;
- ASSERT_TRUE(playbackDataFlowTest(filterConf, inputConf, goldenOutputFiles));
+ ASSERT_TRUE(playbackDataFlowTest(filterConf, playbackConf, goldenOutputFiles));
}
TEST_F(TunerHidlTest, BroadcastDataFlowWithPesFilterTest) {
@@ -1036,12 +1177,19 @@
filterConf.resize(1);
DemuxFilterSettings filterSetting;
- DemuxFilterPesDataSettings pesFilterSetting{
- .tpid = 18,
+ DemuxTsFilterSettings tsFilterSetting{
+ .tpid = 119,
};
- filterSetting.pesData(pesFilterSetting);
+ DemuxFilterPesDataSettings pesFilterSetting;
+ tsFilterSetting.filterSettings.pesData(pesFilterSetting);
+ filterSetting.ts(tsFilterSetting);
+
+ DemuxFilterType type{
+ .mainType = DemuxFilterMainType::TS,
+ };
+ type.subType.tsFilterType(DemuxTsFilterType::PES);
FilterConf pesFilterConf{
- .type = DemuxFilterType::PES,
+ .type = type,
.setting = filterSetting,
};
filterConf[0] = pesFilterConf;
diff --git a/vibrator/1.0/vts/functional/Android.bp b/vibrator/1.0/vts/functional/Android.bp
index 391d3d4..10ec2cb 100644
--- a/vibrator/1.0/vts/functional/Android.bp
+++ b/vibrator/1.0/vts/functional/Android.bp
@@ -19,6 +19,6 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalVibratorV1_0TargetTest.cpp"],
static_libs: ["android.hardware.vibrator@1.0"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp b/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp
index 6f8aa02..2aee338 100644
--- a/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp
+++ b/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp
@@ -21,8 +21,9 @@
#include <android/hardware/vibrator/1.0/types.h>
#include <unistd.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
using ::android::sp;
using ::android::hardware::hidl_enum_range;
@@ -35,27 +36,11 @@
#define EXPECT_OK(ret) EXPECT_TRUE((ret).isOk())
-// Test environment for Vibrator HIDL HAL.
-class VibratorHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static VibratorHidlEnvironment* Instance() {
- static VibratorHidlEnvironment* instance = new VibratorHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IVibrator>(); }
-
- private:
- VibratorHidlEnvironment() {}
-};
-
// The main test class for VIBRATOR HIDL HAL.
-class VibratorHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class VibratorHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- vibrator = ::testing::VtsHalHidlTargetTestBase::getService<IVibrator>(
- VibratorHidlEnvironment::Instance()->getServiceName<IVibrator>());
+ vibrator = IVibrator::getService(GetParam());
ASSERT_NE(vibrator, nullptr);
}
@@ -79,13 +64,13 @@
<< "Effects that return UNSUPPORTED_OPERATION must have a duration of zero";
}
-TEST_F(VibratorHidlTest, OnThenOffBeforeTimeout) {
+TEST_P(VibratorHidlTest, OnThenOffBeforeTimeout) {
EXPECT_EQ(Status::OK, vibrator->on(2000));
sleep(1);
EXPECT_EQ(Status::OK, vibrator->off());
}
-TEST_F(VibratorHidlTest, PerformEffect) {
+TEST_P(VibratorHidlTest, PerformEffect) {
vibrator->perform(Effect::CLICK, EffectStrength::MEDIUM, validatePerformEffect);
vibrator->perform(Effect::DOUBLE_CLICK, EffectStrength::LIGHT, validatePerformEffect);
}
@@ -93,7 +78,7 @@
/*
* Test to make sure effect values above the valid range are rejected.
*/
-TEST_F(VibratorHidlTest, PerformEffect_BadEffects_AboveValidRange) {
+TEST_P(VibratorHidlTest, PerformEffect_BadEffects_AboveValidRange) {
Effect effect = *std::prev(hidl_enum_range<Effect>().end());
Effect badEffect = static_cast<Effect>(static_cast<int32_t>(effect) + 1);
EXPECT_OK(vibrator->perform(badEffect, EffectStrength::LIGHT, validatePerformEffectBadInput));
@@ -102,7 +87,7 @@
/*
* Test to make sure effect values below the valid range are rejected.
*/
-TEST_F(VibratorHidlTest, PerformEffect_BadEffects_BelowValidRange) {
+TEST_P(VibratorHidlTest, PerformEffect_BadEffects_BelowValidRange) {
Effect effect = *hidl_enum_range<Effect>().begin();
Effect badEffect = static_cast<Effect>(static_cast<int32_t>(effect) - 1);
EXPECT_OK(vibrator->perform(badEffect, EffectStrength::LIGHT, validatePerformEffectBadInput));
@@ -111,7 +96,7 @@
/*
* Test to make sure strength values above the valid range are rejected.
*/
-TEST_F(VibratorHidlTest, PerformEffect_BadStrength_AboveValidRange) {
+TEST_P(VibratorHidlTest, PerformEffect_BadStrength_AboveValidRange) {
EffectStrength strength = *std::prev(hidl_enum_range<EffectStrength>().end());
EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) + 1);
EXPECT_OK(vibrator->perform(Effect::CLICK, badStrength, validatePerformEffectBadInput));
@@ -120,13 +105,13 @@
/*
* Test to make sure strength values below the valid range are rejected.
*/
-TEST_F(VibratorHidlTest, PerformEffect_BadStrength_BelowValidRange) {
+TEST_P(VibratorHidlTest, PerformEffect_BadStrength_BelowValidRange) {
EffectStrength strength = *hidl_enum_range<EffectStrength>().begin();
EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) - 1);
EXPECT_OK(vibrator->perform(Effect::CLICK, badStrength, validatePerformEffectBadInput));
}
-TEST_F(VibratorHidlTest, ChangeVibrationalAmplitude) {
+TEST_P(VibratorHidlTest, ChangeVibrationalAmplitude) {
if (vibrator->supportsAmplitudeControl()) {
EXPECT_EQ(Status::OK, vibrator->setAmplitude(1));
EXPECT_EQ(Status::OK, vibrator->on(2000));
@@ -137,23 +122,19 @@
}
}
-TEST_F(VibratorHidlTest, AmplitudeOutsideRangeFails) {
+TEST_P(VibratorHidlTest, AmplitudeOutsideRangeFails) {
if (vibrator->supportsAmplitudeControl()) {
EXPECT_EQ(Status::BAD_VALUE, vibrator->setAmplitude(0));
}
}
-TEST_F(VibratorHidlTest, SetAmplitudeReturnUnsupportedOperationIfNotSupported) {
+TEST_P(VibratorHidlTest, SetAmplitudeReturnUnsupportedOperationIfNotSupported) {
if (!vibrator->supportsAmplitudeControl()) {
EXPECT_EQ(Status::UNSUPPORTED_OPERATION, vibrator->setAmplitude(1));
}
}
-int main(int argc, char **argv) {
- ::testing::AddGlobalTestEnvironment(VibratorHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- VibratorHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, VibratorHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IVibrator::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/vibrator/1.1/vts/functional/Android.bp b/vibrator/1.1/vts/functional/Android.bp
index c65ff41..4cde350 100644
--- a/vibrator/1.1/vts/functional/Android.bp
+++ b/vibrator/1.1/vts/functional/Android.bp
@@ -22,6 +22,6 @@
"android.hardware.vibrator@1.0",
"android.hardware.vibrator@1.1",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/vibrator/1.1/vts/functional/VtsHalVibratorV1_1TargetTest.cpp b/vibrator/1.1/vts/functional/VtsHalVibratorV1_1TargetTest.cpp
index 3c3ebf2..da94308 100644
--- a/vibrator/1.1/vts/functional/VtsHalVibratorV1_1TargetTest.cpp
+++ b/vibrator/1.1/vts/functional/VtsHalVibratorV1_1TargetTest.cpp
@@ -16,11 +16,12 @@
#define LOG_TAG "vibrator_hidl_hal_test"
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <android-base/logging.h>
#include <android/hardware/vibrator/1.1/IVibrator.h>
#include <android/hardware/vibrator/1.1/types.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <unistd.h>
using ::android::sp;
@@ -34,27 +35,11 @@
#define EXPECT_OK(ret) EXPECT_TRUE((ret).isOk())
-// Test environment for Vibrator HIDL HAL.
-class VibratorHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static VibratorHidlEnvironment* Instance() {
- static VibratorHidlEnvironment* instance = new VibratorHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IVibrator>(); }
-
- private:
- VibratorHidlEnvironment() {}
-};
-
// The main test class for VIBRATOR HIDL HAL 1.1.
-class VibratorHidlTest_1_1 : public ::testing::VtsHalHidlTargetTestBase {
+class VibratorHidlTest_1_1 : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- vibrator = ::testing::VtsHalHidlTargetTestBase::getService<IVibrator>(
- VibratorHidlEnvironment::Instance()->getServiceName<IVibrator>());
+ vibrator = IVibrator::getService(GetParam());
ASSERT_NE(vibrator, nullptr);
}
@@ -80,7 +65,7 @@
<< "Effects that return UNSUPPORTED_OPERATION must have a duration of zero";
}
-TEST_F(VibratorHidlTest_1_1, PerformEffect_1_1) {
+TEST_P(VibratorHidlTest_1_1, PerformEffect_1_1) {
vibrator->perform_1_1(Effect_1_1::CLICK, EffectStrength::MEDIUM, validatePerformEffect);
vibrator->perform_1_1(Effect_1_1::TICK, EffectStrength::STRONG, validatePerformEffect);
}
@@ -88,7 +73,7 @@
/*
* Test to make sure effect values above the valid range are rejected.
*/
-TEST_F(VibratorHidlTest_1_1, PerformEffect_1_1_BadEffects_AboveValidRange) {
+TEST_P(VibratorHidlTest_1_1, PerformEffect_1_1_BadEffects_AboveValidRange) {
Effect_1_1 effect = *std::prev(hidl_enum_range<Effect_1_1>().end());
Effect_1_1 badEffect = static_cast<Effect_1_1>(static_cast<int32_t>(effect) + 1);
EXPECT_OK(
@@ -98,7 +83,7 @@
/*
* Test to make sure effect values below the valid range are rejected.
*/
-TEST_F(VibratorHidlTest_1_1, PerformEffect_1_1_BadEffects_BelowValidRange) {
+TEST_P(VibratorHidlTest_1_1, PerformEffect_1_1_BadEffects_BelowValidRange) {
Effect_1_1 effect = *hidl_enum_range<Effect_1_1>().begin();
Effect_1_1 badEffect = static_cast<Effect_1_1>(static_cast<int32_t>(effect) - 1);
EXPECT_OK(
@@ -108,7 +93,7 @@
/*
* Test to make sure strength values above the valid range are rejected.
*/
-TEST_F(VibratorHidlTest_1_1, PerformEffect_1_1_BadStrength_AboveValidRange) {
+TEST_P(VibratorHidlTest_1_1, PerformEffect_1_1_BadStrength_AboveValidRange) {
EffectStrength strength = *std::prev(hidl_enum_range<EffectStrength>().end());
EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) + 1);
EXPECT_OK(vibrator->perform_1_1(Effect_1_1::CLICK, badStrength, validatePerformEffectBadInput));
@@ -117,17 +102,13 @@
/*
* Test to make sure strength values below the valid range are rejected.
*/
-TEST_F(VibratorHidlTest_1_1, PerformEffect_1_1_BadStrength_BelowValidRange) {
+TEST_P(VibratorHidlTest_1_1, PerformEffect_1_1_BadStrength_BelowValidRange) {
EffectStrength strength = *hidl_enum_range<EffectStrength>().begin();
EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) - 1);
EXPECT_OK(vibrator->perform_1_1(Effect_1_1::CLICK, badStrength, validatePerformEffectBadInput));
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(VibratorHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- VibratorHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, VibratorHidlTest_1_1,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IVibrator::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/vibrator/1.2/vts/functional/Android.bp b/vibrator/1.2/vts/functional/Android.bp
index 1e3ec97..e7052f2 100644
--- a/vibrator/1.2/vts/functional/Android.bp
+++ b/vibrator/1.2/vts/functional/Android.bp
@@ -23,6 +23,6 @@
"android.hardware.vibrator@1.1",
"android.hardware.vibrator@1.2",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/vibrator/1.2/vts/functional/VtsHalVibratorV1_2TargetTest.cpp b/vibrator/1.2/vts/functional/VtsHalVibratorV1_2TargetTest.cpp
index d69695a..2058e85 100644
--- a/vibrator/1.2/vts/functional/VtsHalVibratorV1_2TargetTest.cpp
+++ b/vibrator/1.2/vts/functional/VtsHalVibratorV1_2TargetTest.cpp
@@ -16,12 +16,13 @@
#define LOG_TAG "vibrator_hidl_hal_test"
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <android-base/logging.h>
#include <android/hardware/vibrator/1.0/types.h>
#include <android/hardware/vibrator/1.2/IVibrator.h>
#include <android/hardware/vibrator/1.2/types.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <unistd.h>
using ::android::hardware::vibrator::V1_0::Status;
@@ -35,27 +36,11 @@
#define EXPECT_OK(ret) ASSERT_TRUE((ret).isOk())
-// Test environment for Vibrator HIDL HAL.
-class VibratorHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static VibratorHidlEnvironment* Instance() {
- static VibratorHidlEnvironment* instance = new VibratorHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IVibrator>(); }
-
- private:
- VibratorHidlEnvironment() {}
-};
-
// The main test class for VIBRATOR HIDL HAL 1.2.
-class VibratorHidlTest_1_2 : public ::testing::VtsHalHidlTargetTestBase {
+class VibratorHidlTest_1_2 : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- vibrator = ::testing::VtsHalHidlTargetTestBase::getService<IVibrator>(
- VibratorHidlEnvironment::Instance()->getServiceName<IVibrator>());
+ vibrator = IVibrator::getService(GetParam());
ASSERT_NE(vibrator, nullptr);
}
@@ -85,7 +70,7 @@
* Test to make sure effects within the valid range return are either supported and return OK with
* a valid duration, or are unsupported and return UNSUPPORTED_OPERATION with a duration of 0.
*/
-TEST_F(VibratorHidlTest_1_2, PerformEffect_1_2) {
+TEST_P(VibratorHidlTest_1_2, PerformEffect_1_2) {
for (const auto& effect : hidl_enum_range<Effect>()) {
for (const auto& strength : hidl_enum_range<EffectStrength>()) {
EXPECT_OK(vibrator->perform_1_2(effect, strength, validatePerformEffect));
@@ -96,7 +81,7 @@
/*
* Test to make sure effect values above the valid range are rejected.
*/
-TEST_F(VibratorHidlTest_1_2, PerformEffect_1_2_BadEffects_AboveValidRange) {
+TEST_P(VibratorHidlTest_1_2, PerformEffect_1_2_BadEffects_AboveValidRange) {
Effect effect = *std::prev(hidl_enum_range<Effect>().end());
Effect badEffect = static_cast<Effect>(static_cast<int32_t>(effect) + 1);
EXPECT_OK(
@@ -106,7 +91,7 @@
/*
* Test to make sure effect values below the valid range are rejected.
*/
-TEST_F(VibratorHidlTest_1_2, PerformEffect_1_2_BadEffects_BelowValidRange) {
+TEST_P(VibratorHidlTest_1_2, PerformEffect_1_2_BadEffects_BelowValidRange) {
Effect effect = *hidl_enum_range<Effect>().begin();
Effect badEffect = static_cast<Effect>(static_cast<int32_t>(effect) - 1);
EXPECT_OK(
@@ -116,7 +101,7 @@
/*
* Test to make sure strength values above the valid range are rejected.
*/
-TEST_F(VibratorHidlTest_1_2, PerformEffect_1_2_BadStrength_AboveValidRange) {
+TEST_P(VibratorHidlTest_1_2, PerformEffect_1_2_BadStrength_AboveValidRange) {
EffectStrength strength = *std::prev(hidl_enum_range<EffectStrength>().end());
EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) + 1);
EXPECT_OK(vibrator->perform_1_2(Effect::THUD, badStrength, validatePerformEffectBadInput));
@@ -125,17 +110,13 @@
/*
* Test to make sure strength values below the valid range are rejected.
*/
-TEST_F(VibratorHidlTest_1_2, PerformEffect_1_2_BadStrength_BelowValidRange) {
+TEST_P(VibratorHidlTest_1_2, PerformEffect_1_2_BadStrength_BelowValidRange) {
EffectStrength strength = *hidl_enum_range<EffectStrength>().begin();
EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) - 1);
EXPECT_OK(vibrator->perform_1_2(Effect::THUD, badStrength, validatePerformEffectBadInput));
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(VibratorHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- VibratorHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, VibratorHidlTest_1_2,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IVibrator::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/vibrator/1.3/vts/functional/Android.bp b/vibrator/1.3/vts/functional/Android.bp
index 5b4c893..038dc5c 100644
--- a/vibrator/1.3/vts/functional/Android.bp
+++ b/vibrator/1.3/vts/functional/Android.bp
@@ -24,6 +24,6 @@
"android.hardware.vibrator@1.2",
"android.hardware.vibrator@1.3",
],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/vibrator/1.3/vts/functional/VtsHalVibratorV1_3TargetTest.cpp b/vibrator/1.3/vts/functional/VtsHalVibratorV1_3TargetTest.cpp
index 818f9c7..3cd3430 100644
--- a/vibrator/1.3/vts/functional/VtsHalVibratorV1_3TargetTest.cpp
+++ b/vibrator/1.3/vts/functional/VtsHalVibratorV1_3TargetTest.cpp
@@ -16,11 +16,12 @@
#define LOG_TAG "vibrator_hidl_hal_test"
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <android-base/logging.h>
#include <android/hardware/vibrator/1.0/types.h>
#include <android/hardware/vibrator/1.3/IVibrator.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <unistd.h>
using ::android::sp;
@@ -34,27 +35,11 @@
#define EXPECT_OK(ret) ASSERT_TRUE((ret).isOk())
-// Test environment for Vibrator HIDL HAL.
-class VibratorHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static VibratorHidlEnvironment* Instance() {
- static VibratorHidlEnvironment* instance = new VibratorHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IVibrator>(); }
-
- private:
- VibratorHidlEnvironment() {}
-};
-
// The main test class for VIBRATOR HIDL HAL 1.3.
-class VibratorHidlTest_1_3 : public ::testing::VtsHalHidlTargetTestBase {
+class VibratorHidlTest_1_3 : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- vibrator = ::testing::VtsHalHidlTargetTestBase::getService<IVibrator>(
- VibratorHidlEnvironment::Instance()->getServiceName<IVibrator>());
+ vibrator = IVibrator::getService(GetParam());
ASSERT_NE(vibrator, nullptr);
}
@@ -63,7 +48,7 @@
sp<IVibrator> vibrator;
};
-TEST_F(VibratorHidlTest_1_3, ChangeVibrationalExternalControl) {
+TEST_P(VibratorHidlTest_1_3, ChangeVibrationalExternalControl) {
if (vibrator->supportsExternalControl()) {
EXPECT_EQ(Status::OK, vibrator->setExternalControl(true));
sleep(1);
@@ -72,7 +57,7 @@
}
}
-TEST_F(VibratorHidlTest_1_3, SetExternalControlReturnUnsupportedOperationIfNotSupported) {
+TEST_P(VibratorHidlTest_1_3, SetExternalControlReturnUnsupportedOperationIfNotSupported) {
if (!vibrator->supportsExternalControl()) {
EXPECT_EQ(Status::UNSUPPORTED_OPERATION, vibrator->setExternalControl(true));
}
@@ -98,7 +83,7 @@
* Test to make sure effects within the valid range return are either supported and return OK with
* a valid duration, or are unsupported and return UNSUPPORTED_OPERATION with a duration of 0.
*/
-TEST_F(VibratorHidlTest_1_3, PerformEffect_1_3) {
+TEST_P(VibratorHidlTest_1_3, PerformEffect_1_3) {
for (const auto& effect : hidl_enum_range<Effect>()) {
for (const auto& strength : hidl_enum_range<EffectStrength>()) {
EXPECT_OK(vibrator->perform_1_3(effect, strength, validatePerformEffect));
@@ -109,7 +94,7 @@
/*
* Test to make sure effect values above the valid range are rejected.
*/
-TEST_F(VibratorHidlTest_1_3, PerformEffect_1_3_BadEffects_AboveValidRange) {
+TEST_P(VibratorHidlTest_1_3, PerformEffect_1_3_BadEffects_AboveValidRange) {
Effect effect = *std::prev(hidl_enum_range<Effect>().end());
Effect badEffect = static_cast<Effect>(static_cast<int32_t>(effect) + 1);
EXPECT_OK(vibrator->perform_1_3(badEffect, EffectStrength::LIGHT,
@@ -119,7 +104,7 @@
/*
* Test to make sure effect values below the valid range are rejected.
*/
-TEST_F(VibratorHidlTest_1_3, PerformEffect_1_3_BadEffects_BelowValidRange) {
+TEST_P(VibratorHidlTest_1_3, PerformEffect_1_3_BadEffects_BelowValidRange) {
Effect effect = *hidl_enum_range<Effect>().begin();
Effect badEffect = static_cast<Effect>(static_cast<int32_t>(effect) - 1);
EXPECT_OK(vibrator->perform_1_3(badEffect, EffectStrength::LIGHT,
@@ -129,7 +114,7 @@
/*
* Test to make sure strength values above the valid range are rejected.
*/
-TEST_F(VibratorHidlTest_1_3, PerformEffect_1_3_BadStrength_AboveValidRange) {
+TEST_P(VibratorHidlTest_1_3, PerformEffect_1_3_BadStrength_AboveValidRange) {
EffectStrength strength = *std::prev(hidl_enum_range<EffectStrength>().end());
EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) + 1);
EXPECT_OK(vibrator->perform_1_3(Effect::THUD, badStrength,
@@ -139,18 +124,14 @@
/*
* Test to make sure strength values below the valid range are rejected.
*/
-TEST_F(VibratorHidlTest_1_3, PerformEffect_1_3_BadStrength_BelowValidRange) {
+TEST_P(VibratorHidlTest_1_3, PerformEffect_1_3_BadStrength_BelowValidRange) {
EffectStrength strength = *hidl_enum_range<EffectStrength>().begin();
EffectStrength badStrength = static_cast<EffectStrength>(static_cast<int32_t>(strength) - 1);
EXPECT_OK(vibrator->perform_1_3(Effect::THUD, badStrength,
validatePerformEffectUnsupportedOperation));
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(VibratorHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- VibratorHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, VibratorHidlTest_1_3,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IVibrator::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/vibrator/1.4/vts/functional/Android.bp b/vibrator/1.4/vts/functional/Android.bp
index 4cdf3b6..202a824 100644
--- a/vibrator/1.4/vts/functional/Android.bp
+++ b/vibrator/1.4/vts/functional/Android.bp
@@ -25,6 +25,9 @@
"android.hardware.vibrator@1.3",
"android.hardware.vibrator@1.4",
],
- test_suites: ["general-tests"],
+ test_suites: [
+ "general-tests",
+ "vts-core",
+ ],
}
diff --git a/weaver/1.0/vts/functional/Android.bp b/weaver/1.0/vts/functional/Android.bp
index 9fdbb18..3942deb 100644
--- a/weaver/1.0/vts/functional/Android.bp
+++ b/weaver/1.0/vts/functional/Android.bp
@@ -19,5 +19,5 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalWeaverV1_0TargetTest.cpp"],
static_libs: ["android.hardware.weaver@1.0"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/weaver/1.0/vts/functional/VtsHalWeaverV1_0TargetTest.cpp b/weaver/1.0/vts/functional/VtsHalWeaverV1_0TargetTest.cpp
index de2a1de..ae92c36 100644
--- a/weaver/1.0/vts/functional/VtsHalWeaverV1_0TargetTest.cpp
+++ b/weaver/1.0/vts/functional/VtsHalWeaverV1_0TargetTest.cpp
@@ -15,12 +15,12 @@
*/
#include <android/hardware/weaver/1.0/IWeaver.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <limits>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
-
using ::android::hardware::weaver::V1_0::IWeaver;
using ::android::hardware::weaver::V1_0::WeaverConfig;
using ::android::hardware::weaver::V1_0::WeaverReadStatus;
@@ -34,22 +34,9 @@
const std::vector<uint8_t> VALUE{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
const std::vector<uint8_t> OTHER_VALUE{0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 255, 255};
-// Test environment for Weaver HIDL HAL.
-class WeaverHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static WeaverHidlEnvironment* Instance() {
- static WeaverHidlEnvironment* instance = new WeaverHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override { registerTestService<IWeaver>(); }
-};
-
-struct WeaverHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+struct WeaverHidlTest : public ::testing::TestWithParam<std::string> {
virtual void SetUp() override {
- weaver = ::testing::VtsHalHidlTargetTestBase::getService<IWeaver>(
- WeaverHidlEnvironment::Instance()->getServiceName<IWeaver>());
+ weaver = IWeaver::getService(GetParam());
ASSERT_NE(weaver, nullptr);
}
@@ -61,7 +48,7 @@
/*
* Checks config values are suitably large
*/
-TEST_F(WeaverHidlTest, GetConfig) {
+TEST_P(WeaverHidlTest, GetConfig) {
WeaverStatus status;
WeaverConfig config;
@@ -83,7 +70,7 @@
/*
* Gets the config twice and checks they are the same
*/
-TEST_F(WeaverHidlTest, GettingConfigMultipleTimesGivesSameResult) {
+TEST_P(WeaverHidlTest, GettingConfigMultipleTimesGivesSameResult) {
WeaverConfig config1;
WeaverConfig config2;
@@ -114,7 +101,7 @@
/*
* Gets the number of slots from the config and writes a key and value to the last one
*/
-TEST_F(WeaverHidlTest, WriteToLastSlot) {
+TEST_P(WeaverHidlTest, WriteToLastSlot) {
WeaverStatus status;
WeaverConfig config;
const auto configRet = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
@@ -134,7 +121,7 @@
* Writes a key and value to a slot
* Reads the slot with the same key and receives the value that was previously written
*/
-TEST_F(WeaverHidlTest, WriteFollowedByReadGivesTheSameValue) {
+TEST_P(WeaverHidlTest, WriteFollowedByReadGivesTheSameValue) {
constexpr uint32_t slotId = 0;
const auto ret = weaver->write(slotId, KEY, VALUE);
ASSERT_TRUE(ret.isOk());
@@ -162,7 +149,7 @@
* Overwrites the slot with a new key and value
* Reads the slot with the new key and receives the new value
*/
-TEST_F(WeaverHidlTest, OverwritingSlotUpdatesTheValue) {
+TEST_P(WeaverHidlTest, OverwritingSlotUpdatesTheValue) {
constexpr uint32_t slotId = 0;
const auto initialWriteRet = weaver->write(slotId, WRONG_KEY, VALUE);
ASSERT_TRUE(initialWriteRet.isOk());
@@ -193,7 +180,7 @@
* Writes a key and value to a slot
* Reads the slot with a different key so does not receive the value
*/
-TEST_F(WeaverHidlTest, WriteFollowedByReadWithWrongKeyDoesNotGiveTheValue) {
+TEST_P(WeaverHidlTest, WriteFollowedByReadWithWrongKeyDoesNotGiveTheValue) {
constexpr uint32_t slotId = 0;
const auto ret = weaver->write(slotId, KEY, VALUE);
ASSERT_TRUE(ret.isOk());
@@ -217,7 +204,7 @@
/*
* Writing to an invalid slot fails
*/
-TEST_F(WeaverHidlTest, WritingToInvalidSlotFails) {
+TEST_P(WeaverHidlTest, WritingToInvalidSlotFails) {
WeaverStatus status;
WeaverConfig config;
const auto configRet = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
@@ -240,7 +227,7 @@
/*
* Reading from an invalid slot fails rather than incorrect key
*/
-TEST_F(WeaverHidlTest, ReadingFromInvalidSlotFails) {
+TEST_P(WeaverHidlTest, ReadingFromInvalidSlotFails) {
WeaverStatus status;
WeaverConfig config;
const auto configRet = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
@@ -276,7 +263,7 @@
/*
* Writing a key that is too large fails
*/
-TEST_F(WeaverHidlTest, WriteWithTooLargeKeyFails) {
+TEST_P(WeaverHidlTest, WriteWithTooLargeKeyFails) {
WeaverStatus status;
WeaverConfig config;
const auto configRet = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
@@ -297,7 +284,7 @@
/*
* Writing a value that is too large fails
*/
-TEST_F(WeaverHidlTest, WriteWithTooLargeValueFails) {
+TEST_P(WeaverHidlTest, WriteWithTooLargeValueFails) {
WeaverStatus status;
WeaverConfig config;
const auto configRet = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
@@ -318,7 +305,7 @@
/*
* Reading with a key that is loo large fails
*/
-TEST_F(WeaverHidlTest, ReadWithTooLargeKeyFails) {
+TEST_P(WeaverHidlTest, ReadWithTooLargeKeyFails) {
WeaverStatus status;
WeaverConfig config;
const auto configRet = weaver->getConfig([&](WeaverStatus s, WeaverConfig c) {
@@ -349,11 +336,7 @@
EXPECT_EQ(timeout, 0u);
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(WeaverHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- WeaverHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- ALOGI("Test result = %d", status);
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WeaverHidlTest,
+ testing::ValuesIn(android::hardware::getAllHalInstanceNames(IWeaver::descriptor)),
+ android::hardware::PrintInstanceNameToString);
diff --git a/wifi/1.4/IWifi.hal b/wifi/1.4/IWifi.hal
index f4bc618..765e09d 100644
--- a/wifi/1.4/IWifi.hal
+++ b/wifi/1.4/IWifi.hal
@@ -24,5 +24,4 @@
* module loaded in the system.
* IWifi.getChip() must return @1.2::IWifiChip
*/
-interface IWifi extends @1.3::IWifi {
-};
+interface IWifi extends @1.3::IWifi {};
diff --git a/wifi/1.4/default/wifi_status_util.cpp b/wifi/1.4/default/wifi_status_util.cpp
index 597c04b..8ceb926 100644
--- a/wifi/1.4/default/wifi_status_util.cpp
+++ b/wifi/1.4/default/wifi_status_util.cpp
@@ -46,6 +46,8 @@
return "BUSY";
case legacy_hal::WIFI_ERROR_UNKNOWN:
return "UNKNOWN";
+ default:
+ return "UNKNOWN ERROR";
}
}
@@ -92,6 +94,10 @@
case legacy_hal::WIFI_ERROR_UNKNOWN:
return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN, "unknown");
+
+ default:
+ return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN,
+ "unknown error");
}
}
diff --git a/wifi/offload/1.0/vts/functional/Android.bp b/wifi/offload/1.0/vts/functional/Android.bp
index de15aa7..965c946 100644
--- a/wifi/offload/1.0/vts/functional/Android.bp
+++ b/wifi/offload/1.0/vts/functional/Android.bp
@@ -19,5 +19,5 @@
defaults: ["VtsHalTargetTestDefaults"],
srcs: ["VtsHalWifiOffloadV1_0TargetTest.cpp"],
static_libs: ["android.hardware.wifi.offload@1.0"],
- test_suites: ["general-tests"],
+ test_suites: ["general-tests", "vts-core"],
}
diff --git a/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp b/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
index dbe4e74..83d834c 100644
--- a/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
+++ b/wifi/offload/1.0/vts/functional/VtsHalWifiOffloadV1_0TargetTest.cpp
@@ -20,10 +20,11 @@
#include <android/hardware/wifi/offload/1.0/IOffload.h>
#include <android/hardware/wifi/offload/1.0/IOffloadCallback.h>
#include <android/hardware/wifi/offload/1.0/types.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
#include <VtsHalHidlTargetCallbackBase.h>
-#include <VtsHalHidlTargetTestBase.h>
-#include <VtsHalHidlTargetTestEnvBase.h>
#include <vector>
@@ -69,33 +70,11 @@
OffloadStatus error_code_;
};
-// Test environment for Weaver HIDL HAL.
-class WifiOffloadHidlEnvironment
- : public ::testing::VtsHalHidlTargetTestEnvBase {
- public:
- // get the test environment singleton
- static WifiOffloadHidlEnvironment* Instance() {
- static WifiOffloadHidlEnvironment* instance =
- new WifiOffloadHidlEnvironment;
- return instance;
- }
-
- virtual void registerTestServices() override {
- registerTestService<IOffload>();
- }
-
- private:
- WifiOffloadHidlEnvironment() {}
-};
-
// The main test class for WifiOffload HIDL HAL.
-class WifiOffloadHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+class WifiOffloadHidlTest : public ::testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- wifi_offload_ =
- ::testing::VtsHalHidlTargetTestBase::getService<IOffload>(
- WifiOffloadHidlEnvironment::Instance()
- ->getServiceName<IOffload>());
+ wifi_offload_ = IOffload::getService(GetParam());
ASSERT_NE(wifi_offload_, nullptr);
wifi_offload_cb_ = new OffloadCallback();
@@ -136,7 +115,7 @@
/*
* Verify that setEventCallback method returns without errors
*/
-TEST_F(WifiOffloadHidlTest, setEventCallback) {
+TEST_P(WifiOffloadHidlTest, setEventCallback) {
auto returnObject = wifi_offload_->setEventCallback(wifi_offload_cb_);
ASSERT_EQ(true, returnObject.isOk());
}
@@ -144,7 +123,7 @@
/*
* Verify that subscribeScanResults method returns without errors
*/
-TEST_F(WifiOffloadHidlTest, subscribeScanResults) {
+TEST_P(WifiOffloadHidlTest, subscribeScanResults) {
const auto& result = HIDL_INVOKE(wifi_offload_, subscribeScanResults, 0);
ASSERT_EQ(OffloadStatusCode::OK, result.code);
}
@@ -152,7 +131,7 @@
/*
* Verify that unsubscribeScanResults method returns without errors
*/
-TEST_F(WifiOffloadHidlTest, unsubscribeScanResults) {
+TEST_P(WifiOffloadHidlTest, unsubscribeScanResults) {
auto returnObject = wifi_offload_->unsubscribeScanResults();
ASSERT_EQ(true, returnObject.isOk());
}
@@ -160,7 +139,7 @@
/*
* Verify that configureScans method returns without errors
*/
-TEST_F(WifiOffloadHidlTest, configureScans) {
+TEST_P(WifiOffloadHidlTest, configureScans) {
ScanParam* pScanParam = new ScanParam();
std::vector<uint32_t> frequencyList = {kFrequency1, kFrequency2};
pScanParam->disconnectedModeScanIntervalMs =
@@ -192,7 +171,7 @@
/*
* Verify that getScanStats returns without any errors
*/
-TEST_F(WifiOffloadHidlTest, getScanStats) {
+TEST_P(WifiOffloadHidlTest, getScanStats) {
const auto& result = HIDL_INVOKE(wifi_offload_, getScanStats);
OffloadStatus status = result.first;
ASSERT_EQ(OffloadStatusCode::OK, status.code);
@@ -201,7 +180,7 @@
/*
* Verify that onScanResult callback is invoked
*/
-TEST_F(WifiOffloadHidlTest, getScanResults) {
+TEST_P(WifiOffloadHidlTest, getScanResults) {
wifi_offload_->setEventCallback(wifi_offload_cb_);
std::vector<ScanResult> scan_results;
std::vector<uint8_t> ssid(kSsid1, kSsid1 + sizeof(kSsid1));
@@ -223,7 +202,7 @@
/*
* Verify that onError callback is invoked
*/
-TEST_F(WifiOffloadHidlTest, getError) {
+TEST_P(WifiOffloadHidlTest, getError) {
wifi_offload_->setEventCallback(wifi_offload_cb_);
OffloadStatus status = {OffloadStatusCode::ERROR, ""};
wifi_offload_cb_->onError(status);
@@ -231,12 +210,8 @@
ASSERT_EQ(true, res.no_timeout);
}
-int main(int argc, char** argv) {
- ::testing::AddGlobalTestEnvironment(WifiOffloadHidlEnvironment::Instance());
- ::testing::InitGoogleTest(&argc, argv);
- WifiOffloadHidlEnvironment::Instance()->init(&argc, argv);
- int status = RUN_ALL_TESTS();
- LOG(INFO) << "Test result = " << status;
-
- return status;
-}
+INSTANTIATE_TEST_SUITE_P(
+ PerInstance, WifiOffloadHidlTest,
+ testing::ValuesIn(
+ android::hardware::getAllHalInstanceNames(IOffload::descriptor)),
+ android::hardware::PrintInstanceNameToString);
\ No newline at end of file
diff --git a/wifi/offload/1.0/vts/functional/hidl_call_util.h b/wifi/offload/1.0/vts/functional/hidl_call_util.h
index f3ca517..99868e8 100644
--- a/wifi/offload/1.0/vts/functional/hidl_call_util.h
+++ b/wifi/offload/1.0/vts/functional/hidl_call_util.h
@@ -21,8 +21,6 @@
#include <type_traits>
#include <utility>
-#include <VtsHalHidlTargetTestBase.h>
-
namespace {
namespace detail {
template <typename>
diff --git a/wifi/supplicant/1.3/ISupplicant.hal b/wifi/supplicant/1.3/ISupplicant.hal
index 75b7e96..246ce1f 100644
--- a/wifi/supplicant/1.3/ISupplicant.hal
+++ b/wifi/supplicant/1.3/ISupplicant.hal
@@ -26,5 +26,4 @@
* 1.2 HAL. For example V1_2::ISupplicant::addIface() adds V1_2::ISupplicantIface,
* which can be cast to V1_3::ISupplicantStaIface.
*/
-interface ISupplicant extends @1.2::ISupplicant {
-};
+interface ISupplicant extends @1.2::ISupplicant {};
diff --git a/wifi/supplicant/1.3/ISupplicantStaIface.hal b/wifi/supplicant/1.3/ISupplicantStaIface.hal
index 62b4033..cb207d8 100644
--- a/wifi/supplicant/1.3/ISupplicantStaIface.hal
+++ b/wifi/supplicant/1.3/ISupplicantStaIface.hal
@@ -18,7 +18,7 @@
import @1.0::SupplicantStatus;
import @1.2::ISupplicantStaIface;
-import @1.3::ISupplicantStaIfaceCallback;
+import ISupplicantStaIfaceCallback;
/**
* Interface exposed by the supplicant for each station mode network
@@ -43,4 +43,15 @@
*/
registerCallback_1_3(ISupplicantStaIfaceCallback callback)
generates (SupplicantStatus status);
+
+ /**
+ * Get Connection capabilities
+ *
+ * @return status Status of the operation, and connection capabilities.
+ * Possible status codes:
+ * |SupplicantStatusCode.SUCCESS|,
+ * |SupplicantStatusCode.FAILURE_UNKNOWN|,
+ */
+ getConnectionCapabilities()
+ generates (SupplicantStatus status, ConnectionCapabilities capabilities);
};
diff --git a/wifi/supplicant/1.3/ISupplicantStaNetwork.hal b/wifi/supplicant/1.3/ISupplicantStaNetwork.hal
index 5e265c6..ab08cff 100644
--- a/wifi/supplicant/1.3/ISupplicantStaNetwork.hal
+++ b/wifi/supplicant/1.3/ISupplicantStaNetwork.hal
@@ -60,6 +60,5 @@
* |SupplicantStatusCode.FAILURE_UNKNOWN|,
* |SupplicantStatusCode.FAILURE_NETWORK_INVALID|
*/
- setPmkCache(vec<uint8_t> serializedEntry)
- generates (SupplicantStatus status);
+ setPmkCache(vec<uint8_t> serializedEntry) generates (SupplicantStatus status);
};
diff --git a/wifi/supplicant/1.3/types.hal b/wifi/supplicant/1.3/types.hal
index a782b49..7874399 100644
--- a/wifi/supplicant/1.3/types.hal
+++ b/wifi/supplicant/1.3/types.hal
@@ -25,3 +25,36 @@
REQUIRE_CERT_STATUS,
REQUIRE_ALL_CERTS_STATUS,
};
+
+/**
+ * Wifi Technologies
+ */
+enum WifiTechnology : uint32_t {
+ UNKNOWN = 0,
+ /**
+ * For 802.11a/b/g
+ */
+ LEGACY = 1,
+ /**
+ * For 802.11n
+ */
+ HT = 2,
+ /**
+ * For 802.11ac
+ */
+ VHT = 3,
+ /**
+ * For 802.11ax
+ */
+ HE = 4,
+};
+
+/**
+ * Connection Capabilities.
+ */
+struct ConnectionCapabilities {
+ /**
+ * Wifi Technology
+ */
+ WifiTechnology technology;
+};
diff --git a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
index 9b68a47..62f3228 100644
--- a/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
+++ b/wifi/supplicant/1.3/vts/functional/supplicant_sta_iface_hidl_test.cpp
@@ -37,6 +37,7 @@
using ::android::hardware::wifi::supplicant::V1_2::DppAkm;
using ::android::hardware::wifi::supplicant::V1_2::DppFailureCode;
using ::android::hardware::wifi::supplicant::V1_2::DppProgressCode;
+using ::android::hardware::wifi::supplicant::V1_3::ConnectionCapabilities;
using ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIface;
using ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaIfaceCallback;
using ::android::hardware::wifi::supplicant::V1_3::ISupplicantStaNetwork;
@@ -179,3 +180,14 @@
EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
});
}
+
+/*
+ * getConnectionCapabilities
+ */
+TEST_F(SupplicantStaIfaceHidlTest, GetConnectionCapabilities) {
+ sta_iface_->getConnectionCapabilities(
+ [&](const SupplicantStatus& status,
+ ConnectionCapabilities /* capabilities */) {
+ EXPECT_EQ(SupplicantStatusCode::SUCCESS, status.code);
+ });
+}