Merge changes from topic "set_assistants_uid"
* changes:
Added audio service API to set active assistants.
Added mechanism for setting multiple UIDs as assistants.
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 40efb38..32c77c7 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -1911,20 +1911,22 @@
aps->setSurroundFormatEnabled(audioFormatAidl, enabled));
}
-status_t AudioSystem::setAssistantUid(uid_t uid) {
+status_t AudioSystem::setAssistantServicesUids(const std::vector<uid_t>& uids) {
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- int32_t uidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(uid));
- return statusTFromBinderStatus(aps->setAssistantUid(uidAidl));
+ std::vector<int32_t> uidsAidl = VALUE_OR_RETURN_STATUS(
+ convertContainer<std::vector<int32_t>>(uids, legacy2aidl_uid_t_int32_t));
+ return statusTFromBinderStatus(aps->setAssistantServicesUids(uidsAidl));
}
-status_t AudioSystem::setHotwordDetectionServiceUid(uid_t uid) {
+status_t AudioSystem::setActiveAssistantServicesUids(const std::vector<uid_t>& activeUids) {
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- int32_t uidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(uid));
- return statusTFromBinderStatus(aps->setHotwordDetectionServiceUid(uidAidl));
+ std::vector<int32_t> activeUidsAidl = VALUE_OR_RETURN_STATUS(
+ convertContainer<std::vector<int32_t>>(activeUids, legacy2aidl_uid_t_int32_t));
+ return statusTFromBinderStatus(aps->setActiveAssistantServicesUids(activeUidsAidl));
}
status_t AudioSystem::setA11yServicesUids(const std::vector<uid_t>& uids) {
diff --git a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
index 69328a7..de0f75b 100644
--- a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
@@ -302,9 +302,9 @@
void setSurroundFormatEnabled(in AudioFormatDescription audioFormat, boolean enabled);
- void setAssistantUid(int /* uid_t */ uid);
+ void setAssistantServicesUids(in int[] /* uid_t[] */ uids);
- void setHotwordDetectionServiceUid(int /* uid_t */ uid);
+ void setActiveAssistantServicesUids(in int[] /* uid_t[] */ activeUids);
void setA11yServicesUids(in int[] /* uid_t[] */ uids);
diff --git a/media/libaudioclient/include/media/AidlConversionUtil.h b/media/libaudioclient/include/media/AidlConversionUtil.h
index 4d16792..820b7cb 100644
--- a/media/libaudioclient/include/media/AidlConversionUtil.h
+++ b/media/libaudioclient/include/media/AidlConversionUtil.h
@@ -77,6 +77,26 @@
}
/**
+ * A generic template that helps convert containers of convertible types, using iterators.
+ * Uses a limit as maximum conversion items.
+ */
+template<typename InputIterator, typename OutputIterator, typename Func>
+status_t convertRangeWithLimit(InputIterator start,
+ InputIterator end,
+ OutputIterator out,
+ const Func& itemConversion,
+ const size_t limit) {
+ InputIterator last = end;
+ if (end - start > limit) {
+ last = start + limit;
+ }
+ for (InputIterator iter = start; (iter != last); ++iter, ++out) {
+ *out = VALUE_OR_RETURN_STATUS(itemConversion(*iter));
+ }
+ return OK;
+}
+
+/**
* A generic template that helps convert containers of convertible types.
*/
template<typename OutputContainer, typename InputContainer, typename Func>
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index e0cb47e..baefee3 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -438,8 +438,9 @@
audio_format_t *surroundFormats);
static status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled);
- static status_t setAssistantUid(uid_t uid);
- static status_t setHotwordDetectionServiceUid(uid_t uid);
+ static status_t setAssistantServicesUids(const std::vector<uid_t>& uids);
+ static status_t setActiveAssistantServicesUids(const std::vector<uid_t>& activeUids);
+
static status_t setA11yServicesUids(const std::vector<uid_t>& uids);
static status_t setCurrentImeUid(uid_t uid);
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 582c048..4da4ea0 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -2002,34 +2002,43 @@
mAudioPolicyManager->setSurroundFormatEnabled(audioFormat, enabled));
}
-Status AudioPolicyService::setAssistantUid(int32_t uidAidl)
-{
- uid_t uid = VALUE_OR_RETURN_BINDER_STATUS(aidl2legacy_int32_t_uid_t(uidAidl));
- Mutex::Autolock _l(mLock);
- mUidPolicy->setAssistantUid(uid);
+Status convertInt32VectorToUidVectorWithLimit(
+ const std::vector<int32_t>& uidsAidl, std::vector<uid_t>& uids) {
+ RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
+ convertRangeWithLimit(uidsAidl.begin(),
+ uidsAidl.end(),
+ std::back_inserter(uids),
+ aidl2legacy_int32_t_uid_t,
+ MAX_ITEMS_PER_LIST)));
+
return Status::ok();
}
-Status AudioPolicyService::setHotwordDetectionServiceUid(int32_t uidAidl)
+Status AudioPolicyService::setAssistantServicesUids(const std::vector<int32_t>& uidsAidl)
{
- uid_t uid = VALUE_OR_RETURN_BINDER_STATUS(aidl2legacy_int32_t_uid_t(uidAidl));
+ std::vector<uid_t> uids;
+ RETURN_IF_BINDER_ERROR(convertInt32VectorToUidVectorWithLimit(uidsAidl, uids));
+
Mutex::Autolock _l(mLock);
- mUidPolicy->setHotwordDetectionServiceUid(uid);
+ mUidPolicy->setAssistantUids(uids);
+ 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)
{
- size_t size = uidsAidl.size();
- if (size > MAX_ITEMS_PER_LIST) {
- size = MAX_ITEMS_PER_LIST;
- }
std::vector<uid_t> uids;
- RETURN_IF_BINDER_ERROR(binderStatusFromStatusT(
- convertRange(uidsAidl.begin(),
- uidsAidl.begin() + size,
- std::back_inserter(uids),
- aidl2legacy_int32_t_uid_t)));
+ RETURN_IF_BINDER_ERROR(convertInt32VectorToUidVectorWithLimit(uidsAidl, uids));
+
Mutex::Autolock _l(mLock);
mUidPolicy->setA11yUids(uids);
return Status::ok();
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 8add137..8263ad1 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -594,6 +594,8 @@
}
write(fd, result.string(), result.size());
+
+ mUidPolicy->dumpInternals(fd);
return NO_ERROR;
}
@@ -607,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
@@ -641,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;
@@ -682,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;
@@ -699,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
@@ -778,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(
@@ -807,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;
}
}
@@ -1036,7 +1081,8 @@
case TRANSACTION_getSurroundFormats:
case TRANSACTION_getReportedSurroundFormats:
case TRANSACTION_setSurroundFormatEnabled:
- case TRANSACTION_setAssistantUid:
+ case TRANSACTION_setAssistantServicesUids:
+ case TRANSACTION_setActiveAssistantServicesUids:
case TRANSACTION_setA11yServicesUids:
case TRANSACTION_setUidDeviceAffinities:
case TRANSACTION_removeUidDeviceAffinities:
@@ -1474,6 +1520,66 @@
return it != mA11yUids.end();
}
+void AudioPolicyService::UidPolicy::setAssistantUids(const std::vector<uid_t>& uids) {
+ mAssistantUids.clear();
+ mAssistantUids = uids;
+}
+
+bool AudioPolicyService::UidPolicy::isAssistantUid(uid_t uid)
+{
+ std::vector<uid_t>::iterator it = find(mAssistantUids.begin(), mAssistantUids.end(), uid);
+ 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];
+ String8 result;
+ auto appendUidsToResult = [&](const char* title, const std::vector<uid_t> &uids) {
+ snprintf(buffer, SIZE, "\t%s: \n", title);
+ result.append(buffer);
+ int counter = 0;
+ if (uids.empty()) {
+ snprintf(buffer, SIZE, "\t\tNo UIDs present.\n");
+ result.append(buffer);
+ return;
+ }
+ for (const auto &uid : uids) {
+ snprintf(buffer, SIZE, "\t\tUID[%d]=%d\n", counter++, uid);
+ result.append(buffer);
+ }
+ };
+
+ snprintf(buffer, SIZE, "UID Policy:\n");
+ result.append(buffer);
+ snprintf(buffer, SIZE, "\tmObserverRegistered=%s\n",(mObserverRegistered ? "True":"False"));
+ result.append(buffer);
+
+ appendUidsToResult("Assistants UIDs", mAssistantUids);
+ appendUidsToResult("Active Assistants UIDs", mActiveAssistantUids);
+
+ appendUidsToResult("Accessibility UIDs", mA11yUids);
+
+ snprintf(buffer, SIZE, "\tInput Method Service UID=%d\n", mCurrentImeUid);
+ result.append(buffer);
+
+ snprintf(buffer, SIZE, "\tIs RTT Enabled: %s\n", (mRttEnabled ? "True":"False"));
+ result.append(buffer);
+
+ write(fd, result.string(), result.size());
+}
+
// ----------- AudioPolicyService::SensorPrivacyService implementation ----------
void AudioPolicyService::SensorPrivacyPolicy::registerSelf() {
SensorPrivacyManager spm;
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 39f2c97..ae65a65 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -218,8 +218,8 @@
std::vector<AudioFormatDescription>* _aidl_return) override;
binder::Status setSurroundFormatEnabled(const AudioFormatDescription& audioFormat,
bool enabled) override;
- binder::Status setAssistantUid(int32_t uid) override;
- binder::Status setHotwordDetectionServiceUid(int32_t uid) 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;
@@ -420,7 +420,7 @@
public:
explicit UidPolicy(wp<AudioPolicyService> service)
: mService(service), mObserverRegistered(false),
- mAssistantUid(0), mHotwordDetectionServiceUid(0), mCurrentImeUid(0),
+ mCurrentImeUid(0),
mRttEnabled(false) {}
void registerSelf();
@@ -431,13 +431,10 @@
bool isUidActive(uid_t uid);
int getUidState(uid_t uid);
- void setAssistantUid(uid_t uid) { mAssistantUid = uid; };
- void setHotwordDetectionServiceUid(uid_t uid) { mHotwordDetectionServiceUid = uid; }
- bool isAssistantUid(uid_t uid) const {
- // The HotwordDetectionService is part of the Assistant package but runs with a separate
- // (isolated) uid, so we check for either uid here.
- return uid == mAssistantUid || uid == mHotwordDetectionServiceUid;
- }
+ 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();
@@ -459,6 +456,8 @@
void updateUid(std::unordered_map<uid_t, std::pair<bool, int>> *uids,
uid_t uid, bool active, int state, bool insert);
+ void dumpInternals(int fd);
+
private:
void notifyService();
void updateOverrideUid(uid_t uid, bool active, bool insert);
@@ -472,8 +471,8 @@
bool mObserverRegistered = false;
std::unordered_map<uid_t, std::pair<bool, int>> mOverrideUids;
std::unordered_map<uid_t, std::pair<bool, int>> mCachedUids;
- uid_t mAssistantUid = -1;
- uid_t mHotwordDetectionServiceUid = -1;
+ std::vector<uid_t> mAssistantUids;
+ std::vector<uid_t> mActiveAssistantUids;
std::vector<uid_t> mA11yUids;
uid_t mCurrentImeUid = -1;
bool mRttEnabled = false;