Bug 793950 - v2: Handle volume change in BluetoothHfpManager, r=qdot

This commit is contained in:
Gina Yeh 2012-09-25 18:18:38 +08:00
parent 26debe74af
commit fb28674744
2 changed files with 114 additions and 0 deletions

View File

@ -4,18 +4,25 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "base/basictypes.h"
#include "BluetoothHfpManager.h"
#include "BluetoothReplyRunnable.h"
#include "BluetoothService.h"
#include "BluetoothServiceUuid.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/Services.h"
#include "nsContentUtils.h"
#include "nsIObserverService.h"
#include "nsIRadioInterfaceLayer.h"
#include "nsVariant.h"
#include <unistd.h> /* usleep() */
#define MOZSETTINGS_CHANGED_ID "mozsettings-changed"
#define AUDIO_VOLUME_MASTER "audio.volume.master"
USING_BLUETOOTH_NAMESPACE
using namespace mozilla::ipc;
@ -25,6 +32,8 @@ static bool sStopSendingRingFlag = true;
static int kRingInterval = 3000000; //unit: us
NS_IMPL_ISUPPORTS1(BluetoothHfpManager, nsIObserver)
class SendRingIndicatorTask : public nsRunnable
{
public:
@ -52,6 +61,11 @@ BluetoothHfpManager::BluetoothHfpManager()
, mCurrentCallIndex(0)
, mCurrentCallState(nsIRadioInterfaceLayer::CALL_STATE_DISCONNECTED)
{
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
if (obs && NS_FAILED(obs->AddObserver(sInstance, MOZSETTINGS_CHANGED_ID, false))) {
NS_WARNING("Failed to add settings change observer!");
}
}
BluetoothHfpManager::~BluetoothHfpManager()
@ -71,6 +85,99 @@ BluetoothHfpManager::Get()
return sInstance;
}
nsresult
BluetoothHfpManager::HandleVolumeChanged(const nsAString& aData)
{
MOZ_ASSERT(NS_IsMainThread());
// The string that we're interested in will be a JSON string that looks like:
// {"key":"volumeup", "value":1.0}
// {"key":"volumedown", "value":0.2}
JSContext* cx = nsContentUtils::GetSafeJSContext();
if (!cx) {
return NS_OK;
}
JS::Value val;
if (!JS_ParseJSON(cx, aData.BeginReading(), aData.Length(), &val)) {
return JS_ReportPendingException(cx) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
if (!val.isObject()) {
return NS_OK;
}
JSObject& obj(val.toObject());
JS::Value key;
if (!JS_GetProperty(cx, &obj, "key", &key)) {
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return NS_ERROR_OUT_OF_MEMORY;
}
if (!key.isString()) {
return NS_OK;
}
JSBool match;
if (!JS_StringEqualsAscii(cx, key.toString(), AUDIO_VOLUME_MASTER, &match)) {
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return NS_ERROR_OUT_OF_MEMORY;
}
if (!match) {
return NS_OK;
}
JS::Value value;
if (!JS_GetProperty(cx, &obj, "value", &value)) {
MOZ_ASSERT(!JS_IsExceptionPending(cx));
return NS_ERROR_OUT_OF_MEMORY;
}
if (!value.isNumber()) {
return NS_ERROR_UNEXPECTED;
}
// AG volume range: [0.0, 1.0]
float volume = value.toNumber();
// HS volume range: [0, 15]
mCurrentVgs = ceil(volume * 15);
nsDiscriminatedUnion du;
du.mType = 0;
du.u.mInt8Value = mCurrentVgs;
nsCString vgs;
if (NS_FAILED(nsVariant::ConvertToACString(du, vgs))) {
NS_WARNING("Failed to convert volume to string");
return NS_ERROR_FAILURE;
}
nsAutoCString newVgs;
newVgs += "+VGS: ";
newVgs += vgs;
SendLine(newVgs.get());
return NS_OK;
}
nsresult
BluetoothHfpManager::Observe(nsISupports* aSubject,
const char* aTopic,
const PRUnichar* aData)
{
if (!strcmp(aTopic, MOZSETTINGS_CHANGED_ID)) {
return HandleVolumeChanged(nsDependentString(aData));
} else {
MOZ_ASSERT(false, "BluetoothHfpManager got unexpected topic!");
}
return NS_ERROR_UNEXPECTED;
}
// Virtual function of class SocketConsumer
void
BluetoothHfpManager::ReceiveSocketData(UnixSocketRawData* aMessage)

View File

@ -9,14 +9,19 @@
#include "BluetoothCommon.h"
#include "mozilla/ipc/UnixSocket.h"
#include "nsIObserver.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothReplyRunnable;
class BluetoothHfpManager : public mozilla::ipc::UnixSocketConsumer
, public nsIObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
~BluetoothHfpManager();
static BluetoothHfpManager* Get();
@ -32,6 +37,8 @@ public:
private:
BluetoothHfpManager();
nsresult HandleVolumeChanged(const nsAString& aData);
int mCurrentVgs;
int mCurrentCallIndex;
int mCurrentCallState;