merge b2g-inbound to mozilla-central a=merge

This commit is contained in:
Carsten "Tomcat" Book 2015-02-16 15:56:10 +01:00
commit 4e0859e7c2
59 changed files with 1401 additions and 63 deletions

View File

@ -1114,8 +1114,10 @@ pref("dom.requestSync.enabled", true);
pref("gfx.vsync.hw-vsync.enabled", true);
pref("gfx.vsync.compositor", true);
pref("gfx.touch.resample", true);
pref("gfx.vsync.refreshdriver", true);
#else
pref("gfx.vsync.hw-vsync.enabled", false);
pref("gfx.vsync.compositor", false);
pref("gfx.touch.resample", false);
pref("gfx.vsync.refreshdriver", false);
#endif

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="cdaa0a4ac28c781709df8c318ed079e9e475503a">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f0b93e0668ef9565bd6f050b15b4f794d59feb65"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ae02fbdeae77b2002cebe33c61aedeee4b9439fd"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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="f0b93e0668ef9565bd6f050b15b4f794d59feb65"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ae02fbdeae77b2002cebe33c61aedeee4b9439fd"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="eb1795a9002eb142ac58c8d68f8f4ba094af07ca"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f0b93e0668ef9565bd6f050b15b4f794d59feb65"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ae02fbdeae77b2002cebe33c61aedeee4b9439fd"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d0d11d190ccc50d7d66009bcc896ad4b42d3f0d"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="cdaa0a4ac28c781709df8c318ed079e9e475503a">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f0b93e0668ef9565bd6f050b15b4f794d59feb65"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ae02fbdeae77b2002cebe33c61aedeee4b9439fd"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

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="f0b93e0668ef9565bd6f050b15b4f794d59feb65"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="ae02fbdeae77b2002cebe33c61aedeee4b9439fd"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="eb1795a9002eb142ac58c8d68f8f4ba094af07ca"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="cdaa0a4ac28c781709df8c318ed079e9e475503a">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f0b93e0668ef9565bd6f050b15b4f794d59feb65"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ae02fbdeae77b2002cebe33c61aedeee4b9439fd"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f0b93e0668ef9565bd6f050b15b4f794d59feb65"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ae02fbdeae77b2002cebe33c61aedeee4b9439fd"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d0d11d190ccc50d7d66009bcc896ad4b42d3f0d"/>

View File

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "f0b93e0668ef9565bd6f050b15b4f794d59feb65",
"git_revision": "ae02fbdeae77b2002cebe33c61aedeee4b9439fd",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "d170342f8e1837435749392fc2bded3b9fee01d4",
"revision": "62d026a98ea42f2b93de000e8d0d4f1254f86730",
"repo_path": "integration/gaia-central"
}

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f0b93e0668ef9565bd6f050b15b4f794d59feb65"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ae02fbdeae77b2002cebe33c61aedeee4b9439fd"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="fe893bb760a3bb64375f62fdf4762a58c59df9ef"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="8d0d11d190ccc50d7d66009bcc896ad4b42d3f0d"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="7f2ee9f4cb926684883fc2a2e407045fd9db2199">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="f0b93e0668ef9565bd6f050b15b4f794d59feb65"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="ae02fbdeae77b2002cebe33c61aedeee4b9439fd"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2262d4a77d4f46ab230fd747bb91e9b77bad36cb"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>

View File

@ -708,6 +708,7 @@ GK_ATOM(onconfigurationchange, "onconfigurationchange")
GK_ATOM(onconnect, "onconnect")
GK_ATOM(onconnected, "onconnected")
GK_ATOM(onconnecting, "onconnecting")
GK_ATOM(onconnectionstatechanged, "onconnectionstatechanged")
GK_ATOM(oncontextmenu, "oncontextmenu")
GK_ATOM(oncopy, "oncopy")
GK_ATOM(oncurrentchannelchanged, "oncurrentchannelchanged")

View File

@ -152,6 +152,10 @@ DOMInterfaces = {
'nativeType': 'mozilla::dom::bluetooth::BluetoothDiscoveryHandle',
},
'BluetoothGatt': {
'nativeType': 'mozilla::dom::bluetooth::BluetoothGatt',
},
'BluetoothManager': {
'nativeType': 'mozilla::dom::bluetooth::BluetoothManager',
},

View File

@ -196,6 +196,12 @@ extern bool gBluetoothDebugFlag;
*/
#define REQUEST_MEDIA_PLAYSTATUS_ID "requestmediaplaystatus"
/**
* When a remote BLE device gets connected / disconnected, we'll dispatch an
* event
*/
#define GATT_CONNECTION_STATE_CHANGED_ID "connectionstatechanged"
// Bluetooth address format: xx:xx:xx:xx:xx:xx (or xx_xx_xx_xx_xx_xx)
#define BLUETOOTH_ADDRESS_LENGTH 17
#define BLUETOOTH_ADDRESS_NONE "00:00:00:00:00:00"

View File

@ -4,15 +4,16 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BluetoothClassOfDevice.h"
#include "BluetoothDevice.h"
#include "BluetoothReplyRunnable.h"
#include "BluetoothService.h"
#include "BluetoothUtils.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/BluetoothAttributeEvent.h"
#include "mozilla/dom/BluetoothDevice2Binding.h"
#include "mozilla/dom/bluetooth/BluetoothClassOfDevice.h"
#include "mozilla/dom/bluetooth/BluetoothDevice.h"
#include "mozilla/dom/bluetooth/BluetoothGatt.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/Promise.h"
using namespace mozilla;
@ -20,7 +21,10 @@ using namespace mozilla::dom;
USING_BLUETOOTH_NAMESPACE
NS_IMPL_CYCLE_COLLECTION_INHERITED(BluetoothDevice, DOMEventTargetHelper, mCod)
NS_IMPL_CYCLE_COLLECTION_INHERITED(BluetoothDevice,
DOMEventTargetHelper,
mCod,
mGatt)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothDevice)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
@ -302,6 +306,19 @@ BluetoothDevice::DispatchAttributeEvent(const nsTArray<nsString>& aTypes)
DispatchTrustedEvent(event);
}
BluetoothGatt*
BluetoothDevice::GetGatt()
{
NS_ENSURE_TRUE(mType == BluetoothDeviceType::Le ||
mType == BluetoothDeviceType::Dual,
nullptr);
if (!mGatt) {
mGatt = new BluetoothGatt(GetOwner(), mAddress);
}
return mGatt;
}
JSObject*
BluetoothDevice::WrapObject(JSContext* aContext)
{

View File

@ -10,7 +10,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/BluetoothDevice2Binding.h"
#include "BluetoothCommon.h"
#include "mozilla/dom/bluetooth/BluetoothCommon.h"
#include "nsString.h"
#include "nsCOMPtr.h"
@ -23,6 +23,7 @@ namespace dom {
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothClassOfDevice;
class BluetoothGatt;
class BluetoothNamedValue;
class BluetoothValue;
class BluetoothSignal;
@ -69,6 +70,8 @@ public:
return mType;
}
BluetoothGatt* GetGatt();
/****************************************************************************
* Event Handlers
***************************************************************************/
@ -173,6 +176,11 @@ private:
* Type of this device. Can be unknown/classic/le/dual.
*/
BluetoothDeviceType mType;
/**
* GATT client object to interact with the remote device.
*/
nsRefPtr<BluetoothGatt> mGatt;
};
END_BLUETOOTH_NAMESPACE

View File

