audio policy: allow silencing capture per port

Add the possibility to silence a particular AudioRecord
client rather than silencing all clients sharing the same UID.

Test: AudioRecordTest#testRecordNoDataForIdleUids

Change-Id: Ic472045cd45c7222ca3a88ccf131435fd1e26475
gugelfrei
Eric Laurent 5 years ago
parent dba03231c2
commit 5ada82ee25

@ -340,11 +340,11 @@ public:
return reply.readInt32(); return reply.readInt32();
} }
virtual void setRecordSilenced(uid_t uid, bool silenced) virtual void setRecordSilenced(audio_port_handle_t portId, bool silenced)
{ {
Parcel data, reply; Parcel data, reply;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
data.writeInt32(uid); data.writeInt32(portId);
data.writeInt32(silenced ? 1 : 0); data.writeInt32(silenced ? 1 : 0);
remote()->transact(SET_RECORD_SILENCED, data, &reply); remote()->transact(SET_RECORD_SILENCED, data, &reply);
} }
@ -1156,11 +1156,9 @@ status_t BnAudioFlinger::onTransact(
} break; } break;
case SET_RECORD_SILENCED: { case SET_RECORD_SILENCED: {
CHECK_INTERFACE(IAudioFlinger, data, reply); CHECK_INTERFACE(IAudioFlinger, data, reply);
uid_t uid = data.readInt32(); audio_port_handle_t portId = data.readInt32();
audio_source_t source;
data.read(&source, sizeof(audio_source_t));
bool silenced = data.readInt32() == 1; bool silenced = data.readInt32() == 1;
setRecordSilenced(uid, silenced); setRecordSilenced(portId, silenced);
return NO_ERROR; return NO_ERROR;
} break; } break;
case SET_PARAMETERS: { case SET_PARAMETERS: {

@ -384,7 +384,7 @@ public:
// mic mute/state // mic mute/state
virtual status_t setMicMute(bool state) = 0; virtual status_t setMicMute(bool state) = 0;
virtual bool getMicMute() const = 0; virtual bool getMicMute() const = 0;
virtual void setRecordSilenced(uid_t uid, bool silenced) = 0; virtual void setRecordSilenced(audio_port_handle_t portId, bool silenced) = 0;
virtual status_t setParameters(audio_io_handle_t ioHandle, virtual status_t setParameters(audio_io_handle_t ioHandle,
const String8& keyValuePairs) = 0; const String8& keyValuePairs) = 0;

@ -1132,16 +1132,16 @@ bool AudioFlinger::getMicMute() const
return mute; return mute;
} }
void AudioFlinger::setRecordSilenced(uid_t uid, bool silenced) void AudioFlinger::setRecordSilenced(audio_port_handle_t portId, bool silenced)
{ {
ALOGV("AudioFlinger::setRecordSilenced(uid:%d, silenced:%d)", uid, silenced); ALOGV("AudioFlinger::setRecordSilenced(portId:%d, silenced:%d)", portId, silenced);
AutoMutex lock(mLock); AutoMutex lock(mLock);
for (size_t i = 0; i < mRecordThreads.size(); i++) { for (size_t i = 0; i < mRecordThreads.size(); i++) {
mRecordThreads[i]->setRecordSilenced(uid, silenced); mRecordThreads[i]->setRecordSilenced(portId, silenced);
} }
for (size_t i = 0; i < mMmapThreads.size(); i++) { for (size_t i = 0; i < mMmapThreads.size(); i++) {
mMmapThreads[i]->setRecordSilenced(uid, silenced); mMmapThreads[i]->setRecordSilenced(portId, silenced);
} }
} }

@ -162,7 +162,7 @@ public:
virtual status_t setMicMute(bool state); virtual status_t setMicMute(bool state);
virtual bool getMicMute() const; virtual bool getMicMute() const;
virtual void setRecordSilenced(uid_t uid, bool silenced); virtual void setRecordSilenced(audio_port_handle_t portId, bool silenced);
virtual status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs); virtual status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs);
virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) const; virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) const;

