AudioSystem: new service cache reduces ANRs and improves performance.

Reduced ANRs:
1) Do not block on AudioFlinger or AudioPolicy for more than 10 seconds
to prevent ANRs.  Audioserver failure is returned to the AudioService which
can be ignored as the ground truth is stored in AudioService and
audioserver is currently dead.

2) Always check for audio services upon each thread request to avoid
ServiceManager notification failure when ThreadPool is locked up.

Improved performance:
1) Trigger actions based on binder driver death notifications and
ServiceManager service notifications, saves about 300ms on Track restore.

2) Single notification handling is shared among all clients.

Flag: EXEMPT bugfix
Test: instrumented audioserver delay, audio setting responsiveness
Test: instrumented audioserver delay, avoid ANR (see bug).
Test: hotword service works
Test: atest powerstats_collector_tests
Bug: 372348587
Change-Id: Ifd5b5457f4ca181ed30b6aea7ed4effad7aebef5
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index a178d01..483a1ef 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -26,12 +26,14 @@
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
 #include <binder/IPCThreadState.h>
+#include <cutils/properties.h>
 #include <media/AidlConversion.h>
 #include <media/AudioResamplerPublic.h>
 #include <media/AudioSystem.h>
 #include <media/IAudioFlinger.h>
 #include <media/PolicyAidlConversion.h>
 #include <media/TypeConverter.h>
+#include <mediautils/ServiceSingleton.h>
 #include <math.h>
 
 #include <system/audio.h>
@@ -80,172 +82,215 @@
 std::mutex AudioSystem::gSoundTriggerMutex;
 sp<CaptureStateListenerImpl> AudioSystem::gSoundTriggerCaptureStateListener;
 
