diff --git a/CLOBBER b/CLOBBER
index d4cdfaff33de..37b2285a1c32 100644
--- a/CLOBBER
+++ b/CLOBBER
@@ -22,4 +22,9 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
-Merge day clobber
\ No newline at end of file
+Bug 1105308 - Cleanup BluetoothUtils.{cpp,h}
+
+This patch set moves some files around and requires a rebuild
+of the build system's dependency information.
+
+Merge day clobber
diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index 3149c3038f12..ab9b5ebce8f6 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index ad8196404bb1..fa56509b363c 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
-
+
@@ -97,7 +97,7 @@
-
+
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 12d14140982b..815ac732a393 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index 966506b445ef..58ee7a860bdd 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index ad8196404bb1..fa56509b363c 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
-
+
@@ -97,7 +97,7 @@
-
+
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index 794a4ac6f703..4e7975e007a2 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index af9ca23883e1..a0ef726996c2 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 802938f5e75f..f143f8477ea5 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
- "revision": "eb65c4355e0a16dc5cd203c5c007fd7e3bf0e4b2",
+ "revision": "c65e0f2f00a05a78a57eecb1185c6420b7984d36",
"repo_path": "integration/gaia-central"
}
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index 14d96f08af35..5be33da37257 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index 0d8c274fec0f..65461620cff2 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index 28dbbedf4eb5..ae6db6eae670 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index de4c0a9bb513..0af5d9c33d8f 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/dom/bluetooth/bluedroid/BluetoothUtils.cpp b/dom/bluetooth/BluetoothUtils.cpp
similarity index 82%
rename from dom/bluetooth/bluedroid/BluetoothUtils.cpp
rename to dom/bluetooth/BluetoothUtils.cpp
index 7054cb6f13b5..c52ff5b58a77 100644
--- a/dom/bluetooth/bluedroid/BluetoothUtils.cpp
+++ b/dom/bluetooth/BluetoothUtils.cpp
@@ -4,33 +4,17 @@
* 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 "BluetoothUtils.h"
#include "BluetoothReplyRunnable.h"
#include "BluetoothService.h"
-#include "BluetoothServiceBluedroid.h"
-#include "BluetoothUtils.h"
#include "jsapi.h"
-#include "mozilla/Scoped.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "nsContentUtils.h"
-#include "nsIScriptContext.h"
#include "nsISystemMessagesInternal.h"
-#include "nsString.h"
-#include "nsTArray.h"
#include "nsServiceManagerUtils.h"
BEGIN_BLUETOOTH_NAMESPACE
-uint16_t
-UuidToServiceClassInt(const BluetoothUuid& mUuid)
-{
- // extract short UUID 0000xxxx-0000-1000-8000-00805f9b34fb
- uint16_t shortUuid;
- memcpy(&shortUuid, mUuid.mUuid + 2, sizeof(uint16_t));
- return ntohs(shortUuid);
-}
-
bool
SetJsObject(JSContext* aContext,
const BluetoothValue& aValue,
@@ -123,6 +107,37 @@ BroadcastSystemMessage(const nsAString& aType,
return true;
}
+bool
+BroadcastSystemMessage(const nsAString& aType,
+ const InfallibleTArray& aData)
+{
+ mozilla::AutoSafeJSContext cx;
+ NS_ASSERTION(!::JS_IsExceptionPending(cx),
+ "Shouldn't get here when an exception is pending!");
+
+ JS::Rooted obj(cx, JS_NewObject(cx, nullptr, JS::NullPtr(),
+ JS::NullPtr()));
+ if (!obj) {
+ BT_WARNING("Failed to new JSObject for system message!");
+ return false;
+ }
+
+ if (!SetJsObject(cx, aData, obj)) {
+ BT_WARNING("Failed to set properties of system message!");
+ return false;
+ }
+
+ nsCOMPtr systemMessenger =
+ do_GetService("@mozilla.org/system-message-internal;1");
+ NS_ENSURE_TRUE(systemMessenger, false);
+
+ JS::Rooted value(cx, JS::ObjectValue(*obj));
+ systemMessenger->BroadcastMessage(aType, value,
+ JS::UndefinedHandleValue);
+
+ return true;
+}
+
void
DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
const BluetoothValue& aValue,
diff --git a/dom/bluetooth/bluedroid/BluetoothUtils.h b/dom/bluetooth/BluetoothUtils.h
similarity index 82%
rename from dom/bluetooth/bluedroid/BluetoothUtils.h
rename to dom/bluetooth/BluetoothUtils.h
index 6d141a44e31e..41449762e551 100644
--- a/dom/bluetooth/bluedroid/BluetoothUtils.h
+++ b/dom/bluetooth/BluetoothUtils.h
@@ -4,8 +4,8 @@
* 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/. */
-#ifndef mozilla_dom_bluetooth_bluetoothutils_h__
-#define mozilla_dom_bluetooth_bluetoothutils_h__
+#ifndef mozilla_dom_bluetooth_bluetoothutils_h
+#define mozilla_dom_bluetooth_bluetoothutils_h
#include "BluetoothCommon.h"
#include "js/TypeDecls.h"
@@ -16,9 +16,6 @@ class BluetoothNamedValue;
class BluetoothValue;
class BluetoothReplyRunnable;
-uint16_t
-UuidToServiceClassInt(const BluetoothUuid& mUuid);
-
bool
SetJsObject(JSContext* aContext,
const BluetoothValue& aValue,
@@ -28,6 +25,10 @@ bool
BroadcastSystemMessage(const nsAString& aType,
const BluetoothValue& aData);
+bool
+BroadcastSystemMessage(const nsAString& aType,
+ const InfallibleTArray& aData);
+
void
DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
const BluetoothValue& aValue,
diff --git a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp
index fd73749c6f6e..81ead9071a5b 100644
--- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp
+++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp
@@ -1098,6 +1098,15 @@ BluetoothServiceBluedroid::ToggleCalls(BluetoothReplyRunnable* aRunnable)
{
}
+uint16_t
+BluetoothServiceBluedroid::UuidToServiceClassInt(const BluetoothUuid& mUuid)
+{
+ // extract short UUID 0000xxxx-0000-1000-8000-00805f9b34fb
+ uint16_t shortUuid;
+ memcpy(&shortUuid, mUuid.mUuid + 2, sizeof(uint16_t));
+ return ntohs(shortUuid);
+}
+
//
// Bluetooth notifications
//
diff --git a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h
index 1979fcc34a4a..f9f3c0dc00f7 100644
--- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h
+++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.h
@@ -221,6 +221,8 @@ protected:
static ControlPlayStatus PlayStatusStringToControlPlayStatus(
const nsAString& aPlayStatus);
+
+ uint16_t UuidToServiceClassInt(const BluetoothUuid& mUuid);
};
END_BLUETOOTH_NAMESPACE
diff --git a/dom/bluetooth/bluez/BluetoothDBusService.cpp b/dom/bluetooth/bluez/BluetoothDBusService.cpp
index 838e62941e32..f4abdef747fc 100644
--- a/dom/bluetooth/bluez/BluetoothDBusService.cpp
+++ b/dom/bluetooth/bluez/BluetoothDBusService.cpp
@@ -392,6 +392,37 @@ BluetoothDBusService::~BluetoothDBusService()
sGetPropertyMonitor = nullptr;
}
+static nsString
+GetObjectPathFromAddress(const nsAString& aAdapterPath,
+ const nsAString& aDeviceAddress)
+{
+ // The object path would be like /org/bluez/2906/hci0/dev_00_23_7F_CB_B4_F1,
+ // and the adapter path would be the first part of the object path, according
+ // to the example above, it's /org/bluez/2906/hci0.
+ nsString devicePath(aAdapterPath);
+ devicePath.AppendLiteral("/dev_");
+ devicePath.Append(aDeviceAddress);
+ devicePath.ReplaceChar(':', '_');
+ return devicePath;
+}
+
+static nsString
+GetAddressFromObjectPath(const nsAString& aObjectPath)
+{
+ // The object path would be like /org/bluez/2906/hci0/dev_00_23_7F_CB_B4_F1,
+ // and the adapter path would be the first part of the object path, according
+ // to the example above, it's /org/bluez/2906/hci0.
+ nsString address(aObjectPath);
+ int addressHead = address.RFind("/") + 5;
+
+ MOZ_ASSERT(addressHead + BLUETOOTH_ADDRESS_LENGTH == (int)address.Length());
+
+ address.Cut(0, addressHead);
+ address.ReplaceChar('_', ':');
+
+ return address;
+}
+
static bool
GetConnectedDevicesFilter(const BluetoothValue& aValue)
{
diff --git a/dom/bluetooth/bluez/BluetoothHfpManager.cpp b/dom/bluetooth/bluez/BluetoothHfpManager.cpp
index e6b3e5c0fd17..9460d11b361c 100644
--- a/dom/bluetooth/bluez/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothHfpManager.cpp
@@ -690,6 +690,28 @@ BluetoothHfpManager::HandleShutdown()
sBluetoothHfpManager = nullptr;
}
+void
+BluetoothHfpManager::ParseAtCommand(const nsACString& aAtCommand,
+ const int aStart,
+ nsTArray& aRetValues)
+{
+ int length = aAtCommand.Length();
+ int begin = aStart;
+
+ for (int i = aStart; i < length; ++i) {
+ // Use ',' as separator
+ if (aAtCommand[i] == ',') {
+ nsCString tmp(nsDependentCSubstring(aAtCommand, begin, i - begin));
+ aRetValues.AppendElement(tmp);
+
+ begin = i + 1;
+ }
+ }
+
+ nsCString tmp(nsDependentCSubstring(aAtCommand, begin));
+ aRetValues.AppendElement(tmp);
+}
+
// Virtual function of class SocketConsumer
void
BluetoothHfpManager::ReceiveSocketData(BluetoothSocket* aSocket,
diff --git a/dom/bluetooth/bluez/BluetoothHfpManager.h b/dom/bluetooth/bluez/BluetoothHfpManager.h
index 2de35b57a22f..2a96fec639a7 100644
--- a/dom/bluetooth/bluez/BluetoothHfpManager.h
+++ b/dom/bluetooth/bluez/BluetoothHfpManager.h
@@ -132,6 +132,9 @@ public:
#endif
private:
+ void ParseAtCommand(const nsACString& aAtCommand, const int aStart,
+ nsTArray& aRetValues);
+
class CloseScoTask;
class GetVolumeTask;
#ifdef MOZ_B2G_RIL
diff --git a/dom/bluetooth/bluez/BluetoothUtils.cpp b/dom/bluetooth/bluez/BluetoothUtils.cpp
deleted file mode 100644
index d4120082d9ea..000000000000
--- a/dom/bluetooth/bluez/BluetoothUtils.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * 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 "BluetoothReplyRunnable.h"
-#include "BluetoothService.h"
-#include "BluetoothUtils.h"
-#include "jsapi.h"
-#include "mozilla/Scoped.h"
-#include "mozilla/dom/bluetooth/BluetoothTypes.h"
-#include "nsContentUtils.h"
-#include "nsIScriptContext.h"
-#include "nsISystemMessagesInternal.h"
-#include "nsString.h"
-#include "nsTArray.h"
-#include "nsServiceManagerUtils.h"
-
-BEGIN_BLUETOOTH_NAMESPACE
-
-bool
-SetJsObject(JSContext* aContext,
- const BluetoothValue& aValue,
- JS::Handle aObj)
-{
- MOZ_ASSERT(aContext && aObj);
-
- if (aValue.type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
- BT_WARNING("SetJsObject: Invalid parameter type");
- return false;
- }
-
- const nsTArray& arr =
- aValue.get_ArrayOfBluetoothNamedValue();
-
- for (uint32_t i = 0; i < arr.Length(); i++) {
- JS::Rooted val(aContext);
- const BluetoothValue& v = arr[i].value();
-
- switch(v.type()) {
- case BluetoothValue::TnsString: {
- JSString* jsData = JS_NewUCStringCopyN(aContext,
- v.get_nsString().BeginReading(),
- v.get_nsString().Length());
- NS_ENSURE_TRUE(jsData, false);
- val = STRING_TO_JSVAL(jsData);
- break;
- }
- case BluetoothValue::Tuint32_t:
- val = INT_TO_JSVAL(v.get_uint32_t());
- break;
- case BluetoothValue::Tbool:
- val = BOOLEAN_TO_JSVAL(v.get_bool());
- break;
- default:
- BT_WARNING("SetJsObject: Parameter is not handled");
- break;
- }
-
- if (!JS_SetProperty(aContext, aObj,
- NS_ConvertUTF16toUTF8(arr[i].name()).get(),
- val)) {
- BT_WARNING("Failed to set property");
- return false;
- }
- }
-
- return true;
-}
-
-nsString
-GetObjectPathFromAddress(const nsAString& aAdapterPath,
- const nsAString& aDeviceAddress)
-{
- // The object path would be like /org/bluez/2906/hci0/dev_00_23_7F_CB_B4_F1,
- // and the adapter path would be the first part of the object path, according
- // to the example above, it's /org/bluez/2906/hci0.
- nsString devicePath(aAdapterPath);
- devicePath.AppendLiteral("/dev_");
- devicePath.Append(aDeviceAddress);
- devicePath.ReplaceChar(':', '_');
- return devicePath;
-}
-
-nsString
-GetAddressFromObjectPath(const nsAString& aObjectPath)
-{
- // The object path would be like /org/bluez/2906/hci0/dev_00_23_7F_CB_B4_F1,
- // and the adapter path would be the first part of the object path, according
- // to the example above, it's /org/bluez/2906/hci0.
- nsString address(aObjectPath);
- int addressHead = address.RFind("/") + 5;
-
- MOZ_ASSERT(addressHead + BLUETOOTH_ADDRESS_LENGTH == (int)address.Length());
-
- address.Cut(0, addressHead);
- address.ReplaceChar('_', ':');
-
- return address;
-}
-
-bool
-BroadcastSystemMessage(const nsAString& aType,
- const InfallibleTArray& aData)
-{
- mozilla::AutoSafeJSContext cx;
- NS_ASSERTION(!::JS_IsExceptionPending(cx),
- "Shouldn't get here when an exception is pending!");
-
- JS::Rooted obj(cx, JS_NewObject(cx, nullptr, JS::NullPtr(),
- JS::NullPtr()));
- if (!obj) {
- BT_WARNING("Failed to new JSObject for system message!");
- return false;
- }
-
- if (!SetJsObject(cx, aData, obj)) {
- BT_WARNING("Failed to set properties of system message!");
- return false;
- }
-
- nsCOMPtr systemMessenger =
- do_GetService("@mozilla.org/system-message-internal;1");
- NS_ENSURE_TRUE(systemMessenger, false);
-
- JS::Rooted value(cx, JS::ObjectValue(*obj));
- systemMessenger->BroadcastMessage(aType, value,
- JS::UndefinedHandleValue);
-
- return true;
-}
-
-void
-DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
- const BluetoothValue& aValue,
- const nsAString& aErrorStr)
-{
- // Reply will be deleted by the runnable after running on main thread
- BluetoothReply* reply;
- if (!aErrorStr.IsEmpty()) {
- nsString err(aErrorStr);
- reply = new BluetoothReply(BluetoothReplyError(err));
- } else {
- MOZ_ASSERT(aValue.type() != BluetoothValue::T__None);
- reply = new BluetoothReply(BluetoothReplySuccess(aValue));
- }
-
- aRunnable->SetReply(reply);
- if (NS_FAILED(NS_DispatchToMainThread(aRunnable))) {
- BT_WARNING("Failed to dispatch to main thread!");
- }
-}
-
-void
-ParseAtCommand(const nsACString& aAtCommand, const int aStart,
- nsTArray& aRetValues)
-{
- int length = aAtCommand.Length();
- int begin = aStart;
-
- for (int i = aStart; i < length; ++i) {
- // Use ',' as separator
- if (aAtCommand[i] == ',') {
- nsCString tmp(nsDependentCSubstring(aAtCommand, begin, i - begin));
- aRetValues.AppendElement(tmp);
-
- begin = i + 1;
- }
- }
-
- nsCString tmp(nsDependentCSubstring(aAtCommand, begin));
- aRetValues.AppendElement(tmp);
-}
-
-void
-DispatchStatusChangedEvent(const nsAString& aType,
- const nsAString& aAddress,
- bool aStatus)
-{
- MOZ_ASSERT(NS_IsMainThread());
-
- InfallibleTArray data;
- data.AppendElement(
- BluetoothNamedValue(NS_LITERAL_STRING("address"), nsString(aAddress)));
- data.AppendElement(
- BluetoothNamedValue(NS_LITERAL_STRING("status"), aStatus));
-
- BluetoothSignal signal(nsString(aType), NS_LITERAL_STRING(KEY_ADAPTER), data);
-
- BluetoothService* bs = BluetoothService::Get();
- NS_ENSURE_TRUE_VOID(bs);
- bs->DistributeSignal(signal);
-}
-
-END_BLUETOOTH_NAMESPACE
diff --git a/dom/bluetooth/bluez/BluetoothUtils.h b/dom/bluetooth/bluez/BluetoothUtils.h
deleted file mode 100644
index 2156207f1d4f..000000000000
--- a/dom/bluetooth/bluez/BluetoothUtils.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * 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/. */
-
-#ifndef mozilla_dom_bluetooth_bluetoothutils_h__
-#define mozilla_dom_bluetooth_bluetoothutils_h__
-
-#include "BluetoothCommon.h"
-#include "js/TypeDecls.h"
-
-BEGIN_BLUETOOTH_NAMESPACE
-
-class BluetoothNamedValue;
-class BluetoothValue;
-class BluetoothReplyRunnable;
-
-bool
-SetJsObject(JSContext* aContext,
- const BluetoothValue& aValue,
- JS::Handle aObj);
-
-nsString
-GetObjectPathFromAddress(const nsAString& aAdapterPath,
- const nsAString& aDeviceAddress);
-
-nsString
-GetAddressFromObjectPath(const nsAString& aObjectPath);
-
-bool
-BroadcastSystemMessage(const nsAString& aType,
- const InfallibleTArray& aData);
-
-void
-DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
- const BluetoothValue& aValue,
- const nsAString& aErrorStr);
-
-void
-ParseAtCommand(const nsACString& aAtCommand, const int aStart,
- nsTArray& aRetValues);
-
-void
-DispatchStatusChangedEvent(const nsAString& aType,
- const nsAString& aDeviceAddress,
- bool aStatus);
-
-END_BLUETOOTH_NAMESPACE
-
-#endif
diff --git a/dom/bluetooth/moz.build b/dom/bluetooth/moz.build
index 585be1865c67..50c91a62ba17 100644
--- a/dom/bluetooth/moz.build
+++ b/dom/bluetooth/moz.build
@@ -15,6 +15,7 @@ if CONFIG['MOZ_B2G_BT']:
'BluetoothPropertyContainer.cpp',
'BluetoothReplyRunnable.cpp',
'BluetoothService.cpp',
+ 'BluetoothUtils.cpp',
'BluetoothUuid.cpp',
'ipc/BluetoothChild.cpp',
'ipc/BluetoothParent.cpp',
@@ -36,8 +37,7 @@ if CONFIG['MOZ_B2G_BT']:
'bluez/BluetoothHfpManager.cpp',
'bluez/BluetoothOppManager.cpp',
'bluez/BluetoothSocket.cpp',
- 'bluez/BluetoothUnixSocketConnector.cpp',
- 'bluez/BluetoothUtils.cpp',
+ 'bluez/BluetoothUnixSocketConnector.cpp'
]
LOCAL_INCLUDES += [
'bluez',
@@ -60,8 +60,7 @@ if CONFIG['MOZ_B2G_BT']:
'bluedroid/BluetoothServiceBluedroid.cpp',
'bluedroid/BluetoothSocket.cpp',
'bluedroid/BluetoothSocketHALInterface.cpp',
- 'bluedroid/BluetoothSocketMessageWatcher.cpp',
- 'bluedroid/BluetoothUtils.cpp',
+ 'bluedroid/BluetoothSocketMessageWatcher.cpp'
]
LOCAL_INCLUDES += [
'bluedroid',
diff --git a/dom/bluetooth2/BluetoothService.cpp b/dom/bluetooth2/BluetoothService.cpp
index a209a9fd09e9..1a95101cd14b 100644
--- a/dom/bluetooth2/BluetoothService.cpp
+++ b/dom/bluetooth2/BluetoothService.cpp
@@ -145,34 +145,7 @@ BluetoothService::ToggleBtAck::ToggleBtAck(bool aEnabled)
NS_METHOD
BluetoothService::ToggleBtAck::Run()
{
- MOZ_ASSERT(NS_IsMainThread());
-
- // This is requested in Bug 836516. With settings this property, WLAN
- // firmware could be aware of Bluetooth has been turned on/off, so that the
- // mecahnism of handling coexistence of WIFI and Bluetooth could be started.
- //
- // In the future, we may have our own way instead of setting a system
- // property to let firmware developers be able to sense that Bluetooth has
- // been toggled.
-#if defined(MOZ_WIDGET_GONK)
- if (property_set(PROP_BLUETOOTH_ENABLED, mEnabled ? "true" : "false") != 0) {
- BT_WARNING("Failed to set bluetooth enabled property");
- }
-#endif
-
- NS_ENSURE_TRUE(sBluetoothService, NS_OK);
-
- if (sInShutdown) {
- sBluetoothService = nullptr;
- return NS_OK;
- }
-
- // Update mEnabled of BluetoothService object since
- // StartInternal/StopInternal have been already done.
- sBluetoothService->SetEnabled(mEnabled);
- sToggleInProgress = false;
-
- sBluetoothService->FireAdapterStateChanged(mEnabled);
+ BluetoothService::AcknowledgeToggleBt(mEnabled);
return NS_OK;
}
@@ -709,3 +682,45 @@ BluetoothService::FireAdapterStateChanged(bool aEnable)
NS_LITERAL_STRING(KEY_ADAPTER), value);
DistributeSignal(signal);
}
+
+void
+BluetoothService::AcknowledgeToggleBt(bool aEnabled)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+#if defined(MOZ_WIDGET_GONK)
+ // This is requested in Bug 836516. With settings this property, WLAN
+ // firmware could be aware of Bluetooth has been turned on/off, so that the
+ // mecahnism of handling coexistence of WIFI and Bluetooth could be started.
+ //
+ // In the future, we may have our own way instead of setting a system
+ // property to let firmware developers be able to sense that Bluetooth has
+ // been toggled.
+ if (property_set(PROP_BLUETOOTH_ENABLED, aEnabled ? "true" : "false") != 0) {
+ BT_WARNING("Failed to set bluetooth enabled property");
+ }
+#endif
+
+ if (sInShutdown) {
+ sBluetoothService = nullptr;
+ return;
+ }
+
+ NS_ENSURE_TRUE_VOID(sBluetoothService);
+
+ sBluetoothService->CompleteToggleBt(aEnabled);
+}
+
+void
+BluetoothService::CompleteToggleBt(bool aEnabled)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ // Update |mEnabled| of |BluetoothService| object since
+ // |StartInternal| and |StopInternal| have been already
+ // done.
+ SetEnabled(aEnabled);
+ sToggleInProgress = false;
+
+ FireAdapterStateChanged(aEnabled);
+}
diff --git a/dom/bluetooth2/BluetoothService.h b/dom/bluetooth2/BluetoothService.h
index 8d72b492a0d2..56092a432865 100644
--- a/dom/bluetooth2/BluetoothService.h
+++ b/dom/bluetooth2/BluetoothService.h
@@ -315,6 +315,8 @@ public:
bool
IsToggling() const;
+ static void AcknowledgeToggleBt(bool aEnabled);
+
void FireAdapterStateChanged(bool aEnable);
nsresult EnableDisable(bool aEnable,
BluetoothReplyRunnable* aRunnable);
@@ -392,6 +394,8 @@ protected:
static BluetoothService*
Create();
+ void CompleteToggleBt(bool aEnabled);
+
typedef nsClassHashtable
BluetoothSignalObserverTable;
diff --git a/dom/bluetooth2/bluedroid/BluetoothDaemonHandsfreeInterface.cpp b/dom/bluetooth2/bluedroid/BluetoothDaemonHandsfreeInterface.cpp
new file mode 100644
index 000000000000..506c776c11d1
--- /dev/null
+++ b/dom/bluetooth2/bluedroid/BluetoothDaemonHandsfreeInterface.cpp
@@ -0,0 +1,1240 @@
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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 "BluetoothDaemonHandsfreeInterface.h"
+#include "BluetoothDaemonSetupInterface.h"
+#include "mozilla/unused.h"
+
+BEGIN_BLUETOOTH_NAMESPACE
+
+//
+// Handsfree module
+//
+
+BluetoothHandsfreeNotificationHandler*
+ BluetoothDaemonHandsfreeModule::sNotificationHandler;
+
+void
+BluetoothDaemonHandsfreeModule::SetNotificationHandler(
+ BluetoothHandsfreeNotificationHandler* aNotificationHandler)
+{
+ sNotificationHandler = aNotificationHandler;
+}
+
+nsresult
+BluetoothDaemonHandsfreeModule::Send(BluetoothDaemonPDU* aPDU,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ aRes->AddRef(); // Keep reference for response
+ return Send(aPDU, static_cast(aRes));
+}
+
+void
+BluetoothDaemonHandsfreeModule::HandleSvc(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU, void* aUserData)
+{
+ static void (BluetoothDaemonHandsfreeModule::* const HandleOp[])(
+ const BluetoothDaemonPDUHeader&, BluetoothDaemonPDU&, void*) = {
+ INIT_ARRAY_AT(0, &BluetoothDaemonHandsfreeModule::HandleRsp),
+ INIT_ARRAY_AT(1, &BluetoothDaemonHandsfreeModule::HandleNtf),
+ };
+
+ MOZ_ASSERT(!NS_IsMainThread());
+
+ // Negate twice to map bit to 0/1
+ unsigned long isNtf = !!(aHeader.mOpcode & 0x80);
+
+ (this->*(HandleOp[isNtf]))(aHeader, aPDU, aUserData);
+}
+
+// Commands
+//
+
+nsresult
+BluetoothDaemonHandsfreeModule::ConnectCmd(
+ const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsAutoPtr pdu(
+ new BluetoothDaemonPDU(SERVICE_ID, OPCODE_CONNECT,
+ 6)); // Address
+
+ nsresult rv = PackPDU(
+ PackConversion(aRemoteAddr), *pdu);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = Send(pdu, aRes);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ unused << pdu.forget();
+ return NS_OK;
+}
+
+nsresult
+BluetoothDaemonHandsfreeModule::DisconnectCmd(
+ const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsAutoPtr pdu(
+ new BluetoothDaemonPDU(SERVICE_ID, OPCODE_DISCONNECT,
+ 6)); // Address
+
+ nsresult rv = PackPDU(
+ PackConversion(aRemoteAddr), *pdu);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = Send(pdu, aRes);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ unused << pdu.forget();
+ return NS_OK;
+}
+
+nsresult
+BluetoothDaemonHandsfreeModule::ConnectAudioCmd(
+ const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsAutoPtr pdu(
+ new BluetoothDaemonPDU(SERVICE_ID, OPCODE_CONNECT_AUDIO,
+ 6)); // Address
+
+ nsresult rv = PackPDU(
+ PackConversion(aRemoteAddr), *pdu);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = Send(pdu, aRes);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ unused << pdu.forget();
+ return NS_OK;
+}
+
+nsresult
+BluetoothDaemonHandsfreeModule::DisconnectAudioCmd(
+ const nsAString& aRemoteAddr, BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsAutoPtr pdu(
+ new BluetoothDaemonPDU(SERVICE_ID, OPCODE_DISCONNECT_AUDIO,
+ 6)); // Address
+
+ nsresult rv = PackPDU(
+ PackConversion(aRemoteAddr), *pdu);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = Send(pdu, aRes);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ unused << pdu.forget();
+ return NS_OK;
+}
+
+nsresult
+BluetoothDaemonHandsfreeModule::StartVoiceRecognitionCmd(
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsAutoPtr pdu(
+ new BluetoothDaemonPDU(SERVICE_ID, OPCODE_START_VOICE_RECOGNITION,
+ 0)); // No payload
+
+ nsresult rv = Send(pdu, aRes);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ unused << pdu.forget();
+ return NS_OK;
+}
+
+nsresult
+BluetoothDaemonHandsfreeModule::StopVoiceRecognitionCmd(
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsAutoPtr pdu(
+ new BluetoothDaemonPDU(SERVICE_ID, OPCODE_STOP_VOICE_RECOGNITION,
+ 0)); // No payload
+
+ nsresult rv = Send(pdu, aRes);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ unused << pdu.forget();
+ return NS_OK;
+}
+
+nsresult
+BluetoothDaemonHandsfreeModule::VolumeControlCmd(
+ BluetoothHandsfreeVolumeType aType, int aVolume,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsAutoPtr pdu(
+ new BluetoothDaemonPDU(SERVICE_ID, OPCODE_VOLUME_CONTROL,
+ 1 + // Volume type
+ 1)); // Volume
+
+ nsresult rv = PackPDU(aType, PackConversion(aVolume), *pdu);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = Send(pdu, aRes);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ unused << pdu.forget();
+ return NS_OK;
+}
+
+nsresult
+BluetoothDaemonHandsfreeModule::DeviceStatusNotificationCmd(
+ BluetoothHandsfreeNetworkState aNtkState,
+ BluetoothHandsfreeServiceType aSvcType, int aSignal, int aBattChg,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsAutoPtr pdu(
+ new BluetoothDaemonPDU(SERVICE_ID, OPCODE_DEVICE_STATUS_NOTIFICATION,
+ 1 + // Network state
+ 1 + // Service type
+ 1 + // Signal strength
+ 1)); // Battery level
+
+ nsresult rv = PackPDU(aNtkState, aSvcType,
+ PackConversion(aSignal),
+ PackConversion(aBattChg), *pdu);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = Send(pdu, aRes);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ unused << pdu.forget();
+ return NS_OK;
+}
+
+nsresult
+BluetoothDaemonHandsfreeModule::CopsResponseCmd(
+ const char* aCops, BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsAutoPtr pdu(
+ new BluetoothDaemonPDU(SERVICE_ID, OPCODE_COPS_RESPONSE,
+ 0)); // Dynamically allocated
+
+ nsresult rv = PackPDU(PackCString0(nsDependentCString(aCops)), *pdu);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = Send(pdu, aRes);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ unused << pdu.forget();
+ return NS_OK;
+}
+
+nsresult
+BluetoothDaemonHandsfreeModule::CindResponseCmd(
+ int aSvc, int aNumActive, int aNumHeld,
+ BluetoothHandsfreeCallState aCallSetupState,
+ int aSignal, int aRoam, int aBattChg,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsAutoPtr pdu(
+ new BluetoothDaemonPDU(SERVICE_ID, OPCODE_CIND_RESPONSE,
+ 1 + // Service
+ 1 + // # Active
+ 1 + // # Held
+ 1 + // Call state
+ 1 + // Signal strength
+ 1 + // Roaming
+ 1)); // Battery level
+
+ nsresult rv = PackPDU(PackConversion(aSvc),
+ PackConversion(aNumActive),
+ PackConversion(aNumHeld),
+ aCallSetupState,
+ PackConversion(aSignal),
+ PackConversion(aRoam),
+ PackConversion(aBattChg), *pdu);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = Send(pdu, aRes);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ unused << pdu.forget();
+ return NS_OK;
+}
+
+nsresult
+BluetoothDaemonHandsfreeModule::FormattedAtResponseCmd(
+ const char* aRsp, BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsAutoPtr pdu(
+ new BluetoothDaemonPDU(SERVICE_ID, OPCODE_FORMATTED_AT_RESPONSE,
+ 0)); // Dynamically allocated
+
+ nsresult rv = PackPDU(PackCString0(nsDependentCString(aRsp)), *pdu);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = Send(pdu, aRes);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ unused << pdu.forget();
+ return NS_OK;
+}
+
+nsresult
+BluetoothDaemonHandsfreeModule::AtResponseCmd(
+ BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ nsAutoPtr pdu(
+ new BluetoothDaemonPDU(SERVICE_ID, OPCODE_AT_RESPONSE,
+ 1 + // AT Response code
+ 1)); // Error code
+
+ nsresult rv = PackPDU(aResponseCode,
+ PackConversion(aErrorCode), *pdu);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = Send(pdu, aRes);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ unused << pdu.forget();
+ return NS_OK;
+}
+
+nsresult
+BluetoothDaemonHandsfreeModule::ClccResponseCmd(
+ int aIndex,
+ BluetoothHandsfreeCallDirection aDir, BluetoothHandsfreeCallState aState,
+ BluetoothHandsfreeCallMode aMode, BluetoothHandsfreeCallMptyType aMpty,
+ const nsAString& aNumber, BluetoothHandsfreeCallAddressType aType,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ NS_ConvertUTF16toUTF8 number(aNumber);
+
+ nsAutoPtr pdu(
+ new BluetoothDaemonPDU(SERVICE_ID, OPCODE_CLCC_RESPONSE,
+ 1 + // Call index
+ 1 + // Call direction
+ 1 + // Call state
+ 1 + // Call mode
+ 1 + // Call MPTY
+ 1 + // Address type
+ number.Length() + 1)); // Number string + \0
+
+ nsresult rv = PackPDU(PackConversion(aIndex),
+ aDir, aState, aMode, aMpty, aType,
+ PackCString0(number), *pdu);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = Send(pdu, aRes);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ unused << pdu.forget();
+ return NS_OK;
+}
+
+nsresult
+BluetoothDaemonHandsfreeModule::PhoneStateChangeCmd(
+ int aNumActive, int aNumHeld, BluetoothHandsfreeCallState aCallSetupState,
+ const nsAString& aNumber, BluetoothHandsfreeCallAddressType aType,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ NS_ConvertUTF16toUTF8 number(aNumber);
+
+ nsAutoPtr pdu(
+ new BluetoothDaemonPDU(SERVICE_ID, OPCODE_PHONE_STATE_CHANGE,
+ 1 + // # Active
+ 1 + // # Held
+ 1 + // Call state
+ 1 + // Address type
+ number.Length() + 1)); // Number string + \0
+
+ nsresult rv = PackPDU(PackConversion(aNumActive),
+ PackConversion(aNumHeld),
+ aCallSetupState, aType,
+ PackCString0(NS_ConvertUTF16toUTF8(aNumber)), *pdu);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = Send(pdu, aRes);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ unused << pdu.forget();
+ return NS_OK;
+}
+
+// Responses
+//
+
+void
+BluetoothDaemonHandsfreeModule::ErrorRsp(
+ const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU, BluetoothHandsfreeResultHandler* aRes)
+{
+ ErrorRunnable::Dispatch(
+ aRes, &BluetoothHandsfreeResultHandler::OnError, UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::ConnectRsp(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ ResultRunnable::Dispatch(
+ aRes, &BluetoothHandsfreeResultHandler::Connect, UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::DisconnectRsp(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ ResultRunnable::Dispatch(
+ aRes, &BluetoothHandsfreeResultHandler::Disconnect, UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::ConnectAudioRsp(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ ResultRunnable::Dispatch(
+ aRes, &BluetoothHandsfreeResultHandler::ConnectAudio,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::DisconnectAudioRsp(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ ResultRunnable::Dispatch(
+ aRes, &BluetoothHandsfreeResultHandler::DisconnectAudio,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::StartVoiceRecognitionRsp(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ ResultRunnable::Dispatch(
+ aRes, &BluetoothHandsfreeResultHandler::StartVoiceRecognition,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::StopVoiceRecognitionRsp(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ ResultRunnable::Dispatch(
+ aRes, &BluetoothHandsfreeResultHandler::StopVoiceRecognition,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::VolumeControlRsp(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ ResultRunnable::Dispatch(
+ aRes, &BluetoothHandsfreeResultHandler::VolumeControl,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::DeviceStatusNotificationRsp(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ ResultRunnable::Dispatch(
+ aRes, &BluetoothHandsfreeResultHandler::DeviceStatusNotification,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::CopsResponseRsp(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ ResultRunnable::Dispatch(
+ aRes, &BluetoothHandsfreeResultHandler::CopsResponse,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::CindResponseRsp(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ ResultRunnable::Dispatch(
+ aRes, &BluetoothHandsfreeResultHandler::CindResponse,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::FormattedAtResponseRsp(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ ResultRunnable::Dispatch(
+ aRes, &BluetoothHandsfreeResultHandler::FormattedAtResponse,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::AtResponseRsp(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ ResultRunnable::Dispatch(
+ aRes, &BluetoothHandsfreeResultHandler::AtResponse,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::ClccResponseRsp(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ ResultRunnable::Dispatch(
+ aRes, &BluetoothHandsfreeResultHandler::ClccResponse,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::PhoneStateChangeRsp(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ ResultRunnable::Dispatch(
+ aRes, &BluetoothHandsfreeResultHandler::PhoneStateChange,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::HandleRsp(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
+ void* aUserData)
+{
+ static void (BluetoothDaemonHandsfreeModule::* const HandleRsp[])(
+ const BluetoothDaemonPDUHeader&,
+ BluetoothDaemonPDU&,
+ BluetoothHandsfreeResultHandler*) = {
+ INIT_ARRAY_AT(OPCODE_ERROR,
+ &BluetoothDaemonHandsfreeModule::ErrorRsp),
+ INIT_ARRAY_AT(OPCODE_CONNECT,
+ &BluetoothDaemonHandsfreeModule::ConnectRsp),
+ INIT_ARRAY_AT(OPCODE_DISCONNECT,
+ &BluetoothDaemonHandsfreeModule::DisconnectRsp),
+ INIT_ARRAY_AT(OPCODE_CONNECT_AUDIO,
+ &BluetoothDaemonHandsfreeModule::ConnectAudioRsp),
+ INIT_ARRAY_AT(OPCODE_DISCONNECT_AUDIO,
+ &BluetoothDaemonHandsfreeModule::DisconnectAudioRsp),
+ INIT_ARRAY_AT(OPCODE_START_VOICE_RECOGNITION,
+ &BluetoothDaemonHandsfreeModule::StartVoiceRecognitionRsp),
+ INIT_ARRAY_AT(OPCODE_STOP_VOICE_RECOGNITION,
+ &BluetoothDaemonHandsfreeModule::StopVoiceRecognitionRsp),
+ INIT_ARRAY_AT(OPCODE_VOLUME_CONTROL,
+ &BluetoothDaemonHandsfreeModule::VolumeControlRsp),
+ INIT_ARRAY_AT(OPCODE_DEVICE_STATUS_NOTIFICATION,
+ &BluetoothDaemonHandsfreeModule::DeviceStatusNotificationRsp),
+ INIT_ARRAY_AT(OPCODE_COPS_RESPONSE,
+ &BluetoothDaemonHandsfreeModule::CopsResponseRsp),
+ INIT_ARRAY_AT(OPCODE_CIND_RESPONSE,
+ &BluetoothDaemonHandsfreeModule::CindResponseRsp),
+ INIT_ARRAY_AT(OPCODE_FORMATTED_AT_RESPONSE,
+ &BluetoothDaemonHandsfreeModule::FormattedAtResponseRsp),
+ INIT_ARRAY_AT(OPCODE_AT_RESPONSE,
+ &BluetoothDaemonHandsfreeModule::AtResponseRsp),
+ INIT_ARRAY_AT(OPCODE_CLCC_RESPONSE,
+ &BluetoothDaemonHandsfreeModule::ClccResponseRsp),
+ INIT_ARRAY_AT(OPCODE_PHONE_STATE_CHANGE,
+ &BluetoothDaemonHandsfreeModule::PhoneStateChangeRsp)
+ };
+
+ MOZ_ASSERT(!NS_IsMainThread()); // I/O thread
+
+ if (NS_WARN_IF(!(aHeader.mOpcode < MOZ_ARRAY_LENGTH(HandleRsp))) ||
+ NS_WARN_IF(!HandleRsp[aHeader.mOpcode])) {
+ return;
+ }
+
+ nsRefPtr res =
+ already_AddRefed(
+ static_cast(aUserData));
+
+ if (!res) {
+ return; // Return early if no result handler has been set for response
+ }
+
+ (this->*(HandleRsp[aHeader.mOpcode]))(aHeader, aPDU, res);
+}
+
+// Notifications
+//
+
+// Returns the current notification handler to a notification runnable
+class BluetoothDaemonHandsfreeModule::NotificationHandlerWrapper MOZ_FINAL
+{
+public:
+ typedef BluetoothHandsfreeNotificationHandler ObjectType;
+
+ static ObjectType* GetInstance()
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ return sNotificationHandler;
+ }
+};
+
+// Init operator class for ConnectionStateNotification
+class BluetoothDaemonHandsfreeModule::ConnectionStateInitOp MOZ_FINAL
+ : private PDUInitOp
+{
+public:
+ ConnectionStateInitOp(BluetoothDaemonPDU& aPDU)
+ : PDUInitOp(aPDU)
+ { }
+
+ nsresult
+ operator () (BluetoothHandsfreeConnectionState& aArg1,
+ nsString& aArg2) const
+ {
+ BluetoothDaemonPDU& pdu = GetPDU();
+
+ /* Read state */
+ nsresult rv = UnpackPDU(pdu, aArg1);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ /* Read address */
+ rv = UnpackPDU(
+ pdu, UnpackConversion(aArg2));
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ WarnAboutTrailingData();
+ return NS_OK;
+ }
+};
+
+void
+BluetoothDaemonHandsfreeModule::ConnectionStateNtf(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
+{
+ ConnectionStateNotification::Dispatch(
+ &BluetoothHandsfreeNotificationHandler::ConnectionStateNotification,
+ ConnectionStateInitOp(aPDU));
+}
+
+// Init operator class for AudioStateNotification
+class BluetoothDaemonHandsfreeModule::AudioStateInitOp MOZ_FINAL
+ : private PDUInitOp
+{
+public:
+ AudioStateInitOp(BluetoothDaemonPDU& aPDU)
+ : PDUInitOp(aPDU)
+ { }
+
+ nsresult
+ operator () (BluetoothHandsfreeAudioState& aArg1,
+ nsString& aArg2) const
+ {
+ BluetoothDaemonPDU& pdu = GetPDU();
+
+ /* Read state */
+ nsresult rv = UnpackPDU(pdu, aArg1);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ /* Read address */
+ rv = UnpackPDU(
+ pdu, UnpackConversion(aArg2));
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ WarnAboutTrailingData();
+ return NS_OK;
+ }
+};
+
+void
+BluetoothDaemonHandsfreeModule::AudioStateNtf(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
+{
+ AudioStateNotification::Dispatch(
+ &BluetoothHandsfreeNotificationHandler::AudioStateNotification,
+ AudioStateInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::VoiceRecognitionNtf(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
+{
+ VoiceRecognitionNotification::Dispatch(
+ &BluetoothHandsfreeNotificationHandler::VoiceRecognitionNotification,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::AnswerCallNtf(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
+{
+ AnswerCallNotification::Dispatch(
+ &BluetoothHandsfreeNotificationHandler::AnswerCallNotification,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::HangupCallNtf(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
+{
+ HangupCallNotification::Dispatch(
+ &BluetoothHandsfreeNotificationHandler::HangupCallNotification,
+ UnpackPDUInitOp(aPDU));
+}
+
+// Init operator class for VolumeNotification
+class BluetoothDaemonHandsfreeModule::VolumeInitOp MOZ_FINAL
+ : private PDUInitOp
+{
+public:
+ VolumeInitOp(BluetoothDaemonPDU& aPDU)
+ : PDUInitOp(aPDU)
+ { }
+
+ nsresult
+ operator () (BluetoothHandsfreeVolumeType& aArg1, int& aArg2) const
+ {
+ BluetoothDaemonPDU& pdu = GetPDU();
+
+ /* Read volume type */
+ nsresult rv = UnpackPDU(pdu, aArg1);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ /* Read volume */
+ rv = UnpackPDU(pdu, UnpackConversion(aArg2));
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ WarnAboutTrailingData();
+ return NS_OK;
+ }
+};
+
+void
+BluetoothDaemonHandsfreeModule::VolumeNtf(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
+{
+ VolumeNotification::Dispatch(
+ &BluetoothHandsfreeNotificationHandler::VolumeNotification,
+ VolumeInitOp(aPDU));
+}
+
+// Init operator class for DialCallNotification
+class BluetoothDaemonHandsfreeModule::DialCallInitOp MOZ_FINAL
+ : private PDUInitOp
+{
+public:
+ DialCallInitOp(BluetoothDaemonPDU& aPDU)
+ : PDUInitOp(aPDU)
+ { }
+
+ nsresult
+ operator () (nsString& aArg1) const
+ {
+ /* Read number */
+ nsresult rv = UnpackPDU(GetPDU(), UnpackString0(aArg1));
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ WarnAboutTrailingData();
+ return NS_OK;
+ }
+};
+
+void
+BluetoothDaemonHandsfreeModule::DialCallNtf(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
+{
+ DialCallNotification::Dispatch(
+ &BluetoothHandsfreeNotificationHandler::DialCallNotification,
+ DialCallInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::DtmfNtf(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
+{
+ DtmfNotification::Dispatch(
+ &BluetoothHandsfreeNotificationHandler::DtmfNotification,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::NRECNtf(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
+{
+ NRECNotification::Dispatch(
+ &BluetoothHandsfreeNotificationHandler::NRECNotification,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::CallHoldNtf(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
+{
+ CallHoldNotification::Dispatch(
+ &BluetoothHandsfreeNotificationHandler::CallHoldNotification,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::CnumNtf(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
+{
+ CnumNotification::Dispatch(
+ &BluetoothHandsfreeNotificationHandler::CnumNotification,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::CindNtf(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
+{
+ CindNotification::Dispatch(
+ &BluetoothHandsfreeNotificationHandler::CindNotification,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::CopsNtf(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
+{
+ CopsNotification::Dispatch(
+ &BluetoothHandsfreeNotificationHandler::CopsNotification,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::ClccNtf(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
+{
+ ClccNotification::Dispatch(
+ &BluetoothHandsfreeNotificationHandler::ClccNotification,
+ UnpackPDUInitOp(aPDU));
+}
+
+// Init operator class for UnknownAtNotification
+class BluetoothDaemonHandsfreeModule::UnknownAtInitOp MOZ_FINAL
+ : private PDUInitOp
+{
+public:
+ UnknownAtInitOp(BluetoothDaemonPDU& aPDU)
+ : PDUInitOp(aPDU)
+ { }
+
+ nsresult
+ operator () (nsCString& aArg1) const
+ {
+ /* Read string */
+ nsresult rv = UnpackPDU(GetPDU(), UnpackCString0(aArg1));
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ WarnAboutTrailingData();
+ return NS_OK;
+ }
+};
+
+void
+BluetoothDaemonHandsfreeModule::UnknownAtNtf(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
+{
+ UnknownAtNotification::Dispatch(
+ &BluetoothHandsfreeNotificationHandler::UnknownAtNotification,
+ UnknownAtInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::KeyPressedNtf(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU)
+{
+ KeyPressedNotification::Dispatch(
+ &BluetoothHandsfreeNotificationHandler::KeyPressedNotification,
+ UnpackPDUInitOp(aPDU));
+}
+
+void
+BluetoothDaemonHandsfreeModule::HandleNtf(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
+ void* aUserData)
+{
+ static void (BluetoothDaemonHandsfreeModule::* const HandleNtf[])(
+ const BluetoothDaemonPDUHeader&, BluetoothDaemonPDU&) = {
+ INIT_ARRAY_AT(0, &BluetoothDaemonHandsfreeModule::ConnectionStateNtf),
+ INIT_ARRAY_AT(1, &BluetoothDaemonHandsfreeModule::AudioStateNtf),
+ INIT_ARRAY_AT(2, &BluetoothDaemonHandsfreeModule::VoiceRecognitionNtf),
+ INIT_ARRAY_AT(3, &BluetoothDaemonHandsfreeModule::AnswerCallNtf),
+ INIT_ARRAY_AT(4, &BluetoothDaemonHandsfreeModule::HangupCallNtf),
+ INIT_ARRAY_AT(5, &BluetoothDaemonHandsfreeModule::VolumeNtf),
+ INIT_ARRAY_AT(6, &BluetoothDaemonHandsfreeModule::DialCallNtf),
+ INIT_ARRAY_AT(7, &BluetoothDaemonHandsfreeModule::DtmfNtf),
+ INIT_ARRAY_AT(8, &BluetoothDaemonHandsfreeModule::NRECNtf),
+ INIT_ARRAY_AT(9, &BluetoothDaemonHandsfreeModule::CallHoldNtf),
+ INIT_ARRAY_AT(10, &BluetoothDaemonHandsfreeModule::CnumNtf),
+ INIT_ARRAY_AT(11, &BluetoothDaemonHandsfreeModule::CindNtf),
+ INIT_ARRAY_AT(12, &BluetoothDaemonHandsfreeModule::CopsNtf),
+ INIT_ARRAY_AT(13, &BluetoothDaemonHandsfreeModule::ClccNtf),
+ INIT_ARRAY_AT(14, &BluetoothDaemonHandsfreeModule::UnknownAtNtf),
+ INIT_ARRAY_AT(15, &BluetoothDaemonHandsfreeModule::KeyPressedNtf)
+ };
+
+ MOZ_ASSERT(!NS_IsMainThread());
+
+ uint8_t index = aHeader.mOpcode - 0x81;
+
+ if (NS_WARN_IF(!(index < MOZ_ARRAY_LENGTH(HandleNtf))) ||
+ NS_WARN_IF(!HandleNtf[index])) {
+ return;
+ }
+
+ (this->*(HandleNtf[index]))(aHeader, aPDU);
+}
+
+//
+// Handsfree interface
+//
+
+BluetoothDaemonHandsfreeInterface::BluetoothDaemonHandsfreeInterface(
+ BluetoothDaemonHandsfreeModule* aModule)
+ : mModule(aModule)
+{ }
+
+BluetoothDaemonHandsfreeInterface::~BluetoothDaemonHandsfreeInterface()
+{ }
+
+class BluetoothDaemonHandsfreeInterface::InitResultHandler MOZ_FINAL
+ : public BluetoothSetupResultHandler
+{
+public:
+ InitResultHandler(BluetoothHandsfreeResultHandler* aRes)
+ : mRes(aRes)
+ {
+ MOZ_ASSERT(mRes);
+ }
+
+ void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ mRes->OnError(aStatus);
+ }
+
+ void RegisterModule() MOZ_OVERRIDE
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ mRes->Init();
+ }
+
+private:
+ nsRefPtr mRes;
+};
+
+void
+BluetoothDaemonHandsfreeInterface::Init(
+ BluetoothHandsfreeNotificationHandler* aNotificationHandler,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ // Set notification handler _before_ registering the module. It could
+ // happen that we receive notifications, before the result handler runs.
+ mModule->SetNotificationHandler(aNotificationHandler);
+
+ InitResultHandler* res;
+
+ if (aRes) {
+ res = new InitResultHandler(aRes);
+ } else {
+ // We don't need a result handler if the caller is not interested.
+ res = nullptr;
+ }
+
+ nsresult rv = mModule->RegisterModule(
+ BluetoothDaemonHandsfreeModule::SERVICE_ID, MODE_NARROWBAND_SPEECH, res);
+
+ if (NS_FAILED(rv) && aRes) {
+ DispatchError(aRes, STATUS_FAIL);
+ }
+}
+
+class BluetoothDaemonHandsfreeInterface::CleanupResultHandler MOZ_FINAL
+ : public BluetoothSetupResultHandler
+{
+public:
+ CleanupResultHandler(BluetoothDaemonHandsfreeModule* aModule,
+ BluetoothHandsfreeResultHandler* aRes)
+ : mModule(aModule)
+ , mRes(aRes)
+ {
+ MOZ_ASSERT(mModule);
+ }
+
+ void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ if (mRes) {
+ mRes->OnError(aStatus);
+ }
+ }
+
+ void UnregisterModule() MOZ_OVERRIDE
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ // Clear notification handler _after_ module has been
+ // unregistered. While unregistering the module, we might
+ // still receive notifications.
+ mModule->SetNotificationHandler(nullptr);
+
+ if (mRes) {
+ mRes->Cleanup();
+ }
+ }
+
+private:
+ BluetoothDaemonHandsfreeModule* mModule;
+ nsRefPtr mRes;
+};
+
+void
+BluetoothDaemonHandsfreeInterface::Cleanup(
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ mModule->UnregisterModule(BluetoothDaemonHandsfreeModule::SERVICE_ID,
+ new CleanupResultHandler(mModule, aRes));
+}
+
+/* Connect / Disconnect */
+
+void
+BluetoothDaemonHandsfreeInterface::Connect(
+ const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(mModule);
+
+ mModule->ConnectCmd(aBdAddr, aRes);
+}
+
+void
+BluetoothDaemonHandsfreeInterface::Disconnect(
+ const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(mModule);
+
+ mModule->DisconnectCmd(aBdAddr, aRes);
+}
+
+void
+BluetoothDaemonHandsfreeInterface::ConnectAudio(
+ const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(mModule);
+
+ mModule->ConnectAudioCmd(aBdAddr, aRes);
+}
+
+void
+BluetoothDaemonHandsfreeInterface::DisconnectAudio(
+ const nsAString& aBdAddr, BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(mModule);
+
+ mModule->DisconnectAudioCmd(aBdAddr, aRes);
+}
+
+/* Voice Recognition */
+
+void
+BluetoothDaemonHandsfreeInterface::StartVoiceRecognition(
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(mModule);
+
+ mModule->StartVoiceRecognitionCmd(aRes);
+}
+
+void
+BluetoothDaemonHandsfreeInterface::StopVoiceRecognition(
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(mModule);
+
+ mModule->StopVoiceRecognitionCmd(aRes);
+}
+
+/* Volume */
+
+void
+BluetoothDaemonHandsfreeInterface::VolumeControl(
+ BluetoothHandsfreeVolumeType aType, int aVolume,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(mModule);
+
+ mModule->VolumeControlCmd(aType, aVolume, aRes);
+}
+
+/* Device status */
+
+void
+BluetoothDaemonHandsfreeInterface::DeviceStatusNotification(
+ BluetoothHandsfreeNetworkState aNtkState,
+ BluetoothHandsfreeServiceType aSvcType, int aSignal, int aBattChg,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(mModule);
+
+ mModule->DeviceStatusNotificationCmd(aNtkState, aSvcType, aSignal,
+ aBattChg, aRes);
+}
+
+/* Responses */
+
+void
+BluetoothDaemonHandsfreeInterface::CopsResponse(
+ const char* aCops, BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(mModule);
+
+ mModule->CopsResponseCmd(aCops, aRes);
+}
+
+void
+BluetoothDaemonHandsfreeInterface::CindResponse(
+ int aSvc, int aNumActive, int aNumHeld,
+ BluetoothHandsfreeCallState aCallSetupState,
+ int aSignal, int aRoam, int aBattChg,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(mModule);
+
+ mModule->CindResponseCmd(aSvc, aNumActive, aNumHeld, aCallSetupState,
+ aSignal, aRoam, aBattChg, aRes);
+}
+
+void
+BluetoothDaemonHandsfreeInterface::FormattedAtResponse(
+ const char* aRsp, BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(mModule);
+
+ mModule->FormattedAtResponseCmd(aRsp, aRes);
+}
+
+void
+BluetoothDaemonHandsfreeInterface::AtResponse(
+ BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(mModule);
+
+ mModule->AtResponseCmd(aResponseCode, aErrorCode, aRes);
+}
+
+void
+BluetoothDaemonHandsfreeInterface::ClccResponse(
+ int aIndex, BluetoothHandsfreeCallDirection aDir,
+ BluetoothHandsfreeCallState aState,
+ BluetoothHandsfreeCallMode aMode,
+ BluetoothHandsfreeCallMptyType aMpty,
+ const nsAString& aNumber,
+ BluetoothHandsfreeCallAddressType aType,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(mModule);
+
+ mModule->ClccResponseCmd(aIndex, aDir, aState, aMode, aMpty, aNumber,
+ aType, aRes);
+}
+
+/* Phone State */
+
+void
+BluetoothDaemonHandsfreeInterface::PhoneStateChange(
+ int aNumActive, int aNumHeld,
+ BluetoothHandsfreeCallState aCallSetupState,
+ const nsAString& aNumber,
+ BluetoothHandsfreeCallAddressType aType,
+ BluetoothHandsfreeResultHandler* aRes)
+{
+ MOZ_ASSERT(mModule);
+
+ mModule->PhoneStateChangeCmd(aNumActive, aNumHeld, aCallSetupState, aNumber,
+ aType, aRes);
+}
+
+void
+BluetoothDaemonHandsfreeInterface::DispatchError(
+ BluetoothHandsfreeResultHandler* aRes, BluetoothStatus aStatus)
+{
+ BluetoothResultRunnable1::Dispatch(
+ aRes, &BluetoothHandsfreeResultHandler::OnError,
+ ConstantInitOp1(aStatus));
+}
+
+END_BLUETOOTH_NAMESPACE
diff --git a/dom/bluetooth2/bluedroid/BluetoothDaemonHandsfreeInterface.h b/dom/bluetooth2/bluedroid/BluetoothDaemonHandsfreeInterface.h
new file mode 100644
index 000000000000..d0938d5b09ee
--- /dev/null
+++ b/dom/bluetooth2/bluedroid/BluetoothDaemonHandsfreeInterface.h
@@ -0,0 +1,412 @@
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+#ifndef mozilla_dom_bluetooth_bluetoothdaemonhandsfreeinterface_h
+#define mozilla_dom_bluetooth_bluetoothdaemonhandsfreeinterface_h
+
+#include "BluetoothDaemonHelpers.h"
+#include "BluetoothInterface.h"
+#include "BluetoothInterfaceHelpers.h"
+
+BEGIN_BLUETOOTH_NAMESPACE
+
+class BluetoothSetupResultHandler;
+
+class BluetoothDaemonHandsfreeModule
+{
+public:
+ enum {
+ SERVICE_ID = 0x05
+ };
+
+ enum {
+ OPCODE_ERROR = 0x00,
+ OPCODE_CONNECT = 0x01,
+ OPCODE_DISCONNECT = 0x02,
+ OPCODE_CONNECT_AUDIO = 0x03,
+ OPCODE_DISCONNECT_AUDIO = 0x04,
+ OPCODE_START_VOICE_RECOGNITION = 0x05,
+ OPCODE_STOP_VOICE_RECOGNITION =0x06,
+ OPCODE_VOLUME_CONTROL = 0x07,
+ OPCODE_DEVICE_STATUS_NOTIFICATION = 0x08,
+ OPCODE_COPS_RESPONSE = 0x09,
+ OPCODE_CIND_RESPONSE = 0x0a,
+ OPCODE_FORMATTED_AT_RESPONSE = 0x0b,
+ OPCODE_AT_RESPONSE = 0x0c,
+ OPCODE_CLCC_RESPONSE = 0x0d,
+ OPCODE_PHONE_STATE_CHANGE = 0x0e
+ };
+
+ virtual nsresult Send(BluetoothDaemonPDU* aPDU, void* aUserData) = 0;
+
+ virtual nsresult RegisterModule(uint8_t aId, uint8_t aMode,
+ BluetoothSetupResultHandler* aRes) = 0;
+
+ virtual nsresult UnregisterModule(uint8_t aId,
+ BluetoothSetupResultHandler* aRes) = 0;
+
+ void SetNotificationHandler(
+ BluetoothHandsfreeNotificationHandler* aNotificationHandler);
+
+ //
+ // Commands
+ //
+
+ nsresult ConnectCmd(const nsAString& aBdAddr,
+ BluetoothHandsfreeResultHandler* aRes);
+ nsresult DisconnectCmd(const nsAString& aBdAddr,
+ BluetoothHandsfreeResultHandler* aRes);
+ nsresult ConnectAudioCmd(const nsAString& aBdAddr,
+ BluetoothHandsfreeResultHandler* aRes);
+ nsresult DisconnectAudioCmd(const nsAString& aBdAddr,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ /* Voice Recognition */
+
+ nsresult StartVoiceRecognitionCmd(BluetoothHandsfreeResultHandler* aRes);
+ nsresult StopVoiceRecognitionCmd(BluetoothHandsfreeResultHandler* aRes);
+
+ /* Volume */
+
+ nsresult VolumeControlCmd(BluetoothHandsfreeVolumeType aType, int aVolume,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ /* Device status */
+
+ nsresult DeviceStatusNotificationCmd(
+ BluetoothHandsfreeNetworkState aNtkState,
+ BluetoothHandsfreeServiceType aSvcType,
+ int aSignal, int aBattChg,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ /* Responses */
+
+ nsresult CopsResponseCmd(const char* aCops,
+ BluetoothHandsfreeResultHandler* aRes);
+ nsresult CindResponseCmd(int aSvc, int aNumActive, int aNumHeld,
+ BluetoothHandsfreeCallState aCallSetupState,
+ int aSignal, int aRoam, int aBattChg,
+ BluetoothHandsfreeResultHandler* aRes);
+ nsresult FormattedAtResponseCmd(const char* aRsp,
+ BluetoothHandsfreeResultHandler* aRes);
+ nsresult AtResponseCmd(BluetoothHandsfreeAtResponse aResponseCode,
+ int aErrorCode,
+ BluetoothHandsfreeResultHandler* aRes);
+ nsresult ClccResponseCmd(int aIndex, BluetoothHandsfreeCallDirection aDir,
+ BluetoothHandsfreeCallState aState,
+ BluetoothHandsfreeCallMode aMode,
+ BluetoothHandsfreeCallMptyType aMpty,
+ const nsAString& aNumber,
+ BluetoothHandsfreeCallAddressType aType,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ /* Phone State */
+
+ nsresult PhoneStateChangeCmd(int aNumActive, int aNumHeld,
+ BluetoothHandsfreeCallState aCallSetupState,
+ const nsAString& aNumber,
+ BluetoothHandsfreeCallAddressType aType,
+ BluetoothHandsfreeResultHandler* aRes);
+
+protected:
+ nsresult Send(BluetoothDaemonPDU* aPDU,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ void HandleSvc(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU, void* aUserData);
+
+ //
+ // Responses
+ //
+
+ typedef BluetoothResultRunnable0
+ ResultRunnable;
+
+ typedef BluetoothResultRunnable1
+ ErrorRunnable;
+
+ void ErrorRsp(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ void ConnectRsp(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ void DisconnectRsp(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ void ConnectAudioRsp(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ void DisconnectAudioRsp(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ void StartVoiceRecognitionRsp(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ void StopVoiceRecognitionRsp(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ void VolumeControlRsp(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ void DeviceStatusNotificationRsp(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ void CopsResponseRsp(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ void CindResponseRsp(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ void FormattedAtResponseRsp(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ void AtResponseRsp(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ void ClccResponseRsp(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ void PhoneStateChangeRsp(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ void HandleRsp(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU,
+ void* aUserData);
+
+ //
+ // Notifications
+ //
+
+ class NotificationHandlerWrapper;
+
+ typedef BluetoothNotificationRunnable2
+ ConnectionStateNotification;
+
+ typedef BluetoothNotificationRunnable2
+ AudioStateNotification;
+
+ typedef BluetoothNotificationRunnable1
+ VoiceRecognitionNotification;
+
+ typedef BluetoothNotificationRunnable0
+ AnswerCallNotification;
+
+ typedef BluetoothNotificationRunnable0
+ HangupCallNotification;
+
+ typedef BluetoothNotificationRunnable2
+ VolumeNotification;
+
+ typedef BluetoothNotificationRunnable1
+ DialCallNotification;
+
+ typedef BluetoothNotificationRunnable1
+ DtmfNotification;
+
+ typedef BluetoothNotificationRunnable1
+ NRECNotification;
+
+ typedef BluetoothNotificationRunnable1
+ CallHoldNotification;
+
+ typedef BluetoothNotificationRunnable0
+ CnumNotification;
+
+ typedef BluetoothNotificationRunnable0
+ CindNotification;
+
+ typedef BluetoothNotificationRunnable0
+ CopsNotification;
+
+ typedef BluetoothNotificationRunnable0
+ ClccNotification;
+
+ typedef BluetoothNotificationRunnable1
+ UnknownAtNotification;
+
+ typedef BluetoothNotificationRunnable0
+ KeyPressedNotification;
+
+ class AudioStateInitOp;
+ class ConnectionStateInitOp;
+ class DialCallInitOp;
+ class VolumeInitOp;
+ class UnknownAtInitOp;
+
+ void ConnectionStateNtf(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU);
+
+ void AudioStateNtf(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU);
+
+ void VoiceRecognitionNtf(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU);
+
+ void AnswerCallNtf(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU);
+
+ void HangupCallNtf(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU);
+
+ void VolumeNtf(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU);
+
+ void DialCallNtf(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU);
+
+ void DtmfNtf(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU);
+
+ void NRECNtf(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU);
+
+ void CallHoldNtf(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU);
+
+ void CnumNtf(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU);
+
+ void CindNtf(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU);
+
+ void CopsNtf(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU);
+
+ void ClccNtf(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU);
+
+ void UnknownAtNtf(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU);
+
+ void KeyPressedNtf(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU);
+
+ void HandleNtf(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU,
+ void* aUserData);
+
+ static BluetoothHandsfreeNotificationHandler* sNotificationHandler;
+};
+
+class BluetoothDaemonHandsfreeInterface MOZ_FINAL
+ : public BluetoothHandsfreeInterface
+{
+ class CleanupResultHandler;
+ class InitResultHandler;
+
+ enum {
+ MODE_HEADSET = 0x00,
+ MODE_NARROWBAND_SPEECH = 0x01,
+ MODE_NARROWBAND_WIDEBAND_SPEECH = 0x02
+ };
+
+public:
+ BluetoothDaemonHandsfreeInterface(BluetoothDaemonHandsfreeModule* aModule);
+ ~BluetoothDaemonHandsfreeInterface();
+
+ void Init(
+ BluetoothHandsfreeNotificationHandler* aNotificationHandler,
+ BluetoothHandsfreeResultHandler* aRes);
+ void Cleanup(BluetoothHandsfreeResultHandler* aRes);
+
+ /* Connect / Disconnect */
+
+ void Connect(const nsAString& aBdAddr,
+ BluetoothHandsfreeResultHandler* aRes);
+ void Disconnect(const nsAString& aBdAddr,
+ BluetoothHandsfreeResultHandler* aRes);
+ void ConnectAudio(const nsAString& aBdAddr,
+ BluetoothHandsfreeResultHandler* aRes);
+ void DisconnectAudio(const nsAString& aBdAddr,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ /* Voice Recognition */
+
+ void StartVoiceRecognition(BluetoothHandsfreeResultHandler* aRes);
+ void StopVoiceRecognition(BluetoothHandsfreeResultHandler* aRes);
+
+ /* Volume */
+
+ void VolumeControl(BluetoothHandsfreeVolumeType aType, int aVolume,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ /* Device status */
+
+ void DeviceStatusNotification(BluetoothHandsfreeNetworkState aNtkState,
+ BluetoothHandsfreeServiceType aSvcType,
+ int aSignal, int aBattChg,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ /* Responses */
+
+ void CopsResponse(const char* aCops,
+ BluetoothHandsfreeResultHandler* aRes);
+ void CindResponse(int aSvc, int aNumActive, int aNumHeld,
+ BluetoothHandsfreeCallState aCallSetupState,
+ int aSignal, int aRoam, int aBattChg,
+ BluetoothHandsfreeResultHandler* aRes);
+ void FormattedAtResponse(const char* aRsp,
+ BluetoothHandsfreeResultHandler* aRes);
+ void AtResponse(BluetoothHandsfreeAtResponse aResponseCode, int aErrorCode,
+ BluetoothHandsfreeResultHandler* aRes);
+ void ClccResponse(int aIndex, BluetoothHandsfreeCallDirection aDir,
+ BluetoothHandsfreeCallState aState,
+ BluetoothHandsfreeCallMode aMode,
+ BluetoothHandsfreeCallMptyType aMpty,
+ const nsAString& aNumber,
+ BluetoothHandsfreeCallAddressType aType,
+ BluetoothHandsfreeResultHandler* aRes);
+
+ /* Phone State */
+
+ void PhoneStateChange(int aNumActive, int aNumHeld,
+ BluetoothHandsfreeCallState aCallSetupState,
+ const nsAString& aNumber,
+ BluetoothHandsfreeCallAddressType aType,
+ BluetoothHandsfreeResultHandler* aRes);
+
+private:
+ void DispatchError(BluetoothHandsfreeResultHandler* aRes,
+ BluetoothStatus aStatus);
+
+ BluetoothDaemonHandsfreeModule* mModule;
+};
+
+END_BLUETOOTH_NAMESPACE
+
+#endif
diff --git a/dom/bluetooth2/bluedroid/BluetoothDaemonHelpers.cpp b/dom/bluetooth2/bluedroid/BluetoothDaemonHelpers.cpp
index b7461991297c..47ddbc5b5882 100644
--- a/dom/bluetooth2/bluedroid/BluetoothDaemonHelpers.cpp
+++ b/dom/bluetooth2/bluedroid/BluetoothDaemonHelpers.cpp
@@ -45,6 +45,18 @@ Convert(bool aIn, BluetoothScanMode& aOut)
return NS_OK;
}
+nsresult
+Convert(int aIn, uint8_t& aOut)
+{
+ if (NS_WARN_IF(aIn < std::numeric_limits::min()) ||
+ NS_WARN_IF(aIn > std::numeric_limits::max())) {
+ aOut = 0; // silences compiler warning
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = static_cast(aIn);
+ return NS_OK;
+}
+
nsresult
Convert(int aIn, int16_t& aOut)
{
@@ -71,6 +83,20 @@ Convert(uint8_t aIn, bool& aOut)
return NS_OK;
}
+nsresult
+Convert(uint8_t aIn, char& aOut)
+{
+ aOut = static_cast(aIn);
+ return NS_OK;
+}
+
+nsresult
+Convert(uint8_t aIn, int& aOut)
+{
+ aOut = static_cast(aIn);
+ return NS_OK;
+}
+
nsresult
Convert(uint8_t aIn, BluetoothAclState& aOut)
{
@@ -100,6 +126,97 @@ Convert(uint8_t aIn, BluetoothBondState& aOut)
return NS_OK;
}
+nsresult
+Convert(uint8_t aIn, BluetoothHandsfreeAudioState& aOut)
+{
+ static const BluetoothHandsfreeAudioState sAudioState[] = {
+ CONVERT(0x00, HFP_AUDIO_STATE_DISCONNECTED),
+ CONVERT(0x01, HFP_AUDIO_STATE_CONNECTING),
+ CONVERT(0x02, HFP_AUDIO_STATE_CONNECTED),
+ CONVERT(0x03, HFP_AUDIO_STATE_DISCONNECTING)
+ };
+ if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sAudioState))) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sAudioState[aIn];
+ return NS_OK;
+}
+
+nsresult
+Convert(uint8_t aIn, BluetoothHandsfreeCallHoldType& aOut)
+{
+ static const BluetoothHandsfreeCallHoldType sCallHoldType[] = {
+ CONVERT(0x00, HFP_CALL_HOLD_RELEASEHELD),
+ CONVERT(0x01, HFP_CALL_HOLD_RELEASEACTIVE_ACCEPTHELD),
+ CONVERT(0x02, HFP_CALL_HOLD_HOLDACTIVE_ACCEPTHELD),
+ CONVERT(0x03, HFP_CALL_HOLD_ADDHELDTOCONF)
+ };
+ if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sCallHoldType))) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sCallHoldType[aIn];
+ return NS_OK;
+}
+
+nsresult
+Convert(uint8_t aIn, BluetoothHandsfreeConnectionState& aOut)
+{
+ static const BluetoothHandsfreeConnectionState sConnectionState[] = {
+ CONVERT(0x00, HFP_CONNECTION_STATE_DISCONNECTED),
+ CONVERT(0x01, HFP_CONNECTION_STATE_CONNECTING),
+ CONVERT(0x02, HFP_CONNECTION_STATE_CONNECTED),
+ CONVERT(0x03, HFP_CONNECTION_STATE_SLC_CONNECTED),
+ CONVERT(0x04, HFP_CONNECTION_STATE_DISCONNECTING)
+ };
+ if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sConnectionState))) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sConnectionState[aIn];
+ return NS_OK;
+}
+
+nsresult
+Convert(uint8_t aIn, BluetoothHandsfreeNRECState& aOut)
+{
+ static const BluetoothHandsfreeNRECState sNRECState[] = {
+ CONVERT(0x00, HFP_NREC_STOPPED),
+ CONVERT(0x01, HFP_NREC_STARTED)
+ };
+ if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sNRECState))) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sNRECState[aIn];
+ return NS_OK;
+}
+
+nsresult
+Convert(uint8_t aIn, BluetoothHandsfreeVoiceRecognitionState& aOut)
+{
+ static const BluetoothHandsfreeVoiceRecognitionState sState[] = {
+ CONVERT(0x00, HFP_VOICE_RECOGNITION_STOPPED),
+ CONVERT(0x01, HFP_VOICE_RECOGNITION_STOPPED)
+ };
+ if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sState))) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sState[aIn];
+ return NS_OK;
+}
+
+nsresult
+Convert(uint8_t aIn, BluetoothHandsfreeVolumeType& aOut)
+{
+ static const BluetoothHandsfreeVolumeType sVolumeType[] = {
+ CONVERT(0x00, HFP_VOLUME_TYPE_SPEAKER),
+ CONVERT(0x01, HFP_VOLUME_TYPE_MICROPHONE)
+ };
+ if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sVolumeType))) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sVolumeType[aIn];
+ return NS_OK;
+}
+
nsresult
Convert(int32_t aIn, BluetoothTypeOfDevice& aOut)
{
@@ -373,6 +490,147 @@ Convert(const BluetoothAddress& aIn, nsAString& aOut)
return NS_OK;
}
+nsresult
+Convert(BluetoothHandsfreeAtResponse aIn, uint8_t& aOut)
+{
+ static const uint8_t sAtResponse[] = {
+ CONVERT(HFP_AT_RESPONSE_ERROR, 0x00),
+ CONVERT(HFP_AT_RESPONSE_OK, 0x01)
+ };
+ if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sAtResponse))) {
+ aOut = 0x00; // silences compiler warning
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sAtResponse[aIn];
+ return NS_OK;
+}
+
+nsresult
+Convert(BluetoothHandsfreeCallAddressType aIn, uint8_t& aOut)
+{
+ static const uint8_t sCallAddressType[] = {
+ CONVERT(HFP_CALL_ADDRESS_TYPE_UNKNOWN, 0x81),
+ CONVERT(HFP_CALL_ADDRESS_TYPE_INTERNATIONAL, 0x91)
+ };
+ if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sCallAddressType))) {
+ aOut = 0x00; // silences compiler warning
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sCallAddressType[aIn];
+ return NS_OK;
+}
+
+nsresult
+Convert(BluetoothHandsfreeCallDirection aIn, uint8_t& aOut)
+{
+ static const uint8_t sCallDirection[] = {
+ CONVERT(HFP_CALL_DIRECTION_OUTGOING, 0x00),
+ CONVERT(HFP_CALL_DIRECTION_INCOMING, 0x01)
+ };
+ if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sCallDirection))) {
+ aOut = 0x00; // silences compiler warning
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sCallDirection[aIn];
+ return NS_OK;
+}
+
+nsresult
+Convert(BluetoothHandsfreeCallState aIn, uint8_t& aOut)
+{
+ static const uint8_t sCallState[] = {
+ CONVERT(HFP_CALL_STATE_ACTIVE, 0x00),
+ CONVERT(HFP_CALL_STATE_HELD, 0x01),
+ CONVERT(HFP_CALL_STATE_DIALING, 0x02),
+ CONVERT(HFP_CALL_STATE_ALERTING, 0x03),
+ CONVERT(HFP_CALL_STATE_INCOMING, 0x04),
+ CONVERT(HFP_CALL_STATE_WAITING, 0x05),
+ CONVERT(HFP_CALL_STATE_IDLE, 0x06)
+ };
+ if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sCallState))) {
+ aOut = 0x00; // silences compiler warning
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sCallState[aIn];
+ return NS_OK;
+}
+
+nsresult
+Convert(BluetoothHandsfreeCallMode aIn, uint8_t& aOut)
+{
+ static const uint8_t sCallMode[] = {
+ CONVERT(HFP_CALL_MODE_VOICE, 0x00),
+ CONVERT(HFP_CALL_MODE_DATA, 0x01),
+ CONVERT(HFP_CALL_MODE_FAX, 0x02)
+ };
+ if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sCallMode))) {
+ aOut = 0x00; // silences compiler warning
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sCallMode[aIn];
+ return NS_OK;
+}
+
+nsresult
+Convert(BluetoothHandsfreeCallMptyType aIn, uint8_t& aOut)
+{
+ static const uint8_t sCallMptyType[] = {
+ CONVERT(HFP_CALL_MPTY_TYPE_SINGLE, 0x00),
+ CONVERT(HFP_CALL_MPTY_TYPE_MULTI, 0x01)
+ };
+ if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sCallMptyType))) {
+ aOut = 0x00; // silences compiler warning
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sCallMptyType[aIn];
+ return NS_OK;
+}
+
+nsresult
+Convert(BluetoothHandsfreeNetworkState aIn, uint8_t& aOut)
+{
+ static const uint8_t sNetworkState[] = {
+ CONVERT(HFP_NETWORK_STATE_NOT_AVAILABLE, 0x00),
+ CONVERT(HFP_NETWORK_STATE_AVAILABLE, 0x01)
+ };
+ if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sNetworkState))) {
+ aOut = 0x00; // silences compiler warning
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sNetworkState[aIn];
+ return NS_OK;
+}
+
+nsresult
+Convert(BluetoothHandsfreeServiceType aIn, uint8_t& aOut)
+{
+ static const uint8_t sServiceType[] = {
+ CONVERT(HFP_SERVICE_TYPE_HOME, 0x00),
+ CONVERT(HFP_SERVICE_TYPE_ROAMING, 0x01)
+ };
+ if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sServiceType))) {
+ aOut = 0x00; // silences compiler warning
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sServiceType[aIn];
+ return NS_OK;
+}
+
+nsresult
+Convert(BluetoothHandsfreeVolumeType aIn, uint8_t& aOut)
+{
+ static const uint8_t sVolumeType[] = {
+ CONVERT(HFP_VOLUME_TYPE_SPEAKER, 0x00),
+ CONVERT(HFP_VOLUME_TYPE_MICROPHONE, 0x01)
+ };
+ if (NS_WARN_IF(aIn >= MOZ_ARRAY_LENGTH(sVolumeType))) {
+ aOut = 0x00; // silences compiler warning
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ aOut = sVolumeType[aIn];
+ return NS_OK;
+}
+
nsresult
Convert(BluetoothPropertyType aIn, uint8_t& aOut)
{
@@ -506,6 +764,69 @@ PackPDU(const BluetoothDaemonPDUHeader& aIn, BluetoothDaemonPDU& aPDU)
return PackPDU(aIn.mService, aIn.mOpcode, aIn.mLength, aPDU);
}
+nsresult
+PackPDU(const BluetoothHandsfreeAtResponse& aIn, BluetoothDaemonPDU& aPDU)
+{
+ return PackPDU(
+ PackConversion(aIn), aPDU);
+}
+
+nsresult
+PackPDU(const BluetoothHandsfreeCallAddressType& aIn, BluetoothDaemonPDU& aPDU)
+{
+ return PackPDU(
+ PackConversion(aIn), aPDU);
+}
+
+nsresult
+PackPDU(const BluetoothHandsfreeCallDirection& aIn, BluetoothDaemonPDU& aPDU)
+{
+ return PackPDU(
+ PackConversion(aIn), aPDU);
+}
+
+nsresult
+PackPDU(const BluetoothHandsfreeCallMode& aIn, BluetoothDaemonPDU& aPDU)
+{
+ return PackPDU(
+ PackConversion(aIn), aPDU);
+}
+
+nsresult
+PackPDU(const BluetoothHandsfreeCallMptyType& aIn, BluetoothDaemonPDU& aPDU)
+{
+ return PackPDU(
+ PackConversion(aIn), aPDU);
+}
+
+nsresult
+PackPDU(const BluetoothHandsfreeCallState& aIn, BluetoothDaemonPDU& aPDU)
+{
+ return PackPDU(
+ PackConversion(aIn), aPDU);
+}
+
+nsresult
+PackPDU(const BluetoothHandsfreeNetworkState& aIn, BluetoothDaemonPDU& aPDU)
+{
+ return PackPDU(
+ PackConversion(aIn), aPDU);
+}
+
+nsresult
+PackPDU(const BluetoothHandsfreeServiceType& aIn, BluetoothDaemonPDU& aPDU)
+{
+ return PackPDU(
+ PackConversion(aIn), aPDU);
+}
+
+nsresult
+PackPDU(const BluetoothHandsfreeVolumeType& aIn, BluetoothDaemonPDU& aPDU)
+{
+ return PackPDU(
+ PackConversion(aIn), aPDU);
+}
+
nsresult
PackPDU(const BluetoothNamedValue& aIn, BluetoothDaemonPDU& aPDU)
{
@@ -591,6 +912,12 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, bool& aOut)
return UnpackPDU(aPDU, UnpackConversion(aOut));
}
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, char& aOut)
+{
+ return UnpackPDU(aPDU, UnpackConversion(aOut));
+}
+
nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAclState& aOut)
{
@@ -610,6 +937,50 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothTypeOfDevice& aOut)
aPDU, UnpackConversion(aOut));
}
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeAudioState& aOut)
+{
+ return UnpackPDU(
+ aPDU, UnpackConversion(aOut));
+}
+
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeCallHoldType& aOut)
+{
+ return UnpackPDU(
+ aPDU, UnpackConversion(aOut));
+}
+
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeConnectionState& aOut)
+{
+ return UnpackPDU(
+ aPDU, UnpackConversion(aOut));
+}
+
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeNRECState& aOut)
+{
+ return UnpackPDU(
+ aPDU, UnpackConversion(aOut));
+}
+
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeVoiceRecognitionState& aOut)
+{
+ return UnpackPDU(
+ aPDU,
+ UnpackConversion(aOut));
+}
+
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeVolumeType& aOut)
+{
+ return UnpackPDU(
+ aPDU, UnpackConversion(aOut));
+}
+
nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothProperty& aOut)
{
@@ -753,4 +1124,64 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothStatus& aOut)
return UnpackPDU(aPDU, UnpackConversion(aOut));
}
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, nsDependentCString& aOut)
+{
+ // We get a pointer to the first character in the PDU, a length
+ // of 1 ensures we consume the \0 byte. With 'str' pointing to
+ // the string in the PDU, we can copy the actual bytes.
+
+ const char* str = reinterpret_cast(aPDU.Consume(1));
+ if (NS_WARN_IF(!str)) {
+ return NS_ERROR_ILLEGAL_VALUE; // end of PDU
+ }
+
+ const char* end = static_cast(memchr(str, '\0', aPDU.GetSize()));
+ if (NS_WARN_IF(!end)) {
+ return NS_ERROR_ILLEGAL_VALUE; // no string terminator
+ }
+
+ ptrdiff_t len = end - str;
+
+ const uint8_t* rest = aPDU.Consume(len);
+ if (NS_WARN_IF(!rest)) {
+ // We couldn't consume bytes that should have been there.
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+
+ aOut.Rebind(str, len);
+
+ return NS_OK;
+}
+
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackCString0& aOut)
+{
+ nsDependentCString cstring;
+
+ nsresult rv = UnpackPDU(aPDU, cstring);
+ if (NS_FAILED(rv)) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+
+ aOut.mString->AssignASCII(cstring.get(), cstring.Length());
+
+ return NS_OK;
+}
+
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackString0& aOut)
+{
+ nsDependentCString cstring;
+
+ nsresult rv = UnpackPDU(aPDU, cstring);
+ if (NS_FAILED(rv)) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+
+ *aOut.mString = NS_ConvertUTF8toUTF16(cstring);
+
+ return NS_OK;
+}
+
END_BLUETOOTH_NAMESPACE
diff --git a/dom/bluetooth2/bluedroid/BluetoothDaemonHelpers.h b/dom/bluetooth2/bluedroid/BluetoothDaemonHelpers.h
index 631c46f13859..c6940f79489a 100644
--- a/dom/bluetooth2/bluedroid/BluetoothDaemonHelpers.h
+++ b/dom/bluetooth2/bluedroid/BluetoothDaemonHelpers.h
@@ -83,18 +83,45 @@ Convert(bool aIn, uint8_t& aOut);
nsresult
Convert(bool aIn, BluetoothScanMode& aOut);
+nsresult
+Convert(int aIn, uint8_t& aOut);
+
nsresult
Convert(int aIn, int16_t& aOut);
nsresult
Convert(uint8_t aIn, bool& aOut);
+nsresult
+Convert(uint8_t aIn, char& aOut);
+
+nsresult
+Convert(uint8_t aIn, int& aOut);
+
nsresult
Convert(uint8_t aIn, BluetoothAclState& aOut);
nsresult
Convert(uint8_t aIn, BluetoothBondState& aOut);
+nsresult
+Convert(uint8_t aIn, BluetoothHandsfreeAudioState& aOut);
+
+nsresult
+Convert(uint8_t aIn, BluetoothHandsfreeCallHoldType& aOut);
+
+nsresult
+Convert(uint8_t aIn, BluetoothHandsfreeConnectionState& aOut);
+
+nsresult
+Convert(uint8_t aIn, BluetoothHandsfreeNRECState& aOut);
+
+nsresult
+Convert(uint8_t aIn, BluetoothHandsfreeVoiceRecognitionState& aOut);
+
+nsresult
+Convert(uint8_t aIn, BluetoothHandsfreeVolumeType& aOut);
+
nsresult
Convert(uint8_t aIn, BluetoothTypeOfDevice& aOut);
@@ -137,6 +164,33 @@ Convert(BluetoothAclState aIn, bool& aOut);
nsresult
Convert(const BluetoothAddress& aIn, nsAString& aOut);
+nsresult
+Convert(BluetoothHandsfreeAtResponse aIn, uint8_t& aOut);
+
+nsresult
+Convert(BluetoothHandsfreeCallAddressType aIn, uint8_t& aOut);
+
+nsresult
+Convert(BluetoothHandsfreeCallDirection aIn, uint8_t& aOut);
+
+nsresult
+Convert(BluetoothHandsfreeCallState aIn, uint8_t& aOut);
+
+nsresult
+Convert(BluetoothHandsfreeCallMode aIn, uint8_t& aOut);
+
+nsresult
+Convert(BluetoothHandsfreeCallMptyType aIn, uint8_t& aOut);
+
+nsresult
+Convert(BluetoothHandsfreeNetworkState aIn, uint8_t& aOut);
+
+nsresult
+Convert(BluetoothHandsfreeServiceType aIn, uint8_t& aOut);
+
+nsresult
+Convert(BluetoothHandsfreeVolumeType aIn, uint8_t& aOut);
+
nsresult
Convert(BluetoothPropertyType aIn, uint8_t& aOut);
@@ -192,6 +246,33 @@ PackPDU(const BluetoothConfigurationParameter& aIn, BluetoothDaemonPDU& aPDU);
nsresult
PackPDU(const BluetoothDaemonPDUHeader& aIn, BluetoothDaemonPDU& aPDU);
+nsresult
+PackPDU(const BluetoothHandsfreeAtResponse& aIn, BluetoothDaemonPDU& aPDU);
+
+nsresult
+PackPDU(const BluetoothHandsfreeCallAddressType& aIn, BluetoothDaemonPDU& aPDU);
+
+nsresult
+PackPDU(const BluetoothHandsfreeCallDirection& aIn, BluetoothDaemonPDU& aPDU);
+
+nsresult
+PackPDU(const BluetoothHandsfreeCallMode& aIn, BluetoothDaemonPDU& aPDU);
+
+nsresult
+PackPDU(const BluetoothHandsfreeCallMptyType& aIn, BluetoothDaemonPDU& aPDU);
+
+nsresult
+PackPDU(const BluetoothHandsfreeCallState& aIn, BluetoothDaemonPDU& aPDU);
+
+nsresult
+PackPDU(const BluetoothHandsfreeNetworkState& aIn, BluetoothDaemonPDU& aPDU);
+
+nsresult
+PackPDU(const BluetoothHandsfreeServiceType& aIn, BluetoothDaemonPDU& aPDU);
+
+nsresult
+PackPDU(const BluetoothHandsfreeVolumeType& aIn, BluetoothDaemonPDU& aPDU);
+
nsresult
PackPDU(const BluetoothNamedValue& aIn, BluetoothDaemonPDU& aPDU);
@@ -279,6 +360,29 @@ PackPDU(const PackArray& aIn, BluetoothDaemonPDU& aPDU)
return aPDU.Write(aIn.mData, aIn.mLength);
}
+/* |PackCString0| is a helper for packing 0-terminated C string,
+ * including the \0 character. Pass an instance of this structure
+ * as the first argument to |PackPDU| to pack a string.
+ */
+struct PackCString0
+{
+ PackCString0(const nsCString& aString)
+ : mString(aString)
+ { }
+
+ const nsCString& mString;
+};
+
+/* This implementation of |PackPDU| packs a 0-terminated C string.
+ */
+inline nsresult
+PackPDU(const PackCString0& aIn, BluetoothDaemonPDU& aPDU)
+{
+ return PackPDU(
+ PackArray(reinterpret_cast(aIn.mString.get()),
+ aIn.mString.Length() + 1), aPDU);
+}
+
template
inline nsresult
PackPDU(const T1& aIn1, const T2& aIn2, BluetoothDaemonPDU& aPDU)
@@ -352,6 +456,41 @@ PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
return PackPDU(aIn5, aPDU);
}
+template
+inline nsresult
+PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3,
+ const T4& aIn4, const T5& aIn5, const T6& aIn6,
+ const T7& aIn7, BluetoothDaemonPDU& aPDU)
+{
+ nsresult rv = PackPDU(aIn1, aPDU);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = PackPDU(aIn2, aPDU);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = PackPDU(aIn3, aPDU);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = PackPDU(aIn4, aPDU);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = PackPDU(aIn5, aPDU);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ rv = PackPDU(aIn6, aPDU);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ return PackPDU(aIn7, aPDU);
+}
+
//
// Unpacking
//
@@ -389,6 +528,9 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, uint32_t& aOut)
nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, bool& aOut);
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, char& aOut);
+
nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothAclState& aOut);
@@ -418,6 +560,25 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothDaemonPDUHeader& aOut)
nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothTypeOfDevice& aOut);
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeAudioState& aOut);
+
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeCallHoldType& aOut);
+
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeConnectionState& aOut);
+
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeNRECState& aOut);
+
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU,
+ BluetoothHandsfreeVoiceRecognitionState& aOut);
+
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothHandsfreeVolumeType& aOut);
+
nsresult
UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothRemoteInfo& aOut);
@@ -451,6 +612,9 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, BluetoothUuid& aOut)
return aPDU.Read(aOut.mUuid, sizeof(aOut.mUuid));
}
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, nsDependentCString& aOut);
+
/* |UnpackConversion| is a helper for convering unpacked values. Pass
* an instance of this structure to |UnpackPDU| to read a value from
* the PDU in the input type and convert it to the output type.
@@ -542,6 +706,44 @@ UnpackPDU(BluetoothDaemonPDU& aPDU, nsTArray& aOut)
return NS_OK;
}
+/* |UnpackCString0| is a helper for unpacking 0-terminated C string,
+ * including the \0 character. Pass an instance of this structure
+ * as the first argument to |UnpackPDU| to unpack a string.
+ */
+struct UnpackCString0
+{
+ UnpackCString0(nsCString& aString)
+ : mString(&aString)
+ { }
+
+ nsCString* mString; // non-null by construction
+};
+
+/* This implementation of |UnpackPDU| unpacks a 0-terminated C string.
+ */
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackCString0& aOut);
+
+/* |UnpackString0| is a helper for unpacking 0-terminated C string,
+ * including the \0 character. Pass an instance of this structure
+ * as the first argument to |UnpackPDU| to unpack a C string and convert
+ * it to wide-character encoding.
+ */
+struct UnpackString0
+{
+ UnpackString0(nsString& aString)
+ : mString(&aString)
+ { }
+
+ nsString* mString; // non-null by construction
+};
+
+/* This implementation of |UnpackPDU| unpacks a 0-terminated C string
+ * and converts it to wide-character encoding.
+ */
+nsresult
+UnpackPDU(BluetoothDaemonPDU& aPDU, const UnpackString0& aOut);
+
//
// Init operators
//
diff --git a/dom/bluetooth2/bluedroid/BluetoothDaemonInterface.cpp b/dom/bluetooth2/bluedroid/BluetoothDaemonInterface.cpp
index 3949f5e4027e..cbb8e35fc2b2 100644
--- a/dom/bluetooth2/bluedroid/BluetoothDaemonInterface.cpp
+++ b/dom/bluetooth2/bluedroid/BluetoothDaemonInterface.cpp
@@ -5,6 +5,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BluetoothDaemonInterface.h"
+#include "BluetoothDaemonHandsfreeInterface.h"
#include "BluetoothDaemonHelpers.h"
#include "BluetoothDaemonSetupInterface.h"
#include "BluetoothDaemonSocketInterface.h"
@@ -1456,10 +1457,17 @@ class BluetoothDaemonProtocol MOZ_FINAL
, public BluetoothDaemonSetupModule
, public BluetoothDaemonCoreModule
, public BluetoothDaemonSocketModule
+ , public BluetoothDaemonHandsfreeModule
{
public:
BluetoothDaemonProtocol(BluetoothDaemonConnection* aConnection);
+ nsresult RegisterModule(uint8_t aId, uint8_t aMode,
+ BluetoothSetupResultHandler* aRes) MOZ_OVERRIDE;
+
+ nsresult UnregisterModule(uint8_t aId,
+ BluetoothSetupResultHandler* aRes) MOZ_OVERRIDE;
+
// Outgoing PDUs
//
@@ -1481,6 +1489,8 @@ private:
BluetoothDaemonPDU& aPDU, void* aUserData);
void HandleSocketSvc(const BluetoothDaemonPDUHeader& aHeader,
BluetoothDaemonPDU& aPDU, void* aUserData);
+ void HandleHandsfreeSvc(const BluetoothDaemonPDUHeader& aHeader,
+ BluetoothDaemonPDU& aPDU, void* aUserData);
BluetoothDaemonConnection* mConnection;
nsTArray mUserDataQ;
@@ -1493,6 +1503,20 @@ BluetoothDaemonProtocol::BluetoothDaemonProtocol(
MOZ_ASSERT(mConnection);
}
+nsresult
+BluetoothDaemonProtocol::RegisterModule(uint8_t aId, uint8_t aMode,
+ BluetoothSetupResultHandler* aRes)
+{
+ return BluetoothDaemonSetupModule::RegisterModuleCmd(aId, aMode, aRes);
+}
+
+nsresult
+BluetoothDaemonProtocol::UnregisterModule(uint8_t aId,
+ BluetoothSetupResultHandler* aRes)
+{
+ return BluetoothDaemonSetupModule::UnregisterModuleCmd(aId, aRes);
+}
+
nsresult
BluetoothDaemonProtocol::Send(BluetoothDaemonPDU* aPDU, void* aUserData)
{
@@ -1527,6 +1551,14 @@ BluetoothDaemonProtocol::HandleSocketSvc(
BluetoothDaemonSocketModule::HandleSvc(aHeader, aPDU, aUserData);
}
+void
+BluetoothDaemonProtocol::HandleHandsfreeSvc(
+ const BluetoothDaemonPDUHeader& aHeader, BluetoothDaemonPDU& aPDU,
+ void* aUserData)
+{
+ BluetoothDaemonHandsfreeModule::HandleSvc(aHeader, aPDU, aUserData);
+}
+
void
BluetoothDaemonProtocol::Handle(BluetoothDaemonPDU& aPDU)
{
@@ -1537,7 +1569,11 @@ BluetoothDaemonProtocol::Handle(BluetoothDaemonPDU& aPDU)
INIT_ARRAY_AT(BluetoothDaemonCoreModule::SERVICE_ID,
&BluetoothDaemonProtocol::HandleCoreSvc),
INIT_ARRAY_AT(BluetoothDaemonSocketModule::SERVICE_ID,
- &BluetoothDaemonProtocol::HandleSocketSvc)
+ &BluetoothDaemonProtocol::HandleSocketSvc),
+ INIT_ARRAY_AT(0x03, nullptr), // HID host
+ INIT_ARRAY_AT(0x04, nullptr), // PAN
+ INIT_ARRAY_AT(BluetoothDaemonHandsfreeModule::SERVICE_ID,
+ &BluetoothDaemonProtocol::HandleHandsfreeSvc)
};
BluetoothDaemonPDUHeader header;
@@ -2110,7 +2146,13 @@ BluetoothDaemonInterface::GetBluetoothSocketInterface()
BluetoothHandsfreeInterface*
BluetoothDaemonInterface::GetBluetoothHandsfreeInterface()
{
- return nullptr;
+ if (mHandsfreeInterface) {
+ return mHandsfreeInterface;
+ }
+
+ mHandsfreeInterface = new BluetoothDaemonHandsfreeInterface(mProtocol);
+
+ return mHandsfreeInterface;
}
BluetoothA2dpInterface*
diff --git a/dom/bluetooth2/bluedroid/BluetoothDaemonInterface.h b/dom/bluetooth2/bluedroid/BluetoothDaemonInterface.h
index 31513fe92baf..0fca73667672 100644
--- a/dom/bluetooth2/bluedroid/BluetoothDaemonInterface.h
+++ b/dom/bluetooth2/bluedroid/BluetoothDaemonInterface.h
@@ -12,6 +12,7 @@
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothDaemonChannel;
+class BluetoothDaemonHandsfreeInterface;
class BluetoothDaemonProtocol;
class BluetoothDaemonSocketInterface;
@@ -126,6 +127,7 @@ private:
nsTArray > mResultHandlerQ;
nsAutoPtr mSocketInterface;
+ nsAutoPtr mHandsfreeInterface;
};
END_BLUETOOTH_NAMESPACE
diff --git a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp
index 2b736c2cd5ff..c734833400b3 100644
--- a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp
+++ b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp
@@ -76,146 +76,12 @@ static nsTArray > sFetchUuidsRunnableArray;
static nsTArray > sBondingRunnableArray;
static nsTArray > sUnbondingRunnableArray;
-/**
- * Classes only used in this file
- */
-
-class SetupAfterEnabledTask MOZ_FINAL : public nsRunnable
-{
-public:
- class SetAdapterPropertyResultHandler MOZ_FINAL
- : public BluetoothResultHandler
- {
- public:
- void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
- {
- BT_LOGR("Fail to set: BT_SCAN_MODE_CONNECTABLE");
- }
- };
-
- NS_IMETHOD
- Run()
- {
- MOZ_ASSERT(NS_IsMainThread());
-
- // Bluetooth just enabled, clear profile controllers and runnable arrays.
- sControllerArray.Clear();
- sChangeDiscoveryRunnableArray.Clear();
- sSetPropertyRunnableArray.Clear();
- sGetDeviceRunnableArray.Clear();
- sFetchUuidsRunnableArray.Clear();
- sBondingRunnableArray.Clear();
- sUnbondingRunnableArray.Clear();
-
- // Bluetooth scan mode is SCAN_MODE_CONNECTABLE by default, i.e., It should
- // be connectable and non-discoverable.
- NS_ENSURE_TRUE(sBtInterface, NS_ERROR_FAILURE);
- sBtInterface->SetAdapterProperty(
- BluetoothNamedValue(NS_ConvertUTF8toUTF16("Discoverable"), false),
- new SetAdapterPropertyResultHandler());
-
- // Trigger BluetoothOppManager to listen
- BluetoothOppManager* opp = BluetoothOppManager::Get();
- if (!opp || !opp->Listen()) {
- BT_LOGR("Fail to start BluetoothOppManager listening");
- }
-
- return NS_OK;
- }
-};
-
-/* |ProfileDeinitResultHandler| collects the results of all profile
- * result handlers and calls |Proceed| after all results handlers
- * have been run.
- */
-class ProfileDeinitResultHandler MOZ_FINAL
-: public BluetoothProfileResultHandler
-{
-public:
- ProfileDeinitResultHandler(unsigned char aNumProfiles)
- : mNumProfiles(aNumProfiles)
- {
- MOZ_ASSERT(mNumProfiles);
- }
-
- void Deinit() MOZ_OVERRIDE
- {
- if (!(--mNumProfiles)) {
- Proceed();
- }
- }
-
- void OnError(nsresult aResult) MOZ_OVERRIDE
- {
- if (!(--mNumProfiles)) {
- Proceed();
- }
- }
-
-private:
- void Proceed() const
- {
- sBtInterface->Cleanup(nullptr);
- }
-
- unsigned char mNumProfiles;
-};
-
-class CleanupTask MOZ_FINAL : public nsRunnable
-{
-public:
- NS_IMETHOD
- Run()
- {
- static void (* const sDeinitManager[])(BluetoothProfileResultHandler*) = {
- BluetoothHfpManager::DeinitHfpInterface,
- BluetoothA2dpManager::DeinitA2dpInterface,
- BluetoothGattManager::DeinitGattInterface
- };
-
- MOZ_ASSERT(NS_IsMainThread());
-
- // Return error if BluetoothService is unavailable
- BluetoothService* bs = BluetoothService::Get();
- NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
-
- // Cleanup static adapter properties and notify adapter.
- sAdapterBdAddress.Truncate();
- sAdapterBdName.Truncate();
-
- InfallibleTArray props;
- BT_APPEND_NAMED_VALUE(props, "Name", sAdapterBdName);
- BT_APPEND_NAMED_VALUE(props, "Address", sAdapterBdAddress);
- if (sAdapterDiscoverable) {
- sAdapterDiscoverable = false;
- BT_APPEND_NAMED_VALUE(props, "Discoverable", false);
- }
- if (sAdapterDiscovering) {
- sAdapterDiscovering = false;
- BT_APPEND_NAMED_VALUE(props, "Discovering", false);
- }
-
- BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"),
- NS_LITERAL_STRING(KEY_ADAPTER), props);
- bs->DistributeSignal(signal);
-
- // Cleanup bluetooth interfaces after BT state becomes BT_STATE_OFF.
- nsRefPtr res =
- new ProfileDeinitResultHandler(MOZ_ARRAY_LENGTH(sDeinitManager));
-
- for (size_t i = 0; i < MOZ_ARRAY_LENGTH(sDeinitManager); ++i) {
- sDeinitManager[i](res);
- }
-
- return NS_OK;
- }
-};
-
/**
* Static callback functions
*/
-static ControlPlayStatus
-PlayStatusStringToControlPlayStatus(const nsAString& aPlayStatus)
+ControlPlayStatus
+BluetoothServiceBluedroid::PlayStatusStringToControlPlayStatus(
+ const nsAString& aPlayStatus)
{
ControlPlayStatus playStatus = ControlPlayStatus::PLAYSTATUS_UNKNOWN;
if (aPlayStatus.EqualsLiteral("STOPPED")) {
@@ -238,8 +104,8 @@ PlayStatusStringToControlPlayStatus(const nsAString& aPlayStatus)
/**
* Static functions
*/
-static bool
-EnsureBluetoothHalLoad()
+bool
+BluetoothServiceBluedroid::EnsureBluetoothHalLoad()
{
sBtInterface = BluetoothInterface::GetInstance();
NS_ENSURE_TRUE(sBtInterface, false);
@@ -247,7 +113,8 @@ EnsureBluetoothHalLoad()
return true;
}
-class EnableResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::EnableResultHandler MOZ_FINAL
+ : public BluetoothResultHandler
{
public:
void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
@@ -256,10 +123,7 @@ public:
BT_LOGR("BluetoothInterface::Enable failed: %d", aStatus);
- nsRefPtr runnable = new BluetoothService::ToggleBtAck(false);
- if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
- BT_WARNING("Failed to dispatch to main thread!");
- }
+ BluetoothService::AcknowledgeToggleBt(false);
}
};
@@ -267,12 +131,12 @@ public:
* result handlers and calls |Proceed| after all results handlers
* have been run.
*/
-class ProfileInitResultHandler MOZ_FINAL
-: public BluetoothProfileResultHandler
+class BluetoothServiceBluedroid::ProfileInitResultHandler MOZ_FINAL
+ : public BluetoothProfileResultHandler
{
public:
ProfileInitResultHandler(unsigned char aNumProfiles)
- : mNumProfiles(aNumProfiles)
+ : mNumProfiles(aNumProfiles)
{
MOZ_ASSERT(mNumProfiles);
}
@@ -300,7 +164,8 @@ private:
unsigned char mNumProfiles;
};
-class InitResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::InitResultHandler MOZ_FINAL
+ : public BluetoothResultHandler
{
public:
void Init() MOZ_OVERRIDE
@@ -332,15 +197,12 @@ public:
sBtInterface = nullptr;
- nsRefPtr runnable = new BluetoothService::ToggleBtAck(false);
- if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
- BT_WARNING("Failed to dispatch to main thread!");
- }
+ BluetoothService::AcknowledgeToggleBt(false);
}
};
-static nsresult
-StartGonkBluetooth()
+nsresult
+BluetoothServiceBluedroid::StartGonkBluetooth()
{
MOZ_ASSERT(NS_IsMainThread());
@@ -351,10 +213,7 @@ StartGonkBluetooth()
if (bs->IsEnabled()) {
// Keep current enable status
- nsRefPtr runnable = new BluetoothService::ToggleBtAck(true);
- if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
- BT_WARNING("Failed to dispatch to main thread!");
- }
+ BluetoothService::AcknowledgeToggleBt(true);
return NS_OK;
}
@@ -364,7 +223,8 @@ StartGonkBluetooth()
return NS_OK;
}
-class DisableResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::DisableResultHandler MOZ_FINAL
+ : public BluetoothResultHandler
{
public:
void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
@@ -373,15 +233,12 @@ public:
BT_LOGR("BluetoothInterface::Disable failed: %d", aStatus);
- nsRefPtr runnable = new BluetoothService::ToggleBtAck(true);
- if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
- BT_WARNING("Failed to dispatch to main thread!");
- }
+ BluetoothService::AcknowledgeToggleBt(true);
}
};
-static nsresult
-StopGonkBluetooth()
+nsresult
+BluetoothServiceBluedroid::StopGonkBluetooth()
{
MOZ_ASSERT(NS_IsMainThread());
@@ -392,10 +249,7 @@ StopGonkBluetooth()
if (!bs->IsEnabled()) {
// Keep current enable status
- nsRefPtr runnable = new BluetoothService::ToggleBtAck(false);
- if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
- BT_WARNING("Failed to dispatch to main thread!");
- }
+ BluetoothService::AcknowledgeToggleBt(false);
return NS_OK;
}
@@ -404,9 +258,10 @@ StopGonkBluetooth()
return NS_OK;
}
-static void
-ReplyStatusError(BluetoothReplyRunnable* aBluetoothReplyRunnable,
- BluetoothStatus aStatusCode, const nsAString& aCustomMsg)
+void
+BluetoothServiceBluedroid::ReplyStatusError(
+ BluetoothReplyRunnable* aBluetoothReplyRunnable,
+ BluetoothStatus aStatusCode, const nsAString& aCustomMsg)
{
MOZ_ASSERT(aBluetoothReplyRunnable, "Reply runnable is nullptr");
@@ -460,12 +315,7 @@ BluetoothServiceBluedroid::StartInternal(BluetoothReplyRunnable* aRunnable)
nsresult ret = StartGonkBluetooth();
if (NS_FAILED(ret)) {
- nsRefPtr runnable =
- new BluetoothService::ToggleBtAck(false);
-
- if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
- BT_WARNING("Failed to dispatch to main thread!");
- }
+ BluetoothService::AcknowledgeToggleBt(false);
// Reject Promise
if(aRunnable) {
@@ -492,12 +342,7 @@ BluetoothServiceBluedroid::StopInternal(BluetoothReplyRunnable* aRunnable)
nsresult ret = StopGonkBluetooth();
if (NS_FAILED(ret)) {
- nsRefPtr runnable =
- new BluetoothService::ToggleBtAck(true);
-
- if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
- BT_WARNING("Failed to dispatch to main thread!");
- }
+ BluetoothService::AcknowledgeToggleBt(true);
// Reject Promise
if(aRunnable) {
@@ -554,8 +399,9 @@ BluetoothServiceBluedroid::GetAdaptersInternal(
return NS_OK;
}
-class GetRemoteDevicePropertiesResultHandler MOZ_FINAL
-: public BluetoothResultHandler
+class BluetoothServiceBluedroid::GetRemoteDevicePropertiesResultHandler
+ MOZ_FINAL
+ : public BluetoothResultHandler
{
public:
GetRemoteDevicePropertiesResultHandler(const nsAString& aDeviceAddress)
@@ -653,7 +499,8 @@ BluetoothServiceBluedroid::GetPairedDevicePropertiesInternal(
return NS_OK;
}
-class StartDiscoveryResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::StartDiscoveryResultHandler MOZ_FINAL
+ : public BluetoothResultHandler
{
public:
StartDiscoveryResultHandler(BluetoothReplyRunnable* aRunnable)
@@ -685,7 +532,8 @@ BluetoothServiceBluedroid::StartDiscoveryInternal(
return NS_OK;
}
-class CancelDiscoveryResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::CancelDiscoveryResultHandler MOZ_FINAL
+ : public BluetoothResultHandler
{
public:
CancelDiscoveryResultHandler(BluetoothReplyRunnable* aRunnable)
@@ -717,7 +565,8 @@ BluetoothServiceBluedroid::StopDiscoveryInternal(
return NS_OK;
}
-class GetRemoteServicesResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::GetRemoteServicesResultHandler MOZ_FINAL
+ : public BluetoothResultHandler
{
public:
GetRemoteServicesResultHandler(BluetoothReplyRunnable* aRunnable)
@@ -759,7 +608,8 @@ BluetoothServiceBluedroid::FetchUuidsInternal(
return NS_OK;
}
-class SetAdapterPropertyResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::SetAdapterPropertyResultHandler MOZ_FINAL
+ : public BluetoothResultHandler
{
public:
SetAdapterPropertyResultHandler(BluetoothReplyRunnable* aRunnable)
@@ -810,7 +660,8 @@ BluetoothServiceBluedroid::UpdateSdpRecords(
return true;
}
-class CreateBondResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::CreateBondResultHandler MOZ_FINAL
+ : public BluetoothResultHandler
{
public:
CreateBondResultHandler(BluetoothReplyRunnable* aRunnable)
@@ -845,7 +696,8 @@ BluetoothServiceBluedroid::CreatePairedDeviceInternal(
return NS_OK;
}
-class RemoveBondResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::RemoveBondResultHandler MOZ_FINAL
+ : public BluetoothResultHandler
{
public:
RemoveBondResultHandler(BluetoothReplyRunnable* aRunnable)
@@ -880,7 +732,8 @@ BluetoothServiceBluedroid::RemoveDeviceInternal(
return NS_OK;
}
-class PinReplyResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::PinReplyResultHandler MOZ_FINAL
+ : public BluetoothResultHandler
{
public:
PinReplyResultHandler(BluetoothReplyRunnable* aRunnable)
@@ -922,7 +775,8 @@ BluetoothServiceBluedroid::SetPasskeyInternal(
return;
}
-class SspReplyResultHandler MOZ_FINAL : public BluetoothResultHandler
+class BluetoothServiceBluedroid::SspReplyResultHandler MOZ_FINAL
+ : public BluetoothResultHandler
{
public:
SspReplyResultHandler(BluetoothReplyRunnable* aRunnable)
@@ -958,8 +812,8 @@ BluetoothServiceBluedroid::SetPairingConfirmationInternal(
aConfirm, 0, new SspReplyResultHandler(aRunnable));
}
-static void
-NextBluetoothProfileController()
+void
+BluetoothServiceBluedroid::NextBluetoothProfileController()
{
MOZ_ASSERT(NS_IsMainThread());
@@ -973,10 +827,11 @@ NextBluetoothProfileController()
}
}
-static void
-ConnectDisconnect(bool aConnect, const nsAString& aDeviceAddress,
- BluetoothReplyRunnable* aRunnable,
- uint16_t aServiceUuid, uint32_t aCod = 0)
+void
+BluetoothServiceBluedroid::ConnectDisconnect(
+ bool aConnect, const nsAString& aDeviceAddress,
+ BluetoothReplyRunnable* aRunnable,
+ uint16_t aServiceUuid, uint32_t aCod)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aRunnable);
@@ -1220,6 +1075,54 @@ BluetoothServiceBluedroid::ToggleCalls(BluetoothReplyRunnable* aRunnable)
// Bluetooth notifications
//
+/* |ProfileDeinitResultHandler| collects the results of all profile
+ * result handlers and calls |Proceed| after all results handlers
+ * have been run.
+ */
+class BluetoothServiceBluedroid::ProfileDeinitResultHandler MOZ_FINAL
+ : public BluetoothProfileResultHandler
+{
+public:
+ ProfileDeinitResultHandler(unsigned char aNumProfiles)
+ : mNumProfiles(aNumProfiles)
+ {
+ MOZ_ASSERT(mNumProfiles);
+ }
+
+ void Deinit() MOZ_OVERRIDE
+ {
+ if (!(--mNumProfiles)) {
+ Proceed();
+ }
+ }
+
+ void OnError(nsresult aResult) MOZ_OVERRIDE
+ {
+ if (!(--mNumProfiles)) {
+ Proceed();
+ }
+ }
+
+private:
+ void Proceed() const
+ {
+ sBtInterface->Cleanup(nullptr);
+ }
+
+ unsigned char mNumProfiles;
+};
+
+class BluetoothServiceBluedroid::SetAdapterPropertyDiscoverableResultHandler
+ MOZ_FINAL
+ : public BluetoothResultHandler
+{
+public:
+ void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
+ {
+ BT_LOGR("Fail to set: BT_SCAN_MODE_CONNECTABLE");
+ }
+};
+
void
BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState)
{
@@ -1229,23 +1132,70 @@ BluetoothServiceBluedroid::AdapterStateChangedNotification(bool aState)
sAdapterEnabled = aState;
- if (!sAdapterEnabled &&
- NS_FAILED(NS_DispatchToMainThread(new CleanupTask()))) {
- BT_WARNING("Failed to dispatch to main thread!");
- return;
+ if (!sAdapterEnabled) {
+ static void (* const sDeinitManager[])(BluetoothProfileResultHandler*) = {
+ BluetoothHfpManager::DeinitHfpInterface,
+ BluetoothA2dpManager::DeinitA2dpInterface,
+ BluetoothGattManager::DeinitGattInterface
+ };
+
+ // Return error if BluetoothService is unavailable
+ BluetoothService* bs = BluetoothService::Get();
+ NS_ENSURE_TRUE_VOID(bs);
+
+ // Cleanup static adapter properties and notify adapter.
+ sAdapterBdAddress.Truncate();
+ sAdapterBdName.Truncate();
+
+ InfallibleTArray props;
+ BT_APPEND_NAMED_VALUE(props, "Name", sAdapterBdName);
+ BT_APPEND_NAMED_VALUE(props, "Address", sAdapterBdAddress);
+ if (sAdapterDiscoverable) {
+ sAdapterDiscoverable = false;
+ BT_APPEND_NAMED_VALUE(props, "Discoverable", false);
+ }
+ if (sAdapterDiscovering) {
+ sAdapterDiscovering = false;
+ BT_APPEND_NAMED_VALUE(props, "Discovering", false);
+ }
+
+ BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"),
+ NS_LITERAL_STRING(KEY_ADAPTER), props);
+ bs->DistributeSignal(signal);
+
+ // Cleanup bluetooth interfaces after BT state becomes BT_STATE_OFF.
+ nsRefPtr res =
+ new ProfileDeinitResultHandler(MOZ_ARRAY_LENGTH(sDeinitManager));
+
+ for (size_t i = 0; i < MOZ_ARRAY_LENGTH(sDeinitManager); ++i) {
+ sDeinitManager[i](res);
+ }
}
- nsRefPtr runnable =
- new BluetoothService::ToggleBtAck(sAdapterEnabled);
- if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
- BT_WARNING("Failed to dispatch to main thread!");
- return;
- }
+ BluetoothService::AcknowledgeToggleBt(sAdapterEnabled);
- if (sAdapterEnabled &&
- NS_FAILED(NS_DispatchToMainThread(new SetupAfterEnabledTask()))) {
- BT_WARNING("Failed to dispatch to main thread!");
- return;
+ if (sAdapterEnabled) {
+ // Bluetooth just enabled, clear profile controllers and runnable arrays.
+ sControllerArray.Clear();
+ sChangeDiscoveryRunnableArray.Clear();
+ sSetPropertyRunnableArray.Clear();
+ sGetDeviceRunnableArray.Clear();
+ sFetchUuidsRunnableArray.Clear();
+ sBondingRunnableArray.Clear();
+ sUnbondingRunnableArray.Clear();
+
+ // Bluetooth scan mode is SCAN_MODE_CONNECTABLE by default, i.e., It should
+ // be connectable and non-discoverable.
+ NS_ENSURE_TRUE_VOID(sBtInterface);
+ sBtInterface->SetAdapterProperty(
+ BluetoothNamedValue(NS_ConvertUTF8toUTF16("Discoverable"), false),
+ new SetAdapterPropertyDiscoverableResultHandler());
+
+ // Trigger BluetoothOppManager to listen
+ BluetoothOppManager* opp = BluetoothOppManager::Get();
+ if (!opp || !opp->Listen()) {
+ BT_LOGR("Fail to start BluetoothOppManager listening");
+ }
}
// Resolve promise if existed
diff --git a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.h b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.h
index 06db64227fea..bd6b86453516 100644
--- a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.h
+++ b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.h
@@ -16,6 +16,22 @@ BEGIN_BLUETOOTH_NAMESPACE
class BluetoothServiceBluedroid : public BluetoothService
, public BluetoothNotificationHandler
{
+ class CancelDiscoveryResultHandler;
+ class CreateBondResultHandler;
+ class DisableResultHandler;
+ class EnableResultHandler;
+ class GetRemoteDevicePropertiesResultHandler;
+ class GetRemoteServicesResultHandler;
+ class InitResultHandler;
+ class PinReplyResultHandler;
+ class ProfileDeinitResultHandler;
+ class ProfileInitResultHandler;
+ class RemoveBondResultHandler;
+ class SetAdapterPropertyDiscoverableResultHandler;
+ class SetAdapterPropertyResultHandler;
+ class SspReplyResultHandler;
+ class StartDiscoveryResultHandler;
+
public:
BluetoothServiceBluedroid();
~BluetoothServiceBluedroid();
@@ -193,6 +209,22 @@ public:
uint8_t aLen) MOZ_OVERRIDE;
virtual void LeTestModeNotification(BluetoothStatus aStatus,
uint16_t aNumPackets) MOZ_OVERRIDE;
+
+protected:
+ static nsresult StartGonkBluetooth();
+ static nsresult StopGonkBluetooth();
+ static bool EnsureBluetoothHalLoad();
+
+ static void ConnectDisconnect(bool aConnect,
+ const nsAString& aDeviceAddress,
+ BluetoothReplyRunnable* aRunnable,
+ uint16_t aServiceUuid, uint32_t aCod = 0);
+ static void NextBluetoothProfileController();
+ static ControlPlayStatus PlayStatusStringToControlPlayStatus(
+ const nsAString& aPlayStatus);
+ static void ReplyStatusError(BluetoothReplyRunnable* aReplyRunnable,
+ BluetoothStatus aStatusCode,
+ const nsAString& aCustomMsg);
};
END_BLUETOOTH_NAMESPACE
diff --git a/dom/bluetooth2/moz.build b/dom/bluetooth2/moz.build
index fa7732b68786..f97a1aa96501 100644
--- a/dom/bluetooth2/moz.build
+++ b/dom/bluetooth2/moz.build
@@ -51,6 +51,7 @@ if CONFIG['MOZ_B2G_BT']:
'bluedroid/BluetoothA2dpHALInterface.cpp',
'bluedroid/BluetoothA2dpManager.cpp',
'bluedroid/BluetoothAvrcpHALInterface.cpp',
+ 'bluedroid/BluetoothDaemonHandsfreeInterface.cpp',
'bluedroid/BluetoothDaemonHelpers.cpp',
'bluedroid/BluetoothDaemonInterface.cpp',
'bluedroid/BluetoothDaemonSetupInterface.cpp',
diff --git a/dom/media/omx/OmxDecoder.cpp b/dom/media/omx/OmxDecoder.cpp
index 5fbd3160d0e4..f0fb361c228a 100644
--- a/dom/media/omx/OmxDecoder.cpp
+++ b/dom/media/omx/OmxDecoder.cpp
@@ -574,12 +574,16 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
while (findNextBuffer) {
options.setSeekTo(aTimeUs, seekMode);
findNextBuffer = false;
- err = mVideoSource->read(&mVideoBuffer, &options);
- {
+ if (mIsVideoSeeking) {
+ err = mVideoSource->read(&mVideoBuffer, &options);
Mutex::Autolock autoLock(mSeekLock);
mIsVideoSeeking = false;
PostReleaseVideoBuffer(nullptr, FenceHandle());
}
+ else {
+ err = mVideoSource->read(&mVideoBuffer);
+ }
+
// If there is no next Keyframe, jump to the previous key frame.
if (err == ERROR_END_OF_STREAM && seekMode == MediaSource::ReadOptions::SEEK_NEXT_SYNC) {
seekMode = MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC;
@@ -593,13 +597,11 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
ALOG("Unexpected error when seeking to %lld", aTimeUs);
break;
}
+ // For some codecs, the length of first decoded frame after seek is 0.
+ // Need to ignore it and continue to find the next one
if (mVideoBuffer->range_length() == 0) {
ReleaseVideoBuffer();
findNextBuffer = true;
- {
- Mutex::Autolock autoLock(mSeekLock);
- mIsVideoSeeking = true;
- }
}
}
aDoSeek = false;
diff --git a/dom/system/gonk/NetworkManager.js b/dom/system/gonk/NetworkManager.js
index a499ff7fbf7f..e6dd6171a814 100644
--- a/dom/system/gonk/NetworkManager.js
+++ b/dom/system/gonk/NetworkManager.js
@@ -997,7 +997,7 @@ NetworkManager.prototype = {
} else {
let mobile = this.getNetworkInterface(
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE, this._dataDefaultServiceId);
- if (mobile) {
+ if (mobile && mobile.name) {
this._tetheringInterface[TETHERING_TYPE_USB].externalInterface = mobile.name;
}
}
@@ -1142,7 +1142,7 @@ NetworkManager.prototype = {
let mobile = this.getNetworkInterface(
Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE, this._dataDefaultServiceId);
// Update the real interface name
- if (mobile) {
+ if (mobile && mobile.name) {
this._tetheringInterface[TETHERING_TYPE_WIFI].externalInterface = mobile.name;
}
diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp
index 1dd1dcd4c176..448ff697d72e 100644
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -2335,7 +2335,11 @@ bool AsyncPanZoomController::SnapBackIfOverscrolled() {
bool AsyncPanZoomController::IsMovingFast() const {
ReentrantMonitorAutoEnter lock(mMonitor);
- return (GetVelocityVector().Length() > gfxPrefs::APZFlingStopOnTapThreshold());
+ if (GetVelocityVector().Length() > gfxPrefs::APZFlingStopOnTapThreshold()) {
+ APZC_LOG("%p is moving fast\n", this);
+ return true;
+ }
+ return false;
}
bool AsyncPanZoomController::IsPannable() const {
diff --git a/gfx/layers/apz/src/Axis.cpp b/gfx/layers/apz/src/Axis.cpp
index d87680ee0cfc..65378e668cbc 100644
--- a/gfx/layers/apz/src/Axis.cpp
+++ b/gfx/layers/apz/src/Axis.cpp
@@ -83,7 +83,8 @@ void Axis::UpdateWithTouchAtDevicePoint(ParentLayerCoord aPos, uint32_t aTimesta
float funcInput = (newVelocity - curveThreshold) / scale;
float funcOutput = gVelocityCurveFunction->GetValue(funcInput);
float curvedVelocity = (funcOutput * scale) + curveThreshold;
- AXIS_LOG("Curving up velocity from %f to %f\n", newVelocity, curvedVelocity);
+ AXIS_LOG("%p|%s curving up velocity from %f to %f\n",
+ mAsyncPanZoomController, Name(), newVelocity, curvedVelocity);
newVelocity = curvedVelocity;
}
}
@@ -93,6 +94,8 @@ void Axis::UpdateWithTouchAtDevicePoint(ParentLayerCoord aPos, uint32_t aTimesta
}
}
+ AXIS_LOG("%p|%s updating velocity to %f with touch\n",
+ mAsyncPanZoomController, Name(), newVelocity);
mVelocity = newVelocity;
mPos = aPos;
mPosTimeMs = aTimestampMs;
@@ -139,6 +142,8 @@ bool Axis::AdjustDisplacement(ParentLayerCoord aDisplacement,
if (aOverscrollAmountOut != 0.0f) {
// No need to have a velocity along this axis anymore; it won't take us
// anywhere, so we're just spinning needlessly.
+ AXIS_LOG("%p|%s has overscrolled, clearing velocity\n",
+ mAsyncPanZoomController, Name());
mVelocity = 0.0f;
displacement -= aOverscrollAmountOut;
}
@@ -217,6 +222,8 @@ bool Axis::SampleOverscrollAnimation(const TimeDuration& aDelta) {
// Apply dampening.
mVelocity *= pow(double(1 - kSpringFriction), aDelta.ToMilliseconds());
+ AXIS_LOG("%p|%s sampled overscroll animation, leaving velocity at %f\n",
+ mAsyncPanZoomController, Name(), mVelocity);
// Adjust the amount of overscroll based on the velocity.
// Note that we allow for oscillations. mInUnderscroll tracks whether
@@ -238,6 +245,8 @@ bool Axis::SampleOverscrollAnimation(const TimeDuration& aDelta) {
fabs(mVelocity) < gfxPrefs::APZOverscrollStopVelocityThreshold()) {
// "Jump" to the at-rest state. The jump shouldn't be noticeable as the
// velocity and overscroll are already low.
+ AXIS_LOG("%p|%s oscillation dropped below threshold, going to rest\n",
+ mAsyncPanZoomController, Name());
mOverscroll = 0;
mVelocity = 0;
mInUnderscroll = false;
@@ -285,12 +294,16 @@ void Axis::EndTouch(uint32_t aTimestampMs) {
if (count > 1) {
mVelocity /= count;
}
+ AXIS_LOG("%p|%s ending touch, computed velocity %f\n",
+ mAsyncPanZoomController, Name(), mVelocity);
}
void Axis::CancelTouch() {
// mVelocityQueue is controller-thread only
AsyncPanZoomController::AssertOnControllerThread();
+ AXIS_LOG("%p|%s cancelling touch, clearing velocity queue\n",
+ mAsyncPanZoomController, Name());
mVelocity = 0.0f;
while (!mVelocityQueue.IsEmpty()) {
mVelocityQueue.RemoveElementAt(0);
@@ -317,6 +330,8 @@ bool Axis::FlingApplyFrictionOrCancel(const TimeDuration& aDelta,
} else {
mVelocity *= pow(1.0f - aFriction, float(aDelta.ToMilliseconds()));
}
+ AXIS_LOG("%p|%s reduced velocity to %f due to friction\n",
+ mAsyncPanZoomController, Name(), mVelocity);
return true;
}
@@ -373,6 +388,8 @@ float Axis::GetVelocity() const {
}
void Axis::SetVelocity(float aVelocity) {
+ AXIS_LOG("%p|%s direct-setting velocity to %f\n",
+ mAsyncPanZoomController, Name(), aVelocity);
mVelocity = aVelocity;
}
@@ -441,6 +458,11 @@ ScreenPoint AxisX::MakePoint(ScreenCoord aCoord) const
return ScreenPoint(aCoord, 0);
}
+const char* AxisX::Name() const
+{
+ return "X";
+}
+
AxisY::AxisY(AsyncPanZoomController* aAsyncPanZoomController)
: Axis(aAsyncPanZoomController)
{
@@ -467,5 +489,10 @@ ScreenPoint AxisY::MakePoint(ScreenCoord aCoord) const
return ScreenPoint(0, aCoord);
}
+const char* AxisY::Name() const
+{
+ return "Y";
+}
+
}
}
diff --git a/gfx/layers/apz/src/Axis.h b/gfx/layers/apz/src/Axis.h
index 4bc5236457c7..a0b8bf983b41 100644
--- a/gfx/layers/apz/src/Axis.h
+++ b/gfx/layers/apz/src/Axis.h
@@ -238,6 +238,8 @@ public:
virtual ScreenPoint MakePoint(ScreenCoord aCoord) const = 0;
+ virtual const char* Name() const = 0;
+
protected:
ParentLayerCoord mPos;
uint32_t mPosTimeMs;
@@ -270,6 +272,7 @@ public:
virtual ParentLayerCoord GetRectLength(const ParentLayerRect& aRect) const MOZ_OVERRIDE;
virtual ParentLayerCoord GetRectOffset(const ParentLayerRect& aRect) const MOZ_OVERRIDE;
virtual ScreenPoint MakePoint(ScreenCoord aCoord) const MOZ_OVERRIDE;
+ virtual const char* Name() const MOZ_OVERRIDE;
};
class AxisY : public Axis {
@@ -279,6 +282,7 @@ public:
virtual ParentLayerCoord GetRectLength(const ParentLayerRect& aRect) const MOZ_OVERRIDE;
virtual ParentLayerCoord GetRectOffset(const ParentLayerRect& aRect) const MOZ_OVERRIDE;
virtual ScreenPoint MakePoint(ScreenCoord aCoord) const MOZ_OVERRIDE;
+ virtual const char* Name() const MOZ_OVERRIDE;
};
}
diff --git a/gfx/layers/apz/src/InputBlockState.cpp b/gfx/layers/apz/src/InputBlockState.cpp
index c8501883102c..d09ab0a01d3d 100644
--- a/gfx/layers/apz/src/InputBlockState.cpp
+++ b/gfx/layers/apz/src/InputBlockState.cpp
@@ -37,6 +37,7 @@ InputBlockState::SetConfirmedTargetApzc(const nsRefPtr&
}
mTargetConfirmed = true;
+ TBS_LOG("%p got confirmed target APZC %p\n", this, mTargetApzc.get());
if (mTargetApzc == aTargetApzc) {
// The confirmed target is the same as the tentative one, so we're done.
return true;
diff --git a/gfx/layers/apz/src/InputQueue.cpp b/gfx/layers/apz/src/InputQueue.cpp
index bc53115ded4b..49902647fa4f 100644
--- a/gfx/layers/apz/src/InputQueue.cpp
+++ b/gfx/layers/apz/src/InputQueue.cpp
@@ -60,6 +60,7 @@ InputQueue::ReceiveInputEvent(const nsRefPtr& aTarget,
// If we're already in a fast fling, then we want the touch event to stop the fling
// and to disallow the touch event from being used as part of a fling.
block->SetDuringFastMotion();
+ INPQ_LOG("block %p tagged as fast-motion\n", block);
}
block->GetOverscrollHandoffChain()->CancelAnimations();
}
@@ -69,6 +70,7 @@ InputQueue::ReceiveInputEvent(const nsRefPtr& aTarget,
waitForMainThread |= aTarget->NeedToWaitForContent();
}
if (block->IsDuringFastMotion()) {
+ block->SetConfirmedTargetApzc(aTarget);
waitForMainThread = false;
}
if (waitForMainThread) {
diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp
index c6d01ddaac3d..e513dac3f573 100644
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -1805,8 +1805,8 @@ nsLayoutUtils::GetNearestScrollableFrame(nsIFrame* aFrame, uint32_t aFlags)
}
if (aFlags & SCROLLABLE_ALWAYS_MATCH_ROOT) {
nsPresContext* pc = f->PresContext();
- if (pc->IsRootContentDocument() && pc->PresShell()->GetRootScrollFrame() == f) {
- return scrollableFrame;
+ if (pc->IsRootContentDocument() && pc->PresShell()->GetRootFrame() == f) {
+ return pc->PresShell()->GetRootScrollFrameAsScrollable();
}
}
}
diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h
index e35633b27f8b..dd30a8eeb003 100644
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -586,7 +586,8 @@ public:
SCROLLABLE_ONLY_ASYNC_SCROLLABLE = 0x04,
/**
* If the SCROLLABLE_ALWAYS_MATCH_ROOT flag is set, then return the
- * root scrollable frame for the root content document if we hit it.
+ * root scrollable frame for the root content document if we don't hit
+ * anything else.
*/
SCROLLABLE_ALWAYS_MATCH_ROOT = 0x08,
};