@ -7934,12 +7934,12 @@ void AudioFlinger::RecordThread::dumpTracks_l(int fd, const Vector<String16>& ar
write(fd, result.string(), result.size()); write(fd, result.string(), result.size());
} }
void AudioFlinger::RecordThread::setRecordSilenced(uid_t uid, bool silenced) void AudioFlinger::RecordThread::setRecordSilenced(audio_port_handle_t portId, bool silenced)
{ {
Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mTracks.size() ; i++) { for (size_t i = 0; i < mTracks.size() ; i++) {
sp<RecordTrack> track = mTracks[i]; sp<RecordTrack> track = mTracks[i];
if (track != 0 && track->uid() == uid) { if (track != 0 && track->portId() == portId) {
track->setSilenced(silenced); track->setSilenced(silenced);
} }
} }
@ -9477,11 +9477,11 @@ void AudioFlinger::MmapCaptureThread::updateMetadata_l()
mInput->stream->updateSinkMetadata(metadata); mInput->stream->updateSinkMetadata(metadata);
} }
void AudioFlinger::MmapCaptureThread::setRecordSilenced(uid_t uid, bool silenced) void AudioFlinger::MmapCaptureThread::setRecordSilenced(audio_port_handle_t portId, bool silenced)
{ {
Mutex::Autolock _l(mLock); Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mActiveTracks.size() ; i++) { for (size_t i = 0; i < mActiveTracks.size() ; i++) {
if (mActiveTracks[i]->uid() == uid) { if (mActiveTracks[i]->portId() == portId) {
mActiveTracks[i]->setSilenced_l(silenced); mActiveTracks[i]->setSilenced_l(silenced);
broadcast_l(); broadcast_l();
} }

@ -1616,7 +1616,7 @@ public:
void checkBtNrec(); void checkBtNrec();
// Sets the UID records silence // Sets the UID records silence
void setRecordSilenced(uid_t uid, bool silenced); void setRecordSilenced(audio_port_handle_t portId, bool silenced);
status_t getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones); status_t getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones);
@ -1785,7 +1785,8 @@ class MmapThread : public ThreadBase
virtual void invalidateTracks(audio_stream_type_t streamType __unused) {} virtual void invalidateTracks(audio_stream_type_t streamType __unused) {}
// Sets the UID records silence // Sets the UID records silence
virtual void setRecordSilenced(uid_t uid __unused, bool silenced __unused) {} virtual void setRecordSilenced(audio_port_handle_t portId __unused,
bool silenced __unused) {}
protected: protected:
void dumpInternals_l(int fd, const Vector<String16>& args) override; void dumpInternals_l(int fd, const Vector<String16>& args) override;
@ -1872,7 +1873,8 @@ public:
void updateMetadata_l() override; void updateMetadata_l() override;
void processVolume_l() override; void processVolume_l() override;
void setRecordSilenced(uid_t uid, bool silenced) override; void setRecordSilenced(audio_port_handle_t portId,
bool silenced) override;
virtual void toAudioPortConfig(struct audio_port_config *config); virtual void toAudioPortConfig(struct audio_port_config *config);

@ -258,7 +258,7 @@ public:
virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP( virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
std::vector<audio_format_t> *formats) = 0; std::vector<audio_format_t> *formats) = 0;
virtual void setAppState(uid_t uid, app_state_t state) = 0; virtual void setAppState(audio_port_handle_t portId, app_state_t state) = 0;
virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) = 0; virtual status_t listAudioProductStrategies(AudioProductStrategyVector &strategies) = 0;

@ -97,7 +97,7 @@ public:
RecordClientVector clientsList(bool activeOnly = false, RecordClientVector clientsList(bool activeOnly = false,
audio_source_t source = AUDIO_SOURCE_DEFAULT, bool preferredDeviceOnly = false) const; audio_source_t source = AUDIO_SOURCE_DEFAULT, bool preferredDeviceOnly = false) const;
void setAppState(uid_t uid, app_state_t state); void setAppState(audio_port_handle_t portId, app_state_t state);
// implementation of ClientMapHandler<RecordClientDescriptor> // implementation of ClientMapHandler<RecordClientDescriptor>
void addClient(const sp<RecordClientDescriptor> &client) override; void addClient(const sp<RecordClientDescriptor> &client) override;