-// Sets the Binder for the AudioFlinger service, passed to this client process
-// from the system server.
-// This allows specific isolated processes to access the audio system. Currently used only for the
-// HotwordDetectionService.
-template <typename ServiceInterface, typename Client, typename AidlInterface,
-        typename ServiceTraits>
-class ServiceHandler {
+// ----------------------------
+
+// AudioSystem is the client side interface to AudioFlinger (AF) and AudioPolicy (AP).
+//
+// For clients:
+// We use the ServiceSingleton class in mediautils to fetch the AF/AP service.
+// The ServiceSingleton offers service prefetch, automatic
+// new service notification, automatic binder death notification.
+//
+// AudioFlingerServiceTraits and AudioPolicyServiceTraits are passed into
+// ServiceSingleton to provide interaction with the service notifications and
+// binder death notifications.
+//
+// If the AF/AP service is unavailable for kServiceWaitMs from ServiceManager,
+// ServiceSingleton will return a nullptr service handle resulting in the same dead object error
+// as if the service died (which it did, otherwise we'd be returning the cached handle).
+//
+// Potential deadlock sequence:
+// 1) audioserver reboots.
+// 2) App clients call into AudioService (system server) obtaining binder threads,
+//    these calls blocking for audioserver reboot completion (or waiting for a mutex
+//    held by those blocked threads).
+// 3) AudioFlinger and AudioPolicyManager services need to call into system server
+//    during initialization.  It can't because app clients hold all the binder threads
+//    in the threadpool.
+// 4) We have a resource deadlock between (2) and (3) potentially causing an ANR and
+//    further reinitialization.
+// 5) However, after the service wait timeout kServiceWaitNs, the calls for (2) will
+//    return an error and resolve itself, breaking the resource deadlock in (4).
+//
+// At this time, it is a matter of experimentation whether the service timeout is
+// applied only for system server, and we let other clients block indefinitely.
+//
+// For audio services:
+// AudioFlinger and AudioPolicy may call back into AudioSystem.  When doing
+// so it should not hold any mutexes.  There is no service wait as AudioFlinger
+// and AudioPolicy are in-process with each other, and the call proceeds without
+// binder. The setLocalService() method is used to set the service interfaces
+// within audioserver to bypass the ServiceManager lookup.
+//
+
+// Wait timeout for AudioFlinger or AudioPolicy service before returning with null.
+// Such an audioserver failure is considered benign as the ground truth is stored in
+// the Java AudioService and can be restored once audioserver has finished initialization.
+//
+// TODO(b/375691003) We use 10s as a conservative timeout value, and will tune closer to 3s.
+// Too small a value (i.e. less than 1s would churn repeated calls to get the service).
+static constexpr int32_t kServiceWaitMs = 10'000;
+
+static constexpr const char kServiceWaitProperty[] = "audio.service.wait_ms";
+
+// AudioFlingerServiceTraits is a collection of methods that parameterize the
+// ServiceSingleton handler for IAudioFlinger
+
+class AudioFlingerServiceTraits {
 public:
-    sp<ServiceInterface> getService()
-            EXCLUDES(mMutex) NO_THREAD_SAFETY_ANALYSIS {  // std::unique_ptr
-        sp<ServiceInterface> service;
-        sp<Client> client;
+    // ------- required by ServiceSingleton
 
-        bool reportNoError = false;
+    static constexpr const char* getServiceName() { return "media.audio_flinger"; }
+
+    static void onNewService(const sp<media::IAudioFlingerService>& afs) {
+        onNewServiceWithAdapter(createServiceAdapter(afs));
+    }
+
+    static void onServiceDied(const sp<media::IAudioFlingerService>&) {
+        ALOGW("%s: %s service died", __func__, getServiceName());
         {
-            std::lock_guard _l(mMutex);
-            if (mService != nullptr) {
-                return mService;
-            }
+            std::lock_guard l(mMutex);
+            mValid = false;
+            mClient->clearIoCache();
         }
+        AudioSystem::reportError(DEAD_OBJECT);
+    }
 
-        std::unique_lock ul_only1thread(mSingleGetter);
-        std::unique_lock ul(mMutex);
-        if (mService != nullptr) {
-            return mService;
-        }
-        if (mClient == nullptr) {
-            mClient = sp<Client>::make();
-        } else {
-            reportNoError = true;
-        }
-        while (true) {
-            mService = mLocalService;
-            if (mService != nullptr) break;
+    static constexpr mediautils::ServiceOptions options() {
+        return mediautils::ServiceOptions::kNone;
+    }
 
-            sp<IBinder> binder = mBinder;
-            if (binder == nullptr) {
-                sp <IServiceManager> sm = defaultServiceManager();
-                binder = sm->checkService(String16(ServiceTraits::SERVICE_NAME));
-                if (binder == nullptr) {
-                    ALOGD("%s: waiting for %s", __func__, ServiceTraits::SERVICE_NAME);
+   // ------- required by AudioSystem
 
-                    // if the condition variable is present, setLocalService() and
-                    // setBinder() is allowed to use it to notify us.
-                    if (mCvGetter == nullptr) {
-                        mCvGetter = std::make_shared<std::condition_variable>();
-                    }
-                    mCvGetter->wait_for(ul, std::chrono::seconds(1));
-                    continue;
-                }
+    static sp<IAudioFlinger> getService(
+            std::chrono::milliseconds waitMs = std::chrono::milliseconds{-1}) {
+        static bool init = false;
+        audio_utils::unique_lock ul(mMutex);
+        if (!init) {
+            if (!mDisableThreadPoolStart) {
+                ProcessState::self()->startThreadPool();
             }
-            binder->linkToDeath(mClient);
-            auto aidlInterface = interface_cast<AidlInterface>(binder);
-            LOG_ALWAYS_FATAL_IF(aidlInterface == nullptr);
-            if constexpr (std::is_same_v<ServiceInterface, AidlInterface>) {
-                mService = std::move(aidlInterface);
-            } else /* constexpr */ {
-                mService = ServiceTraits::createServiceAdapter(aidlInterface);
-            }
-            break;
+            mediautils::initService<media::IAudioFlingerService, AudioFlingerServiceTraits>();
+            mWaitMs = std::chrono::milliseconds(
+                property_get_int32(kServiceWaitProperty, kServiceWaitMs));
+            init = true;
         }
-        if (mCvGetter) mCvGetter.reset();  // remove condition variable.
-        client = mClient;
-        service = mService;
-        // Make sure callbacks can be received by the client
-        if (mCanStartThreadPool) {
-            ProcessState::self()->startThreadPool();
-        }
+        if (mValid) return mService;
+        if (waitMs.count() < 0) waitMs = mWaitMs;
         ul.unlock();
-        ul_only1thread.unlock();
-        ServiceTraits::onServiceCreate(service, client);
-        if (reportNoError) AudioSystem::reportError(NO_ERROR);
-        return service;
+
+        // mediautils::getService() installs a persistent new service notification.
+        auto service = mediautils::getService<
+            media::IAudioFlingerService>(waitMs);
+        ALOGD("%s: checking for service %s: %p", __func__, getServiceName(), service.get());
+
+        ul.lock();
+        // return the IAudioFlinger interface which is adapted
+        // from the media::IAudioFlingerService.
+        return mService;
     }
 
-    status_t setLocalService(const sp<ServiceInterface>& service) EXCLUDES(mMutex) {
-        std::lock_guard _l(mMutex);
-        // we allow clearing once set, but not a double non-null set.
-        if (mService != nullptr && service != nullptr) return INVALID_OPERATION;
-        mLocalService = service;
-        if (mCvGetter) mCvGetter->notify_one();
-        return OK;
-    }
+    static sp<AudioSystem::AudioFlingerClient> getClient() {
+        audio_utils::unique_lock ul(mMutex);
+        if (mValid) return mClient;
+        ul.unlock();
 
-    sp<Client> getClient() EXCLUDES(mMutex)  {
-        const auto service = getService();
-        if (service == nullptr) return nullptr;
-        std::lock_guard _l(mMutex);
+        auto service = getService();
+        ALOGD("%s: checking for service: %p", __func__, service.get());
+
+        ul.lock();
         return mClient;
     }
 
-    void setBinder(const sp<IBinder>& binder) EXCLUDES(mMutex)  {
-        std::lock_guard _l(mMutex);
-        if (mService != nullptr) {
-            ALOGW("%s: ignoring; %s connection already established.",
-                    __func__, ServiceTraits::SERVICE_NAME);
-            return;
+    static void setBinder(const sp<IBinder>& binder) {
+         setLocalService(createServiceAdapter(
+                    mediautils::interfaceFromBinder<media::IAudioFlingerService>(binder)));
+    }
+
+    static status_t setLocalService(const sp<IAudioFlinger>& af) {
+        mediautils::skipService<media::IAudioFlingerService>();
+        sp<IAudioFlinger> old;
+        {
+            std::lock_guard l(mMutex);
+            old = mService;
+            mService = af;
         }
-        mBinder = binder;
-        if (mCvGetter) mCvGetter->notify_one();
+        if (old) onServiceDied({});
+        if (af) onNewServiceWithAdapter(af);
+        return OK;
     }
 
-    void clearService() EXCLUDES(mMutex)  {
-        std::lock_guard _l(mMutex);
-        mService.clear();
-        if (mClient) ServiceTraits::onClearService(mClient);
+    static void disableThreadPoolStart() {
+        mDisableThreadPoolStart = true;
     }
 
-    void disableThreadPool() {
-        mCanStartThreadPool = false;
+    static bool isValid() {
+        audio_utils::unique_lock ul(mMutex);
+        if (mValid) return true;
+        ul.unlock();
+        (void)getService({});
+        ul.lock();
+        return mValid;
+    }
+
+    // called to determine error on nullptr service return.
+    static constexpr status_t getError() {
+        return DEAD_OBJECT;
     }
 
 private:
-    std::mutex mSingleGetter;
-    std::mutex mMutex;
-    std::shared_ptr<std::condition_variable> mCvGetter GUARDED_BY(mMutex);
-    sp<IBinder> mBinder GUARDED_BY(mMutex);
-    sp<ServiceInterface> mLocalService GUARDED_BY(mMutex);
-    sp<ServiceInterface> mService GUARDED_BY(mMutex);
-    sp<Client> mClient GUARDED_BY(mMutex);
-    std::atomic<bool> mCanStartThreadPool = true;
-};
 
-struct AudioFlingerTraits {
-    static void onServiceCreate(
-            const sp<IAudioFlinger>& af, const sp<AudioSystem::AudioFlingerClient>& afc) {
+   static void onNewServiceWithAdapter(const sp<IAudioFlinger>& service) {
+        ALOGD("%s: %s service obtained %p", __func__, getServiceName(), service.get());
+        sp<AudioSystem::AudioFlingerClient> client;
+        bool reportNoError = false;
+        {
+            std::lock_guard l(mMutex);
+            if (mClient == nullptr) {
+                mClient = sp<AudioSystem::AudioFlingerClient>::make();
+            } else {
+                mClient->clearIoCache();
+                reportNoError = true;
+            }
+            mService = service;
+            client = mClient;
+            mValid = true;
+        }
+        // TODO(b/375280520) consider registerClient() within mMutex lock.
         const int64_t token = IPCThreadState::self()->clearCallingIdentity();
-        af->registerClient(afc);
+        service->registerClient(client);
         IPCThreadState::self()->restoreCallingIdentity(token);
+
+        if (reportNoError) AudioSystem::reportError(NO_ERROR);
     }
 
     static sp<IAudioFlinger> createServiceAdapter(
-            const sp<media::IAudioFlingerService>& aidlInterface) {
-        return sp<AudioFlingerClientAdapter>::make(aidlInterface);
+            const sp<media::IAudioFlingerService>& af) {
+        return sp<AudioFlingerClientAdapter>::make(af);
     }
 
-    static void onClearService(const sp<AudioSystem::AudioFlingerClient>& afc) {
-        afc->clearIoCache();
-    }
-
-    static constexpr const char* SERVICE_NAME = IAudioFlinger::DEFAULT_SERVICE_NAME;
+    static inline constinit std::mutex mMutex;
+    static inline constinit sp<AudioSystem::AudioFlingerClient> mClient GUARDED_BY(mMutex);
+    static inline constinit sp<IAudioFlinger> mService GUARDED_BY(mMutex);
+    static inline constinit std::chrono::milliseconds mWaitMs GUARDED_BY(mMutex) {kServiceWaitMs};
+    static inline constinit bool mValid GUARDED_BY(mMutex) = false;
+    static inline constinit std::atomic_bool mDisableThreadPoolStart = false;
 };
 
-[[clang::no_destroy]] static constinit ServiceHandler<IAudioFlinger,
-        AudioSystem::AudioFlingerClient, media::IAudioFlingerService,
-        AudioFlingerTraits> gAudioFlingerServiceHandler;
-
 sp<IAudioFlinger> AudioSystem::get_audio_flinger() {
-    return gAudioFlingerServiceHandler.getService();
+    return AudioFlingerServiceTraits::getService();
 }
 
 sp<AudioSystem::AudioFlingerClient> AudioSystem::getAudioFlingerClient() {
-    return gAudioFlingerServiceHandler.getClient();
+    return AudioFlingerServiceTraits::getClient();
 }
 
 void AudioSystem::setAudioFlingerBinder(const sp<IBinder>& audioFlinger) {
-    if (audioFlinger->getInterfaceDescriptor() != media::IAudioFlingerService::descriptor) {
-        ALOGE("%s: received a binder of type %s",
-                __func__, String8(audioFlinger->getInterfaceDescriptor()).c_str());
-        return;
-    }
-    gAudioFlingerServiceHandler.setBinder(audioFlinger);
+    AudioFlingerServiceTraits::setBinder(audioFlinger);
 }
 
 status_t AudioSystem::setLocalAudioFlinger(const sp<IAudioFlinger>& af) {
-    return gAudioFlingerServiceHandler.setLocalService(af);
+   return AudioFlingerServiceTraits::setLocalService(af);
 }
 
 sp<AudioIoDescriptor> AudioSystem::getIoDescriptor(audio_io_handle_t ioHandle) {
@@ -258,9 +303,7 @@
 }
 
 /* static */ status_t AudioSystem::checkAudioFlinger() {
-    if (defaultServiceManager()->checkService(String16("media.audio_flinger")) != 0) {
-        return NO_ERROR;
-    }
+    if (AudioFlingerServiceTraits::isValid()) return OK;
     return DEAD_OBJECT;
 }
 
@@ -268,41 +311,41 @@
 
 status_t AudioSystem::muteMicrophone(bool state) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     return af->setMicMute(state);
 }
 
 status_t AudioSystem::isMicrophoneMuted(bool* state) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     *state = af->getMicMute();
     return NO_ERROR;
 }
 
 status_t AudioSystem::setMasterVolume(float value) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     af->setMasterVolume(value);
     return NO_ERROR;
 }
 
 status_t AudioSystem::setMasterMute(bool mute) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     af->setMasterMute(mute);
     return NO_ERROR;
 }
 
 status_t AudioSystem::getMasterVolume(float* volume) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     *volume = af->masterVolume();
     return NO_ERROR;
 }
 
 status_t AudioSystem::getMasterMute(bool* mute) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     *mute = af->masterMute();
     return NO_ERROR;
 }
@@ -311,7 +354,7 @@
                                       bool muted, audio_io_handle_t output) {
     if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE;
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     af->setStreamVolume(stream, value, muted, output);
     return NO_ERROR;
 }
@@ -319,7 +362,7 @@
 status_t AudioSystem::setStreamMute(audio_stream_type_t stream, bool mute) {
     if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE;
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     af->setStreamMute(stream, mute);
     return NO_ERROR;
 }
@@ -328,7 +371,7 @@
         const std::vector<audio_port_handle_t>& portIds, float volume, bool muted,
         audio_io_handle_t output) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     std::vector<int32_t> portIdsAidl = VALUE_OR_RETURN_STATUS(
             convertContainer<std::vector<int32_t>>(
                     portIds, legacy2aidl_audio_port_handle_t_int32_t));
@@ -340,26 +383,26 @@
 status_t AudioSystem::setMode(audio_mode_t mode) {
     if (uint32_t(mode) >= AUDIO_MODE_CNT) return BAD_VALUE;
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     return af->setMode(mode);
 }
 
 status_t AudioSystem::setSimulateDeviceConnections(bool enabled) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     return af->setSimulateDeviceConnections(enabled);
 }
 
 status_t AudioSystem::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     return af->setParameters(ioHandle, keyValuePairs);
 }
 
 String8 AudioSystem::getParameters(audio_io_handle_t ioHandle, const String8& keys) {
     const sp<IAudioFlinger> af = get_audio_flinger();
     String8 result = String8("");
-    if (af == 0) return result;
+    if (af == nullptr) return result;
 
     result = af->getParameters(ioHandle, keys);
     return result;
@@ -438,7 +481,7 @@
 status_t AudioSystem::getSamplingRate(audio_io_handle_t ioHandle,
                                       uint32_t* samplingRate) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     sp<AudioIoDescriptor> desc = getIoDescriptor(ioHandle);
     if (desc == 0) {
         *samplingRate = af->sampleRate(ioHandle);
@@ -473,7 +516,7 @@
 status_t AudioSystem::getFrameCount(audio_io_handle_t ioHandle,
                                     size_t* frameCount) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     sp<AudioIoDescriptor> desc = getIoDescriptor(ioHandle);
     if (desc == 0) {
         *frameCount = af->frameCount(ioHandle);
@@ -508,7 +551,7 @@
 status_t AudioSystem::getLatency(audio_io_handle_t output,
                                  uint32_t* latency) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     sp<AudioIoDescriptor> outputDesc = getIoDescriptor(output);
     if (outputDesc == 0) {
         *latency = af->latency(output);
@@ -532,14 +575,14 @@
 
 status_t AudioSystem::setVoiceVolume(float value) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     return af->setVoiceVolume(value);
 }
 
 status_t AudioSystem::getRenderPosition(audio_io_handle_t output, uint32_t* halFrames,
                                         uint32_t* dspFrames) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
 
     return af->getRenderPosition(halFrames, dspFrames, output);
 }
@@ -547,7 +590,7 @@
 uint32_t AudioSystem::getInputFramesLost(audio_io_handle_t ioHandle) {
     const sp<IAudioFlinger> af = get_audio_flinger();
     uint32_t result = 0;
-    if (af == 0) return result;
+    if (af == nullptr) return result;
     if (ioHandle == AUDIO_IO_HANDLE_NONE) return result;
 
     result = af->getInputFramesLost(ioHandle);
@@ -557,7 +600,7 @@
 audio_unique_id_t AudioSystem::newAudioUniqueId(audio_unique_id_use_t use) {
     // Must not use AF as IDs will re-roll on audioserver restart, b/130369529.
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return AUDIO_UNIQUE_ID_ALLOCATE;
+    if (af == nullptr) return AUDIO_UNIQUE_ID_ALLOCATE;
     return af->newAudioUniqueId(use);
 }
 
@@ -577,26 +620,26 @@
 
 audio_hw_sync_t AudioSystem::getAudioHwSyncForSession(audio_session_t sessionId) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return AUDIO_HW_SYNC_INVALID;
+    if (af == nullptr) return AUDIO_HW_SYNC_INVALID;
     return af->getAudioHwSyncForSession(sessionId);
 }
 
 status_t AudioSystem::systemReady() {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return NO_INIT;
+    if (af == nullptr) return NO_INIT;
     return af->systemReady();
 }
 
 status_t AudioSystem::audioPolicyReady() {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return NO_INIT;
+    if (af == nullptr) return NO_INIT;
     return af->audioPolicyReady();
 }
 
 status_t AudioSystem::getFrameCountHAL(audio_io_handle_t ioHandle,
                                        size_t* frameCount) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     sp<AudioIoDescriptor> desc = getIoDescriptor(ioHandle);
     if (desc == 0) {
         *frameCount = af->frameCountHAL(ioHandle);
@@ -625,13 +668,6 @@
     mInChannelMask = AUDIO_CHANNEL_NONE;
 }
 
-void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who __unused) {
-    gAudioFlingerServiceHandler.clearService();
-    reportError(DEAD_OBJECT);
-
-    ALOGW("AudioFlinger server died!");
-}
-
 Status AudioSystem::AudioFlingerClient::ioConfigChanged(
         media::AudioIoConfigEvent _event,
         const media::AudioIoDescriptor& _ioDesc) {
@@ -788,9 +824,7 @@
         uint32_t sampleRate, audio_format_t format,
         audio_channel_mask_t channelMask, size_t* buffSize) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) {
-        return PERMISSION_DENIED;
-    }
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     std::lock_guard _l(mMutex);
     // Do we have a stale mInBuffSize or are we requesting the input buffer size for new values
     if ((mInBuffSize == 0) || (sampleRate != mInSamplingRate) || (format != mInFormat)
@@ -925,47 +959,145 @@
     gVolRangeInitReqCallback = cb;
 }
 
