AudioSystem: onServiceDied check service match
It is conceivable though unlikely that the onServiceDied notification
may match a previous server death if the service restarts quickly.
Warn when unusual situations occur.
Flag: EXEMPT bugfix
Test: for run in {1..100}; do (sleep 8; echo $run; adb shell pkill audioserver); done
Test: atest CtsMediaAudioTestCases
Bug: 379427790
Change-Id: Ic86a4ce45c46162f47b4cf846a37fc281ad3b01b
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 8094d07..c675c34 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -146,10 +146,19 @@
onNewServiceWithAdapter(createServiceAdapter(afs));
}
- static void onServiceDied(const sp<media::IAudioFlingerService>&) {
- ALOGW("%s: %s service died", __func__, getServiceName());
+ static void onServiceDied(const sp<media::IAudioFlingerService>& service) {
+ ALOGW("%s: %s service died %p", __func__, getServiceName(), service.get());
{
std::lock_guard l(mMutex);
+ if (!mValid) {
+ ALOGW("%s: %s service already invalidated, ignoring", __func__, getServiceName());
+ return;
+ }
+ if (!mService || mService->getDelegate() != service) {
+ ALOGW("%s: %s unmatched service death pointers, ignoring",
+ __func__, getServiceName());
+ return;
+ }
mValid = false;
if (mClient) {
mClient->clearIoCache();
@@ -219,12 +228,18 @@
static status_t setLocalService(const sp<IAudioFlinger>& af) {
mediautils::skipService<media::IAudioFlingerService>();
sp<IAudioFlinger> old;
- {
- std::lock_guard l(mMutex);
- old = mService;
- mService = af;
+
+ audio_utils::unique_lock ul(mMutex);
+ old = mService;
+ if (old) {
+ ul.unlock();
+ onServiceDied(old->getDelegate());
+ ul.lock();
+ ALOGW_IF(old != mService,
+ "%s: service changed during callback, continuing.", __func__);
}
- if (old) onServiceDied({});
+ mService = af;
+ ul.unlock();
if (af) onNewServiceWithAdapter(af);
return OK;
}
@@ -255,6 +270,8 @@
bool reportNoError = false;
{
std::lock_guard l(mMutex);
+ ALOGW_IF(mValid, "%s: %s service already valid, continuing with initialization",
+ __func__, getServiceName());
if (mClient == nullptr) {
mClient = sp<AudioSystem::AudioFlingerClient>::make();
} else {
@@ -985,6 +1002,8 @@
sp<AudioSystem::AudioPolicyServiceClient> client;
{
std::lock_guard l(mMutex);
+ ALOGW_IF(mValid, "%s: %s service already valid, continuing with initialization",
+ __func__, getServiceName());
if (mClient == nullptr) {
mClient = sp<AudioSystem::AudioPolicyServiceClient>::make();
}
@@ -1000,11 +1019,20 @@
IPCThreadState::self()->restoreCallingIdentity(token);
}
- static void onServiceDied(const sp<IAudioPolicyService>&) {
- ALOGW("%s: %s service died", __func__, getServiceName());
+ static void onServiceDied(const sp<IAudioPolicyService>& service) {
+ ALOGW("%s: %s service died %p", __func__, getServiceName(), service.get());
sp<AudioSystem::AudioPolicyServiceClient> client;
{
std::lock_guard l(mMutex);
+ if (!mValid) {
+ ALOGW("%s: %s service already invalidated, ignoring", __func__, getServiceName());
+ return;
+ }
+ if (mService != service) {
+ ALOGW("%s: %s unmatched service death pointers, ignoring",
+ __func__, getServiceName());
+ return;
+ }
mValid = false;
client = mClient;
}
@@ -1069,12 +1097,19 @@
static status_t setLocalService(const sp<IAudioPolicyService>& aps) {
mediautils::skipService<IAudioPolicyService>();
sp<IAudioPolicyService> old;
- {
- std::lock_guard l(mMutex);
- old = mService;
- mService = aps;
+ audio_utils::unique_lock ul(mMutex);
+ old = mService;
+ if (old) {
+ ul.unlock();
+ onServiceDied(old);
+ ul.lock();
+ if (mService != old) {
+ ALOGD("%s: service changed during callback, ignoring.", __func__);
+ return OK;
+ }
}
- if (old) onServiceDied(old);
+ mService = aps;
+ ul.unlock();
if (aps) onNewService(aps);
return OK;
}
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 8292eef..6b501a7 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -181,6 +181,8 @@
fromAidl(const media::CreateRecordResponse& aidl);
};
+ virtual sp<media::IAudioFlingerService> getDelegate() const { return {}; }
+
/* create an audio track and registers it with AudioFlinger.
* The audioTrack field will be null if the track cannot be created and the status will reflect
* failure.
@@ -414,6 +416,8 @@
public:
explicit AudioFlingerClientAdapter(const sp<media::IAudioFlingerService> delegate);
+ sp<media::IAudioFlingerService> getDelegate() const final { return mDelegate; }
+
status_t createTrack(const media::CreateTrackRequest& input,
media::CreateTrackResponse& output) override;
status_t createRecord(const media::CreateRecordRequest& input,