Bug 872907 - Patch 5: Handle A2DP status changed in AudioManager, r=echou, r=mwu

This commit is contained in:
Gina Yeh 2013-06-08 23:26:28 +08:00
parent f200d479f6
commit fe63c7c6f5
5 changed files with 74 additions and 31 deletions

View File

@ -8,6 +8,7 @@
#include "BluetoothA2dpManager.h"
#include "BluetoothCommon.h"
#include "BluetoothService.h"
#include "BluetoothSocket.h"
#include "BluetoothUtils.h"
@ -18,7 +19,6 @@
#include "nsIAudioManager.h"
#include "nsIObserverService.h"
#define BLUETOOTH_A2DP_STATUS_CHANGED "bluetooth-a2dp-status-changed"
using namespace mozilla;
USING_BLUETOOTH_NAMESPACE

View File

@ -40,6 +40,7 @@ public:
virtual void OnGetServiceChannel(const nsAString& aDeviceAddress,
const nsAString& aServiceUuid,
int aChannel) MOZ_OVERRIDE;
virtual void OnUpdateSdpRecords(const nsAString& aDeviceAddress) MOZ_OVERRIDE;
virtual void GetAddress(nsAString& aDeviceAddress) MOZ_OVERRIDE;
private:

View File

@ -51,6 +51,13 @@ extern bool gBluetoothDebugFlag;
#define KEY_MANAGER "/B2G/bluetooth/manager"
#define KEY_ADAPTER "/B2G/bluetooth/adapter"
/**
* When connection status of Bluetooth profiles change, we'll notify observers
* of following topics.
*/
#define BLUETOOTH_SCO_STATUS_CHANGED "bluetooth-sco-status-changed"
#define BLUETOOTH_A2DP_STATUS_CHANGED "bluetooth-a2dp-status-changed"
// Bluetooth address format: xx:xx:xx:xx:xx:xx (or xx_xx_xx_xx_xx_xx)
#define BLUETOOTH_ADDRESS_LENGTH 17
#define BLUETOOTH_ADDRESS_NONE "00:00:00:00:00:00"

View File

