Loading media/libmediaplayerservice/MediaRecorderClient.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading media/utils/ServiceUtilities.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading media/utils/include/mediautils/ServiceUtilities.h +3 −1 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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(); Loading services/audioflinger/RecordTracks.h +10 −8 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading Loading @@ -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; Loading services/audioflinger/Tracks.cpp +22 −22 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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) { } Loading @@ -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); } Loading @@ -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(); } } Loading Loading @@ -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 Loading
media/libmediaplayerservice/MediaRecorderClient.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading
media/utils/ServiceUtilities.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading
media/utils/include/mediautils/ServiceUtilities.h +3 −1 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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(); Loading
services/audioflinger/RecordTracks.h +10 −8 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading Loading @@ -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; Loading
services/audioflinger/Tracks.cpp +22 −22 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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) { } Loading @@ -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); } Loading @@ -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(); } } Loading Loading @@ -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