merge b2g-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2014-07-09 15:42:24 +02:00
commit aa155b98d6
17 changed files with 868 additions and 208 deletions

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0f9f11d0a6dadb3ea27160204bbe911c1ad69a6f"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c394b7b4205b6f1a6ca44915fc08650f3ad127ec"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0f9f11d0a6dadb3ea27160204bbe911c1ad69a6f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c394b7b4205b6f1a6ca44915fc08650f3ad127ec"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ee6e7320bb83409ebd4685fbd87a8ae033704182"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="276ce45e78b09c4a4ee643646f691d22804754c1">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0f9f11d0a6dadb3ea27160204bbe911c1ad69a6f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c394b7b4205b6f1a6ca44915fc08650f3ad127ec"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0f9f11d0a6dadb3ea27160204bbe911c1ad69a6f"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c394b7b4205b6f1a6ca44915fc08650f3ad127ec"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0f9f11d0a6dadb3ea27160204bbe911c1ad69a6f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c394b7b4205b6f1a6ca44915fc08650f3ad127ec"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ee6e7320bb83409ebd4685fbd87a8ae033704182"/>

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "4d2c0a0848326ad805ccc89f0a3893d35f90a9ef",
"revision": "8749f2b7d7998019d04618b46d28b5cb9d77aadb",
"repo_path": "/integration/gaia-central"
}

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0f9f11d0a6dadb3ea27160204bbe911c1ad69a6f"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c394b7b4205b6f1a6ca44915fc08650f3ad127ec"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0f9f11d0a6dadb3ea27160204bbe911c1ad69a6f"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c394b7b4205b6f1a6ca44915fc08650f3ad127ec"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="0f9f11d0a6dadb3ea27160204bbe911c1ad69a6f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c394b7b4205b6f1a6ca44915fc08650f3ad127ec"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="dc5ca96695cab87b4c2fcd7c9f046ae3415a70a5"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="ee6e7320bb83409ebd4685fbd87a8ae033704182"/>

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="0f9f11d0a6dadb3ea27160204bbe911c1ad69a6f"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c394b7b4205b6f1a6ca44915fc08650f3ad127ec"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="230f11aff069d90d20fc2dc63b48e9ae3d4bdcd1"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -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<class T>
struct interface_traits
{ };
//
// Result handling
//
template <typename Obj, typename Res>
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<Obj> mObj;
void (Obj::*mMethod)();
};
template <typename Obj, typename Res, typename Arg1>
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<Obj> mObj;
void (Obj::*mMethod)(Arg1);
Arg1 mArg1;
};
//
// Socket Interface
//
@ -371,6 +428,36 @@ BluetoothAvrcpInterface::SetVolume(uint8_t aVolume)
// Bluetooth Core Interface
//
typedef
BluetoothInterfaceRunnable0<BluetoothResultHandler, void>
BluetoothResultRunnable;
typedef
BluetoothInterfaceRunnable1<BluetoothResultHandler, void, int>
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 */

View File

@ -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 */

View File

@ -57,6 +57,7 @@ static InfallibleTArray<nsString> sAdapterBondedAddressArray;
// Static variables below should only be used on *main thread*
static BluetoothInterface* sBtInterface;
static nsTArray<nsRefPtr<BluetoothProfileController> > sControllerArray;
static InfallibleTArray<BluetoothNamedValue> sRemoteDevicesPack;
static nsTArray<int> sRequestedDeviceCountArray;
static nsTArray<nsRefPtr<BluetoothReplyRunnable> > sChangeAdapterStateRunnableArray;
static nsTArray<nsRefPtr<BluetoothReplyRunnable> > 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<BluetoothNamedValue> 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<nsRunnable> 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();
return sBtInterface->Enable();
sBtInterface->Enable(new EnableResultHandler());
}
void OnError(int aStatus) MOZ_OVERRIDE
{
MOZ_ASSERT(NS_IsMainThread());
BT_LOGR("BluetoothInterface::Init failed: %d", aStatus);
sBtInterface = nullptr;
nsRefPtr<nsRunnable> 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<nsRunnable> runnable =
new BluetoothService::ToggleBtAck(aShouldEnable);
nsRefPtr<nsRunnable> 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<nsRunnable> 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<nsRunnable> 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<nsRunnable> 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<nsRunnable> 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,21 +1142,17 @@ 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);
}
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);
}
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(
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());
}
(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;
}

View File

@ -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()|.
*/

View File

@ -5,3 +5,4 @@ qemu = false
[test_dom_BluetoothManager_API2.js]
[test_dom_BluetoothAdapter_enable_API2.js]
[test_dom_BluetoothAdapter_setters_API2.js]

View File

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

View File

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