-struct AudioPolicyTraits {
-    static void onServiceCreate(const sp<IAudioPolicyService>& ap,
-            const sp<AudioSystem::AudioPolicyServiceClient>& apc) {
+
+// AudioPolicyServiceTraits is a collection of methods that parameterize the
+// ServiceSingleton class implementation of IAudioPolicyService.
+
+class AudioPolicyServiceTraits {
+public:
+    // ------- methods required by ServiceSingleton
+
+    static constexpr const char* getServiceName() { return "media.audio_policy"; }
+
+    static void onNewService(const sp<IAudioPolicyService>& aps) {
+        ALOGD("%s: %s service obtained %p", __func__, getServiceName(), aps.get());
+        sp<AudioSystem::AudioPolicyServiceClient> client;
+        {
+            std::lock_guard l(mMutex);
+            if (mClient == nullptr) {
+                mClient = sp<AudioSystem::AudioPolicyServiceClient>::make();
+            }
+            client = mClient;
+            mService = aps;
+            mValid = true;
+        }
+        // TODO(b/375280520) consider registerClient() within mMutex lock.
         const int64_t token = IPCThreadState::self()->clearCallingIdentity();
-        ap->registerClient(apc);
-        ap->setAudioPortCallbacksEnabled(apc->isAudioPortCbEnabled());
-        ap->setAudioVolumeGroupCallbacksEnabled(apc->isAudioVolumeGroupCbEnabled());
+        aps->registerClient(client);
         IPCThreadState::self()->restoreCallingIdentity(token);
     }
 
-    static void onClearService(const sp<AudioSystem::AudioPolicyServiceClient>&) {}
+    static void onServiceDied(const sp<IAudioPolicyService>&) {
+        ALOGW("%s: %s service died", __func__, getServiceName());
+        sp<AudioSystem::AudioPolicyServiceClient> client;
+        {
+            std::lock_guard l(mMutex);
+            mValid = false;
+            client = mClient;
+        }
+        client->onServiceDied();
+    }
 
-    static constexpr const char *SERVICE_NAME = "media.audio_policy";
+    static constexpr mediautils::ServiceOptions options() {
+        return mediautils::ServiceOptions::kNone;
+    }
+
+    // ------- methods required by AudioSystem
+
+    static sp<IAudioPolicyService> getService(
+            std::chrono::milliseconds waitMs = std::chrono::milliseconds{-1}) {
+        static bool init = false;
+        audio_utils::unique_lock ul(mMutex);
+        if (!init) {
+            if (!mDisableThreadPoolStart) {
+                ProcessState::self()->startThreadPool();
+            }
+            mediautils::initService<IAudioPolicyService, AudioPolicyServiceTraits>();
+            mWaitMs = std::chrono::milliseconds(
+                    property_get_int32(kServiceWaitProperty, kServiceWaitMs));
+            init = true;
+        }
+        if (mValid) return mService;
+        if (waitMs.count() < 0) waitMs = mWaitMs;
+        ul.unlock();
+
+        auto service = mediautils::getService<
+                media::IAudioPolicyService>(waitMs);
+        ALOGD("%s: checking for service %s: %p", __func__, getServiceName(), service.get());
+
+        // mediautils::getService() will return early if setLocalService() is called
+        // (whereupon mService contained the actual local service pointer to use).
+        // we should always return mService.
+        ul.lock();
+        return mService;
+    }
+
+    static sp<AudioSystem::AudioPolicyServiceClient> getClient() {
+        audio_utils::unique_lock ul(mMutex);
+        if (mValid) return mClient;
+        ul.unlock();
+
+        auto service = getService();
+        ALOGD("%s: checking for service: %p", __func__, service.get());
+
+        ul.lock();
+        return mClient;
+    }
+
+    static status_t setLocalService(const sp<IAudioPolicyService>& aps) {
+        mediautils::skipService<IAudioPolicyService>();
+        sp<IAudioPolicyService> old;
+        {
+            std::lock_guard l(mMutex);
+            old = mService;
+            mService = aps;
+        }
+        if (old) onServiceDied(old);
+        if (aps) onNewService(aps);
+        return OK;
+    }
+
+    static void disableThreadPoolStart() {
+        mDisableThreadPoolStart = true;
+    }
+
+    // called to determine error on nullptr service return.
+    static constexpr status_t getError() {
+        return DEAD_OBJECT;
+    }
+private:
+
+    static inline constinit std::mutex mMutex;
+    static inline constinit sp<AudioSystem::AudioPolicyServiceClient> mClient GUARDED_BY(mMutex);
+    static inline constinit sp<IAudioPolicyService> mService GUARDED_BY(mMutex);
+    static inline constinit bool mValid GUARDED_BY(mMutex) = false;
+    static inline constinit std::chrono::milliseconds mWaitMs GUARDED_BY(mMutex) {kServiceWaitMs};
+    static inline constinit std::atomic_bool mDisableThreadPoolStart = false;
 };
 
-[[clang::no_destroy]] static constinit ServiceHandler<IAudioPolicyService,
-        AudioSystem::AudioPolicyServiceClient, IAudioPolicyService,
-        AudioPolicyTraits> gAudioPolicyServiceHandler;
-
-status_t AudioSystem::setLocalAudioPolicyService(const sp<IAudioPolicyService>& aps) {
-    return gAudioPolicyServiceHandler.setLocalService(aps);
-}
 
 sp<IAudioPolicyService> AudioSystem::get_audio_policy_service() {
-    return gAudioPolicyServiceHandler.getService();
+    return AudioPolicyServiceTraits::getService();
 }
 
-void AudioSystem::clearAudioPolicyService() {
-    gAudioPolicyServiceHandler.clearService();
+status_t AudioSystem::setLocalAudioPolicyService(const sp<IAudioPolicyService>& aps) {
+    return AudioPolicyServiceTraits::setLocalService(aps);
+}
+
+sp<AudioSystem::AudioPolicyServiceClient> AudioSystem::getAudioPolicyClient() {
+    return AudioPolicyServiceTraits::getClient();
 }
 
 void AudioSystem::disableThreadPool() {
-    gAudioFlingerServiceHandler.disableThreadPool();
-    gAudioPolicyServiceHandler.disableThreadPool();
+    AudioFlingerServiceTraits::disableThreadPoolStart();
+    AudioPolicyServiceTraits::disableThreadPoolStart();
 }
 
 // ---------------------------------------------------------------------------
 
 void AudioSystem::onNewAudioModulesAvailable() {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return;
+    if (aps == nullptr) return;
     aps->onNewAudioModulesAvailable();
 }
 
@@ -974,7 +1106,7 @@
                                                audio_format_t encodedFormat) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
 
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     return statusTFromBinderStatus(
             aps->setDeviceConnectionState(
@@ -988,7 +1120,7 @@
 audio_policy_dev_state_t AudioSystem::getDeviceConnectionState(audio_devices_t device,
                                                                const char* device_address) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
+    if (aps == nullptr) return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
 
     auto result = [&]() -> ConversionResult<audio_policy_dev_state_t> {
         AudioDevice deviceAidl = VALUE_OR_RETURN(
@@ -1011,7 +1143,7 @@
     const char* address = "";
     const char* name = "";
 
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     if (device_address != NULL) {
         address = device_address;
@@ -1031,7 +1163,7 @@
 status_t AudioSystem::setPhoneState(audio_mode_t state, uid_t uid) {
     if (uint32_t(state) >= AUDIO_MODE_CNT) return BAD_VALUE;
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     return statusTFromBinderStatus(aps->setPhoneState(
             VALUE_OR_RETURN_STATUS(legacy2aidl_audio_mode_t_AudioMode(state)),
@@ -1041,7 +1173,7 @@
 status_t
 AudioSystem::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     return statusTFromBinderStatus(
             aps->setForceUse(
@@ -1054,7 +1186,7 @@
 
 audio_policy_forced_cfg_t AudioSystem::getForceUse(audio_policy_force_use_t usage) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return AUDIO_POLICY_FORCE_NONE;
+    if (aps == nullptr) return AUDIO_POLICY_FORCE_NONE;
 
     auto result = [&]() -> ConversionResult<audio_policy_forced_cfg_t> {
         AudioPolicyForceUse usageAidl = VALUE_OR_RETURN(
@@ -1071,7 +1203,7 @@
 
 audio_io_handle_t AudioSystem::getOutput(audio_stream_type_t stream) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return AUDIO_IO_HANDLE_NONE;
+    if (aps == nullptr) return AUDIO_IO_HANDLE_NONE;
 
     auto result = [&]() -> ConversionResult<audio_io_handle_t> {
         AudioStreamType streamAidl = VALUE_OR_RETURN(
@@ -1121,7 +1253,7 @@
     }
 
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return NO_INIT;
+    if (aps == nullptr) return NO_INIT;
 
     media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_attributes_t_AudioAttributes(*attr));
@@ -1172,7 +1304,7 @@
 
 status_t AudioSystem::startOutput(audio_port_handle_t portId) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     int32_t portIdAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_handle_t_int32_t(portId));
     return statusTFromBinderStatus(aps->startOutput(portIdAidl));
@@ -1180,7 +1312,7 @@
 
 status_t AudioSystem::stopOutput(audio_port_handle_t portId) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     int32_t portIdAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_handle_t_int32_t(portId));
     return statusTFromBinderStatus(aps->stopOutput(portIdAidl));
@@ -1188,7 +1320,7 @@
 
 void AudioSystem::releaseOutput(audio_port_handle_t portId) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return;
+    if (aps == nullptr) return;
 
     auto status = [&]() -> status_t {
         int32_t portIdAidl = VALUE_OR_RETURN_STATUS(
@@ -1228,7 +1360,7 @@
     }
 
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return NO_INIT;
+    if (aps == nullptr) return NO_INIT;
 
     media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_attributes_t_AudioAttributes(*attr));
@@ -1262,7 +1394,7 @@
 
 status_t AudioSystem::startInput(audio_port_handle_t portId) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     int32_t portIdAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_handle_t_int32_t(portId));
     return statusTFromBinderStatus(aps->startInput(portIdAidl));
@@ -1270,7 +1402,7 @@
 
 status_t AudioSystem::stopInput(audio_port_handle_t portId) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     int32_t portIdAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_handle_t_int32_t(portId));
     return statusTFromBinderStatus(aps->stopInput(portIdAidl));
@@ -1278,7 +1410,7 @@
 
 void AudioSystem::releaseInput(audio_port_handle_t portId) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return;
+    if (aps == nullptr) return;
 
     auto status = [&]() -> status_t {
         int32_t portIdAidl = VALUE_OR_RETURN_STATUS(
@@ -1296,7 +1428,7 @@
                                                      bool enabled,
                                                      audio_stream_type_t streamToDriveAbs) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == nullptr) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     AudioDevice deviceAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_device_AudioDevice(deviceType, address));
@@ -1310,7 +1442,7 @@
                                        int indexMin,
                                        int indexMax) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     AudioStreamType streamAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_stream_type_t_AudioStreamType(stream));
@@ -1318,12 +1450,6 @@
     int32_t indexMaxAidl = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(indexMax));
     status_t status = statusTFromBinderStatus(
             aps->initStreamVolume(streamAidl, indexMinAidl, indexMaxAidl));
-    if (status == DEAD_OBJECT) {
-        // This is a critical operation since w/o proper stream volumes no audio
-        // will be heard. Make sure we recover from a failure in any case.
-        ALOGE("Received DEAD_OBJECT from APS, clearing the client");
-        clearAudioPolicyService();
-    }
     return status;
 }
 
@@ -1332,7 +1458,7 @@
                                            bool muted,
                                            audio_devices_t device) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     AudioStreamType streamAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_stream_type_t_AudioStreamType(stream));
@@ -1347,7 +1473,7 @@
                                            int* index,
                                            audio_devices_t device) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     AudioStreamType streamAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_stream_type_t_AudioStreamType(stream));
@@ -1367,7 +1493,7 @@
                                                   bool muted,
                                                   audio_devices_t device) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_attributes_t_AudioAttributes(attr));
