Merge "Tentative fix for issue 3362362." into honeycomb
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 51b5947..16c042d 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -131,18 +131,21 @@
     : 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 @@
     }
 
     // when hw supports master volume, don't scale in sw mixer
-    AutoMutex lock(mHardwareLock);
-    mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
-    if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
-        value = 1.0f;
+    { // 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;
     }
-    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 @@
         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 @@
         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);
diff --git a/services/audioflinger/AudioPolicyManagerBase.cpp b/services/audioflinger/AudioPolicyManagerBase.cpp
index eeca7ab..e4086c4 100644
--- a/services/audioflinger/AudioPolicyManagerBase.cpp
+++ b/services/audioflinger/AudioPolicyManagerBase.cpp
@@ -1052,25 +1052,27 @@
 
     updateDeviceForStrategy();
 #ifdef AUDIO_POLICY_TEST
-    AudioParameter outputCmd = AudioParameter();
-    outputCmd.addInt(String8("set_id"), 0);
-    mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString());
+    if (mHardwareOutput != 0) {
+        AudioParameter outputCmd = AudioParameter();
+        outputCmd.addInt(String8("set_id"), 0);
+        mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString());
 
-    mTestDevice = AudioSystem::DEVICE_OUT_SPEAKER;
-    mTestSamplingRate = 44100;
-    mTestFormat = AudioSystem::PCM_16_BIT;
-    mTestChannels =  AudioSystem::CHANNEL_OUT_STEREO;
-    mTestLatencyMs = 0;
-    mCurOutput = 0;
-    mDirectOutput = false;
-    for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
-        mTestOutputs[i] = 0;
+        mTestDevice = AudioSystem::DEVICE_OUT_SPEAKER;
+        mTestSamplingRate = 44100;
+        mTestFormat = AudioSystem::PCM_16_BIT;
+        mTestChannels =  AudioSystem::CHANNEL_OUT_STEREO;
+        mTestLatencyMs = 0;
+        mCurOutput = 0;
+        mDirectOutput = false;
+        for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
+            mTestOutputs[i] = 0;
+        }
+
+        const size_t SIZE = 256;
+        char buffer[SIZE];
+        snprintf(buffer, SIZE, "AudioPolicyManagerTest");
+        run(buffer, ANDROID_PRIORITY_AUDIO);
     }
-
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    snprintf(buffer, SIZE, "AudioPolicyManagerTest");
-    run(buffer, ANDROID_PRIORITY_AUDIO);
 #endif //AUDIO_POLICY_TEST
 }
 
@@ -1091,6 +1093,11 @@
    mInputs.clear();
 }
 
+status_t AudioPolicyManagerBase::initCheck()
+{
+    return (mHardwareOutput == 0) ? NO_INIT : NO_ERROR;
+}
+
 #ifdef AUDIO_POLICY_TEST
 bool AudioPolicyManagerBase::threadLoop()
 {
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index f24e08e..46a01ad 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -68,6 +68,8 @@
 {
     char value[PROPERTY_VALUE_MAX];
 
+    Mutex::Autolock _l(mLock);
+
     // start tone playback thread
     mTonePlaybackThread = new AudioCommandThread(String8(""));
     // start audio commands thread
@@ -88,9 +90,18 @@
     }
 #endif
 
-    // load properties
-    property_get("ro.camera.sound.forced", value, "0");
-    mpPolicyManager->setSystemProperty("ro.camera.sound.forced", value);
+    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()