@ -0,0 +1,217 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BluetoothReplyRunnable.h"
#include "BluetoothService.h"
#include "BluetoothUtils.h"
#include "mozilla/dom/bluetooth/BluetoothGatt.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/dom/BluetoothGattBinding.h"
#include "mozilla/dom/Promise.h"
#include "nsIUUIDGenerator.h"
#include "nsServiceManagerUtils.h"
using namespace mozilla;
using namespace mozilla::dom;
USING_BLUETOOTH_NAMESPACE
NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothGatt)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothGatt,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothGatt,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothGatt)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(BluetoothGatt, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(BluetoothGatt, DOMEventTargetHelper)
BluetoothGatt::BluetoothGatt(nsPIDOMWindow* aWindow,
const nsAString& aDeviceAddr)
: DOMEventTargetHelper(aWindow)
, mAppUuid(EmptyString())
, mClientIf(0)
, mConnectionState(BluetoothConnectionState::Disconnected)
, mDeviceAddr(aDeviceAddr)
{
MOZ_ASSERT(aWindow);
MOZ_ASSERT(!mDeviceAddr.IsEmpty());
}
BluetoothGatt::~BluetoothGatt()
{
BluetoothService* bs = BluetoothService::Get();
// bs can be null on shutdown, where destruction might happen.
NS_ENSURE_TRUE_VOID(bs);
if (mClientIf > 0) {
nsRefPtr<BluetoothVoidReplyRunnable> result =
new BluetoothVoidReplyRunnable(nullptr);
bs->UnregisterGattClientInternal(mClientIf, result);
}
bs->UnregisterBluetoothSignalHandler(mAppUuid, this);
}
void
BluetoothGatt::GenerateUuid(nsAString &aUuidString)
{
nsresult rv;
nsCOMPtr<nsIUUIDGenerator> uuidGenerator =
do_GetService("@mozilla.org/uuid-generator;1", &rv);
NS_ENSURE_SUCCESS_VOID(rv);
nsID uuid;
rv = uuidGenerator->GenerateUUIDInPlace(&uuid);
NS_ENSURE_SUCCESS_VOID(rv);
// Build a string in {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} format
char uuidBuffer[NSID_LENGTH];
uuid.ToProvidedString(uuidBuffer);
NS_ConvertASCIItoUTF16 uuidString(uuidBuffer);
// Remove {} and the null terminator
aUuidString.Assign(Substring(uuidString, 1, NSID_LENGTH - 3));
}
void
BluetoothGatt::DisconnectFromOwner()
{
DOMEventTargetHelper::DisconnectFromOwner();
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
if (mClientIf > 0) {
nsRefPtr<BluetoothVoidReplyRunnable> result =
new BluetoothVoidReplyRunnable(nullptr);
bs->UnregisterGattClientInternal(mClientIf, result);
}
bs->UnregisterBluetoothSignalHandler(mAppUuid, this);
}
already_AddRefed<Promise>
BluetoothGatt::Connect(ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
if (!global) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
BT_ENSURE_TRUE_REJECT(
mConnectionState == BluetoothConnectionState::Disconnected,
NS_ERROR_DOM_INVALID_STATE_ERR);
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, NS_ERROR_NOT_AVAILABLE);
if (mAppUuid.IsEmpty()) {
GenerateUuid(mAppUuid);
BT_ENSURE_TRUE_REJECT(!mAppUuid.IsEmpty(),
NS_ERROR_DOM_OPERATION_ERR);
bs->RegisterBluetoothSignalHandler(mAppUuid, this);
}
UpdateConnectionState(BluetoothConnectionState::Connecting);
nsRefPtr<BluetoothReplyRunnable> result =
new BluetoothVoidReplyRunnable(nullptr /* DOMRequest */,
promise,
NS_LITERAL_STRING("ConnectGattClient"));
bs->ConnectGattClientInternal(mAppUuid,
mDeviceAddr,
result);
return promise.forget();
}
already_AddRefed<Promise>
BluetoothGatt::Disconnect(ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetParentObject());
if (!global) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
nsRefPtr<Promise> promise = Promise::Create(global, aRv);
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
BT_ENSURE_TRUE_REJECT(
mConnectionState == BluetoothConnectionState::Connected,
NS_ERROR_DOM_INVALID_STATE_ERR);
BluetoothService* bs = BluetoothService::Get();
BT_ENSURE_TRUE_REJECT(bs, NS_ERROR_NOT_AVAILABLE);
UpdateConnectionState(BluetoothConnectionState::Disconnecting);
nsRefPtr<BluetoothReplyRunnable> result =
new BluetoothVoidReplyRunnable(nullptr /* DOMRequest */,
promise,
NS_LITERAL_STRING("DisconnectGattClient"));
bs->DisconnectGattClientInternal(mAppUuid, mDeviceAddr, result);
return promise.forget();
}
void
BluetoothGatt::UpdateConnectionState(BluetoothConnectionState aState)
{
BT_API2_LOGR("GATT connection state changes to: %d", int(aState));
mConnectionState = aState;
// Dispatch connectionstatechanged event to application
nsCOMPtr<nsIDOMEvent> event;
nsresult rv = NS_NewDOMEvent(getter_AddRefs(event), this, nullptr, nullptr);
NS_ENSURE_SUCCESS_VOID(rv);
rv = event->InitEvent(NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
false,
false);
NS_ENSURE_SUCCESS_VOID(rv);
DispatchTrustedEvent(event);
}
void
BluetoothGatt::Notify(const BluetoothSignal& aData)
{
BT_LOGD("[D] %s", NS_ConvertUTF16toUTF8(aData.name()).get());
BluetoothValue v = aData.value();
if (aData.name().EqualsLiteral("ClientRegistered")) {
MOZ_ASSERT(v.type() == BluetoothValue::Tuint32_t);
mClientIf = v.get_uint32_t();
} else if (aData.name().EqualsLiteral("ClientUnregistered")) {
mClientIf = 0;
} else if (aData.name().EqualsLiteral(GATT_CONNECTION_STATE_CHANGED_ID)) {
MOZ_ASSERT(v.type() == BluetoothValue::Tbool);
BluetoothConnectionState state =
v.get_bool() ? BluetoothConnectionState::Connected
: BluetoothConnectionState::Disconnected;
UpdateConnectionState(state);
} else {
BT_WARNING("Not handling GATT signal: %s",
NS_ConvertUTF16toUTF8(aData.name()).get());
}
}
JSObject*
BluetoothGatt::WrapObject(JSContext* aContext)
{
return BluetoothGattBinding::Wrap(aContext, this);
}

View File

@ -0,0 +1,116 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_bluetoothgatt_h__
#define mozilla_dom_bluetooth_bluetoothgatt_h__
#include "mozilla/Attributes.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/BluetoothGattBinding.h"
#include "mozilla/dom/bluetooth/BluetoothCommon.h"
#include "nsCOMPtr.h"
namespace mozilla {
namespace dom {
class Promise;
}
}
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothReplyRunnable;
class BluetoothService;
class BluetoothSignal;
class BluetoothValue;
class BluetoothGatt MOZ_FINAL : public DOMEventTargetHelper
, public BluetoothSignalObserver
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BluetoothGatt, DOMEventTargetHelper)
/****************************************************************************
* Attribute Getters
***************************************************************************/
BluetoothConnectionState ConnectionState() const
{
return mConnectionState;
}
/****************************************************************************
* Event Handlers
***************************************************************************/
IMPL_EVENT_HANDLER(connectionstatechanged);
/****************************************************************************
* Methods (Web API Implementation)
***************************************************************************/
already_AddRefed<Promise> Connect(ErrorResult& aRv);
already_AddRefed<Promise> Disconnect(ErrorResult& aRv);
/****************************************************************************
* Others
***************************************************************************/
void Notify(const BluetoothSignal& aParam); // BluetoothSignalObserver
nsPIDOMWindow* GetParentObject() const
{
return GetOwner();
}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
virtual void DisconnectFromOwner() MOZ_OVERRIDE;
BluetoothGatt(nsPIDOMWindow* aOwner,
const nsAString& aDeviceAddr);
private:
~BluetoothGatt();
/**
* Update mConnectionState to aState and fire
* connectionstatechanged event to the application.
*
* @param aState [in] New connection state
*/
void UpdateConnectionState(BluetoothConnectionState aState);
/**
* Generate a random uuid.
*
* @param aUuidString [out] String to store the generated uuid.
*/
void GenerateUuid(nsAString &aUuidString);
/****************************************************************************
* Variables
***************************************************************************/
/**
* Random generated UUID of this GATT client.
*/
nsString mAppUuid;
/**
* Id of the GATT client interface given by bluetooth stack.
* 0 if the client is not registered yet, nonzero otherwise.
*/
int mClientIf;
/**
* Connection state of this remote device.
*/
BluetoothConnectionState mConnectionState;
/**
* Address of the remote device.
*/
nsString mDeviceAddr;
};
END_BLUETOOTH_NAMESPACE
#endif