@@ -1382,7 +1508,7 @@
                                                   int& index,
                                                   audio_devices_t device) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_attributes_t_AudioAttributes(attr));
@@ -1397,7 +1523,7 @@
 
 status_t AudioSystem::getMaxVolumeIndexForAttributes(const audio_attributes_t& attr, int& index) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_attributes_t_AudioAttributes(attr));
@@ -1410,7 +1536,7 @@
 
 status_t AudioSystem::getMinVolumeIndexForAttributes(const audio_attributes_t& attr, int& index) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_attributes_t_AudioAttributes(attr));
@@ -1423,7 +1549,7 @@
 
 product_strategy_t AudioSystem::getStrategyForStream(audio_stream_type_t stream) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PRODUCT_STRATEGY_NONE;
+    if (aps == nullptr) return PRODUCT_STRATEGY_NONE;
 
     auto result = [&]() -> ConversionResult<product_strategy_t> {
         AudioStreamType streamAidl = VALUE_OR_RETURN(
@@ -1443,7 +1569,7 @@
         return BAD_VALUE;
     }
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     media::audio::common::AudioAttributes aaAidl = VALUE_OR_RETURN_STATUS(
              legacy2aidl_audio_attributes_t_AudioAttributes(aa));
@@ -1460,7 +1586,7 @@
 audio_io_handle_t AudioSystem::getOutputForEffect(const effect_descriptor_t* desc) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
     // FIXME change return type to status_t, and return PERMISSION_DENIED here
-    if (aps == 0) return AUDIO_IO_HANDLE_NONE;
+    if (aps == nullptr) return AUDIO_IO_HANDLE_NONE;
 
     auto result = [&]() -> ConversionResult<audio_io_handle_t> {
         media::EffectDescriptor descAidl = VALUE_OR_RETURN(
@@ -1480,7 +1606,7 @@
                                      audio_session_t session,
                                      int id) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     media::EffectDescriptor descAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_effect_descriptor_t_EffectDescriptor(*desc));
@@ -1494,7 +1620,7 @@
 
 status_t AudioSystem::unregisterEffect(int id) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     int32_t idAidl = VALUE_OR_RETURN_STATUS(convertReinterpret<int32_t>(id));
     return statusTFromBinderStatus(
@@ -1503,7 +1629,7 @@
 
 status_t AudioSystem::setEffectEnabled(int id, bool enabled) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     int32_t idAidl = VALUE_OR_RETURN_STATUS(convertReinterpret<int32_t>(id));
     return statusTFromBinderStatus(
@@ -1512,7 +1638,7 @@
 
 status_t AudioSystem::moveEffectsToIo(const std::vector<int>& ids, audio_io_handle_t io) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     std::vector<int32_t> idsAidl = VALUE_OR_RETURN_STATUS(
             convertContainer<std::vector<int32_t>>(ids, convertReinterpret<int32_t, int>));
@@ -1522,7 +1648,7 @@
 
 status_t AudioSystem::isStreamActive(audio_stream_type_t stream, bool* state, uint32_t inPastMs) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
     if (state == NULL) return BAD_VALUE;
 
     AudioStreamType streamAidl = VALUE_OR_RETURN_STATUS(
@@ -1536,7 +1662,7 @@
 status_t AudioSystem::isStreamActiveRemotely(audio_stream_type_t stream, bool* state,
                                              uint32_t inPastMs) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
     if (state == NULL) return BAD_VALUE;
 
     AudioStreamType streamAidl = VALUE_OR_RETURN_STATUS(
@@ -1549,7 +1675,7 @@
 
 status_t AudioSystem::isSourceActive(audio_source_t stream, bool* state) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
     if (state == NULL) return BAD_VALUE;
 
     AudioSource streamAidl = VALUE_OR_RETURN_STATUS(
@@ -1561,32 +1687,25 @@
 
 uint32_t AudioSystem::getPrimaryOutputSamplingRate() {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return 0;
+    if (af == nullptr) return 0;
     return af->getPrimaryOutputSamplingRate();
 }
 
 size_t AudioSystem::getPrimaryOutputFrameCount() {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return 0;
+    if (af == nullptr) return 0;
     return af->getPrimaryOutputFrameCount();
 }
 
 status_t AudioSystem::setLowRamDevice(bool isLowRamDevice, int64_t totalMemory) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     return af->setLowRamDevice(isLowRamDevice, totalMemory);
 }
 
-void AudioSystem::clearAudioConfigCache() {
-    // called by restoreTrack_l(), which needs new IAudioFlinger and IAudioPolicyService instances
-    ALOGV("clearAudioConfigCache()");
-    gAudioFlingerServiceHandler.clearService();
-    clearAudioPolicyService();
-}
-
 status_t AudioSystem::setSupportedSystemUsages(const std::vector<audio_usage_t>& systemUsages) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == nullptr) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     std::vector<AudioUsage> systemUsagesAidl = VALUE_OR_RETURN_STATUS(
             convertContainer<std::vector<AudioUsage>>(systemUsages,
@@ -1596,7 +1715,7 @@
 
 status_t AudioSystem::setAllowedCapturePolicy(uid_t uid, audio_flags_mask_t capturePolicy) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == nullptr) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     int32_t uidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(uid));
     int32_t capturePolicyAidl = VALUE_OR_RETURN_STATUS(
@@ -1607,7 +1726,7 @@
 audio_offload_mode_t AudioSystem::getOffloadSupport(const audio_offload_info_t& info) {
     ALOGV("%s", __func__);
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return AUDIO_OFFLOAD_NOT_SUPPORTED;
+    if (aps == nullptr) return AUDIO_OFFLOAD_NOT_SUPPORTED;
 
     auto result = [&]() -> ConversionResult<audio_offload_mode_t> {
         AudioOffloadInfo infoAidl = VALUE_OR_RETURN(
@@ -1632,7 +1751,7 @@
     }
 
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     media::AudioPortRole roleAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_port_role_t_AudioPortRole(role));
@@ -1656,7 +1775,7 @@
                                               std::vector<media::AudioPortFw>* result) {
     if (result == nullptr) return BAD_VALUE;
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
     RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(aps->listDeclaredDevicePorts(role, result)));
     return OK;
 }
@@ -1666,7 +1785,7 @@
         return BAD_VALUE;
     }
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     media::AudioPortFw portAidl;
     RETURN_STATUS_IF_ERROR(
@@ -1682,7 +1801,7 @@
     }
 
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     media::AudioPatchFw patchAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_patch_AudioPatchFw(*patch));
@@ -1695,7 +1814,7 @@
 
 status_t AudioSystem::releaseAudioPatch(audio_patch_handle_t handle) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     int32_t handleAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_patch_handle_t_int32_t(handle));
     return statusTFromBinderStatus(aps->releaseAudioPatch(handleAidl));
@@ -1710,7 +1829,7 @@
     }
 
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
 
     Int numPatchesAidl;
