Prevent recording when sensor privacy is enabled
Test: Manually verified audio was not recorded when sensor privacy \
was enabled.
Bug: 110842805
Change-Id: I3bb966d9322e258a8aba43fb4e9f65badd7c3506
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
index 02ab8ad..bfa1b5e 100644
--- a/services/audiopolicy/Android.mk
+++ b/services/audiopolicy/Android.mk
@@ -25,7 +25,11 @@
libmedia_helper \
libmediametrics \
libmediautils \
- libeffectsconfig
+ libeffectsconfig \
+ libsensorprivacy
+
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
+ libsensorprivacy
LOCAL_STATIC_LIBRARIES := \
libaudiopolicycomponents
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index ee5d6ff..f233971 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -38,6 +38,7 @@
#include <media/AudioEffect.h>
#include <media/AudioParameter.h>
#include <mediautils/ServiceUtilities.h>
+#include <sensorprivacy/SensorPrivacyManager.h>
#include <system/audio.h>
#include <system/audio_policy.h>
@@ -84,6 +85,9 @@
mUidPolicy = new UidPolicy(this);
mUidPolicy->registerSelf();
+
+ mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
+ mSensorPrivacyPolicy->registerSelf();
}
AudioPolicyService::~AudioPolicyService()
@@ -99,6 +103,9 @@
mUidPolicy->unregisterSelf();
mUidPolicy.clear();
+
+ mSensorPrivacyPolicy->unregisterSelf();
+ mSensorPrivacyPolicy.clear();
}
// A notification client is always registered by AudioSystem when the client process
@@ -375,6 +382,12 @@
bool isAssistantOnTop = false;
bool isSensitiveActive = false;
+ // if Sensor Privacy is enabled then all recordings should be silenced.
+ if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
+ silenceAllRecordings_l();
+ return;
+ }
+
for (size_t i =0; i < mAudioRecordClients.size(); i++) {
sp<AudioRecordClient> current = mAudioRecordClients[i];
if (!current->active) continue;
@@ -445,6 +458,13 @@
}
}
+void AudioPolicyService::silenceAllRecordings_l() {
+ for (size_t i = 0; i < mAudioRecordClients.size(); i++) {
+ sp<AudioRecordClient> current = mAudioRecordClients[i];
+ setAppState_l(current->uid, APP_STATE_IDLE);
+ }
+}
+
/* static */
app_state_t AudioPolicyService::apmStatFromAmState(int amState) {
switch (amState) {
@@ -858,6 +878,31 @@
return it != mA11yUids.end();
}
+// ----------- AudioPolicyService::SensorPrivacyService implementation ----------
+void AudioPolicyService::SensorPrivacyPolicy::registerSelf() {
+ SensorPrivacyManager spm;
+ mSensorPrivacyEnabled = spm.isSensorPrivacyEnabled();
+ spm.addSensorPrivacyListener(this);
+}
+
+void AudioPolicyService::SensorPrivacyPolicy::unregisterSelf() {
+ SensorPrivacyManager spm;
+ spm.removeSensorPrivacyListener(this);
+}
+
+bool AudioPolicyService::SensorPrivacyPolicy::isSensorPrivacyEnabled() {
+ return mSensorPrivacyEnabled;
+}
+
+binder::Status AudioPolicyService::SensorPrivacyPolicy::onSensorPrivacyChanged(bool enabled) {
+ mSensorPrivacyEnabled = enabled;
+ sp<AudioPolicyService> service = mService.promote();
+ if (service != nullptr) {
+ service->updateUidStates();
+ }
+ return binder::Status::ok();
+}
+
// ----------- AudioPolicyService::AudioCommandThread implementation ----------
AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name,
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 23c3daa..45d37dc 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -33,6 +33,7 @@
#include <media/AudioPolicy.h>
#include "AudioPolicyEffects.h"
#include "managerdefault/AudioPolicyManager.h"
+#include <android/hardware/BnSensorPrivacyListener.h>
#include <unordered_map>
@@ -279,6 +280,8 @@
void updateUidStates();
void updateUidStates_l();
+ void silenceAllRecordings_l();
+
static bool isPrivacySensitive(audio_source_t source);
// If recording we need to make sure the UID is allowed to do that. If the UID is idle
@@ -334,6 +337,27 @@
std::vector<uid_t> mA11yUids;
};
+ // If sensor privacy is enabled then all apps, including those that are active, should be
+ // prevented from recording. This is handled similar to idle UIDs, any app that attempts
+ // to record while sensor privacy is enabled will receive buffers with zeros. As soon as
+ // sensor privacy is disabled active apps will receive the expected data when recording.
+ class SensorPrivacyPolicy : public hardware::BnSensorPrivacyListener {
+ public:
+ explicit SensorPrivacyPolicy(wp<AudioPolicyService> service)
+ : mService(service) {}
+
+ void registerSelf();
+ void unregisterSelf();
+
+ bool isSensorPrivacyEnabled();
+
+ binder::Status onSensorPrivacyChanged(bool enabled);
+
+ private:
+ wp<AudioPolicyService> mService;
+ std::atomic_bool mSensorPrivacyEnabled;
+ };
+
// Thread used to send audio config commands to audio flinger
// For audio config commands, it is necessary because audio flinger requires that the calling
// process (user) has permission to modify audio settings.
@@ -718,6 +742,8 @@
audio_mode_t mPhoneState;
sp<UidPolicy> mUidPolicy;
+ sp<SensorPrivacyPolicy> mSensorPrivacyPolicy;
+
DefaultKeyedVector< audio_port_handle_t, sp<AudioRecordClient> > mAudioRecordClients;
DefaultKeyedVector< audio_port_handle_t, sp<AudioPlaybackClient> > mAudioPlaybackClients;
};