From d974bfb77802fce40ba03af08a03ccac95dd63c5 Mon Sep 17 00:00:00 2001 From: Steven Lee Date: Wed, 19 Sep 2012 13:51:35 -0400 Subject: [PATCH] Bug 749053 - FM radio support: AudioManager implementation. r=jlebar,mwu --- dom/system/gonk/AudioManager.cpp | 49 +++++++++++++++++++++ dom/system/gonk/AudioManager.h | 1 + dom/system/gonk/nsIAudioManager.idl | 5 +++ media/libsydneyaudio/src/gonk/AudioSystem.h | 4 ++ 4 files changed, 59 insertions(+) diff --git a/dom/system/gonk/AudioManager.cpp b/dom/system/gonk/AudioManager.cpp index 29d8006e0b72..179a1543aa03 100644 --- a/dom/system/gonk/AudioManager.cpp +++ b/dom/system/gonk/AudioManager.cpp @@ -33,6 +33,19 @@ using namespace mozilla; #define HEADPHONES_STATUS_OFF NS_LITERAL_STRING("off").get() #define HEADPHONES_STATUS_UNKNOWN NS_LITERAL_STRING("unknown").get() +static bool +IsFmRadioAudioOn() +{ + if (static_cast< + audio_policy_dev_state_t (*) (audio_devices_t, const char *) + >(AudioSystem::getDeviceConnectionState)) { + return AudioSystem::getDeviceConnectionState(AUDIO_DEVICE_OUT_FM, "") == + AUDIO_POLICY_DEVICE_STATE_AVAILABLE ? true : false; + } else { + return false; + } +} + NS_IMPL_ISUPPORTS1(AudioManager, nsIAudioManager) static AudioSystem::audio_devices @@ -133,6 +146,11 @@ AudioManager::SetMasterVolume(float aMasterVolume) if (AudioSystem::setVoiceVolume(aMasterVolume)) { return NS_ERROR_FAILURE; } + + if (IsFmRadioAudioOn() && AudioSystem::setFmVolume(aMasterVolume)) { + return NS_ERROR_FAILURE; + } + return NS_OK; } @@ -234,5 +252,36 @@ AudioManager::SetAudioRoute(int aRoutes) { GetRoutingMode(aRoutes) == AudioSystem::DEVICE_OUT_WIRED_HEADSET ? AUDIO_POLICY_DEVICE_STATE_AVAILABLE : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, ""); + + // The audio volume is not consistent when we plug and unplug the headset. + // Set the fm volume again here. + if (IsFmRadioAudioOn()) { + float masterVolume; + AudioSystem::getMasterVolume(&masterVolume); + AudioSystem::setFmVolume(masterVolume); + } + } +} + +NS_IMETHODIMP +AudioManager::GetFmRadioAudioEnabled(bool *aFmRadioAudioEnabled) +{ + *aFmRadioAudioEnabled = IsFmRadioAudioOn(); + return NS_OK; +} + +NS_IMETHODIMP +AudioManager::SetFmRadioAudioEnabled(bool aFmRadioAudioEnabled) +{ + if (static_cast< + status_t (*) (AudioSystem::audio_devices, AudioSystem::device_connection_state, const char *) + >(AudioSystem::setDeviceConnectionState)) { + AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_FM, + aFmRadioAudioEnabled ? AUDIO_POLICY_DEVICE_STATE_AVAILABLE : + AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, ""); + InternalSetAudioRoutes(GetCurrentSwitchState(SWITCH_HEADPHONES)); + return NS_OK; + } else { + return NS_ERROR_NOT_IMPLEMENTED; } } diff --git a/dom/system/gonk/AudioManager.h b/dom/system/gonk/AudioManager.h index 076fbf2e68bb..b89237f9c642 100644 --- a/dom/system/gonk/AudioManager.h +++ b/dom/system/gonk/AudioManager.h @@ -45,6 +45,7 @@ public: ~AudioManager(); static void SetAudioRoute(int aRoutes); + protected: int32_t mPhoneState; diff --git a/dom/system/gonk/nsIAudioManager.idl b/dom/system/gonk/nsIAudioManager.idl index 7d00c3682a76..114edc833130 100644 --- a/dom/system/gonk/nsIAudioManager.idl +++ b/dom/system/gonk/nsIAudioManager.idl @@ -22,6 +22,11 @@ interface nsIAudioManager : nsISupports */ attribute boolean masterMuted; + /** + * Are we playing audio from the FM radio? + */ + attribute boolean fmRadioAudioEnabled; + /** * Set the phone's audio mode. */ diff --git a/media/libsydneyaudio/src/gonk/AudioSystem.h b/media/libsydneyaudio/src/gonk/AudioSystem.h index 7899149eb921..c0575dff5f28 100644 --- a/media/libsydneyaudio/src/gonk/AudioSystem.h +++ b/media/libsydneyaudio/src/gonk/AudioSystem.h @@ -658,6 +658,8 @@ public: uint32_t channels = CHANNEL_OUT_STEREO, output_flags flags = OUTPUT_FLAG_INDIRECT); static status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state, const char *device_address); + static status_t setFmVolume(float volume); + static audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device, const char *device_address); #else static status_t setForceUse(force_use usage, forced_config config) __attribute__((weak)); static forced_config getForceUse(force_use usage) __attribute__((weak)); @@ -675,6 +677,8 @@ public: uint32_t channels = AUDIO_CHANNEL_OUT_STEREO, audio_policy_output_flags_t flags = AUDIO_POLICY_OUTPUT_FLAG_INDIRECT) __attribute__((weak)); static status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state, const char *device_address) __attribute__((weak)); + static status_t setFmVolume(float volume) __attribute__((weak)); + static audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device, const char *device_address) __attribute__((weak)); #endif static status_t startOutput(audio_io_handle_t output,