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; }