Added audio service API to set active assistants.
Added API to manage the currently active assistants UIDs. When an
assistant can become active the API can be called to set voice
interaction service and corresponging trusted hotword service as active.
If there are no assistant UIDs in the active list the audio policy
service uses the default policy, which is to find the latest active
assistant and allow that to continue listening. This is to continue
support for legacy devices where the management of the active assistant
should be preserve.
Bug: 189312611
Test: m -j, and run assistant
Change-Id: I18984f3dcb8bf63dd16b3ae86d96dfbce39ced03
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 0479958..4da4ea0 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -2024,6 +2024,16 @@
return Status::ok();
}
+Status AudioPolicyService::setActiveAssistantServicesUids(
+ const std::vector<int32_t>& activeUidsAidl) {
+ std::vector<uid_t> activeUids;
+ RETURN_IF_BINDER_ERROR(convertInt32VectorToUidVectorWithLimit(activeUidsAidl, activeUids));
+
+ Mutex::Autolock _l(mLock);
+ mUidPolicy->setActiveAssistantUids(activeUids);
+ return Status::ok();
+}
+
Status AudioPolicyService::setA11yServicesUids(const std::vector<int32_t>& uidsAidl)
{
std::vector<uid_t> uids;
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index fb6b096..8263ad1 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -609,13 +609,20 @@
{
// Go over all active clients and allow capture (does not force silence) in the
// following cases:
-// The client is the assistant
+// The client is in the active assistant list
+// AND is TOP
+// AND an accessibility service is TOP
+// AND source is either VOICE_RECOGNITION OR HOTWORD
+// OR there is no active privacy sensitive capture or call
+// OR client has CAPTURE_AUDIO_OUTPUT privileged permission
+// AND source is VOICE_RECOGNITION OR HOTWORD
+// The client is an assistant AND active assistant is not being used
// AND an accessibility service is on TOP or a RTT call is active
// AND the source is VOICE_RECOGNITION or HOTWORD
-// OR uses VOICE_RECOGNITION AND is on TOP
-// OR uses HOTWORD
-// AND there is no active privacy sensitive capture or call
+// OR there is no active privacy sensitive capture or call
// OR client has CAPTURE_AUDIO_OUTPUT privileged permission
+// AND is TOP most recent assistant and uses VOICE_RECOGNITION or HOTWORD
+// OR there is no top recent assistant and source is HOTWORD
// OR The client is an accessibility service
// AND Is on TOP
// AND the source is VOICE_RECOGNITION or HOTWORD
@@ -643,13 +650,16 @@
sp<AudioRecordClient> latestActive;
sp<AudioRecordClient> topSensitiveActive;
sp<AudioRecordClient> latestSensitiveActiveOrComm;
+ sp<AudioRecordClient> latestActiveAssistant;
nsecs_t topStartNs = 0;
nsecs_t latestStartNs = 0;
nsecs_t topSensitiveStartNs = 0;
nsecs_t latestSensitiveStartNs = 0;
+ nsecs_t latestAssistantStartNs = 0;
bool isA11yOnTop = mUidPolicy->isA11yOnTop();
bool isAssistantOnTop = false;
+ bool useActiveAssistantList = false;
bool isSensitiveActive = false;
bool isInCall = mPhoneState == AUDIO_MODE_IN_CALL;
bool isInCommunication = mPhoneState == AUDIO_MODE_IN_COMMUNICATION;
@@ -684,6 +694,7 @@
// for top or latest active to avoid masking regular clients started before
if (!isAccessibility && !isVirtualSource(current->attributes.source)) {
bool isAssistant = mUidPolicy->isAssistantUid(currentUid);
+ bool isActiveAssistant = mUidPolicy->isActiveAssistantUid(currentUid);
bool isPrivacySensitive =
(current->attributes.flags & AUDIO_FLAG_CAPTURE_PRIVATE) != 0;
@@ -701,6 +712,14 @@
}
if (isAssistant) {
isAssistantOnTop = true;
+ if (isActiveAssistant) {
+ useActiveAssistantList = true;
+ } else if (!useActiveAssistantList) {
+ if (current->startTimeNs > latestAssistantStartNs) {
+ latestActiveAssistant = current;
+ latestAssistantStartNs = current->startTimeNs;
+ }
+ }
}
}
// Clients capturing for HOTWORD are not considered
@@ -780,6 +799,8 @@
current->attributionSource.uid == topActive->attributionSource.uid;
bool isTopOrLatestSensitive = topSensitiveActive == nullptr ? false :
current->attributionSource.uid == topSensitiveActive->attributionSource.uid;
+ bool isTopOrLatestAssistant = latestActiveAssistant == nullptr ? false :
+ current->attributionSource.uid == latestActiveAssistant->attributionSource.uid;
auto canCaptureIfInCallOrCommunication = [&](const auto &recordClient) REQUIRES(mLock) {
uid_t recordUid = VALUE_OR_FATAL(aidl2legacy_int32_t_uid_t(
@@ -809,23 +830,45 @@
} else if (isVirtualSource(source)) {
// Allow capture for virtual (remote submix, call audio TX or RX...) sources
allowCapture = true;
- } else if (mUidPolicy->isAssistantUid(currentUid)) {
+ } else if (!useActiveAssistantList && mUidPolicy->isAssistantUid(currentUid)) {
// For assistant allow capture if:
- // An accessibility service is on TOP or a RTT call is active
+ // Active assistant list is not being used
+ // AND accessibility service is on TOP or a RTT call is active
// AND the source is VOICE_RECOGNITION or HOTWORD
- // OR is on TOP AND uses VOICE_RECOGNITION
- // OR uses HOTWORD
- // AND there is no active privacy sensitive capture or call
- // OR client has CAPTURE_AUDIO_OUTPUT privileged permission
+ // OR there is no active privacy sensitive capture or call
+ // OR client has CAPTURE_AUDIO_OUTPUT privileged permission
+ // AND is latest TOP assistant AND
+ // uses VOICE_RECOGNITION OR uses HOTWORD
+ // OR there is no TOP assistant and uses HOTWORD
if (isA11yOnTop || rttCallActive) {
if (source == AUDIO_SOURCE_HOTWORD || source == AUDIO_SOURCE_VOICE_RECOGNITION) {
allowCapture = true;
}
- } else {
- if (((isAssistantOnTop && source == AUDIO_SOURCE_VOICE_RECOGNITION) ||
- source == AUDIO_SOURCE_HOTWORD)
- && !(isSensitiveActive && !current->canCaptureOutput)
+ } else if (!(isSensitiveActive && !current->canCaptureOutput)
+ && canCaptureIfInCallOrCommunication(current)) {
+ if (isTopOrLatestAssistant
+ && (source == AUDIO_SOURCE_VOICE_RECOGNITION
+ || source == AUDIO_SOURCE_HOTWORD)) {
+ allowCapture = true;
+ } else if (!isAssistantOnTop && (source == AUDIO_SOURCE_HOTWORD)) {
+ allowCapture = true;
+ }
+ }
+ } else if (useActiveAssistantList && mUidPolicy->isActiveAssistantUid(currentUid)) {
+ // For assistant on active list and on top allow capture if:
+ // An accessibility service is on TOP
+ // AND the source is VOICE_RECOGNITION or HOTWORD
+ // OR there is no active privacy sensitive capture or call
+ // OR client has CAPTURE_AUDIO_OUTPUT privileged permission
+ // AND uses VOICE_RECOGNITION OR uses HOTWORD
+ if (isA11yOnTop) {
+ if (source == AUDIO_SOURCE_HOTWORD || source == AUDIO_SOURCE_VOICE_RECOGNITION) {
+ allowCapture = true;
+ }
+ } else if (!(isSensitiveActive && !current->canCaptureOutput)
&& canCaptureIfInCallOrCommunication(current)) {
+ if ((source == AUDIO_SOURCE_VOICE_RECOGNITION) || (source == AUDIO_SOURCE_HOTWORD))
+ {
allowCapture = true;
}
}
@@ -1039,6 +1082,7 @@
case TRANSACTION_getReportedSurroundFormats:
case TRANSACTION_setSurroundFormatEnabled:
case TRANSACTION_setAssistantServicesUids:
+ case TRANSACTION_setActiveAssistantServicesUids:
case TRANSACTION_setA11yServicesUids:
case TRANSACTION_setUidDeviceAffinities:
case TRANSACTION_removeUidDeviceAffinities:
@@ -1487,6 +1531,17 @@
return it != mAssistantUids.end();
}
+void AudioPolicyService::UidPolicy::setActiveAssistantUids(const std::vector<uid_t>& activeUids) {
+ mActiveAssistantUids = activeUids;
+}
+
+bool AudioPolicyService::UidPolicy::isActiveAssistantUid(uid_t uid)
+{
+ std::vector<uid_t>::iterator it = find(mActiveAssistantUids.begin(),
+ mActiveAssistantUids.end(), uid);
+ return it != mActiveAssistantUids.end();
+}
+
void AudioPolicyService::UidPolicy::dumpInternals(int fd) {
const size_t SIZE = 256;
char buffer[SIZE];
@@ -1512,6 +1567,7 @@
result.append(buffer);
appendUidsToResult("Assistants UIDs", mAssistantUids);
+ appendUidsToResult("Active Assistants UIDs", mActiveAssistantUids);
appendUidsToResult("Accessibility UIDs", mA11yUids);
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 3be3a1b..ae65a65 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -219,6 +219,7 @@
binder::Status setSurroundFormatEnabled(const AudioFormatDescription& audioFormat,
bool enabled) override;
binder::Status setAssistantServicesUids(const std::vector<int32_t>& uids) override;
+ binder::Status setActiveAssistantServicesUids(const std::vector<int32_t>& activeUids) override;
binder::Status setA11yServicesUids(const std::vector<int32_t>& uids) override;
binder::Status setCurrentImeUid(int32_t uid) override;
binder::Status isHapticPlaybackSupported(bool* _aidl_return) override;
@@ -432,6 +433,8 @@
int getUidState(uid_t uid);
void setAssistantUids(const std::vector<uid_t>& uids);
bool isAssistantUid(uid_t uid);
+ void setActiveAssistantUids(const std::vector<uid_t>& activeUids);
+ bool isActiveAssistantUid(uid_t uid);
void setA11yUids(const std::vector<uid_t>& uids) { mA11yUids.clear(); mA11yUids = uids; }
bool isA11yUid(uid_t uid);
bool isA11yOnTop();
@@ -469,6 +472,7 @@
std::unordered_map<uid_t, std::pair<bool, int>> mOverrideUids;
std::unordered_map<uid_t, std::pair<bool, int>> mCachedUids;
std::vector<uid_t> mAssistantUids;
+ std::vector<uid_t> mActiveAssistantUids;
std::vector<uid_t> mA11yUids;
uid_t mCurrentImeUid = -1;
bool mRttEnabled = false;