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

Commit 01635943 authored by Eric Laurent's avatar Eric Laurent
Browse files

Tentative fix for issue 3362362.

The problem is likely that one method is called on the AudioPolicyManagerBase
instance while it is still being constructed by AudioPolicyService.

To avoid this, the AudioPolicyService mutex is held by the constructor until the
platform specific AudioPolicyManager is constructed and the member
mpPolicyManager initialized.

Also added an initCheck() method to AudioPolicyInterface to verify successful
initialization of AudioPolicyManager.

A similar change is done in AudioFlinger constructor.
Also added some missing protections in AudioFlinger methods where the
playback thread list is parsed.

Change-Id: I006b244ec057e1bb0aa5ebe426ef006e3b171056
parent 6cfc7a0a
Loading
Loading
Loading
Loading
+18 −10
Original line number Diff line number Diff line
@@ -131,18 +131,21 @@ AudioFlinger::AudioFlinger()
    : BnAudioFlinger(),
        mAudioHardware(0), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1)
{
    Mutex::Autolock _l(mLock);

    mHardwareStatus = AUDIO_HW_IDLE;

    mAudioHardware = AudioHardwareInterface::create();

    mHardwareStatus = AUDIO_HW_INIT;
    if (mAudioHardware->initCheck() == NO_ERROR) {
        // open 16-bit output stream for s/w mixer
        AutoMutex lock(mHardwareLock);
        mMode = AudioSystem::MODE_NORMAL;
        setMode(mMode);

        setMasterVolume(1.0f);
        setMasterMute(false);
        mHardwareStatus = AUDIO_HW_SET_MODE;
        mAudioHardware->setMode(mMode);
        mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
        mAudioHardware->setMasterVolume(1.0f);
        mHardwareStatus = AUDIO_HW_IDLE;
    } else {
        LOGE("Couldn't even initialize the stubbed audio hardware!");
    }
@@ -440,13 +443,16 @@ status_t AudioFlinger::setMasterVolume(float value)
    }

    // when hw supports master volume, don't scale in sw mixer
    { // scope for the lock
        AutoMutex lock(mHardwareLock);
        mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
        if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
            value = 1.0f;
        }
        mHardwareStatus = AUDIO_HW_IDLE;
    }

    Mutex::Autolock _l(mLock);
    mMasterVolume = value;
    for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
       mPlaybackThreads.valueAt(i)->setMasterVolume(value);
@@ -517,6 +523,7 @@ status_t AudioFlinger::setMasterMute(bool muted)
        return PERMISSION_DENIED;
    }

    Mutex::Autolock _l(mLock);
    mMasterMute = muted;
    for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
       mPlaybackThreads.valueAt(i)->setMasterMute(muted);
@@ -579,6 +586,7 @@ status_t AudioFlinger::setStreamMute(int stream, bool muted)
        return BAD_VALUE;
    }

    AutoMutex lock(mLock);
    mStreamTypes[stream].mute = muted;
    for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
       mPlaybackThreads.valueAt(i)->setStreamMute(stream, muted);
+25 −18
Original line number Diff line number Diff line
@@ -1052,6 +1052,7 @@ AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clien

    updateDeviceForStrategy();
#ifdef AUDIO_POLICY_TEST
    if (mHardwareOutput != 0) {
        AudioParameter outputCmd = AudioParameter();
        outputCmd.addInt(String8("set_id"), 0);
        mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString());
@@ -1071,6 +1072,7 @@ AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clien
        char buffer[SIZE];
        snprintf(buffer, SIZE, "AudioPolicyManagerTest");
        run(buffer, ANDROID_PRIORITY_AUDIO);
    }
#endif //AUDIO_POLICY_TEST
}

@@ -1091,6 +1093,11 @@ AudioPolicyManagerBase::~AudioPolicyManagerBase()
   mInputs.clear();
}

status_t AudioPolicyManagerBase::initCheck()
{
    return (mHardwareOutput == 0) ? NO_INIT : NO_ERROR;
}

#ifdef AUDIO_POLICY_TEST
bool AudioPolicyManagerBase::threadLoop()
{
+14 −3
Original line number Diff line number Diff line
@@ -68,6 +68,8 @@ AudioPolicyService::AudioPolicyService()
{
    char value[PROPERTY_VALUE_MAX];

    Mutex::Autolock _l(mLock);

    // start tone playback thread
    mTonePlaybackThread = new AudioCommandThread(String8(""));
    // start audio commands thread
@@ -88,10 +90,19 @@ AudioPolicyService::AudioPolicyService()
    }
#endif

    if ((mpPolicyManager != NULL) && (mpPolicyManager->initCheck() != NO_ERROR)) {
        delete mpPolicyManager;
        mpPolicyManager = NULL;
    }

    if (mpPolicyManager == NULL) {
        LOGE("Could not create AudioPolicyManager");
    } else {
        // load properties
        property_get("ro.camera.sound.forced", value, "0");
        mpPolicyManager->setSystemProperty("ro.camera.sound.forced", value);
    }
}

AudioPolicyService::~AudioPolicyService()
{