Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cfd28304 authored by Michael Groover's avatar Michael Groover
Browse files

Prevent recording when sensor privacy is enabled

Test: Manually verified audio was not recorded when sensor privacy \
      was enabled.
Bug: 110842805

Change-Id: I3bb966d9322e258a8aba43fb4e9f65badd7c3506
parent e21f3418
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -25,7 +25,11 @@ LOCAL_SHARED_LIBRARIES := \
    libmedia_helper \
    libmediametrics \
    libmediautils \
    libeffectsconfig
    libeffectsconfig \
    libsensorprivacy

LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
    libsensorprivacy

LOCAL_STATIC_LIBRARIES := \
    libaudiopolicycomponents
+45 −0
Original line number Diff line number Diff line
@@ -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 @@ void AudioPolicyService::onFirstRef()

    mUidPolicy = new UidPolicy(this);
    mUidPolicy->registerSelf();

    mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
    mSensorPrivacyPolicy->registerSelf();
}

AudioPolicyService::~AudioPolicyService()
@@ -99,6 +103,9 @@ AudioPolicyService::~AudioPolicyService()

    mUidPolicy->unregisterSelf();
    mUidPolicy.clear();

    mSensorPrivacyPolicy->unregisterSelf();
    mSensorPrivacyPolicy.clear();
}

// A notification client is always registered by AudioSystem when the client process
@@ -375,6 +382,12 @@ void AudioPolicyService::updateUidStates_l()
    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::updateUidStates_l()
    }
}

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 @@ bool AudioPolicyService::UidPolicy::isA11yUid(uid_t uid)
    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,
+26 −0
Original line number Diff line number Diff line
@@ -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 @@ private:
    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 @@ private:
        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 @@ private:
    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;
};