Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e63196d9 authored by Andy Hung's avatar Andy Hung
Browse files

AudioPolicyService: Make device effect init synchronous

This initialization is done prior to exposing the AF and APS
to ServiceManager to ensure consistent state and avoid
nondeterministic bugs.

AudioPolicyService::onAudioSystemReady() is called
during audioserver initialization when both AF and APS
are available to create internal audio client objects.

Test: atest CtsMediaAudioTestCases
Bug: 319515492
Merged-In: Ie6e0817c830da51e9b722b17ebd54f005b6a6055
Change-Id: Ie6e0817c830da51e9b722b17ebd54f005b6a6055
parent 29479777
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -169,6 +169,11 @@ int main(int argc __unused, char **argv)
                "%s: AudioSystem already has an AudioFlinger instance!", __func__);
        const auto aps = sp<AudioPolicyService>::make();
        ALOGD("%s: AudioPolicy created", __func__);
        ALOGW_IF(AudioSystem::setLocalAudioPolicyService(aps) != OK,
                 "%s: AudioSystem already has an AudioPolicyService instance!", __func__);

        // Start initialization of internally managed audio objects such as Device Effects.
        aps->onAudioSystemReady();

        // Add AudioFlinger and AudioPolicy to ServiceManager.
        sp<IServiceManager> sm = defaultServiceManager();
+0 −5
Original line number Diff line number Diff line
@@ -61,11 +61,6 @@ AudioPolicyEffects::AudioPolicyEffects(const sp<EffectsFactoryHalInterface>& eff
    }
}

void AudioPolicyEffects::setDefaultDeviceEffects() {
    mDefaultDeviceEffectFuture = std::async(
                std::launch::async, &AudioPolicyEffects::initDefaultDeviceEffects, this);
}

status_t AudioPolicyEffects::addInputEffects(audio_io_handle_t input,
                             audio_source_t inputSource,
                             audio_session_t audioSession)
+2 −21
Original line number Diff line number Diff line
@@ -116,10 +116,8 @@ public:
    // Remove the default stream effect from wherever it's attached.
    status_t removeStreamDefaultEffect(audio_unique_id_t id) EXCLUDES_AudioPolicyEffects_Mutex;

    // Called by AudioPolicyService::onFirstRef() to load device effects
    // on a separate worker thread.
    // TODO(b/319515492) move this initialization after AudioPolicyService::onFirstRef().
    void setDefaultDeviceEffects();
    // Initializes the Effects (AudioSystem must be ready as this creates audio client objects).
    void initDefaultDeviceEffects() EXCLUDES(mDeviceEffectsMutex) EXCLUDES_EffectHandle_Mutex;

private:

@@ -201,11 +199,6 @@ private:

    };

    // Called on an async thread because it creates AudioEffects
    // which register with AudioFlinger and AudioPolicy.
    // We must therefore exclude the EffectHandle_Mutex.
    void initDefaultDeviceEffects() EXCLUDES(mDeviceEffectsMutex) EXCLUDES_EffectHandle_Mutex;

    status_t loadAudioEffectConfig_ll(const sp<EffectsFactoryHalInterface>& effectsFactoryHal)
            REQUIRES(mMutex, mDeviceEffectsMutex);

@@ -281,18 +274,6 @@ private:
    std::mutex mDeviceEffectsMutex;
    std::map<std::string, std::unique_ptr<DeviceEffects>> mDeviceEffects
            GUARDED_BY(mDeviceEffectsMutex);

    /**
     * Device Effect initialization must be asynchronous: the audio_policy service parses and init
     * effect on first reference. AudioFlinger will handle effect creation and register these
     * effect on audio_policy service.
     *
     * The future is associated with the std::async launched thread - no need to lock as
     * it is only set once on init.  Due to the async nature, it is conceivable that
     * some device effects are not available immediately after AudioPolicyService::onFirstRef()
     * while the effects are being created.
     */
    std::future<void> mDefaultDeviceEffectFuture;
};

} // namespace android
+10 −3
Original line number Diff line number Diff line
@@ -312,9 +312,16 @@ void AudioPolicyService::onFirstRef()
        }
    }
    AudioSystem::audioPolicyReady();
    // AudioFlinger will handle effect creation and register these effects on audio_policy
    // service. Hence, audio_policy service must be ready.
    audioPolicyEffects->setDefaultDeviceEffects();
}

void AudioPolicyService::onAudioSystemReady() {
    sp<AudioPolicyEffects> audioPolicyEffects;
    {
        audio_utils::lock_guard _l(mMutex);

        audioPolicyEffects = mAudioPolicyEffects;
    }
    audioPolicyEffects->initDefaultDeviceEffects();
}

void AudioPolicyService::unloadAudioPolicyManager()
+3 −0
Original line number Diff line number Diff line
@@ -320,6 +320,9 @@ public:
    // RefBase
    virtual     void        onFirstRef();

    // Commence initialization when AudioSystem is ready.
    void onAudioSystemReady();

    //
    // Helpers for the struct audio_policy_service_ops implementation.
    // This is used by the audio policy manager for certain operations that