@ -450,13 +450,13 @@ EffectDescriptorCollection AudioInputDescriptor::getEnabledEffects() const
return enabledEffects; return enabledEffects;
} }
void AudioInputDescriptor::setAppState(uid_t uid, app_state_t state) void AudioInputDescriptor::setAppState(audio_port_handle_t portId, app_state_t state)
{ {
RecordClientVector clients = clientsList(false /*activeOnly*/); RecordClientVector clients = clientsList(false /*activeOnly*/);
RecordClientVector updatedClients; RecordClientVector updatedClients;
for (const auto& client : clients) { for (const auto& client : clients) {
if (uid == client->uid()) { if (portId == client->portId()) {
bool wasSilenced = client->isSilenced(); bool wasSilenced = client->isSilenced();
client->setAppState(state); client->setAppState(state);
if (client->active() && wasSilenced != client->isSilenced()) { if (client->active() && wasSilenced != client->isSilenced()) {

@ -4183,11 +4183,11 @@ status_t AudioPolicyManager::setSurroundFormatEnabled(audio_format_t audioFormat
return profileUpdated ? NO_ERROR : INVALID_OPERATION; return profileUpdated ? NO_ERROR : INVALID_OPERATION;
} }
void AudioPolicyManager::setAppState(uid_t uid, app_state_t state) void AudioPolicyManager::setAppState(audio_port_handle_t portId, app_state_t state)
{ {
ALOGV("%s(uid:%d, state:%d)", __func__, uid, state); ALOGV("%s(portId:%d, state:%d)", __func__, portId, state);
for (size_t i = 0; i < mInputs.size(); i++) { for (size_t i = 0; i < mInputs.size(); i++) {
mInputs.valueAt(i)->setAppState(uid, state); mInputs.valueAt(i)->setAppState(portId, state);
} }
} }

@ -278,7 +278,7 @@ public:
virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP( virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
std::vector<audio_format_t> *formats); std::vector<audio_format_t> *formats);
virtual void setAppState(uid_t uid, app_state_t state); virtual void setAppState(audio_port_handle_t portId, app_state_t state);
virtual bool isHapticPlaybackSupported(); virtual bool isHapticPlaybackSupported();

@ -222,7 +222,7 @@ status_t AudioPolicyService::getOutputForAttr(audio_attributes_t *attr,
if (result == NO_ERROR) { if (result == NO_ERROR) {
sp <AudioPlaybackClient> client = sp <AudioPlaybackClient> client =
new AudioPlaybackClient(*attr, *output, uid, pid, session, *selectedDeviceId, *stream); new AudioPlaybackClient(*attr, *output, uid, pid, session, *portId, *selectedDeviceId, *stream);
mAudioPlaybackClients.add(*portId, client); mAudioPlaybackClients.add(*portId, client);
} }
return result; return result;
@ -451,7 +451,7 @@ status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
return status; return status;
} }
sp<AudioRecordClient> client = new AudioRecordClient(*attr, *input, uid, pid, session, sp<AudioRecordClient> client = new AudioRecordClient(*attr, *input, uid, pid, session, *portId,
*selectedDeviceId, opPackageName, *selectedDeviceId, opPackageName,
canCaptureOutput, canCaptureHotword); canCaptureOutput, canCaptureHotword);
mAudioRecordClients.add(*portId, client); mAudioRecordClients.add(*portId, client);

@ -569,7 +569,7 @@ void AudioPolicyService::updateUidStates_l()
} }
} }
} }
setAppState_l(current->uid, setAppState_l(current->portId,
allowCapture ? apmStatFromAmState(mUidPolicy->getUidState(current->uid)) : allowCapture ? apmStatFromAmState(mUidPolicy->getUidState(current->uid)) :
APP_STATE_IDLE); APP_STATE_IDLE);
if (allowCapture) { if (allowCapture) {
@ -582,7 +582,7 @@ void AudioPolicyService::silenceAllRecordings_l() {
for (size_t i = 0; i < mAudioRecordClients.size(); i++) { for (size_t i = 0; i < mAudioRecordClients.size(); i++) {
sp<AudioRecordClient> current = mAudioRecordClients[i]; sp<AudioRecordClient> current = mAudioRecordClients[i];
if (!isVirtualSource(current->attributes.source)) { if (!isVirtualSource(current->attributes.source)) {
setAppState_l(current->uid, APP_STATE_IDLE); setAppState_l(current->portId, APP_STATE_IDLE);
} }
} }
} }
@ -628,17 +628,17 @@ bool AudioPolicyService::isVirtualSource(audio_source_t source)
return false; return false;
} }
void AudioPolicyService::setAppState_l(uid_t uid, app_state_t state) void AudioPolicyService::setAppState_l(audio_port_handle_t portId, app_state_t state)
{ {
AutoCallerClear acc; AutoCallerClear acc;
if (mAudioPolicyManager) { if (mAudioPolicyManager) {
mAudioPolicyManager->setAppState(uid, state); mAudioPolicyManager->setAppState(portId, state);
} }
sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
if (af) { if (af) {
bool silenced = state == APP_STATE_IDLE; bool silenced = state == APP_STATE_IDLE;
af->setRecordSilenced(uid, silenced); af->setRecordSilenced(portId, silenced);
} }
} }

