diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 90aeca1a797..93de83c93c8 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
-
+
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index f56fac25cbe..eb2c2840d3b 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 1266c1a8713..d8f3ac50fa5 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 90aeca1a797..93de83c93c8 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
-
+
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index e6272babefd..0322d020bae 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 1a44d33c0f8..f2ec6100f97 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
- "revision": "4d2c0a0848326ad805ccc89f0a3893d35f90a9ef",
+ "revision": "8749f2b7d7998019d04618b46d28b5cb9d77aadb",
"repo_path": "/integration/gaia-central"
}
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index 5a844708f3c..5fa58ad34de 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 df685ffdbd9..8e56614fb23 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 52e066748b6..f9a6dc6773c 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 190d3ee9117..6a4a9b02585 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
-
+
diff --git a/dom/bluetooth2/bluedroid/BluetoothInterface.cpp b/dom/bluetooth2/bluedroid/BluetoothInterface.cpp
index d17359f3e11..54d3dd54026 100644
--- a/dom/bluetooth2/bluedroid/BluetoothInterface.cpp
+++ b/dom/bluetooth2/bluedroid/BluetoothInterface.cpp
@@ -5,6 +5,8 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BluetoothInterface.h"
+#include "nsAutoPtr.h"
+#include "nsThreadUtils.h"
BEGIN_BLUETOOTH_NAMESPACE
@@ -12,6 +14,61 @@ template
struct interface_traits
{ };
+//
+// Result handling
+//
+
+template
+class BluetoothInterfaceRunnable0 : public nsRunnable
+{
+public:
+ BluetoothInterfaceRunnable0(Obj* aObj, Res (Obj::*aMethod)())
+ : mObj(aObj)
+ , mMethod(aMethod)
+ {
+ MOZ_ASSERT(mObj);
+ MOZ_ASSERT(mMethod);
+ }
+
+ NS_METHOD
+ Run() MOZ_OVERRIDE
+ {
+ ((*mObj).*mMethod)();
+ return NS_OK;
+ }
+
+private:
+ nsRefPtr mObj;
+ void (Obj::*mMethod)();
+};
+
+template
+class BluetoothInterfaceRunnable1 : public nsRunnable
+{
+public:
+ BluetoothInterfaceRunnable1(Obj* aObj, Res (Obj::*aMethod)(Arg1),
+ const Arg1& aArg1)
+ : mObj(aObj)
+ , mMethod(aMethod)
+ , mArg1(aArg1)
+ {
+ MOZ_ASSERT(mObj);
+ MOZ_ASSERT(mMethod);
+ }
+
+ NS_METHOD
+ Run() MOZ_OVERRIDE
+ {
+ ((*mObj).*mMethod)(mArg1);
+ return NS_OK;
+ }
+
+private:
+ nsRefPtr mObj;
+ void (Obj::*mMethod)(Arg1);
+ Arg1 mArg1;
+};
+
//
// Socket Interface
//
@@ -371,6 +428,36 @@ BluetoothAvrcpInterface::SetVolume(uint8_t aVolume)
// Bluetooth Core Interface
//
+typedef
+ BluetoothInterfaceRunnable0
+ BluetoothResultRunnable;
+
+typedef
+ BluetoothInterfaceRunnable1
+ BluetoothErrorRunnable;
+
+static nsresult
+DispatchBluetoothResult(BluetoothResultHandler* aRes,
+ void (BluetoothResultHandler::*aMethod)(),
+ int aStatus)
+{
+ MOZ_ASSERT(aRes);
+
+ nsRunnable* runnable;
+
+ if (aStatus == BT_STATUS_SUCCESS) {
+ runnable = new BluetoothResultRunnable(aRes, aMethod);
+ } else {
+ runnable = new
+ BluetoothErrorRunnable(aRes, &BluetoothResultHandler::OnError, aStatus);
+ }
+ nsresult rv = NS_DispatchToMainThread(runnable);
+ if (NS_FAILED(rv)) {
+ BT_LOGR("NS_DispatchToMainThread failed: %X", rv);
+ }
+ return rv;
+}
+
/* returns the container structure of a variable; _t is the container's
* type, _v the name of the variable, and _m is _v's field within _t
*/
@@ -442,158 +529,303 @@ BluetoothInterface::BluetoothInterface(const bt_interface_t* aInterface)
BluetoothInterface::~BluetoothInterface()
{ }
-int
-BluetoothInterface::Init(bt_callbacks_t* aCallbacks)
+void
+BluetoothInterface::Init(bt_callbacks_t* aCallbacks,
+ BluetoothResultHandler* aRes)
{
- return mInterface->init(aCallbacks);
+ int status = mInterface->init(aCallbacks);
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes, &BluetoothResultHandler::Init, status);
+ }
}
void
-BluetoothInterface::Cleanup()
+BluetoothInterface::Cleanup(BluetoothResultHandler* aRes)
{
mInterface->cleanup();
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes, &BluetoothResultHandler::Cleanup,
+ BT_STATUS_SUCCESS);
+ }
}
-int
-BluetoothInterface::Enable()
+void
+BluetoothInterface::Enable(BluetoothResultHandler* aRes)
{
- return mInterface->enable();
+ int status = mInterface->enable();
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes, &BluetoothResultHandler::Enable, status);
+ }
}
-int
-BluetoothInterface::Disable()
+void
+BluetoothInterface::Disable(BluetoothResultHandler* aRes)
{
- return mInterface->disable();
+ int status = mInterface->disable();
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes, &BluetoothResultHandler::Disable, status);
+ }
}
/* Adapter Properties */
-int
-BluetoothInterface::GetAdapterProperties()
+void
+BluetoothInterface::GetAdapterProperties(BluetoothResultHandler* aRes)
{
- return mInterface->get_adapter_properties();
+ int status = mInterface->get_adapter_properties();
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes,
+ &BluetoothResultHandler::GetAdapterProperties,
+ status);
+ }
}
-int
-BluetoothInterface::GetAdapterProperty(bt_property_type_t aType)
+void
+BluetoothInterface::GetAdapterProperty(bt_property_type_t aType,
+ BluetoothResultHandler* aRes)
{
- return mInterface->get_adapter_property(aType);
+ int status = mInterface->get_adapter_property(aType);
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes,
+ &BluetoothResultHandler::GetAdapterProperty,
+ status);
+ }
}
-int
-BluetoothInterface::SetAdapterProperty(const bt_property_t* aProperty)
+void
+BluetoothInterface::SetAdapterProperty(const bt_property_t* aProperty,
+ BluetoothResultHandler* aRes)
{
- return mInterface->set_adapter_property(aProperty);
+ int status = mInterface->set_adapter_property(aProperty);
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes,
+ &BluetoothResultHandler::SetAdapterProperty,
+ status);
+ }
}
/* Remote Device Properties */
-int
-BluetoothInterface::GetRemoteDeviceProperties(bt_bdaddr_t *aRemoteAddr)
+void
+BluetoothInterface::GetRemoteDeviceProperties(bt_bdaddr_t *aRemoteAddr,
+ BluetoothResultHandler* aRes)
{
- return mInterface->get_remote_device_properties(aRemoteAddr);
+ int status = mInterface->get_remote_device_properties(aRemoteAddr);
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes,
+ &BluetoothResultHandler::GetRemoteDeviceProperties,
+ status);
+ }
}
-int
+void
BluetoothInterface::GetRemoteDeviceProperty(bt_bdaddr_t* aRemoteAddr,
- bt_property_type_t aType)
+ bt_property_type_t aType,
+ BluetoothResultHandler* aRes)
{
- return mInterface->get_remote_device_property(aRemoteAddr, aType);
+ int status = mInterface->get_remote_device_property(aRemoteAddr, aType);
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes,
+ &BluetoothResultHandler::GetRemoteDeviceProperty,
+ status);
+ }
}
-int
+void
BluetoothInterface::SetRemoteDeviceProperty(bt_bdaddr_t* aRemoteAddr,
- const bt_property_t* aProperty)
+ const bt_property_t* aProperty,
+ BluetoothResultHandler* aRes)
{
- return mInterface->set_remote_device_property(aRemoteAddr, aProperty);
+ int status = mInterface->set_remote_device_property(aRemoteAddr, aProperty);
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes,
+ &BluetoothResultHandler::SetRemoteDeviceProperty,
+ status);
+ }
}
/* Remote Services */
-int
+void
BluetoothInterface::GetRemoteServiceRecord(bt_bdaddr_t* aRemoteAddr,
- bt_uuid_t* aUuid)
+ bt_uuid_t* aUuid,
+ BluetoothResultHandler* aRes)
{
- return mInterface->get_remote_service_record(aRemoteAddr, aUuid);
+ int status = mInterface->get_remote_service_record(aRemoteAddr, aUuid);
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes,
+ &BluetoothResultHandler::GetRemoteServiceRecord,
+ status);
+ }
}
-int
-BluetoothInterface::GetRemoteServices(bt_bdaddr_t* aRemoteAddr)
+void
+BluetoothInterface::GetRemoteServices(bt_bdaddr_t* aRemoteAddr,
+ BluetoothResultHandler* aRes)
{
- return mInterface->get_remote_services(aRemoteAddr);
+ int status = mInterface->get_remote_services(aRemoteAddr);
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes,
+ &BluetoothResultHandler::GetRemoteServices,
+ status);
+ }
}
/* Discovery */
-int
-BluetoothInterface::StartDiscovery()
+void
+BluetoothInterface::StartDiscovery(BluetoothResultHandler* aRes)
{
- return mInterface->start_discovery();
+ int status = mInterface->start_discovery();
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes,
+ &BluetoothResultHandler::StartDiscovery,
+ status);
+ }
}
-int
-BluetoothInterface::CancelDiscovery()
+void
+BluetoothInterface::CancelDiscovery(BluetoothResultHandler* aRes)
{
- return mInterface->cancel_discovery();
+ int status = mInterface->cancel_discovery();
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes,
+ &BluetoothResultHandler::CancelDiscovery,
+ status);
+ }
}
/* Bonds */
-int
-BluetoothInterface::CreateBond(const bt_bdaddr_t* aBdAddr)
+void
+BluetoothInterface::CreateBond(const bt_bdaddr_t* aBdAddr,
+ BluetoothResultHandler* aRes)
{
- return mInterface->create_bond(aBdAddr);
+ int status = mInterface->create_bond(aBdAddr);
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes,
+ &BluetoothResultHandler::CreateBond,
+ status);
+ }
}
-int
-BluetoothInterface::RemoveBond(const bt_bdaddr_t* aBdAddr)
+void
+BluetoothInterface::RemoveBond(const bt_bdaddr_t* aBdAddr,
+ BluetoothResultHandler* aRes)
{
- return mInterface->remove_bond(aBdAddr);
+ int status = mInterface->remove_bond(aBdAddr);
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes,
+ &BluetoothResultHandler::RemoveBond,
+ status);
+ }
}
-int
-BluetoothInterface::CancelBond(const bt_bdaddr_t* aBdAddr)
+void
+BluetoothInterface::CancelBond(const bt_bdaddr_t* aBdAddr,
+ BluetoothResultHandler* aRes)
{
- return mInterface->cancel_bond(aBdAddr);
+ int status = mInterface->cancel_bond(aBdAddr);
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes,
+ &BluetoothResultHandler::CancelBond,
+ status);
+ }
}
/* Authentication */
-int
+void
BluetoothInterface::PinReply(const bt_bdaddr_t* aBdAddr, uint8_t aAccept,
- uint8_t aPinLen, bt_pin_code_t* aPinCode)
+ uint8_t aPinLen, bt_pin_code_t* aPinCode,
+ BluetoothResultHandler* aRes)
{
- return mInterface->pin_reply(aBdAddr, aAccept, aPinLen, aPinCode);
+ int status = mInterface->pin_reply(aBdAddr, aAccept, aPinLen, aPinCode);
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes,
+ &BluetoothResultHandler::PinReply,
+ status);
+ }
}
-int
+void
BluetoothInterface::SspReply(const bt_bdaddr_t* aBdAddr,
bt_ssp_variant_t aVariant,
- uint8_t aAccept, uint32_t aPasskey)
+ uint8_t aAccept, uint32_t aPasskey,
+ BluetoothResultHandler* aRes)
{
- return mInterface->ssp_reply(aBdAddr, aVariant, aAccept, aPasskey);
+ int status = mInterface->ssp_reply(aBdAddr, aVariant, aAccept, aPasskey);
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes,
+ &BluetoothResultHandler::SspReply,
+ status);
+ }
}
/* DUT Mode */
-int
-BluetoothInterface::DutModeConfigure(uint8_t aEnable)
+void
+BluetoothInterface::DutModeConfigure(uint8_t aEnable,
+ BluetoothResultHandler* aRes)
{
- return mInterface->dut_mode_configure(aEnable);
+ int status = mInterface->dut_mode_configure(aEnable);
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes,
+ &BluetoothResultHandler::DutModeConfigure,
+ status);
+ }
}
-int
-BluetoothInterface::DutModeSend(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen)
+void
+BluetoothInterface::DutModeSend(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
+ BluetoothResultHandler* aRes)
{
- return mInterface->dut_mode_send(aOpcode, aBuf, aLen);
+ int status = mInterface->dut_mode_send(aOpcode, aBuf, aLen);
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes,
+ &BluetoothResultHandler::DutModeSend,
+ status);
+ }
}
/* LE Mode */
-int
-BluetoothInterface::LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen)
+void
+BluetoothInterface::LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
+ BluetoothResultHandler* aRes)
{
- return mInterface->le_test_mode(aOpcode, aBuf, aLen);
+#if ANDROID_VERSION >= 18
+ int status = mInterface->le_test_mode(aOpcode, aBuf, aLen);
+#else
+ int status = BT_STATUS_UNSUPPORTED;
+#endif
+
+ if (aRes) {
+ DispatchBluetoothResult(aRes,
+ &BluetoothResultHandler::LeTestMode,
+ status);
+ }
}
/* Profile Interfaces */
diff --git a/dom/bluetooth2/bluedroid/BluetoothInterface.h b/dom/bluetooth2/bluedroid/BluetoothInterface.h
index 91c93ca92ae..ebb62fe5804 100644
--- a/dom/bluetooth2/bluedroid/BluetoothInterface.h
+++ b/dom/bluetooth2/bluedroid/BluetoothInterface.h
@@ -181,64 +181,120 @@ private:
// Bluetooth Core Interface
//
+class BluetoothResultHandler
+{
+public:
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BluetoothResultHandler)
+
+ virtual ~BluetoothResultHandler() { }
+
+ virtual void OnError(int aStatus)
+ {
+ BT_LOGR("Received error code %d", aStatus);
+ }
+
+ virtual void Init() { }
+ virtual void Cleanup() { }
+ virtual void Enable() { }
+ virtual void Disable() { }
+
+ virtual void GetAdapterProperties() { }
+ virtual void GetAdapterProperty() { }
+ virtual void SetAdapterProperty() { }
+
+ virtual void GetRemoteDeviceProperties() { }
+ virtual void GetRemoteDeviceProperty() { }
+ virtual void SetRemoteDeviceProperty() { }
+
+ virtual void GetRemoteServiceRecord() { }
+ virtual void GetRemoteServices() { }
+
+ virtual void StartDiscovery() { }
+ virtual void CancelDiscovery() { }
+
+ virtual void CreateBond() { }
+ virtual void RemoveBond() { }
+ virtual void CancelBond() { }
+
+ virtual void PinReply() { }
+ virtual void SspReply() { }
+
+ virtual void DutModeConfigure() { }
+ virtual void DutModeSend() { }
+
+ virtual void LeTestMode() { }
+};
+
class BluetoothInterface
{
public:
static BluetoothInterface* GetInstance();
- int Init(bt_callbacks_t* aCallbacks);
- void Cleanup();
+ void Init(bt_callbacks_t* aCallbacks, BluetoothResultHandler* aRes);
+ void Cleanup(BluetoothResultHandler* aRes);
+
+ void Enable(BluetoothResultHandler* aRes);
+ void Disable(BluetoothResultHandler* aRes);
- int Enable();
- int Disable();
/* Adapter Properties */
- int GetAdapterProperties();
- int GetAdapterProperty(bt_property_type_t aType);
- int SetAdapterProperty(const bt_property_t* aProperty);
+ void GetAdapterProperties(BluetoothResultHandler* aRes);
+ void GetAdapterProperty(bt_property_type_t aType,
+ BluetoothResultHandler* aRes);
+ void SetAdapterProperty(const bt_property_t* aProperty,
+ BluetoothResultHandler* aRes);
/* Remote Device Properties */
- int GetRemoteDeviceProperties(bt_bdaddr_t *aRemoteAddr);
- int GetRemoteDeviceProperty(bt_bdaddr_t* aRemoteAddr,
- bt_property_type_t aType);
- int SetRemoteDeviceProperty(bt_bdaddr_t* aRemoteAddr,
- const bt_property_t* aProperty);
+ void GetRemoteDeviceProperties(bt_bdaddr_t *aRemoteAddr,
+ BluetoothResultHandler* aRes);
+ void GetRemoteDeviceProperty(bt_bdaddr_t* aRemoteAddr,
+ bt_property_type_t aType,
+ BluetoothResultHandler* aRes);
+ void SetRemoteDeviceProperty(bt_bdaddr_t* aRemoteAddr,
+ const bt_property_t* aProperty,
+ BluetoothResultHandler* aRes);
/* Remote Services */
- int GetRemoteServiceRecord(bt_bdaddr_t* aRemoteAddr,
- bt_uuid_t* aUuid);
- int GetRemoteServices(bt_bdaddr_t* aRemoteAddr);
+ void GetRemoteServiceRecord(bt_bdaddr_t* aRemoteAddr,
+ bt_uuid_t* aUuid,
+ BluetoothResultHandler* aRes);
+ void GetRemoteServices(bt_bdaddr_t* aRemoteAddr,
+ BluetoothResultHandler* aRes);
/* Discovery */
- int StartDiscovery();
- int CancelDiscovery();
+ void StartDiscovery(BluetoothResultHandler* aRes);
+ void CancelDiscovery(BluetoothResultHandler* aRes);
/* Bonds */
- int CreateBond(const bt_bdaddr_t* aBdAddr);
- int RemoveBond(const bt_bdaddr_t* aBdAddr);
- int CancelBond(const bt_bdaddr_t* aBdAddr);
+ void CreateBond(const bt_bdaddr_t* aBdAddr, BluetoothResultHandler* aRes);
+ void RemoveBond(const bt_bdaddr_t* aBdAddr, BluetoothResultHandler* aRes);
+ void CancelBond(const bt_bdaddr_t* aBdAddr, BluetoothResultHandler* aRes);
/* Authentication */
- int PinReply(const bt_bdaddr_t* aBdAddr, uint8_t aAccept,
- uint8_t aPinLen, bt_pin_code_t* aPinCode);
+ void PinReply(const bt_bdaddr_t* aBdAddr, uint8_t aAccept,
+ uint8_t aPinLen, bt_pin_code_t* aPinCode,
+ BluetoothResultHandler* aRes);
- int SspReply(const bt_bdaddr_t* aBdAddr, bt_ssp_variant_t aVariant,
- uint8_t aAccept, uint32_t aPasskey);
+ void SspReply(const bt_bdaddr_t* aBdAddr, bt_ssp_variant_t aVariant,
+ uint8_t aAccept, uint32_t aPasskey,
+ BluetoothResultHandler* aRes);
/* DUT Mode */
- int DutModeConfigure(uint8_t aEnable);
- int DutModeSend(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen);
+ void DutModeConfigure(uint8_t aEnable, BluetoothResultHandler* aRes);
+ void DutModeSend(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
+ BluetoothResultHandler* aRes);
/* LE Mode */
- int LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen);
+ void LeTestMode(uint16_t aOpcode, uint8_t* aBuf, uint8_t aLen,
+ BluetoothResultHandler* aRes);
/* Profile Interfaces */
diff --git a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp
index 1e90cb734ff..74dce091926 100644
--- a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp
+++ b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp
@@ -57,6 +57,7 @@ static InfallibleTArray sAdapterBondedAddressArray;
// Static variables below should only be used on *main thread*
static BluetoothInterface* sBtInterface;
static nsTArray > sControllerArray;
+static InfallibleTArray sRemoteDevicesPack;
static nsTArray sRequestedDeviceCountArray;
static nsTArray > sChangeAdapterStateRunnableArray;
static nsTArray > sChangeDiscoveryRunnableArray;
@@ -105,6 +106,16 @@ private:
class SetupAfterEnabledTask MOZ_FINAL : public nsRunnable
{
public:
+ class SetAdapterPropertyResultHandler MOZ_FINAL
+ : public BluetoothResultHandler
+ {
+ public:
+ void OnError(int aStatus) MOZ_OVERRIDE
+ {
+ BT_LOGR("Fail to set: BT_SCAN_MODE_CONNECTABLE");
+ }
+ };
+
NS_IMETHOD
Run()
{
@@ -126,11 +137,8 @@ public:
prop.len = sizeof(mode);
NS_ENSURE_TRUE(sBtInterface, NS_ERROR_FAILURE);
-
- int ret = sBtInterface->SetAdapterProperty(&prop);
- if (ret != BT_STATUS_SUCCESS) {
- BT_LOGR("Fail to set: BT_SCAN_MODE_CONNECTABLE");
- }
+ sBtInterface->SetAdapterProperty(&prop,
+ new SetAdapterPropertyResultHandler());
// Trigger BluetoothOppManager to listen
BluetoothOppManager* opp = BluetoothOppManager::Get();
@@ -177,7 +185,7 @@ public:
// Cleanup bluetooth interfaces after BT state becomes BT_STATE_OFF.
BluetoothHfpManager::DeinitHfpInterface();
BluetoothA2dpManager::DeinitA2dpInterface();
- sBtInterface->Cleanup();
+ sBtInterface->Cleanup(nullptr);
return NS_OK;
}
@@ -484,8 +492,6 @@ public:
return NS_OK;
}
- static InfallibleTArray sRemoteDevicesPack;
-
// Use address as the index
sRemoteDevicesPack.AppendElement(
BluetoothNamedValue(mRemoteDeviceBdAddress, mProps));
@@ -812,26 +818,54 @@ EnsureBluetoothHalLoad()
return true;
}
-static bool
-EnableInternal()
+class EnableResultHandler MOZ_FINAL : public BluetoothResultHandler
{
- int ret = sBtInterface->Init(&sBluetoothCallbacks);
- if (ret != BT_STATUS_SUCCESS) {
- BT_LOGR("Error while setting the callbacks");
- sBtInterface = nullptr;
- return false;
+public:
+ void OnError(int aStatus) MOZ_OVERRIDE
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ 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!");
+ }
+ }
+};
+
+class InitResultHandler MOZ_FINAL : public BluetoothResultHandler
+{
+public:
+ void Init() MOZ_OVERRIDE
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ // Register all the bluedroid callbacks before enable() get called
+ // It is required to register a2dp callbacks before a2dp media task starts up.
+ // If any interface cannot be initialized, turn on bluetooth core anyway.
+ BluetoothHfpManager::InitHfpInterface();
+ BluetoothA2dpManager::InitA2dpInterface();
+ sBtInterface->Enable(new EnableResultHandler());
}
- // Register all the bluedroid callbacks before enable() get called
- // It is required to register a2dp callbacks before a2dp media task starts up.
- // If any interface cannot be initialized, turn on bluetooth core anyway.
- BluetoothHfpManager::InitHfpInterface();
- BluetoothA2dpManager::InitA2dpInterface();
- return sBtInterface->Enable();
-}
+ void OnError(int aStatus) MOZ_OVERRIDE
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ BT_LOGR("BluetoothInterface::Init failed: %d", aStatus);
+
+ sBtInterface = nullptr;
+
+ nsRefPtr runnable = new BluetoothService::ToggleBtAck(false);
+ if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
+ BT_WARNING("Failed to dispatch to main thread!");
+ }
+ }
+};
static nsresult
-StartStopGonkBluetooth(bool aShouldEnable)
+StartGonkBluetooth()
{
MOZ_ASSERT(NS_IsMainThread());
@@ -840,18 +874,56 @@ StartStopGonkBluetooth(bool aShouldEnable)
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
- if (bs->IsEnabled() == aShouldEnable) {
+ if (bs->IsEnabled()) {
// Keep current enable status
- nsRefPtr runnable =
- new BluetoothService::ToggleBtAck(aShouldEnable);
+ nsRefPtr runnable = new BluetoothService::ToggleBtAck(true);
if (NS_FAILED(NS_DispatchToMainThread(runnable))) {
BT_WARNING("Failed to dispatch to main thread!");
}
return NS_OK;
}
- int ret = aShouldEnable ? EnableInternal() : sBtInterface->Disable();
- NS_ENSURE_TRUE(ret == BT_STATUS_SUCCESS, NS_ERROR_FAILURE);
+ sBtInterface->Init(&sBluetoothCallbacks, new InitResultHandler());
+
+ return NS_OK;
+}
+
+class DisableResultHandler MOZ_FINAL : public BluetoothResultHandler
+{
+public:
+ void OnError(int aStatus) MOZ_OVERRIDE
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ 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!");
+ }
+ }
+};
+
+static nsresult
+StopGonkBluetooth()
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ NS_ENSURE_TRUE(sBtInterface, NS_ERROR_FAILURE);
+
+ BluetoothService* bs = BluetoothService::Get();
+ NS_ENSURE_TRUE(bs, NS_ERROR_FAILURE);
+
+ 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!");
+ }
+ return NS_OK;
+ }
+
+ sBtInterface->Disable(new DisableResultHandler());
return NS_OK;
}
@@ -910,7 +982,7 @@ BluetoothServiceBluedroid::StartInternal(BluetoothReplyRunnable* aRunnable)
sChangeAdapterStateRunnableArray.AppendElement(aRunnable);
}
- nsresult ret = StartStopGonkBluetooth(true);
+ nsresult ret = StartGonkBluetooth();
if (NS_FAILED(ret)) {
nsRefPtr runnable =
new BluetoothService::ToggleBtAck(false);
@@ -942,7 +1014,7 @@ BluetoothServiceBluedroid::StopInternal(BluetoothReplyRunnable* aRunnable)
sChangeAdapterStateRunnableArray.AppendElement(aRunnable);
}
- nsresult ret = StartStopGonkBluetooth(false);
+ nsresult ret = StopGonkBluetooth();
if (NS_FAILED(ret)) {
nsRefPtr runnable =
new BluetoothService::ToggleBtAck(true);
@@ -1006,6 +1078,39 @@ BluetoothServiceBluedroid::GetAdaptersInternal(
return NS_OK;
}
+class GetRemoteDevicePropertiesResultHandler MOZ_FINAL
+: public BluetoothResultHandler
+{
+public:
+ GetRemoteDevicePropertiesResultHandler(const nsAString& aDeviceAddress)
+ : mDeviceAddress(aDeviceAddress)
+ { }
+
+ void OnError(int aStatus) MOZ_OVERRIDE
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ BT_WARNING("GetRemoteDeviceProperties(%s) failed: %d",
+ NS_ConvertUTF16toUTF8(mDeviceAddress).get(), aStatus);
+
+ /* dispatch result after final pending operation */
+ if (--sRequestedDeviceCountArray[0] == 0) {
+ if (!sGetDeviceRunnableArray.IsEmpty()) {
+ DispatchBluetoothReply(
+ sGetDeviceRunnableArray[0], sRemoteDevicesPack,
+ NS_LITERAL_STRING("GetRemoteDeviceProperties failed"));
+ sGetDeviceRunnableArray.RemoveElementAt(0);
+ }
+
+ sRequestedDeviceCountArray.RemoveElementAt(0);
+ sRemoteDevicesPack.Clear();
+ }
+ }
+
+private:
+ nsString mDeviceAddress;
+};
+
nsresult
BluetoothServiceBluedroid::GetConnectedDevicePropertiesInternal(
uint16_t aServiceUuid, BluetoothReplyRunnable* aRunnable)
@@ -1037,22 +1142,18 @@ BluetoothServiceBluedroid::GetConnectedDevicePropertiesInternal(
return NS_OK;
}
+ sRequestedDeviceCountArray.AppendElement(requestedDeviceCount);
+ sGetDeviceRunnableArray.AppendElement(aRunnable);
+
for (int i = 0; i < requestedDeviceCount; i++) {
// Retrieve all properties of devices
bt_bdaddr_t addressType;
StringToBdAddressType(deviceAddresses[i], &addressType);
- int ret = sBtInterface->GetRemoteDeviceProperties(&addressType);
- if (ret != BT_STATUS_SUCCESS) {
- DispatchBluetoothReply(aRunnable, BluetoothValue(true),
- NS_LITERAL_STRING("GetConnectedDeviceFailed"));
- return NS_OK;
- }
+ sBtInterface->GetRemoteDeviceProperties(&addressType,
+ new GetRemoteDevicePropertiesResultHandler(deviceAddresses[i]));
}
- sRequestedDeviceCountArray.AppendElement(requestedDeviceCount);
- sGetDeviceRunnableArray.AppendElement(aRunnable);
-
return NS_OK;
}
@@ -1071,24 +1172,39 @@ BluetoothServiceBluedroid::GetPairedDevicePropertiesInternal(
return NS_OK;
}
+ sRequestedDeviceCountArray.AppendElement(requestedDeviceCount);
+ sGetDeviceRunnableArray.AppendElement(aRunnable);
+
for (int i = 0; i < requestedDeviceCount; i++) {
// Retrieve all properties of devices
bt_bdaddr_t addressType;
StringToBdAddressType(aDeviceAddress[i], &addressType);
- int ret = sBtInterface->GetRemoteDeviceProperties(&addressType);
- if (ret != BT_STATUS_SUCCESS) {
- DispatchBluetoothReply(aRunnable, BluetoothValue(true),
- NS_LITERAL_STRING("GetPairedDeviceFailed"));
- return NS_OK;
- }
- }
- sRequestedDeviceCountArray.AppendElement(requestedDeviceCount);
- sGetDeviceRunnableArray.AppendElement(aRunnable);
+ sBtInterface->GetRemoteDeviceProperties(&addressType,
+ new GetRemoteDevicePropertiesResultHandler(aDeviceAddress[i]));
+ }
return NS_OK;
}
+class StartDiscoveryResultHandler MOZ_FINAL : public BluetoothResultHandler
+{
+public:
+ StartDiscoveryResultHandler(BluetoothReplyRunnable* aRunnable)
+ : mRunnable(aRunnable)
+ { }
+
+ void OnError(int aStatus) MOZ_OVERRIDE
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+ sChangeDiscoveryRunnableArray.RemoveElement(mRunnable);
+ ReplyStatusError(mRunnable, aStatus, NS_LITERAL_STRING("StartDiscovery"));
+ }
+
+private:
+ BluetoothReplyRunnable* mRunnable;
+};
+
nsresult
BluetoothServiceBluedroid::StartDiscoveryInternal(
BluetoothReplyRunnable* aRunnable)
@@ -1097,17 +1213,30 @@ BluetoothServiceBluedroid::StartDiscoveryInternal(
ENSURE_BLUETOOTH_IS_READY(aRunnable, NS_OK);
- int ret = sBtInterface->StartDiscovery();
- if (ret != BT_STATUS_SUCCESS) {
- ReplyStatusError(aRunnable, ret, NS_LITERAL_STRING("StartDiscovery"));
-
- return NS_OK;
- }
-
sChangeDiscoveryRunnableArray.AppendElement(aRunnable);
+ sBtInterface->StartDiscovery(new StartDiscoveryResultHandler(aRunnable));
+
return NS_OK;
}
+class CancelDiscoveryResultHandler MOZ_FINAL : public BluetoothResultHandler
+{
+public:
+ CancelDiscoveryResultHandler(BluetoothReplyRunnable* aRunnable)
+ : mRunnable(aRunnable)
+ { }
+
+ void OnError(int aStatus) MOZ_OVERRIDE
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+ sChangeDiscoveryRunnableArray.RemoveElement(mRunnable);
+ ReplyStatusError(mRunnable, aStatus, NS_LITERAL_STRING("StopDiscovery"));
+ }
+
+private:
+ BluetoothReplyRunnable* mRunnable;
+};
+
nsresult
BluetoothServiceBluedroid::StopDiscoveryInternal(
BluetoothReplyRunnable* aRunnable)
@@ -1116,17 +1245,29 @@ BluetoothServiceBluedroid::StopDiscoveryInternal(
ENSURE_BLUETOOTH_IS_READY(aRunnable, NS_OK);
- int ret = sBtInterface->CancelDiscovery();
- if (ret != BT_STATUS_SUCCESS) {
- ReplyStatusError(aRunnable, ret, NS_LITERAL_STRING("StopDiscovery"));
- return NS_OK;
- }
-
sChangeDiscoveryRunnableArray.AppendElement(aRunnable);
+ sBtInterface->CancelDiscovery(new CancelDiscoveryResultHandler(aRunnable));
return NS_OK;
}
+class SetAdapterPropertyResultHandler MOZ_FINAL : public BluetoothResultHandler
+{
+public:
+ SetAdapterPropertyResultHandler(BluetoothReplyRunnable* aRunnable)
+ : mRunnable(aRunnable)
+ { }
+
+ void OnError(int aStatus) MOZ_OVERRIDE
+ {
+ MOZ_ASSERT(NS_IsMainThread());
+ sSetPropertyRunnableArray.RemoveElement(mRunnable);
+ ReplyStatusError(mRunnable, aStatus, NS_LITERAL_STRING("SetProperty"));
+ }
+private:
+ BluetoothReplyRunnable* mRunnable;
+};
+
nsresult
BluetoothServiceBluedroid::SetProperty(BluetoothObjectType aType,
const BluetoothNamedValue& aValue,
@@ -1181,11 +1322,8 @@ BluetoothServiceBluedroid::SetProperty(BluetoothObjectType aType,
sSetPropertyRunnableArray.AppendElement(aRunnable);
- int ret = sBtInterface->SetAdapterProperty(&prop);
- if (ret != BT_STATUS_SUCCESS) {
- ReplyStatusError(aRunnable, ret, NS_LITERAL_STRING(ERR_SET_PROPERTY));
- sSetPropertyRunnableArray.RemoveElement(aRunnable);
- }
+ sBtInterface->SetAdapterProperty(&prop,
+ new SetAdapterPropertyResultHandler(aRunnable));
return NS_OK;
}
@@ -1207,6 +1345,25 @@ BluetoothServiceBluedroid::UpdateSdpRecords(
return true;
}
+class CreateBondResultHandler MOZ_FINAL : public BluetoothResultHandler
+{
+public:
+ CreateBondResultHandler(BluetoothReplyRunnable* aRunnable)
+ : mRunnable(aRunnable)
+ {
+ MOZ_ASSERT(mRunnable);
+ }
+
+ void OnError(int aStatus) MOZ_OVERRIDE
+ {
+ sBondingRunnableArray.RemoveElement(mRunnable);
+ ReplyStatusError(mRunnable, aStatus, NS_LITERAL_STRING("CreatedPairedDevice"));
+ }
+
+private:
+ BluetoothReplyRunnable* mRunnable;
+};
+
nsresult
BluetoothServiceBluedroid::CreatePairedDeviceInternal(
const nsAString& aDeviceAddress, int aTimeout,
@@ -1219,16 +1376,32 @@ BluetoothServiceBluedroid::CreatePairedDeviceInternal(
bt_bdaddr_t remoteAddress;
StringToBdAddressType(aDeviceAddress, &remoteAddress);
- int ret = sBtInterface->CreateBond(&remoteAddress);
- if (ret != BT_STATUS_SUCCESS) {
- ReplyStatusError(aRunnable, ret, NS_LITERAL_STRING("CreatedPairedDevice"));
- } else {
- sBondingRunnableArray.AppendElement(aRunnable);
- }
+ sBondingRunnableArray.AppendElement(aRunnable);
+ sBtInterface->CreateBond(&remoteAddress,
+ new CreateBondResultHandler(aRunnable));
return NS_OK;
}
+class RemoveBondResultHandler MOZ_FINAL : public BluetoothResultHandler
+{
+public:
+ RemoveBondResultHandler(BluetoothReplyRunnable* aRunnable)
+ : mRunnable(aRunnable)
+ {
+ MOZ_ASSERT(mRunnable);
+ }
+
+ void OnError(int aStatus) MOZ_OVERRIDE
+ {
+ sUnbondingRunnableArray.RemoveElement(mRunnable);
+ ReplyStatusError(mRunnable, aStatus, NS_LITERAL_STRING("RemoveDevice"));
+ }
+
+private:
+ BluetoothReplyRunnable* mRunnable;
+};
+
nsresult
BluetoothServiceBluedroid::RemoveDeviceInternal(
const nsAString& aDeviceAddress, BluetoothReplyRunnable* aRunnable)
@@ -1240,17 +1413,35 @@ BluetoothServiceBluedroid::RemoveDeviceInternal(
bt_bdaddr_t remoteAddress;
StringToBdAddressType(aDeviceAddress, &remoteAddress);
- int ret = sBtInterface->RemoveBond(&remoteAddress);
- if (ret != BT_STATUS_SUCCESS) {
- ReplyStatusError(aRunnable, ret,
- NS_LITERAL_STRING("RemoveDevice"));
- } else {
- sUnbondingRunnableArray.AppendElement(aRunnable);
- }
+ sUnbondingRunnableArray.AppendElement(aRunnable);
+
+ sBtInterface->RemoveBond(&remoteAddress,
+ new RemoveBondResultHandler(aRunnable));
return NS_OK;
}
+class PinReplyResultHandler MOZ_FINAL : public BluetoothResultHandler
+{
+public:
+ PinReplyResultHandler(BluetoothReplyRunnable* aRunnable)
+ : mRunnable(aRunnable)
+ { }
+
+ void PinReply() MOZ_OVERRIDE
+ {
+ DispatchBluetoothReply(mRunnable, BluetoothValue(true), EmptyString());
+ }
+
+ void OnError(int aStatus) MOZ_OVERRIDE
+ {
+ ReplyStatusError(mRunnable, aStatus, NS_LITERAL_STRING("SetPinCode"));
+ }
+
+private:
+ BluetoothReplyRunnable* mRunnable;
+};
+
bool
BluetoothServiceBluedroid::SetPinCodeInternal(
const nsAString& aDeviceAddress, const nsAString& aPinCode,
@@ -1263,15 +1454,10 @@ BluetoothServiceBluedroid::SetPinCodeInternal(
bt_bdaddr_t remoteAddress;
StringToBdAddressType(aDeviceAddress, &remoteAddress);
- int ret = sBtInterface->PinReply(
- &remoteAddress, true, aPinCode.Length(),
- (bt_pin_code_t*)NS_ConvertUTF16toUTF8(aPinCode).get());
-
- if (ret != BT_STATUS_SUCCESS) {
- ReplyStatusError(aRunnable, ret, NS_LITERAL_STRING("SetPinCode"));
- } else {
- DispatchBluetoothReply(aRunnable, BluetoothValue(true), EmptyString());
- }
+ sBtInterface->PinReply(
+ &remoteAddress, true, aPinCode.Length(),
+ (bt_pin_code_t*)NS_ConvertUTF16toUTF8(aPinCode).get(),
+ new PinReplyResultHandler(aRunnable));
return true;
}
@@ -1284,6 +1470,28 @@ BluetoothServiceBluedroid::SetPasskeyInternal(
return true;
}
+class SspReplyResultHandler MOZ_FINAL : public BluetoothResultHandler
+{
+public:
+ SspReplyResultHandler(BluetoothReplyRunnable* aRunnable)
+ : mRunnable(aRunnable)
+ { }
+
+ void SspReply() MOZ_OVERRIDE
+ {
+ DispatchBluetoothReply(mRunnable, BluetoothValue(true), EmptyString());
+ }
+
+ void OnError(int aStatus) MOZ_OVERRIDE
+ {
+ ReplyStatusError(mRunnable, aStatus,
+ NS_LITERAL_STRING("SetPairingConfirmation"));
+ }
+
+private:
+ BluetoothReplyRunnable* mRunnable;
+};
+
bool
BluetoothServiceBluedroid::SetPairingConfirmationInternal(
const nsAString& aDeviceAddress, bool aConfirm,
@@ -1296,15 +1504,8 @@ BluetoothServiceBluedroid::SetPairingConfirmationInternal(
bt_bdaddr_t remoteAddress;
StringToBdAddressType(aDeviceAddress, &remoteAddress);
- int ret = sBtInterface->SspReply(&remoteAddress, (bt_ssp_variant_t)0,
- aConfirm, 0);
- if (ret != BT_STATUS_SUCCESS) {
- ReplyStatusError(aRunnable, ret,
- NS_LITERAL_STRING("SetPairingConfirmation"));
- } else {
- DispatchBluetoothReply(aRunnable, BluetoothValue(true), EmptyString());
- }
-
+ sBtInterface->SspReply(&remoteAddress, (bt_ssp_variant_t)0, aConfirm, 0,
+ new SspReplyResultHandler(aRunnable));
return true;
}
diff --git a/dom/bluetooth2/tests/marionette/head.js b/dom/bluetooth2/tests/marionette/head.js
index d73176f53b0..8fd146dd3d2 100644
--- a/dom/bluetooth2/tests/marionette/head.js
+++ b/dom/bluetooth2/tests/marionette/head.js
@@ -503,6 +503,64 @@ function waitForAdapterStateChanged(aAdapter, aStateChangesInOrder) {
return deferred.promise;
}
+/**
+ * Wait for an 'onattributechanged' event for a specified attribute and compare
+ * the new value with the expected value.
+ *
+ * Resolve if the specified event occurs. Never reject.
+ *
+ * Fulfill params: a BluetoothAttributeEvent with property attrs that contains
+ * changed BluetoothAdapterAttributes.
+ *
+ * @param aAdapter
+ * The BluetoothAdapter you want to use.
+ * @param aAttrName
+ * The name of the attribute of adapter.
+ * @param aExpectedValue
+ * The expected new value of the attribute.
+ *
+ * @return A deferred promise.
+ */
+function waitForAdapterAttributeChanged(aAdapter, aAttrName, aExpectedValue) {
+ let deferred = Promise.defer();
+
+ aAdapter.onattributechanged = function(aEvent) {
+ let i = aEvent.attrs.indexOf(aAttrName);
+ if (i >= 0) {
+ switch (aEvent.attrs[i]) {
+ case "state":
+ log(" 'state' changed to " + aAdapter.state);
+ is(aAdapter.state, aExpectedValue, "adapter.state");
+ break;
+ case "name":
+ log(" 'name' changed to " + aAdapter.name);
+ is(aAdapter.name, aExpectedValue, "adapter.name");
+ break;
+ case "address":
+ log(" 'address' changed to " + aAdapter.address);
+ is(aAdapter.address, aExpectedValue, "adapter.address");
+ break;
+ case "discoverable":
+ log(" 'discoverable' changed to " + aAdapter.discoverable);
+ is(aAdapter.discoverable, aExpectedValue, "adapter.discoverable");
+ break;
+ case "discovering":
+ log(" 'discovering' changed to " + aAdapter.discovering);
+ is(aAdapter.discovering, aExpectedValue, "adapter.discovering");
+ break;
+ case "unknown":
+ default:
+ ok(false, "Unknown attribute '" + aAttrName + "' changed." );
+ break;
+ }
+ aAdapter.onattributechanged = null;
+ deferred.resolve(aEvent);
+ }
+ };
+
+ return deferred.promise;
+}
+
/**
* Flush permission settings and call |finish()|.
*/
diff --git a/dom/bluetooth2/tests/marionette/manifest.ini b/dom/bluetooth2/tests/marionette/manifest.ini
index d3ed382f7f5..88c6fe50b95 100644
--- a/dom/bluetooth2/tests/marionette/manifest.ini
+++ b/dom/bluetooth2/tests/marionette/manifest.ini
@@ -5,3 +5,4 @@ qemu = false
[test_dom_BluetoothManager_API2.js]
[test_dom_BluetoothAdapter_enable_API2.js]
+[test_dom_BluetoothAdapter_setters_API2.js]
diff --git a/dom/bluetooth2/tests/marionette/test_dom_BluetoothAdapter_setters_API2.js b/dom/bluetooth2/tests/marionette/test_dom_BluetoothAdapter_setters_API2.js
new file mode 100644
index 00000000000..91293292d26
--- /dev/null
+++ b/dom/bluetooth2/tests/marionette/test_dom_BluetoothAdapter_setters_API2.js
@@ -0,0 +1,111 @@
+/* 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/. */
+
+///////////////////////////////////////////////////////////////////////////////
+// Test Purpose:
+// To verify that all setters of BluetoothAdapter (except for pairing related
+// APIs) can change properties correctly.
+//
+// Test Procedure:
+// [0] Set Bluetooth permission and enable default adapter.
+// [1] Verify the functionality of 'setName'.
+// [2] Verify the functionality of 'setDiscoverable'.
+// [3] Disable Bluetooth and collect changed attributes.
+// [4] Verify the changes of attributes when BT is disabled.
+// [5] Set properties when Bluetooth is disabled.
+// [6] Enable Bluetooth and collect changed attributes.
+// [7] Verify the changes of attributes when BT is enabled.
+// [8] Restore the original 'adapter.name'.
+// [9] Check the validity of setting properties to their present value.
+//
+// Test Coverage:
+// - BluetoothAdapter.setName()
+// - BluetoothAdapter.setDiscoverable()
+// - BluetoothAdapter.onattributechanged()
+// - BluetoothAdapter.state
+// - BluetoothAdapter.name
+// - BluetoothAdapter.discoverable
+//
+///////////////////////////////////////////////////////////////////////////////
+
+MARIONETTE_TIMEOUT = 60000;
+MARIONETTE_HEAD_JS = 'head.js';
+
+startBluetoothTest(true, function testCaseMain(aAdapter) {
+ log("Checking adapter attributes ...");
+
+ is(aAdapter.state, "enabled", "adapter.state");
+ isnot(aAdapter.address, "", "adapter.address");
+
+ // Since adapter has just been re-enabled, these properties should be 'false'.
+ is(aAdapter.discovering, false, "adapter.discovering");
+ is(aAdapter.discoverable, false, "adapter.discoverable at step [0]");
+
+ log("adapter.address: " + aAdapter.address);
+ log("adapter.name: " + aAdapter.name);
+
+ let originalName = aAdapter.name;
+ return Promise.resolve()
+ .then(function() {
+ log("[1] Set 'name' ... ");
+ let promises = [];
+ promises.push(waitForAdapterAttributeChanged(aAdapter, "name", originalName + "_modified"));
+ promises.push(aAdapter.setName(originalName + "_modified"));
+ return Promise.all(promises);
+ })
+ .then(function() {
+ log("[2] Set 'discoverable' ... ");
+ let promises = [];
+ promises.push(waitForAdapterAttributeChanged(aAdapter, "discoverable", !aAdapter.discoverable));
+ promises.push(aAdapter.setDiscoverable(!aAdapter.discoverable));
+ return Promise.all(promises);
+ })
+ .then(function() {
+ log("[3] Disable Bluetooth ...");
+ let promises = [];
+ promises.push(waitForAdapterStateChanged(aAdapter, ["disabling", "disabled"]));
+ promises.push(aAdapter.disable());
+ return Promise.all(promises);
+ })
+ .then(function(aResults) {
+ log("[4] Verify the changes of attributes ...");
+ isnot(aResults[0].indexOf("name"), -1, "Indicator of 'name' changed event");
+ isnot(aResults[0].indexOf("discoverable"), -1, "Indicator of 'discoverable' changed event");
+ is(aAdapter.name, "", "adapter.name");
+ is(aAdapter.discoverable, false, "adapter.discoverable at step [4]");
+ })
+ .then(() => log("[5] Set properties when Bluetooth is disabled ..."))
+ .then(() => aAdapter.setName(originalName))
+ .then(() => ok(false, "Failed to handle 'setName' when BT is disabled."),
+ () => aAdapter.setDiscoverable(true))
+ .then(() => ok(false, "Failed to handle 'setDiscoverable' when BT is disabled."),
+ () => null)
+ .then(function() {
+ log("[6] Enable Bluetooth ...");
+ let promises = [];
+ promises.push(waitForAdapterStateChanged(aAdapter, ["enabling", "enabled"]));
+ promises.push(aAdapter.enable());
+ return Promise.all(promises);
+ })
+ .then(function(aResults) {
+ log("[7] Verify the changes of attributes ...");
+ isnot(aResults[0].indexOf("name"), -1, "Indicator of 'name' changed event");
+ is(aAdapter.name, originalName + "_modified", "adapter.name");
+ is(aAdapter.discoverable, false, "adapter.discoverable at step [7]");
+ })
+ .then(function() {
+ log("[8] Restore the original 'name' ...");
+ let promises = [];
+ promises.push(waitForAdapterAttributeChanged(aAdapter, "name", originalName));
+ promises.push(aAdapter.setName(originalName));
+ return Promise.all(promises);
+ })
+ .then(function() {
+ log("[9] Check the validity of setting properties to their present value ...");
+ let promises = [];
+ promises.push(aAdapter.setName(aAdapter.name));
+ promises.push(aAdapter.setDiscoverable(aAdapter.discoverable));
+ return Promise.all(promises);
+ });
+});
diff --git a/dom/nfc/tests/marionette/test_nfc_error_messages.js b/dom/nfc/tests/marionette/test_nfc_error_messages.js
index afadd6f3e57..bf5ef15c1e6 100644
--- a/dom/nfc/tests/marionette/test_nfc_error_messages.js
+++ b/dom/nfc/tests/marionette/test_nfc_error_messages.js
@@ -4,7 +4,7 @@
'use strict';
/* globals log, is, ok, runTests, toggleNFC, runNextTest,
- SpecialPowers, nfc, enableRE0, MozNDEFRecord */
+ SpecialPowers, nfc, MozNDEFRecord, emulator */
const MARIONETTE_TIMEOUT = 60000;
const MARIONETTE_HEAD_JS = 'head.js';
@@ -27,7 +27,7 @@ let sessionTokens = [];
function testNfcNotEnabledError() {
log('testNfcNotEnabledError');
toggleNFC(true)
- .then(enableRE0)
+ .then(() => emulator.activateRE(0))
.then(registerAndFireOnpeerready)
.then(() => toggleNFC(false))
.then(() => sendNDEFExpectError(nfcPeers[0], 'NfcNotEnabledError'))
@@ -45,11 +45,10 @@ function testNfcNotEnabledError() {
function testNfcBadSessionIdError() {
log('testNfcBadSessionIdError');
toggleNFC(true)
- .then(enableRE0)
+ .then(() => emulator.activateRE(0))
.then(registerAndFireOnpeerready)
- .then(() => toggleNFC(false))
- .then(() => toggleNFC(true))
- .then(enableRE0)
+ .then(() => emulator.deactivate())
+ .then(() => emulator.activateRE(0))
.then(registerAndFireOnpeerready)
// we have 2 peers in nfcPeers array, peer0 has old/invalid session token
.then(() => sendNDEFExpectError(nfcPeers[0], 'NfcBadSessionIdError'))
@@ -66,7 +65,7 @@ function testNfcBadSessionIdError() {
function testNfcConnectError() {
log('testNfcConnectError');
toggleNFC(true)
- .then(enableRE0)
+ .then(() => emulator.activateRE(0))
.then(registerAndFireOnpeerready)
.then(() => connectToNFCTagExpectError(sessionTokens[0],
'NDEF',
@@ -84,9 +83,10 @@ function testNfcConnectError() {
function testNoErrorInTechMsg() {
log('testNoErrorInTechMsg');
toggleNFC(true)
- .then(enableRE0)
+ .then(() => emulator.activateRE(0))
.then(setTechDiscoveredHandler)
.then(setAndFireTechLostHandler)
+ .then(() => toggleNFC(false))
.then(endTest)
.catch(handleRejectedPromise);
}
@@ -201,8 +201,9 @@ function setAndFireTechLostHandler() {
window.navigator.mozSetMessageHandler('nfc-manager-tech-lost',
techLostHandler);
- // TODO should be refactored once Bug 1023079 lands
- toggleNFC(false);
+
+ // triggers tech-lost
+ emulator.deactivate();
return deferred.promise;
}