View File

@ -307,6 +307,31 @@ public:
SendInputMessage(const nsAString& aDeviceAddresses,
const nsAString& aMessage) = 0;
/**
* Connect to a remote GATT server. (platform specific implementation)
*/
virtual void
ConnectGattClientInternal(const nsAString& aAppUuid,
const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable) = 0;
/**
* Disconnect GATT client from a remote GATT server.
* (platform specific implementation)
*/
virtual void
DisconnectGattClientInternal(const nsAString& aAppUuid,
const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable) = 0;
/**
* Unregister a GATT client. (platform specific implementation)
*/
virtual void
UnregisterGattClientInternal(int aClientIf,
BluetoothReplyRunnable* aRunnable) = 0;
bool
IsEnabled() const
{

View File

@ -40,6 +40,30 @@ UuidToString(const BluetoothUuid& aUuid, nsAString& aString)
aString.AssignLiteral(uuidStr);
}
void
StringToUuid(const char* aString, BluetoothUuid& aUuid)
{
uint32_t uuid0, uuid4;
uint16_t uuid1, uuid2, uuid3, uuid5;
sscanf(aString, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
&uuid0, &uuid1, &uuid2, &uuid3, &uuid4, &uuid5);
uuid0 = htonl(uuid0);
uuid1 = htons(uuid1);
uuid2 = htons(uuid2);
uuid3 = htons(uuid3);
uuid4 = htonl(uuid4);
uuid5 = htons(uuid5);
memcpy(&aUuid.mUuid[0], &uuid0, 4);
memcpy(&aUuid.mUuid[4], &uuid1, 2);
memcpy(&aUuid.mUuid[6], &uuid2, 2);
memcpy(&aUuid.mUuid[8], &uuid3, 2);
memcpy(&aUuid.mUuid[10], &uuid4, 4);
memcpy(&aUuid.mUuid[14], &uuid5, 2);
}
bool
SetJsObject(JSContext* aContext,
const BluetoothValue& aValue,

View File

@ -19,6 +19,14 @@ class BluetoothReplyRunnable;
void
UuidToString(const BluetoothUuid& aUuid, nsAString& aString);
/**
* Convert xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx uuid string to BluetoothUuid object.
* This utility function is used by gecko internal only to convert uuid string
* created by gecko back to BluetoothUuid representation.
*/
void
StringToUuid(const char* aString, BluetoothUuid& aUuid);
bool
SetJsObject(JSContext* aContext,
const BluetoothValue& aValue,

View File

@ -5,16 +5,28 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BluetoothGattManager.h"
#include "BluetoothCommon.h"
#include "BluetoothUtils.h"
#include "BluetoothInterface.h"
#include "BluetoothCommon.h"
#include "BluetoothInterface.h"
#include "BluetoothReplyRunnable.h"
#include "BluetoothService.h"
#include "BluetoothUtils.h"
#include "MainThreadUtils.h"
#include "mozilla/Services.h"
#include "mozilla/StaticPtr.h"
#include "MainThreadUtils.h"
#include "nsIObserverService.h"
#include "nsThreadUtils.h"
#define ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(runnable) \
do { \
if (!sBluetoothGattInterface) { \
NS_NAMED_LITERAL_STRING(errorStr, \
"BluetoothGattClientInterface is not ready"); \
DispatchBluetoothReply(runnable, BluetoothValue(), errorStr); \
return; \
} \
} while(0)
using namespace mozilla;
USING_BLUETOOTH_NAMESPACE
@ -26,9 +38,58 @@ namespace {
bool BluetoothGattManager::mInShutdown = false;
/*
* Static functions
*/
class BluetoothGattClient;
static StaticAutoPtr<nsTArray<nsRefPtr<BluetoothGattClient> > > sClients;
class BluetoothGattClient MOZ_FINAL : public nsISupports
{
public:
NS_DECL_ISUPPORTS
BluetoothGattClient(const nsAString& aAppUuid, const nsAString& aDeviceAddr)
: mAppUuid(aAppUuid)
, mDeviceAddr(aDeviceAddr)
, mClientIf(0)
, mConnId(0)
{ }
~BluetoothGattClient()
{
mConnectRunnable = nullptr;
mDisconnectRunnable = nullptr;
mUnregisterClientRunnable = nullptr;
}
nsString mAppUuid;
nsString mDeviceAddr;
int mClientIf;
int mConnId;
nsRefPtr<BluetoothReplyRunnable> mConnectRunnable;
nsRefPtr<BluetoothReplyRunnable> mDisconnectRunnable;
nsRefPtr<BluetoothReplyRunnable> mUnregisterClientRunnable;
};
NS_IMPL_ISUPPORTS0(BluetoothGattClient)
class UuidComparator
{
public:
bool Equals(const nsRefPtr<BluetoothGattClient>& aClient,
const nsAString& aAppUuid) const
{
return aClient->mAppUuid.Equals(aAppUuid);
}
};
class ClientIfComparator
{
public:
bool Equals(const nsRefPtr<BluetoothGattClient>& aClient,
int aClientIf) const
{
return aClient->mClientIf == aClientIf;
}
};
BluetoothGattManager*
BluetoothGattManager::Get()
@ -103,6 +164,10 @@ BluetoothGattManager::InitGattInterface(BluetoothProfileResultHandler* aRes)
sBluetoothGattInterface->GetBluetoothGattClientInterface();
NS_ENSURE_TRUE_VOID(sBluetoothGattClientInterface);
if (!sClients) {
sClients = new nsTArray<nsRefPtr<BluetoothGattClient> >;
}
BluetoothGattManager* gattManager = BluetoothGattManager::Get();
sBluetoothGattInterface->Init(gattManager,
new InitGattResultHandler(aRes));
@ -129,6 +194,8 @@ public:
{
sBluetoothGattClientInterface = nullptr;
sBluetoothGattInterface = nullptr;
sClients = nullptr;
if (mRes) {
mRes->Deinit();
}
@ -176,6 +243,265 @@ BluetoothGattManager::DeinitGattInterface(BluetoothProfileResultHandler* aRes)
}
}
class BluetoothGattManager::RegisterClientResultHandler MOZ_FINAL
: public BluetoothGattClientResultHandler
{
public:
RegisterClientResultHandler(BluetoothGattClient* aClient)
: mClient(aClient)
{
MOZ_ASSERT(mClient);
}
void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
{
BT_WARNING("BluetoothGattClientInterface::RegisterClient failed: %d",
(int)aStatus);
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
// Notify BluetoothGatt for client disconnected
BluetoothSignal signal(
NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
mClient->mAppUuid,
BluetoothValue(false)); // Disconnected
bs->DistributeSignal(signal);
// Reject the connect request
if (mClient->mConnectRunnable) {
NS_NAMED_LITERAL_STRING(errorStr, "Register GATT client failed");
DispatchBluetoothReply(mClient->mConnectRunnable,
BluetoothValue(),
errorStr);
mClient->mConnectRunnable = nullptr;
}
sClients->RemoveElement(mClient);
}
private:
nsRefPtr<BluetoothGattClient> mClient;
};
class BluetoothGattManager::UnregisterClientResultHandler MOZ_FINAL
: public BluetoothGattClientResultHandler
{
public:
UnregisterClientResultHandler(BluetoothGattClient* aClient)
: mClient(aClient)
{
MOZ_ASSERT(mClient);
}
void UnregisterClient() MOZ_OVERRIDE
{
MOZ_ASSERT(mClient->mUnregisterClientRunnable);
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
// Notify BluetoothGatt to clear the clientIf
BluetoothSignal signal(
NS_LITERAL_STRING("ClientUnregistered"),
mClient->mAppUuid,
BluetoothValue(true));
bs->DistributeSignal(signal);
// Resolve the unregister request
DispatchBluetoothReply(mClient->mUnregisterClientRunnable,
BluetoothValue(true),
EmptyString());
mClient->mUnregisterClientRunnable = nullptr;
sClients->RemoveElement(mClient);
}
void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
{
BT_WARNING("BluetoothGattClientInterface::UnregisterClient failed: %d",
(int)aStatus);
MOZ_ASSERT(mClient->mUnregisterClientRunnable);
// Reject the unregister request
NS_NAMED_LITERAL_STRING(errorStr, "Unregister GATT client failed");
DispatchBluetoothReply(mClient->mUnregisterClientRunnable,
BluetoothValue(),
errorStr);
mClient->mUnregisterClientRunnable = nullptr;
}
private:
nsRefPtr<BluetoothGattClient> mClient;
};
void
BluetoothGattManager::UnregisterClient(int aClientIf,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aRunnable);
ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);
size_t index = sClients->IndexOf(aClientIf, 0 /* Start */,
ClientIfComparator());
// Reject the unregister request if the client is not found
if (index == sClients->NoIndex) {
NS_NAMED_LITERAL_STRING(errorStr, "Unregister GATT client failed");
DispatchBluetoothReply(aRunnable,
BluetoothValue(),
errorStr);
return;
}
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
client->mUnregisterClientRunnable = aRunnable;
sBluetoothGattClientInterface->UnregisterClient(
aClientIf,
new UnregisterClientResultHandler(client));
}
class BluetoothGattManager::ConnectResultHandler MOZ_FINAL
: public BluetoothGattClientResultHandler
{
public:
ConnectResultHandler(BluetoothGattClient* aClient)
: mClient(aClient)
{
MOZ_ASSERT(mClient);
}
void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
{
BT_WARNING("BluetoothGattClientInterface::Connect failed: %d",
(int)aStatus);
MOZ_ASSERT(mClient->mConnectRunnable);
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
// Notify BluetoothGatt for client disconnected
BluetoothSignal signal(
NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
mClient->mAppUuid,
BluetoothValue(false)); // Disconnected
bs->DistributeSignal(signal);
// Reject the connect request
NS_NAMED_LITERAL_STRING(errorStr, "Connect failed");
DispatchBluetoothReply(mClient->mConnectRunnable,
BluetoothValue(),
errorStr);
mClient->mConnectRunnable = nullptr;
}
private:
nsRefPtr<BluetoothGattClient> mClient;
};
void
BluetoothGattManager::Connect(const nsAString& aAppUuid,
const nsAString& aDeviceAddr,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aRunnable);
ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);
size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
if (index == sClients->NoIndex) {
index = sClients->Length();
sClients->AppendElement(new BluetoothGattClient(aAppUuid, aDeviceAddr));
}
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
client->mConnectRunnable = aRunnable;
if (client->mClientIf > 0) {
sBluetoothGattClientInterface->Connect(client->mClientIf,
aDeviceAddr,
true, // direct connect
new ConnectResultHandler(client));
} else {
BluetoothUuid uuid;
StringToUuid(NS_ConvertUTF16toUTF8(aAppUuid).get(), uuid);
// connect will be proceeded after client registered
sBluetoothGattClientInterface->RegisterClient(
uuid, new RegisterClientResultHandler(client));
}
}
class BluetoothGattManager::DisconnectResultHandler MOZ_FINAL
: public BluetoothGattClientResultHandler
{
public:
DisconnectResultHandler(BluetoothGattClient* aClient)
: mClient(aClient)
{
MOZ_ASSERT(mClient);
}
void OnError(BluetoothStatus aStatus) MOZ_OVERRIDE
{
BT_WARNING("BluetoothGattClientInterface::Disconnect failed: %d",
(int)aStatus);
MOZ_ASSERT(mClient->mDisconnectRunnable);
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
// Notify BluetoothGatt that the client remains connected
BluetoothSignal signal(
NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
mClient->mAppUuid,
BluetoothValue(true)); // Connected
bs->DistributeSignal(signal);
// Reject the disconnect request
NS_NAMED_LITERAL_STRING(errorStr, "Disconnect failed");
DispatchBluetoothReply(mClient->mDisconnectRunnable,
BluetoothValue(),
errorStr);
mClient->mDisconnectRunnable = nullptr;
}
private:
nsRefPtr<BluetoothGattClient> mClient;
};
void
BluetoothGattManager::Disconnect(const nsAString& aAppUuid,
const nsAString& aDeviceAddr,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aRunnable);
ENSURE_GATT_CLIENT_INTF_IS_READY_VOID(aRunnable);
size_t index = sClients->IndexOf(aAppUuid, 0 /* Start */, UuidComparator());
// Reject the disconnect request if the client is not found
if (index == sClients->NoIndex) {
NS_NAMED_LITERAL_STRING(errorStr, "Disconnect failed");
DispatchBluetoothReply(aRunnable, BluetoothValue(), errorStr);
return;
}
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
client->mDisconnectRunnable = aRunnable;
sBluetoothGattClientInterface->Disconnect(
client->mClientIf,
aDeviceAddr,
client->mConnId,
new DisconnectResultHandler(client));
}
//
// Notification Handlers
//
@ -183,7 +509,60 @@ void
BluetoothGattManager::RegisterClientNotification(int aStatus,
int aClientIf,
const BluetoothUuid& aAppUuid)
{ }
{
BT_API2_LOGR("Client Registered, clientIf = %d", aClientIf);
MOZ_ASSERT(NS_IsMainThread());
nsString uuid;
UuidToString(aAppUuid, uuid);
size_t index = sClients->IndexOf(uuid, 0 /* Start */, UuidComparator());
NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
if (aStatus) { // operation failed
BT_API2_LOGR(
"RegisterClient failed, clientIf = %d, status = %d, appUuid = %s",
aClientIf, aStatus, NS_ConvertUTF16toUTF8(uuid).get());
// Notify BluetoothGatt for client disconnected
BluetoothSignal signal(
NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
uuid, BluetoothValue(false)); // Disconnected
bs->DistributeSignal(signal);
// Reject the connect request
if (client->mConnectRunnable) {
NS_NAMED_LITERAL_STRING(errorStr,
"Connect failed due to registration failed");
DispatchBluetoothReply(client->mConnectRunnable,
BluetoothValue(),
errorStr);
client->mConnectRunnable = nullptr;
}
sClients->RemoveElement(client);
return;
}
client->mClientIf = aClientIf;
// Notify BluetoothGatt to update the clientIf
BluetoothSignal signal(
NS_LITERAL_STRING("ClientRegistered"),
uuid, BluetoothValue(uint32_t(aClientIf)));
bs->DistributeSignal(signal);
// Client just registered, proceed remaining connect request.
if (client->mConnectRunnable) {
sBluetoothGattClientInterface->Connect(
aClientIf, client->mDeviceAddr, true /* direct connect */,
new ConnectResultHandler(client));
}
}
void
BluetoothGattManager::ScanResultNotification(
@ -195,15 +574,114 @@ void
BluetoothGattManager::ConnectNotification(int aConnId,
int aStatus,
int aClientIf,
const nsAString& aBdAddr)
{ }
const nsAString& aDeviceAddr)
{
BT_API2_LOGR();
MOZ_ASSERT(NS_IsMainThread());
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
size_t index = sClients->IndexOf(aClientIf, 0 /* Start */,
ClientIfComparator());
NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
if (aStatus) { // operation failed
BT_API2_LOGR("Connect failed, clientIf = %d, connId = %d, status = %d",
aClientIf, aConnId, aStatus);
// Notify BluetoothGatt that the client remains disconnected
BluetoothSignal signal(
NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
client->mAppUuid,
BluetoothValue(false)); // Disconnected
bs->DistributeSignal(signal);
// Reject the connect request
if (client->mConnectRunnable) {
NS_NAMED_LITERAL_STRING(errorStr, "Connect failed");
DispatchBluetoothReply(client->mConnectRunnable,
BluetoothValue(),
errorStr);
client->mConnectRunnable = nullptr;
}
return;
}
client->mConnId = aConnId;
// Notify BluetoothGatt for client connected
BluetoothSignal signal(
NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
client->mAppUuid,
BluetoothValue(true)); // Connected
bs->DistributeSignal(signal);
// Resolve the connect request
if (client->mConnectRunnable) {
DispatchBluetoothReply(client->mConnectRunnable,
BluetoothValue(true),
EmptyString());
client->mConnectRunnable = nullptr;
}
}
void
BluetoothGattManager::DisconnectNotification(int aConnId,
int aStatus,
int aClientIf,
const nsAString& aBdAddr)
{ }
const nsAString& aDeviceAddr)
{
BT_API2_LOGR();
MOZ_ASSERT(NS_IsMainThread());
BluetoothService* bs = BluetoothService::Get();
NS_ENSURE_TRUE_VOID(bs);
size_t index = sClients->IndexOf(aClientIf, 0 /* Start */,
ClientIfComparator());
NS_ENSURE_TRUE_VOID(index != sClients->NoIndex);
nsRefPtr<BluetoothGattClient> client = sClients->ElementAt(index);
if (aStatus) { // operation failed
// Notify BluetoothGatt that the client remains connected
BluetoothSignal signal(
NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
client->mAppUuid,
BluetoothValue(true)); // Connected
bs->DistributeSignal(signal);
// Reject the disconnect request
if (client->mDisconnectRunnable) {
NS_NAMED_LITERAL_STRING(errorStr, "Disconnect failed");
DispatchBluetoothReply(client->mDisconnectRunnable,
BluetoothValue(),
errorStr);
client->mDisconnectRunnable = nullptr;
}
return;
}
client->mConnId = 0;
// Notify BluetoothGatt for client disconnected
BluetoothSignal signal(
NS_LITERAL_STRING(GATT_CONNECTION_STATE_CHANGED_ID),
client->mAppUuid,
BluetoothValue(false)); // Disconnected
bs->DistributeSignal(signal);
// Resolve the disconnect request
if (client->mDisconnectRunnable) {
DispatchBluetoothReply(client->mDisconnectRunnable,
BluetoothValue(true),
EmptyString());
client->mDisconnectRunnable = nullptr;
}
}
void
BluetoothGattManager::SearchCompleteNotification(int aConnId, int aStatus)

