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>
