merge b2g-inbound to mozilla-central a=merge
@ -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
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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"
|
||||
}
|
||||
|
@ -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"/>
|
||||
|
@ -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"/>
|
||||
|
@ -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")
|
||||
|
@ -152,6 +152,10 @@ DOMInterfaces = {
|
||||
'nativeType': 'mozilla::dom::bluetooth::BluetoothDiscoveryHandle',
|
||||
},
|
||||
|
||||
'BluetoothGatt': {
|
||||
'nativeType': 'mozilla::dom::bluetooth::BluetoothGatt',
|
||||
},
|
||||
|
||||
'BluetoothManager': {
|
||||
'nativeType': 'mozilla::dom::bluetooth::BluetoothManager',
|
||||
},
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
217
dom/bluetooth2/BluetoothGatt.cpp
Normal 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);
|
||||
}
|
116
dom/bluetooth2/BluetoothGatt.h
Normal 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
|
@ -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
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
//
|
||||
|
@ -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
|
||||
//
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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',
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
38
dom/webidl/BluetoothGatt.webidl
Normal 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"
|
||||
};
|
@ -632,6 +632,7 @@ if CONFIG['MOZ_B2G_BT']:
|
||||
'BluetoothClassOfDevice.webidl',
|
||||
'BluetoothDevice2.webidl',
|
||||
'BluetoothDiscoveryHandle.webidl',
|
||||
'BluetoothGatt.webidl',
|
||||
'BluetoothManager2.webidl',
|
||||
'BluetoothPairingHandle.webidl',
|
||||
'BluetoothPairingListener.webidl',
|
||||
|
@ -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]
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 3.0 KiB |
@ -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'
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
||||
|