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

Commit 4eefc090 authored by Eric Laurent's avatar Eric Laurent Committed by Automerger Merge Worker
Browse files

Merge "audio flinger: match app op monitoring to audio source" into sc-dev am:...

Merge "audio flinger: match app op monitoring to audio source" into sc-dev am: 28ba8f44 am: d8625e32

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/av/+/14663306

Change-Id: I430dc36912e25d28f27b2f0c39a5e9f0fb99c033
parents 0eb25492 d8625e32
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -127,7 +127,7 @@ status_t MediaRecorderClient::setAudioSource(int as)

    if ((as == AUDIO_SOURCE_FM_TUNER
            && !(captureAudioOutputAllowed(mIdentity) || captureTunerAudioInputAllowed(mIdentity)))
            || !recordingAllowed(mIdentity)) {
            || !recordingAllowed(mIdentity, (audio_source_t)as)) {
        return PERMISSION_DENIED;
    }
    Mutex::Autolock lock(mLock);
+3 −3
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ static String16 resolveCallingPackage(PermissionController& permissionController
    return packages[0];
}

static int32_t getOpForSource(audio_source_t source) {
int32_t getOpForSource(audio_source_t source) {
  switch (source) {
    case AUDIO_SOURCE_HOTWORD:
      return AppOpsManager::OP_RECORD_AUDIO_HOTWORD;
@@ -133,8 +133,8 @@ static bool checkRecordingInternal(const Identity& identity, const String16& msg
    return true;
}

bool recordingAllowed(const Identity& identity) {
    return checkRecordingInternal(identity, String16(), /*start*/ false, AUDIO_SOURCE_DEFAULT);
bool recordingAllowed(const Identity& identity, audio_source_t source) {
    return checkRecordingInternal(identity, String16(), /*start*/ false, source);
}

bool startRecording(const Identity& identity, const String16& msg, audio_source_t source) {
+3 −1
Original line number Diff line number Diff line
@@ -80,7 +80,8 @@ static inline bool isAudioServerOrMediaServerUid(uid_t uid) {
    }
}

bool recordingAllowed(const media::permission::Identity& identity);
bool recordingAllowed(const media::permission::Identity& identity,
        audio_source_t source = AUDIO_SOURCE_DEFAULT);
bool startRecording(const media::permission::Identity& identity,
    const String16& msg, audio_source_t source);
void finishRecording(const media::permission::Identity& identity, audio_source_t source);
@@ -98,6 +99,7 @@ bool dumpAllowed();
bool modifyPhoneStateAllowed(const media::permission::Identity& identity);
bool bypassInterruptionPolicyAllowed(const media::permission::Identity& identity);
void purgePermissionCache();
int32_t getOpForSource(audio_source_t source);

media::permission::Identity getCallingIdentity();

+10 −8
Original line number Diff line number Diff line
@@ -19,17 +19,18 @@
    #error This header file should only be included from AudioFlinger.h
#endif

// Checks and monitors OP_RECORD_AUDIO
// Checks and monitors app ops for audio record
class OpRecordAudioMonitor : public RefBase {
public:
    ~OpRecordAudioMonitor() override;
    bool hasOpRecordAudio() const;
    bool hasOp() const;
    int32_t getOp() const { return mAppOp; }

    static sp<OpRecordAudioMonitor> createIfNeeded
        (const media::permission::Identity& identity, const audio_attributes_t& attr);

private:
    explicit OpRecordAudioMonitor(const media::permission::Identity& identity);
    OpRecordAudioMonitor(const media::permission::Identity& identity, int32_t appOp);
    void onFirstRef() override;

    AppOpsManager mAppOpsManager;
@@ -44,12 +45,13 @@ private:
    };

    sp<RecordAudioOpCallback> mOpCallback;
    // called by RecordAudioOpCallback when OP_RECORD_AUDIO is updated in AppOp callback
    // and in onFirstRef()
    void checkRecordAudio();
    // called by RecordAudioOpCallback when the app op for this OpRecordAudioMonitor is updated
    // in AppOp callback and in onFirstRef()
    void checkOp();

    std::atomic_bool mHasOpRecordAudio;
    std::atomic_bool mHasOp;
    const media::permission::Identity mIdentity;
    const int32_t mAppOp;
};

// record track
@@ -149,7 +151,7 @@ private:

            bool                               mSilenced;

            // used to enforce OP_RECORD_AUDIO
            // used to enforce the audio record app op corresponding to this track's audio source
            sp<OpRecordAudioMonitor>           mOpRecordAudioMonitor;
            std::string                        mSharedAudioPackageName = {};
            int32_t                            mStartFrames = -1;
+22 −22
Original line number Diff line number Diff line
@@ -2215,7 +2215,7 @@ AudioFlinger::RecordThread::OpRecordAudioMonitor::createIfNeeded(
        return nullptr;
    }

    // Capturing from FM TUNER output is not controlled by OP_RECORD_AUDIO
    // Capturing from FM TUNER output is not controlled by an app op
    // because it does not affect users privacy as does capturing from an actual microphone.
    if (attr.source == AUDIO_SOURCE_FM_TUNER) {
        ALOGV("not muting FM TUNER capture for uid %d", identity.uid);
@@ -2227,12 +2227,12 @@ AudioFlinger::RecordThread::OpRecordAudioMonitor::createIfNeeded(
            || checkedIdentity.packageName.value().size() == 0) {
        return nullptr;
    }
    return new OpRecordAudioMonitor(checkedIdentity);
    return new OpRecordAudioMonitor(checkedIdentity, getOpForSource(attr.source));
}

AudioFlinger::RecordThread::OpRecordAudioMonitor::OpRecordAudioMonitor(
        const Identity& identity)
        : mHasOpRecordAudio(true), mIdentity(identity)
        const Identity& identity, int32_t appOp)
        : mHasOp(true), mIdentity(identity), mAppOp(appOp)
{
}

@@ -2246,36 +2246,36 @@ AudioFlinger::RecordThread::OpRecordAudioMonitor::~OpRecordAudioMonitor()

void AudioFlinger::RecordThread::OpRecordAudioMonitor::onFirstRef()
{
    checkRecordAudio();
    checkOp();
    mOpCallback = new RecordAudioOpCallback(this);
    ALOGV("start watching OP_RECORD_AUDIO for %s", mIdentity.toString().c_str());
    mAppOpsManager.startWatchingMode(AppOpsManager::OP_RECORD_AUDIO,
    ALOGV("start watching op %d for %s", mAppOp, mIdentity.toString().c_str());
    mAppOpsManager.startWatchingMode(mAppOp,
        VALUE_OR_FATAL(aidl2legacy_string_view_String16(mIdentity.packageName.value_or(""))),
        mOpCallback);
}

bool AudioFlinger::RecordThread::OpRecordAudioMonitor::hasOpRecordAudio() const {
    return mHasOpRecordAudio.load();
bool AudioFlinger::RecordThread::OpRecordAudioMonitor::hasOp() const {
    return mHasOp.load();
}

// Called by RecordAudioOpCallback when OP_RECORD_AUDIO is updated in AppOp callback
// and in onFirstRef()
// Called by RecordAudioOpCallback when the app op corresponding to this OpRecordAudioMonitor
// is updated in AppOp callback and in onFirstRef()
// Note this method is never called (and never to be) for audio server / root track
// due to the UID in createIfNeeded(). As a result for those record track, it's:
// - not called from constructor,
// - not called from RecordAudioOpCallback because the callback is not installed in this case
void AudioFlinger::RecordThread::OpRecordAudioMonitor::checkRecordAudio()
void AudioFlinger::RecordThread::OpRecordAudioMonitor::checkOp()
{

    const int32_t mode = mAppOpsManager.checkOp(AppOpsManager::OP_RECORD_AUDIO,
    const int32_t mode = mAppOpsManager.checkOp(mAppOp,
            mIdentity.uid, VALUE_OR_FATAL(aidl2legacy_string_view_String16(
                mIdentity.packageName.value_or(""))));
    const bool hasIt =  (mode == AppOpsManager::MODE_ALLOWED);
    // verbose logging only log when appOp changed
    ALOGI_IF(hasIt != mHasOpRecordAudio.load(),
            "OP_RECORD_AUDIO missing, %ssilencing record %s",
            hasIt ? "un" : "", mIdentity.toString().c_str());
    mHasOpRecordAudio.store(hasIt);
    ALOGI_IF(hasIt != mHasOp.load(),
            "App op %d missing, %ssilencing record %s",
            mAppOp, hasIt ? "un" : "", mIdentity.toString().c_str());
    mHasOp.store(hasIt);

}

@@ -2286,12 +2286,12 @@ AudioFlinger::RecordThread::OpRecordAudioMonitor::RecordAudioOpCallback::RecordA
void AudioFlinger::RecordThread::OpRecordAudioMonitor::RecordAudioOpCallback::opChanged(int32_t op,
            const String16& packageName) {
    UNUSED(packageName);
    if (op != AppOpsManager::OP_RECORD_AUDIO) {
        return;
    }
    sp<OpRecordAudioMonitor> monitor = mMonitor.promote();
    if (monitor != NULL) {
        monitor->checkRecordAudio();
        if (op != monitor->getOp()) {
            return;
        }
        monitor->checkOp();
    }
}

@@ -2661,7 +2661,7 @@ bool AudioFlinger::RecordThread::RecordTrack::isSilenced() const {
        return true;
    }
    // The monitor is only created for record tracks that can be silenced.
    return mOpRecordAudioMonitor ? !mOpRecordAudioMonitor->hasOpRecordAudio() : false;
    return mOpRecordAudioMonitor ? !mOpRecordAudioMonitor->hasOp() : false;
}

status_t AudioFlinger::RecordThread::RecordTrack::getActiveMicrophones(
Loading