@@ -1733,7 +1852,7 @@
     }
 
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     media::AudioPortConfigFw configAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_port_config_AudioPortConfigFw(*config));
@@ -1742,8 +1861,8 @@
 
 status_t AudioSystem::addAudioPortCallback(const sp<AudioPortCallback>& callback) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
-    const auto apc = gAudioPolicyServiceHandler.getClient();
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
+    const auto apc = getAudioPolicyClient();
     if (apc == nullptr) return NO_INIT;
 
     std::lock_guard _l(gApsCallbackMutex);
@@ -1757,8 +1876,8 @@
 /*static*/
 status_t AudioSystem::removeAudioPortCallback(const sp<AudioPortCallback>& callback) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
-    const auto apc = gAudioPolicyServiceHandler.getClient();
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
+    const auto apc = AudioSystem::getAudioPolicyClient();
     if (apc == nullptr) return NO_INIT;
 
     std::lock_guard _l(gApsCallbackMutex);
@@ -1771,8 +1890,8 @@
 
 status_t AudioSystem::addAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
-    const auto apc = gAudioPolicyServiceHandler.getClient();
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
+    const auto apc = AudioSystem::getAudioPolicyClient();
     if (apc == nullptr) return NO_INIT;
 
     std::lock_guard _l(gApsCallbackMutex);
