am 87fb4f30: am d1b28d41: audioflniger: fix leaked audiosession references
* commit '87fb4f30077e7bcf78e65cf25fe95bd58238bad1':
audioflniger: fix leaked audiosession references
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 4d36bad..68a4871 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -267,6 +267,12 @@
}
}
+ result.append("Notification Clients:\n");
+ for (size_t i = 0; i < mNotificationClients.size(); ++i) {
+ snprintf(buffer, SIZE, " pid: %d\n", mNotificationClients.keyAt(i));
+ result.append(buffer);
+ }
+
result.append("Global session refs:\n");
result.append(" session pid count\n");
for (size_t i = 0; i < mAudioSessionRefs.size(); i++) {
@@ -1852,6 +1858,16 @@
Mutex::Autolock _l(mLock);
pid_t caller = IPCThreadState::self()->getCallingPid();
ALOGV("acquiring %d from %d", audioSession, caller);
+
+ // 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);
+ return;
+ }
+
size_t num = mAudioSessionRefs.size();
for (size_t i = 0; i< num; i++) {
AudioSessionRef *ref = mAudioSessionRefs.editItemAt(i);
@@ -1884,7 +1900,9 @@
return;
}
}
- ALOGW("session id %d not found for pid %d", audioSession, caller);
+ // If the caller is mediaserver it is likely that the session being released was acquired
+ // on behalf of a process not in notification clients and we ignore the warning.
+ ALOGW_IF(caller != getpid_cached, "session id %d not found for pid %d", audioSession, caller);
}
void AudioFlinger::purgeStaleEffects_l() {