Loading services/audiopolicy/service/AudioPolicyService.cpp +78 −34 Original line number Diff line number Diff line Loading @@ -446,17 +446,19 @@ void AudioPolicyService::updateUidStates_l() sp<AudioRecordClient> topActive; sp<AudioRecordClient> latestActive; sp<AudioRecordClient> topSensitiveActive; sp<AudioRecordClient> latestSensitiveActive; nsecs_t topStartNs = 0; nsecs_t latestStartNs = 0; nsecs_t topSensitiveStartNs = 0; nsecs_t latestSensitiveStartNs = 0; bool isA11yOnTop = mUidPolicy->isA11yOnTop(); bool isAssistantOnTop = false; bool isSensitiveActive = false; bool isInCall = mPhoneState == AUDIO_MODE_IN_CALL; bool rttCallActive = (mPhoneState == AUDIO_MODE_IN_CALL || mPhoneState == AUDIO_MODE_IN_COMMUNICATION) bool isInCommunication = mPhoneState == AUDIO_MODE_IN_COMMUNICATION; bool rttCallActive = (isInCall || isInCommunication) && mUidPolicy->isRttEnabled(); bool onlyHotwordActive = true; Loading @@ -479,32 +481,46 @@ void AudioPolicyService::updateUidStates_l() continue; } bool isAssistant = mUidPolicy->isAssistantUid(current->uid); bool isAccessibility = mUidPolicy->isA11yUid(current->uid); if (appState == APP_STATE_TOP && !isAccessibility) { // Clients capturing for Accessibility services are not considered // for top or latest active to avoid masking regular clients started before if (!isAccessibility) { bool isAssistant = mUidPolicy->isAssistantUid(current->uid); bool isPrivacySensitive = (current->attributes.flags & AUDIO_FLAG_CAPTURE_PRIVATE) != 0; if (appState == APP_STATE_TOP) { if (isPrivacySensitive) { if (current->startTimeNs > topSensitiveStartNs) { topSensitiveActive = current; topSensitiveStartNs = current->startTimeNs; } } else { if (current->startTimeNs > topStartNs) { topActive = current; topStartNs = current->startTimeNs; } } if (isAssistant) { isAssistantOnTop = true; } } // Client capturing for HOTWORD or Accessibility services not considered // Clients capturing for HOTWORD are not considered // for latest active to avoid masking regular clients started before if (current->startTimeNs > latestStartNs && !(current->attributes.source == AUDIO_SOURCE_HOTWORD || ((isA11yOnTop || rttCallActive) && isAssistant)) && !isAccessibility) { latestActive = current; latestStartNs = current->startTimeNs; } if ((current->attributes.flags & AUDIO_FLAG_CAPTURE_PRIVATE) != 0) { if (!(current->attributes.source == AUDIO_SOURCE_HOTWORD || ((isA11yOnTop || rttCallActive) && isAssistant))) { if (isPrivacySensitive) { if (current->startTimeNs > latestSensitiveStartNs) { latestSensitiveActive = current; latestSensitiveStartNs = current->startTimeNs; } isSensitiveActive = true; } else { if (current->startTimeNs > latestStartNs) { latestActive = current; latestStartNs = current->startTimeNs; } } } } if (current->attributes.source != AUDIO_SOURCE_HOTWORD) { onlyHotwordActive = false; Loading @@ -514,6 +530,21 @@ void AudioPolicyService::updateUidStates_l() // if no active client with UI on Top, consider latest active as top if (topActive == nullptr) { topActive = latestActive; topStartNs = latestStartNs; } if (topSensitiveActive == nullptr) { topSensitiveActive = latestSensitiveActive; topSensitiveStartNs = latestSensitiveStartNs; } // If both privacy sensitive and regular capture are active: // if the regular capture is privileged // allow concurrency // else // favor the privacy sensitive case if (topActive != nullptr && topSensitiveActive != nullptr && !topActive->canCaptureCallOrOutput) { topActive = nullptr; } for (size_t i =0; i < mAudioRecordClients.size(); i++) { Loading @@ -524,8 +555,17 @@ void AudioPolicyService::updateUidStates_l() audio_source_t source = current->attributes.source; bool isTopOrLatestActive = topActive == nullptr ? false : current->uid == topActive->uid; bool isLatestSensitive = latestSensitiveActive == nullptr ? false : current->uid == latestSensitiveActive->uid; bool isTopOrLatestSensitive = topSensitiveActive == nullptr ? false : current->uid == topSensitiveActive->uid; auto canCaptureIfInCallOrCommunication = [&](const auto &recordClient) { bool canCaptureCall = recordClient->canCaptureCallOrOutput; bool canCaptureCommunication = recordClient->canCaptureCallOrOutput || recordClient->uid == mPhoneStateOwnerUid || isServiceUid(mPhoneStateOwnerUid); return !(isInCall && !canCaptureCall) && !(isInCommunication && !canCaptureCommunication); }; // By default allow capture if: // The assistant is not on TOP Loading @@ -533,9 +573,10 @@ void AudioPolicyService::updateUidStates_l() // AND there is no active privacy sensitive capture or call // OR client has CAPTURE_AUDIO_OUTPUT privileged permission bool allowCapture = !isAssistantOnTop && ((isTopOrLatestActive && !isLatestSensitive) || isLatestSensitive) && !(isSensitiveActive && !(isLatestSensitive || current->canCaptureCallOrOutput)) && !(isInCall && !current->canCaptureCallOrOutput); && (isTopOrLatestActive || isTopOrLatestSensitive) && !(isSensitiveActive && !(isTopOrLatestSensitive || current->canCaptureCallOrOutput)) && canCaptureIfInCallOrCommunication(current); if (isVirtualSource(source)) { // Allow capture for virtual (remote submix, call audio TX or RX...) sources Loading @@ -554,8 +595,9 @@ void AudioPolicyService::updateUidStates_l() } } else { if (((isAssistantOnTop && source == AUDIO_SOURCE_VOICE_RECOGNITION) || source == AUDIO_SOURCE_HOTWORD) && (!(isSensitiveActive || isInCall) || current->canCaptureCallOrOutput)) { source == AUDIO_SOURCE_HOTWORD) && !(isSensitiveActive && !current->canCaptureCallOrOutput) && canCaptureIfInCallOrCommunication(current)) { allowCapture = true; } } Loading @@ -567,7 +609,8 @@ void AudioPolicyService::updateUidStates_l() // OR // Is on TOP AND the source is VOICE_RECOGNITION or HOTWORD if (!isAssistantOnTop && (!(isSensitiveActive || isInCall) || current->canCaptureCallOrOutput)) { && !(isSensitiveActive && !current->canCaptureCallOrOutput) && canCaptureIfInCallOrCommunication(current)) { allowCapture = true; } if (isA11yOnTop) { Loading @@ -580,7 +623,8 @@ void AudioPolicyService::updateUidStates_l() // All active clients are using HOTWORD source // AND no call is active // OR client has CAPTURE_AUDIO_OUTPUT privileged permission if (onlyHotwordActive && !(isInCall && !current->canCaptureCallOrOutput)) { if (onlyHotwordActive && canCaptureIfInCallOrCommunication(current)) { allowCapture = true; } } Loading Loading
services/audiopolicy/service/AudioPolicyService.cpp +78 −34 Original line number Diff line number Diff line Loading @@ -446,17 +446,19 @@ void AudioPolicyService::updateUidStates_l() sp<AudioRecordClient> topActive; sp<AudioRecordClient> latestActive; sp<AudioRecordClient> topSensitiveActive; sp<AudioRecordClient> latestSensitiveActive; nsecs_t topStartNs = 0; nsecs_t latestStartNs = 0; nsecs_t topSensitiveStartNs = 0; nsecs_t latestSensitiveStartNs = 0; bool isA11yOnTop = mUidPolicy->isA11yOnTop(); bool isAssistantOnTop = false; bool isSensitiveActive = false; bool isInCall = mPhoneState == AUDIO_MODE_IN_CALL; bool rttCallActive = (mPhoneState == AUDIO_MODE_IN_CALL || mPhoneState == AUDIO_MODE_IN_COMMUNICATION) bool isInCommunication = mPhoneState == AUDIO_MODE_IN_COMMUNICATION; bool rttCallActive = (isInCall || isInCommunication) && mUidPolicy->isRttEnabled(); bool onlyHotwordActive = true; Loading @@ -479,32 +481,46 @@ void AudioPolicyService::updateUidStates_l() continue; } bool isAssistant = mUidPolicy->isAssistantUid(current->uid); bool isAccessibility = mUidPolicy->isA11yUid(current->uid); if (appState == APP_STATE_TOP && !isAccessibility) { // Clients capturing for Accessibility services are not considered // for top or latest active to avoid masking regular clients started before if (!isAccessibility) { bool isAssistant = mUidPolicy->isAssistantUid(current->uid); bool isPrivacySensitive = (current->attributes.flags & AUDIO_FLAG_CAPTURE_PRIVATE) != 0; if (appState == APP_STATE_TOP) { if (isPrivacySensitive) { if (current->startTimeNs > topSensitiveStartNs) { topSensitiveActive = current; topSensitiveStartNs = current->startTimeNs; } } else { if (current->startTimeNs > topStartNs) { topActive = current; topStartNs = current->startTimeNs; } } if (isAssistant) { isAssistantOnTop = true; } } // Client capturing for HOTWORD or Accessibility services not considered // Clients capturing for HOTWORD are not considered // for latest active to avoid masking regular clients started before if (current->startTimeNs > latestStartNs && !(current->attributes.source == AUDIO_SOURCE_HOTWORD || ((isA11yOnTop || rttCallActive) && isAssistant)) && !isAccessibility) { latestActive = current; latestStartNs = current->startTimeNs; } if ((current->attributes.flags & AUDIO_FLAG_CAPTURE_PRIVATE) != 0) { if (!(current->attributes.source == AUDIO_SOURCE_HOTWORD || ((isA11yOnTop || rttCallActive) && isAssistant))) { if (isPrivacySensitive) { if (current->startTimeNs > latestSensitiveStartNs) { latestSensitiveActive = current; latestSensitiveStartNs = current->startTimeNs; } isSensitiveActive = true; } else { if (current->startTimeNs > latestStartNs) { latestActive = current; latestStartNs = current->startTimeNs; } } } } if (current->attributes.source != AUDIO_SOURCE_HOTWORD) { onlyHotwordActive = false; Loading @@ -514,6 +530,21 @@ void AudioPolicyService::updateUidStates_l() // if no active client with UI on Top, consider latest active as top if (topActive == nullptr) { topActive = latestActive; topStartNs = latestStartNs; } if (topSensitiveActive == nullptr) { topSensitiveActive = latestSensitiveActive; topSensitiveStartNs = latestSensitiveStartNs; } // If both privacy sensitive and regular capture are active: // if the regular capture is privileged // allow concurrency // else // favor the privacy sensitive case if (topActive != nullptr && topSensitiveActive != nullptr && !topActive->canCaptureCallOrOutput) { topActive = nullptr; } for (size_t i =0; i < mAudioRecordClients.size(); i++) { Loading @@ -524,8 +555,17 @@ void AudioPolicyService::updateUidStates_l() audio_source_t source = current->attributes.source; bool isTopOrLatestActive = topActive == nullptr ? false : current->uid == topActive->uid; bool isLatestSensitive = latestSensitiveActive == nullptr ? false : current->uid == latestSensitiveActive->uid; bool isTopOrLatestSensitive = topSensitiveActive == nullptr ? false : current->uid == topSensitiveActive->uid; auto canCaptureIfInCallOrCommunication = [&](const auto &recordClient) { bool canCaptureCall = recordClient->canCaptureCallOrOutput; bool canCaptureCommunication = recordClient->canCaptureCallOrOutput || recordClient->uid == mPhoneStateOwnerUid || isServiceUid(mPhoneStateOwnerUid); return !(isInCall && !canCaptureCall) && !(isInCommunication && !canCaptureCommunication); }; // By default allow capture if: // The assistant is not on TOP Loading @@ -533,9 +573,10 @@ void AudioPolicyService::updateUidStates_l() // AND there is no active privacy sensitive capture or call // OR client has CAPTURE_AUDIO_OUTPUT privileged permission bool allowCapture = !isAssistantOnTop && ((isTopOrLatestActive && !isLatestSensitive) || isLatestSensitive) && !(isSensitiveActive && !(isLatestSensitive || current->canCaptureCallOrOutput)) && !(isInCall && !current->canCaptureCallOrOutput); && (isTopOrLatestActive || isTopOrLatestSensitive) && !(isSensitiveActive && !(isTopOrLatestSensitive || current->canCaptureCallOrOutput)) && canCaptureIfInCallOrCommunication(current); if (isVirtualSource(source)) { // Allow capture for virtual (remote submix, call audio TX or RX...) sources Loading @@ -554,8 +595,9 @@ void AudioPolicyService::updateUidStates_l() } } else { if (((isAssistantOnTop && source == AUDIO_SOURCE_VOICE_RECOGNITION) || source == AUDIO_SOURCE_HOTWORD) && (!(isSensitiveActive || isInCall) || current->canCaptureCallOrOutput)) { source == AUDIO_SOURCE_HOTWORD) && !(isSensitiveActive && !current->canCaptureCallOrOutput) && canCaptureIfInCallOrCommunication(current)) { allowCapture = true; } } Loading @@ -567,7 +609,8 @@ void AudioPolicyService::updateUidStates_l() // OR // Is on TOP AND the source is VOICE_RECOGNITION or HOTWORD if (!isAssistantOnTop && (!(isSensitiveActive || isInCall) || current->canCaptureCallOrOutput)) { && !(isSensitiveActive && !current->canCaptureCallOrOutput) && canCaptureIfInCallOrCommunication(current)) { allowCapture = true; } if (isA11yOnTop) { Loading @@ -580,7 +623,8 @@ void AudioPolicyService::updateUidStates_l() // All active clients are using HOTWORD source // AND no call is active // OR client has CAPTURE_AUDIO_OUTPUT privileged permission if (onlyHotwordActive && !(isInCall && !current->canCaptureCallOrOutput)) { if (onlyHotwordActive && canCaptureIfInCallOrCommunication(current)) { allowCapture = true; } } Loading