Implement config flags.
Bug: 69958423
Test: VTS
Change-Id: I6221d2bd2c6f1e31c93b105fce4cfc6d673e3b77
diff --git a/broadcastradio/2.0/Android.bp b/broadcastradio/2.0/Android.bp
index 5146932..afbd6d4 100644
--- a/broadcastradio/2.0/Android.bp
+++ b/broadcastradio/2.0/Android.bp
@@ -16,6 +16,7 @@
"android.hidl.base@1.0",
],
types: [
+ "ConfigFlag",
"Constants",
"IdentifierType",
"Metadata",
diff --git a/broadcastradio/2.0/ITunerSession.hal b/broadcastradio/2.0/ITunerSession.hal
index ae6cbb5..8a21768 100644
--- a/broadcastradio/2.0/ITunerSession.hal
+++ b/broadcastradio/2.0/ITunerSession.hal
@@ -77,6 +77,32 @@
cancel();
/**
+ * Fetches the current setting of a given config flag.
+ *
+ * The success/failure result must be consistent with setConfigFlag.
+ *
+ * @param flag Flag to fetch.
+ * @return result OK successfully fetched the flag.
+ * INVALID_STATE if the flag is not applicable right now.
+ * NOT_SUPPORTED if the flag is not supported at all.
+ * @return value The current value of the flag, if result is OK.
+ */
+ getConfigFlag(ConfigFlag flag) generates (Result result, bool value);
+
+ /**
+ * Sets the config flag.
+ *
+ * The success/failure result must be consistent with getConfigFlag.
+ *
+ * @param flag Flag to set.
+ * @param value The new value of a given flag.
+ * @return result OK successfully set the flag.
+ * INVALID_STATE if the flag is not applicable right now.
+ * NOT_SUPPORTED if the flag is not supported at all.
+ */
+ setConfigFlag(ConfigFlag flag, bool value) generates (Result result);
+
+ /**
* Generic method for setting vendor-specific parameter values.
* The framework does not interpret the parameters, they are passed
* in an opaque manner between a vendor application and HAL.
diff --git a/broadcastradio/2.0/default/TunerSession.cpp b/broadcastradio/2.0/default/TunerSession.cpp
index f0b98b8..54af3389 100644
--- a/broadcastradio/2.0/default/TunerSession.cpp
+++ b/broadcastradio/2.0/default/TunerSession.cpp
@@ -205,6 +205,19 @@
return {};
}
+Return<void> TunerSession::getConfigFlag(ConfigFlag flag, getConfigFlag_cb _hidl_cb) {
+ ALOGV("%s(%s)", __func__, toString(flag).c_str());
+
+ _hidl_cb(Result::NOT_SUPPORTED, false);
+ return {};
+}
+
+Return<Result> TunerSession::setConfigFlag(ConfigFlag flag, bool value) {
+ ALOGV("%s(%s, %d)", __func__, toString(flag).c_str(), value);
+
+ return Result::NOT_SUPPORTED;
+}
+
Return<void> TunerSession::setParameters(const hidl_vec<VendorKeyValue>& /* parameters */,
setParameters_cb _hidl_cb) {
ALOGV("%s", __func__);
diff --git a/broadcastradio/2.0/default/TunerSession.h b/broadcastradio/2.0/default/TunerSession.h
index 08a7588..9a72182 100644
--- a/broadcastradio/2.0/default/TunerSession.h
+++ b/broadcastradio/2.0/default/TunerSession.h
@@ -38,6 +38,8 @@
virtual Return<Result> scan(bool directionUp, bool skipSubChannel) override;
virtual Return<Result> step(bool directionUp) override;
virtual Return<void> cancel() override;
+ virtual Return<void> getConfigFlag(ConfigFlag flag, getConfigFlag_cb _hidl_cb);
+ virtual Return<Result> setConfigFlag(ConfigFlag flag, bool value);
virtual Return<void> setParameters(const hidl_vec<VendorKeyValue>& parameters,
setParameters_cb _hidl_cb) override;
virtual Return<void> getParameters(const hidl_vec<hidl_string>& keys,
diff --git a/broadcastradio/2.0/types.hal b/broadcastradio/2.0/types.hal
index 4b9878b..fc5809f 100644
--- a/broadcastradio/2.0/types.hal
+++ b/broadcastradio/2.0/types.hal
@@ -37,6 +37,73 @@
};
/**
+ * Configuration flags to be used with getConfigFlag and setConfigFlag methods
+ * of ITunerSession.
+ */
+enum ConfigFlag : uint32_t {
+ /**
+ * Forces mono audio stream reception.
+ *
+ * Analog broadcasts can recover poor reception conditions by jointing
+ * stereo channels into one. Mainly for, but not limited to AM/FM.
+ */
+ FORCE_MONO = 1,
+
+ /**
+ * Forces the analog playback for the supporting radio technology.
+ *
+ * User may disable digital playback for FM HD Radio or hybrid FM/DAB with
+ * this option. This is purely user choice, ie. does not reflect digital-
+ * analog handover state managed from the HAL implementation side.
+ *
+ * Some radio technologies may not support this, ie. DAB.
+ */
+ FORCE_ANALOG,
+
+ /**
+ * Forces the digital playback for the supporting radio technology.
+ *
+ * User may disable digital-analog handover that happens with poor
+ * receiption conditions. With digital forced, the radio will remain silent
+ * instead of switching to analog channel if it's available. This is purely
+ * user choice, it does not reflect the actual state of handover.
+ */
+ FORCE_DIGITAL,
+
+ /**
+ * RDS Alternative Frequencies.
+ *
+ * If set, radio tuner automatically switches to the best available
+ * frequency that currently listened RDS station broadcasts.
+ */
+ RDS_AF,
+
+ /**
+ * RDS region-specific program lock-down.
+ *
+ * Allows user to lock to the current region as they move into the
+ * other region.
+ */
+ RDS_REG,
+
+ /**
+ * Enables DAB implicit linking, based on program identifiers
+ * (DAB SId, RDS PI).
+ */
+ DAB_IMPLICIT_LINKING,
+
+ /**
+ * Enables DAB hard linking (the same content).
+ */
+ DAB_HARD_LINKING,
+
+ /**
+ * Enables DAB hard linking (related content).
+ */
+ DAB_SOFT_LINKING,
+};
+
+/**
* A key-value pair for vendor-specific information to be passed as-is through
* Android framework to the front-end application.
*/
diff --git a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
index a12afd6..d0e4144 100644
--- a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
+++ b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
@@ -57,6 +57,12 @@
} // namespace timeout
+static const ConfigFlag gConfigFlagValues[] = {
+ ConfigFlag::FORCE_MONO, ConfigFlag::FORCE_ANALOG, ConfigFlag::FORCE_DIGITAL,
+ ConfigFlag::RDS_AF, ConfigFlag::RDS_REG, ConfigFlag::DAB_IMPLICIT_LINKING,
+ ConfigFlag::DAB_HARD_LINKING, ConfigFlag::DAB_SOFT_LINKING,
+};
+
struct TunerCallbackMock : public ITunerCallback {
TunerCallbackMock() {
// we expect the antenna is connected through the whole test
@@ -378,6 +384,85 @@
ASSERT_EQ(0u, len);
}
+/**
+ * Test getting config flags.
+ *
+ * Verifies that:
+ * - getConfigFlag either succeeds or ends with NOT_SUPPORTED or INVALID_STATE;
+ * - call success or failure is consistent with setConfigFlag.
+ */
+TEST_F(BroadcastRadioHalTest, GetConfigFlags) {
+ ASSERT_TRUE(openSession());
+
+ for (auto flag : gConfigFlagValues) {
+ auto halResult = Result::UNKNOWN_ERROR;
+ auto cb = [&](Result result, bool) { halResult = result; };
+ auto hidlResult = mSession->getConfigFlag(flag, cb);
+ EXPECT_TRUE(hidlResult.isOk());
+
+ if (halResult != Result::NOT_SUPPORTED && halResult != Result::INVALID_STATE) {
+ ASSERT_EQ(Result::OK, halResult);
+ }
+
+ // set must fail or succeed the same way as get
+ auto setResult = mSession->setConfigFlag(flag, false);
+ EXPECT_EQ(halResult, setResult);
+ setResult = mSession->setConfigFlag(flag, true);
+ EXPECT_EQ(halResult, setResult);
+ }
+}
+
+/**
+ * Test setting config flags.
+ *
+ * Verifies that:
+ * - setConfigFlag either succeeds or ends with NOT_SUPPORTED or INVALID_STATE;
+ * - getConfigFlag reflects the state requested immediately after the set call.
+ */
+TEST_F(BroadcastRadioHalTest, SetConfigFlags) {
+ ASSERT_TRUE(openSession());
+
+ auto get = [&](ConfigFlag flag) {
+ auto halResult = Result::UNKNOWN_ERROR;
+ bool gotValue = false;
+ auto cb = [&](Result result, bool value) {
+ halResult = result;
+ gotValue = value;
+ };
+ auto hidlResult = mSession->getConfigFlag(flag, cb);
+ EXPECT_TRUE(hidlResult.isOk());
+ EXPECT_EQ(Result::OK, halResult);
+ return gotValue;
+ };
+
+ for (auto flag : gConfigFlagValues) {
+ auto result = mSession->setConfigFlag(flag, false);
+ if (result == Result::NOT_SUPPORTED || result == Result::INVALID_STATE) {
+ // setting to true must result in the same error as false
+ auto secondResult = mSession->setConfigFlag(flag, true);
+ EXPECT_EQ(result, secondResult);
+ continue;
+ }
+ ASSERT_EQ(Result::OK, result);
+
+ // verify false is set
+ auto value = get(flag);
+ EXPECT_FALSE(value);
+
+ // try setting true this time
+ result = mSession->setConfigFlag(flag, true);
+ ASSERT_EQ(Result::OK, result);
+ value = get(flag);
+ EXPECT_TRUE(value);
+
+ // false again
+ result = mSession->setConfigFlag(flag, false);
+ ASSERT_EQ(Result::OK, result);
+ value = get(flag);
+ EXPECT_FALSE(value);
+ }
+}
+
} // namespace vts
} // namespace V2_0
} // namespace broadcastradio