@@ -1785,8 +1904,8 @@
 
 status_t AudioSystem::removeAudioVolumeGroupCallback(const sp<AudioVolumeGroupCallback>& callback) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
-    const auto apc = gAudioPolicyServiceHandler.getClient();
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
+    const auto apc = AudioSystem::getAudioPolicyClient();
     if (apc == nullptr) return NO_INIT;
 
     std::lock_guard _l(gApsCallbackMutex);
@@ -1844,7 +1963,7 @@
 
 audio_port_handle_t AudioSystem::getDeviceIdForIo(audio_io_handle_t audioIo) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     const sp<AudioIoDescriptor> desc = getIoDescriptor(audioIo);
     if (desc == 0) {
         return AUDIO_PORT_HANDLE_NONE;
@@ -1859,7 +1978,7 @@
         return BAD_VALUE;
     }
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     media::SoundTriggerSession retAidl;
     RETURN_STATUS_IF_ERROR(
@@ -1873,7 +1992,7 @@
 
 status_t AudioSystem::releaseSoundTriggerSession(audio_session_t session) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     int32_t sessionAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_session_t_int32_t(session));
     return statusTFromBinderStatus(aps->releaseSoundTriggerSession(sessionAidl));
@@ -1881,7 +2000,7 @@
 
 audio_mode_t AudioSystem::getPhoneState() {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return AUDIO_MODE_INVALID;
+    if (aps == nullptr) return AUDIO_MODE_INVALID;
 
     auto result = [&]() -> ConversionResult<audio_mode_t> {
         media::audio::common::AudioMode retAidl;
@@ -1894,7 +2013,7 @@
 
 status_t AudioSystem::registerPolicyMixes(const Vector<AudioMix>& mixes, bool registration) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     size_t mixesSize = std::min(mixes.size(), size_t{MAX_MIXES_PER_POLICY});
     std::vector<media::AudioMix> mixesAidl;
@@ -1910,7 +2029,7 @@
     }
 
     const sp<IAudioPolicyService> aps = AudioSystem::get_audio_policy_service();
-    if (aps == nullptr) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     std::vector<::android::media::AudioMix> aidlMixes;
     Status status = aps->getRegisteredPolicyMixes(&aidlMixes);
@@ -1927,7 +2046,7 @@
         const std::vector<std::pair<AudioMix, std::vector<AudioMixMatchCriterion>>>&
                 mixesWithUpdates) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     std::vector<media::AudioMixUpdate> updatesAidl;
     updatesAidl.reserve(mixesWithUpdates.size());
@@ -1946,7 +2065,7 @@
 
 status_t AudioSystem::setUidDeviceAffinities(uid_t uid, const AudioDeviceTypeAddrVector& devices) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     int32_t uidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(uid));
     std::vector<AudioDevice> devicesAidl = VALUE_OR_RETURN_STATUS(
@@ -1957,7 +2076,7 @@
 
 status_t AudioSystem::removeUidDeviceAffinities(uid_t uid) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     int32_t uidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(uid));
     return statusTFromBinderStatus(aps->removeUidDeviceAffinities(uidAidl));
@@ -1966,7 +2085,7 @@
 status_t AudioSystem::setUserIdDeviceAffinities(int userId,
                                                 const AudioDeviceTypeAddrVector& devices) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     int32_t userIdAidl = VALUE_OR_RETURN_STATUS(convertReinterpret<int32_t>(userId));
     std::vector<AudioDevice> devicesAidl = VALUE_OR_RETURN_STATUS(
@@ -1978,7 +2097,7 @@
 
 status_t AudioSystem::removeUserIdDeviceAffinities(int userId) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
     int32_t userIdAidl = VALUE_OR_RETURN_STATUS(convertReinterpret<int32_t>(userId));
     return statusTFromBinderStatus(aps->removeUserIdDeviceAffinities(userIdAidl));
 }