@ -311,7 +311,7 @@ private:
virtual status_t shellCommand(int in, int out, int err, Vector<String16>& args); virtual status_t shellCommand(int in, int out, int err, Vector<String16>& args);
// Sets whether the given UID records only silence // Sets whether the given UID records only silence
virtual void setAppState_l(uid_t uid, app_state_t state); virtual void setAppState_l(audio_port_handle_t portId, app_state_t state);
// Overrides the UID state as if it is idle // Overrides the UID state as if it is idle
status_t handleSetUidState(Vector<String16>& args, int err); status_t handleSetUidState(Vector<String16>& args, int err);
@ -759,9 +759,10 @@ private:
public: public:
AudioClient(const audio_attributes_t attributes, AudioClient(const audio_attributes_t attributes,
const audio_io_handle_t io, uid_t uid, pid_t pid, const audio_io_handle_t io, uid_t uid, pid_t pid,
const audio_session_t session, const audio_port_handle_t deviceId) : const audio_session_t session, audio_port_handle_t portId,
const audio_port_handle_t deviceId) :
attributes(attributes), io(io), uid(uid), pid(pid), attributes(attributes), io(io), uid(uid), pid(pid),
session(session), deviceId(deviceId), active(false) {} session(session), portId(portId), deviceId(deviceId), active(false) {}
~AudioClient() override = default; ~AudioClient() override = default;
@ -770,6 +771,7 @@ private:
const uid_t uid; // client UID const uid_t uid; // client UID
const pid_t pid; // client PID const pid_t pid; // client PID
const audio_session_t session; // audio session ID const audio_session_t session; // audio session ID
const audio_port_handle_t portId;
const audio_port_handle_t deviceId; // selected input device port ID const audio_port_handle_t deviceId; // selected input device port ID
bool active; // Playback/Capture is active or inactive bool active; // Playback/Capture is active or inactive
}; };
@ -781,10 +783,10 @@ private:
public: public:
AudioRecordClient(const audio_attributes_t attributes, AudioRecordClient(const audio_attributes_t attributes,
const audio_io_handle_t io, uid_t uid, pid_t pid, const audio_io_handle_t io, uid_t uid, pid_t pid,
const audio_session_t session, const audio_port_handle_t deviceId, const audio_session_t session, audio_port_handle_t portId,
const String16& opPackageName, const audio_port_handle_t deviceId, const String16& opPackageName,
bool canCaptureOutput, bool canCaptureHotword) : bool canCaptureOutput, bool canCaptureHotword) :
AudioClient(attributes, io, uid, pid, session, deviceId), AudioClient(attributes, io, uid, pid, session, portId, deviceId),
opPackageName(opPackageName), startTimeNs(0), opPackageName(opPackageName), startTimeNs(0),
canCaptureOutput(canCaptureOutput), canCaptureHotword(canCaptureHotword) {} canCaptureOutput(canCaptureOutput), canCaptureHotword(canCaptureHotword) {}
~AudioRecordClient() override = default; ~AudioRecordClient() override = default;
@ -802,9 +804,9 @@ private:
public: public:
AudioPlaybackClient(const audio_attributes_t attributes, AudioPlaybackClient(const audio_attributes_t attributes,
const audio_io_handle_t io, uid_t uid, pid_t pid, const audio_io_handle_t io, uid_t uid, pid_t pid,
const audio_session_t session, audio_port_handle_t deviceId, const audio_session_t session, audio_port_handle_t portId,
audio_stream_type_t stream) : audio_port_handle_t deviceId, audio_stream_type_t stream) :
AudioClient(attributes, io, uid, pid, session, deviceId), stream(stream) {} AudioClient(attributes, io, uid, pid, session, portId, deviceId), stream(stream) {}
~AudioPlaybackClient() override = default; ~AudioPlaybackClient() override = default;
const audio_stream_type_t stream; const audio_stream_type_t stream;

Loading…
Cancel
Save