From d457c970c8d08519cd77280a90b61ae1e342cfe3 Mon Sep 17 00:00:00 2001 From: Marco Nelissen Date: Tue, 11 Feb 2014 08:47:07 -0800 Subject: Track pid for each session so they can be properly freed. Change-Id: I6f389035bc29e74e7c367c1c6d0252b180f666b3 --- include/media/AudioSystem.h | 4 +-- include/media/AudioTrack.h | 10 +++++--- include/media/IAudioFlinger.h | 4 +-- media/libmedia/AudioRecord.cpp | 4 +-- media/libmedia/AudioSystem.cpp | 8 +++--- media/libmedia/AudioTrack.cpp | 29 ++++++++++++++++------ media/libmedia/IAudioFlinger.cpp | 12 ++++++--- media/libmedia/mediaplayer.cpp | 8 +++--- media/libmediaplayerservice/MediaPlayerService.cpp | 12 ++++++--- media/libmediaplayerservice/MediaPlayerService.h | 3 ++- services/audioflinger/AudioFlinger.cpp | 16 ++++++++---- services/audioflinger/AudioFlinger.h | 4 +-- 12 files changed, 73 insertions(+), 41 deletions(-) diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index dfc2066..fd86737 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -141,8 +141,8 @@ public: static uint32_t getInputFramesLost(audio_io_handle_t ioHandle); static int newAudioSessionId(); - static void acquireAudioSessionId(int audioSession); - static void releaseAudioSessionId(int audioSession); + static void acquireAudioSessionId(int audioSession, pid_t pid); + static void releaseAudioSessionId(int audioSession, pid_t pid); // types of io configuration change events received with ioConfigChanged() enum io_config_event { diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index 5a50280..d0df710 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -190,7 +190,8 @@ public: int sessionId = AUDIO_SESSION_ALLOCATE, transfer_type transferType = TRANSFER_DEFAULT, const audio_offload_info_t *offloadInfo = NULL, - int uid = -1); + int uid = -1, + pid_t pid = -1); /* Creates an audio track and registers it with AudioFlinger. * With this constructor, the track is configured for static buffer mode. @@ -215,7 +216,8 @@ public: int sessionId = AUDIO_SESSION_ALLOCATE, transfer_type transferType = TRANSFER_DEFAULT, const audio_offload_info_t *offloadInfo = NULL, - int uid = -1); + int uid = -1, + pid_t pid = -1); /* Terminates the AudioTrack and unregisters it from AudioFlinger. * Also destroys all resources associated with the AudioTrack. @@ -253,7 +255,8 @@ public: int sessionId = AUDIO_SESSION_ALLOCATE, transfer_type transferType = TRANSFER_DEFAULT, const audio_offload_info_t *offloadInfo = NULL, - int uid = -1); + int uid = -1, + pid_t pid = -1); /* Result of constructing the AudioTrack. This must be checked for successful initialization * before using any AudioTrack API (except for set()), because using @@ -757,6 +760,7 @@ private: sp mDeathNotifier; uint32_t mSequence; // incremented for each new IAudioTrack attempt int mClientUid; + pid_t mClientPid; }; class TimedAudioTrack : public AudioTrack diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h index ea225ac..7f53bfc 100644 --- a/include/media/IAudioFlinger.h +++ b/include/media/IAudioFlinger.h @@ -180,8 +180,8 @@ public: virtual int newAudioSessionId() = 0; - virtual void acquireAudioSessionId(int audioSession) = 0; - virtual void releaseAudioSessionId(int audioSession) = 0; + virtual void acquireAudioSessionId(int audioSession, pid_t pid) = 0; + virtual void releaseAudioSessionId(int audioSession, pid_t pid) = 0; virtual status_t queryNumberEffects(uint32_t *numEffects) const = 0; diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index 541cb51..6ca499b 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -115,7 +115,7 @@ AudioRecord::~AudioRecord() mAudioRecord.clear(); } IPCThreadState::self()->flushCommands(); - AudioSystem::releaseAudioSessionId(mSessionId); + AudioSystem::releaseAudioSessionId(mSessionId, -1); } } @@ -266,7 +266,7 @@ status_t AudioRecord::set( mMarkerReached = false; mNewPosition = 0; mUpdatePeriod = 0; - AudioSystem::acquireAudioSessionId(mSessionId); + AudioSystem::acquireAudioSessionId(mSessionId, -1); mSequence = 1; mObservedSequence = mSequence; mInOverrun = false; diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index 87f4b4c..140fb66 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -435,19 +435,19 @@ int AudioSystem::newAudioSessionId() return af->newAudioSessionId(); } -void AudioSystem::acquireAudioSessionId(int audioSession) +void AudioSystem::acquireAudioSessionId(int audioSession, pid_t pid) { const sp& af = AudioSystem::get_audio_flinger(); if (af != 0) { - af->acquireAudioSessionId(audioSession); + af->acquireAudioSessionId(audioSession, pid); } } -void AudioSystem::releaseAudioSessionId(int audioSession) +void AudioSystem::releaseAudioSessionId(int audioSession, pid_t pid) { const sp& af = AudioSystem::get_audio_flinger(); if (af != 0) { - af->releaseAudioSessionId(audioSession); + af->releaseAudioSessionId(audioSession, pid); } } diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 63eaf1a..5c62260 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -116,7 +116,8 @@ AudioTrack::AudioTrack( int sessionId, transfer_type transferType, const audio_offload_info_t *offloadInfo, - int uid) + int uid, + pid_t pid) : mStatus(NO_INIT), mIsTimed(false), mPreviousPriority(ANDROID_PRIORITY_NORMAL), @@ -125,7 +126,7 @@ AudioTrack::AudioTrack( mStatus = set(streamType, sampleRate, format, channelMask, frameCount, flags, cbf, user, notificationFrames, 0 /*sharedBuffer*/, false /*threadCanCallJava*/, sessionId, transferType, - offloadInfo, uid); + offloadInfo, uid, pid); } AudioTrack::AudioTrack( @@ -141,7 +142,8 @@ AudioTrack::AudioTrack( int sessionId, transfer_type transferType, const audio_offload_info_t *offloadInfo, - int uid) + int uid, + pid_t pid) : mStatus(NO_INIT), mIsTimed(false), mPreviousPriority(ANDROID_PRIORITY_NORMAL), @@ -149,7 +151,8 @@ AudioTrack::AudioTrack( { mStatus = set(streamType, sampleRate, format, channelMask, 0 /*frameCount*/, flags, cbf, user, notificationFrames, - sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, uid); + sharedBuffer, false /*threadCanCallJava*/, sessionId, transferType, offloadInfo, + uid, pid); } AudioTrack::~AudioTrack() @@ -168,7 +171,9 @@ AudioTrack::~AudioTrack() mAudioTrack->asBinder()->unlinkToDeath(mDeathNotifier, this); mAudioTrack.clear(); IPCThreadState::self()->flushCommands(); - AudioSystem::releaseAudioSessionId(mSessionId); + ALOGV("~AudioTrack, releasing session id from %d on behalf of %d", + IPCThreadState::self()->getCallingPid(), mClientPid); + AudioSystem::releaseAudioSessionId(mSessionId, mClientPid); } } @@ -187,7 +192,8 @@ status_t AudioTrack::set( int sessionId, transfer_type transferType, const audio_offload_info_t *offloadInfo, - int uid) + int uid, + pid_t pid) { switch (transferType) { case TRANSFER_DEFAULT: @@ -335,11 +341,18 @@ status_t AudioTrack::set( mNotificationFramesReq = notificationFrames; mNotificationFramesAct = 0; mSessionId = sessionId; - if (uid == -1 || (IPCThreadState::self()->getCallingPid() != getpid())) { + int callingpid = IPCThreadState::self()->getCallingPid(); + int mypid = getpid(); + if (uid == -1 || (callingpid != mypid)) { mClientUid = IPCThreadState::self()->getCallingUid(); } else { mClientUid = uid; } + if (pid == -1 || (callingpid != mypid)) { + mClientPid = callingpid; + } else { + mClientPid = pid; + } mAuxEffectId = 0; mFlags = flags; mCbf = cbf; @@ -379,7 +392,7 @@ status_t AudioTrack::set( mMarkerReached = false; mNewPosition = 0; mUpdatePeriod = 0; - AudioSystem::acquireAudioSessionId(mSessionId); + AudioSystem::acquireAudioSessionId(mSessionId, mClientPid); mSequence = 1; mObservedSequence = mSequence; mInUnderrun = false; diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp index eef6a3d..7b15e68 100644 --- a/media/libmedia/IAudioFlinger.cpp +++ b/media/libmedia/IAudioFlinger.cpp @@ -609,19 +609,21 @@ public: return id; } - virtual void acquireAudioSessionId(int audioSession) + virtual void acquireAudioSessionId(int audioSession, int pid) { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); data.writeInt32(audioSession); + data.writeInt32(pid); remote()->transact(ACQUIRE_AUDIO_SESSION_ID, data, &reply); } - virtual void releaseAudioSessionId(int audioSession) + virtual void releaseAudioSessionId(int audioSession, int pid) { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); data.writeInt32(audioSession); + data.writeInt32(pid); remote()->transact(RELEASE_AUDIO_SESSION_ID, data, &reply); } @@ -1082,13 +1084,15 @@ status_t BnAudioFlinger::onTransact( case ACQUIRE_AUDIO_SESSION_ID: { CHECK_INTERFACE(IAudioFlinger, data, reply); int audioSession = data.readInt32(); - acquireAudioSessionId(audioSession); + int pid = data.readInt32(); + acquireAudioSessionId(audioSession, pid); return NO_ERROR; } break; case RELEASE_AUDIO_SESSION_ID: { CHECK_INTERFACE(IAudioFlinger, data, reply); int audioSession = data.readInt32(); - releaseAudioSessionId(audioSession); + int pid = data.readInt32(); + releaseAudioSessionId(audioSession, pid); return NO_ERROR; } break; case QUERY_NUM_EFFECTS: { diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp index 24663ad..d94c7c5 100644 --- a/media/libmedia/mediaplayer.cpp +++ b/media/libmedia/mediaplayer.cpp @@ -58,7 +58,7 @@ MediaPlayer::MediaPlayer() mVideoWidth = mVideoHeight = 0; mLockThreadId = 0; mAudioSessionId = AudioSystem::newAudioSessionId(); - AudioSystem::acquireAudioSessionId(mAudioSessionId); + AudioSystem::acquireAudioSessionId(mAudioSessionId, -1); mSendLevel = 0; mRetransmitEndpointValid = false; } @@ -66,7 +66,7 @@ MediaPlayer::MediaPlayer() MediaPlayer::~MediaPlayer() { ALOGV("destructor"); - AudioSystem::releaseAudioSessionId(mAudioSessionId); + AudioSystem::releaseAudioSessionId(mAudioSessionId, -1); disconnect(); IPCThreadState::self()->flushCommands(); } @@ -576,8 +576,8 @@ status_t MediaPlayer::setAudioSessionId(int sessionId) return BAD_VALUE; } if (sessionId != mAudioSessionId) { - AudioSystem::acquireAudioSessionId(sessionId); - AudioSystem::releaseAudioSessionId(mAudioSessionId); + AudioSystem::acquireAudioSessionId(sessionId, -1); + AudioSystem::releaseAudioSessionId(mAudioSessionId, -1); mAudioSessionId = sessionId; } return NO_ERROR; diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 1f70620..142788d 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -586,7 +586,8 @@ sp MediaPlayerService::Client::setDataSource_pre( } if (!p->hardwareOutput()) { - mAudioOutput = new AudioOutput(mAudioSessionId, IPCThreadState::self()->getCallingUid()); + mAudioOutput = new AudioOutput(mAudioSessionId, IPCThreadState::self()->getCallingUid(), + mPid); static_cast(p.get())->setAudioSink(mAudioOutput); } @@ -1299,13 +1300,14 @@ Exit: #undef LOG_TAG #define LOG_TAG "AudioSink" -MediaPlayerService::AudioOutput::AudioOutput(int sessionId, int uid) +MediaPlayerService::AudioOutput::AudioOutput(int sessionId, int uid, int pid) : mCallback(NULL), mCallbackCookie(NULL), mCallbackData(NULL), mBytesWritten(0), mSessionId(sessionId), mUid(uid), + mPid(pid), mFlags(AUDIO_OUTPUT_FLAG_NONE) { ALOGV("AudioOutput(%d)", sessionId); mStreamType = AUDIO_STREAM_MUSIC; @@ -1554,7 +1556,8 @@ status_t MediaPlayerService::AudioOutput::open( mSessionId, AudioTrack::TRANSFER_CALLBACK, offloadInfo, - mUid); + mUid, + mPid); } else { t = new AudioTrack( mStreamType, @@ -1569,7 +1572,8 @@ status_t MediaPlayerService::AudioOutput::open( mSessionId, AudioTrack::TRANSFER_DEFAULT, NULL, // offload info - mUid); + mUid, + mPid); } if ((t == 0) || (t->initCheck() != NO_ERROR)) { diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index fc355b0..448f27a 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -72,7 +72,7 @@ class MediaPlayerService : public BnMediaPlayerService class CallbackData; public: - AudioOutput(int sessionId, int uid); + AudioOutput(int sessionId, int uid, int pid); virtual ~AudioOutput(); virtual bool ready() const { return mTrack != 0; } @@ -140,6 +140,7 @@ class MediaPlayerService : public BnMediaPlayerService float mMsecsPerFrame; int mSessionId; int mUid; + int mPid; float mSendLevel; int mAuxEffectId; static bool mIsOnEmulator; diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 21bd2f4..b74fa89 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1929,18 +1929,21 @@ int AudioFlinger::newAudioSessionId() return nextUniqueId(); } -void AudioFlinger::acquireAudioSessionId(int audioSession) +void AudioFlinger::acquireAudioSessionId(int audioSession, pid_t pid) { Mutex::Autolock _l(mLock); pid_t caller = IPCThreadState::self()->getCallingPid(); - ALOGV("acquiring %d from %d", audioSession, caller); + ALOGV("acquiring %d from %d, for %d", audioSession, caller, pid); + if (pid != -1 && (caller == getpid_cached)) { + caller = pid; + } // Ignore requests received from processes not known as notification client. The request // is likely proxied by mediaserver (e.g CameraService) and releaseAudioSessionId() can be // called from a different pid leaving a stale session reference. Also we don't know how // to clear this reference if the client process dies. if (mNotificationClients.indexOfKey(caller) < 0) { - ALOGV("acquireAudioSessionId() unknown client %d for session %d", caller, audioSession); + ALOGW("acquireAudioSessionId() unknown client %d for session %d", caller, audioSession); return; } @@ -1957,11 +1960,14 @@ void AudioFlinger::acquireAudioSessionId(int audioSession) ALOGV(" added new entry for %d", audioSession); } -void AudioFlinger::releaseAudioSessionId(int audioSession) +void AudioFlinger::releaseAudioSessionId(int audioSession, pid_t pid) { Mutex::Autolock _l(mLock); pid_t caller = IPCThreadState::self()->getCallingPid(); - ALOGV("releasing %d from %d", audioSession, caller); + ALOGV("releasing %d from %d for %d", audioSession, caller, pid); + if (pid != -1 && (caller == getpid_cached)) { + caller = pid; + } size_t num = mAudioSessionRefs.size(); for (size_t i = 0; i< num; i++) { AudioSessionRef *ref = mAudioSessionRefs.itemAt(i); diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 459d2ec..4799beb 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -193,9 +193,9 @@ public: virtual int newAudioSessionId(); - virtual void acquireAudioSessionId(int audioSession); + virtual void acquireAudioSessionId(int audioSession, pid_t pid); - virtual void releaseAudioSessionId(int audioSession); + virtual void releaseAudioSessionId(int audioSession, pid_t pid); virtual status_t queryNumberEffects(uint32_t *numEffects) const; -- cgit v1.1