audioservice: add RTT mode observer

Enable audio capture by the Assistant when RTT is ON during a call
similarly to when an accessibility service is in the foreground.

Also remove log when permission checked for hotword
and audio output capture fail as those checks are now done
systematically.

Also do not check permission to bypass interruption policy if
bypass flags are not set.

Bug: 132976361
Test: use voice input during a call with RTT enabled.
Change-Id: Iff45b0816dac889262ec29ea115f74dea4dc6b6d
gugelfrei
Eric Laurent 5 years ago
parent e0092766d2
commit 6ede98f9b3

@ -1512,6 +1512,13 @@ status_t AudioSystem::getVolumeGroupFromAudioAttributes(const AudioAttributes &a
return aps->getVolumeGroupFromAudioAttributes(aa, volumeGroup);
}
status_t AudioSystem::setRttEnabled(bool enabled)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return aps->setRttEnabled(enabled);
}
// ---------------------------------------------------------------------------
int AudioSystem::AudioPolicyServiceClient::addAudioPortCallback(

@ -104,6 +104,7 @@ enum {
GET_VOLUME_GROUP_FOR_ATTRIBUTES,
SET_ALLOWED_CAPTURE_POLICY,
MOVE_EFFECTS_TO_IO,
SET_RTT_ENABLED
};
#define MAX_ITEMS_PER_LIST 1024
@ -1271,6 +1272,18 @@ public:
volumeGroup = static_cast<volume_group_t>(reply.readInt32());
return NO_ERROR;
}
virtual status_t setRttEnabled(bool enabled)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(static_cast<int32_t>(enabled));
status_t status = remote()->transact(SET_RTT_ENABLED, data, &reply);
if (status != NO_ERROR) {
return status;
}
return static_cast<status_t>(reply.readInt32());
}
};
IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@ -1332,7 +1345,8 @@ status_t BnAudioPolicyService::onTransact(
case REMOVE_UID_DEVICE_AFFINITY:
case GET_OFFLOAD_FORMATS_A2DP:
case LIST_AUDIO_VOLUME_GROUPS:
case GET_VOLUME_GROUP_FOR_ATTRIBUTES: {
case GET_VOLUME_GROUP_FOR_ATTRIBUTES:
case SET_RTT_ENABLED: {
if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
__func__, code, IPCThreadState::self()->getCallingPid(),
@ -2347,6 +2361,14 @@ status_t BnAudioPolicyService::onTransact(
return NO_ERROR;
}
case SET_RTT_ENABLED: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
bool enabled = static_cast<bool>(data.readInt32());
status_t status = setRttEnabled(enabled);
reply->writeInt32(status);
return NO_ERROR;
}
default:
return BBinder::onTransact(code, data, reply, flags);
}

@ -394,6 +394,8 @@ public:
static status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
volume_group_t &volumeGroup);
static status_t setRttEnabled(bool enabled);
// ----------------------------------------------------------------------------
class AudioVolumeGroupCallback : public RefBase

@ -220,6 +220,8 @@ public:
virtual status_t listAudioVolumeGroups(AudioVolumeGroupVector &groups) = 0;
virtual status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
volume_group_t &volumeGroup) = 0;
virtual status_t setRttEnabled(bool enabled) = 0;
};

@ -128,7 +128,7 @@ bool captureAudioOutputAllowed(pid_t pid, uid_t uid) {
if (isAudioServerOrRootUid(uid)) return true;
static const String16 sCaptureAudioOutput("android.permission.CAPTURE_AUDIO_OUTPUT");
bool ok = PermissionCache::checkPermission(sCaptureAudioOutput, pid, uid);
if (!ok) ALOGE("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");
if (!ok) ALOGV("Request requires android.permission.CAPTURE_AUDIO_OUTPUT");
return ok;
}
@ -149,7 +149,7 @@ bool captureHotwordAllowed(const String16& opPackageName, pid_t pid, uid_t uid)
// IMPORTANT: Use PermissionCache - not a runtime permission and may not change.
ok = PermissionCache::checkPermission(sCaptureHotwordAllowed, pid, uid);
}
if (!ok) ALOGE("android.permission.CAPTURE_AUDIO_HOTWORD");
if (!ok) ALOGV("android.permission.CAPTURE_AUDIO_HOTWORD");
return ok;
}