@@ -1990,7 +2109,7 @@
         return BAD_VALUE;
     }
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     media::AudioPortConfigFw sourceAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_port_config_AudioPortConfigFw(*source));
@@ -2005,7 +2124,7 @@
 
 status_t AudioSystem::stopAudioSource(audio_port_handle_t portId) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     int32_t portIdAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_handle_t_int32_t(portId));
     return statusTFromBinderStatus(aps->stopAudioSource(portIdAidl));
@@ -2013,7 +2132,7 @@
 
 status_t AudioSystem::setMasterMono(bool mono) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
     return statusTFromBinderStatus(aps->setMasterMono(mono));
 }
 
@@ -2022,26 +2141,26 @@
         return BAD_VALUE;
     }
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
     return statusTFromBinderStatus(aps->getMasterMono(mono));
 }
 
 status_t AudioSystem::setMasterBalance(float balance) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     return af->setMasterBalance(balance);
 }
 
 status_t AudioSystem::getMasterBalance(float* balance) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     return af->getMasterBalance(balance);
 }
 
 float
 AudioSystem::getStreamVolumeDB(audio_stream_type_t stream, int index, audio_devices_t device) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return NAN;
+    if (aps == nullptr) return NAN;
 
     auto result = [&]() -> ConversionResult<float> {
         AudioStreamType streamAidl = VALUE_OR_RETURN(
@@ -2059,13 +2178,13 @@
 
 status_t AudioSystem::getMicrophones(std::vector<media::MicrophoneInfoFw>* microphones) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     return af->getMicrophones(microphones);
 }
 
 status_t AudioSystem::setAudioHalPids(const std::vector<pid_t>& pids) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == nullptr) return PERMISSION_DENIED;
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     return af->setAudioHalPids(pids);
 }
 
@@ -2079,7 +2198,7 @@
     }
 
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
     Int numSurroundFormatsAidl;
     numSurroundFormatsAidl.value =
             VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(*numSurroundFormats));
@@ -2106,7 +2225,7 @@
     }
 
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
     Int numSurroundFormatsAidl;
     numSurroundFormatsAidl.value =
             VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(*numSurroundFormats));
@@ -2124,7 +2243,7 @@
 
 status_t AudioSystem::setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     AudioFormatDescription audioFormatAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_format_t_AudioFormatDescription(audioFormat));
@@ -2134,7 +2253,7 @@
 
 status_t AudioSystem::setAssistantServicesUids(const std::vector<uid_t>& uids) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     std::vector<int32_t> uidsAidl = VALUE_OR_RETURN_STATUS(
                 convertContainer<std::vector<int32_t>>(uids, legacy2aidl_uid_t_int32_t));
@@ -2143,7 +2262,7 @@
 
 status_t AudioSystem::setActiveAssistantServicesUids(const std::vector<uid_t>& activeUids) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     std::vector<int32_t> activeUidsAidl = VALUE_OR_RETURN_STATUS(
                 convertContainer<std::vector<int32_t>>(activeUids, legacy2aidl_uid_t_int32_t));
@@ -2152,7 +2271,7 @@
 
 status_t AudioSystem::setA11yServicesUids(const std::vector<uid_t>& uids) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     std::vector<int32_t> uidsAidl = VALUE_OR_RETURN_STATUS(
             convertContainer<std::vector<int32_t>>(uids, legacy2aidl_uid_t_int32_t));
@@ -2161,7 +2280,7 @@
 
 status_t AudioSystem::setCurrentImeUid(uid_t uid) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     int32_t uidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(uid));
     return statusTFromBinderStatus(aps->setCurrentImeUid(uidAidl));
@@ -2169,7 +2288,7 @@
 
 bool AudioSystem::isHapticPlaybackSupported() {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return false;
+    if (aps == nullptr) return false;
 
     auto result = [&]() -> ConversionResult<bool> {
         bool retVal;
@@ -2182,7 +2301,7 @@
 
 bool AudioSystem::isUltrasoundSupported() {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return false;
+    if (aps == nullptr) return false;
 
     auto result = [&]() -> ConversionResult<bool> {
         bool retVal;
@@ -2200,7 +2319,7 @@
     }
 
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     std::vector<AudioFormatDescription> formatsAidl;
     AudioDeviceDescription deviceAidl = VALUE_OR_RETURN_STATUS(
@@ -2216,7 +2335,7 @@
 
 status_t AudioSystem::listAudioProductStrategies(AudioProductStrategyVector& strategies) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     std::vector<media::AudioProductStrategy> strategiesAidl;
     RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
@@ -2278,7 +2397,7 @@
                                                             product_strategy_t& productStrategy,
                                                             bool fallbackOnDefault) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     media::audio::common::AudioAttributes aaAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_attributes_t_AudioAttributes(aa));
@@ -2294,7 +2413,7 @@
 
 status_t AudioSystem::listAudioVolumeGroups(AudioVolumeGroupVector& groups) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     std::vector<media::AudioVolumeGroup> groupsAidl;
     RETURN_STATUS_IF_ERROR(
@@ -2308,7 +2427,7 @@
                                                         volume_group_t& volumeGroup,
                                                         bool fallbackOnDefault) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     media::audio::common::AudioAttributes aaAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_attributes_t_AudioAttributes(aa));
@@ -2321,13 +2440,13 @@
 
 status_t AudioSystem::setRttEnabled(bool enabled) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return PERMISSION_DENIED;
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
     return statusTFromBinderStatus(aps->setRttEnabled(enabled));
 }
 
 bool AudioSystem::isCallScreenModeSupported() {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) return false;
+    if (aps == nullptr) return false;
 
     auto result = [&]() -> ConversionResult<bool> {
         bool retAidl;
@@ -2342,9 +2461,7 @@
                                                 device_role_t role,
                                                 const AudioDeviceTypeAddrVector& devices) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) {
-        return PERMISSION_DENIED;
-    }
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     int32_t strategyAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_product_strategy_t_int32_t(strategy));
     media::DeviceRole roleAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_device_role_t_DeviceRole(role));
@@ -2359,9 +2476,7 @@
                                                    device_role_t role,
                                                    const AudioDeviceTypeAddrVector& devices) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) {
-        return PERMISSION_DENIED;
-    }
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     int32_t strategyAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_product_strategy_t_int32_t(strategy));
     media::DeviceRole roleAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_device_role_t_DeviceRole(role));
@@ -2375,9 +2490,8 @@
 status_t
 AudioSystem::clearDevicesRoleForStrategy(product_strategy_t strategy, device_role_t role) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) {
-        return PERMISSION_DENIED;
-    }
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
+
     int32_t strategyAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_product_strategy_t_int32_t(strategy));
     media::DeviceRole roleAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_device_role_t_DeviceRole(role));
     return statusTFromBinderStatus(
@@ -2388,9 +2502,8 @@
                                                    device_role_t role,
                                                    AudioDeviceTypeAddrVector& devices) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) {
-        return PERMISSION_DENIED;
-    }
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
+
     int32_t strategyAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_product_strategy_t_int32_t(strategy));
     media::DeviceRole roleAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_device_role_t_DeviceRole(role));
     std::vector<AudioDevice> devicesAidl;
@@ -2406,9 +2519,7 @@
                                                      device_role_t role,
                                                      const AudioDeviceTypeAddrVector& devices) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) {
-        return PERMISSION_DENIED;
-    }
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     AudioSource audioSourceAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_source_t_AudioSource(audioSource));
@@ -2424,9 +2535,8 @@
                                                      device_role_t role,
                                                      const AudioDeviceTypeAddrVector& devices) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) {
-        return PERMISSION_DENIED;
-    }
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
+
     AudioSource audioSourceAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_source_t_AudioSource(audioSource));
     media::DeviceRole roleAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_device_role_t_DeviceRole(role));
@@ -2440,9 +2550,8 @@
 status_t AudioSystem::removeDevicesRoleForCapturePreset(
         audio_source_t audioSource, device_role_t role, const AudioDeviceTypeAddrVector& devices) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) {
-        return PERMISSION_DENIED;
-    }
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
+
     AudioSource audioSourceAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_source_t_AudioSource(audioSource));
     media::DeviceRole roleAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_device_role_t_DeviceRole(role));
