Merge "soundtrigger: Switch audio service to load soundtrigger 2.1"
diff --git a/broadcastradio/2.0/default/BroadcastRadio.cpp b/broadcastradio/2.0/default/BroadcastRadio.cpp
index aa5afad..0148fec 100644
--- a/broadcastradio/2.0/default/BroadcastRadio.cpp
+++ b/broadcastradio/2.0/default/BroadcastRadio.cpp
@@ -112,6 +112,12 @@
Return<void> BroadcastRadio::openSession(const sp<ITunerCallback>& callback,
openSession_cb _hidl_cb) {
ALOGV("%s", __func__);
+
+ /* For the needs of default implementation it's fine to instantiate new session object
+ * out of the lock scope. If your implementation needs it, use reentrant lock.
+ */
+ sp<TunerSession> newSession = new TunerSession(*this, callback);
+
lock_guard<mutex> lk(mMut);
auto oldSession = mSession.promote();
@@ -121,7 +127,6 @@
mSession = nullptr;
}
- sp<TunerSession> newSession = new TunerSession(*this, callback);
mSession = newSession;
_hidl_cb(Result::OK, newSession);
diff --git a/broadcastradio/2.0/default/TunerSession.cpp b/broadcastradio/2.0/default/TunerSession.cpp
index 3166d86..ba8285f 100644
--- a/broadcastradio/2.0/default/TunerSession.cpp
+++ b/broadcastradio/2.0/default/TunerSession.cpp
@@ -50,7 +50,12 @@
} // namespace delay
TunerSession::TunerSession(BroadcastRadio& module, const sp<ITunerCallback>& callback)
- : mCallback(callback), mModule(module) {}
+ : mCallback(callback), mModule(module) {
+ auto&& ranges = module.getAmFmConfig().ranges;
+ if (ranges.size() > 0) {
+ tuneInternalLocked(utils::make_selector_amfm(ranges[0].lowerBound));
+ }
+}
// makes ProgramInfo that points to no program
static ProgramInfo makeDummyProgramInfo(const ProgramSelector& selector) {
@@ -63,6 +68,8 @@
}
void TunerSession::tuneInternalLocked(const ProgramSelector& sel) {
+ ALOGV("%s(%s)", __func__, toString(sel).c_str());
+
VirtualProgram virtualProgram;
ProgramInfo programInfo;
if (virtualRadio().getProgram(sel, virtualProgram)) {
@@ -100,6 +107,8 @@
return Result::INVALID_ARGUMENTS;
}
+ cancelLocked();
+
mIsTuneCompleted = false;
auto task = [this, sel]() {
lock_guard<mutex> lk(mMut);
@@ -115,6 +124,8 @@
lock_guard<mutex> lk(mMut);
if (mIsClosed) return Result::INVALID_STATE;
+ cancelLocked();
+
auto list = virtualRadio().getProgramList();
if (list.empty()) {
@@ -166,13 +177,13 @@
lock_guard<mutex> lk(mMut);
if (mIsClosed) return Result::INVALID_STATE;
+ cancelLocked();
+
if (!utils::hasId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY)) {
ALOGE("Can't step in anything else than AM/FM");
return Result::NOT_SUPPORTED;
}
- mIsTuneCompleted = false;
-
auto stepTo = utils::getId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY);
auto range = getAmFmRangeLocked();
if (!range) {
@@ -188,6 +199,7 @@
if (stepTo > range->upperBound) stepTo = range->lowerBound;
if (stepTo < range->lowerBound) stepTo = range->upperBound;
+ mIsTuneCompleted = false;
auto task = [this, stepTo]() {
ALOGI("Performing step to %s", std::to_string(stepTo).c_str());
@@ -200,12 +212,22 @@
return Result::OK;
}
+void TunerSession::cancelLocked() {
+ ALOGV("%s", __func__);
+
+ mThread.cancelAll();
+ if (utils::getType(mCurrentProgram.primaryId) != IdentifierType::INVALID) {
+ mIsTuneCompleted = true;
+ }
+}
+
Return<void> TunerSession::cancel() {
ALOGV("%s", __func__);
lock_guard<mutex> lk(mMut);
if (mIsClosed) return {};
- mThread.cancelAll();
+ cancelLocked();
+
return {};
}
@@ -281,7 +303,10 @@
}
std::optional<AmFmBandRange> TunerSession::getAmFmRangeLocked() const {
- if (!mIsTuneCompleted) return {};
+ if (!mIsTuneCompleted) {
+ ALOGW("tune operation in process");
+ return {};
+ }
if (!utils::hasId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY)) return {};
auto freq = utils::getId(mCurrentProgram, IdentifierType::AMFM_FREQUENCY);
diff --git a/broadcastradio/2.0/default/TunerSession.h b/broadcastradio/2.0/default/TunerSession.h
index 5d27b1e..4130341 100644
--- a/broadcastradio/2.0/default/TunerSession.h
+++ b/broadcastradio/2.0/default/TunerSession.h
@@ -63,6 +63,7 @@
bool mIsTuneCompleted = false;
ProgramSelector mCurrentProgram = {};
+ void cancelLocked();
void tuneInternalLocked(const ProgramSelector& sel);
const VirtualRadio& virtualRadio() const;
const BroadcastRadio& module() const;
diff --git a/broadcastradio/2.0/types.hal b/broadcastradio/2.0/types.hal
index 1fd3715..003c444 100644
--- a/broadcastradio/2.0/types.hal
+++ b/broadcastradio/2.0/types.hal
@@ -215,7 +215,9 @@
/**
* Channel name, i.e. 5A, 7B.
*
- * It must match the following regular expression: /^[A-Z0-9]{2,5}$/.
+ * It must match the following regular expression:
+ * /^[A-Z0-9][A-Z0-9 ]{0,5}[A-Z0-9]$/ (2-7 uppercase alphanumeric characters
+ * without spaces allowed at the beginning nor end).
*/
string label;
diff --git a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
index 8d9d622..1ecf615 100644
--- a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
+++ b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
@@ -15,6 +15,8 @@
*/
#define LOG_TAG "BcRadio.vts"
+#define LOG_NDEBUG 0
+#define EGMOCK_VERBOSE 1
#include <VtsHalHidlTargetTestBase.h>
#include <android-base/logging.h>
@@ -113,7 +115,15 @@
std::cout << "[ SKIPPED ] " << msg << std::endl;
}
+MATCHER_P(InfoHasId, id,
+ std::string(negation ? "does not contain" : "contains") + " " + toString(id)) {
+ auto ids = utils::getAllIds(arg.selector, utils::getType(id));
+ return ids.end() != find(ids.begin(), ids.end(), id.value);
+}
+
TunerCallbackMock::TunerCallbackMock() {
+ EXPECT_TIMEOUT_CALL(*this, onCurrentProgramInfoChanged, _).Times(AnyNumber());
+
// we expect the antenna is connected through the whole test
EXPECT_CALL(*this, onAntennaStateChange(false)).Times(0);
}
@@ -332,11 +342,13 @@
}
ASSERT_EQ(Result::OK, halResult);
- std::regex re("^[A-Z0-9]{2,5}$");
+ std::regex re("^[A-Z0-9][A-Z0-9 ]{0,5}[A-Z0-9]$");
// double-check correctness of the test
ASSERT_TRUE(std::regex_match("5A", re));
ASSERT_FALSE(std::regex_match("5a", re));
- ASSERT_FALSE(std::regex_match("123ABC", re));
+ ASSERT_FALSE(std::regex_match("1234ABCD", re));
+ ASSERT_TRUE(std::regex_match("CN 12D", re));
+ ASSERT_FALSE(std::regex_match(" 5A", re));
for (auto&& entry : config) {
EXPECT_TRUE(std::regex_match(std::string(entry.label), re));
@@ -362,9 +374,19 @@
uint64_t freq = 100100; // 100.1 FM
auto sel = make_selector_amfm(freq);
+ /* TODO(b/69958777): there is a race condition between tune() and onCurrentProgramInfoChanged
+ * callback setting infoCb, because egmock cannot distinguish calls with different matchers
+ * (there is one here and one in callback constructor).
+ *
+ * This sleep workaround will fix default implementation, but the real HW tests will still be
+ * flaky. We probably need to implement egmock alternative based on actions.
+ */
+ std::this_thread::sleep_for(100ms);
+
// try tuning
ProgramInfo infoCb = {};
- EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChanged, _)
+ EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChanged,
+ InfoHasId(utils::make_identifier(IdentifierType::AMFM_FREQUENCY, freq)))
.Times(AnyNumber())
.WillOnce(DoAll(SaveArg<0>(&infoCb), testing::Return(ByMove(Void()))));
auto result = mSession->tune(sel);
@@ -379,6 +401,8 @@
EXPECT_EQ(Result::OK, result);
EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onCurrentProgramInfoChanged, timeout::tune);
+ ALOGD("current program info: %s", toString(infoCb).c_str());
+
// it should tune exactly to what was requested
auto freqs = utils::getAllIds(infoCb.selector, IdentifierType::AMFM_FREQUENCY);
EXPECT_NE(freqs.end(), find(freqs.begin(), freqs.end(), freq));
@@ -442,6 +466,9 @@
TEST_F(BroadcastRadioHalTest, Scan) {
ASSERT_TRUE(openSession());
+ // TODO(b/69958777): see FmTune workaround
+ std::this_thread::sleep_for(100ms);
+
EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChanged, _);
auto result = mSession->scan(true /* up */, true /* skip subchannel */);
EXPECT_EQ(Result::OK, result);
@@ -464,9 +491,15 @@
TEST_F(BroadcastRadioHalTest, Step) {
ASSERT_TRUE(openSession());
+ // TODO(b/69958777): see FmTune workaround
+ std::this_thread::sleep_for(100ms);
+
EXPECT_TIMEOUT_CALL(*mCallback, onCurrentProgramInfoChanged, _).Times(AnyNumber());
auto result = mSession->step(true /* up */);
- if (result == Result::NOT_SUPPORTED) return;
+ if (result == Result::NOT_SUPPORTED) {
+ printSkipped("step not supported");
+ return;
+ }
EXPECT_EQ(Result::OK, result);
EXPECT_TIMEOUT_CALL_WAIT(*mCallback, onCurrentProgramInfoChanged, timeout::tune);
diff --git a/broadcastradio/common/vts/utils/include/broadcastradio-vts-utils/mock-timeout.h b/broadcastradio/common/vts/utils/include/broadcastradio-vts-utils/mock-timeout.h
index 12453bb..1f716f1 100644
--- a/broadcastradio/common/vts/utils/include/broadcastradio-vts-utils/mock-timeout.h
+++ b/broadcastradio/common/vts/utils/include/broadcastradio-vts-utils/mock-timeout.h
@@ -13,12 +13,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#ifndef ANDROID_HARDWARE_BROADCASTRADIO_V1_1_MOCK_TIMEOUT
-#define ANDROID_HARDWARE_BROADCASTRADIO_V1_1_MOCK_TIMEOUT
+#ifndef ANDROID_HARDWARE_BROADCASTRADIO_VTS_MOCK_TIMEOUT
+#define ANDROID_HARDWARE_BROADCASTRADIO_VTS_MOCK_TIMEOUT
#include <gmock/gmock.h>
#include <thread>
+#ifndef EGMOCK_VERBOSE
+#define EGMOCK_VERBOSE 0
+#endif
+
+/**
+ * Print log message.
+ *
+ * INTERNAL IMPLEMENTATION - don't use in user code.
+ */
+#if EGMOCK_VERBOSE
+#define EGMOCK_LOG_(...) ALOGV("egmock: " __VA_ARGS__)
+#else
+#define EGMOCK_LOG_(...)
+#endif
+
/**
* Common helper objects for gmock timeout extension.
*
@@ -61,6 +76,7 @@
auto invokeMock = [&]() { return egmock_##Method(__VA_ARGS__); }; \
auto notify = [&]() { \
std::lock_guard<std::mutex> lk(egmock_mut_##Method); \
+ EGMOCK_LOG_(#Method " called"); \
egmock_called_##Method = true; \
egmock_cond_##Method.notify_all(); \
}; \
@@ -105,6 +121,7 @@
* EXPECT_TIMEOUT_CALL(account, charge, 100, Currency::USD);
*/
#define EXPECT_TIMEOUT_CALL(obj, Method, ...) \
+ EGMOCK_LOG_(#Method " expected to call"); \
(obj).egmock_called_##Method = false; \
EXPECT_CALL(obj, egmock_##Method(__VA_ARGS__))
@@ -124,6 +141,7 @@
*/
#define EXPECT_TIMEOUT_CALL_WAIT(obj, Method, timeout) \
{ \
+ EGMOCK_LOG_("waiting for " #Method " call"); \
std::unique_lock<std::mutex> lk((obj).egmock_mut_##Method); \
if (!(obj).egmock_called_##Method) { \
auto status = (obj).egmock_cond_##Method.wait_for(lk, timeout); \
@@ -131,4 +149,4 @@
} \
}
-#endif // ANDROID_HARDWARE_BROADCASTRADIO_V1_1_MOCK_TIMEOUT
+#endif // ANDROID_HARDWARE_BROADCASTRADIO_VTS_MOCK_TIMEOUT
diff --git a/keymaster/4.0/default/service.cpp b/keymaster/4.0/default/service.cpp
index f4b5fd3..cfb960a 100644
--- a/keymaster/4.0/default/service.cpp
+++ b/keymaster/4.0/default/service.cpp
@@ -21,8 +21,10 @@
#include <AndroidKeymaster4Device.h>
+using android::hardware::keymaster::V4_0::SecurityLevel;
+
int main() {
- auto keymaster = ::keymaster::V4_0::ng::CreateKeymasterDevice();
+ auto keymaster = ::keymaster::V4_0::ng::CreateKeymasterDevice(SecurityLevel::SOFTWARE);
auto status = keymaster->registerAsService();
if (status != android::OK) {
LOG(FATAL) << "Could not register service for Keymaster 4.0 (" << status << ")";
diff --git a/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h b/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h
index 2f9f88b..73e03fb 100644
--- a/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h
+++ b/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h
@@ -329,6 +329,92 @@
return accessTagValue(ttag, param);
}
+inline bool operator==(const KeyParameter& a, const KeyParameter& b) {
+ if (a.tag != b.tag) {
+ return false;
+ }
+
+ switch (a.tag) {
+ /* Boolean tags */
+ case Tag::INVALID:
+ case Tag::CALLER_NONCE:
+ case Tag::INCLUDE_UNIQUE_ID:
+ case Tag::BOOTLOADER_ONLY:
+ case Tag::NO_AUTH_REQUIRED:
+ case Tag::ALLOW_WHILE_ON_BODY:
+ case Tag::ROLLBACK_RESISTANCE:
+ case Tag::RESET_SINCE_ID_ROTATION:
+ case Tag::TRUSTED_USER_PRESENCE_REQUIRED:
+ return true;
+
+ /* Integer tags */
+ case Tag::KEY_SIZE:
+ case Tag::MIN_MAC_LENGTH:
+ case Tag::MIN_SECONDS_BETWEEN_OPS:
+ case Tag::MAX_USES_PER_BOOT:
+ case Tag::OS_VERSION:
+ case Tag::OS_PATCHLEVEL:
+ case Tag::MAC_LENGTH:
+ case Tag::AUTH_TIMEOUT:
+ return a.f.integer == b.f.integer;
+
+ /* Long integer tags */
+ case Tag::RSA_PUBLIC_EXPONENT:
+ case Tag::USER_SECURE_ID:
+ return a.f.longInteger == b.f.longInteger;
+
+ /* Date-time tags */
+ case Tag::ACTIVE_DATETIME:
+ case Tag::ORIGINATION_EXPIRE_DATETIME:
+ case Tag::USAGE_EXPIRE_DATETIME:
+ case Tag::CREATION_DATETIME:
+ return a.f.dateTime == b.f.dateTime;
+
+ /* Bytes tags */
+ case Tag::APPLICATION_ID:
+ case Tag::APPLICATION_DATA:
+ case Tag::ROOT_OF_TRUST:
+ case Tag::UNIQUE_ID:
+ case Tag::ATTESTATION_CHALLENGE:
+ case Tag::ATTESTATION_APPLICATION_ID:
+ case Tag::ATTESTATION_ID_BRAND:
+ case Tag::ATTESTATION_ID_DEVICE:
+ case Tag::ATTESTATION_ID_PRODUCT:
+ case Tag::ATTESTATION_ID_SERIAL:
+ case Tag::ATTESTATION_ID_IMEI:
+ case Tag::ATTESTATION_ID_MEID:
+ case Tag::ATTESTATION_ID_MANUFACTURER:
+ case Tag::ATTESTATION_ID_MODEL:
+ case Tag::ASSOCIATED_DATA:
+ case Tag::NONCE:
+ return a.blob == b.blob;
+
+ /* Enum tags */
+ case Tag::PURPOSE:
+ return a.f.purpose == b.f.purpose;
+ case Tag::ALGORITHM:
+ return a.f.algorithm == b.f.algorithm;
+ case Tag::BLOCK_MODE:
+ return a.f.blockMode == b.f.blockMode;
+ case Tag::DIGEST:
+ return a.f.digest == b.f.digest;
+ case Tag::PADDING:
+ return a.f.paddingMode == b.f.paddingMode;
+ case Tag::EC_CURVE:
+ return a.f.ecCurve == b.f.ecCurve;
+ case Tag::BLOB_USAGE_REQUIREMENTS:
+ return a.f.keyBlobUsageRequirements == b.f.keyBlobUsageRequirements;
+ case Tag::USER_AUTH_TYPE:
+ return a.f.integer == b.f.integer;
+ case Tag::ORIGIN:
+ return a.f.origin == b.f.origin;
+ case Tag::HARDWARE_TYPE:
+ return a.f.hardwareType == b.f.hardwareType;
+ }
+
+ return false;
+}
+
} // namespace V4_0
} // namespace keymaster
} // namespace hardware
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 cb6ade2..31d6ad1 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -52,92 +52,6 @@
namespace keymaster {
namespace V4_0 {
-bool operator==(const KeyParameter& a, const KeyParameter& b) {
- if (a.tag != b.tag) {
- return false;
- }
-
- switch (a.tag) {
- /* Boolean tags */
- case Tag::INVALID:
- case Tag::CALLER_NONCE:
- case Tag::INCLUDE_UNIQUE_ID:
- case Tag::BOOTLOADER_ONLY:
- case Tag::NO_AUTH_REQUIRED:
- case Tag::ALLOW_WHILE_ON_BODY:
- case Tag::ROLLBACK_RESISTANCE:
- case Tag::RESET_SINCE_ID_ROTATION:
- case Tag::TRUSTED_USER_PRESENCE_REQUIRED:
- return true;
-
- /* Integer tags */
- case Tag::KEY_SIZE:
- case Tag::MIN_MAC_LENGTH:
- case Tag::MIN_SECONDS_BETWEEN_OPS:
- case Tag::MAX_USES_PER_BOOT:
- case Tag::OS_VERSION:
- case Tag::OS_PATCHLEVEL:
- case Tag::MAC_LENGTH:
- case Tag::AUTH_TIMEOUT:
- return a.f.integer == b.f.integer;
-
- /* Long integer tags */
- case Tag::RSA_PUBLIC_EXPONENT:
- case Tag::USER_SECURE_ID:
- return a.f.longInteger == b.f.longInteger;
-
- /* Date-time tags */
- case Tag::ACTIVE_DATETIME:
- case Tag::ORIGINATION_EXPIRE_DATETIME:
- case Tag::USAGE_EXPIRE_DATETIME:
- case Tag::CREATION_DATETIME:
- return a.f.dateTime == b.f.dateTime;
-
- /* Bytes tags */
- case Tag::APPLICATION_ID:
- case Tag::APPLICATION_DATA:
- case Tag::ROOT_OF_TRUST:
- case Tag::UNIQUE_ID:
- case Tag::ATTESTATION_CHALLENGE:
- case Tag::ATTESTATION_APPLICATION_ID:
- case Tag::ATTESTATION_ID_BRAND:
- case Tag::ATTESTATION_ID_DEVICE:
- case Tag::ATTESTATION_ID_PRODUCT:
- case Tag::ATTESTATION_ID_SERIAL:
- case Tag::ATTESTATION_ID_IMEI:
- case Tag::ATTESTATION_ID_MEID:
- case Tag::ATTESTATION_ID_MANUFACTURER:
- case Tag::ATTESTATION_ID_MODEL:
- case Tag::ASSOCIATED_DATA:
- case Tag::NONCE:
- return a.blob == b.blob;
-
- /* Enum tags */
- case Tag::PURPOSE:
- return a.f.purpose == b.f.purpose;
- case Tag::ALGORITHM:
- return a.f.algorithm == b.f.algorithm;
- case Tag::BLOCK_MODE:
- return a.f.blockMode == b.f.blockMode;
- case Tag::DIGEST:
- return a.f.digest == b.f.digest;
- case Tag::PADDING:
- return a.f.paddingMode == b.f.paddingMode;
- case Tag::EC_CURVE:
- return a.f.ecCurve == b.f.ecCurve;
- case Tag::BLOB_USAGE_REQUIREMENTS:
- return a.f.keyBlobUsageRequirements == b.f.keyBlobUsageRequirements;
- case Tag::USER_AUTH_TYPE:
- return a.f.integer == b.f.integer;
- case Tag::ORIGIN:
- return a.f.origin == b.f.origin;
- case Tag::HARDWARE_TYPE:
- return a.f.hardwareType == b.f.hardwareType;
- }
-
- return false;
-}
-
bool operator==(const AuthorizationSet& a, const AuthorizationSet& b) {
return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());
}