View File

@ -12,6 +12,9 @@
#include "BluetoothProfileManagerBase.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothReplyRunnable;
class BluetoothGattManager MOZ_FINAL : public nsIObserver
, public BluetoothGattNotificationHandler
{
@ -24,10 +27,25 @@ public:
static void DeinitGattInterface(BluetoothProfileResultHandler* aRes);
virtual ~BluetoothGattManager();
void Connect(const nsAString& aAppUuid,
const nsAString& aDeviceAddr,
BluetoothReplyRunnable* aRunnable);
void Disconnect(const nsAString& aAppUuid,
const nsAString& aDeviceAddr,
BluetoothReplyRunnable* aRunnable);
void UnregisterClient(int aClientIf,
BluetoothReplyRunnable* aRunnable);
private:
class CleanupResultHandler;
class CleanupResultHandlerRunnable;
class InitGattResultHandler;
class RegisterClientResultHandler;
class UnregisterClientResultHandler;
class ConnectResultHandler;
class DisconnectResultHandler;
BluetoothGattManager();

View File

@ -55,6 +55,15 @@
} \
} while(0)
#define ENSURE_GATT_MGR_IS_READY_VOID(gatt, runnable) \
do { \
if (!gatt) { \
NS_NAMED_LITERAL_STRING(replyError, "GattManager is not ready"); \
DispatchBluetoothReply(runnable, BluetoothValue(), replyError); \
return; \
} \
} while(0)
using namespace mozilla;
using namespace mozilla::ipc;
USING_BLUETOOTH_NAMESPACE
@ -1107,6 +1116,54 @@ BluetoothServiceBluedroid::ToggleCalls(BluetoothReplyRunnable* aRunnable)
{
}
//
// GATT Client
//
void
BluetoothServiceBluedroid::ConnectGattClientInternal(
const nsAString& aAppUuid, const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
ENSURE_BLUETOOTH_IS_READY_VOID(aRunnable);
BluetoothGattManager* gatt = BluetoothGattManager::Get();
ENSURE_GATT_MGR_IS_READY_VOID(gatt, aRunnable);
gatt->Connect(aAppUuid, aDeviceAddress, aRunnable);
}
void
BluetoothServiceBluedroid::DisconnectGattClientInternal(
const nsAString& aAppUuid, const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
ENSURE_BLUETOOTH_IS_READY_VOID(aRunnable);
BluetoothGattManager* gatt = BluetoothGattManager::Get();
ENSURE_GATT_MGR_IS_READY_VOID(gatt, aRunnable);
gatt->Disconnect(aAppUuid, aDeviceAddress, aRunnable);
}
void
BluetoothServiceBluedroid::UnregisterGattClientInternal(
int aClientIf, BluetoothReplyRunnable* aRunnable)
{
MOZ_ASSERT(NS_IsMainThread());
ENSURE_BLUETOOTH_IS_READY_VOID(aRunnable);
BluetoothGattManager* gatt = BluetoothGattManager::Get();
ENSURE_GATT_MGR_IS_READY_VOID(gatt, aRunnable);
gatt->UnregisterClient(aClientIf, aRunnable);
}
//
// Bluetooth notifications
//