@ -193,7 +193,8 @@ status_t AudioPolicyService::getOutputForAttr(audio_attributes_t *attr,
if (!mPackageManager.allowPlaybackCapture(uid)) {
attr->flags |= AUDIO_FLAG_NO_MEDIA_PROJECTION;
}
if (!bypassInterruptionPolicyAllowed(pid, uid)) {
if (((attr->flags & (AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY|AUDIO_FLAG_BYPASS_MUTE)) != 0)
&& !bypassInterruptionPolicyAllowed(pid, uid)) {
attr->flags &= ~(AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY|AUDIO_FLAG_BYPASS_MUTE);
}
audio_output_flags_t originalFlags = flags;
@ -1316,4 +1317,12 @@ status_t AudioPolicyService::getVolumeGroupFromAudioAttributes(const AudioAttrib
Mutex::Autolock _l(mLock);
return mAudioPolicyManager->getVolumeGroupFromAudioAttributes(aa, volumeGroup);
}
status_t AudioPolicyService::setRttEnabled(bool enabled)
{
Mutex::Autolock _l(mLock);
mUidPolicy->setRttEnabled(enabled);
return NO_ERROR;
}
} // namespace android

@ -409,7 +409,7 @@ void AudioPolicyService::updateUidStates_l()
// following cases:
// Another client in the same UID has already been allowed to capture
// OR The client is the assistant
// AND an accessibility service is on TOP
// 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
@ -436,6 +436,9 @@ void AudioPolicyService::updateUidStates_l()
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)
&& mUidPolicy->isRttEnabled();
// if Sensor Privacy is enabled then all recordings should be silenced.
if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
@ -518,13 +521,13 @@ void AudioPolicyService::updateUidStates_l()
allowCapture = true;
} else if (mUidPolicy->isAssistantUid(current->uid)) {
// For assistant allow capture if:
// An accessibility service is on TOP
// An 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
if (isA11yOnTop) {
if (isA11yOnTop || rttCallActive) {
if (source == AUDIO_SOURCE_HOTWORD || source == AUDIO_SOURCE_VOICE_RECOGNITION) {
allowCapture = true;
}

@ -256,6 +256,8 @@ public:
virtual status_t getVolumeGroupFromAudioAttributes(const AudioAttributes &aa,
volume_group_t &volumeGroup);
virtual status_t setRttEnabled(bool enabled);
status_t doStopOutput(audio_port_handle_t portId);
void doReleaseOutput(audio_port_handle_t portId);
@ -345,7 +347,8 @@ private:
class UidPolicy : public BnUidObserver, public virtual IBinder::DeathRecipient {
public:
explicit UidPolicy(wp<AudioPolicyService> service)
: mService(service), mObserverRegistered(false), mAssistantUid(0) {}
: mService(service), mObserverRegistered(false),
mAssistantUid(0), mRttEnabled(false) {}
void registerSelf();
void unregisterSelf();
@ -360,6 +363,8 @@ private:
void setA11yUids(const std::vector<uid_t>& uids) { mA11yUids.clear(); mA11yUids = uids; }
bool isA11yUid(uid_t uid);
bool isA11yOnTop();
void setRttEnabled(bool enabled) { mRttEnabled = enabled; }
bool isRttEnabled() { return mRttEnabled; }
// BnUidObserver implementation
void onUidActive(uid_t uid) override;
@ -387,6 +392,7 @@ private:
std::unordered_map<uid_t, std::pair<bool, int>> mCachedUids;
uid_t mAssistantUid;
std::vector<uid_t> mA11yUids;
bool mRttEnabled;
};
// If sensor privacy is enabled then all apps, including those that are active, should be

Loading…
Cancel
Save