@ -31,7 +31,6 @@
#define MOZSETTINGS_CHANGED_ID "mozsettings-changed"
#define MOBILE_CONNECTION_ICCINFO_CHANGED "mobile-connection-iccinfo-changed"
#define MOBILE_CONNECTION_VOICE_CHANGED "mobile-connection-voice-changed"
#define BLUETOOTH_SCO_STATUS_CHANGED "bluetooth-sco-status-changed"
/**
* BRSF bitmask of AG supported features. See 4.34.1 "Bluetooth Defined AT

View File

@ -15,16 +15,23 @@
#include <android/log.h>
#include "mozilla/Hal.h"
#include "AudioManager.h"
#include "nsIObserverService.h"
#include "mozilla/Services.h"
#include "AudioChannelService.h"
#include "AudioManager.h"
#include "nsIObserverService.h"
#include "nsPrintfCString.h"
#include "mozilla/Hal.h"
#include "mozilla/Services.h"
#include "BluetoothCommon.h"
#include "BluetoothProfileManagerBase.h"
using namespace mozilla::dom::gonk;
using namespace android;
using namespace mozilla::hal;
using namespace mozilla;
using namespace mozilla::dom::bluetooth;
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "AudioManager" , ## args)
@ -33,7 +40,6 @@ using namespace mozilla;
#define HEADPHONES_STATUS_HEADPHONE NS_LITERAL_STRING("headphone").get()
#define HEADPHONES_STATUS_OFF NS_LITERAL_STRING("off").get()
#define HEADPHONES_STATUS_UNKNOWN NS_LITERAL_STRING("unknown").get()
#define BLUETOOTH_SCO_STATUS_CHANGED "bluetooth-sco-status-changed"
static void BinderDeadCallback(status_t aErr);
static void InternalSetAudioRoutes(SwitchState aState);
@ -53,7 +59,7 @@ static int sMaxStreamVolumeTbl[AUDIO_STREAM_CNT] = {
};
// A bitwise variable for recording what kind of headset is attached.
static int sHeadsetState;
static int kBtSampleRate = 8000;
static const int kBtSampleRate = 8000;
class RecoverTask : public nsRunnable
{
@ -188,32 +194,58 @@ AudioManager::Observe(nsISupports* aSubject,
const char* aTopic,
const PRUnichar* aData)
{
if (!strcmp(aTopic, BLUETOOTH_SCO_STATUS_CHANGED)) {
if (NS_strlen(aData) > 0) {
String8 cmd;
cmd.appendFormat("bt_samplerate=%d", kBtSampleRate);
AudioSystem::setParameters(0, cmd);
NS_ConvertUTF16toUTF8 address(aData);
AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address.get());
AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE, address.get());
SetForceForUse(nsIAudioManager::USE_COMMUNICATION, nsIAudioManager::FORCE_BT_SCO);
} else {
AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, "");
AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, "");
// only force to none if the current force setting is bt_sco
int32_t force;
GetForceForUse(nsIAudioManager::USE_COMMUNICATION, &force);
if (force == nsIAudioManager::FORCE_BT_SCO)
SetForceForUse(nsIAudioManager::USE_COMMUNICATION, nsIAudioManager::FORCE_NONE);
if ((strcmp(aTopic, BLUETOOTH_SCO_STATUS_CHANGED) == 0) ||
(strcmp(aTopic, BLUETOOTH_A2DP_STATUS_CHANGED) == 0)) {
nsresult rv;
int status = NS_ConvertUTF16toUTF8(aData).ToInteger(&rv);
if (NS_FAILED(rv) || status > 1 || status < 0) {
NS_WARNING(nsPrintfCString("Wrong data value of %s", aTopic).get());
return NS_ERROR_FAILURE;
}
return NS_OK;
nsAutoString tmp_address;
BluetoothProfileManagerBase* profile =
static_cast<BluetoothProfileManagerBase*>(aSubject);
profile->GetAddress(tmp_address);
nsAutoCString address = NS_ConvertUTF16toUTF8(tmp_address);
audio_policy_dev_state_t audioState = status ?
AUDIO_POLICY_DEVICE_STATE_AVAILABLE :
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
if (!strcmp(aTopic, BLUETOOTH_SCO_STATUS_CHANGED)) {
AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET,
audioState, address.get());
AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
audioState, address.get());
if (audioState == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
String8 cmd;
cmd.appendFormat("bt_samplerate=%d", kBtSampleRate);
AudioSystem::setParameters(0, cmd);
SetForceForUse(nsIAudioManager::USE_COMMUNICATION, nsIAudioManager::FORCE_BT_SCO);
} else {
// only force to none if the current force setting is bt_sco
int32_t force;
GetForceForUse(nsIAudioManager::USE_COMMUNICATION, &force);
if (force == nsIAudioManager::FORCE_BT_SCO)
SetForceForUse(nsIAudioManager::USE_COMMUNICATION, nsIAudioManager::FORCE_NONE);
}
} else if (!strcmp(aTopic, BLUETOOTH_A2DP_STATUS_CHANGED)) {
AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP,
audioState, address.get());
if (audioState == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
String8 cmd("bluetooth_enabled=true");
AudioSystem::setParameters(0, cmd);
cmd.setTo("A2dpSuspended=false");
AudioSystem::setParameters(0, cmd);
}
}
} else {
NS_WARNING("Unexpected topic in AudioManager");
return NS_ERROR_FAILURE;
}
return NS_ERROR_UNEXPECTED;
return NS_OK;
}
static void
@ -253,6 +285,8 @@ AudioManager::AudioManager() : mPhoneState(PHONE_STATE_CURRENT),
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (NS_FAILED(obs->AddObserver(this, BLUETOOTH_SCO_STATUS_CHANGED, false))) {
NS_WARNING("Failed to add bluetooth-sco-status-changed oberver!");
} else if (NS_FAILED(obs->AddObserver(this, BLUETOOTH_A2DP_STATUS_CHANGED, false))) {
NS_WARNING("Failed to add bluetooth-a2dp-status-changed oberver!");
}
for (int loop = 0; loop < AUDIO_STREAM_CNT; loop++) {
@ -281,6 +315,8 @@ AudioManager::~AudioManager() {
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (NS_FAILED(obs->RemoveObserver(this, BLUETOOTH_SCO_STATUS_CHANGED))) {
NS_WARNING("Failed to remove bluetooth-sco-status-changed oberver!");
} else if (NS_FAILED(obs->RemoveObserver(this, BLUETOOTH_A2DP_STATUS_CHANGED))) {
NS_WARNING("Failed to remove bluetooth-a2dp-status-changed oberver!");
}
}