View File

@ -170,6 +170,24 @@ public:
SendInputMessage(const nsAString& aDeviceAddresses,
const nsAString& aMessage) MOZ_OVERRIDE;
//
// GATT Client
//
virtual void
ConnectGattClientInternal(const nsAString& aAppUuid,
const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
virtual void
DisconnectGattClientInternal(const nsAString& aAppUuid,
const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
virtual void
UnregisterGattClientInternal(int aClientIf,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
//
// Bluetooth notifications
//

View File

@ -4266,3 +4266,23 @@ BluetoothDBusService::UpdateNotification(ControlEventId aEventId,
Task* task = new UpdateNotificationTask(deviceAddress, aEventId, aData);
DispatchToDBusThread(task);
}
void
BluetoothDBusService::ConnectGattClientInternal(
const nsAString& aAppUuid, const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothDBusService::DisconnectGattClientInternal(
const nsAString& aAppUuid, const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable)
{
}
void
BluetoothDBusService::UnregisterGattClientInternal(
int aClientIf, BluetoothReplyRunnable* aRunnable)
{
}

View File

@ -184,6 +184,20 @@ public:
virtual nsresult
SendInputMessage(const nsAString& aDeviceAddresses,
const nsAString& aMessage) MOZ_OVERRIDE;
virtual void
ConnectGattClientInternal(const nsAString& aAppUuid,
const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
virtual void
DisconnectGattClientInternal(const nsAString& aAppUuid,
const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
virtual void
UnregisterGattClientInternal(int aClientIf,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
private:
nsresult SendGetPropertyMessage(const nsAString& aPath,
const char* aInterface,

View File

@ -250,6 +250,12 @@ BluetoothParent::RecvPBluetoothRequestConstructor(
return actor->DoRequest(aRequest.get_SendMetaDataRequest());
case Request::TSendPlayStatusRequest:
return actor->DoRequest(aRequest.get_SendPlayStatusRequest());
case Request::TConnectGattClientRequest:
return actor->DoRequest(aRequest.get_ConnectGattClientRequest());
case Request::TDisconnectGattClientRequest:
return actor->DoRequest(aRequest.get_DisconnectGattClientRequest());
case Request::TUnregisterGattClientRequest:
return actor->DoRequest(aRequest.get_UnregisterGattClientRequest());
default:
MOZ_CRASH("Unknown type!");
}
@ -684,3 +690,41 @@ BluetoothRequestParent::DoRequest(const SendPlayStatusRequest& aRequest)
mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(const ConnectGattClientRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TConnectGattClientRequest);
mService->ConnectGattClientInternal(aRequest.appUuid(),
aRequest.deviceAddress(),
mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(const DisconnectGattClientRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TDisconnectGattClientRequest);
mService->DisconnectGattClientInternal(aRequest.appUuid(),
aRequest.deviceAddress(),
mReplyRunnable.get());
return true;
}
bool
BluetoothRequestParent::DoRequest(const UnregisterGattClientRequest& aRequest)
{
MOZ_ASSERT(mService);
MOZ_ASSERT(mRequestType == Request::TUnregisterGattClientRequest);
mService->UnregisterGattClientInternal(aRequest.clientIf(),
mReplyRunnable.get());
return true;
}

View File

@ -216,6 +216,15 @@ protected:
bool
DoRequest(const SendPlayStatusRequest& aRequest);
bool
DoRequest(const ConnectGattClientRequest& aRequest);
bool
DoRequest(const DisconnectGattClientRequest& aRequest);
bool
DoRequest(const UnregisterGattClientRequest& aRequest);
};
END_BLUETOOTH_NAMESPACE

View File

@ -141,7 +141,7 @@ BluetoothServiceChildProcess::GetPairedDevicePropertiesInternal(
nsresult
BluetoothServiceChildProcess::FetchUuidsInternal(
const nsAString& aDeviceAddress, BluetoothReplyRunnable* aRunnable)
const nsAString& aDeviceAddress, BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable, FetchUuidsRequest(nsString(aDeviceAddress)));
return NS_OK;
@ -379,6 +379,31 @@ BluetoothServiceChildProcess::SendPlayStatus(int64_t aDuration,
nsString(aPlayStatus)));
}
void
BluetoothServiceChildProcess::ConnectGattClientInternal(
const nsAString& aAppUuid, const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable, ConnectGattClientRequest(nsString(aAppUuid),
nsString(aDeviceAddress)));
}
void
BluetoothServiceChildProcess::DisconnectGattClientInternal(
const nsAString& aAppUuid, const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable,
DisconnectGattClientRequest(nsString(aAppUuid), nsString(aDeviceAddress)));
}
void
BluetoothServiceChildProcess::UnregisterGattClientInternal(
int aClientIf, BluetoothReplyRunnable* aRunnable)
{
SendRequest(aRunnable, UnregisterGattClientRequest(aClientIf));
}
nsresult
BluetoothServiceChildProcess::HandleStartup()
{

View File

@ -192,6 +192,20 @@ public:
SendInputMessage(const nsAString& aDeviceAddresses,
const nsAString& aMessage) MOZ_OVERRIDE;
virtual void
ConnectGattClientInternal(const nsAString& aAppUuid,
const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
virtual void
DisconnectGattClientInternal(const nsAString& aAppUuid,
const nsAString& aDeviceAddress,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
virtual void
UnregisterGattClientInternal(int aClientIf,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
protected:
BluetoothServiceChildProcess();
virtual ~BluetoothServiceChildProcess();

View File

@ -176,6 +176,23 @@ struct SendPlayStatusRequest
nsString playStatus;
};
struct ConnectGattClientRequest
{
nsString appUuid;
nsString deviceAddress;
};
struct DisconnectGattClientRequest
{
nsString appUuid;
nsString deviceAddress;
};
struct UnregisterGattClientRequest
{
int clientIf;
};
union Request
{
GetAdaptersRequest;
@ -208,6 +225,9 @@ union Request
ToggleCallsRequest;
SendMetaDataRequest;
SendPlayStatusRequest;
ConnectGattClientRequest;
DisconnectGattClientRequest;
UnregisterGattClientRequest;
};
protocol PBluetooth

View File

@ -10,6 +10,7 @@ if CONFIG['MOZ_B2G_BT']:
'BluetoothClassOfDevice.cpp',
'BluetoothDevice.cpp',
'BluetoothDiscoveryHandle.cpp',
'BluetoothGatt.cpp',
'BluetoothHidManager.cpp',
'BluetoothInterface.cpp',
'BluetoothManager.cpp',
@ -122,6 +123,7 @@ EXPORTS.mozilla.dom.bluetooth += [
'BluetoothCommon.h',
'BluetoothDevice.h',
'BluetoothDiscoveryHandle.h',
'BluetoothGatt.h',
'BluetoothManager.h',
'BluetoothPairingHandle.h',
'BluetoothPairingListener.h',

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2012 Mozilla Foundation
* Copyright (C) 2012-2015 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -40,14 +40,15 @@ DEF_GONK_RECORDER_PROFILE(CAMCORDER_QUALITY_1080P, "1080p")
* profiles may have more than one resolution, depending on the camera.
*/
DEF_GONK_RECORDER_PROFILE_DETECT("fwvga", 864, 480)
DEF_GONK_RECORDER_PROFILE_DETECT("fwvga", 854, 480)
DEF_GONK_RECORDER_PROFILE_DETECT("wvga", 800, 480)
DEF_GONK_RECORDER_PROFILE_DETECT("wvga", 768, 480)
DEF_GONK_RECORDER_PROFILE_DETECT("vga", 640, 480)
DEF_GONK_RECORDER_PROFILE_DETECT("hvga", 480, 320)
DEF_GONK_RECORDER_PROFILE_DETECT("wqvga", 400, 240)
DEF_GONK_RECORDER_PROFILE_DETECT("qvga", 320, 240)
DEF_GONK_RECORDER_PROFILE_DETECT("4kuhd", 3840, 2160)
DEF_GONK_RECORDER_PROFILE_DETECT("fwvga", 864, 480)
DEF_GONK_RECORDER_PROFILE_DETECT("fwvga", 854, 480)
DEF_GONK_RECORDER_PROFILE_DETECT("wvga", 800, 480)
DEF_GONK_RECORDER_PROFILE_DETECT("wvga", 768, 480)
DEF_GONK_RECORDER_PROFILE_DETECT("vga", 640, 480)
DEF_GONK_RECORDER_PROFILE_DETECT("hvga", 480, 320)
DEF_GONK_RECORDER_PROFILE_DETECT("wqvga", 400, 240)
DEF_GONK_RECORDER_PROFILE_DETECT("qvga", 320, 240)
#undef DEF_GONK_RECORDER_PROFILE
#undef DEF_GONK_RECORDER_PROFILE_DETECT

View File

@ -600,7 +600,7 @@ bool OmxDecoder::ReadVideo(VideoFrame *aFrame, int64_t aTimeUs,
// For some codecs, the length of first decoded frame after seek is 0.
// Need to ignore it and continue to find the next one
if (mVideoBuffer->range_length() == 0) {
ReleaseVideoBuffer();
PostReleaseVideoBuffer(mVideoBuffer, FenceHandle());
findNextBuffer = true;
}
}

View File

@ -178,8 +178,10 @@ XPCOMUtils.defineLazyGetter(this, "gMessageManager", function () {
},
setFocusApp: function setFocusApp(id, isFocus) {
// if calling setNFCFocus(true) on the same browser-element, ignore.
if (isFocus && (id == this.focusApp)) {
// if calling setNFCFocus(true) on the browser-element which is already
// focused, or calling setNFCFocus(false) on the browser-element which has
// lost focus already, ignore.
if (isFocus == (id == this.focusApp)) {
return;
}

View File

@ -314,7 +314,7 @@ typedef enum {
AUDIO_DEVICE_IN_DEFAULT),
AUDIO_DEVICE_IN_ALL_SCO = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
} audio_devices_t;
#else
#elif ANDROID_VERSION < 21
enum {
AUDIO_DEVICE_NONE = 0x0,
/* reserved bits */
@ -415,6 +415,133 @@ enum {
AUDIO_DEVICE_IN_ALL_SCO = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
};
typedef uint32_t audio_devices_t;
#else
enum {
AUDIO_DEVICE_NONE = 0x0,
/* reserved bits */
AUDIO_DEVICE_BIT_IN = 0x80000000,
AUDIO_DEVICE_BIT_DEFAULT = 0x40000000,
/* output devices */
AUDIO_DEVICE_OUT_EARPIECE = 0x1,
AUDIO_DEVICE_OUT_SPEAKER = 0x2,
AUDIO_DEVICE_OUT_WIRED_HEADSET = 0x4,
AUDIO_DEVICE_OUT_WIRED_HEADPHONE = 0x8,
AUDIO_DEVICE_OUT_BLUETOOTH_SCO = 0x10,
AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20,
AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40,
AUDIO_DEVICE_OUT_BLUETOOTH_A2DP = 0x80,
AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100,
AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200,
AUDIO_DEVICE_OUT_AUX_DIGITAL = 0x400,
AUDIO_DEVICE_OUT_HDMI = AUDIO_DEVICE_OUT_AUX_DIGITAL,
/* uses an analog connection (multiplexed over the USB connector pins for instance) */
AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET = 0x800,
AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET = 0x1000,
/* USB accessory mode: your Android device is a USB device and the dock is a USB host */
AUDIO_DEVICE_OUT_USB_ACCESSORY = 0x2000,
/* USB host mode: your Android device is a USB host and the dock is a USB device */
AUDIO_DEVICE_OUT_USB_DEVICE = 0x4000,
AUDIO_DEVICE_OUT_REMOTE_SUBMIX = 0x8000,
/* Telephony voice TX path */
AUDIO_DEVICE_OUT_TELEPHONY_TX = 0x10000,
/* Analog jack with line impedance detected */
AUDIO_DEVICE_OUT_LINE = 0x20000,
/* HDMI Audio Return Channel */
AUDIO_DEVICE_OUT_HDMI_ARC = 0x40000,
/* S/PDIF out */
AUDIO_DEVICE_OUT_SPDIF = 0x80000,
/* FM transmitter out */
AUDIO_DEVICE_OUT_FM = 0x100000,
/* Line out for av devices */
AUDIO_DEVICE_OUT_AUX_LINE = 0x200000,
/* limited-output speaker device for acoustic safety */
AUDIO_DEVICE_OUT_SPEAKER_SAFE = 0x400000,
AUDIO_DEVICE_OUT_DEFAULT = AUDIO_DEVICE_BIT_DEFAULT,
AUDIO_DEVICE_OUT_ALL = (AUDIO_DEVICE_OUT_EARPIECE |
AUDIO_DEVICE_OUT_SPEAKER |
AUDIO_DEVICE_OUT_WIRED_HEADSET |
AUDIO_DEVICE_OUT_WIRED_HEADPHONE |
AUDIO_DEVICE_OUT_BLUETOOTH_SCO |
AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT |
AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER |
AUDIO_DEVICE_OUT_AUX_DIGITAL |
AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET |
AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET |
AUDIO_DEVICE_OUT_USB_ACCESSORY |
AUDIO_DEVICE_OUT_USB_DEVICE |
AUDIO_DEVICE_OUT_REMOTE_SUBMIX |
AUDIO_DEVICE_OUT_TELEPHONY_TX |
AUDIO_DEVICE_OUT_LINE |
AUDIO_DEVICE_OUT_HDMI_ARC |
AUDIO_DEVICE_OUT_SPDIF |
AUDIO_DEVICE_OUT_FM |
AUDIO_DEVICE_OUT_AUX_LINE |
AUDIO_DEVICE_OUT_SPEAKER_SAFE |
AUDIO_DEVICE_OUT_DEFAULT),
AUDIO_DEVICE_OUT_ALL_A2DP = (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
AUDIO_DEVICE_OUT_ALL_SCO = (AUDIO_DEVICE_OUT_BLUETOOTH_SCO |
AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET |
AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT),
AUDIO_DEVICE_OUT_ALL_USB = (AUDIO_DEVICE_OUT_USB_ACCESSORY |
AUDIO_DEVICE_OUT_USB_DEVICE),
/* input devices */
AUDIO_DEVICE_IN_COMMUNICATION = AUDIO_DEVICE_BIT_IN | 0x1,
AUDIO_DEVICE_IN_AMBIENT = AUDIO_DEVICE_BIT_IN | 0x2,
AUDIO_DEVICE_IN_BUILTIN_MIC = AUDIO_DEVICE_BIT_IN | 0x4,
AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET = AUDIO_DEVICE_BIT_IN | 0x8,
AUDIO_DEVICE_IN_WIRED_HEADSET = AUDIO_DEVICE_BIT_IN | 0x10,
AUDIO_DEVICE_IN_AUX_DIGITAL = AUDIO_DEVICE_BIT_IN | 0x20,
AUDIO_DEVICE_IN_HDMI = AUDIO_DEVICE_IN_AUX_DIGITAL,
/* Telephony voice RX path */
AUDIO_DEVICE_IN_VOICE_CALL = AUDIO_DEVICE_BIT_IN | 0x40,
AUDIO_DEVICE_IN_BACK_MIC = AUDIO_DEVICE_BIT_IN | 0x80,
AUDIO_DEVICE_IN_REMOTE_SUBMIX = AUDIO_DEVICE_BIT_IN | 0x100,
AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET = AUDIO_DEVICE_BIT_IN | 0x200,
AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET = AUDIO_DEVICE_BIT_IN | 0x400,
AUDIO_DEVICE_IN_USB_ACCESSORY = AUDIO_DEVICE_BIT_IN | 0x800,
AUDIO_DEVICE_IN_USB_DEVICE = AUDIO_DEVICE_BIT_IN | 0x1000,
/* FM tuner input */
AUDIO_DEVICE_IN_FM_TUNER = AUDIO_DEVICE_BIT_IN | 0x2000,
/* TV tuner input */
AUDIO_DEVICE_IN_TV_TUNER = AUDIO_DEVICE_BIT_IN | 0x4000,
/* Analog jack with line impedance detected */
AUDIO_DEVICE_IN_LINE = AUDIO_DEVICE_BIT_IN | 0x8000,
/* S/PDIF in */
AUDIO_DEVICE_IN_SPDIF = AUDIO_DEVICE_BIT_IN | 0x10000,
AUDIO_DEVICE_IN_BLUETOOTH_A2DP = AUDIO_DEVICE_BIT_IN | 0x20000,
AUDIO_DEVICE_IN_LOOPBACK = AUDIO_DEVICE_BIT_IN | 0x40000,
AUDIO_DEVICE_IN_DEFAULT = AUDIO_DEVICE_BIT_IN | AUDIO_DEVICE_BIT_DEFAULT,
AUDIO_DEVICE_IN_ALL = (AUDIO_DEVICE_IN_COMMUNICATION |
AUDIO_DEVICE_IN_AMBIENT |
AUDIO_DEVICE_IN_BUILTIN_MIC |
AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET |
AUDIO_DEVICE_IN_WIRED_HEADSET |
AUDIO_DEVICE_IN_AUX_DIGITAL |
AUDIO_DEVICE_IN_VOICE_CALL |
AUDIO_DEVICE_IN_BACK_MIC |
AUDIO_DEVICE_IN_REMOTE_SUBMIX |
AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET |
AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET |
AUDIO_DEVICE_IN_USB_ACCESSORY |
AUDIO_DEVICE_IN_USB_DEVICE |
AUDIO_DEVICE_IN_FM_TUNER |
AUDIO_DEVICE_IN_TV_TUNER |
AUDIO_DEVICE_IN_LINE |
AUDIO_DEVICE_IN_SPDIF |
AUDIO_DEVICE_IN_BLUETOOTH_A2DP |
AUDIO_DEVICE_IN_LOOPBACK |
AUDIO_DEVICE_IN_DEFAULT),
AUDIO_DEVICE_IN_ALL_SCO = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET,
AUDIO_DEVICE_IN_ALL_USB = (AUDIO_DEVICE_IN_USB_ACCESSORY |
AUDIO_DEVICE_IN_USB_DEVICE),
};
typedef uint32_t audio_devices_t;
#endif

View File

@ -465,6 +465,8 @@ this.NETWORK_CREG_TECH_EHRPD = 13;
this.NETWORK_CREG_TECH_LTE = 14;
this.NETWORK_CREG_TECH_HSPAP = 15;
this.NETWORK_CREG_TECH_GSM = 16;
this.NETWORK_CREG_TECH_DCHSPAP_1 = 18; // Some devices reports as 18
this.NETWORK_CREG_TECH_DCHSPAP_2 = 19; // Some others report it as 19
this.CELL_INFO_TYPE_GSM = 1;
this.CELL_INFO_TYPE_CDMA = 2;
@ -2913,7 +2915,10 @@ this.GECKO_RADIO_TECH = [
"ehrpd",
"lte",
"hspa+",
"gsm"
"gsm",
null,
"hspa+", // DC-HSPA+
"hspa+"
];
this.GECKO_VOICEMAIL_MESSAGE_COUNT_UNKNOWN = -1;

View File

@ -4226,6 +4226,8 @@ RilObject.prototype = {
case NETWORK_CREG_TECH_LTE:
case NETWORK_CREG_TECH_HSPAP:
case NETWORK_CREG_TECH_GSM:
case NETWORK_CREG_TECH_DCHSPAP_1:
case NETWORK_CREG_TECH_DCHSPAP_2:
return true;
}
@ -6194,6 +6196,8 @@ RilObject.prototype[REQUEST_GET_NEIGHBORING_CELL_IDS] = function REQUEST_GET_NEI
case NETWORK_CREG_TECH_HSUPA:
case NETWORK_CREG_TECH_HSPA:
case NETWORK_CREG_TECH_HSPAP:
case NETWORK_CREG_TECH_DCHSPAP_1:
case NETWORK_CREG_TECH_DCHSPAP_2:
cellId.wcdmaPsc = this.parseInt(cid, -1, 16);
break;
}

View File

@ -13,6 +13,12 @@ interface BluetoothDevice : EventTarget
readonly attribute boolean paired;
readonly attribute BluetoothDeviceType type;
/**
* Retrieve the BluetoothGatt interface to interact with remote BLE devices.
* This attribute is null if the device type is not dual or le.
*/
readonly attribute BluetoothGatt? gatt;
[Cached, Pure]
readonly attribute sequence<DOMString> uuids;

View File

@ -0,0 +1,38 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
[CheckPermissions="bluetooth"]
interface BluetoothGatt : EventTarget
{
readonly attribute BluetoothConnectionState connectionState;
// Fired when attribute connectionState changed
attribute EventHandler onconnectionstatechanged;
/**
* Connect/Disconnect to the remote BLE device if the connectionState is
* disconnected/connected. Otherwise, the Promise will be rejected directly.
*
* If current connectionState is disconnected/connected,
* 1) connectionState change to connecting/disconnecting along with a
* connectionstatechanged event.
* 2) connectionState change to connected/disconnected if the operation
* succeeds. Otherwise, change to disconnected/connected.
* 3) Promise is resolved or rejected according to the operation result.
*/
[NewObject]
Promise<void> connect();
[NewObject]
Promise<void> disconnect();
};
enum BluetoothConnectionState
{
"disconnected",
"disconnecting",
"connected",
"connecting"
};

View File

@ -632,6 +632,7 @@ if CONFIG['MOZ_B2G_BT']:
'BluetoothClassOfDevice.webidl',
'BluetoothDevice2.webidl',
'BluetoothDiscoveryHandle.webidl',
'BluetoothGatt.webidl',
'BluetoothManager2.webidl',
'BluetoothPairingHandle.webidl',
'BluetoothPairingListener.webidl',

View File

@ -37,6 +37,7 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec
[test_bug639338.xhtml]
[test_bug790265.xhtml]
[test_bug821850.html]
skip-if = buildapp == 'mulet'
[test_bug844783.html]
[test_bug872273.xhtml]
[test_bug946815.html]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -9,6 +9,6 @@ support-files =
[test_private_window_from_content.html]
# Next two tests are disabled in e10s because of bug 989501.
[test_window_open_position_constraint.html]
skip-if = toolkit == 'android' || e10s
skip-if = toolkit == 'android' || e10s || buildapp == 'mulet'
[test_window_open_units.html]
skip-if = toolkit == 'android' || e10s
skip-if = toolkit == 'android' || e10s || buildapp == 'mulet'

View File

@ -6,6 +6,7 @@
from by import By
from marionette import Actions
from marionette_test import MarionetteTestCase
from math import ceil, floor
from selection import SelectionManager
from gestures import long_press_without_contextmenu
@ -185,17 +186,24 @@ class SelectionCaretsTest(MarionetteTestCase):
(caret1_x, caret1_y), (caret2_x, caret2_y) = sel.selection_carets_location()
self.actions.flick(el, caret1_x, caret1_y, caret2_x, caret2_y).perform()
# Caret width is 29px, so we make a series of hit tests for the two
# tilted carets. If any of the hits is missed, selection would be
# collapsed and both two carets should not be draggable.
# We make two hit tests targeting the left edge of the left tilted caret
# and the right edge of the right tilted caret. If either of the hits is
# missed, selection would be collapsed and both carets should not be
# draggable.
(caret3_x, caret3_y), (caret4_x, caret4_y) = sel.selection_carets_location()
right_x = int(caret4_x + 0.5)
for i in range (right_x, right_x + 29, + 1):
self.actions.press(el, i, caret4_y).release().perform()
left_x = int(caret3_x - 0.5)
for i in range (left_x, left_x - 29, - 1):
self.actions.press(el, i, caret3_y).release().perform()
# The following values are from ua.css.
caret_width = 44
caret_margin_left = -23
tilt_right_margin_left = 18
tilt_left_margin_left = -17
left_caret_left_edge_x = caret3_x + caret_margin_left + tilt_left_margin_left
el.tap(ceil(left_caret_left_edge_x), caret3_y)
right_caret_right_edge_x = (caret4_x + caret_margin_left +
tilt_right_margin_left + caret_width)
el.tap(floor(right_caret_right_edge_x), caret4_y)
# Drag the left caret back to the initial selection, the first word.
self.actions.flick(el, caret3_x, caret3_y, caret1_x, caret1_y).perform()
@ -380,8 +388,6 @@ class SelectionCaretsTest(MarionetteTestCase):
########################################################################
# <div> contenteditable2 test cases with selection carets enabled
########################################################################
def test_contenteditable_minimum_select_one_character(self):
def test_contenteditable2_minimum_select_one_character(self):
self.openTestHtml(enabled=True)
self._test_minimum_select_one_character(self._contenteditable2, self.assertEqual)

View File

@ -325,8 +325,8 @@ div:-moz-native-anonymous.moz-selectioncaret-left,
div:-moz-native-anonymous.moz-selectioncaret-right,
div:-moz-native-anonymous.moz-selectioncaret-left > div,
div:-moz-native-anonymous.moz-selectioncaret-right > div {
width: 29px;
height: 31px;
width: 44px;
height: 47px;
background-position: center center;
background-size: 100% 100%;
z-index: 2147483647;
@ -341,17 +341,17 @@ div:-moz-native-anonymous.moz-selectioncaret-right > div {
div:-moz-native-anonymous.moz-touchcaret,
div:-moz-native-anonymous.moz-selectioncaret-left,
div:-moz-native-anonymous.moz-selectioncaret-right {
margin-left: -15px;
margin-left: -23px;
}
div:-moz-native-anonymous.moz-selectioncaret-left.tilt > div {
background-image: url("resource://gre/res/text_caret_tilt_left.png");
margin-left: -14px;
margin-left: -17px;
}
div:-moz-native-anonymous.moz-selectioncaret-right.tilt > div {
background-image: url("resource://gre/res/text_caret_tilt_right.png");
margin-left: 14px;
margin-left: 18px;
}
@media (min-resolution: 1.5dppx) {

View File

@ -17,7 +17,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "CommonUtils", "resource://services-comm
XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm");
let ReaderMode = {
this.ReaderMode = {
// Version of the cache schema.
CACHE_VERSION: 1,