Revert "Revert "audio policy: concurrent capture""
This reverts commit df628924e691e01da190c1ac5db173304442e54a.
Bug: 120588242
Bug: 111438757
Test: make
Change-Id: If58ff2143fdb744678bb84394598104ced01f5b9
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 78dbf5f..2893872 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -348,11 +348,91 @@
void AudioPolicyService::updateUidStates_l()
{
- //TODO: implement real concurrent capture policy: for now just apply each app state directly
+// Go over all active clients and allow capture (does not force silence) in the
+// following cases:
+// - The client is the assistant AND
+// an accessibility service is on TOP AND the source is VOICE_RECOGNITION or HOTWORD
+// OR
+// is on TOP AND uses VOICE_RECOGNITION
+// OR uses HOTWORD AND there is no privacy sensitive active capture
+// - The client is an accessibility service AND
+// is on TOP AND the source is VOICE_RECOGNITION or HOTWORD
+// - Any other client AND
+// The assistant is not on TOP AND
+// is on TOP OR latest started AND
+// there is no privacy sensitive active capture
+//TODO: mamanage pre processing effects according to use case priority
+
+ sp<AudioRecordClient> topActive;
+ sp<AudioRecordClient> latestActive;
+ nsecs_t latestStartNs = 0;
+ sp<AudioRecordClient> latestSensitiveActive;
+ nsecs_t latestSensitiveStartNs = 0;
+ bool isA11yOnTop = mUidPolicy->isA11yOnTop();
+ bool isAssistantOnTop = false;
+ bool isSensitiveActive = false;
+
for (size_t i =0; i < mAudioRecordClients.size(); i++) {
sp<AudioRecordClient> current = mAudioRecordClients[i];
if (!current->active) continue;
- setAppState_l(current->uid, apmStatFromAmState(mUidPolicy->getUidState(current->uid)));
+ if (isPrivacySensitive(current->attributes.source)) {
+ if (current->startTimeNs > latestSensitiveStartNs) {
+ latestSensitiveActive = current;
+ latestSensitiveStartNs = current->startTimeNs;
+ }
+ isSensitiveActive = true;
+ }
+ if (mUidPolicy->getUidState(current->uid) == ActivityManager::PROCESS_STATE_TOP) {
+ topActive = current;
+ latestActive = nullptr;
+ if (mUidPolicy->isAssistantUid(current->uid)) {
+ isAssistantOnTop = true;
+ }
+ }
+ if (current->startTimeNs > latestStartNs) {
+ latestActive = current;
+ latestStartNs = current->startTimeNs;
+ }
+ }
+
+ if (topActive == nullptr && latestActive == nullptr) {
+ return;
+ }
+
+ for (size_t i =0; i < mAudioRecordClients.size(); i++) {
+ sp<AudioRecordClient> current = mAudioRecordClients[i];
+ if (!current->active) continue;
+
+ audio_source_t source = current->attributes.source;
+ bool isOnTop = mUidPolicy->getUidState(current->uid) == ActivityManager::PROCESS_STATE_TOP;
+ bool isLatest = current == latestActive;
+ bool isLatestSensitive = current == latestSensitiveActive;
+ bool forceIdle = true;
+ if (mUidPolicy->isAssistantUid(current->uid)) {
+ if (isA11yOnTop) {
+ if (source == AUDIO_SOURCE_HOTWORD || source == AUDIO_SOURCE_VOICE_RECOGNITION) {
+ forceIdle = false;
+ }
+ } else {
+ if (((isOnTop && source == AUDIO_SOURCE_VOICE_RECOGNITION) ||
+ source == AUDIO_SOURCE_HOTWORD) && !isSensitiveActive) {
+ forceIdle = false;
+ }
+ }
+ } else if (mUidPolicy->isA11yUid(current->uid)) {
+ if (isOnTop &&
+ (source == AUDIO_SOURCE_VOICE_RECOGNITION || source == AUDIO_SOURCE_HOTWORD)) {
+ forceIdle = false;
+ }
+ } else {
+ if (!isAssistantOnTop && (isOnTop || (topActive == nullptr && isLatest)) &&
+ (!isSensitiveActive || isLatestSensitive)) {
+ forceIdle = false;
+ }
+ }
+ setAppState_l(current->uid,
+ forceIdle ? APP_STATE_IDLE :
+ apmStatFromAmState(mUidPolicy->getUidState(current->uid)));
}
}
@@ -369,6 +449,22 @@
return APP_STATE_FOREGROUND;
}
+/* static */
+bool AudioPolicyService::isPrivacySensitive(audio_source_t source)
+{
+ switch (source) {
+ case AUDIO_SOURCE_VOICE_UPLINK:
+ case AUDIO_SOURCE_VOICE_DOWNLINK:
+ case AUDIO_SOURCE_VOICE_CALL:
+ case AUDIO_SOURCE_CAMCORDER:
+ case AUDIO_SOURCE_VOICE_COMMUNICATION:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
void AudioPolicyService::setAppState_l(uid_t uid, app_state_t state)
{
AutoCallerClear acc;
@@ -548,6 +644,7 @@
mObserverRegistered = true;
} else {
ALOGE("UidPolicy::registerSelf linkToDeath failed: %d", res);
+
am.unregisterUidObserver(this);
}
}
@@ -650,6 +747,7 @@
mCachedUids.insert(std::pair<uid_t,
std::pair<bool, int>>(uid, std::pair<bool, int>(active, state)));
}
+
return state;
}
@@ -730,6 +828,21 @@
}
}
+bool AudioPolicyService::UidPolicy::isA11yOnTop() {
+ for (const auto &uid : mCachedUids) {
+ std::vector<uid_t>::iterator it = find(mA11yUids.begin(), mA11yUids.end(), uid.first);
+ if (it == mA11yUids.end()) {
+ continue;
+ }
+ if (uid.second.second == ActivityManager::PROCESS_STATE_TOP ||
+ uid.second.second == ActivityManager::PROCESS_STATE_FOREGROUND_SERVICE ||
+ uid.second.second == ActivityManager::PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
+ return true;
+ }
+ }
+ return false;
+}
+
bool AudioPolicyService::UidPolicy::isA11yUid(uid_t uid)
{
std::vector<uid_t>::iterator it = find(mA11yUids.begin(), mA11yUids.end(), uid);