@@ -2456,9 +2565,8 @@
 status_t AudioSystem::clearDevicesRoleForCapturePreset(audio_source_t audioSource,
                                                        device_role_t role) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) {
-        return PERMISSION_DENIED;
-    }
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
+
     AudioSource audioSourceAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_source_t_AudioSource(audioSource));
     media::DeviceRole roleAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_device_role_t_DeviceRole(role));
@@ -2470,9 +2578,7 @@
                                                         device_role_t role,
                                                         AudioDeviceTypeAddrVector& devices) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) {
-        return PERMISSION_DENIED;
-    }
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
     AudioSource audioSourceAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_source_t_AudioSource(audioSource));
     media::DeviceRole roleAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_device_role_t_DeviceRole(role));
@@ -2491,9 +2597,7 @@
     if (spatializer == nullptr) {
         return BAD_VALUE;
     }
-    if (aps == 0) {
-        return PERMISSION_DENIED;
-    }
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
     media::GetSpatializerResponse response;
     RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
             aps->getSpatializer(callback, &response)));
@@ -2510,9 +2614,7 @@
     if (canBeSpatialized == nullptr) {
         return BAD_VALUE;
     }
-    if (aps == 0) {
-        return PERMISSION_DENIED;
-    }
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
     audio_attributes_t attributes = attr != nullptr ? *attr : AUDIO_ATTRIBUTES_INITIALIZER;
     audio_config_t configuration = config != nullptr ? *config : AUDIO_CONFIG_INITIALIZER;
 
@@ -2531,9 +2633,7 @@
 status_t AudioSystem::getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback,
                                             sp<media::ISoundDose>* soundDose) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == nullptr) {
-        return PERMISSION_DENIED;
-    }
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     if (soundDose == nullptr) {
         return BAD_VALUE;
     }
@@ -2550,9 +2650,7 @@
     }
 
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) {
-        return PERMISSION_DENIED;
-    }
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_attributes_t_AudioAttributes(*attr));
@@ -2574,9 +2672,7 @@
     }
 
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) {
-        return PERMISSION_DENIED;
-    }
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_attributes_t_AudioAttributes(*attr));
@@ -2593,52 +2689,40 @@
 status_t AudioSystem::setRequestedLatencyMode(
             audio_io_handle_t output, audio_latency_mode_t mode) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == nullptr) {
-        return PERMISSION_DENIED;
-    }
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     return af->setRequestedLatencyMode(output, mode);
 }
 
 status_t AudioSystem::getSupportedLatencyModes(audio_io_handle_t output,
         std::vector<audio_latency_mode_t>* modes) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == nullptr) {
-        return PERMISSION_DENIED;
-    }
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     return af->getSupportedLatencyModes(output, modes);
 }
 
 status_t AudioSystem::setBluetoothVariableLatencyEnabled(bool enabled) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == nullptr) {
-        return PERMISSION_DENIED;
-    }
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     return af->setBluetoothVariableLatencyEnabled(enabled);
 }
 
 status_t AudioSystem::isBluetoothVariableLatencyEnabled(
         bool *enabled) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == nullptr) {
-        return PERMISSION_DENIED;
-    }
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     return af->isBluetoothVariableLatencyEnabled(enabled);
 }
 
 status_t AudioSystem::supportsBluetoothVariableLatency(
         bool *support) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == nullptr) {
-        return PERMISSION_DENIED;
-    }
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     return af->supportsBluetoothVariableLatency(support);
 }
 
 status_t AudioSystem::getAudioPolicyConfig(media::AudioPolicyConfig *config) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == nullptr) {
-        return PERMISSION_DENIED;
-    }
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     return af->getAudioPolicyConfig(config);
 }
 
@@ -2685,9 +2769,7 @@
     LOG_ALWAYS_FATAL_IF(listener == nullptr);
 
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == 0) {
-        return PERMISSION_DENIED;
-    }
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     std::lock_guard _l(AudioSystem::gSoundTriggerMutex);
     gSoundTriggerCaptureStateListener = new CaptureStateListenerImpl(aps, listener);
@@ -2699,43 +2781,33 @@
 status_t AudioSystem::setVibratorInfos(
         const std::vector<media::AudioVibratorInfo>& vibratorInfos) {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == nullptr) {
-        return PERMISSION_DENIED;
-    }
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     return af->setVibratorInfos(vibratorInfos);
 }
 
 status_t AudioSystem::getMmapPolicyInfos(
         AudioMMapPolicyType policyType, std::vector<AudioMMapPolicyInfo> *policyInfos) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == nullptr) {
-        return PERMISSION_DENIED;
-    }
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
     return statusTFromBinderStatus(aps->getMmapPolicyInfos(policyType, policyInfos));
 }
 
 int32_t AudioSystem::getAAudioMixerBurstCount() {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == nullptr) {
-        return PERMISSION_DENIED;
-    }
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     return af->getAAudioMixerBurstCount();
 }
 
 int32_t AudioSystem::getAAudioHardwareBurstMinUsec() {
     const sp<IAudioFlinger> af = get_audio_flinger();
-    if (af == nullptr) {
-        return PERMISSION_DENIED;
-    }
+    if (af == nullptr) return AudioFlingerServiceTraits::getError();
     return af->getAAudioHardwareBurstMinUsec();
 }
 
 status_t AudioSystem::getSupportedMixerAttributes(
         audio_port_handle_t portId, std::vector<audio_mixer_attributes_t> *mixerAttrs) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == nullptr) {
-        return PERMISSION_DENIED;
-    }
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     int32_t portIdAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_port_handle_t_int32_t(portId));
     std::vector<media::AudioMixerAttributesInternal> _aidlReturn;
@@ -2753,9 +2825,7 @@
                                                   uid_t uid,
                                                   const audio_mixer_attributes_t *mixerAttr) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == nullptr) {
-        return PERMISSION_DENIED;
-    }
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_attributes_t_AudioAttributes(*attr));
@@ -2773,9 +2843,7 @@
         audio_port_handle_t portId,
         std::optional<audio_mixer_attributes_t> *mixerAttr) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == nullptr) {
-        return PERMISSION_DENIED;
-    }
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_attributes_t_AudioAttributes(*attr));
@@ -2796,9 +2864,7 @@
                                                     audio_port_handle_t portId,
                                                     uid_t uid) {
     const sp<IAudioPolicyService> aps = get_audio_policy_service();
-    if (aps == nullptr) {
-        return PERMISSION_DENIED;
-    }
+    if (aps == nullptr) return AudioPolicyServiceTraits::getError();
 
     media::audio::common::AudioAttributes attrAidl = VALUE_OR_RETURN_STATUS(
             legacy2aidl_audio_attributes_t_AudioAttributes(*attr));
@@ -2964,19 +3030,14 @@
     return Status::ok();
 }
 
-void AudioSystem::AudioPolicyServiceClient::binderDied(const wp<IBinder>& who __unused) {
-    {
-        std::lock_guard _l(mMutex);
-        for (const auto& callback : mAudioPortCallbacks) {
-            callback->onServiceDied();
-        }
-        for (const auto& callback : mAudioVolumeGroupCallbacks) {
-            callback->onServiceDied();
-        }
+void AudioSystem::AudioPolicyServiceClient::onServiceDied() {
+    std::lock_guard _l(mMutex);
+    for (const auto& callback : mAudioPortCallbacks) {
+        callback->onServiceDied();
     }
-    AudioSystem::clearAudioPolicyService();
-
-    ALOGW("AudioPolicyService server died!");
+    for (const auto& callback : mAudioVolumeGroupCallbacks) {
+        callback->onServiceDied();
+    }
 }
 
 ConversionResult<record_client_info_t>