audio: Fix handling of a thread exit command with a bad cookie

In case when the command was sent by the HAL itself (from another
thread), the worker thread must not post a reply. The only case
when a reply needs to be posted is in the case when the command
was sent from a VTS test. This case is identified by the fact that
the cookie has value '0'.

Bug: 300181540
Test: atest VtsHalAudioCoreTargetTest
Change-Id: Ifeb0722b5cf7346a694c5a938f6b324f5fa825f1
This commit is contained in:
Mikhail Naganov 2024-01-12 13:48:21 -08:00
parent e016befb4f
commit 1850779bc4
2 changed files with 19 additions and 13 deletions

View file

@ -180,17 +180,20 @@ StreamInWorkerLogic::Status StreamInWorkerLogic::cycle() {
StreamDescriptor::Reply reply{};
reply.status = STATUS_BAD_VALUE;
switch (command.getTag()) {
case Tag::halReservedExit:
if (const int32_t cookie = command.get<Tag::halReservedExit>();
cookie == (mContext->getInternalCommandCookie() ^ getTid())) {
case Tag::halReservedExit: {
const int32_t cookie = command.get<Tag::halReservedExit>();
if (cookie == (mContext->getInternalCommandCookie() ^ getTid())) {
mDriver->shutdown();
setClosed();
// This is an internal command, no need to reply.
return Status::EXIT;
} else {
LOG(WARNING) << __func__ << ": EXIT command has a bad cookie: " << cookie;
}
break;
if (cookie != 0) { // This is an internal command, no need to reply.
return Status::EXIT;
} else {
break;
}
}
case Tag::getStatus:
populateReply(&reply, mIsConnected);
break;
@ -400,17 +403,20 @@ StreamOutWorkerLogic::Status StreamOutWorkerLogic::cycle() {
reply.status = STATUS_BAD_VALUE;
using Tag = StreamDescriptor::Command::Tag;
switch (command.getTag()) {
case Tag::halReservedExit:
if (const int32_t cookie = command.get<Tag::halReservedExit>();
cookie == (mContext->getInternalCommandCookie() ^ getTid())) {
case Tag::halReservedExit: {
const int32_t cookie = command.get<Tag::halReservedExit>();
if (cookie == (mContext->getInternalCommandCookie() ^ getTid())) {
mDriver->shutdown();
setClosed();
// This is an internal command, no need to reply.
return Status::EXIT;
} else {
LOG(WARNING) << __func__ << ": EXIT command has a bad cookie: " << cookie;
}
break;
if (cookie != 0) { // This is an internal command, no need to reply.
return Status::EXIT;
} else {
break;
}
}
case Tag::getStatus:
populateReply(&reply, mIsConnected);
break;

View file

@ -90,7 +90,7 @@ class StreamContext {
std::weak_ptr<sounddose::StreamDataProcessorInterface> streamDataProcessor,
DebugParameters debugParameters)
: mCommandMQ(std::move(commandMQ)),
mInternalCommandCookie(std::rand()),
mInternalCommandCookie(std::rand() | 1 /* make sure it's not 0 */),
mReplyMQ(std::move(replyMQ)),
mFormat(format),
mChannelLayout(channelLayout),