summaryrefslogtreecommitdiffstats
path: root/services/audioflinger
diff options
context:
space:
mode:
authorMikhail Naganov <mnaganov@google.com>2019-04-22 16:43:26 -0700
committerMikhail Naganov <mnaganov@google.com>2019-04-22 16:53:41 -0700
commitf7e3a3a2eb753da4500b9000c113ae0f3b058792 (patch)
tree83b0c8c42a44d092b1b054fd059a98df23b81521 /services/audioflinger
parent3208826f676b1be78e1c04692d7f17249e45c3ea (diff)
downloadframeworks_av-f7e3a3a2eb753da4500b9000c113ae0f3b058792.tar.gz
frameworks_av-f7e3a3a2eb753da4500b9000c113ae0f3b058792.tar.bz2
frameworks_av-f7e3a3a2eb753da4500b9000c113ae0f3b058792.zip
audioflinger: Fix reference counting protocol in OpPlayAudioMonitor
OpPlayAudioMonitor was constructing a weak pointer to itself in the constructor. This practice can lead to crashes due to race conditions vs object destruction. This code is now moved to onFirstRef method which is called when at least one strong reference exists. This change also reduces the number of created OpPlayAudioMonitor objects by using a factory method. Bug: 130038586 Test: enable / disable DND mode Change-Id: I22e63a883ebaa25b9c96e79271bb9693b5ed75cd
Diffstat (limited to 'services/audioflinger')
-rw-r--r--services/audioflinger/PlaybackTracks.h11
-rw-r--r--services/audioflinger/Tracks.cpp43
2 files changed, 37 insertions, 17 deletions
diff --git a/services/audioflinger/PlaybackTracks.h b/services/audioflinger/PlaybackTracks.h
index 4fd72a7917..56be433d4b 100644
--- a/services/audioflinger/PlaybackTracks.h
+++ b/services/audioflinger/PlaybackTracks.h
@@ -22,11 +22,16 @@
// Checks and monitors OP_PLAY_AUDIO
class OpPlayAudioMonitor : public RefBase {
public:
- OpPlayAudioMonitor(uid_t uid, audio_usage_t usage, int id, audio_stream_type_t streamType);
~OpPlayAudioMonitor() override;
bool hasOpPlayAudio() const;
+ static sp<OpPlayAudioMonitor> createIfNeeded(
+ uid_t uid, audio_usage_t usage, int id, audio_stream_type_t streamType);
+
private:
+ OpPlayAudioMonitor(uid_t uid, audio_usage_t usage, int id);
+ void onFirstRef() override;
+
AppOpsManager mAppOpsManager;
class PlayAudioOpCallback : public BnAppOpsCallback {
@@ -209,7 +214,9 @@ public:
int fastIndex() const { return mFastIndex; }
- bool isPlaybackRestricted() const { return !mOpPlayAudioMonitor->hasOpPlayAudio(); }
+ bool isPlaybackRestricted() const {
+ // The monitor is only created for tracks that can be silenced.
+ return mOpPlayAudioMonitor ? !mOpPlayAudioMonitor->hasOpPlayAudio() : false; }
protected:
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 2ff80c65ea..8d59431a65 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -381,26 +381,28 @@ status_t AudioFlinger::TrackHandle::onTransact(
// ----------------------------------------------------------------------------
// AppOp for audio playback
// -------------------------------
-AudioFlinger::PlaybackThread::OpPlayAudioMonitor::OpPlayAudioMonitor(uid_t uid, audio_usage_t usage,
- int id, audio_stream_type_t streamType)
- : mHasOpPlayAudio(true), mUid(uid), mUsage((int32_t) usage), mId(id)
+
+// static
+sp<AudioFlinger::PlaybackThread::OpPlayAudioMonitor>
+AudioFlinger::PlaybackThread::OpPlayAudioMonitor::createIfNeeded(
+ uid_t uid, audio_usage_t usage, int id, audio_stream_type_t streamType)
{
if (isAudioServerOrRootUid(uid)) {
- ALOGD("OpPlayAudio: not muting track:%d usage:%d root or audioserver", mId, usage);
- return;
+ ALOGD("OpPlayAudio: not muting track:%d usage:%d root or audioserver", id, usage);
+ return nullptr;
}
// stream type has been filtered by audio policy to indicate whether it can be muted
if (streamType == AUDIO_STREAM_ENFORCED_AUDIBLE) {
- ALOGD("OpPlayAudio: not muting track:%d usage:%d ENFORCED_AUDIBLE", mId, usage);
- return;
- }
- PermissionController permissionController;
- permissionController.getPackagesForUid(uid, mPackages);
- checkPlayAudioForUsage();
- if (!mPackages.isEmpty()) {
- mOpCallback = new PlayAudioOpCallback(this);
- mAppOpsManager.startWatchingMode(AppOpsManager::OP_PLAY_AUDIO, mPackages[0], mOpCallback);
+ ALOGD("OpPlayAudio: not muting track:%d usage:%d ENFORCED_AUDIBLE", id, usage);
+ return nullptr;
}
+ return new OpPlayAudioMonitor(uid, usage, id);
+}
+
+AudioFlinger::PlaybackThread::OpPlayAudioMonitor::OpPlayAudioMonitor(
+ uid_t uid, audio_usage_t usage, int id)
+ : mHasOpPlayAudio(true), mUid(uid), mUsage((int32_t) usage), mId(id)
+{
}
AudioFlinger::PlaybackThread::OpPlayAudioMonitor::~OpPlayAudioMonitor()
@@ -411,6 +413,17 @@ AudioFlinger::PlaybackThread::OpPlayAudioMonitor::~OpPlayAudioMonitor()
mOpCallback.clear();
}
+void AudioFlinger::PlaybackThread::OpPlayAudioMonitor::onFirstRef()
+{
+ PermissionController permissionController;
+ permissionController.getPackagesForUid(mUid, mPackages);
+ checkPlayAudioForUsage();
+ if (!mPackages.isEmpty()) {
+ mOpCallback = new PlayAudioOpCallback(this);
+ mAppOpsManager.startWatchingMode(AppOpsManager::OP_PLAY_AUDIO, mPackages[0], mOpCallback);
+ }
+}
+
bool AudioFlinger::PlaybackThread::OpPlayAudioMonitor::hasOpPlayAudio() const {
return mHasOpPlayAudio.load();
}
@@ -492,7 +505,7 @@ AudioFlinger::PlaybackThread::Track::Track(
mPresentationCompleteFrames(0),
mFrameMap(16 /* sink-frame-to-track-frame map memory */),
mVolumeHandler(new media::VolumeHandler(sampleRate)),
- mOpPlayAudioMonitor(new OpPlayAudioMonitor(uid, attr.usage, id(), streamType)),
+ mOpPlayAudioMonitor(OpPlayAudioMonitor::createIfNeeded(uid, attr.usage, id(), streamType)),
// mSinkTimestamp
mFastIndex(-1),
mCachedVolume(1.0),